xref: /freebsd/crypto/krb5/src/lib/kadm5/kadm_rpc_xdr.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
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 			  (xdrproc_t)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 			  (xdrproc_t)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),
460 		      (xdrproc_t)xdr_krb5_key_data_nocontents);
461 	objp->n_key_data = n;
462 	if (!r) {
463 		return (FALSE);
464 	}
465 
466 	return (TRUE);
467 }
468 
469 static bool_t
_xdr_kadm5_policy_ent_rec(XDR * xdrs,kadm5_policy_ent_rec * objp,int vers)470 _xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp, int vers)
471 {
472 	if (!xdr_nullstring(xdrs, &objp->policy)) {
473 		return (FALSE);
474 	}
475 	/* these all used to be u_int32, but it's stupid for sized types
476 	   to be exposed at the api, and they're the same as longs on the
477 	   wire. */
478 	if (!xdr_long(xdrs, &objp->pw_min_life)) {
479 		return (FALSE);
480 	}
481 	if (!xdr_long(xdrs, &objp->pw_max_life)) {
482 		return (FALSE);
483 	}
484 	if (!xdr_long(xdrs, &objp->pw_min_length)) {
485 		return (FALSE);
486 	}
487 	if (!xdr_long(xdrs, &objp->pw_min_classes)) {
488 		return (FALSE);
489 	}
490 	if (!xdr_long(xdrs, &objp->pw_history_num)) {
491 		return (FALSE);
492 	}
493 	if (!xdr_long(xdrs, &objp->policy_refcnt)) {
494 		return (FALSE);
495 	}
496 	if (xdrs->x_op == XDR_DECODE) {
497 		objp->pw_max_fail = 0;
498 		objp->pw_failcnt_interval = 0;
499 		objp->pw_lockout_duration = 0;
500 		objp->attributes = 0;
501 		objp->max_life = 0;
502 		objp->max_renewable_life = 0;
503 		objp->allowed_keysalts = NULL;
504 		objp->n_tl_data = 0;
505 		objp->tl_data = NULL;
506 	}
507 	if (vers >= KADM5_API_VERSION_3) {
508 		if (!xdr_krb5_kvno(xdrs, &objp->pw_max_fail))
509 			return (FALSE);
510 		if (!xdr_krb5_deltat(xdrs, &objp->pw_failcnt_interval))
511 			return (FALSE);
512 		if (!xdr_krb5_deltat(xdrs, &objp->pw_lockout_duration))
513 			return (FALSE);
514 	}
515 	if (vers >= KADM5_API_VERSION_4) {
516 		if (!xdr_krb5_flags(xdrs, &objp->attributes)) {
517 			return (FALSE);
518 		}
519 		if (!xdr_krb5_deltat(xdrs, &objp->max_life)) {
520 			return (FALSE);
521 		}
522 		if (!xdr_krb5_deltat(xdrs, &objp->max_renewable_life)) {
523 			return (FALSE);
524 		}
525 		if (!xdr_nullstring(xdrs, &objp->allowed_keysalts)) {
526 			return (FALSE);
527 		}
528 		if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) {
529 			return (FALSE);
530 		}
531 		if (!xdr_nulltype(xdrs, (void **) &objp->tl_data,
532 				  (xdrproc_t)xdr_krb5_tl_data)) {
533 			return FALSE;
534 		}
535 	}
536 	return (TRUE);
537 }
538 
539 bool_t
xdr_kadm5_policy_ent_rec(XDR * xdrs,kadm5_policy_ent_rec * objp)540 xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp)
541 {
542 	return _xdr_kadm5_policy_ent_rec(xdrs, objp, KADM5_API_VERSION_4);
543 }
544 
545 bool_t
xdr_cprinc_arg(XDR * xdrs,cprinc_arg * objp)546 xdr_cprinc_arg(XDR *xdrs, cprinc_arg *objp)
547 {
548 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
549 		return (FALSE);
550 	}
551 	if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
552 					  objp->api_version)) {
553 		return (FALSE);
554 	}
555 	if (!xdr_long(xdrs, &objp->mask)) {
556 		return (FALSE);
557 	}
558 	if (!xdr_nullstring(xdrs, &objp->passwd)) {
559 		return (FALSE);
560 	}
561 	return (TRUE);
562 }
563 
564 bool_t
xdr_cprinc3_arg(XDR * xdrs,cprinc3_arg * objp)565 xdr_cprinc3_arg(XDR *xdrs, cprinc3_arg *objp)
566 {
567 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
568 		return (FALSE);
569 	}
570 	if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
571 					  objp->api_version)) {
572 		return (FALSE);
573 	}
574 	if (!xdr_long(xdrs, &objp->mask)) {
575 		return (FALSE);
576 	}
577 	if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
578 		       (unsigned int *)&objp->n_ks_tuple, ~0,
579 		       sizeof(krb5_key_salt_tuple),
580 		       (xdrproc_t)xdr_krb5_key_salt_tuple)) {
581 		return (FALSE);
582 	}
583 	if (!xdr_nullstring(xdrs, &objp->passwd)) {
584 		return (FALSE);
585 	}
586 	return (TRUE);
587 }
588 
589 bool_t
xdr_generic_ret(XDR * xdrs,generic_ret * objp)590 xdr_generic_ret(XDR *xdrs, generic_ret *objp)
591 {
592 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
593 		return (FALSE);
594 	}
595 	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
596 		return (FALSE);
597 	}
598 
599 	return(TRUE);
600 }
601 
602 bool_t
xdr_dprinc_arg(XDR * xdrs,dprinc_arg * objp)603 xdr_dprinc_arg(XDR *xdrs, dprinc_arg *objp)
604 {
605 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
606 		return (FALSE);
607 	}
608 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
609 		return (FALSE);
610 	}
611 	return (TRUE);
612 }
613 
614 bool_t
xdr_mprinc_arg(XDR * xdrs,mprinc_arg * objp)615 xdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp)
616 {
617 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
618 		return (FALSE);
619 	}
620 	if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
621 					  objp->api_version)) {
622 		return (FALSE);
623 	}
624 	if (!xdr_long(xdrs, &objp->mask)) {
625 		return (FALSE);
626 	}
627 	return (TRUE);
628 }
629 
630 bool_t
xdr_rprinc_arg(XDR * xdrs,rprinc_arg * objp)631 xdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp)
632 {
633 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
634 		return (FALSE);
635 	}
636 	if (!xdr_krb5_principal(xdrs, &objp->src)) {
637 		return (FALSE);
638 	}
639 	if (!xdr_krb5_principal(xdrs, &objp->dest)) {
640 		return (FALSE);
641 	}
642 	return (TRUE);
643 }
644 
645 bool_t
xdr_gprincs_arg(XDR * xdrs,gprincs_arg * objp)646 xdr_gprincs_arg(XDR *xdrs, gprincs_arg *objp)
647 {
648      if (!xdr_ui_4(xdrs, &objp->api_version)) {
649 	  return (FALSE);
650      }
651      if (!xdr_nullstring(xdrs, &objp->exp)) {
652 	  return (FALSE);
653      }
654      return (TRUE);
655 }
656 
657 bool_t
xdr_gprincs_ret(XDR * xdrs,gprincs_ret * objp)658 xdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp)
659 {
660      if (!xdr_ui_4(xdrs, &objp->api_version)) {
661 	  return (FALSE);
662      }
663      if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
664 	  return (FALSE);
665      }
666      if (objp->code == KADM5_OK) {
667 	  if (!xdr_int(xdrs, &objp->count)) {
668 	       return (FALSE);
669 	  }
670 	  if (!xdr_array(xdrs, (caddr_t *) &objp->princs,
671 			 (unsigned int *) &objp->count, ~0,
672 			 sizeof(char *), (xdrproc_t)xdr_nullstring)) {
673 	       return (FALSE);
674 	  }
675      }
676 
677      return (TRUE);
678 }
679 
680 bool_t
xdr_chpass_arg(XDR * xdrs,chpass_arg * objp)681 xdr_chpass_arg(XDR *xdrs, chpass_arg *objp)
682 {
683 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
684 		return (FALSE);
685 	}
686 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
687 		return (FALSE);
688 	}
689 	if (!xdr_nullstring(xdrs, &objp->pass)) {
690 		return (FALSE);
691 	}
692 	return (TRUE);
693 }
694 
695 bool_t
xdr_chpass3_arg(XDR * xdrs,chpass3_arg * objp)696 xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp)
697 {
698 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
699 		return (FALSE);
700 	}
701 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
702 		return (FALSE);
703 	}
704 	if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
705 		return (FALSE);
706 	}
707 	if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
708 		       (unsigned int*)&objp->n_ks_tuple, ~0,
709 		       sizeof(krb5_key_salt_tuple),
710 		       (xdrproc_t)xdr_krb5_key_salt_tuple)) {
711 		return (FALSE);
712 	}
713 	if (!xdr_nullstring(xdrs, &objp->pass)) {
714 		return (FALSE);
715 	}
716 	return (TRUE);
717 }
718 
719 bool_t
xdr_setkey_arg(XDR * xdrs,setkey_arg * objp)720 xdr_setkey_arg(XDR *xdrs, setkey_arg *objp)
721 {
722 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
723 		return (FALSE);
724 	}
725 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
726 		return (FALSE);
727 	}
728 	if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
729 		       (unsigned int *) &objp->n_keys, ~0,
730 		       sizeof(krb5_keyblock), (xdrproc_t)xdr_krb5_keyblock)) {
731 		return (FALSE);
732 	}
733 	return (TRUE);
734 }
735 
736 bool_t
xdr_setkey3_arg(XDR * xdrs,setkey3_arg * objp)737 xdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp)
738 {
739 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
740 		return (FALSE);
741 	}
742 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
743 		return (FALSE);
744 	}
745 	if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
746 		return (FALSE);
747 	}
748 	if (!xdr_array(xdrs, (caddr_t *) &objp->ks_tuple,
749 		       (unsigned int *) &objp->n_ks_tuple, ~0,
750 		       sizeof(krb5_key_salt_tuple),
751 		       (xdrproc_t)xdr_krb5_key_salt_tuple)) {
752 		return (FALSE);
753 	}
754 	if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
755 		       (unsigned int *) &objp->n_keys, ~0,
756 		       sizeof(krb5_keyblock), (xdrproc_t)xdr_krb5_keyblock)) {
757 		return (FALSE);
758 	}
759 	return (TRUE);
760 }
761 
762 bool_t
xdr_setkey4_arg(XDR * xdrs,setkey4_arg * objp)763 xdr_setkey4_arg(XDR *xdrs, setkey4_arg *objp)
764 {
765 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
766 		return FALSE;
767 	}
768 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
769 		return FALSE;
770 	}
771 	if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
772 		return FALSE;
773 	}
774 	if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
775 		       (unsigned int *) &objp->n_key_data, ~0,
776 		       sizeof(kadm5_key_data),
777 		       (xdrproc_t)xdr_kadm5_key_data)) {
778 		return FALSE;
779 	}
780 	return TRUE;
781 }
782 
783 bool_t
xdr_chrand_arg(XDR * xdrs,chrand_arg * objp)784 xdr_chrand_arg(XDR *xdrs, chrand_arg *objp)
785 {
786 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
787 		return (FALSE);
788 	}
789 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
790 		return (FALSE);
791 	}
792 	return (TRUE);
793 }
794 
795 bool_t
xdr_chrand3_arg(XDR * xdrs,chrand3_arg * objp)796 xdr_chrand3_arg(XDR *xdrs, chrand3_arg *objp)
797 {
798 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
799 		return (FALSE);
800 	}
801 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
802 		return (FALSE);
803 	}
804 	if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
805 		return (FALSE);
806 	}
807 	if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
808 		       (unsigned int*)&objp->n_ks_tuple, ~0,
809 		       sizeof(krb5_key_salt_tuple),
810 		       (xdrproc_t)xdr_krb5_key_salt_tuple)) {
811 		return (FALSE);
812 	}
813 	return (TRUE);
814 }
815 
816 bool_t
xdr_chrand_ret(XDR * xdrs,chrand_ret * objp)817 xdr_chrand_ret(XDR *xdrs, chrand_ret *objp)
818 {
819 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
820 		return (FALSE);
821 	}
822 	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
823 		return (FALSE);
824 	}
825 	if (objp->code == KADM5_OK) {
826 		if (!xdr_array(xdrs, (char **)&objp->keys,
827 			       (unsigned int *)&objp->n_keys, ~0,
828 			       sizeof(krb5_keyblock),
829 			       (xdrproc_t)xdr_krb5_keyblock))
830 			return FALSE;
831 	}
832 
833 	return (TRUE);
834 }
835 
836 bool_t
xdr_gprinc_arg(XDR * xdrs,gprinc_arg * objp)837 xdr_gprinc_arg(XDR *xdrs, gprinc_arg *objp)
838 {
839 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
840 		return (FALSE);
841 	}
842 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
843 		return (FALSE);
844 	}
845 	if (!xdr_long(xdrs, &objp->mask)) {
846 	     return FALSE;
847 	}
848 
849 	return (TRUE);
850 }
851 
852 bool_t
xdr_gprinc_ret(XDR * xdrs,gprinc_ret * objp)853 xdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp)
854 {
855 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
856 		return (FALSE);
857 	}
858 	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
859 		return (FALSE);
860 	}
861 	if(objp->code == KADM5_OK)  {
862 		if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
863 						  objp->api_version)) {
864 			return (FALSE);
865 		}
866 	}
867 
868 	return (TRUE);
869 }
870 
871 bool_t
xdr_cpol_arg(XDR * xdrs,cpol_arg * objp)872 xdr_cpol_arg(XDR *xdrs, cpol_arg *objp)
873 {
874 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
875 		return (FALSE);
876 	}
877 	if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
878 				       objp->api_version)) {
879 		return (FALSE);
880 	}
881 	if (!xdr_long(xdrs, &objp->mask)) {
882 		return (FALSE);
883 	}
884 	return (TRUE);
885 }
886 
887 bool_t
xdr_dpol_arg(XDR * xdrs,dpol_arg * objp)888 xdr_dpol_arg(XDR *xdrs, dpol_arg *objp)
889 {
890 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
891 		return (FALSE);
892 	}
893 	if (!xdr_nullstring(xdrs, &objp->name)) {
894 		return (FALSE);
895 	}
896 	return (TRUE);
897 }
898 
899 bool_t
xdr_mpol_arg(XDR * xdrs,mpol_arg * objp)900 xdr_mpol_arg(XDR *xdrs, mpol_arg *objp)
901 {
902 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
903 		return (FALSE);
904 	}
905 	if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
906 				       objp->api_version)) {
907 		return (FALSE);
908 	}
909 	if (!xdr_long(xdrs, &objp->mask)) {
910 		return (FALSE);
911 	}
912 	return (TRUE);
913 }
914 
915 bool_t
xdr_gpol_arg(XDR * xdrs,gpol_arg * objp)916 xdr_gpol_arg(XDR *xdrs, gpol_arg *objp)
917 {
918 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
919 		return (FALSE);
920 	}
921 	if (!xdr_nullstring(xdrs, &objp->name)) {
922 		return (FALSE);
923 	}
924 	return (TRUE);
925 }
926 
927 bool_t
xdr_gpol_ret(XDR * xdrs,gpol_ret * objp)928 xdr_gpol_ret(XDR *xdrs, gpol_ret *objp)
929 {
930 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
931 		return (FALSE);
932 	}
933 	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
934 		return (FALSE);
935 	}
936 	if(objp->code == KADM5_OK) {
937 	    if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
938 					   objp->api_version))
939 		return (FALSE);
940 	}
941 
942 	return (TRUE);
943 }
944 
945 bool_t
xdr_gpols_arg(XDR * xdrs,gpols_arg * objp)946 xdr_gpols_arg(XDR *xdrs, gpols_arg *objp)
947 {
948      if (!xdr_ui_4(xdrs, &objp->api_version)) {
949 	  return (FALSE);
950      }
951      if (!xdr_nullstring(xdrs, &objp->exp)) {
952 	  return (FALSE);
953      }
954      return (TRUE);
955 }
956 
957 bool_t
xdr_gpols_ret(XDR * xdrs,gpols_ret * objp)958 xdr_gpols_ret(XDR *xdrs, gpols_ret *objp)
959 {
960      if (!xdr_ui_4(xdrs, &objp->api_version)) {
961 	  return (FALSE);
962      }
963      if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
964 	  return (FALSE);
965      }
966      if (objp->code == KADM5_OK) {
967 	  if (!xdr_int(xdrs, &objp->count)) {
968 	       return (FALSE);
969 	  }
970 	  if (!xdr_array(xdrs, (caddr_t *) &objp->pols,
971 			 (unsigned int *) &objp->count, ~0,
972 			 sizeof(char *), (xdrproc_t)xdr_nullstring)) {
973 	       return (FALSE);
974 	  }
975      }
976 
977      return (TRUE);
978 }
979 
xdr_getprivs_ret(XDR * xdrs,getprivs_ret * objp)980 bool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp)
981 {
982 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
983 		return (FALSE);
984 	}
985      if (! xdr_kadm5_ret_t(xdrs, &objp->code) ||
986 	 ! xdr_long(xdrs, &objp->privs))
987 	  return FALSE;
988 
989      return TRUE;
990 }
991 
992 bool_t
xdr_purgekeys_arg(XDR * xdrs,purgekeys_arg * objp)993 xdr_purgekeys_arg(XDR *xdrs, purgekeys_arg *objp)
994 {
995 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
996 		return (FALSE);
997 	}
998 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
999 		return (FALSE);
1000 	}
1001 	if (!xdr_int(xdrs, &objp->keepkvno)) {
1002 	     return FALSE;
1003 	}
1004 
1005 	return (TRUE);
1006 }
1007 
1008 bool_t
xdr_gstrings_arg(XDR * xdrs,gstrings_arg * objp)1009 xdr_gstrings_arg(XDR *xdrs, gstrings_arg *objp)
1010 {
1011 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
1012 		return (FALSE);
1013 	}
1014 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
1015 		return (FALSE);
1016 	}
1017 
1018 	return (TRUE);
1019 }
1020 
1021 bool_t
xdr_gstrings_ret(XDR * xdrs,gstrings_ret * objp)1022 xdr_gstrings_ret(XDR *xdrs, gstrings_ret *objp)
1023 {
1024 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
1025 		return (FALSE);
1026 	}
1027 	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
1028 		return (FALSE);
1029 	}
1030 	if (objp->code == KADM5_OK) {
1031 		if (!xdr_int(xdrs, &objp->count)) {
1032 			return (FALSE);
1033 		}
1034 		if (!xdr_array(xdrs, (caddr_t *) &objp->strings,
1035 			       (unsigned int *) &objp->count, ~0,
1036 			       sizeof(krb5_string_attr),
1037 			       (xdrproc_t)xdr_krb5_string_attr)) {
1038 			return (FALSE);
1039 		}
1040 	}
1041 
1042 	return (TRUE);
1043 }
1044 
1045 bool_t
xdr_sstring_arg(XDR * xdrs,sstring_arg * objp)1046 xdr_sstring_arg(XDR *xdrs, sstring_arg *objp)
1047 {
1048 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
1049 		return (FALSE);
1050 	}
1051 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
1052 		return (FALSE);
1053 	}
1054 	if (!xdr_nullstring(xdrs, &objp->key)) {
1055 		return (FALSE);
1056 	}
1057 	if (!xdr_nullstring(xdrs, &objp->value)) {
1058 		return (FALSE);
1059 	}
1060 
1061 	return (TRUE);
1062 }
1063 
1064 bool_t
xdr_krb5_principal(XDR * xdrs,krb5_principal * objp)1065 xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
1066 {
1067     int	    ret;
1068     char	    *p = NULL;
1069     krb5_principal  pr = NULL;
1070     static krb5_context context = NULL;
1071 
1072     /* using a static context here is ugly, but should work
1073        ok, and the other solutions are even uglier */
1074 
1075     if (!context &&
1076 	kadm5_init_krb5_context(&context))
1077        return(FALSE);
1078 
1079     switch(xdrs->x_op) {
1080     case XDR_ENCODE:
1081 	if (*objp) {
1082 	     if((ret = krb5_unparse_name(context, *objp, &p)) != 0)
1083 		  return FALSE;
1084 	}
1085 	if(!xdr_nullstring(xdrs, &p))
1086 	    return FALSE;
1087 	if (p) free(p);
1088 	break;
1089     case XDR_DECODE:
1090 	if(!xdr_nullstring(xdrs, &p))
1091 	    return FALSE;
1092 	if (p) {
1093 	     ret = krb5_parse_name(context, p, &pr);
1094 	     if(ret != 0)
1095 		  return FALSE;
1096 	     *objp = pr;
1097 	     free(p);
1098 	} else
1099 	     *objp = NULL;
1100 	break;
1101     case XDR_FREE:
1102 	if(*objp != NULL)
1103 	    krb5_free_principal(context, *objp);
1104 	*objp = NULL;
1105 	break;
1106     }
1107     return TRUE;
1108 }
1109 
1110 bool_t
xdr_krb5_octet(XDR * xdrs,krb5_octet * objp)1111 xdr_krb5_octet(XDR *xdrs, krb5_octet *objp)
1112 {
1113    if (!xdr_u_char(xdrs, objp))
1114 	return (FALSE);
1115    return (TRUE);
1116 }
1117 
1118 bool_t
xdr_krb5_enctype(XDR * xdrs,krb5_enctype * objp)1119 xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp)
1120 {
1121    if (!xdr_int32(xdrs, (int32_t *) objp))
1122 	return (FALSE);
1123    return (TRUE);
1124 }
1125 
1126 bool_t
xdr_krb5_salttype(XDR * xdrs,krb5_int32 * objp)1127 xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp)
1128 {
1129     if (!xdr_int32(xdrs, (int32_t *) objp))
1130 	return FALSE;
1131     return TRUE;
1132 }
1133 
1134 bool_t
xdr_krb5_keyblock(XDR * xdrs,krb5_keyblock * objp)1135 xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp)
1136 {
1137    char *cp;
1138 
1139    /* XXX This only works because free_keyblock assumes ->contents
1140       is allocated by malloc() */
1141    if(!xdr_krb5_enctype(xdrs, &objp->enctype))
1142       return FALSE;
1143    cp = (char *)objp->contents;
1144    if(!xdr_bytes(xdrs, &cp, &objp->length, ~0))
1145       return FALSE;
1146    objp->contents = (uint8_t *)cp;
1147    return TRUE;
1148 }
1149 
1150 bool_t
xdr_krb5_string_attr(XDR * xdrs,krb5_string_attr * objp)1151 xdr_krb5_string_attr(XDR *xdrs, krb5_string_attr *objp)
1152 {
1153 	if (!xdr_nullstring(xdrs, &objp->key))
1154 		return FALSE;
1155 	if (!xdr_nullstring(xdrs, &objp->value))
1156 		return FALSE;
1157 	if (xdrs->x_op == XDR_DECODE &&
1158 	    (objp->key == NULL || objp->value == NULL))
1159 		return FALSE;
1160 	return TRUE;
1161 }
1162 
1163 bool_t
xdr_kadm5_key_data(XDR * xdrs,kadm5_key_data * objp)1164 xdr_kadm5_key_data(XDR *xdrs, kadm5_key_data *objp)
1165 {
1166 	if (!xdr_krb5_kvno(xdrs, &objp->kvno))
1167 		return FALSE;
1168 	if (!xdr_krb5_keyblock(xdrs, &objp->key))
1169 		return FALSE;
1170 	if (!xdr_krb5_int16(xdrs, &objp->salt.type))
1171 		return FALSE;
1172 	if (!xdr_bytes(xdrs, &objp->salt.data.data,
1173 		       &objp->salt.data.length, ~0))
1174 		return FALSE;
1175 	return TRUE;
1176 }
1177 
1178 bool_t
xdr_getpkeys_arg(XDR * xdrs,getpkeys_arg * objp)1179 xdr_getpkeys_arg(XDR *xdrs, getpkeys_arg *objp)
1180 {
1181 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
1182 		return FALSE;
1183 	}
1184 	if (!xdr_krb5_principal(xdrs, &objp->princ)) {
1185 		return FALSE;
1186 	}
1187 	if (!xdr_krb5_kvno(xdrs, &objp->kvno)) {
1188 		return FALSE;
1189 	}
1190 	return TRUE;
1191 }
1192 
1193 bool_t
xdr_getpkeys_ret(XDR * xdrs,getpkeys_ret * objp)1194 xdr_getpkeys_ret(XDR *xdrs, getpkeys_ret *objp)
1195 {
1196 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
1197 		return FALSE;
1198 	}
1199 	if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
1200 		return FALSE;
1201 	}
1202 	if (objp->code == KADM5_OK) {
1203 		if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
1204 			       (unsigned int *) &objp->n_key_data, ~0,
1205 			       sizeof(kadm5_key_data),
1206 			       (xdrproc_t)xdr_kadm5_key_data)) {
1207 		    return FALSE;
1208 		}
1209 	}
1210 	return TRUE;
1211 }
1212 
1213 bool_t
xdr_calias_arg(XDR * xdrs,calias_arg * objp)1214 xdr_calias_arg(XDR *xdrs, calias_arg *objp)
1215 {
1216 	if (!xdr_ui_4(xdrs, &objp->api_version)) {
1217 		return (FALSE);
1218 	}
1219 	if (!xdr_krb5_principal(xdrs, &objp->alias)) {
1220 		return (FALSE);
1221 	}
1222 	if (!xdr_krb5_principal(xdrs, &objp->target)) {
1223 		return (FALSE);
1224 	}
1225 	return (TRUE);
1226 }
1227