xref: /freebsd/crypto/krb5/src/lib/kadm5/kadm_rpc_xdr.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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