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