1 /* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
2 /*
3 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
4 */
5
6 #include <gssrpc/rpc.h>
7 #include <krb5.h>
8 #include <errno.h>
9 #include <kadm5/admin.h>
10 #include <kadm5/kadm_rpc.h>
11 #include <kadm5/admin_xdr.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 static bool_t
16 _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
17 int v);
18 static bool_t
19 _xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp, int vers);
20
21 /*
22 * Function: xdr_ui_4
23 *
24 * Purpose: XDR function which serves as a wrapper for xdr_u_int32,
25 * to prevent compiler warnings about type clashes between u_int32
26 * and krb5_ui_4.
27 */
xdr_ui_4(XDR * xdrs,krb5_ui_4 * objp)28 bool_t xdr_ui_4(XDR *xdrs, krb5_ui_4 *objp)
29 {
30 /* Assumes that krb5_ui_4 and u_int32 are both four bytes long.
31 This should not be a harmful assumption. */
32 return xdr_u_int32(xdrs, (uint32_t *) objp);
33 }
34
35
36 /*
37 * Function: xdr_nullstring
38 *
39 * Purpose: XDR function for "strings" that are either NULL-terminated
40 * or NULL.
41 */
xdr_nullstring(XDR * xdrs,char ** objp)42 bool_t xdr_nullstring(XDR *xdrs, char **objp)
43 {
44 u_int size;
45
46 if (xdrs->x_op == XDR_ENCODE) {
47 if (*objp == NULL)
48 size = 0;
49 else
50 size = strlen(*objp) + 1;
51 }
52 if (! xdr_u_int(xdrs, &size)) {
53 return FALSE;
54 }
55 switch (xdrs->x_op) {
56 case XDR_DECODE:
57 if (size == 0) {
58 *objp = NULL;
59 return TRUE;
60 } else if (*objp == NULL) {
61 *objp = (char *) mem_alloc(size);
62 if (*objp == NULL) {
63 errno = ENOMEM;
64 return FALSE;
65 }
66 }
67 if (!xdr_opaque(xdrs, *objp, size))
68 return FALSE;
69 /* Check that the unmarshalled bytes are a C string. */
70 if ((*objp)[size - 1] != '\0')
71 return FALSE;
72 if (memchr(*objp, '\0', size - 1) != NULL)
73 return FALSE;
74 return TRUE;
75
76 case XDR_ENCODE:
77 if (size != 0)
78 return (xdr_opaque(xdrs, *objp, size));
79 return TRUE;
80
81 case XDR_FREE:
82 if (*objp != NULL)
83 mem_free(*objp, size);
84 *objp = NULL;
85 return TRUE;
86 }
87
88 return FALSE;
89 }
90
91 /*
92 * Function: xdr_nulltype
93 *
94 * Purpose: XDR function for arbitrary pointer types that are either
95 * NULL or contain data.
96 */
xdr_nulltype(XDR * xdrs,void ** objp,xdrproc_t proc)97 bool_t xdr_nulltype(XDR *xdrs, void **objp, xdrproc_t proc)
98 {
99 bool_t null;
100
101 switch (xdrs->x_op) {
102 case XDR_DECODE:
103 if (!xdr_bool(xdrs, &null))
104 return FALSE;
105 if (null) {
106 *objp = NULL;
107 return TRUE;
108 }
109 return (*proc)(xdrs, objp);
110
111 case XDR_ENCODE:
112 if (*objp == NULL)
113 null = TRUE;
114 else
115 null = FALSE;
116 if (!xdr_bool(xdrs, &null))
117 return FALSE;
118 if (null == FALSE)
119 return (*proc)(xdrs, objp);
120 return TRUE;
121
122 case XDR_FREE:
123 if (*objp)
124 return (*proc)(xdrs, objp);
125 return TRUE;
126 }
127
128 return FALSE;
129 }
130
131 bool_t
xdr_krb5_timestamp(XDR * xdrs,krb5_timestamp * objp)132 xdr_krb5_timestamp(XDR *xdrs, krb5_timestamp *objp)
133 {
134 /* This assumes that int32 and krb5_timestamp are the same size.
135 This shouldn't be a problem, since we've got a unit test which
136 checks for this. */
137 if (!xdr_int32(xdrs, (int32_t *) objp)) {
138 return (FALSE);
139 }
140 return (TRUE);
141 }
142
143 bool_t
xdr_krb5_kvno(XDR * xdrs,krb5_kvno * objp)144 xdr_krb5_kvno(XDR *xdrs, krb5_kvno *objp)
145 {
146 return xdr_u_int(xdrs, objp);
147 }
148
149 bool_t
xdr_krb5_deltat(XDR * xdrs,krb5_deltat * objp)150 xdr_krb5_deltat(XDR *xdrs, krb5_deltat *objp)
151 {
152 /* This assumes that int32 and krb5_deltat are the same size.
153 This shouldn't be a problem, since we've got a unit test which
154 checks for this. */
155 if (!xdr_int32(xdrs, (int32_t *) objp)) {
156 return (FALSE);
157 }
158 return (TRUE);
159 }
160
161 bool_t
xdr_krb5_flags(XDR * xdrs,krb5_flags * objp)162 xdr_krb5_flags(XDR *xdrs, krb5_flags *objp)
163 {
164 /* This assumes that int32 and krb5_flags are the same size.
165 This shouldn't be a problem, since we've got a unit test which
166 checks for this. */
167 if (!xdr_int32(xdrs, (int32_t *) objp)) {
168 return (FALSE);
169 }
170 return (TRUE);
171 }
172
173 bool_t
xdr_krb5_ui_4(XDR * xdrs,krb5_ui_4 * objp)174 xdr_krb5_ui_4(XDR *xdrs, krb5_ui_4 *objp)
175 {
176 if (!xdr_u_int32(xdrs, (uint32_t *) objp)) {
177 return (FALSE);
178 }
179 return (TRUE);
180 }
181
182 bool_t
xdr_krb5_int16(XDR * xdrs,krb5_int16 * objp)183 xdr_krb5_int16(XDR *xdrs, krb5_int16 *objp)
184 {
185 int tmp;
186
187 tmp = (int) *objp;
188
189 if (!xdr_int(xdrs, &tmp))
190 return(FALSE);
191
192 *objp = (krb5_int16) tmp;
193
194 return(TRUE);
195 }
196
197 /*
198 * Function: xdr_krb5_ui_2
199 *
200 * Purpose: XDR function which serves as a wrapper for xdr_u_int,
201 * to prevent compiler warnings about type clashes between u_int
202 * and krb5_ui_2.
203 */
204 bool_t
xdr_krb5_ui_2(XDR * xdrs,krb5_ui_2 * objp)205 xdr_krb5_ui_2(XDR *xdrs, krb5_ui_2 *objp)
206 {
207 unsigned int tmp;
208
209 tmp = (unsigned int) *objp;
210
211 if (!xdr_u_int(xdrs, &tmp))
212 return(FALSE);
213
214 *objp = (krb5_ui_2) tmp;
215
216 return(TRUE);
217 }
218
219
220
xdr_krb5_boolean(XDR * xdrs,krb5_boolean * kbool)221 static bool_t xdr_krb5_boolean(XDR *xdrs, krb5_boolean *kbool)
222 {
223 bool_t val;
224
225 switch (xdrs->x_op) {
226 case XDR_DECODE:
227 if (!xdr_bool(xdrs, &val))
228 return FALSE;
229
230 *kbool = (val == FALSE) ? FALSE : TRUE;
231 return TRUE;
232
233 case XDR_ENCODE:
234 val = *kbool ? TRUE : FALSE;
235 return xdr_bool(xdrs, &val);
236
237 case XDR_FREE:
238 return TRUE;
239 }
240
241 return FALSE;
242 }
243
xdr_krb5_key_data_nocontents(XDR * xdrs,krb5_key_data * objp)244 bool_t xdr_krb5_key_data_nocontents(XDR *xdrs, krb5_key_data *objp)
245 {
246 /*
247 * Note that this function intentionally DOES NOT transfer key
248 * length or contents! xdr_krb5_key_data in adb_xdr.c does, but
249 * that is only for use within the server-side library.
250 */
251 unsigned int tmp;
252
253 if (xdrs->x_op == XDR_DECODE)
254 memset(objp, 0, sizeof(krb5_key_data));
255
256 if (!xdr_krb5_int16(xdrs, &objp->key_data_ver)) {
257 return (FALSE);
258 }
259 if (!xdr_krb5_ui_2(xdrs, &objp->key_data_kvno)) {
260 return (FALSE);
261 }
262 if (!xdr_krb5_int16(xdrs, &objp->key_data_type[0])) {
263 return (FALSE);
264 }
265 if (objp->key_data_ver > 1) {
266 if (!xdr_krb5_int16(xdrs, &objp->key_data_type[1])) {
267 return (FALSE);
268 }
269 }
270 /*
271 * kadm5_get_principal on the server side allocates and returns
272 * key contents when asked. Even though this function refuses to
273 * transmit that data, it still has to *free* the data at the
274 * appropriate time to avoid a memory leak.
275 */
276 if (xdrs->x_op == XDR_FREE) {
277 tmp = (unsigned int) objp->key_data_length[0];
278 if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[0],
279 &tmp, ~0))
280 return FALSE;
281
282 tmp = (unsigned int) objp->key_data_length[1];
283 if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[1],
284 &tmp, ~0))
285 return FALSE;
286 }
287
288 return (TRUE);
289 }
290
291
292 bool_t
xdr_krb5_key_salt_tuple(XDR * xdrs,krb5_key_salt_tuple * objp)293 xdr_krb5_key_salt_tuple(XDR *xdrs, krb5_key_salt_tuple *objp)
294 {
295 if (!xdr_krb5_enctype(xdrs, &objp->ks_enctype))
296 return FALSE;
297 if (!xdr_krb5_salttype(xdrs, &objp->ks_salttype))
298 return FALSE;
299 return TRUE;
300 }
301
xdr_krb5_tl_data(XDR * xdrs,krb5_tl_data ** tl_data_head)302 bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
303 {
304 krb5_tl_data *tl, *tl2;
305 bool_t more;
306 unsigned int len;
307
308 switch (xdrs->x_op) {
309 case XDR_FREE:
310 tl = tl2 = *tl_data_head;
311 while (tl) {
312 tl2 = tl->tl_data_next;
313 free(tl->tl_data_contents);
314 free(tl);
315 tl = tl2;
316 }
317 *tl_data_head = NULL;
318 break;
319
320 case XDR_ENCODE:
321 tl = *tl_data_head;
322 while (1) {
323 more = (tl != NULL);
324 if (!xdr_bool(xdrs, &more))
325 return FALSE;
326 if (tl == NULL)
327 break;
328 if (!xdr_krb5_int16(xdrs, &tl->tl_data_type))
329 return FALSE;
330 len = tl->tl_data_length;
331 if (!xdr_bytes(xdrs, (char **) &tl->tl_data_contents, &len, ~0))
332 return FALSE;
333 tl = tl->tl_data_next;
334 }
335 break;
336
337 case XDR_DECODE:
338 tl = NULL;
339 while (1) {
340 if (!xdr_bool(xdrs, &more))
341 return FALSE;
342 if (more == FALSE)
343 break;
344 tl2 = (krb5_tl_data *) malloc(sizeof(krb5_tl_data));
345 if (tl2 == NULL)
346 return FALSE;
347 memset(tl2, 0, sizeof(krb5_tl_data));
348 if (!xdr_krb5_int16(xdrs, &tl2->tl_data_type))
349 return FALSE;
350 if (!xdr_bytes(xdrs, (char **)&tl2->tl_data_contents, &len, ~0))
351 return FALSE;
352 tl2->tl_data_length = len;
353
354 tl2->tl_data_next = tl;
355 tl = tl2;
356 }
357
358 *tl_data_head = tl;
359 break;
360 }
361
362 return TRUE;
363 }
364
365 bool_t
xdr_kadm5_ret_t(XDR * xdrs,kadm5_ret_t * objp)366 xdr_kadm5_ret_t(XDR *xdrs, kadm5_ret_t *objp)
367 {
368 uint32_t tmp;
369
370 if (xdrs->x_op == XDR_ENCODE)
371 tmp = (uint32_t) *objp;
372
373 if (!xdr_u_int32(xdrs, &tmp))
374 return (FALSE);
375
376 if (xdrs->x_op == XDR_DECODE)
377 *objp = (kadm5_ret_t) tmp;
378
379 return (TRUE);
380 }
381
xdr_kadm5_principal_ent_rec(XDR * xdrs,kadm5_principal_ent_rec * objp)382 bool_t xdr_kadm5_principal_ent_rec(XDR *xdrs,
383 kadm5_principal_ent_rec *objp)
384 {
385 return _xdr_kadm5_principal_ent_rec(xdrs, objp, KADM5_API_VERSION_3);
386 }
387
388 static bool_t
_xdr_kadm5_principal_ent_rec(XDR * xdrs,kadm5_principal_ent_rec * objp,int v)389 _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
390 int v)
391 {
392 unsigned int n;
393 bool_t r;
394
395 if (!xdr_krb5_principal(xdrs, &objp->principal)) {
396 return (FALSE);
397 }
398 if (!xdr_krb5_timestamp(xdrs, &objp->princ_expire_time)) {
399 return (FALSE);
400 }
401 if (!xdr_krb5_timestamp(xdrs, &objp->last_pwd_change)) {
402 return (FALSE);
403 }
404 if (!xdr_krb5_timestamp(xdrs, &objp->pw_expiration)) {
405 return (FALSE);
406 }
407 if (!xdr_krb5_deltat(xdrs, &objp->max_life)) {
408 return (FALSE);
409 }
410 if (!xdr_nulltype(xdrs, (void **) &objp->mod_name,
411 xdr_krb5_principal)) {
412 return (FALSE);
413 }
414 if (!xdr_krb5_timestamp(xdrs, &objp->mod_date)) {
415 return (FALSE);
416 }
417 if (!xdr_krb5_flags(xdrs, &objp->attributes)) {
418 return (FALSE);
419 }
420 if (!xdr_krb5_kvno(xdrs, &objp->kvno)) {
421 return (FALSE);
422 }
423 if (!xdr_krb5_kvno(xdrs, &objp->mkvno)) {
424 return (FALSE);
425 }
426 if (!xdr_nullstring(xdrs, &objp->policy)) {
427 return (FALSE);
428 }
429 if (!xdr_long(xdrs, &objp->aux_attributes)) {
430 return (FALSE);
431 }
432 if (!xdr_krb5_deltat(xdrs, &objp->max_renewable_life)) {
433 return (FALSE);
434 }
435 if (!xdr_krb5_timestamp(xdrs, &objp->last_success)) {
436 return (FALSE);
437 }
438 if (!xdr_krb5_timestamp(xdrs, &objp->last_failed)) {
439 return (FALSE);
440 }
441 if (!xdr_krb5_kvno(xdrs, &objp->fail_auth_count)) {
442 return (FALSE);
443 }
444 if (!xdr_krb5_int16(xdrs, &objp->n_key_data)) {
445 return (FALSE);
446 }
447 if (xdrs->x_op == XDR_DECODE && objp->n_key_data < 0) {
448 return (FALSE);
449 }
450 if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) {
451 return (FALSE);
452 }
453 if (!xdr_nulltype(xdrs, (void **) &objp->tl_data,
454 xdr_krb5_tl_data)) {
455 return FALSE;
456 }
457 n = objp->n_key_data;
458 r = xdr_array(xdrs, (caddr_t *) &objp->key_data, &n, objp->n_key_data,
459 sizeof(krb5_key_data), xdr_krb5_key_data_nocontents);
460 objp->n_key_data = n;
461 if (!r) {
462 return (FALSE);
463 }
464
465 return (TRUE);
466 }
467
468 static bool_t
_xdr_kadm5_policy_ent_rec(XDR * xdrs,kadm5_policy_ent_rec * objp,int vers)469 _xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp, int vers)
470 {
471 if (!xdr_nullstring(xdrs, &objp->policy)) {
472 return (FALSE);
473 }
474 /* these all used to be u_int32, but it's stupid for sized types
475 to be exposed at the api, and they're the same as longs on the
476 wire. */
477 if (!xdr_long(xdrs, &objp->pw_min_life)) {
478 return (FALSE);
479 }
480 if (!xdr_long(xdrs, &objp->pw_max_life)) {
481 return (FALSE);
482 }
483 if (!xdr_long(xdrs, &objp->pw_min_length)) {
484 return (FALSE);
485 }
486 if (!xdr_long(xdrs, &objp->pw_min_classes)) {
487 return (FALSE);
488 }
489 if (!xdr_long(xdrs, &objp->pw_history_num)) {
490 return (FALSE);
491 }
492 if (!xdr_long(xdrs, &objp->policy_refcnt)) {
493 return (FALSE);
494 }
495 if (xdrs->x_op == XDR_DECODE) {
496 objp->pw_max_fail = 0;
497 objp->pw_failcnt_interval = 0;
498 objp->pw_lockout_duration = 0;
499 objp->attributes = 0;
500 objp->max_life = 0;
501 objp->max_renewable_life = 0;
502 objp->allowed_keysalts = NULL;
503 objp->n_tl_data = 0;
504 objp->tl_data = NULL;
505 }
506 if (vers >= KADM5_API_VERSION_3) {
507 if (!xdr_krb5_kvno(xdrs, &objp->pw_max_fail))
508 return (FALSE);
509 if (!xdr_krb5_deltat(xdrs, &objp->pw_failcnt_interval))
510 return (FALSE);
511 if (!xdr_krb5_deltat(xdrs, &objp->pw_lockout_duration))
512 return (FALSE);
513 }
514 if (vers >= KADM5_API_VERSION_4) {
515 if (!xdr_krb5_flags(xdrs, &objp->attributes)) {
516 return (FALSE);
517 }
518 if (!xdr_krb5_deltat(xdrs, &objp->max_life)) {
519 return (FALSE);
520 }
521 if (!xdr_krb5_deltat(xdrs, &objp->max_renewable_life)) {
522 return (FALSE);
523 }
524 if (!xdr_nullstring(xdrs, &objp->allowed_keysalts)) {
525 return (FALSE);
526 }
527 if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) {
528 return (FALSE);
529 }
530 if (!xdr_nulltype(xdrs, (void **) &objp->tl_data,
531 xdr_krb5_tl_data)) {
532 return FALSE;
533 }
534 }
535 return (TRUE);
536 }
537
538 bool_t
xdr_kadm5_policy_ent_rec(XDR * xdrs,kadm5_policy_ent_rec * objp)539 xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp)
540 {
541 return _xdr_kadm5_policy_ent_rec(xdrs, objp, KADM5_API_VERSION_4);
542 }
543
544 bool_t
xdr_cprinc_arg(XDR * xdrs,cprinc_arg * objp)545 xdr_cprinc_arg(XDR *xdrs, cprinc_arg *objp)
546 {
547 if (!xdr_ui_4(xdrs, &objp->api_version)) {
548 return (FALSE);
549 }
550 if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
551 objp->api_version)) {
552 return (FALSE);
553 }
554 if (!xdr_long(xdrs, &objp->mask)) {
555 return (FALSE);
556 }
557 if (!xdr_nullstring(xdrs, &objp->passwd)) {
558 return (FALSE);
559 }
560 return (TRUE);
561 }
562
563 bool_t
xdr_cprinc3_arg(XDR * xdrs,cprinc3_arg * objp)564 xdr_cprinc3_arg(XDR *xdrs, cprinc3_arg *objp)
565 {
566 if (!xdr_ui_4(xdrs, &objp->api_version)) {
567 return (FALSE);
568 }
569 if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
570 objp->api_version)) {
571 return (FALSE);
572 }
573 if (!xdr_long(xdrs, &objp->mask)) {
574 return (FALSE);
575 }
576 if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
577 (unsigned int *)&objp->n_ks_tuple, ~0,
578 sizeof(krb5_key_salt_tuple),
579 xdr_krb5_key_salt_tuple)) {
580 return (FALSE);
581 }
582 if (!xdr_nullstring(xdrs, &objp->passwd)) {
583 return (FALSE);
584 }
585 return (TRUE);
586 }
587
588 bool_t
xdr_generic_ret(XDR * xdrs,generic_ret * objp)589 xdr_generic_ret(XDR *xdrs, generic_ret *objp)
590 {
591 if (!xdr_ui_4(xdrs, &objp->api_version)) {
592 return (FALSE);
593 }
594 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
595 return (FALSE);
596 }
597
598 return(TRUE);
599 }
600
601 bool_t
xdr_dprinc_arg(XDR * xdrs,dprinc_arg * objp)602 xdr_dprinc_arg(XDR *xdrs, dprinc_arg *objp)
603 {
604 if (!xdr_ui_4(xdrs, &objp->api_version)) {
605 return (FALSE);
606 }
607 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
608 return (FALSE);
609 }
610 return (TRUE);
611 }
612
613 bool_t
xdr_mprinc_arg(XDR * xdrs,mprinc_arg * objp)614 xdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp)
615 {
616 if (!xdr_ui_4(xdrs, &objp->api_version)) {
617 return (FALSE);
618 }
619 if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
620 objp->api_version)) {
621 return (FALSE);
622 }
623 if (!xdr_long(xdrs, &objp->mask)) {
624 return (FALSE);
625 }
626 return (TRUE);
627 }
628
629 bool_t
xdr_rprinc_arg(XDR * xdrs,rprinc_arg * objp)630 xdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp)
631 {
632 if (!xdr_ui_4(xdrs, &objp->api_version)) {
633 return (FALSE);
634 }
635 if (!xdr_krb5_principal(xdrs, &objp->src)) {
636 return (FALSE);
637 }
638 if (!xdr_krb5_principal(xdrs, &objp->dest)) {
639 return (FALSE);
640 }
641 return (TRUE);
642 }
643
644 bool_t
xdr_gprincs_arg(XDR * xdrs,gprincs_arg * objp)645 xdr_gprincs_arg(XDR *xdrs, gprincs_arg *objp)
646 {
647 if (!xdr_ui_4(xdrs, &objp->api_version)) {
648 return (FALSE);
649 }
650 if (!xdr_nullstring(xdrs, &objp->exp)) {
651 return (FALSE);
652 }
653 return (TRUE);
654 }
655
656 bool_t
xdr_gprincs_ret(XDR * xdrs,gprincs_ret * objp)657 xdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp)
658 {
659 if (!xdr_ui_4(xdrs, &objp->api_version)) {
660 return (FALSE);
661 }
662 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
663 return (FALSE);
664 }
665 if (objp->code == KADM5_OK) {
666 if (!xdr_int(xdrs, &objp->count)) {
667 return (FALSE);
668 }
669 if (!xdr_array(xdrs, (caddr_t *) &objp->princs,
670 (unsigned int *) &objp->count, ~0,
671 sizeof(char *), xdr_nullstring)) {
672 return (FALSE);
673 }
674 }
675
676 return (TRUE);
677 }
678
679 bool_t
xdr_chpass_arg(XDR * xdrs,chpass_arg * objp)680 xdr_chpass_arg(XDR *xdrs, chpass_arg *objp)
681 {
682 if (!xdr_ui_4(xdrs, &objp->api_version)) {
683 return (FALSE);
684 }
685 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
686 return (FALSE);
687 }
688 if (!xdr_nullstring(xdrs, &objp->pass)) {
689 return (FALSE);
690 }
691 return (TRUE);
692 }
693
694 bool_t
xdr_chpass3_arg(XDR * xdrs,chpass3_arg * objp)695 xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp)
696 {
697 if (!xdr_ui_4(xdrs, &objp->api_version)) {
698 return (FALSE);
699 }
700 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
701 return (FALSE);
702 }
703 if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
704 return (FALSE);
705 }
706 if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
707 (unsigned int*)&objp->n_ks_tuple, ~0,
708 sizeof(krb5_key_salt_tuple),
709 xdr_krb5_key_salt_tuple)) {
710 return (FALSE);
711 }
712 if (!xdr_nullstring(xdrs, &objp->pass)) {
713 return (FALSE);
714 }
715 return (TRUE);
716 }
717
718 bool_t
xdr_setkey_arg(XDR * xdrs,setkey_arg * objp)719 xdr_setkey_arg(XDR *xdrs, setkey_arg *objp)
720 {
721 if (!xdr_ui_4(xdrs, &objp->api_version)) {
722 return (FALSE);
723 }
724 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
725 return (FALSE);
726 }
727 if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
728 (unsigned int *) &objp->n_keys, ~0,
729 sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
730 return (FALSE);
731 }
732 return (TRUE);
733 }
734
735 bool_t
xdr_setkey3_arg(XDR * xdrs,setkey3_arg * objp)736 xdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp)
737 {
738 if (!xdr_ui_4(xdrs, &objp->api_version)) {
739 return (FALSE);
740 }
741 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
742 return (FALSE);
743 }
744 if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
745 return (FALSE);
746 }
747 if (!xdr_array(xdrs, (caddr_t *) &objp->ks_tuple,
748 (unsigned int *) &objp->n_ks_tuple, ~0,
749 sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) {
750 return (FALSE);
751 }
752 if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
753 (unsigned int *) &objp->n_keys, ~0,
754 sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
755 return (FALSE);
756 }
757 return (TRUE);
758 }
759
760 bool_t
xdr_setkey4_arg(XDR * xdrs,setkey4_arg * objp)761 xdr_setkey4_arg(XDR *xdrs, setkey4_arg *objp)
762 {
763 if (!xdr_ui_4(xdrs, &objp->api_version)) {
764 return FALSE;
765 }
766 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
767 return FALSE;
768 }
769 if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
770 return FALSE;
771 }
772 if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
773 (unsigned int *) &objp->n_key_data, ~0,
774 sizeof(kadm5_key_data), xdr_kadm5_key_data)) {
775 return FALSE;
776 }
777 return TRUE;
778 }
779
780 bool_t
xdr_chrand_arg(XDR * xdrs,chrand_arg * objp)781 xdr_chrand_arg(XDR *xdrs, chrand_arg *objp)
782 {
783 if (!xdr_ui_4(xdrs, &objp->api_version)) {
784 return (FALSE);
785 }
786 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
787 return (FALSE);
788 }
789 return (TRUE);
790 }
791
792 bool_t
xdr_chrand3_arg(XDR * xdrs,chrand3_arg * objp)793 xdr_chrand3_arg(XDR *xdrs, chrand3_arg *objp)
794 {
795 if (!xdr_ui_4(xdrs, &objp->api_version)) {
796 return (FALSE);
797 }
798 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
799 return (FALSE);
800 }
801 if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
802 return (FALSE);
803 }
804 if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
805 (unsigned int*)&objp->n_ks_tuple, ~0,
806 sizeof(krb5_key_salt_tuple),
807 xdr_krb5_key_salt_tuple)) {
808 return (FALSE);
809 }
810 return (TRUE);
811 }
812
813 bool_t
xdr_chrand_ret(XDR * xdrs,chrand_ret * objp)814 xdr_chrand_ret(XDR *xdrs, chrand_ret *objp)
815 {
816 if (!xdr_ui_4(xdrs, &objp->api_version)) {
817 return (FALSE);
818 }
819 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
820 return (FALSE);
821 }
822 if (objp->code == KADM5_OK) {
823 if (!xdr_array(xdrs, (char **)&objp->keys,
824 (unsigned int *)&objp->n_keys, ~0,
825 sizeof(krb5_keyblock), xdr_krb5_keyblock))
826 return FALSE;
827 }
828
829 return (TRUE);
830 }
831
832 bool_t
xdr_gprinc_arg(XDR * xdrs,gprinc_arg * objp)833 xdr_gprinc_arg(XDR *xdrs, gprinc_arg *objp)
834 {
835 if (!xdr_ui_4(xdrs, &objp->api_version)) {
836 return (FALSE);
837 }
838 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
839 return (FALSE);
840 }
841 if (!xdr_long(xdrs, &objp->mask)) {
842 return FALSE;
843 }
844
845 return (TRUE);
846 }
847
848 bool_t
xdr_gprinc_ret(XDR * xdrs,gprinc_ret * objp)849 xdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp)
850 {
851 if (!xdr_ui_4(xdrs, &objp->api_version)) {
852 return (FALSE);
853 }
854 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
855 return (FALSE);
856 }
857 if(objp->code == KADM5_OK) {
858 if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
859 objp->api_version)) {
860 return (FALSE);
861 }
862 }
863
864 return (TRUE);
865 }
866
867 bool_t
xdr_cpol_arg(XDR * xdrs,cpol_arg * objp)868 xdr_cpol_arg(XDR *xdrs, cpol_arg *objp)
869 {
870 if (!xdr_ui_4(xdrs, &objp->api_version)) {
871 return (FALSE);
872 }
873 if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
874 objp->api_version)) {
875 return (FALSE);
876 }
877 if (!xdr_long(xdrs, &objp->mask)) {
878 return (FALSE);
879 }
880 return (TRUE);
881 }
882
883 bool_t
xdr_dpol_arg(XDR * xdrs,dpol_arg * objp)884 xdr_dpol_arg(XDR *xdrs, dpol_arg *objp)
885 {
886 if (!xdr_ui_4(xdrs, &objp->api_version)) {
887 return (FALSE);
888 }
889 if (!xdr_nullstring(xdrs, &objp->name)) {
890 return (FALSE);
891 }
892 return (TRUE);
893 }
894
895 bool_t
xdr_mpol_arg(XDR * xdrs,mpol_arg * objp)896 xdr_mpol_arg(XDR *xdrs, mpol_arg *objp)
897 {
898 if (!xdr_ui_4(xdrs, &objp->api_version)) {
899 return (FALSE);
900 }
901 if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
902 objp->api_version)) {
903 return (FALSE);
904 }
905 if (!xdr_long(xdrs, &objp->mask)) {
906 return (FALSE);
907 }
908 return (TRUE);
909 }
910
911 bool_t
xdr_gpol_arg(XDR * xdrs,gpol_arg * objp)912 xdr_gpol_arg(XDR *xdrs, gpol_arg *objp)
913 {
914 if (!xdr_ui_4(xdrs, &objp->api_version)) {
915 return (FALSE);
916 }
917 if (!xdr_nullstring(xdrs, &objp->name)) {
918 return (FALSE);
919 }
920 return (TRUE);
921 }
922
923 bool_t
xdr_gpol_ret(XDR * xdrs,gpol_ret * objp)924 xdr_gpol_ret(XDR *xdrs, gpol_ret *objp)
925 {
926 if (!xdr_ui_4(xdrs, &objp->api_version)) {
927 return (FALSE);
928 }
929 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
930 return (FALSE);
931 }
932 if(objp->code == KADM5_OK) {
933 if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
934 objp->api_version))
935 return (FALSE);
936 }
937
938 return (TRUE);
939 }
940
941 bool_t
xdr_gpols_arg(XDR * xdrs,gpols_arg * objp)942 xdr_gpols_arg(XDR *xdrs, gpols_arg *objp)
943 {
944 if (!xdr_ui_4(xdrs, &objp->api_version)) {
945 return (FALSE);
946 }
947 if (!xdr_nullstring(xdrs, &objp->exp)) {
948 return (FALSE);
949 }
950 return (TRUE);
951 }
952
953 bool_t
xdr_gpols_ret(XDR * xdrs,gpols_ret * objp)954 xdr_gpols_ret(XDR *xdrs, gpols_ret *objp)
955 {
956 if (!xdr_ui_4(xdrs, &objp->api_version)) {
957 return (FALSE);
958 }
959 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
960 return (FALSE);
961 }
962 if (objp->code == KADM5_OK) {
963 if (!xdr_int(xdrs, &objp->count)) {
964 return (FALSE);
965 }
966 if (!xdr_array(xdrs, (caddr_t *) &objp->pols,
967 (unsigned int *) &objp->count, ~0,
968 sizeof(char *), xdr_nullstring)) {
969 return (FALSE);
970 }
971 }
972
973 return (TRUE);
974 }
975
xdr_getprivs_ret(XDR * xdrs,getprivs_ret * objp)976 bool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp)
977 {
978 if (!xdr_ui_4(xdrs, &objp->api_version)) {
979 return (FALSE);
980 }
981 if (! xdr_kadm5_ret_t(xdrs, &objp->code) ||
982 ! xdr_long(xdrs, &objp->privs))
983 return FALSE;
984
985 return TRUE;
986 }
987
988 bool_t
xdr_purgekeys_arg(XDR * xdrs,purgekeys_arg * objp)989 xdr_purgekeys_arg(XDR *xdrs, purgekeys_arg *objp)
990 {
991 if (!xdr_ui_4(xdrs, &objp->api_version)) {
992 return (FALSE);
993 }
994 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
995 return (FALSE);
996 }
997 if (!xdr_int(xdrs, &objp->keepkvno)) {
998 return FALSE;
999 }
1000
1001 return (TRUE);
1002 }
1003
1004 bool_t
xdr_gstrings_arg(XDR * xdrs,gstrings_arg * objp)1005 xdr_gstrings_arg(XDR *xdrs, gstrings_arg *objp)
1006 {
1007 if (!xdr_ui_4(xdrs, &objp->api_version)) {
1008 return (FALSE);
1009 }
1010 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
1011 return (FALSE);
1012 }
1013
1014 return (TRUE);
1015 }
1016
1017 bool_t
xdr_gstrings_ret(XDR * xdrs,gstrings_ret * objp)1018 xdr_gstrings_ret(XDR *xdrs, gstrings_ret *objp)
1019 {
1020 if (!xdr_ui_4(xdrs, &objp->api_version)) {
1021 return (FALSE);
1022 }
1023 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
1024 return (FALSE);
1025 }
1026 if (objp->code == KADM5_OK) {
1027 if (!xdr_int(xdrs, &objp->count)) {
1028 return (FALSE);
1029 }
1030 if (!xdr_array(xdrs, (caddr_t *) &objp->strings,
1031 (unsigned int *) &objp->count, ~0,
1032 sizeof(krb5_string_attr),
1033 xdr_krb5_string_attr)) {
1034 return (FALSE);
1035 }
1036 }
1037
1038 return (TRUE);
1039 }
1040
1041 bool_t
xdr_sstring_arg(XDR * xdrs,sstring_arg * objp)1042 xdr_sstring_arg(XDR *xdrs, sstring_arg *objp)
1043 {
1044 if (!xdr_ui_4(xdrs, &objp->api_version)) {
1045 return (FALSE);
1046 }
1047 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
1048 return (FALSE);
1049 }
1050 if (!xdr_nullstring(xdrs, &objp->key)) {
1051 return (FALSE);
1052 }
1053 if (!xdr_nullstring(xdrs, &objp->value)) {
1054 return (FALSE);
1055 }
1056
1057 return (TRUE);
1058 }
1059
1060 bool_t
xdr_krb5_principal(XDR * xdrs,krb5_principal * objp)1061 xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
1062 {
1063 int ret;
1064 char *p = NULL;
1065 krb5_principal pr = NULL;
1066 static krb5_context context = NULL;
1067
1068 /* using a static context here is ugly, but should work
1069 ok, and the other solutions are even uglier */
1070
1071 if (!context &&
1072 kadm5_init_krb5_context(&context))
1073 return(FALSE);
1074
1075 switch(xdrs->x_op) {
1076 case XDR_ENCODE:
1077 if (*objp) {
1078 if((ret = krb5_unparse_name(context, *objp, &p)) != 0)
1079 return FALSE;
1080 }
1081 if(!xdr_nullstring(xdrs, &p))
1082 return FALSE;
1083 if (p) free(p);
1084 break;
1085 case XDR_DECODE:
1086 if(!xdr_nullstring(xdrs, &p))
1087 return FALSE;
1088 if (p) {
1089 ret = krb5_parse_name(context, p, &pr);
1090 if(ret != 0)
1091 return FALSE;
1092 *objp = pr;
1093 free(p);
1094 } else
1095 *objp = NULL;
1096 break;
1097 case XDR_FREE:
1098 if(*objp != NULL)
1099 krb5_free_principal(context, *objp);
1100 *objp = NULL;
1101 break;
1102 }
1103 return TRUE;
1104 }
1105
1106 bool_t
xdr_krb5_octet(XDR * xdrs,krb5_octet * objp)1107 xdr_krb5_octet(XDR *xdrs, krb5_octet *objp)
1108 {
1109 if (!xdr_u_char(xdrs, objp))
1110 return (FALSE);
1111 return (TRUE);
1112 }
1113
1114 bool_t
xdr_krb5_enctype(XDR * xdrs,krb5_enctype * objp)1115 xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp)
1116 {
1117 if (!xdr_int32(xdrs, (int32_t *) objp))
1118 return (FALSE);
1119 return (TRUE);
1120 }
1121
1122 bool_t
xdr_krb5_salttype(XDR * xdrs,krb5_int32 * objp)1123 xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp)
1124 {
1125 if (!xdr_int32(xdrs, (int32_t *) objp))
1126 return FALSE;
1127 return TRUE;
1128 }
1129
1130 bool_t
xdr_krb5_keyblock(XDR * xdrs,krb5_keyblock * objp)1131 xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp)
1132 {
1133 char *cp;
1134
1135 /* XXX This only works because free_keyblock assumes ->contents
1136 is allocated by malloc() */
1137 if(!xdr_krb5_enctype(xdrs, &objp->enctype))
1138 return FALSE;
1139 cp = (char *)objp->contents;
1140 if(!xdr_bytes(xdrs, &cp, &objp->length, ~0))
1141 return FALSE;
1142 objp->contents = (uint8_t *)cp;
1143 return TRUE;
1144 }
1145
1146 bool_t
xdr_krb5_string_attr(XDR * xdrs,krb5_string_attr * objp)1147 xdr_krb5_string_attr(XDR *xdrs, krb5_string_attr *objp)
1148 {
1149 if (!xdr_nullstring(xdrs, &objp->key))
1150 return FALSE;
1151 if (!xdr_nullstring(xdrs, &objp->value))
1152 return FALSE;
1153 if (xdrs->x_op == XDR_DECODE &&
1154 (objp->key == NULL || objp->value == NULL))
1155 return FALSE;
1156 return TRUE;
1157 }
1158
1159 bool_t
xdr_kadm5_key_data(XDR * xdrs,kadm5_key_data * objp)1160 xdr_kadm5_key_data(XDR *xdrs, kadm5_key_data *objp)
1161 {
1162 if (!xdr_krb5_kvno(xdrs, &objp->kvno))
1163 return FALSE;
1164 if (!xdr_krb5_keyblock(xdrs, &objp->key))
1165 return FALSE;
1166 if (!xdr_krb5_int16(xdrs, &objp->salt.type))
1167 return FALSE;
1168 if (!xdr_bytes(xdrs, &objp->salt.data.data,
1169 &objp->salt.data.length, ~0))
1170 return FALSE;
1171 return TRUE;
1172 }
1173
1174 bool_t
xdr_getpkeys_arg(XDR * xdrs,getpkeys_arg * objp)1175 xdr_getpkeys_arg(XDR *xdrs, getpkeys_arg *objp)
1176 {
1177 if (!xdr_ui_4(xdrs, &objp->api_version)) {
1178 return FALSE;
1179 }
1180 if (!xdr_krb5_principal(xdrs, &objp->princ)) {
1181 return FALSE;
1182 }
1183 if (!xdr_krb5_kvno(xdrs, &objp->kvno)) {
1184 return FALSE;
1185 }
1186 return TRUE;
1187 }
1188
1189 bool_t
xdr_getpkeys_ret(XDR * xdrs,getpkeys_ret * objp)1190 xdr_getpkeys_ret(XDR *xdrs, getpkeys_ret *objp)
1191 {
1192 if (!xdr_ui_4(xdrs, &objp->api_version)) {
1193 return FALSE;
1194 }
1195 if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
1196 return FALSE;
1197 }
1198 if (objp->code == KADM5_OK) {
1199 if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
1200 (unsigned int *) &objp->n_key_data, ~0,
1201 sizeof(kadm5_key_data), xdr_kadm5_key_data)) {
1202 return FALSE;
1203 }
1204 }
1205 return TRUE;
1206 }
1207