add kadm5_setkey_principal
[krb5.git] / src / lib / kadm5 / kadm_rpc_xdr.c
1 /*
2  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
3  *
4  * $Header$
5  */
6
7 #if !defined(lint) && !defined(__CODECENTER__)
8 static char *rcsid = "$Header$";
9 #endif
10
11 #include <rpc/rpc.h>
12 #include <krb5.h>
13 #include <k5-int.h>
14 #include <kadm5/admin.h>
15 #include <kadm5/kadm_rpc.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 static bool_t
20 _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
21                              int v);
22
23 /*
24  * Function: xdr_ui_4
25  *
26  * Purpose: XDR function which serves as a wrapper for xdr_u_int32,
27  * to prevent compiler warnings about type clashes between u_int32
28  * and krb5_ui_4.
29  */
30 bool_t xdr_ui_4(XDR *xdrs, krb5_ui_4 *objp)
31 {
32   /* Assumes that krb5_ui_4 and u_int32 are both four bytes long.
33      This should not be a harmful assumption. */
34   return xdr_u_int32(xdrs, (rpc_u_int32 *) objp);
35 }
36
37
38 /*
39  * Function: xdr_nullstring
40  *
41  * Purpose: XDR function for "strings" that are either NULL-terminated
42  * or NULL.
43  */
44 bool_t xdr_nullstring(XDR *xdrs, char **objp)
45 {
46      u_int size;
47
48      if (xdrs->x_op == XDR_ENCODE) {
49           if (*objp == NULL)
50                size = 0;
51           else
52                size = strlen(*objp) + 1;
53      }
54      if (! xdr_u_int(xdrs, &size)) {
55           return FALSE;
56         }
57      switch (xdrs->x_op) {
58      case XDR_DECODE:
59           if (size == 0) {
60                *objp = NULL;
61                return TRUE;
62           } else if (*objp == NULL) {
63                *objp = (char *) mem_alloc(size);
64                if (*objp == NULL) {
65                     errno = ENOMEM;
66                     return FALSE;
67                }
68           }
69           return (xdr_opaque(xdrs, *objp, size));
70           
71      case XDR_ENCODE:
72           if (size != 0)
73                return (xdr_opaque(xdrs, *objp, size));
74           return TRUE;
75
76      case XDR_FREE:
77           if (*objp != NULL)
78                mem_free(*objp, size);
79           *objp = NULL;
80           return TRUE;
81      }
82
83      return FALSE;
84 }
85
86 /*
87  * Function: xdr_nulltype
88  *
89  * Purpose: XDR function for arbitrary pointer types that are either
90  * NULL or contain data.
91  */
92 bool_t xdr_nulltype(XDR *xdrs, void **objp, xdrproc_t proc)
93 {
94      bool_t null;
95
96      switch (xdrs->x_op) {
97      case XDR_DECODE:
98           if (!xdr_bool(xdrs, &null))
99               return FALSE;
100           if (null) {
101                *objp = NULL;
102                return TRUE;
103           }
104           return (*proc)(xdrs, objp);
105
106      case XDR_ENCODE:
107           if (*objp == NULL)
108                null = TRUE;
109           else
110                null = FALSE;
111           if (!xdr_bool(xdrs, &null))
112                return FALSE;
113           if (null == FALSE)
114                return (*proc)(xdrs, objp);
115           return TRUE;
116
117      case XDR_FREE:
118           if (*objp)
119                return (*proc)(xdrs, objp);
120           return TRUE;
121      }
122
123      return FALSE;
124 }
125
126 bool_t
127 xdr_krb5_timestamp(XDR *xdrs, krb5_timestamp *objp)
128 {
129   /* This assumes that int32 and krb5_timestamp are the same size.
130      This shouldn't be a problem, since we've got a unit test which
131      checks for this. */
132         if (!xdr_int32(xdrs, (rpc_int32 *) objp)) {
133                 return (FALSE);
134         }
135         return (TRUE);
136 }
137
138 bool_t
139 xdr_krb5_kvno(XDR *xdrs, krb5_kvno *objp)
140 {
141         unsigned char tmp;
142
143         tmp = '\0'; /* for purify, else xdr_u_char performs a umr */
144
145         if (xdrs->x_op == XDR_ENCODE)
146                 tmp = (unsigned char) *objp;
147
148         if (!xdr_u_char(xdrs, &tmp))
149                 return (FALSE);
150
151         if (xdrs->x_op == XDR_DECODE)
152                 *objp = (krb5_kvno) tmp;
153
154         return (TRUE);
155 }
156
157 bool_t
158 xdr_krb5_deltat(XDR *xdrs, krb5_deltat *objp)
159 {
160   /* This assumes that int32 and krb5_deltat are the same size.
161      This shouldn't be a problem, since we've got a unit test which
162      checks for this. */
163         if (!xdr_int32(xdrs, (rpc_int32 *) objp)) {
164                 return (FALSE);
165         }
166         return (TRUE);
167 }
168
169 bool_t
170 xdr_krb5_flags(XDR *xdrs, krb5_flags *objp)
171 {
172   /* This assumes that int32 and krb5_flags are the same size.
173      This shouldn't be a problem, since we've got a unit test which
174      checks for this. */
175         if (!xdr_int32(xdrs, (rpc_int32 *) objp)) {
176                 return (FALSE);
177         }
178         return (TRUE);
179 }
180
181 bool_t
182 xdr_krb5_ui_4(XDR *xdrs, krb5_ui_4 *objp)
183 {
184         if (!xdr_u_int32(xdrs, (rpc_u_int32 *) objp)) {
185                 return (FALSE);
186         }
187         return (TRUE);
188 }
189
190 bool_t
191 xdr_krb5_int16(XDR *xdrs, krb5_int16 *objp)
192 {
193     int tmp;
194
195     tmp = (int) *objp;
196
197     if (!xdr_int(xdrs, &tmp))
198         return(FALSE);
199
200     *objp = (krb5_int16) tmp;
201
202     return(TRUE);
203 }
204
205 bool_t xdr_krb5_key_data_nocontents(XDR *xdrs, krb5_key_data *objp)
206 {
207      /*
208       * Note that this function intentionally DOES NOT tranfer key
209       * length or contents!  xdr_krb5_key_data in adb_xdr.c does, but
210       * that is only for use within the server-side library.
211       */
212      unsigned int tmp;
213
214      if (xdrs->x_op == XDR_DECODE)
215           memset((char *) objp, 0, sizeof(krb5_key_data));
216
217      if (!xdr_krb5_int16(xdrs, &objp->key_data_ver)) {
218           return (FALSE);
219      }
220      if (!xdr_krb5_int16(xdrs, &objp->key_data_kvno)) {
221           return (FALSE);
222      }
223      if (!xdr_krb5_int16(xdrs, &objp->key_data_type[0])) {
224           return (FALSE);
225      }
226      if (objp->key_data_ver > 1) {
227           if (!xdr_krb5_int16(xdrs, &objp->key_data_type[1])) {
228                return (FALSE);
229           }
230      }
231      /*
232       * kadm5_get_principal on the server side allocates and returns
233       * key contents when asked.  Even though this function refuses to
234       * transmit that data, it still has to *free* the data at the
235       * appropriate time to avoid a memory leak.
236       */
237      if (xdrs->x_op == XDR_FREE) {
238           tmp = (unsigned int) objp->key_data_length[0];
239           if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[0],
240                          &tmp, ~0))
241                return FALSE;
242           
243           tmp = (unsigned int) objp->key_data_length[1];
244           if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[1],
245                          &tmp, ~0))
246                return FALSE;
247      }
248      
249      return (TRUE);
250 }
251
252 bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
253 {
254      krb5_tl_data *tl, *tl2;
255      bool_t more;
256      int len;
257
258      switch (xdrs->x_op) {
259      case XDR_FREE:
260           tl = tl2 = *tl_data_head;
261           while (tl) {
262                tl2 = tl->tl_data_next;
263                free(tl->tl_data_contents);
264                free(tl);
265                tl = tl2;
266           }
267           break;
268           
269      case XDR_ENCODE:
270           tl = *tl_data_head;
271           while (1) {
272                more = (tl != NULL);
273                if (!xdr_bool(xdrs, &more))
274                     return FALSE;
275                if (tl == NULL)
276                     break;
277                if (!xdr_krb5_int16(xdrs, &tl->tl_data_type))
278                     return FALSE;
279                len = tl->tl_data_length;
280                if (!xdr_bytes(xdrs, (char **) &tl->tl_data_contents, &len, ~0))
281                     return FALSE;
282                tl = tl->tl_data_next;
283           }
284           break;
285
286      case XDR_DECODE:
287           tl = NULL;
288           while (1) {
289                if (!xdr_bool(xdrs, &more))
290                     return FALSE;
291                if (more == FALSE)
292                     break;
293                tl2 = (krb5_tl_data *) malloc(sizeof(krb5_tl_data));
294                if (tl2 == NULL)
295                     return FALSE;
296                memset((char *) tl2, 0, sizeof(krb5_tl_data));
297                if (!xdr_krb5_int16(xdrs, &tl2->tl_data_type))
298                     return FALSE;
299                if (!xdr_bytes(xdrs, (char **)&tl2->tl_data_contents, &len, ~0))
300                     return FALSE;
301                tl2->tl_data_length = len;
302
303                tl2->tl_data_next = tl;
304                tl = tl2;
305           }
306
307           *tl_data_head = tl;
308           break;
309      }
310
311      return TRUE;
312 }
313
314 bool_t
315 xdr_kadm5_ret_t(XDR *xdrs, kadm5_ret_t *objp)
316 {
317         rpc_u_int32 tmp;
318
319         if (xdrs->x_op == XDR_ENCODE)
320                 tmp = (rpc_u_int32) *objp;
321
322         if (!xdr_u_int32(xdrs, &tmp))
323                 return (FALSE);
324
325         if (xdrs->x_op == XDR_DECODE)
326                 *objp = (kadm5_ret_t) tmp;
327
328         return (TRUE);
329 }
330
331 bool_t xdr_kadm5_principal_ent_rec_v1(XDR *xdrs,
332                                       kadm5_principal_ent_rec *objp)
333 {
334      return _xdr_kadm5_principal_ent_rec(xdrs, objp, KADM5_API_VERSION_1);
335 }
336
337 bool_t xdr_kadm5_principal_ent_rec(XDR *xdrs,
338                                    kadm5_principal_ent_rec *objp)
339 {
340      return _xdr_kadm5_principal_ent_rec(xdrs, objp, KADM5_API_VERSION_2);
341 }
342
343 static bool_t
344 _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
345                              int v)
346 {
347      unsigned int n;
348      
349         if (!xdr_krb5_principal(xdrs, &objp->principal)) {
350                 return (FALSE);
351         }
352         if (!xdr_krb5_timestamp(xdrs, &objp->princ_expire_time)) {
353                 return (FALSE);
354         }
355         if (!xdr_krb5_timestamp(xdrs, &objp->last_pwd_change)) {
356                 return (FALSE);
357         }
358         if (!xdr_krb5_timestamp(xdrs, &objp->pw_expiration)) {
359                 return (FALSE);
360         }
361         if (!xdr_krb5_deltat(xdrs, &objp->max_life)) {
362                 return (FALSE);
363         }
364         if (v == KADM5_API_VERSION_1) {
365              if (!xdr_krb5_principal(xdrs, &objp->mod_name)) {
366                   return (FALSE);
367              }
368         } else {
369              if (!xdr_nulltype(xdrs, (void **) &objp->mod_name,
370                                xdr_krb5_principal)) {
371                   return (FALSE);
372              }
373         }
374         if (!xdr_krb5_timestamp(xdrs, &objp->mod_date)) {
375                 return (FALSE);
376         }
377         if (!xdr_krb5_flags(xdrs, &objp->attributes)) {
378                 return (FALSE);
379         }
380         if (!xdr_krb5_kvno(xdrs, &objp->kvno)) {
381                 return (FALSE);
382         }
383         if (!xdr_krb5_kvno(xdrs, &objp->mkvno)) {
384                 return (FALSE);
385         }
386         if (!xdr_nullstring(xdrs, &objp->policy)) {
387                 return (FALSE);
388         }
389         if (!xdr_long(xdrs, &objp->aux_attributes)) {
390                 return (FALSE);
391         }
392         if (v != KADM5_API_VERSION_1) {
393              if (!xdr_krb5_deltat(xdrs, &objp->max_renewable_life)) {
394                   return (FALSE);
395              }
396              if (!xdr_krb5_timestamp(xdrs, &objp->last_success)) {
397                   return (FALSE);
398              }
399              if (!xdr_krb5_timestamp(xdrs, &objp->last_failed)) {
400                   return (FALSE);
401              }
402              if (!xdr_krb5_kvno(xdrs, &objp->fail_auth_count)) {
403                   return (FALSE);
404              }
405              if (!xdr_krb5_int16(xdrs, &objp->n_key_data)) {
406                   return (FALSE);
407              }
408              if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) {
409                   return (FALSE);
410              }
411              if (!xdr_nulltype(xdrs, (void **) &objp->tl_data,
412                                xdr_krb5_tl_data)) { 
413                   return FALSE;
414              }
415              n = objp->n_key_data;
416              if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
417                             &n, ~0, sizeof(krb5_key_data),
418                             xdr_krb5_key_data_nocontents)) {
419                   return (FALSE);
420              }
421         }
422         return (TRUE);
423 }
424
425 bool_t
426 xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp)
427 {
428         if (!xdr_nullstring(xdrs, &objp->policy)) {
429                 return (FALSE);
430         }
431         /* these all used to be u_int32, but it's stupid for sized types
432            to be exposed at the api, and they're the same as longs on the
433            wire. */
434         if (!xdr_long(xdrs, &objp->pw_min_life)) {
435                 return (FALSE);
436         }
437         if (!xdr_long(xdrs, &objp->pw_max_life)) {
438                 return (FALSE);
439         }
440         if (!xdr_long(xdrs, &objp->pw_min_length)) {
441                 return (FALSE);
442         }
443         if (!xdr_long(xdrs, &objp->pw_min_classes)) {
444                 return (FALSE);
445         }
446         if (!xdr_long(xdrs, &objp->pw_history_num)) {
447                 return (FALSE);
448         }
449         if (!xdr_long(xdrs, &objp->policy_refcnt)) {
450                 return (FALSE);
451         }
452         return (TRUE);
453 }
454
455 bool_t
456 xdr_cprinc_arg(XDR *xdrs, cprinc_arg *objp)
457 {
458         if (!xdr_ui_4(xdrs, &objp->api_version)) {
459                 return (FALSE);
460         }
461         if (objp->api_version == KADM5_API_VERSION_1) {
462              if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) {
463                   return (FALSE);
464              }
465         } else {
466              if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) {
467                   return (FALSE);
468              }
469         }
470         if (!xdr_long(xdrs, &objp->mask)) {
471                 return (FALSE);
472         }
473         if (!xdr_nullstring(xdrs, &objp->passwd)) {
474                 return (FALSE);
475         }
476         return (TRUE);
477 }
478
479 bool_t
480 xdr_generic_ret(XDR *xdrs, generic_ret *objp)
481 {
482         if (!xdr_ui_4(xdrs, &objp->api_version)) {
483                 return (FALSE);
484         }
485         if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
486                 return (FALSE);
487         }
488         return(TRUE);
489 }
490
491 bool_t
492 xdr_dprinc_arg(XDR *xdrs, dprinc_arg *objp)
493 {
494         if (!xdr_ui_4(xdrs, &objp->api_version)) {
495                 return (FALSE);
496         }
497         if (!xdr_krb5_principal(xdrs, &objp->princ)) {
498                 return (FALSE);
499         }
500         return (TRUE);
501 }
502
503 bool_t
504 xdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp)
505 {
506         if (!xdr_ui_4(xdrs, &objp->api_version)) {
507                 return (FALSE);
508         }
509         if (objp->api_version == KADM5_API_VERSION_1) {
510              if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) {
511                   return (FALSE);
512              }
513         } else {
514              if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) {
515                   return (FALSE);
516              }
517         }
518         if (!xdr_long(xdrs, &objp->mask)) {
519                 return (FALSE);
520         }
521         return (TRUE);
522 }
523
524 bool_t
525 xdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp)
526 {
527         if (!xdr_ui_4(xdrs, &objp->api_version)) {
528                 return (FALSE);
529         }
530         if (!xdr_krb5_principal(xdrs, &objp->src)) {
531                 return (FALSE);
532         }
533         if (!xdr_krb5_principal(xdrs, &objp->dest)) {
534                 return (FALSE);
535         }
536         return (TRUE);
537 }
538
539 bool_t
540 xdr_gprincs_arg(XDR *xdrs, gprincs_arg *objp)
541 {
542      if (!xdr_ui_4(xdrs, &objp->api_version)) {
543           return (FALSE);
544      }
545      if (!xdr_nullstring(xdrs, &objp->exp)) {
546           return (FALSE);
547      }
548      return (TRUE);
549 }
550
551 bool_t
552 xdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp)     
553 {
554      if (!xdr_ui_4(xdrs, &objp->api_version)) {
555           return (FALSE);
556      }
557      if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
558           return (FALSE);
559      }
560      if (objp->code == KADM5_OK) {
561           if (!xdr_int(xdrs, &objp->count)) {
562                return (FALSE);
563           }
564           if (!xdr_array(xdrs, (caddr_t *) &objp->princs,
565                          (unsigned int *) &objp->count, ~0,
566                          sizeof(char *), xdr_nullstring)) {
567                return (FALSE);
568           }
569      }
570      return (TRUE);
571 }
572
573 bool_t
574 xdr_chpass_arg(XDR *xdrs, chpass_arg *objp)
575 {
576         if (!xdr_ui_4(xdrs, &objp->api_version)) {
577                 return (FALSE);
578         }
579         if (!xdr_krb5_principal(xdrs, &objp->princ)) {
580                 return (FALSE);
581         }
582         if (!xdr_nullstring(xdrs, &objp->pass)) {
583                 return (FALSE);
584         }
585         return (TRUE);
586 }
587
588 bool_t
589 xdr_setkey_arg(XDR *xdrs, setkey_arg *objp)
590 {
591         if (!xdr_ui_4(xdrs, &objp->api_version)) {
592                 return (FALSE);
593         }
594         if (!xdr_krb5_principal(xdrs, &objp->princ)) {
595                 return (FALSE);
596         }
597         if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
598                        (unsigned int *) &objp->n_keys, ~0,
599                        sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
600                 return (FALSE);
601         }
602         return (TRUE);
603 }
604
605 bool_t
606 xdr_chrand_arg(XDR *xdrs, chrand_arg *objp)
607 {
608         if (!xdr_ui_4(xdrs, &objp->api_version)) {
609                 return (FALSE);
610         }
611         if (!xdr_krb5_principal(xdrs, &objp->princ)) {
612                 return (FALSE);
613         }
614         return (TRUE);
615 }
616
617 bool_t
618 xdr_chrand_ret(XDR *xdrs, chrand_ret *objp)
619 {
620         if (!xdr_ui_4(xdrs, &objp->api_version)) {
621                 return (FALSE);
622         }
623         if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
624                 return (FALSE);
625         }
626         if (objp->api_version == KADM5_API_VERSION_1) {
627              if(objp->code == KADM5_OK) {
628                   if (!xdr_krb5_keyblock(xdrs, &objp->key)) {
629                        return (FALSE);
630                   }
631              }
632         } else {
633              if (objp->code == KADM5_OK) {
634                   if (!xdr_array(xdrs, (char **)&objp->keys, &objp->n_keys, ~0,
635                                  sizeof(krb5_keyblock),
636                                  xdr_krb5_keyblock))
637                        return FALSE;
638              }
639         }
640         
641         return (TRUE);
642 }
643
644 bool_t
645 xdr_gprinc_arg(XDR *xdrs, gprinc_arg *objp)
646 {
647         if (!xdr_ui_4(xdrs, &objp->api_version)) {
648                 return (FALSE);
649         }
650         if (!xdr_krb5_principal(xdrs, &objp->princ)) {
651                 return (FALSE);
652         }
653         if ((objp->api_version > KADM5_API_VERSION_1) &&
654             !xdr_long(xdrs, &objp->mask)) {
655              return FALSE;
656         }
657              
658         return (TRUE);
659 }
660
661 bool_t
662 xdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp)
663 {
664         if (!xdr_ui_4(xdrs, &objp->api_version)) {
665                 return (FALSE);
666         }
667         if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
668                 return (FALSE);
669         }
670         if(objp->code == KADM5_OK)  {
671              if (objp->api_version == KADM5_API_VERSION_1) {
672                   if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) {
673                        return (FALSE);
674                   }
675              } else {
676                   if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) {
677                        return (FALSE);
678                   }
679              }
680         }
681         return (TRUE);
682 }
683
684 bool_t
685 xdr_cpol_arg(XDR *xdrs, cpol_arg *objp)
686 {
687         if (!xdr_ui_4(xdrs, &objp->api_version)) {
688                 return (FALSE);
689         }
690         if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec)) {
691                 return (FALSE);
692         }
693         if (!xdr_long(xdrs, &objp->mask)) {
694                 return (FALSE);
695         }
696         return (TRUE);
697 }
698
699 bool_t
700 xdr_dpol_arg(XDR *xdrs, dpol_arg *objp)
701 {
702         if (!xdr_ui_4(xdrs, &objp->api_version)) {
703                 return (FALSE);
704         }
705         if (!xdr_nullstring(xdrs, &objp->name)) {
706                 return (FALSE);
707         }
708         return (TRUE);
709 }
710
711 bool_t
712 xdr_mpol_arg(XDR *xdrs, mpol_arg *objp)
713 {
714         if (!xdr_ui_4(xdrs, &objp->api_version)) {
715                 return (FALSE);
716         }
717         if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec)) {
718                 return (FALSE);
719         }
720         if (!xdr_long(xdrs, &objp->mask)) {
721                 return (FALSE);
722         }
723         return (TRUE);
724 }
725
726 bool_t
727 xdr_gpol_arg(XDR *xdrs, gpol_arg *objp)
728 {
729         if (!xdr_ui_4(xdrs, &objp->api_version)) {
730                 return (FALSE);
731         }
732         if (!xdr_nullstring(xdrs, &objp->name)) {
733                 return (FALSE);
734         }
735         return (TRUE);
736 }
737
738 bool_t
739 xdr_gpol_ret(XDR *xdrs, gpol_ret *objp)
740 {
741         if (!xdr_ui_4(xdrs, &objp->api_version)) {
742                 return (FALSE);
743         }
744         if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
745                 return (FALSE);
746         }
747         if(objp->code == KADM5_OK) {
748             if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec))
749                 return (FALSE);
750         }
751         return (TRUE);
752 }
753
754 bool_t
755 xdr_gpols_arg(XDR *xdrs, gpols_arg *objp)
756 {
757      if (!xdr_ui_4(xdrs, &objp->api_version)) {
758           return (FALSE);
759      }
760      if (!xdr_nullstring(xdrs, &objp->exp)) {
761           return (FALSE);
762      }
763      return (TRUE);
764 }
765
766 bool_t
767 xdr_gpols_ret(XDR *xdrs, gpols_ret *objp)     
768 {
769      if (!xdr_ui_4(xdrs, &objp->api_version)) {
770           return (FALSE);
771      }
772      if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
773           return (FALSE);
774      }
775      if (objp->code == KADM5_OK) {
776           if (!xdr_int(xdrs, &objp->count)) {
777                return (FALSE);
778           }
779           if (!xdr_array(xdrs, (caddr_t *) &objp->pols,
780                          (unsigned int *) &objp->count, ~0,
781                          sizeof(char *), xdr_nullstring)) {
782                return (FALSE);
783           }
784      }
785      return (TRUE);
786 }
787
788 bool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp)
789 {
790         if (!xdr_ui_4(xdrs, &objp->api_version)) {
791                 return (FALSE);
792         }
793      if (! xdr_kadm5_ret_t(xdrs, &objp->code) ||
794          ! xdr_long(xdrs, &objp->privs))
795           return FALSE;
796      return TRUE;
797 }
798
799 bool_t
800 xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
801 {
802     int     ret;
803     char            *p = NULL;
804     krb5_principal  pr = NULL;
805     static krb5_context context = NULL;
806
807     /* using a static context here is ugly, but should work
808        ok, and the other solutions are even uglier */
809
810     if (!context &&
811         krb5_init_context(&context))
812        return(FALSE);
813
814     switch(xdrs->x_op) {
815     case XDR_ENCODE:
816         if (*objp) {
817              if((ret = krb5_unparse_name(context, *objp, &p)) != 0) 
818                   return FALSE;
819         }
820         if(!xdr_nullstring(xdrs, &p))
821             return FALSE;
822         if (p) free(p);
823         break;
824     case XDR_DECODE:
825         if(!xdr_nullstring(xdrs, &p))
826             return FALSE;
827         if (p) {
828              ret = krb5_parse_name(context, p, &pr);
829              if(ret != 0) 
830                   return FALSE;
831              *objp = pr;
832              free(p);
833         } else
834              *objp = NULL;
835         break;
836     case XDR_FREE:
837         if(*objp != NULL) 
838             krb5_free_principal(context, *objp);
839         break;
840     }
841     return TRUE;
842 }
843
844 bool_t
845 xdr_krb5_octet(XDR *xdrs, krb5_octet *objp)
846 {
847    if (!xdr_u_char(xdrs, objp))
848         return (FALSE);
849    return (TRUE);
850 }
851
852 bool_t
853 xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp)
854 {
855    /*
856     * This used to be xdr_krb5_keytype, but keytypes and enctypes have
857     * been merged into only enctypes.  However, randkey_principal
858     * already ensures that only a key of ENCTYPE_DES_CBC_CRC will be
859     * returned to v1 clients, and ENCTYPE_DES_CBC_CRC has the same
860     * value as KEYTYPE_DES used too, which is what all v1 clients
861     * expect.  Therefore, IMHO, just encoding whatever enctype we get
862     * is safe.
863     */
864
865    if (!xdr_u_int(xdrs, (unsigned int *) objp))
866         return (FALSE);
867    return (TRUE);
868 }
869
870 bool_t
871 xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp)
872 {
873    /* XXX This only works because free_keyblock assumes ->contents
874       is allocated by malloc() */
875
876    if(!xdr_krb5_enctype(xdrs, &objp->enctype))
877       return FALSE;
878    if(!xdr_bytes(xdrs, (char **) &objp->contents, (unsigned int *)
879                  &objp->length, ~0))
880       return FALSE;
881    return TRUE;
882 }
883