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
36 RCSID("$Id$");
37 #define CHECK(e) do { if (e) return EINVAL; } while (0)
38
39 kadm5_ret_t
kadm5_store_key_data(krb5_storage * sp,krb5_key_data * key)40 kadm5_store_key_data(krb5_storage *sp,
41 krb5_key_data *key)
42 {
43 krb5_data c;
44 CHECK(krb5_store_int32(sp, key->key_data_ver));
45 CHECK(krb5_store_int32(sp, key->key_data_kvno));
46 CHECK(krb5_store_int32(sp, key->key_data_type[0]));
47 c.length = key->key_data_length[0];
48 c.data = key->key_data_contents[0];
49 CHECK(krb5_store_data(sp, c));
50 CHECK(krb5_store_int32(sp, key->key_data_type[1]));
51 c.length = key->key_data_length[1];
52 c.data = key->key_data_contents[1];
53 CHECK(krb5_store_data(sp, c));
54 return 0;
55 }
56
57 kadm5_ret_t
kadm5_ret_key_data(krb5_storage * sp,krb5_key_data * key)58 kadm5_ret_key_data(krb5_storage *sp,
59 krb5_key_data *key)
60 {
61 kadm5_ret_t ret;
62 krb5_data c;
63 int32_t tmp;
64 ret = krb5_ret_int32(sp, &tmp);
65 if (ret == 0) {
66 key->key_data_ver = tmp;
67 ret = krb5_ret_int32(sp, &tmp);
68 }
69 if (ret == 0) {
70 key->key_data_kvno = tmp;
71 ret = krb5_ret_int32(sp, &tmp);
72 }
73 if (ret == 0) {
74 key->key_data_type[0] = tmp;
75 ret = krb5_ret_data(sp, &c);
76 }
77 if (ret == 0) {
78 key->key_data_length[0] = c.length;
79 key->key_data_contents[0] = c.data;
80 ret = krb5_ret_int32(sp, &tmp);
81 }
82 if (ret == 0) {
83 key->key_data_type[1] = tmp;
84 ret = krb5_ret_data(sp, &c);
85 }
86 if (ret == 0) {
87 key->key_data_length[1] = c.length;
88 key->key_data_contents[1] = c.data;
89 return 0;
90 }
91 return KADM5_FAILURE;
92 }
93
94 kadm5_ret_t
kadm5_store_tl_data(krb5_storage * sp,krb5_tl_data * tl)95 kadm5_store_tl_data(krb5_storage *sp,
96 krb5_tl_data *tl)
97 {
98 krb5_data c;
99 CHECK(krb5_store_int32(sp, tl->tl_data_type));
100 c.length = tl->tl_data_length;
101 c.data = tl->tl_data_contents;
102 CHECK(krb5_store_data(sp, c));
103 return 0;
104 }
105
106 kadm5_ret_t
kadm5_ret_tl_data(krb5_storage * sp,krb5_tl_data * tl)107 kadm5_ret_tl_data(krb5_storage *sp,
108 krb5_tl_data *tl)
109 {
110 krb5_data c;
111 int32_t tmp;
112 krb5_ret_int32(sp, &tmp);
113 tl->tl_data_type = tmp;
114 CHECK(krb5_ret_data(sp, &c));
115 tl->tl_data_length = c.length;
116 tl->tl_data_contents = c.data;
117 return 0;
118 }
119
120 static kadm5_ret_t
store_principal_ent(krb5_storage * sp,kadm5_principal_ent_t princ,uint32_t mask)121 store_principal_ent(krb5_storage *sp,
122 kadm5_principal_ent_t princ,
123 uint32_t mask)
124 {
125 int i;
126
127 if (mask & KADM5_PRINCIPAL)
128 CHECK(krb5_store_principal(sp, princ->principal));
129 if (mask & KADM5_PRINC_EXPIRE_TIME)
130 CHECK(krb5_store_int32(sp, princ->princ_expire_time));
131 if (mask & KADM5_PW_EXPIRATION)
132 CHECK(krb5_store_int32(sp, princ->pw_expiration));
133 if (mask & KADM5_LAST_PWD_CHANGE)
134 CHECK(krb5_store_int32(sp, princ->last_pwd_change));
135 if (mask & KADM5_MAX_LIFE)
136 CHECK(krb5_store_int32(sp, princ->max_life));
137 if (mask & KADM5_MOD_NAME) {
138 CHECK(krb5_store_int32(sp, princ->mod_name != NULL));
139 if(princ->mod_name)
140 CHECK(krb5_store_principal(sp, princ->mod_name));
141 }
142 if (mask & KADM5_MOD_TIME)
143 CHECK(krb5_store_int32(sp, princ->mod_date));
144 if (mask & KADM5_ATTRIBUTES)
145 CHECK(krb5_store_int32(sp, princ->attributes));
146 if (mask & KADM5_KVNO)
147 CHECK(krb5_store_int32(sp, princ->kvno));
148 if (mask & KADM5_MKVNO)
149 CHECK(krb5_store_int32(sp, princ->mkvno));
150 if (mask & KADM5_POLICY) {
151 CHECK(krb5_store_int32(sp, princ->policy != NULL));
152 if(princ->policy)
153 CHECK(krb5_store_string(sp, princ->policy));
154 }
155 if (mask & KADM5_AUX_ATTRIBUTES)
156 CHECK(krb5_store_int32(sp, princ->aux_attributes));
157 if (mask & KADM5_MAX_RLIFE)
158 CHECK(krb5_store_int32(sp, princ->max_renewable_life));
159 if (mask & KADM5_LAST_SUCCESS)
160 CHECK(krb5_store_int32(sp, princ->last_success));
161 if (mask & KADM5_LAST_FAILED)
162 CHECK(krb5_store_int32(sp, princ->last_failed));
163 if (mask & KADM5_FAIL_AUTH_COUNT)
164 CHECK(krb5_store_int32(sp, princ->fail_auth_count));
165 if (mask & KADM5_KEY_DATA) {
166 CHECK(krb5_store_int32(sp, princ->n_key_data));
167 for(i = 0; i < princ->n_key_data; i++)
168 CHECK(kadm5_store_key_data(sp, &princ->key_data[i]));
169 }
170 if (mask & KADM5_TL_DATA) {
171 krb5_tl_data *tp;
172
173 CHECK(krb5_store_int32(sp, princ->n_tl_data));
174 for(tp = princ->tl_data; tp; tp = tp->tl_data_next)
175 CHECK(kadm5_store_tl_data(sp, tp));
176 }
177 return 0;
178 }
179
180
181 kadm5_ret_t
kadm5_store_principal_ent(krb5_storage * sp,kadm5_principal_ent_t princ)182 kadm5_store_principal_ent(krb5_storage *sp,
183 kadm5_principal_ent_t princ)
184 {
185 return store_principal_ent (sp, princ, ~0);
186 }
187
188 kadm5_ret_t
kadm5_store_principal_ent_mask(krb5_storage * sp,kadm5_principal_ent_t princ,uint32_t mask)189 kadm5_store_principal_ent_mask(krb5_storage *sp,
190 kadm5_principal_ent_t princ,
191 uint32_t mask)
192 {
193 kadm5_ret_t ret;
194
195 ret = krb5_store_int32(sp, mask);
196 if (ret == 0)
197 ret = store_principal_ent (sp, princ, mask);
198 return (ret);
199 }
200
201 static kadm5_ret_t
ret_principal_ent(krb5_storage * sp,kadm5_principal_ent_t princ,uint32_t mask)202 ret_principal_ent(krb5_storage *sp,
203 kadm5_principal_ent_t princ,
204 uint32_t mask)
205 {
206 int i;
207 int32_t tmp;
208
209 if (mask & KADM5_PRINCIPAL)
210 CHECK(krb5_ret_principal(sp, &princ->principal));
211 if (mask & KADM5_PRINC_EXPIRE_TIME) {
212 CHECK(krb5_ret_int32(sp, &tmp));
213 princ->princ_expire_time = tmp;
214 }
215 if (mask & KADM5_PW_EXPIRATION) {
216 CHECK(krb5_ret_int32(sp, &tmp));
217 princ->pw_expiration = tmp;
218 }
219 if (mask & KADM5_LAST_PWD_CHANGE) {
220 CHECK(krb5_ret_int32(sp, &tmp));
221 princ->last_pwd_change = tmp;
222 }
223 if (mask & KADM5_MAX_LIFE) {
224 CHECK(krb5_ret_int32(sp, &tmp));
225 princ->max_life = tmp;
226 }
227 if (mask & KADM5_MOD_NAME) {
228 CHECK(krb5_ret_int32(sp, &tmp));
229 if(tmp)
230 CHECK(krb5_ret_principal(sp, &princ->mod_name));
231 else
232 princ->mod_name = NULL;
233 }
234 if (mask & KADM5_MOD_TIME) {
235 CHECK(krb5_ret_int32(sp, &tmp));
236 princ->mod_date = tmp;
237 }
238 if (mask & KADM5_ATTRIBUTES) {
239 CHECK(krb5_ret_int32(sp, &tmp));
240 princ->attributes = tmp;
241 }
242 if (mask & KADM5_KVNO) {
243 CHECK(krb5_ret_int32(sp, &tmp));
244 princ->kvno = tmp;
245 }
246 if (mask & KADM5_MKVNO) {
247 CHECK(krb5_ret_int32(sp, &tmp));
248 princ->mkvno = tmp;
249 }
250 if (mask & KADM5_POLICY) {
251 CHECK(krb5_ret_int32(sp, &tmp));
252 if(tmp)
253 CHECK(krb5_ret_string(sp, &princ->policy));
254 else
255 princ->policy = NULL;
256 }
257 if (mask & KADM5_AUX_ATTRIBUTES) {
258 CHECK(krb5_ret_int32(sp, &tmp));
259 princ->aux_attributes = tmp;
260 }
261 if (mask & KADM5_MAX_RLIFE) {
262 CHECK(krb5_ret_int32(sp, &tmp));
263 princ->max_renewable_life = tmp;
264 }
265 if (mask & KADM5_LAST_SUCCESS) {
266 CHECK(krb5_ret_int32(sp, &tmp));
267 princ->last_success = tmp;
268 }
269 if (mask & KADM5_LAST_FAILED) {
270 CHECK(krb5_ret_int32(sp, &tmp));
271 princ->last_failed = tmp;
272 }
273 if (mask & KADM5_FAIL_AUTH_COUNT) {
274 CHECK(krb5_ret_int32(sp, &tmp));
275 princ->fail_auth_count = tmp;
276 }
277 if (mask & KADM5_KEY_DATA) {
278 CHECK(krb5_ret_int32(sp, &tmp));
279 princ->n_key_data = tmp;
280 princ->key_data = malloc(princ->n_key_data * sizeof(*princ->key_data));
281 if (princ->key_data == NULL && princ->n_key_data != 0)
282 return ENOMEM;
283 for(i = 0; i < princ->n_key_data; i++)
284 CHECK(kadm5_ret_key_data(sp, &princ->key_data[i]));
285 }
286 if (mask & KADM5_TL_DATA) {
287 CHECK(krb5_ret_int32(sp, &tmp));
288 princ->n_tl_data = tmp;
289 princ->tl_data = NULL;
290 for(i = 0; i < princ->n_tl_data; i++){
291 krb5_tl_data *tp = malloc(sizeof(*tp));
292 if (tp == NULL)
293 return ENOMEM;
294 CHECK(kadm5_ret_tl_data(sp, tp));
295 tp->tl_data_next = princ->tl_data;
296 princ->tl_data = tp;
297 }
298 }
299 return 0;
300 }
301
302 kadm5_ret_t
kadm5_ret_principal_ent(krb5_storage * sp,kadm5_principal_ent_t princ)303 kadm5_ret_principal_ent(krb5_storage *sp,
304 kadm5_principal_ent_t princ)
305 {
306 return ret_principal_ent (sp, princ, ~0);
307 }
308
309 kadm5_ret_t
kadm5_ret_principal_ent_mask(krb5_storage * sp,kadm5_principal_ent_t princ,uint32_t * mask)310 kadm5_ret_principal_ent_mask(krb5_storage *sp,
311 kadm5_principal_ent_t princ,
312 uint32_t *mask)
313 {
314 kadm5_ret_t ret;
315 int32_t tmp;
316
317 ret = krb5_ret_int32 (sp, &tmp);
318 if (ret) {
319 *mask = 0;
320 return (ret);
321 }
322 *mask = tmp;
323 return ret_principal_ent (sp, princ, *mask);
324 }
325
326 kadm5_ret_t
_kadm5_marshal_params(krb5_context context,kadm5_config_params * params,krb5_data * out)327 _kadm5_marshal_params(krb5_context context,
328 kadm5_config_params *params,
329 krb5_data *out)
330 {
331 kadm5_ret_t ret;
332
333 krb5_storage *sp = krb5_storage_emem();
334
335 ret = krb5_store_int32(sp, params->mask & (KADM5_CONFIG_REALM));
336
337 if (ret == 0 && params->mask & KADM5_CONFIG_REALM)
338 ret = krb5_store_string(sp, params->realm);
339 if (ret == 0)
340 krb5_storage_to_data(sp, out);
341 krb5_storage_free(sp);
342
343 return (ret);
344 }
345
346 kadm5_ret_t
_kadm5_unmarshal_params(krb5_context context,krb5_data * in,kadm5_config_params * params)347 _kadm5_unmarshal_params(krb5_context context,
348 krb5_data *in,
349 kadm5_config_params *params)
350 {
351 krb5_error_code ret;
352 krb5_storage *sp;
353 int32_t mask;
354
355 sp = krb5_storage_from_data(in);
356 if (sp == NULL)
357 return ENOMEM;
358
359 ret = krb5_ret_int32(sp, &mask);
360 if (ret)
361 goto out;
362 if (mask & KADM5_CONFIG_REALM & KADM5_CONFIG_DBNAME
363 & KADM5_CONFIG_ACL_FILE & KADM5_CONFIG_STASH_FILE) {
364 ret = EINVAL;
365 goto out;
366 }
367 params->mask = mask;
368
369 if (params->mask & KADM5_CONFIG_REALM) {
370 ret = krb5_ret_string(sp, ¶ms->realm);
371 if (params->realm == NULL) {
372 ret = EINVAL;
373 goto out;
374 }
375 }
376 if (params->mask & KADM5_CONFIG_DBNAME) {
377 ret = krb5_ret_string(sp, ¶ms->dbname);
378 if (params->dbname == NULL) {
379 ret = EINVAL;
380 goto out;
381 }
382 }
383 if (params->mask & KADM5_CONFIG_ACL_FILE) {
384 ret = krb5_ret_string(sp, ¶ms->acl_file);
385 if (params->acl_file == NULL) {
386 ret = EINVAL;
387 goto out;
388 }
389 }
390 if (params->mask & KADM5_CONFIG_STASH_FILE) {
391 ret = krb5_ret_string(sp, ¶ms->stash_file);
392 if (params->stash_file == NULL) {
393 ret = EINVAL;
394 }
395 }
396 out:
397 krb5_storage_free(sp);
398
399 return ret;
400 }
401