1/*
2 * Copyright (c) 1997 - 1999 Kungliga Tekniska H��gskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "kadm5_locl.h"
35
36RCSID("$Id$");
37
38kadm5_ret_t
39kadm5_store_key_data(krb5_storage *sp,
40		     krb5_key_data *key)
41{
42    krb5_data c;
43    krb5_store_int32(sp, key->key_data_ver);
44    krb5_store_int32(sp, key->key_data_kvno);
45    krb5_store_int32(sp, key->key_data_type[0]);
46    c.length = key->key_data_length[0];
47    c.data = key->key_data_contents[0];
48    krb5_store_data(sp, c);
49    krb5_store_int32(sp, key->key_data_type[1]);
50    c.length = key->key_data_length[1];
51    c.data = key->key_data_contents[1];
52    krb5_store_data(sp, c);
53    return 0;
54}
55
56kadm5_ret_t
57kadm5_ret_key_data(krb5_storage *sp,
58		   krb5_key_data *key)
59{
60    krb5_data c;
61    int32_t tmp;
62    krb5_ret_int32(sp, &tmp);
63    key->key_data_ver = tmp;
64    krb5_ret_int32(sp, &tmp);
65    key->key_data_kvno = tmp;
66    krb5_ret_int32(sp, &tmp);
67    key->key_data_type[0] = tmp;
68    krb5_ret_data(sp, &c);
69    key->key_data_length[0] = c.length;
70    key->key_data_contents[0] = c.data;
71    krb5_ret_int32(sp, &tmp);
72    key->key_data_type[1] = tmp;
73    krb5_ret_data(sp, &c);
74    key->key_data_length[1] = c.length;
75    key->key_data_contents[1] = c.data;
76    return 0;
77}
78
79kadm5_ret_t
80kadm5_store_tl_data(krb5_storage *sp,
81		    krb5_tl_data *tl)
82{
83    krb5_data c;
84    krb5_store_int32(sp, tl->tl_data_type);
85    c.length = tl->tl_data_length;
86    c.data = tl->tl_data_contents;
87    krb5_store_data(sp, c);
88    return 0;
89}
90
91kadm5_ret_t
92kadm5_ret_tl_data(krb5_storage *sp,
93		  krb5_tl_data *tl)
94{
95    krb5_data c;
96    int32_t tmp;
97    krb5_ret_int32(sp, &tmp);
98    tl->tl_data_type = tmp;
99    krb5_ret_data(sp, &c);
100    tl->tl_data_length = c.length;
101    tl->tl_data_contents = c.data;
102    return 0;
103}
104
105static kadm5_ret_t
106store_principal_ent(krb5_storage *sp,
107		    kadm5_principal_ent_t princ,
108		    uint32_t mask)
109{
110    int i;
111
112    if (mask & KADM5_PRINCIPAL)
113	krb5_store_principal(sp, princ->principal);
114    if (mask & KADM5_PRINC_EXPIRE_TIME)
115	krb5_store_int32(sp, princ->princ_expire_time);
116    if (mask & KADM5_PW_EXPIRATION)
117	krb5_store_int32(sp, princ->pw_expiration);
118    if (mask & KADM5_LAST_PWD_CHANGE)
119	krb5_store_int32(sp, princ->last_pwd_change);
120    if (mask & KADM5_MAX_LIFE)
121	krb5_store_int32(sp, princ->max_life);
122    if (mask & KADM5_MOD_NAME) {
123	krb5_store_int32(sp, princ->mod_name != NULL);
124	if(princ->mod_name)
125	    krb5_store_principal(sp, princ->mod_name);
126    }
127    if (mask & KADM5_MOD_TIME)
128	krb5_store_int32(sp, princ->mod_date);
129    if (mask & KADM5_ATTRIBUTES)
130	krb5_store_int32(sp, princ->attributes);
131    if (mask & KADM5_KVNO)
132	krb5_store_int32(sp, princ->kvno);
133    if (mask & KADM5_MKVNO)
134	krb5_store_int32(sp, princ->mkvno);
135    if (mask & KADM5_POLICY) {
136	krb5_store_int32(sp, princ->policy != NULL);
137	if(princ->policy)
138	    krb5_store_string(sp, princ->policy);
139    }
140    if (mask & KADM5_AUX_ATTRIBUTES)
141	krb5_store_int32(sp, princ->aux_attributes);
142    if (mask & KADM5_MAX_RLIFE)
143	krb5_store_int32(sp, princ->max_renewable_life);
144    if (mask & KADM5_LAST_SUCCESS)
145	krb5_store_int32(sp, princ->last_success);
146    if (mask & KADM5_LAST_FAILED)
147	krb5_store_int32(sp, princ->last_failed);
148    if (mask & KADM5_FAIL_AUTH_COUNT)
149	krb5_store_int32(sp, princ->fail_auth_count);
150    if (mask & KADM5_KEY_DATA) {
151	krb5_store_int32(sp, princ->n_key_data);
152	for(i = 0; i < princ->n_key_data; i++)
153	    kadm5_store_key_data(sp, &princ->key_data[i]);
154    }
155    if (mask & KADM5_TL_DATA) {
156	krb5_tl_data *tp;
157
158	krb5_store_int32(sp, princ->n_tl_data);
159	for(tp = princ->tl_data; tp; tp = tp->tl_data_next)
160	    kadm5_store_tl_data(sp, tp);
161    }
162    return 0;
163}
164
165
166kadm5_ret_t
167kadm5_store_principal_ent(krb5_storage *sp,
168			  kadm5_principal_ent_t princ)
169{
170    return store_principal_ent (sp, princ, ~0);
171}
172
173kadm5_ret_t
174kadm5_store_principal_ent_mask(krb5_storage *sp,
175			       kadm5_principal_ent_t princ,
176			       uint32_t mask)
177{
178    krb5_store_int32(sp, mask);
179    return store_principal_ent (sp, princ, mask);
180}
181
182static kadm5_ret_t
183ret_principal_ent(krb5_storage *sp,
184		  kadm5_principal_ent_t princ,
185		  uint32_t mask)
186{
187    int i;
188    int32_t tmp;
189
190    if (mask & KADM5_PRINCIPAL)
191	krb5_ret_principal(sp, &princ->principal);
192
193    if (mask & KADM5_PRINC_EXPIRE_TIME) {
194	krb5_ret_int32(sp, &tmp);
195	princ->princ_expire_time = tmp;
196    }
197    if (mask & KADM5_PW_EXPIRATION) {
198	krb5_ret_int32(sp, &tmp);
199	princ->pw_expiration = tmp;
200    }
201    if (mask & KADM5_LAST_PWD_CHANGE) {
202	krb5_ret_int32(sp, &tmp);
203	princ->last_pwd_change = tmp;
204    }
205    if (mask & KADM5_MAX_LIFE) {
206	krb5_ret_int32(sp, &tmp);
207	princ->max_life = tmp;
208    }
209    if (mask & KADM5_MOD_NAME) {
210	krb5_ret_int32(sp, &tmp);
211	if(tmp)
212	    krb5_ret_principal(sp, &princ->mod_name);
213	else
214	    princ->mod_name = NULL;
215    }
216    if (mask & KADM5_MOD_TIME) {
217	krb5_ret_int32(sp, &tmp);
218	princ->mod_date = tmp;
219    }
220    if (mask & KADM5_ATTRIBUTES) {
221	krb5_ret_int32(sp, &tmp);
222	princ->attributes = tmp;
223    }
224    if (mask & KADM5_KVNO) {
225	krb5_ret_int32(sp, &tmp);
226	princ->kvno = tmp;
227    }
228    if (mask & KADM5_MKVNO) {
229	krb5_ret_int32(sp, &tmp);
230	princ->mkvno = tmp;
231    }
232    if (mask & KADM5_POLICY) {
233	krb5_ret_int32(sp, &tmp);
234	if(tmp)
235	    krb5_ret_string(sp, &princ->policy);
236	else
237	    princ->policy = NULL;
238    }
239    if (mask & KADM5_AUX_ATTRIBUTES) {
240	krb5_ret_int32(sp, &tmp);
241	princ->aux_attributes = tmp;
242    }
243    if (mask & KADM5_MAX_RLIFE) {
244	krb5_ret_int32(sp, &tmp);
245	princ->max_renewable_life = tmp;
246    }
247    if (mask & KADM5_LAST_SUCCESS) {
248	krb5_ret_int32(sp, &tmp);
249	princ->last_success = tmp;
250    }
251    if (mask & KADM5_LAST_FAILED) {
252	krb5_ret_int32(sp, &tmp);
253	princ->last_failed = tmp;
254    }
255    if (mask & KADM5_FAIL_AUTH_COUNT) {
256	krb5_ret_int32(sp, &tmp);
257	princ->fail_auth_count = tmp;
258    }
259    if (mask & KADM5_KEY_DATA) {
260	krb5_ret_int32(sp, &tmp);
261	princ->n_key_data = tmp;
262	princ->key_data = malloc(princ->n_key_data * sizeof(*princ->key_data));
263	if (princ->key_data == NULL && princ->n_key_data != 0)
264	    return ENOMEM;
265	for(i = 0; i < princ->n_key_data; i++)
266	    kadm5_ret_key_data(sp, &princ->key_data[i]);
267    }
268    if (mask & KADM5_TL_DATA) {
269	krb5_ret_int32(sp, &tmp);
270	princ->n_tl_data = tmp;
271	princ->tl_data = NULL;
272	for(i = 0; i < princ->n_tl_data; i++){
273	    krb5_tl_data *tp = malloc(sizeof(*tp));
274	    if (tp == NULL)
275		return ENOMEM;
276	    kadm5_ret_tl_data(sp, tp);
277	    tp->tl_data_next = princ->tl_data;
278	    princ->tl_data = tp;
279	}
280    }
281    return 0;
282}
283
284kadm5_ret_t
285kadm5_ret_principal_ent(krb5_storage *sp,
286			kadm5_principal_ent_t princ)
287{
288    return ret_principal_ent (sp, princ, ~0);
289}
290
291kadm5_ret_t
292kadm5_ret_principal_ent_mask(krb5_storage *sp,
293			     kadm5_principal_ent_t princ,
294			     uint32_t *mask)
295{
296    int32_t tmp;
297
298    krb5_ret_int32 (sp, &tmp);
299    *mask = tmp;
300    return ret_principal_ent (sp, princ, *mask);
301}
302
303kadm5_ret_t
304_kadm5_marshal_params(krb5_context context,
305		      kadm5_config_params *params,
306		      krb5_data *out)
307{
308    krb5_storage *sp = krb5_storage_emem();
309
310    krb5_store_int32(sp, params->mask & (KADM5_CONFIG_REALM));
311
312    if(params->mask & KADM5_CONFIG_REALM)
313	krb5_store_string(sp, params->realm);
314    krb5_storage_to_data(sp, out);
315    krb5_storage_free(sp);
316
317    return 0;
318}
319
320kadm5_ret_t
321_kadm5_unmarshal_params(krb5_context context,
322			krb5_data *in,
323			kadm5_config_params *params)
324{
325    krb5_error_code ret;
326    krb5_storage *sp;
327    int32_t mask;
328
329    sp = krb5_storage_from_data(in);
330    if (sp == NULL)
331	return ENOMEM;
332
333    ret = krb5_ret_int32(sp, &mask);
334    if (ret)
335	goto out;
336    params->mask = mask;
337
338    if(params->mask & KADM5_CONFIG_REALM)
339	ret = krb5_ret_string(sp, &params->realm);
340 out:
341    krb5_storage_free(sp);
342
343    return ret;
344}
345