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