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 841 xdr_free(xdr_generic_ret, (char *) &ret); 842 843 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 844 return &ret; 845 846 if ((ret.code = check_handle((void *)handle))) 847 goto error; 848 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 849 ret.code = KADM5_FAILURE; 850 goto error; 851 } 852 if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) || 853 krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) { 854 ret.code = KADM5_BAD_PRINCIPAL; 855 goto error; 856 } 857 sprintf(prime_arg, "%s to %s", prime_arg1, prime_arg2); 858 859 ret.code = KADM5_OK; 860 861 if (!(name = get_clnt_name(rqstp))) { 862 ret.code = KADM5_FAILURE; 863 goto error; 864 } 865 866 if (! CHANGEPW_SERVICE(rqstp)) { 867 if (!kadm5int_acl_check(handle->context, name, 868 ACL_DELETE, arg->src, NULL)) 869 ret.code = KADM5_AUTH_DELETE; 870 /* any restrictions at all on the ADD kills the RENAME */ 871 if (!kadm5int_acl_check(handle->context, name, 872 ACL_ADD, arg->dest, &rp)) { 873 if (ret.code == KADM5_AUTH_DELETE) 874 ret.code = KADM5_AUTH_INSUFFICIENT; 875 else 876 ret.code = KADM5_AUTH_ADD; 877 } 878 } else 879 ret.code = KADM5_AUTH_INSUFFICIENT; 880 if (ret.code != KADM5_OK) { 881 882 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 883 "kadm5_rename_principal", 884 prime_arg, client_name); 885 log_unauth("kadm5_rename_principal", prime_arg, client_name, 886 service_name, client_addr(rqstp, buf)); 887 } else { 888 ret.code = kadm5_rename_principal((void *)handle, arg->src, 889 arg->dest); 890 891 audit_kadmind_auth(rqstp->rq_xprt, l_port, 892 "kadm5_rename_principal", 893 prime_arg, client_name, ret.code); 894 log_done("kadm5_rename_principal", prime_arg, 895 ((ret.code == 0) ? "success" : error_message(ret.code)), 896 client_name, service_name, client_addr(rqstp, buf)); 897 } 898 899 error: 900 if (name) 901 gss_release_name(&min_stat, &name); 902 free_server_handle(handle); 903 if (prime_arg1) 904 free(prime_arg1); 905 if (prime_arg2) 906 free(prime_arg2); 907 if (client_name) 908 free(client_name); 909 if (service_name) 910 free(service_name); 911 return &ret; 912 } 913 914 gprinc_ret * 915 get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp) 916 { 917 static gprinc_ret ret; 918 kadm5_principal_ent_t_v1 e; 919 char *prime_arg = NULL, *funcname; 920 char *client_name = NULL, *service_name = NULL; 921 OM_uint32 min_stat; 922 kadm5_server_handle_t handle; 923 gss_name_t name = NULL; 924 925 xdr_free(xdr_gprinc_ret, (char *) &ret); 926 927 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 928 return &ret; 929 930 if ((ret.code = check_handle((void *)handle))) 931 goto error; 932 ret.api_version = handle->api_version; 933 934 funcname = handle->api_version == KADM5_API_VERSION_1 ? 935 "kadm5_get_principal (V1)" : "kadm5_get_principal"; 936 937 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 938 ret.code = KADM5_FAILURE; 939 goto error; 940 } 941 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 942 ret.code = KADM5_BAD_PRINCIPAL; 943 goto error; 944 } 945 if (!(name = get_clnt_name(rqstp))) { 946 ret.code = KADM5_FAILURE; 947 goto error; 948 } 949 950 if (! cmp_gss_krb5_name(handle, name, arg->princ) && 951 (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 952 name, 953 ACL_INQUIRE, 954 arg->princ, 955 NULL))) { 956 ret.code = KADM5_AUTH_GET; 957 958 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 959 funcname, 960 prime_arg, client_name); 961 log_unauth(funcname, prime_arg, client_name, service_name, 962 client_addr(rqstp, buf)); 963 } else { 964 if (handle->api_version == KADM5_API_VERSION_1) { 965 ret.code = kadm5_get_principal_v1((void *)handle, 966 arg->princ, &e); 967 if(ret.code == KADM5_OK) { 968 memcpy(&ret.rec, e, sizeof(kadm5_principal_ent_rec_v1)); 969 free(e); 970 } 971 } else { 972 ret.code = kadm5_get_principal((void *)handle, 973 arg->princ, &ret.rec, 974 arg->mask); 975 } 976 977 audit_kadmind_auth(rqstp->rq_xprt, l_port, 978 funcname, 979 prime_arg, client_name, ret.code); 980 log_done(funcname, prime_arg, 981 ((ret.code == 0) ? "success" : error_message(ret.code)), 982 client_name, service_name, client_addr(rqstp, buf)); 983 } 984 985 error: 986 if (name) 987 gss_release_name(&min_stat, &name); 988 free_server_handle(handle); 989 if (prime_arg) 990 free(prime_arg); 991 if (client_name) 992 free(client_name); 993 if (service_name) 994 free(service_name); 995 return &ret; 996 } 997 998 gprincs_ret * 999 get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp) 1000 { 1001 static gprincs_ret ret; 1002 char *prime_arg = NULL; 1003 char *client_name = NULL, *service_name = NULL; 1004 OM_uint32 min_stat; 1005 kadm5_server_handle_t handle; 1006 gss_name_t name = NULL; 1007 1008 xdr_free(xdr_gprincs_ret, (char *) &ret); 1009 1010 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1011 return &ret; 1012 1013 if ((ret.code = check_handle((void *)handle))) 1014 goto error; 1015 ret.api_version = handle->api_version; 1016 1017 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1018 ret.code = KADM5_FAILURE; 1019 goto error; 1020 } 1021 prime_arg = arg->exp; 1022 if (prime_arg == NULL) 1023 prime_arg = "*"; 1024 1025 if (!(name = get_clnt_name(rqstp))) { 1026 ret.code = KADM5_FAILURE; 1027 goto error; 1028 } 1029 1030 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1031 name, 1032 ACL_LIST, 1033 NULL, 1034 NULL)) { 1035 ret.code = KADM5_AUTH_LIST; 1036 1037 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1038 "kadm5_get_principals", 1039 prime_arg, client_name); 1040 log_unauth("kadm5_get_principals", prime_arg, client_name, 1041 service_name, client_addr(rqstp, buf)); 1042 } else { 1043 ret.code = kadm5_get_principals((void *)handle, 1044 arg->exp, &ret.princs, 1045 &ret.count); 1046 1047 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1048 "kadm5_get_principals", 1049 prime_arg, client_name, ret.code); 1050 log_done("kadm5_get_principals", prime_arg, 1051 ((ret.code == 0) ? "success" : error_message(ret.code)), 1052 client_name, service_name, client_addr(rqstp, buf)); 1053 } 1054 1055 error: 1056 if (name) 1057 gss_release_name(&min_stat, &name); 1058 free_server_handle(handle); 1059 if (client_name) 1060 free(client_name); 1061 if (service_name) 1062 free(service_name); 1063 return (&ret); 1064 } 1065 1066 generic_ret * 1067 chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp) 1068 { 1069 static generic_ret ret; 1070 char *prime_arg = NULL; 1071 char *client_name = NULL, *service_name = NULL; 1072 OM_uint32 min_stat; 1073 kadm5_server_handle_t handle; 1074 gss_name_t name = NULL; 1075 1076 xdr_free(xdr_generic_ret, (char *) &ret); 1077 1078 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1079 return &ret; 1080 1081 if ((ret.code = check_handle((void *)handle))) 1082 goto error; 1083 ret.api_version = handle->api_version; 1084 1085 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1086 ret.code = KADM5_FAILURE; 1087 goto error; 1088 } 1089 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1090 ret.code = KADM5_BAD_PRINCIPAL; 1091 goto error; 1092 } 1093 if (!(name = get_clnt_name(rqstp))) { 1094 ret.code = KADM5_FAILURE; 1095 goto error; 1096 } 1097 1098 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1099 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ, 1100 FALSE, 0, NULL, arg->pass); 1101 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1102 kadm5int_acl_check(handle->context, name, 1103 ACL_CHANGEPW, arg->princ, NULL)) { 1104 ret.code = kadm5_chpass_principal((void *)handle, arg->princ, 1105 arg->pass); 1106 } else { 1107 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1108 "kadm5_chpass_principal", 1109 prime_arg, client_name); 1110 log_unauth("kadm5_chpass_principal", prime_arg, client_name, 1111 service_name, client_addr(rqstp, buf)); 1112 ret.code = KADM5_AUTH_CHANGEPW; 1113 } 1114 1115 if(ret.code != KADM5_AUTH_CHANGEPW) { 1116 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1117 "kadm5_chpass_principal", 1118 prime_arg, client_name, ret.code); 1119 log_done("kadm5_chpass_principal", prime_arg, 1120 ((ret.code == 0) ? "success" : error_message(ret.code)), 1121 client_name, service_name, client_addr(rqstp, buf)); 1122 } 1123 1124 error: 1125 if (name) 1126 gss_release_name(&min_stat, &name); 1127 free_server_handle(handle); 1128 if (prime_arg) 1129 free(prime_arg); 1130 if (client_name) 1131 free(client_name); 1132 if (service_name) 1133 free(service_name); 1134 return (&ret); 1135 } 1136 1137 generic_ret * 1138 chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp) 1139 { 1140 static generic_ret ret; 1141 char *prime_arg = NULL; 1142 char *client_name = NULL, 1143 *service_name = NULL; 1144 OM_uint32 min_stat; 1145 kadm5_server_handle_t handle; 1146 gss_name_t name = NULL; 1147 1148 xdr_free(xdr_generic_ret, (char *) &ret); 1149 1150 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1151 return &ret; 1152 1153 if ((ret.code = check_handle((void *)handle))) 1154 goto error; 1155 ret.api_version = handle->api_version; 1156 1157 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1158 ret.code = KADM5_FAILURE; 1159 goto error; 1160 } 1161 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1162 ret.code = KADM5_BAD_PRINCIPAL; 1163 goto error; 1164 } 1165 if (!(name = get_clnt_name(rqstp))) { 1166 ret.code = KADM5_FAILURE; 1167 goto error; 1168 } 1169 1170 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1171 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ, 1172 arg->keepold, 1173 arg->n_ks_tuple, 1174 arg->ks_tuple, 1175 arg->pass); 1176 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1177 kadm5int_acl_check(handle->context, name, 1178 ACL_CHANGEPW, arg->princ, NULL)) { 1179 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ, 1180 arg->keepold, 1181 arg->n_ks_tuple, 1182 arg->ks_tuple, 1183 arg->pass); 1184 } else { 1185 log_unauth("kadm5_chpass_principal", prime_arg, 1186 client_name, service_name, client_addr(rqstp, buf)); 1187 ret.code = KADM5_AUTH_CHANGEPW; 1188 } 1189 1190 if(ret.code != KADM5_AUTH_CHANGEPW) { 1191 log_done("kadm5_chpass_principal", prime_arg, 1192 ((ret.code == 0) ? "success" : error_message(ret.code)), 1193 client_name, service_name, client_addr(rqstp, buf)); 1194 } 1195 1196 error: 1197 if (name) 1198 gss_release_name(&min_stat, &name); 1199 free_server_handle(handle); 1200 if (client_name) 1201 free(client_name); 1202 if (service_name) 1203 free(service_name); 1204 if (prime_arg) 1205 free(prime_arg); 1206 return (&ret); 1207 } 1208 1209 #ifdef SUNWOFF 1210 generic_ret * 1211 setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp) 1212 { 1213 static generic_ret ret; 1214 char *prime_arg = NULL; 1215 char *client_name = NULL, 1216 *service_name = NULL; 1217 OM_uint32 min_stat; 1218 kadm5_server_handle_t handle; 1219 gss_name_t name = NULL; 1220 1221 xdr_free(xdr_generic_ret, (char *) &ret); 1222 1223 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1224 return &ret; 1225 1226 if ((ret.code = check_handle((void *)handle))) 1227 goto error; 1228 ret.api_version = handle->api_version; 1229 1230 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1231 ret.code = KADM5_FAILURE; 1232 goto error; 1233 } 1234 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1235 ret.code = KADM5_BAD_PRINCIPAL; 1236 goto error; 1237 } 1238 if (!(name = get_clnt_name(rqstp))) { 1239 ret.code = KADM5_FAILURE; 1240 goto error; 1241 } 1242 1243 if (!(CHANGEPW_SERVICE(rqstp)) && 1244 kadm5int_acl_check(handle->context, name, 1245 ACL_SETKEY, arg->princ, NULL)) { 1246 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ, 1247 arg->keyblock); 1248 } else { 1249 log_unauth("kadm5_setv4key_principal", prime_arg, 1250 client_name, service_name, client_addr(rqstp, buf)); 1251 ret.code = KADM5_AUTH_SETKEY; 1252 } 1253 1254 if(ret.code != KADM5_AUTH_SETKEY) { 1255 log_done("kadm5_setv4key_principal", prime_arg, 1256 ((ret.code == 0) ? "success" : error_message(ret.code)), 1257 client_name, service_name, client_addr(rqstp, buf)); 1258 } 1259 1260 error: 1261 if (name) 1262 gss_release_name(&min_stat, &name); 1263 free_server_handle(handle); 1264 if (client_name) 1265 free(client_name); 1266 if (service_name) 1267 free(service_name); 1268 if (prime_arg) 1269 free(prime_arg); 1270 return (&ret); 1271 } 1272 #endif 1273 1274 generic_ret * 1275 setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp) 1276 { 1277 static generic_ret ret; 1278 char *prime_arg; 1279 char *client_name, 1280 *service_name; 1281 OM_uint32 min_stat; 1282 kadm5_server_handle_t handle; 1283 gss_name_t name; 1284 1285 xdr_free(xdr_generic_ret, (char *) &ret); 1286 1287 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1288 return &ret; 1289 1290 if ((ret.code = check_handle((void *)handle))) 1291 goto error; 1292 ret.api_version = handle->api_version; 1293 1294 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1295 ret.code = KADM5_FAILURE; 1296 goto error; 1297 } 1298 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1299 ret.code = KADM5_BAD_PRINCIPAL; 1300 goto error; 1301 } 1302 if (!(name = get_clnt_name(rqstp))) { 1303 ret.code = KADM5_FAILURE; 1304 goto error; 1305 } 1306 1307 if (!(CHANGEPW_SERVICE(rqstp)) && 1308 kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) { 1309 ret.code = kadm5_setkey_principal((void *)handle, arg->princ, 1310 arg->keyblocks, arg->n_keys); 1311 } else { 1312 log_unauth("kadm5_setkey_principal", prime_arg, 1313 client_name, service_name, client_addr(rqstp, buf)); 1314 ret.code = KADM5_AUTH_SETKEY; 1315 } 1316 1317 if(ret.code != KADM5_AUTH_SETKEY) { 1318 log_done("kadm5_setkey_principal", prime_arg, 1319 ((ret.code == 0) ? "success" : error_message(ret.code)), 1320 client_name, service_name, client_addr(rqstp, buf)); 1321 } 1322 1323 error: 1324 if (name) 1325 gss_release_name(&min_stat, &name); 1326 free_server_handle(handle); 1327 if (client_name) 1328 free(client_name); 1329 if (service_name) 1330 free(service_name); 1331 if (prime_arg) 1332 free(prime_arg); 1333 return (&ret); 1334 } 1335 1336 generic_ret * 1337 setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp) 1338 { 1339 static generic_ret ret; 1340 char *prime_arg = NULL; 1341 char *client_name = NULL, 1342 *service_name = NULL; 1343 OM_uint32 min_stat; 1344 kadm5_server_handle_t handle; 1345 gss_name_t name = NULL; 1346 1347 xdr_free(xdr_generic_ret, (char *) &ret); 1348 1349 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1350 return &ret; 1351 1352 if ((ret.code = check_handle((void *)handle))) 1353 goto error; 1354 ret.api_version = handle->api_version; 1355 1356 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1357 ret.code = KADM5_FAILURE; 1358 goto error; 1359 } 1360 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1361 ret.code = KADM5_BAD_PRINCIPAL; 1362 goto error; 1363 } 1364 if (!(name = get_clnt_name(rqstp))) { 1365 ret.code = KADM5_FAILURE; 1366 goto error; 1367 } 1368 1369 if (!(CHANGEPW_SERVICE(rqstp)) && 1370 kadm5int_acl_check(handle->context, name, 1371 ACL_SETKEY, arg->princ, NULL)) { 1372 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ, 1373 arg->keepold, 1374 arg->n_ks_tuple, 1375 arg->ks_tuple, 1376 arg->keyblocks, arg->n_keys); 1377 } else { 1378 log_unauth("kadm5_setkey_principal", prime_arg, 1379 client_name, service_name, client_addr(rqstp, buf)); 1380 ret.code = KADM5_AUTH_SETKEY; 1381 } 1382 1383 if(ret.code != KADM5_AUTH_SETKEY) { 1384 log_done("kadm5_setkey_principal", prime_arg, 1385 ((ret.code == 0) ? "success" : error_message(ret.code)), 1386 client_name, service_name, client_addr(rqstp, buf)); 1387 } 1388 1389 error: 1390 if (name) 1391 gss_release_name(&min_stat, &name); 1392 free_server_handle(handle); 1393 if (client_name) 1394 free(client_name); 1395 if (service_name) 1396 free(service_name); 1397 if (prime_arg) 1398 free(prime_arg); 1399 return &ret; 1400 } 1401 1402 chrand_ret * 1403 chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp) 1404 { 1405 static chrand_ret ret; 1406 krb5_keyblock *k; 1407 int nkeys; 1408 char *prime_arg = NULL, *funcname; 1409 char *client_name = NULL, *service_name = NULL; 1410 OM_uint32 min_stat; 1411 kadm5_server_handle_t handle; 1412 gss_name_t name = NULL; 1413 1414 xdr_free(xdr_chrand_ret, (char *) &ret); 1415 1416 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1417 return &ret; 1418 1419 if ((ret.code = check_handle((void *)handle))) 1420 goto error; 1421 1422 ret.api_version = handle->api_version; 1423 1424 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1425 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal"; 1426 1427 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1428 ret.code = KADM5_FAILURE; 1429 goto error; 1430 } 1431 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1432 ret.code = KADM5_BAD_PRINCIPAL; 1433 goto error; 1434 } 1435 if (!(name = get_clnt_name(rqstp))) { 1436 ret.code = KADM5_FAILURE; 1437 goto error; 1438 } 1439 1440 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1441 ret.code = randkey_principal_wrapper((void *)handle, arg->princ, &k, 1442 &nkeys); 1443 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1444 kadm5int_acl_check(handle->context, name, 1445 ACL_CHANGEPW, arg->princ, NULL)) { 1446 ret.code = kadm5_randkey_principal((void *)handle, arg->princ, 1447 &k, &nkeys); 1448 } else { 1449 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1450 funcname, prime_arg, client_name); 1451 log_unauth(funcname, prime_arg, 1452 client_name, service_name, client_addr(rqstp, buf)); 1453 ret.code = KADM5_AUTH_CHANGEPW; 1454 } 1455 1456 if(ret.code == KADM5_OK) { 1457 if (handle->api_version == KADM5_API_VERSION_1) { 1458 krb5_copy_keyblock_contents(handle->context, k, &ret.key); 1459 krb5_free_keyblock(handle->context, k); 1460 } else { 1461 ret.keys = k; 1462 ret.n_keys = nkeys; 1463 } 1464 } 1465 1466 if(ret.code != KADM5_AUTH_CHANGEPW) { 1467 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1468 funcname, prime_arg, client_name, ret.code); 1469 log_done(funcname, prime_arg, 1470 ((ret.code == 0) ? "success" : error_message(ret.code)), 1471 client_name, service_name, client_addr(rqstp, buf)); 1472 } 1473 1474 error: 1475 if (name) 1476 gss_release_name(&min_stat, &name); 1477 free_server_handle(handle); 1478 if (prime_arg) 1479 free(prime_arg); 1480 if (client_name) 1481 free(client_name); 1482 if (service_name) 1483 free(service_name); 1484 return &ret; 1485 } 1486 1487 chrand_ret * 1488 chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp) 1489 { 1490 static chrand_ret ret; 1491 krb5_keyblock *k; 1492 int nkeys; 1493 char *prime_arg = NULL, *funcname; 1494 char *client_name = NULL, 1495 *service_name = NULL; 1496 OM_uint32 min_stat; 1497 kadm5_server_handle_t handle; 1498 gss_name_t name = NULL; 1499 1500 xdr_free(xdr_chrand_ret, (char *) &ret); 1501 1502 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1503 return &ret; 1504 1505 if ((ret.code = check_handle((void *)handle))) 1506 goto error; 1507 ret.api_version = handle->api_version; 1508 1509 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1510 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal"; 1511 1512 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1513 ret.code = KADM5_FAILURE; 1514 goto error; 1515 } 1516 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1517 ret.code = KADM5_BAD_PRINCIPAL; 1518 goto error; 1519 } 1520 if (!(name = get_clnt_name(rqstp))) { 1521 ret.code = KADM5_FAILURE; 1522 goto error; 1523 } 1524 1525 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1526 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ, 1527 arg->keepold, 1528 arg->n_ks_tuple, 1529 arg->ks_tuple, 1530 &k, &nkeys); 1531 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1532 kadm5int_acl_check(handle->context, name, 1533 ACL_CHANGEPW, arg->princ, NULL)) { 1534 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ, 1535 arg->keepold, 1536 arg->n_ks_tuple, 1537 arg->ks_tuple, 1538 &k, &nkeys); 1539 } else { 1540 log_unauth(funcname, prime_arg, 1541 client_name, service_name, client_addr(rqstp, buf)); 1542 ret.code = KADM5_AUTH_CHANGEPW; 1543 } 1544 1545 if(ret.code == KADM5_OK) { 1546 if (handle->api_version == KADM5_API_VERSION_1) { 1547 krb5_copy_keyblock_contents(handle->context, k, &ret.key); 1548 krb5_free_keyblock(handle->context, k); 1549 } else { 1550 ret.keys = k; 1551 ret.n_keys = nkeys; 1552 } 1553 } 1554 1555 if(ret.code != KADM5_AUTH_CHANGEPW) { 1556 log_done(funcname, prime_arg, 1557 ((ret.code == 0) ? "success" : error_message(ret.code)), 1558 client_name, service_name, client_addr(rqstp, buf)); 1559 } 1560 1561 error: 1562 if (name) 1563 gss_release_name(&min_stat, &name); 1564 free_server_handle(handle); 1565 if (client_name) 1566 free(client_name); 1567 if (service_name) 1568 free(service_name); 1569 if (prime_arg) 1570 free(prime_arg); 1571 return (&ret); 1572 } 1573 1574 generic_ret * 1575 create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp) 1576 { 1577 static generic_ret ret; 1578 char *prime_arg = NULL; 1579 char *client_name = NULL, *service_name = NULL; 1580 OM_uint32 min_stat; 1581 kadm5_server_handle_t handle; 1582 gss_name_t name = NULL; 1583 1584 xdr_free(xdr_generic_ret, (char *) &ret); 1585 1586 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1587 return &ret; 1588 1589 if ((ret.code = check_handle((void *)handle))) 1590 goto error; 1591 1592 ret.api_version = handle->api_version; 1593 1594 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1595 ret.code = KADM5_FAILURE; 1596 goto error; 1597 } 1598 prime_arg = arg->rec.policy; 1599 1600 if (!(name = get_clnt_name(rqstp))) { 1601 ret.code = KADM5_FAILURE; 1602 goto error; 1603 } 1604 1605 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1606 name, 1607 ACL_ADD, NULL, NULL)) { 1608 ret.code = KADM5_AUTH_ADD; 1609 1610 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1611 "kadm5_create_policy", 1612 prime_arg, client_name); 1613 log_unauth("kadm5_create_policy", prime_arg, 1614 client_name, service_name, client_addr(rqstp, buf)); 1615 1616 } else { 1617 ret.code = kadm5_create_policy((void *)handle, &arg->rec, 1618 arg->mask); 1619 1620 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1621 "kadm5_create_policy", 1622 prime_arg, client_name, ret.code); 1623 log_done("kadm5_create_policy", 1624 ((prime_arg == NULL) ? "(null)" : prime_arg), 1625 ((ret.code == 0) ? "success" : error_message(ret.code)), 1626 client_name, service_name, client_addr(rqstp, buf)); 1627 } 1628 1629 error: 1630 if (name) 1631 gss_release_name(&min_stat, &name); 1632 free_server_handle(handle); 1633 if (client_name) 1634 free(client_name); 1635 if (service_name) 1636 free(service_name); 1637 return &ret; 1638 } 1639 1640 generic_ret * 1641 delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp) 1642 { 1643 static generic_ret ret; 1644 char *prime_arg = NULL; 1645 char *client_name = NULL, *service_name = NULL; 1646 OM_uint32 min_stat; 1647 kadm5_server_handle_t handle; 1648 gss_name_t name = NULL; 1649 1650 xdr_free(xdr_generic_ret, (char *) &ret); 1651 1652 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1653 return &ret; 1654 1655 if ((ret.code = check_handle((void *)handle))) 1656 goto error; 1657 ret.api_version = handle->api_version; 1658 1659 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1660 ret.code = KADM5_FAILURE; 1661 goto error; 1662 } 1663 prime_arg = arg->name; 1664 1665 if (!(name = get_clnt_name(rqstp))) { 1666 ret.code = KADM5_FAILURE; 1667 goto error; 1668 } 1669 1670 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1671 name, 1672 ACL_DELETE, NULL, NULL)) { 1673 1674 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1675 "kadm5_delete_policy", 1676 prime_arg, client_name); 1677 log_unauth("kadm5_delete_policy", prime_arg, 1678 client_name, service_name, client_addr(rqstp, buf)); 1679 ret.code = KADM5_AUTH_DELETE; 1680 } else { 1681 ret.code = kadm5_delete_policy((void *)handle, arg->name); 1682 1683 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1684 "kadm5_delete_policy", 1685 prime_arg, client_name, ret.code); 1686 log_done("kadm5_delete_policy", 1687 ((prime_arg == NULL) ? "(null)" : prime_arg), 1688 ((ret.code == 0) ? "success" : error_message(ret.code)), 1689 client_name, service_name, client_addr(rqstp, buf)); 1690 } 1691 1692 error: 1693 if (name) 1694 gss_release_name(&min_stat, &name); 1695 free_server_handle(handle); 1696 if (client_name) 1697 free(client_name); 1698 if (service_name) 1699 free(service_name); 1700 return &ret; 1701 } 1702 1703 generic_ret * 1704 modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp) 1705 { 1706 static generic_ret ret; 1707 char *prime_arg = NULL; 1708 char *client_name = NULL, *service_name = NULL; 1709 OM_uint32 min_stat; 1710 kadm5_server_handle_t handle; 1711 gss_name_t name = NULL; 1712 1713 xdr_free(xdr_generic_ret, (char *) &ret); 1714 1715 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1716 return &ret; 1717 1718 if ((ret.code = check_handle((void *)handle))) 1719 goto error; 1720 ret.api_version = handle->api_version; 1721 1722 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1723 ret.code = KADM5_FAILURE; 1724 goto error; 1725 } 1726 prime_arg = arg->rec.policy; 1727 1728 if (!(name = get_clnt_name(rqstp))) { 1729 ret.code = KADM5_FAILURE; 1730 goto error; 1731 } 1732 1733 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1734 name, 1735 ACL_MODIFY, NULL, NULL)) { 1736 1737 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1738 "kadm5_modify_policy", 1739 prime_arg, client_name); 1740 log_unauth("kadm5_modify_policy", prime_arg, 1741 client_name, service_name, client_addr(rqstp, buf)); 1742 ret.code = KADM5_AUTH_MODIFY; 1743 } else { 1744 ret.code = kadm5_modify_policy((void *)handle, &arg->rec, 1745 arg->mask); 1746 1747 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1748 "kadm5_modify_policy", 1749 prime_arg, client_name, ret.code); 1750 log_done("kadm5_modify_policy", 1751 ((prime_arg == NULL) ? "(null)" : prime_arg), 1752 ((ret.code == 0) ? "success" : error_message(ret.code)), 1753 client_name, service_name, client_addr(rqstp, buf)); 1754 } 1755 1756 error: 1757 if (name) 1758 gss_release_name(&min_stat, &name); 1759 free_server_handle(handle); 1760 if (client_name) 1761 free(client_name); 1762 if (service_name) 1763 free(service_name); 1764 return (&ret); 1765 } 1766 1767 gpol_ret * 1768 get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp) 1769 { 1770 static gpol_ret ret; 1771 kadm5_ret_t ret2; 1772 char *prime_arg = NULL, *funcname; 1773 char *client_name = NULL, *service_name = NULL; 1774 OM_uint32 min_stat; 1775 kadm5_policy_ent_t e; 1776 kadm5_principal_ent_rec caller_ent; 1777 krb5_principal caller; 1778 kadm5_server_handle_t handle; 1779 gss_name_t name = NULL; 1780 1781 xdr_free(xdr_gpol_ret, (char *) &ret); 1782 1783 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1784 return &ret; 1785 1786 if ((ret.code = check_handle((void *) handle))) 1787 goto error; 1788 1789 ret.api_version = handle->api_version; 1790 1791 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1792 "kadm5_get_policy (V1)" : "kadm5_get_policy"; 1793 1794 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1795 ret.code = KADM5_FAILURE; 1796 goto error; 1797 } 1798 prime_arg = arg->name; 1799 ret.code = KADM5_AUTH_GET; 1800 1801 if (!(name = get_clnt_name(rqstp))) { 1802 ret.code = KADM5_FAILURE; 1803 goto error; 1804 } 1805 1806 if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context, 1807 name, 1808 ACL_INQUIRE, NULL, NULL)) 1809 ret.code = KADM5_OK; 1810 else { 1811 ret.code = kadm5_get_principal(handle->lhandle, 1812 handle->current_caller, 1813 &caller_ent, 1814 KADM5_PRINCIPAL_NORMAL_MASK); 1815 if (ret.code == KADM5_OK) { 1816 if (caller_ent.aux_attributes & KADM5_POLICY && 1817 strcmp(caller_ent.policy, arg->name) == 0) { 1818 ret.code = KADM5_OK; 1819 } else ret.code = KADM5_AUTH_GET; 1820 ret2 = kadm5_free_principal_ent(handle->lhandle, 1821 &caller_ent); 1822 ret.code = ret.code ? ret.code : ret2; 1823 } 1824 } 1825 1826 if (ret.code == KADM5_OK) { 1827 if (handle->api_version == KADM5_API_VERSION_1) { 1828 ret.code = kadm5_get_policy_v1((void *)handle, arg->name, &e); 1829 if(ret.code == KADM5_OK) { 1830 memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec)); 1831 free(e); 1832 } 1833 } else { 1834 ret.code = kadm5_get_policy((void *)handle, arg->name, 1835 &ret.rec); 1836 } 1837 1838 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1839 funcname, prime_arg, client_name, ret.code); 1840 log_done(funcname, ((prime_arg == NULL) ? "(null)" : prime_arg), 1841 ((ret.code == 0) ? "success" : error_message(ret.code)), 1842 client_name, service_name, client_addr(rqstp, buf)); 1843 } else { 1844 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1845 funcname, prime_arg, client_name); 1846 log_unauth(funcname, prime_arg, client_name, 1847 service_name, client_addr(rqstp, buf)); 1848 } 1849 1850 error: 1851 if (name) 1852 gss_release_name(&min_stat, &name); 1853 free_server_handle(handle); 1854 if (client_name) 1855 free(client_name); 1856 if (service_name) 1857 free(service_name); 1858 return (&ret); 1859 1860 } 1861 1862 gpols_ret * 1863 get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp) 1864 { 1865 static gpols_ret ret; 1866 char *prime_arg = NULL; 1867 char *client_name = NULL, *service_name = NULL; 1868 OM_uint32 min_stat; 1869 kadm5_server_handle_t handle; 1870 gss_name_t name = NULL; 1871 1872 xdr_free(xdr_gpols_ret, (char *) &ret); 1873 1874 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1875 return &ret; 1876 1877 if ((ret.code = check_handle((void *)handle))) 1878 goto error; 1879 1880 ret.api_version = handle->api_version; 1881 1882 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1883 ret.code = KADM5_FAILURE; 1884 goto error; 1885 } 1886 prime_arg = arg->exp; 1887 if (prime_arg == NULL) 1888 prime_arg = "*"; 1889 1890 if (!(name = get_clnt_name(rqstp))) { 1891 ret.code = KADM5_FAILURE; 1892 goto error; 1893 } 1894 1895 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1896 name, 1897 ACL_LIST, NULL, NULL)) { 1898 ret.code = KADM5_AUTH_LIST; 1899 1900 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1901 "kadm5_get_policies", 1902 prime_arg, client_name); 1903 log_unauth("kadm5_get_policies", prime_arg, 1904 client_name, service_name, client_addr(rqstp, buf)); 1905 } else { 1906 ret.code = kadm5_get_policies((void *)handle, 1907 arg->exp, &ret.pols, 1908 &ret.count); 1909 1910 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1911 "kadm5_get_policies", 1912 prime_arg, client_name, ret.code); 1913 log_done("kadm5_get_policies", prime_arg, 1914 ((ret.code == 0) ? "success" : error_message(ret.code)), 1915 client_name, service_name, client_addr(rqstp, buf)); 1916 } 1917 1918 error: 1919 if (name) 1920 gss_release_name(&min_stat, &name); 1921 free_server_handle(handle); 1922 if (client_name) 1923 free(client_name); 1924 if (service_name) 1925 free(service_name); 1926 return (&ret); 1927 } 1928 1929 getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp) 1930 { 1931 static getprivs_ret ret; 1932 char *client_name = NULL, *service_name = NULL; 1933 OM_uint32 min_stat; 1934 kadm5_server_handle_t handle; 1935 gss_name_t name = NULL; 1936 1937 xdr_free(xdr_getprivs_ret, (char *) &ret); 1938 1939 if ((ret.code = new_server_handle(*arg, rqstp, &handle))) 1940 return &ret; 1941 1942 if ((ret.code = check_handle((void *)handle))) 1943 goto error; 1944 1945 ret.api_version = handle->api_version; 1946 1947 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1948 ret.code = KADM5_FAILURE; 1949 goto error; 1950 } 1951 if (!(name = get_clnt_name(rqstp))) { 1952 ret.code = KADM5_FAILURE; 1953 goto error; 1954 } 1955 1956 ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name); 1957 1958 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1959 "kadm5_get_privs", NULL, client_name, 1960 ret.code); 1961 log_done("kadm5_get_privs", client_name, 1962 ((ret.code == 0) ? "success" : error_message(ret.code)), 1963 client_name, service_name, client_addr(rqstp, buf)); 1964 1965 error: 1966 if (name) 1967 gss_release_name(&min_stat, &name); 1968 free_server_handle(handle); 1969 if (client_name) 1970 free(client_name); 1971 if (service_name) 1972 free(service_name); 1973 return (&ret); 1974 } 1975 1976 generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp) 1977 { 1978 static generic_ret ret; 1979 char *client_name, *service_name; 1980 kadm5_server_handle_t handle; 1981 size_t clen, slen; 1982 char *cdots, *sdots; 1983 1984 xdr_free(xdr_generic_ret, (char *) &ret); 1985 1986 if ((ret.code = new_server_handle(*arg, rqstp, &handle))) 1987 return &ret; 1988 if (! (ret.code = check_handle((void *)handle))) { 1989 ret.api_version = handle->api_version; 1990 } 1991 1992 free_server_handle(handle); 1993 1994 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1995 ret.code = KADM5_FAILURE; 1996 return &ret; 1997 } 1998 1999 audit_kadmind_auth(rqstp->rq_xprt, l_port, 2000 (ret.api_version == KADM5_API_VERSION_1 ? 2001 "kadm5_init (V1)" : "kadm5_init"), 2002 NULL, client_name, ret.code); 2003 2004 clen = strlen(client_name); 2005 trunc_name(&clen, &cdots); 2006 slen = strlen(service_name); 2007 trunc_name(&slen, &sdots); 2008 krb5_klog_syslog(LOG_NOTICE, "Request %s, %.*s%s, %s, " 2009 "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d", 2010 (ret.api_version == KADM5_API_VERSION_1 ? 2011 "kadm5_init (V1)" : "kadm5_init"), 2012 clen, client_name, cdots, 2013 (ret.code == 0) ? "success" : error_message(ret.code), 2014 clen, client_name, cdots, 2015 slen, service_name, sdots, 2016 client_addr(rqstp, buf), 2017 rqstp->rq_cred.oa_flavor); 2018 free(client_name); 2019 free(service_name); 2020 2021 return (&ret); 2022 } 2023