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