1 /* 2 * Copyright 2007 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 31 #include <gssapi/gssapi.h> 32 #include <gssapi_krb5.h> /* for gss_nt_krb5_name */ 33 #include <krb5.h> 34 #include <kadm5/admin.h> 35 #include <kadm5/kadm_rpc.h> 36 #include <kadm5/server_internal.h> 37 #include <kadm5/srv/server_acl.h> 38 #include <security/pam_appl.h> 39 40 #include <syslog.h> 41 #include <arpa/inet.h> /* inet_ntoa */ 42 #include <krb5/adm_proto.h> /* krb5_klog_syslog */ 43 #include <libintl.h> 44 #include "misc.h" 45 46 #define LOG_UNAUTH gettext("Unauthorized request: %s, %s, " \ 47 "client=%s, service=%s, addr=%s") 48 #define LOG_DONE gettext("Request: %s, %s, %s, client=%s, " \ 49 "service=%s, addr=%s") 50 51 extern gss_name_t gss_changepw_name; 52 extern gss_name_t gss_oldchangepw_name; 53 extern void * global_server_handle; 54 extern short l_port; 55 56 char buf[33]; 57 58 #define CHANGEPW_SERVICE(rqstp) \ 59 (cmp_gss_names_rel_1(acceptor_name(rqstp), gss_changepw_name) |\ 60 (gss_oldchangepw_name && \ 61 cmp_gss_names_rel_1(acceptor_name(rqstp), \ 62 gss_oldchangepw_name))) 63 64 65 static int gss_to_krb5_name(kadm5_server_handle_t handle, 66 gss_name_t gss_name, krb5_principal *princ); 67 68 static int gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str); 69 70 static gss_name_t acceptor_name(struct svc_req * rqstp); 71 72 kadm5_ret_t 73 kadm5_get_priv(void *server_handle, 74 long *privs, gss_name_t clnt); 75 76 gss_name_t 77 get_clnt_name(struct svc_req * rqstp) 78 { 79 OM_uint32 maj_stat, min_stat; 80 gss_name_t name; 81 rpc_gss_rawcred_t *raw_cred; 82 void *cookie; 83 gss_buffer_desc name_buff; 84 85 rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie); 86 name_buff.value = raw_cred->client_principal->name; 87 name_buff.length = raw_cred->client_principal->len; 88 maj_stat = gss_import_name(&min_stat, &name_buff, 89 (gss_OID) GSS_C_NT_EXPORT_NAME, &name); 90 if (maj_stat != GSS_S_COMPLETE) { 91 return (NULL); 92 } 93 return (name); 94 } 95 96 char * 97 client_addr(struct svc_req * req, char *buf) 98 { 99 struct sockaddr *ca; 100 u_char *b; 101 char *frontspace = " "; 102 103 /* 104 * Convert the caller's IP address to a dotted string 105 */ 106 ca = (struct sockaddr *) 107 svc_getrpccaller(req->rq_xprt)->buf; 108 109 if (ca->sa_family == AF_INET) { 110 b = (u_char *) & ((struct sockaddr_in *) ca)->sin_addr; 111 (void) sprintf(buf, "%s(%d.%d.%d.%d) ", frontspace, 112 b[0] & 0xFF, b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF); 113 } else { 114 /* 115 * No IP address to print. If there was a host name 116 * printed, then we print a space. 117 */ 118 (void) sprintf(buf, frontspace); 119 } 120 121 return (buf); 122 } 123 124 static int cmp_gss_names(gss_name_t n1, gss_name_t n2) 125 { 126 OM_uint32 emaj, emin; 127 int equal; 128 129 if (GSS_ERROR(emaj = gss_compare_name(&emin, n1, n2, &equal))) 130 return(0); 131 132 return(equal); 133 } 134 135 /* Does a comparison of the names and then releases the first entity */ 136 /* For use above in CHANGEPW_SERVICE */ 137 static int cmp_gss_names_rel_1(gss_name_t n1, gss_name_t n2) 138 { 139 OM_uint32 min_stat; 140 int ret; 141 142 ret = cmp_gss_names(n1, n2); 143 if (n1) (void) gss_release_name(&min_stat, &n1); 144 return ret; 145 } 146 147 /* 148 * Function check_handle 149 * 150 * Purpose: Check a server handle and return a com_err code if it is 151 * invalid or 0 if it is valid. 152 * 153 * Arguments: 154 * 155 * handle The server handle. 156 */ 157 158 static int check_handle(void *handle) 159 { 160 CHECK_HANDLE(handle); 161 return 0; 162 } 163 164 /* 165 * Function: new_server_handle 166 * 167 * Purpose: Constructs a server handle suitable for passing into the 168 * server library API functions, by folding the client's API version 169 * and calling principal into the server handle returned by 170 * kadm5_init. 171 * 172 * Arguments: 173 * api_version (input) The API version specified by the client 174 * rqstp (input) The RPC request 175 * handle (output) The returned handle 176 * <return value> (output) An error code, or 0 if no error occurred 177 * 178 * Effects: 179 * Returns a pointer to allocated storage containing the server 180 * handle. If an error occurs, then no allocated storage is 181 * returned, and the return value of the function will be a 182 * non-zero com_err code. 183 * 184 * The allocated storage for the handle should be freed with 185 * free_server_handle (see below) when it is no longer needed. 186 */ 187 188 static kadm5_ret_t new_server_handle(krb5_ui_4 api_version, 189 struct svc_req *rqstp, 190 kadm5_server_handle_t 191 *out_handle) 192 { 193 kadm5_server_handle_t handle; 194 gss_name_t name; 195 OM_uint32 min_stat; 196 197 if (! (handle = (kadm5_server_handle_t) 198 malloc(sizeof(*handle)))) 199 return ENOMEM; 200 201 *handle = *(kadm5_server_handle_t)global_server_handle; 202 handle->api_version = api_version; 203 204 if (!(name = get_clnt_name(rqstp))) { 205 free(handle); 206 return KADM5_FAILURE; 207 } 208 if (! gss_to_krb5_name(handle, name, &handle->current_caller)) { 209 free(handle); 210 gss_release_name(&min_stat, &name); 211 return KADM5_FAILURE; 212 } 213 gss_release_name(&min_stat, &name); 214 215 *out_handle = handle; 216 return 0; 217 } 218 219 /* 220 * Function: free_server_handle 221 * 222 * Purpose: Free handle memory allocated by new_server_handle 223 * 224 * Arguments: 225 * handle (input/output) The handle to free 226 */ 227 static void free_server_handle(kadm5_server_handle_t handle) 228 { 229 krb5_free_principal(handle->context, handle->current_caller); 230 free(handle); 231 } 232 233 /* 234 * Function: setup_gss_names 235 * 236 * Purpose: Create printable representations of the client and server 237 * names. 238 * 239 * Arguments: 240 * rqstp (r) the RPC request 241 * client_name (w) pointer to client_name string 242 * server_name (w) pointer to server_name string 243 * 244 * Effects: 245 * 246 * Unparses the client and server names into client_name and 247 * server_name, both of which must be freed by the caller. Returns 0 248 * on success and -1 on failure. On failure client_name and server_name 249 * will point to null. 250 */ 251 /* SUNW14resync */ 252 int setup_gss_names(struct svc_req *rqstp, 253 char **client_name, char **server_name) 254 { 255 OM_uint32 maj_stat, min_stat; 256 rpc_gss_rawcred_t *raw_cred; 257 gss_buffer_desc name_buf; 258 char *tmp, *val; 259 size_t len; 260 gss_name_t name; 261 262 *client_name = NULL; 263 264 rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL); 265 266 /* Return a copy of the service principal from the raw_cred */ 267 *server_name = strdup(raw_cred->svc_principal); 268 269 if (*server_name == NULL) 270 return (-1); 271 272 if (!(name = get_clnt_name(rqstp))) { 273 free(*server_name); 274 *server_name = NULL; 275 return (-1); 276 } 277 maj_stat = gss_display_name(&min_stat, name, &name_buf, NULL); 278 if (maj_stat != GSS_S_COMPLETE) { 279 free(*server_name); 280 gss_release_name(&min_stat, &name); 281 *server_name = NULL; 282 return (-1); 283 } 284 gss_release_name(&min_stat, &name); 285 286 /* 287 * Allocate space to copy the client principal. We allocate an 288 * extra byte to make the string null terminated if we need to. 289 */ 290 291 val = name_buf.value; 292 len = name_buf.length + (val[name_buf.length - 1] != '\0'); 293 294 /* len is the length including the null terminating byte. */ 295 296 tmp = malloc(len); 297 if (tmp) { 298 memcpy(tmp, val, len - 1); 299 tmp[len - 1] = '\0'; 300 } else { 301 free(*server_name); 302 *server_name = NULL; 303 } 304 305 /* Were done with the GSS buffer */ 306 (void) gss_release_buffer(&min_stat, &name_buf); 307 308 *client_name = tmp; 309 310 return (tmp ? 0 : -1); 311 } 312 313 static gss_name_t acceptor_name(struct svc_req * rqstp) 314 { 315 OM_uint32 maj_stat, min_stat; 316 gss_name_t name; 317 rpc_gss_rawcred_t *raw_cred; 318 void *cookie; 319 gss_buffer_desc name_buff; 320 321 rpc_gss_getcred(rqstp, &raw_cred, NULL, &cookie); 322 name_buff.value = raw_cred->svc_principal; 323 name_buff.length = strlen(raw_cred->svc_principal); 324 maj_stat = gss_import_name(&min_stat, &name_buff, 325 (gss_OID) gss_nt_krb5_name, &name); 326 if (maj_stat != GSS_S_COMPLETE) { 327 gss_release_buffer(&min_stat, &name_buff); 328 return (NULL); 329 } 330 maj_stat = gss_display_name(&min_stat, name, &name_buff, NULL); 331 if (maj_stat != GSS_S_COMPLETE) { 332 gss_release_buffer(&min_stat, &name_buff); 333 return (NULL); 334 } 335 gss_release_buffer(&min_stat, &name_buff); 336 337 return name; 338 } 339 340 static int cmp_gss_krb5_name(kadm5_server_handle_t handle, 341 gss_name_t gss_name, krb5_principal princ) 342 { 343 krb5_principal princ2; 344 int status; 345 346 if (! gss_to_krb5_name(handle, gss_name, &princ2)) 347 return 0; 348 status = krb5_principal_compare(handle->context, princ, princ2); 349 krb5_free_principal(handle->context, princ2); 350 return status; 351 } 352 353 354 /* 355 * This routine primarily validates the username and password 356 * of the principal to be created, if a prior acl check for 357 * the 'u' privilege succeeds. Validation is done using 358 * the PAM `k5migrate' service. k5migrate normally stacks 359 * pam_unix_auth.so and pam_unix_account.so in its auth and 360 * account stacks respectively. 361 * 362 * Returns 1 (true), if validation is successful, 363 * else returns 0 (false). 364 */ 365 int verify_pam_pw(char *userdata, char *pwd) { 366 pam_handle_t *pamh; 367 int err = 0; 368 int result = 1; 369 char *user = NULL; 370 char *ptr = NULL; 371 372 ptr = strchr(userdata, '@'); 373 if (ptr != NULL) { 374 user = (char *)malloc(ptr - userdata + 1); 375 (void) strlcpy(user, userdata, (ptr - userdata) + 1); 376 } else { 377 user = (char *)strdup(userdata); 378 } 379 380 err = pam_start("k5migrate", user, NULL, &pamh); 381 if (err != PAM_SUCCESS) { 382 syslog(LOG_ERR, "verify_pam_pw: pam_start() failed, %s\n", 383 pam_strerror(pamh, err)); 384 if (user) 385 free(user); 386 return (0); 387 } 388 if (user) 389 free(user); 390 391 err = pam_set_item(pamh, PAM_AUTHTOK, (void *)pwd); 392 if (err != PAM_SUCCESS) { 393 syslog(LOG_ERR, "verify_pam_pw: pam_set_item() failed, %s\n", 394 pam_strerror(pamh, err)); 395 (void) pam_end(pamh, err); 396 return (0); 397 } 398 399 err = pam_authenticate(pamh, PAM_SILENT); 400 if (err != PAM_SUCCESS) { 401 syslog(LOG_ERR, "verify_pam_pw: pam_authenticate() " 402 "failed, %s\n", pam_strerror(pamh, err)); 403 (void) pam_end(pamh, err); 404 return (0); 405 } 406 407 err = pam_acct_mgmt(pamh, PAM_SILENT); 408 if (err != PAM_SUCCESS) { 409 syslog(LOG_ERR, "verify_pam_pw: pam_acct_mgmt() failed, %s\n", 410 pam_strerror(pamh, err)); 411 (void) pam_end(pamh, err); 412 return (0); 413 } 414 415 (void) pam_end(pamh, PAM_SUCCESS); 416 return (result); 417 } 418 419 static int gss_to_krb5_name(kadm5_server_handle_t handle, 420 gss_name_t gss_name, krb5_principal *princ) 421 { 422 OM_uint32 status, minor_stat; 423 gss_buffer_desc gss_str; 424 gss_OID gss_type; 425 int success; 426 427 status = gss_display_name(&minor_stat, gss_name, &gss_str, &gss_type); 428 if ((status != GSS_S_COMPLETE) || (!g_OID_equal(gss_type, gss_nt_krb5_name))) 429 return 0; 430 success = (krb5_parse_name(handle->context, gss_str.value, princ) == 0); 431 gss_release_buffer(&minor_stat, &gss_str); 432 return success; 433 } 434 435 static int 436 gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str) 437 { 438 OM_uint32 status, minor_stat; 439 gss_OID gss_type; 440 441 status = gss_display_name(&minor_stat, gss_name, str, &gss_type); 442 if ((status != GSS_S_COMPLETE) || (gss_type != gss_nt_krb5_name)) 443 return 1; 444 return 0; 445 } 446 447 static int 448 log_unauth( 449 char *op, 450 char *target, 451 char *client, 452 char *server, 453 char *addr) 454 { 455 size_t tlen, clen, slen; 456 char *tdots, *cdots, *sdots; 457 458 tlen = strlen(target); 459 trunc_name(&tlen, &tdots); 460 clen = strlen(client); 461 trunc_name(&clen, &cdots); 462 slen = strlen(server); 463 trunc_name(&slen, &sdots); 464 465 return krb5_klog_syslog(LOG_NOTICE, 466 "Unauthorized request: %s, %.*s%s, " 467 "client=%.*s%s, service=%.*s%s, addr=%s", 468 op, tlen, target, tdots, 469 clen, client, cdots, 470 slen, server, sdots, 471 addr); 472 } 473 474 static int 475 log_done( 476 char *op, 477 char *target, 478 const char *errmsg, 479 char *client, 480 char *server, 481 char *addr) 482 { 483 size_t tlen, clen, slen; 484 char *tdots, *cdots, *sdots; 485 486 tlen = strlen(target); 487 trunc_name(&tlen, &tdots); 488 clen = strlen(client); 489 trunc_name(&clen, &cdots); 490 slen = strlen(server); 491 trunc_name(&slen, &sdots); 492 493 return krb5_klog_syslog(LOG_NOTICE, 494 "Request: %s, %.*s%s, %s, " 495 "client=%.*s%s, service=%.*s%s, addr=%s", 496 op, tlen, target, tdots, errmsg, 497 clen, client, cdots, 498 slen, server, sdots, 499 addr); 500 } 501 502 generic_ret * 503 create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp) 504 { 505 static generic_ret ret; 506 char *prime_arg = NULL; 507 char *client_name = NULL, *service_name = NULL; 508 int policy_migrate = 0; 509 510 OM_uint32 minor_stat; 511 kadm5_server_handle_t handle; 512 kadm5_ret_t retval; 513 restriction_t *rp; 514 gss_name_t name = NULL; 515 516 xdr_free(xdr_generic_ret, (char *) &ret); 517 518 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 519 return &ret; 520 521 if ((ret.code = check_handle((void *)handle))) 522 goto error; 523 ret.api_version = handle->api_version; 524 525 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 526 ret.code = KADM5_FAILURE; 527 goto error; 528 } 529 if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) { 530 ret.code = KADM5_BAD_PRINCIPAL; 531 goto error; 532 } 533 if (!(name = get_clnt_name(rqstp))) { 534 ret.code = KADM5_FAILURE; 535 goto error; 536 } 537 538 if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE, 539 arg->rec.principal, &rp) && 540 verify_pam_pw(prime_arg, arg->passwd)) { 541 policy_migrate = 1; 542 } 543 544 if (CHANGEPW_SERVICE(rqstp) 545 || (!kadm5int_acl_check(handle->context, name, ACL_ADD, 546 arg->rec.principal, &rp) && 547 !(policy_migrate)) 548 || kadm5int_acl_impose_restrictions(handle->context, 549 &arg->rec, &arg->mask, rp)) { 550 ret.code = KADM5_AUTH_ADD; 551 552 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 553 "kadm5_create_principal", 554 prime_arg, client_name); 555 log_unauth("kadm5_create_principal", prime_arg, 556 client_name, service_name, client_addr(rqstp, buf)); 557 } else { 558 ret.code = kadm5_create_principal((void *)handle, 559 &arg->rec, arg->mask, 560 arg->passwd); 561 562 audit_kadmind_auth(rqstp->rq_xprt, l_port, 563 "kadm5_create_principal", 564 prime_arg, client_name, ret.code); 565 log_done("kadm5_create_principal", prime_arg, 566 ((ret.code == 0) ? "success" : error_message(ret.code)), 567 client_name, service_name, client_addr(rqstp, buf)); 568 569 if (policy_migrate && (ret.code == 0)) { 570 arg->rec.policy = strdup("default"); 571 if ((arg->mask & KADM5_PW_EXPIRATION)) { 572 arg->mask = 0; 573 arg->mask |= KADM5_POLICY; 574 arg->mask |= KADM5_PW_EXPIRATION; 575 } else { 576 arg->mask = 0; 577 arg->mask |= KADM5_POLICY; 578 } 579 580 retval = kadm5_modify_principal((void *)handle, 581 &arg->rec, arg->mask); 582 log_done("kadm5_modify_principal", 583 prime_arg, ((retval == 0) ? "success" : 584 error_message(retval)), client_name, 585 service_name, client_addr(rqstp, buf)); 586 } 587 } 588 589 error: 590 if (name) 591 gss_release_name(&minor_stat, &name); 592 free_server_handle(handle); 593 if (prime_arg) 594 free(prime_arg); 595 if (client_name) 596 free(client_name); 597 if (service_name) 598 free(service_name); 599 return (&ret); 600 } 601 602 generic_ret * 603 create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp) 604 { 605 static generic_ret ret; 606 char *prime_arg = NULL; 607 char *client_name = NULL, *service_name = NULL; 608 int policy_migrate = 0; 609 610 OM_uint32 minor_stat; 611 kadm5_server_handle_t handle; 612 kadm5_ret_t retval; 613 restriction_t *rp; 614 gss_name_t name = NULL; 615 616 xdr_free(xdr_generic_ret, (char *) &ret); 617 618 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 619 return &ret; 620 621 if ((ret.code = check_handle((void *)handle))) 622 goto error; 623 ret.api_version = handle->api_version; 624 625 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 626 ret.code = KADM5_FAILURE; 627 goto error; 628 } 629 if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) { 630 ret.code = KADM5_BAD_PRINCIPAL; 631 goto error; 632 } 633 if (!(name = get_clnt_name(rqstp))) { 634 ret.code = KADM5_FAILURE; 635 goto error; 636 } 637 638 if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE, 639 arg->rec.principal, &rp) && 640 verify_pam_pw(prime_arg, arg->passwd)) { 641 policy_migrate = 1; 642 } 643 644 if (CHANGEPW_SERVICE(rqstp) 645 || (!kadm5int_acl_check(handle->context, name, ACL_ADD, 646 arg->rec.principal, &rp) && 647 !(policy_migrate)) 648 || kadm5int_acl_impose_restrictions(handle->context, 649 &arg->rec, &arg->mask, rp)) { 650 ret.code = KADM5_AUTH_ADD; 651 log_unauth("kadm5_create_principal", prime_arg, 652 client_name, service_name, client_addr(rqstp, buf)); 653 } else { 654 ret.code = kadm5_create_principal_3((void *)handle, 655 &arg->rec, arg->mask, 656 arg->n_ks_tuple, 657 arg->ks_tuple, 658 arg->passwd); 659 log_done("kadm5_create_principal", prime_arg, 660 ((ret.code == 0) ? "success" : error_message(ret.code)), 661 client_name, service_name, client_addr(rqstp, buf)); 662 663 if (policy_migrate && (ret.code == 0)) { 664 arg->rec.policy = strdup("default"); 665 if ((arg->mask & KADM5_PW_EXPIRATION)) { 666 arg->mask = 0; 667 arg->mask |= KADM5_POLICY; 668 arg->mask |= KADM5_PW_EXPIRATION; 669 } else { 670 arg->mask = 0; 671 arg->mask |= KADM5_POLICY; 672 } 673 674 retval = kadm5_modify_principal((void *)handle, 675 &arg->rec, arg->mask); 676 log_done("kadm5_modify_principal", prime_arg, 677 ((retval == 0) ? "success" : error_message(retval)), 678 client_name, service_name, client_addr(rqstp, buf)); 679 } 680 } 681 682 error: 683 if (name) 684 gss_release_name(&minor_stat, &name); 685 free_server_handle(handle); 686 if (client_name) 687 free(client_name); 688 if (service_name) 689 free(service_name); 690 if (prime_arg) 691 free(prime_arg); 692 return &ret; 693 } 694 695 generic_ret * 696 delete_principal_1_svc(dprinc_arg *arg, struct svc_req *rqstp) 697 { 698 static generic_ret ret; 699 char *prime_arg = NULL; 700 char *client_name = NULL, *service_name = NULL; 701 OM_uint32 min_stat; 702 kadm5_server_handle_t handle; 703 gss_name_t name = NULL; 704 705 xdr_free(xdr_generic_ret, (char *) &ret); 706 707 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 708 return &ret; 709 710 if ((ret.code = check_handle((void *)handle))) 711 goto error; 712 ret.api_version = handle->api_version; 713 714 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 715 ret.code = KADM5_FAILURE; 716 goto error; 717 } 718 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 719 ret.code = KADM5_BAD_PRINCIPAL; 720 goto error; 721 } 722 if (!(name = get_clnt_name(rqstp))) { 723 ret.code = KADM5_FAILURE; 724 goto error; 725 } 726 727 if (CHANGEPW_SERVICE(rqstp) 728 || !kadm5int_acl_check(handle->context, name, ACL_DELETE, 729 arg->princ, NULL)) { 730 ret.code = KADM5_AUTH_DELETE; 731 732 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 733 "kadm5_delete_principal", 734 prime_arg, client_name); 735 log_unauth("kadm5_delete_principal", prime_arg, client_name, 736 service_name, client_addr(rqstp, buf)); 737 } else { 738 ret.code = kadm5_delete_principal((void *)handle, arg->princ); 739 740 audit_kadmind_auth(rqstp->rq_xprt, l_port, 741 "kadm5_delete_principal", 742 prime_arg, client_name, ret.code); 743 log_done("kadm5_delete_principal", prime_arg, 744 ((ret.code == 0) ? "success" : error_message(ret.code)), 745 client_name, service_name, client_addr(rqstp, buf)); 746 } 747 748 error: 749 if (name) 750 gss_release_name(&min_stat, &name); 751 if (prime_arg) 752 free(prime_arg); 753 free_server_handle(handle); 754 if (client_name) 755 free(client_name); 756 if (service_name) 757 free(service_name); 758 return &ret; 759 } 760 761 generic_ret * 762 modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp) 763 { 764 static generic_ret ret; 765 char *prime_arg = NULL; 766 char *client_name = NULL, *service_name = NULL; 767 OM_uint32 min_stat; 768 kadm5_server_handle_t handle; 769 restriction_t *rp; 770 gss_name_t name = NULL; 771 772 xdr_free(xdr_generic_ret, (char *) &ret); 773 774 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 775 return &ret; 776 777 if ((ret.code = check_handle((void *)handle))) 778 goto error; 779 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 780 ret.code = KADM5_FAILURE; 781 goto error; 782 } 783 if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) { 784 ret.code = KADM5_BAD_PRINCIPAL; 785 goto error; 786 } 787 if (!(name = get_clnt_name(rqstp))) { 788 ret.code = KADM5_FAILURE; 789 goto error; 790 } 791 792 if (CHANGEPW_SERVICE(rqstp) 793 || !kadm5int_acl_check(handle->context, name, ACL_MODIFY, 794 arg->rec.principal, &rp) 795 || kadm5int_acl_impose_restrictions(handle->context, 796 &arg->rec, &arg->mask, rp)) { 797 ret.code = KADM5_AUTH_MODIFY; 798 799 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 800 "kadm5_modify_principal", 801 prime_arg, client_name); 802 log_unauth("kadm5_modify_principal", prime_arg, client_name, 803 service_name, client_addr(rqstp, buf)); 804 } else { 805 ret.code = kadm5_modify_principal((void *)handle, &arg->rec, 806 arg->mask); 807 808 audit_kadmind_auth(rqstp->rq_xprt, l_port, 809 "kadm5_modify_principal", 810 prime_arg, client_name, ret.code); 811 log_done("kadm5_modify_principal", prime_arg, 812 ((ret.code == 0) ? "success" : error_message(ret.code)), 813 client_name, service_name, client_addr(rqstp, buf)); 814 } 815 816 error: 817 if (name) 818 gss_release_name(&min_stat, &name); 819 free_server_handle(handle); 820 if (prime_arg) 821 free(prime_arg); 822 if (client_name) 823 free(client_name); 824 if (service_name) 825 free(service_name); 826 return &ret; 827 } 828 829 generic_ret * 830 rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp) 831 { 832 static generic_ret ret; 833 char *prime_arg1 = NULL, *prime_arg2 = NULL; 834 char prime_arg[BUFSIZ]; 835 char *client_name = NULL, *service_name = NULL; 836 OM_uint32 min_stat; 837 kadm5_server_handle_t handle; 838 restriction_t *rp; 839 gss_name_t name = NULL; 840 size_t tlen1, tlen2, clen, slen; 841 char *tdots1, *tdots2, *cdots, *sdots; 842 843 xdr_free(xdr_generic_ret, (char *) &ret); 844 845 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 846 return &ret; 847 848 if ((ret.code = check_handle((void *)handle))) 849 goto error; 850 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 851 ret.code = KADM5_FAILURE; 852 goto error; 853 } 854 if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) || 855 krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) { 856 ret.code = KADM5_BAD_PRINCIPAL; 857 goto error; 858 } 859 tlen1 = strlen(prime_arg1); 860 trunc_name(&tlen1, &tdots1); 861 tlen2 = strlen(prime_arg2); 862 trunc_name(&tlen2, &tdots2); 863 clen = strlen(client_name); 864 trunc_name(&clen, &cdots); 865 slen = strlen(service_name); 866 trunc_name(&slen, &sdots); 867 868 (void) snprintf(prime_arg, sizeof (prime_arg), "%.*s%s to %.*s*s", 869 tlen1, prime_arg1, tdots1, 870 tlen2, prime_arg2, tdots2); 871 ret.code = KADM5_OK; 872 873 if (!(name = get_clnt_name(rqstp))) { 874 ret.code = KADM5_FAILURE; 875 goto error; 876 } 877 878 if (! CHANGEPW_SERVICE(rqstp)) { 879 if (!kadm5int_acl_check(handle->context, name, 880 ACL_DELETE, arg->src, NULL)) 881 ret.code = KADM5_AUTH_DELETE; 882 /* any restrictions at all on the ADD kills the RENAME */ 883 if (!kadm5int_acl_check(handle->context, name, 884 ACL_ADD, arg->dest, &rp)) { 885 if (ret.code == KADM5_AUTH_DELETE) 886 ret.code = KADM5_AUTH_INSUFFICIENT; 887 else 888 ret.code = KADM5_AUTH_ADD; 889 } 890 } else 891 ret.code = KADM5_AUTH_INSUFFICIENT; 892 if (ret.code != KADM5_OK) { 893 894 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 895 "kadm5_rename_principal", 896 prime_arg, client_name); 897 krb5_klog_syslog(LOG_NOTICE, 898 "Unauthorized request: kadm5_rename_principal, " 899 "%.*s%s to %.*s%s, " 900 "client=%.*s%s, service=%.*s%s, addr=%s", 901 tlen1, prime_arg1, tdots1, 902 tlen2, prime_arg2, tdots2, 903 clen, client_name, cdots, 904 slen, service_name, sdots, 905 client_addr(rqstp, buf)); 906 } else { 907 ret.code = kadm5_rename_principal((void *)handle, arg->src, 908 arg->dest); 909 910 audit_kadmind_auth(rqstp->rq_xprt, l_port, 911 "kadm5_rename_principal", 912 prime_arg, client_name, ret.code); 913 krb5_klog_syslog(LOG_NOTICE, 914 "Request: kadm5_rename_principal, " 915 "%.*s%s to %.*s%s, %s, " 916 "client=%.*s%s, service=%.*s%s, addr=%s", 917 tlen1, prime_arg1, tdots1, 918 tlen2, prime_arg2, tdots2, 919 clen, client_name, cdots, 920 slen, service_name, sdots, 921 client_addr(rqstp, buf)); 922 } 923 924 error: 925 if (name) 926 gss_release_name(&min_stat, &name); 927 free_server_handle(handle); 928 if (prime_arg1) 929 free(prime_arg1); 930 if (prime_arg2) 931 free(prime_arg2); 932 if (client_name) 933 free(client_name); 934 if (service_name) 935 free(service_name); 936 return &ret; 937 } 938 939 gprinc_ret * 940 get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp) 941 { 942 static gprinc_ret ret; 943 kadm5_principal_ent_t_v1 e; 944 char *prime_arg = NULL, *funcname; 945 char *client_name = NULL, *service_name = NULL; 946 OM_uint32 min_stat; 947 kadm5_server_handle_t handle; 948 gss_name_t name = NULL; 949 950 xdr_free(xdr_gprinc_ret, (char *) &ret); 951 952 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 953 return &ret; 954 955 if ((ret.code = check_handle((void *)handle))) 956 goto error; 957 ret.api_version = handle->api_version; 958 959 funcname = handle->api_version == KADM5_API_VERSION_1 ? 960 "kadm5_get_principal (V1)" : "kadm5_get_principal"; 961 962 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 963 ret.code = KADM5_FAILURE; 964 goto error; 965 } 966 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 967 ret.code = KADM5_BAD_PRINCIPAL; 968 goto error; 969 } 970 if (!(name = get_clnt_name(rqstp))) { 971 ret.code = KADM5_FAILURE; 972 goto error; 973 } 974 975 if (! cmp_gss_krb5_name(handle, name, arg->princ) && 976 (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 977 name, 978 ACL_INQUIRE, 979 arg->princ, 980 NULL))) { 981 ret.code = KADM5_AUTH_GET; 982 983 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 984 funcname, 985 prime_arg, client_name); 986 log_unauth(funcname, prime_arg, client_name, service_name, 987 client_addr(rqstp, buf)); 988 } else { 989 if (handle->api_version == KADM5_API_VERSION_1) { 990 ret.code = kadm5_get_principal_v1((void *)handle, 991 arg->princ, &e); 992 if(ret.code == KADM5_OK) { 993 memcpy(&ret.rec, e, sizeof(kadm5_principal_ent_rec_v1)); 994 free(e); 995 } 996 } else { 997 ret.code = kadm5_get_principal((void *)handle, 998 arg->princ, &ret.rec, 999 arg->mask); 1000 } 1001 1002 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1003 funcname, 1004 prime_arg, client_name, ret.code); 1005 log_done(funcname, prime_arg, 1006 ((ret.code == 0) ? "success" : error_message(ret.code)), 1007 client_name, service_name, client_addr(rqstp, buf)); 1008 } 1009 1010 error: 1011 if (name) 1012 gss_release_name(&min_stat, &name); 1013 free_server_handle(handle); 1014 if (prime_arg) 1015 free(prime_arg); 1016 if (client_name) 1017 free(client_name); 1018 if (service_name) 1019 free(service_name); 1020 return &ret; 1021 } 1022 1023 gprincs_ret * 1024 get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp) 1025 { 1026 static gprincs_ret ret; 1027 char *prime_arg = NULL; 1028 char *client_name = NULL, *service_name = NULL; 1029 OM_uint32 min_stat; 1030 kadm5_server_handle_t handle; 1031 gss_name_t name = NULL; 1032 1033 xdr_free(xdr_gprincs_ret, (char *) &ret); 1034 1035 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1036 return &ret; 1037 1038 if ((ret.code = check_handle((void *)handle))) 1039 goto error; 1040 ret.api_version = handle->api_version; 1041 1042 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1043 ret.code = KADM5_FAILURE; 1044 goto error; 1045 } 1046 prime_arg = arg->exp; 1047 if (prime_arg == NULL) 1048 prime_arg = "*"; 1049 1050 if (!(name = get_clnt_name(rqstp))) { 1051 ret.code = KADM5_FAILURE; 1052 goto error; 1053 } 1054 1055 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1056 name, 1057 ACL_LIST, 1058 NULL, 1059 NULL)) { 1060 ret.code = KADM5_AUTH_LIST; 1061 1062 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1063 "kadm5_get_principals", 1064 prime_arg, client_name); 1065 log_unauth("kadm5_get_principals", prime_arg, client_name, 1066 service_name, client_addr(rqstp, buf)); 1067 } else { 1068 ret.code = kadm5_get_principals((void *)handle, 1069 arg->exp, &ret.princs, 1070 &ret.count); 1071 1072 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1073 "kadm5_get_principals", 1074 prime_arg, client_name, ret.code); 1075 log_done("kadm5_get_principals", prime_arg, 1076 ((ret.code == 0) ? "success" : error_message(ret.code)), 1077 client_name, service_name, client_addr(rqstp, buf)); 1078 } 1079 1080 error: 1081 if (name) 1082 gss_release_name(&min_stat, &name); 1083 free_server_handle(handle); 1084 if (client_name) 1085 free(client_name); 1086 if (service_name) 1087 free(service_name); 1088 return (&ret); 1089 } 1090 1091 generic_ret * 1092 chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp) 1093 { 1094 static generic_ret ret; 1095 char *prime_arg = NULL; 1096 char *client_name = NULL, *service_name = NULL; 1097 OM_uint32 min_stat; 1098 kadm5_server_handle_t handle; 1099 gss_name_t name = NULL; 1100 1101 xdr_free(xdr_generic_ret, (char *) &ret); 1102 1103 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1104 return &ret; 1105 1106 if ((ret.code = check_handle((void *)handle))) 1107 goto error; 1108 ret.api_version = handle->api_version; 1109 1110 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1111 ret.code = KADM5_FAILURE; 1112 goto error; 1113 } 1114 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1115 ret.code = KADM5_BAD_PRINCIPAL; 1116 goto error; 1117 } 1118 if (!(name = get_clnt_name(rqstp))) { 1119 ret.code = KADM5_FAILURE; 1120 goto error; 1121 } 1122 1123 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1124 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ, 1125 FALSE, 0, NULL, arg->pass); 1126 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1127 kadm5int_acl_check(handle->context, name, 1128 ACL_CHANGEPW, arg->princ, NULL)) { 1129 ret.code = kadm5_chpass_principal((void *)handle, arg->princ, 1130 arg->pass); 1131 } else { 1132 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1133 "kadm5_chpass_principal", 1134 prime_arg, client_name); 1135 log_unauth("kadm5_chpass_principal", prime_arg, client_name, 1136 service_name, client_addr(rqstp, buf)); 1137 ret.code = KADM5_AUTH_CHANGEPW; 1138 } 1139 1140 if(ret.code != KADM5_AUTH_CHANGEPW) { 1141 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1142 "kadm5_chpass_principal", 1143 prime_arg, client_name, ret.code); 1144 log_done("kadm5_chpass_principal", prime_arg, 1145 ((ret.code == 0) ? "success" : error_message(ret.code)), 1146 client_name, service_name, client_addr(rqstp, buf)); 1147 } 1148 1149 error: 1150 if (name) 1151 gss_release_name(&min_stat, &name); 1152 free_server_handle(handle); 1153 if (prime_arg) 1154 free(prime_arg); 1155 if (client_name) 1156 free(client_name); 1157 if (service_name) 1158 free(service_name); 1159 return (&ret); 1160 } 1161 1162 generic_ret * 1163 chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp) 1164 { 1165 static generic_ret ret; 1166 char *prime_arg = NULL; 1167 char *client_name = NULL, 1168 *service_name = NULL; 1169 OM_uint32 min_stat; 1170 kadm5_server_handle_t handle; 1171 gss_name_t name = NULL; 1172 1173 xdr_free(xdr_generic_ret, (char *) &ret); 1174 1175 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1176 return &ret; 1177 1178 if ((ret.code = check_handle((void *)handle))) 1179 goto error; 1180 ret.api_version = handle->api_version; 1181 1182 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1183 ret.code = KADM5_FAILURE; 1184 goto error; 1185 } 1186 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1187 ret.code = KADM5_BAD_PRINCIPAL; 1188 goto error; 1189 } 1190 if (!(name = get_clnt_name(rqstp))) { 1191 ret.code = KADM5_FAILURE; 1192 goto error; 1193 } 1194 1195 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1196 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ, 1197 arg->keepold, 1198 arg->n_ks_tuple, 1199 arg->ks_tuple, 1200 arg->pass); 1201 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1202 kadm5int_acl_check(handle->context, name, 1203 ACL_CHANGEPW, arg->princ, NULL)) { 1204 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ, 1205 arg->keepold, 1206 arg->n_ks_tuple, 1207 arg->ks_tuple, 1208 arg->pass); 1209 } else { 1210 log_unauth("kadm5_chpass_principal", prime_arg, 1211 client_name, service_name, client_addr(rqstp, buf)); 1212 ret.code = KADM5_AUTH_CHANGEPW; 1213 } 1214 1215 if(ret.code != KADM5_AUTH_CHANGEPW) { 1216 log_done("kadm5_chpass_principal", prime_arg, 1217 ((ret.code == 0) ? "success" : error_message(ret.code)), 1218 client_name, service_name, client_addr(rqstp, buf)); 1219 } 1220 1221 error: 1222 if (name) 1223 gss_release_name(&min_stat, &name); 1224 free_server_handle(handle); 1225 if (client_name) 1226 free(client_name); 1227 if (service_name) 1228 free(service_name); 1229 if (prime_arg) 1230 free(prime_arg); 1231 return (&ret); 1232 } 1233 1234 #ifdef SUNWOFF 1235 generic_ret * 1236 setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp) 1237 { 1238 static generic_ret ret; 1239 char *prime_arg = NULL; 1240 char *client_name = NULL, 1241 *service_name = NULL; 1242 OM_uint32 min_stat; 1243 kadm5_server_handle_t handle; 1244 gss_name_t name = NULL; 1245 1246 xdr_free(xdr_generic_ret, (char *) &ret); 1247 1248 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1249 return &ret; 1250 1251 if ((ret.code = check_handle((void *)handle))) 1252 goto error; 1253 ret.api_version = handle->api_version; 1254 1255 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1256 ret.code = KADM5_FAILURE; 1257 goto error; 1258 } 1259 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1260 ret.code = KADM5_BAD_PRINCIPAL; 1261 goto error; 1262 } 1263 if (!(name = get_clnt_name(rqstp))) { 1264 ret.code = KADM5_FAILURE; 1265 goto error; 1266 } 1267 1268 if (!(CHANGEPW_SERVICE(rqstp)) && 1269 kadm5int_acl_check(handle->context, name, 1270 ACL_SETKEY, arg->princ, NULL)) { 1271 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ, 1272 arg->keyblock); 1273 } else { 1274 log_unauth("kadm5_setv4key_principal", prime_arg, 1275 client_name, service_name, client_addr(rqstp, buf)); 1276 ret.code = KADM5_AUTH_SETKEY; 1277 } 1278 1279 if(ret.code != KADM5_AUTH_SETKEY) { 1280 log_done("kadm5_setv4key_principal", prime_arg, 1281 ((ret.code == 0) ? "success" : error_message(ret.code)), 1282 client_name, service_name, client_addr(rqstp, buf)); 1283 } 1284 1285 error: 1286 if (name) 1287 gss_release_name(&min_stat, &name); 1288 free_server_handle(handle); 1289 if (client_name) 1290 free(client_name); 1291 if (service_name) 1292 free(service_name); 1293 if (prime_arg) 1294 free(prime_arg); 1295 return (&ret); 1296 } 1297 #endif 1298 1299 generic_ret * 1300 setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp) 1301 { 1302 static generic_ret ret; 1303 char *prime_arg; 1304 char *client_name, 1305 *service_name; 1306 OM_uint32 min_stat; 1307 kadm5_server_handle_t handle; 1308 gss_name_t name; 1309 1310 xdr_free(xdr_generic_ret, (char *) &ret); 1311 1312 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1313 return &ret; 1314 1315 if ((ret.code = check_handle((void *)handle))) 1316 goto error; 1317 ret.api_version = handle->api_version; 1318 1319 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1320 ret.code = KADM5_FAILURE; 1321 goto error; 1322 } 1323 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1324 ret.code = KADM5_BAD_PRINCIPAL; 1325 goto error; 1326 } 1327 if (!(name = get_clnt_name(rqstp))) { 1328 ret.code = KADM5_FAILURE; 1329 goto error; 1330 } 1331 1332 if (!(CHANGEPW_SERVICE(rqstp)) && 1333 kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) { 1334 ret.code = kadm5_setkey_principal((void *)handle, arg->princ, 1335 arg->keyblocks, arg->n_keys); 1336 } else { 1337 log_unauth("kadm5_setkey_principal", prime_arg, 1338 client_name, service_name, client_addr(rqstp, buf)); 1339 ret.code = KADM5_AUTH_SETKEY; 1340 } 1341 1342 if(ret.code != KADM5_AUTH_SETKEY) { 1343 log_done("kadm5_setkey_principal", prime_arg, 1344 ((ret.code == 0) ? "success" : error_message(ret.code)), 1345 client_name, service_name, client_addr(rqstp, buf)); 1346 } 1347 1348 error: 1349 if (name) 1350 gss_release_name(&min_stat, &name); 1351 free_server_handle(handle); 1352 if (client_name) 1353 free(client_name); 1354 if (service_name) 1355 free(service_name); 1356 if (prime_arg) 1357 free(prime_arg); 1358 return (&ret); 1359 } 1360 1361 generic_ret * 1362 setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp) 1363 { 1364 static generic_ret ret; 1365 char *prime_arg = NULL; 1366 char *client_name = NULL, 1367 *service_name = NULL; 1368 OM_uint32 min_stat; 1369 kadm5_server_handle_t handle; 1370 gss_name_t name = NULL; 1371 1372 xdr_free(xdr_generic_ret, (char *) &ret); 1373 1374 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1375 return &ret; 1376 1377 if ((ret.code = check_handle((void *)handle))) 1378 goto error; 1379 ret.api_version = handle->api_version; 1380 1381 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1382 ret.code = KADM5_FAILURE; 1383 goto error; 1384 } 1385 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1386 ret.code = KADM5_BAD_PRINCIPAL; 1387 goto error; 1388 } 1389 if (!(name = get_clnt_name(rqstp))) { 1390 ret.code = KADM5_FAILURE; 1391 goto error; 1392 } 1393 1394 if (!(CHANGEPW_SERVICE(rqstp)) && 1395 kadm5int_acl_check(handle->context, name, 1396 ACL_SETKEY, arg->princ, NULL)) { 1397 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ, 1398 arg->keepold, 1399 arg->n_ks_tuple, 1400 arg->ks_tuple, 1401 arg->keyblocks, arg->n_keys); 1402 } else { 1403 log_unauth("kadm5_setkey_principal", prime_arg, 1404 client_name, service_name, client_addr(rqstp, buf)); 1405 ret.code = KADM5_AUTH_SETKEY; 1406 } 1407 1408 if(ret.code != KADM5_AUTH_SETKEY) { 1409 log_done("kadm5_setkey_principal", prime_arg, 1410 ((ret.code == 0) ? "success" : error_message(ret.code)), 1411 client_name, service_name, client_addr(rqstp, buf)); 1412 } 1413 1414 error: 1415 if (name) 1416 gss_release_name(&min_stat, &name); 1417 free_server_handle(handle); 1418 if (client_name) 1419 free(client_name); 1420 if (service_name) 1421 free(service_name); 1422 if (prime_arg) 1423 free(prime_arg); 1424 return &ret; 1425 } 1426 1427 chrand_ret * 1428 chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp) 1429 { 1430 static chrand_ret ret; 1431 krb5_keyblock *k; 1432 int nkeys; 1433 char *prime_arg = NULL, *funcname; 1434 char *client_name = NULL, *service_name = NULL; 1435 OM_uint32 min_stat; 1436 kadm5_server_handle_t handle; 1437 gss_name_t name = NULL; 1438 1439 xdr_free(xdr_chrand_ret, (char *) &ret); 1440 1441 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1442 return &ret; 1443 1444 if ((ret.code = check_handle((void *)handle))) 1445 goto error; 1446 1447 ret.api_version = handle->api_version; 1448 1449 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1450 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal"; 1451 1452 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1453 ret.code = KADM5_FAILURE; 1454 goto error; 1455 } 1456 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1457 ret.code = KADM5_BAD_PRINCIPAL; 1458 goto error; 1459 } 1460 if (!(name = get_clnt_name(rqstp))) { 1461 ret.code = KADM5_FAILURE; 1462 goto error; 1463 } 1464 1465 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1466 ret.code = randkey_principal_wrapper((void *)handle, arg->princ, &k, 1467 &nkeys); 1468 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1469 kadm5int_acl_check(handle->context, name, 1470 ACL_CHANGEPW, arg->princ, NULL)) { 1471 ret.code = kadm5_randkey_principal((void *)handle, arg->princ, 1472 &k, &nkeys); 1473 } else { 1474 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1475 funcname, prime_arg, client_name); 1476 log_unauth(funcname, prime_arg, 1477 client_name, service_name, client_addr(rqstp, buf)); 1478 ret.code = KADM5_AUTH_CHANGEPW; 1479 } 1480 1481 if(ret.code == KADM5_OK) { 1482 if (handle->api_version == KADM5_API_VERSION_1) { 1483 krb5_copy_keyblock_contents(handle->context, k, &ret.key); 1484 krb5_free_keyblock(handle->context, k); 1485 } else { 1486 ret.keys = k; 1487 ret.n_keys = nkeys; 1488 } 1489 } 1490 1491 if(ret.code != KADM5_AUTH_CHANGEPW) { 1492 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1493 funcname, prime_arg, client_name, ret.code); 1494 log_done(funcname, prime_arg, 1495 ((ret.code == 0) ? "success" : error_message(ret.code)), 1496 client_name, service_name, client_addr(rqstp, buf)); 1497 } 1498 1499 error: 1500 if (name) 1501 gss_release_name(&min_stat, &name); 1502 free_server_handle(handle); 1503 if (prime_arg) 1504 free(prime_arg); 1505 if (client_name) 1506 free(client_name); 1507 if (service_name) 1508 free(service_name); 1509 return &ret; 1510 } 1511 1512 chrand_ret * 1513 chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp) 1514 { 1515 static chrand_ret ret; 1516 krb5_keyblock *k; 1517 int nkeys; 1518 char *prime_arg = NULL, *funcname; 1519 char *client_name = NULL, 1520 *service_name = NULL; 1521 OM_uint32 min_stat; 1522 kadm5_server_handle_t handle; 1523 gss_name_t name = NULL; 1524 1525 xdr_free(xdr_chrand_ret, (char *) &ret); 1526 1527 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1528 return &ret; 1529 1530 if ((ret.code = check_handle((void *)handle))) 1531 goto error; 1532 ret.api_version = handle->api_version; 1533 1534 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1535 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal"; 1536 1537 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1538 ret.code = KADM5_FAILURE; 1539 goto error; 1540 } 1541 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1542 ret.code = KADM5_BAD_PRINCIPAL; 1543 goto error; 1544 } 1545 if (!(name = get_clnt_name(rqstp))) { 1546 ret.code = KADM5_FAILURE; 1547 goto error; 1548 } 1549 1550 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1551 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ, 1552 arg->keepold, 1553 arg->n_ks_tuple, 1554 arg->ks_tuple, 1555 &k, &nkeys); 1556 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1557 kadm5int_acl_check(handle->context, name, 1558 ACL_CHANGEPW, arg->princ, NULL)) { 1559 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ, 1560 arg->keepold, 1561 arg->n_ks_tuple, 1562 arg->ks_tuple, 1563 &k, &nkeys); 1564 } else { 1565 log_unauth(funcname, prime_arg, 1566 client_name, service_name, client_addr(rqstp, buf)); 1567 ret.code = KADM5_AUTH_CHANGEPW; 1568 } 1569 1570 if(ret.code == KADM5_OK) { 1571 if (handle->api_version == KADM5_API_VERSION_1) { 1572 krb5_copy_keyblock_contents(handle->context, k, &ret.key); 1573 krb5_free_keyblock(handle->context, k); 1574 } else { 1575 ret.keys = k; 1576 ret.n_keys = nkeys; 1577 } 1578 } 1579 1580 if(ret.code != KADM5_AUTH_CHANGEPW) { 1581 log_done(funcname, prime_arg, 1582 ((ret.code == 0) ? "success" : error_message(ret.code)), 1583 client_name, service_name, client_addr(rqstp, buf)); 1584 } 1585 1586 error: 1587 if (name) 1588 gss_release_name(&min_stat, &name); 1589 free_server_handle(handle); 1590 if (client_name) 1591 free(client_name); 1592 if (service_name) 1593 free(service_name); 1594 if (prime_arg) 1595 free(prime_arg); 1596 return (&ret); 1597 } 1598 1599 generic_ret * 1600 create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp) 1601 { 1602 static generic_ret ret; 1603 char *prime_arg = NULL; 1604 char *client_name = NULL, *service_name = NULL; 1605 OM_uint32 min_stat; 1606 kadm5_server_handle_t handle; 1607 gss_name_t name = NULL; 1608 1609 xdr_free(xdr_generic_ret, (char *) &ret); 1610 1611 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1612 return &ret; 1613 1614 if ((ret.code = check_handle((void *)handle))) 1615 goto error; 1616 1617 ret.api_version = handle->api_version; 1618 1619 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1620 ret.code = KADM5_FAILURE; 1621 goto error; 1622 } 1623 prime_arg = arg->rec.policy; 1624 1625 if (!(name = get_clnt_name(rqstp))) { 1626 ret.code = KADM5_FAILURE; 1627 goto error; 1628 } 1629 1630 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1631 name, 1632 ACL_ADD, NULL, NULL)) { 1633 ret.code = KADM5_AUTH_ADD; 1634 1635 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1636 "kadm5_create_policy", 1637 prime_arg, client_name); 1638 log_unauth("kadm5_create_policy", prime_arg, 1639 client_name, service_name, client_addr(rqstp, buf)); 1640 1641 } else { 1642 ret.code = kadm5_create_policy((void *)handle, &arg->rec, 1643 arg->mask); 1644 1645 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1646 "kadm5_create_policy", 1647 prime_arg, client_name, ret.code); 1648 log_done("kadm5_create_policy", 1649 ((prime_arg == NULL) ? "(null)" : prime_arg), 1650 ((ret.code == 0) ? "success" : error_message(ret.code)), 1651 client_name, service_name, client_addr(rqstp, buf)); 1652 } 1653 1654 error: 1655 if (name) 1656 gss_release_name(&min_stat, &name); 1657 free_server_handle(handle); 1658 if (client_name) 1659 free(client_name); 1660 if (service_name) 1661 free(service_name); 1662 return &ret; 1663 } 1664 1665 generic_ret * 1666 delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp) 1667 { 1668 static generic_ret ret; 1669 char *prime_arg = NULL; 1670 char *client_name = NULL, *service_name = NULL; 1671 OM_uint32 min_stat; 1672 kadm5_server_handle_t handle; 1673 gss_name_t name = NULL; 1674 1675 xdr_free(xdr_generic_ret, (char *) &ret); 1676 1677 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1678 return &ret; 1679 1680 if ((ret.code = check_handle((void *)handle))) 1681 goto error; 1682 ret.api_version = handle->api_version; 1683 1684 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1685 ret.code = KADM5_FAILURE; 1686 goto error; 1687 } 1688 prime_arg = arg->name; 1689 1690 if (!(name = get_clnt_name(rqstp))) { 1691 ret.code = KADM5_FAILURE; 1692 goto error; 1693 } 1694 1695 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1696 name, 1697 ACL_DELETE, NULL, NULL)) { 1698 1699 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1700 "kadm5_delete_policy", 1701 prime_arg, client_name); 1702 log_unauth("kadm5_delete_policy", prime_arg, 1703 client_name, service_name, client_addr(rqstp, buf)); 1704 ret.code = KADM5_AUTH_DELETE; 1705 } else { 1706 ret.code = kadm5_delete_policy((void *)handle, arg->name); 1707 1708 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1709 "kadm5_delete_policy", 1710 prime_arg, client_name, ret.code); 1711 log_done("kadm5_delete_policy", 1712 ((prime_arg == NULL) ? "(null)" : prime_arg), 1713 ((ret.code == 0) ? "success" : error_message(ret.code)), 1714 client_name, service_name, client_addr(rqstp, buf)); 1715 } 1716 1717 error: 1718 if (name) 1719 gss_release_name(&min_stat, &name); 1720 free_server_handle(handle); 1721 if (client_name) 1722 free(client_name); 1723 if (service_name) 1724 free(service_name); 1725 return &ret; 1726 } 1727 1728 generic_ret * 1729 modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp) 1730 { 1731 static generic_ret ret; 1732 char *prime_arg = NULL; 1733 char *client_name = NULL, *service_name = NULL; 1734 OM_uint32 min_stat; 1735 kadm5_server_handle_t handle; 1736 gss_name_t name = NULL; 1737 1738 xdr_free(xdr_generic_ret, (char *) &ret); 1739 1740 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1741 return &ret; 1742 1743 if ((ret.code = check_handle((void *)handle))) 1744 goto error; 1745 ret.api_version = handle->api_version; 1746 1747 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1748 ret.code = KADM5_FAILURE; 1749 goto error; 1750 } 1751 prime_arg = arg->rec.policy; 1752 1753 if (!(name = get_clnt_name(rqstp))) { 1754 ret.code = KADM5_FAILURE; 1755 goto error; 1756 } 1757 1758 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1759 name, 1760 ACL_MODIFY, NULL, NULL)) { 1761 1762 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1763 "kadm5_modify_policy", 1764 prime_arg, client_name); 1765 log_unauth("kadm5_modify_policy", prime_arg, 1766 client_name, service_name, client_addr(rqstp, buf)); 1767 ret.code = KADM5_AUTH_MODIFY; 1768 } else { 1769 ret.code = kadm5_modify_policy((void *)handle, &arg->rec, 1770 arg->mask); 1771 1772 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1773 "kadm5_modify_policy", 1774 prime_arg, client_name, ret.code); 1775 log_done("kadm5_modify_policy", 1776 ((prime_arg == NULL) ? "(null)" : prime_arg), 1777 ((ret.code == 0) ? "success" : error_message(ret.code)), 1778 client_name, service_name, client_addr(rqstp, buf)); 1779 } 1780 1781 error: 1782 if (name) 1783 gss_release_name(&min_stat, &name); 1784 free_server_handle(handle); 1785 if (client_name) 1786 free(client_name); 1787 if (service_name) 1788 free(service_name); 1789 return (&ret); 1790 } 1791 1792 gpol_ret * 1793 get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp) 1794 { 1795 static gpol_ret ret; 1796 kadm5_ret_t ret2; 1797 char *prime_arg = NULL, *funcname; 1798 char *client_name = NULL, *service_name = NULL; 1799 OM_uint32 min_stat; 1800 kadm5_policy_ent_t e; 1801 kadm5_principal_ent_rec caller_ent; 1802 krb5_principal caller; 1803 kadm5_server_handle_t handle; 1804 gss_name_t name = NULL; 1805 1806 xdr_free(xdr_gpol_ret, (char *) &ret); 1807 1808 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1809 return &ret; 1810 1811 if ((ret.code = check_handle((void *) handle))) 1812 goto error; 1813 1814 ret.api_version = handle->api_version; 1815 1816 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1817 "kadm5_get_policy (V1)" : "kadm5_get_policy"; 1818 1819 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1820 ret.code = KADM5_FAILURE; 1821 goto error; 1822 } 1823 prime_arg = arg->name; 1824 ret.code = KADM5_AUTH_GET; 1825 1826 if (!(name = get_clnt_name(rqstp))) { 1827 ret.code = KADM5_FAILURE; 1828 goto error; 1829 } 1830 1831 if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context, 1832 name, 1833 ACL_INQUIRE, NULL, NULL)) 1834 ret.code = KADM5_OK; 1835 else { 1836 ret.code = kadm5_get_principal(handle->lhandle, 1837 handle->current_caller, 1838 &caller_ent, 1839 KADM5_PRINCIPAL_NORMAL_MASK); 1840 if (ret.code == KADM5_OK) { 1841 if (caller_ent.aux_attributes & KADM5_POLICY && 1842 strcmp(caller_ent.policy, arg->name) == 0) { 1843 ret.code = KADM5_OK; 1844 } else ret.code = KADM5_AUTH_GET; 1845 ret2 = kadm5_free_principal_ent(handle->lhandle, 1846 &caller_ent); 1847 ret.code = ret.code ? ret.code : ret2; 1848 } 1849 } 1850 1851 if (ret.code == KADM5_OK) { 1852 if (handle->api_version == KADM5_API_VERSION_1) { 1853 ret.code = kadm5_get_policy_v1((void *)handle, arg->name, &e); 1854 if(ret.code == KADM5_OK) { 1855 memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec)); 1856 free(e); 1857 } 1858 } else { 1859 ret.code = kadm5_get_policy((void *)handle, arg->name, 1860 &ret.rec); 1861 } 1862 1863 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1864 funcname, prime_arg, client_name, ret.code); 1865 log_done(funcname, ((prime_arg == NULL) ? "(null)" : prime_arg), 1866 ((ret.code == 0) ? "success" : error_message(ret.code)), 1867 client_name, service_name, client_addr(rqstp, buf)); 1868 } else { 1869 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1870 funcname, prime_arg, client_name); 1871 log_unauth(funcname, prime_arg, client_name, 1872 service_name, client_addr(rqstp, buf)); 1873 } 1874 1875 error: 1876 if (name) 1877 gss_release_name(&min_stat, &name); 1878 free_server_handle(handle); 1879 if (client_name) 1880 free(client_name); 1881 if (service_name) 1882 free(service_name); 1883 return (&ret); 1884 1885 } 1886 1887 gpols_ret * 1888 get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp) 1889 { 1890 static gpols_ret ret; 1891 char *prime_arg = NULL; 1892 char *client_name = NULL, *service_name = NULL; 1893 OM_uint32 min_stat; 1894 kadm5_server_handle_t handle; 1895 gss_name_t name = NULL; 1896 1897 xdr_free(xdr_gpols_ret, (char *) &ret); 1898 1899 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1900 return &ret; 1901 1902 if ((ret.code = check_handle((void *)handle))) 1903 goto error; 1904 1905 ret.api_version = handle->api_version; 1906 1907 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1908 ret.code = KADM5_FAILURE; 1909 goto error; 1910 } 1911 prime_arg = arg->exp; 1912 if (prime_arg == NULL) 1913 prime_arg = "*"; 1914 1915 if (!(name = get_clnt_name(rqstp))) { 1916 ret.code = KADM5_FAILURE; 1917 goto error; 1918 } 1919 1920 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1921 name, 1922 ACL_LIST, NULL, NULL)) { 1923 ret.code = KADM5_AUTH_LIST; 1924 1925 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1926 "kadm5_get_policies", 1927 prime_arg, client_name); 1928 log_unauth("kadm5_get_policies", prime_arg, 1929 client_name, service_name, client_addr(rqstp, buf)); 1930 } else { 1931 ret.code = kadm5_get_policies((void *)handle, 1932 arg->exp, &ret.pols, 1933 &ret.count); 1934 1935 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1936 "kadm5_get_policies", 1937 prime_arg, client_name, ret.code); 1938 log_done("kadm5_get_policies", prime_arg, 1939 ((ret.code == 0) ? "success" : error_message(ret.code)), 1940 client_name, service_name, client_addr(rqstp, buf)); 1941 } 1942 1943 error: 1944 if (name) 1945 gss_release_name(&min_stat, &name); 1946 free_server_handle(handle); 1947 if (client_name) 1948 free(client_name); 1949 if (service_name) 1950 free(service_name); 1951 return (&ret); 1952 } 1953 1954 getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp) 1955 { 1956 static getprivs_ret ret; 1957 char *client_name = NULL, *service_name = NULL; 1958 OM_uint32 min_stat; 1959 kadm5_server_handle_t handle; 1960 gss_name_t name = NULL; 1961 1962 xdr_free(xdr_getprivs_ret, (char *) &ret); 1963 1964 if ((ret.code = new_server_handle(*arg, rqstp, &handle))) 1965 return &ret; 1966 1967 if ((ret.code = check_handle((void *)handle))) 1968 goto error; 1969 1970 ret.api_version = handle->api_version; 1971 1972 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1973 ret.code = KADM5_FAILURE; 1974 goto error; 1975 } 1976 if (!(name = get_clnt_name(rqstp))) { 1977 ret.code = KADM5_FAILURE; 1978 goto error; 1979 } 1980 1981 ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name); 1982 1983 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1984 "kadm5_get_privs", NULL, client_name, 1985 ret.code); 1986 log_done("kadm5_get_privs", client_name, 1987 ((ret.code == 0) ? "success" : error_message(ret.code)), 1988 client_name, service_name, client_addr(rqstp, buf)); 1989 1990 error: 1991 if (name) 1992 gss_release_name(&min_stat, &name); 1993 free_server_handle(handle); 1994 if (client_name) 1995 free(client_name); 1996 if (service_name) 1997 free(service_name); 1998 return (&ret); 1999 } 2000 2001 generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp) 2002 { 2003 static generic_ret ret; 2004 char *client_name, *service_name; 2005 kadm5_server_handle_t handle; 2006 size_t clen, slen; 2007 char *cdots, *sdots; 2008 2009 xdr_free(xdr_generic_ret, (char *) &ret); 2010 2011 if ((ret.code = new_server_handle(*arg, rqstp, &handle))) 2012 return &ret; 2013 if (! (ret.code = check_handle((void *)handle))) { 2014 ret.api_version = handle->api_version; 2015 } 2016 2017 free_server_handle(handle); 2018 2019 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 2020 ret.code = KADM5_FAILURE; 2021 return &ret; 2022 } 2023 2024 audit_kadmind_auth(rqstp->rq_xprt, l_port, 2025 (ret.api_version == KADM5_API_VERSION_1 ? 2026 "kadm5_init (V1)" : "kadm5_init"), 2027 NULL, client_name, ret.code); 2028 2029 clen = strlen(client_name); 2030 trunc_name(&clen, &cdots); 2031 slen = strlen(service_name); 2032 trunc_name(&slen, &sdots); 2033 krb5_klog_syslog(LOG_NOTICE, "Request %s, %.*s%s, %s, " 2034 "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d", 2035 (ret.api_version == KADM5_API_VERSION_1 ? 2036 "kadm5_init (V1)" : "kadm5_init"), 2037 clen, client_name, cdots, 2038 (ret.code == 0) ? "success" : error_message(ret.code), 2039 clen, client_name, cdots, 2040 slen, service_name, sdots, 2041 client_addr(rqstp, buf), 2042 rqstp->rq_cred.oa_flavor); 2043 free(client_name); 2044 free(service_name); 2045 2046 return (&ret); 2047 } 2048