1 /* 2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 10 * 11 * Openvision retains the copyright to derivative works of 12 * this source code. Do *NOT* create a derivative of this 13 * source code before consulting with your legal department. 14 * Do *NOT* integrate *ANY* of this source code into another 15 * product before consulting with your legal department. 16 * 17 * For further information, read the top-level Openvision 18 * copyright which is contained in the top-level MIT Kerberos 19 * copyright. 20 * 21 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 22 * 23 */ 24 25 26 /* 27 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 28 * 29 */ 30 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 generic_ret * 448 create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp) 449 { 450 static generic_ret ret; 451 char *prime_arg = NULL; 452 char *client_name = NULL, *service_name = NULL; 453 int policy_migrate = 0; 454 455 OM_uint32 minor_stat; 456 kadm5_server_handle_t handle; 457 kadm5_ret_t retval; 458 restriction_t *rp; 459 gss_name_t name = NULL; 460 461 xdr_free(xdr_generic_ret, (char *) &ret); 462 463 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 464 return &ret; 465 466 if ((ret.code = check_handle((void *)handle))) 467 goto error; 468 ret.api_version = handle->api_version; 469 470 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 471 ret.code = KADM5_FAILURE; 472 goto error; 473 } 474 if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) { 475 ret.code = KADM5_BAD_PRINCIPAL; 476 goto error; 477 } 478 if (!(name = get_clnt_name(rqstp))) { 479 ret.code = KADM5_FAILURE; 480 goto error; 481 } 482 483 if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE, 484 arg->rec.principal, &rp) && 485 verify_pam_pw(prime_arg, arg->passwd)) { 486 policy_migrate = 1; 487 } 488 489 if (CHANGEPW_SERVICE(rqstp) 490 || (!kadm5int_acl_check(handle->context, name, ACL_ADD, 491 arg->rec.principal, &rp) && 492 !(policy_migrate)) 493 || kadm5int_acl_impose_restrictions(handle->context, 494 &arg->rec, &arg->mask, rp)) { 495 ret.code = KADM5_AUTH_ADD; 496 497 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 498 "kadm5_create_principal", 499 prime_arg, client_name); 500 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal", 501 prime_arg, client_name, 502 service_name, client_addr(rqstp, buf)); 503 } else { 504 ret.code = kadm5_create_principal((void *)handle, 505 &arg->rec, arg->mask, 506 arg->passwd); 507 508 audit_kadmind_auth(rqstp->rq_xprt, l_port, 509 "kadm5_create_principal", 510 prime_arg, client_name, ret.code); 511 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal", 512 prime_arg,((ret.code == 0) ? "success" : 513 error_message(ret.code)), 514 client_name, service_name, client_addr(rqstp, buf)); 515 516 if (policy_migrate && (ret.code == 0)) { 517 arg->rec.policy = strdup("default"); 518 if ((arg->mask & KADM5_PW_EXPIRATION)) { 519 arg->mask = 0; 520 arg->mask |= KADM5_POLICY; 521 arg->mask |= KADM5_PW_EXPIRATION; 522 } else { 523 arg->mask = 0; 524 arg->mask |= KADM5_POLICY; 525 } 526 527 retval = kadm5_modify_principal((void *)handle, 528 &arg->rec, arg->mask); 529 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, 530 "kadm5_modify_principal", 531 prime_arg, ((retval == 0) ? "success" : 532 error_message(retval)), client_name, 533 service_name, client_addr(rqstp, buf)); 534 } 535 } 536 537 error: 538 if (name) 539 gss_release_name(&minor_stat, &name); 540 free_server_handle(handle); 541 if (prime_arg) 542 free(prime_arg); 543 if (client_name) 544 free(client_name); 545 if (service_name) 546 free(service_name); 547 return (&ret); 548 } 549 550 generic_ret * 551 create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp) 552 { 553 static generic_ret ret; 554 char *prime_arg = NULL; 555 char *client_name = NULL, *service_name = NULL; 556 int policy_migrate = 0; 557 558 OM_uint32 minor_stat; 559 kadm5_server_handle_t handle; 560 kadm5_ret_t retval; 561 restriction_t *rp; 562 gss_name_t name = NULL; 563 564 xdr_free(xdr_generic_ret, (char *) &ret); 565 566 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 567 return &ret; 568 569 if ((ret.code = check_handle((void *)handle))) 570 goto error; 571 ret.api_version = handle->api_version; 572 573 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 574 ret.code = KADM5_FAILURE; 575 goto error; 576 } 577 if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) { 578 ret.code = KADM5_BAD_PRINCIPAL; 579 goto error; 580 } 581 if (!(name = get_clnt_name(rqstp))) { 582 ret.code = KADM5_FAILURE; 583 goto error; 584 } 585 586 if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE, 587 arg->rec.principal, &rp) && 588 verify_pam_pw(prime_arg, arg->passwd)) { 589 policy_migrate = 1; 590 } 591 592 if (CHANGEPW_SERVICE(rqstp) 593 || (!kadm5int_acl_check(handle->context, name, ACL_ADD, 594 arg->rec.principal, &rp) && 595 !(policy_migrate)) 596 || kadm5int_acl_impose_restrictions(handle->context, 597 &arg->rec, &arg->mask, rp)) { 598 ret.code = KADM5_AUTH_ADD; 599 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_principal", 600 prime_arg, client_name, service_name, 601 client_addr(rqstp, buf)); 602 } else { 603 ret.code = kadm5_create_principal_3((void *)handle, 604 &arg->rec, arg->mask, 605 arg->n_ks_tuple, 606 arg->ks_tuple, 607 arg->passwd); 608 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_principal", 609 prime_arg,((ret.code == 0) ? "success" : 610 error_message(ret.code)), 611 client_name, service_name, 612 client_addr(rqstp, buf)); 613 614 if (policy_migrate && (ret.code == 0)) { 615 arg->rec.policy = strdup("default"); 616 if ((arg->mask & KADM5_PW_EXPIRATION)) { 617 arg->mask = 0; 618 arg->mask |= KADM5_POLICY; 619 arg->mask |= KADM5_PW_EXPIRATION; 620 } else { 621 arg->mask = 0; 622 arg->mask |= KADM5_POLICY; 623 } 624 625 retval = kadm5_modify_principal((void *)handle, 626 &arg->rec, arg->mask); 627 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, 628 "kadm5_modify_principal", 629 prime_arg, ((retval == 0) ? "success" : 630 error_message(retval)), client_name, 631 service_name, client_addr(rqstp, buf)); 632 } 633 } 634 635 error: 636 if (name) 637 gss_release_name(&minor_stat, &name); 638 free_server_handle(handle); 639 if (client_name) 640 free(client_name); 641 if (service_name) 642 free(service_name); 643 if (prime_arg) 644 free(prime_arg); 645 return &ret; 646 } 647 648 generic_ret * 649 delete_principal_1_svc(dprinc_arg *arg, struct svc_req *rqstp) 650 { 651 static generic_ret ret; 652 char *prime_arg = NULL; 653 char *client_name = NULL, *service_name = NULL; 654 OM_uint32 min_stat; 655 kadm5_server_handle_t handle; 656 gss_name_t name = NULL; 657 658 xdr_free(xdr_generic_ret, (char *) &ret); 659 660 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 661 return &ret; 662 663 if ((ret.code = check_handle((void *)handle))) 664 goto error; 665 ret.api_version = handle->api_version; 666 667 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 668 ret.code = KADM5_FAILURE; 669 goto error; 670 } 671 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 672 ret.code = KADM5_BAD_PRINCIPAL; 673 goto error; 674 } 675 if (!(name = get_clnt_name(rqstp))) { 676 ret.code = KADM5_FAILURE; 677 goto error; 678 } 679 680 if (CHANGEPW_SERVICE(rqstp) 681 || !kadm5int_acl_check(handle->context, name, ACL_DELETE, 682 arg->princ, NULL)) { 683 ret.code = KADM5_AUTH_DELETE; 684 685 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 686 "kadm5_delete_principal", 687 prime_arg, client_name); 688 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_principal", 689 prime_arg, client_name, 690 service_name, client_addr(rqstp, buf)); 691 } else { 692 ret.code = kadm5_delete_principal((void *)handle, arg->princ); 693 694 audit_kadmind_auth(rqstp->rq_xprt, l_port, 695 "kadm5_delete_principal", 696 prime_arg, client_name, ret.code); 697 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_principal", prime_arg, 698 ((ret.code == 0) ? "success" : error_message(ret.code)), 699 client_name, service_name, client_addr(rqstp, buf)); 700 } 701 702 error: 703 if (name) 704 gss_release_name(&min_stat, &name); 705 if (prime_arg) 706 free(prime_arg); 707 free_server_handle(handle); 708 if (client_name) 709 free(client_name); 710 if (service_name) 711 free(service_name); 712 return &ret; 713 } 714 715 generic_ret * 716 modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp) 717 { 718 static generic_ret ret; 719 char *prime_arg = NULL; 720 char *client_name = NULL, *service_name = NULL; 721 OM_uint32 min_stat; 722 kadm5_server_handle_t handle; 723 restriction_t *rp; 724 gss_name_t name = NULL; 725 726 xdr_free(xdr_generic_ret, (char *) &ret); 727 728 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 729 return &ret; 730 731 if ((ret.code = check_handle((void *)handle))) 732 goto error; 733 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 734 ret.code = KADM5_FAILURE; 735 goto error; 736 } 737 if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) { 738 ret.code = KADM5_BAD_PRINCIPAL; 739 goto error; 740 } 741 if (!(name = get_clnt_name(rqstp))) { 742 ret.code = KADM5_FAILURE; 743 goto error; 744 } 745 746 if (CHANGEPW_SERVICE(rqstp) 747 || !kadm5int_acl_check(handle->context, name, ACL_MODIFY, 748 arg->rec.principal, &rp) 749 || kadm5int_acl_impose_restrictions(handle->context, 750 &arg->rec, &arg->mask, rp)) { 751 ret.code = KADM5_AUTH_MODIFY; 752 753 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 754 "kadm5_modify_principal", 755 prime_arg, client_name); 756 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_principal", 757 prime_arg, client_name, 758 service_name, client_addr(rqstp, buf)); 759 } else { 760 ret.code = kadm5_modify_principal((void *)handle, &arg->rec, 761 arg->mask); 762 763 audit_kadmind_auth(rqstp->rq_xprt, l_port, 764 "kadm5_modify_principal", 765 prime_arg, client_name, ret.code); 766 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_principal", 767 prime_arg, ((ret.code == 0) ? "success" : 768 error_message(ret.code)), 769 client_name, service_name, client_addr(rqstp, buf)); 770 } 771 772 error: 773 if (name) 774 gss_release_name(&min_stat, &name); 775 free_server_handle(handle); 776 if (prime_arg) 777 free(prime_arg); 778 if (client_name) 779 free(client_name); 780 if (service_name) 781 free(service_name); 782 return &ret; 783 } 784 785 generic_ret * 786 rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp) 787 { 788 static generic_ret ret; 789 char *prime_arg1 = NULL, *prime_arg2 = NULL; 790 char prime_arg[BUFSIZ]; 791 char *client_name = NULL, *service_name = NULL; 792 OM_uint32 min_stat; 793 kadm5_server_handle_t handle; 794 restriction_t *rp; 795 gss_name_t name = NULL; 796 797 xdr_free(xdr_generic_ret, (char *) &ret); 798 799 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 800 return &ret; 801 802 if ((ret.code = check_handle((void *)handle))) 803 goto error; 804 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 805 ret.code = KADM5_FAILURE; 806 goto error; 807 } 808 if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) || 809 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 815 ret.code = KADM5_OK; 816 817 if (!(name = get_clnt_name(rqstp))) { 818 ret.code = KADM5_FAILURE; 819 goto error; 820 } 821 822 if (! CHANGEPW_SERVICE(rqstp)) { 823 if (!kadm5int_acl_check(handle->context, name, 824 ACL_DELETE, arg->src, NULL)) 825 ret.code = KADM5_AUTH_DELETE; 826 /* any restrictions at all on the ADD kills the RENAME */ 827 if (!kadm5int_acl_check(handle->context, name, 828 ACL_ADD, arg->dest, &rp)) { 829 if (ret.code == KADM5_AUTH_DELETE) 830 ret.code = KADM5_AUTH_INSUFFICIENT; 831 else 832 ret.code = KADM5_AUTH_ADD; 833 } 834 } else 835 ret.code = KADM5_AUTH_INSUFFICIENT; 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, "kadm5_rename_principal", 842 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_svc(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) || !kadm5int_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, sizeof(kadm5_principal_ent_rec_v1)); 928 free(e); 929 } 930 } else { 931 ret.code = kadm5_get_principal((void *)handle, 932 arg->princ, &ret.rec, 933 arg->mask); 934 } 935 936 audit_kadmind_auth(rqstp->rq_xprt, l_port, 937 funcname, 938 prime_arg, client_name, ret.code); 939 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname, 940 prime_arg, 941 ((ret.code == 0) ? "success" : error_message(ret.code)), 942 client_name, service_name, client_addr(rqstp, buf)); 943 } 944 945 error: 946 if (name) 947 gss_release_name(&min_stat, &name); 948 free_server_handle(handle); 949 if (prime_arg) 950 free(prime_arg); 951 if (client_name) 952 free(client_name); 953 if (service_name) 954 free(service_name); 955 return &ret; 956 } 957 958 gprincs_ret * 959 get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp) 960 { 961 static gprincs_ret ret; 962 char *prime_arg = NULL; 963 char *client_name = NULL, *service_name = NULL; 964 OM_uint32 min_stat; 965 kadm5_server_handle_t handle; 966 gss_name_t name = NULL; 967 968 xdr_free(xdr_gprincs_ret, (char *) &ret); 969 970 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 971 return &ret; 972 973 if ((ret.code = check_handle((void *)handle))) 974 goto error; 975 ret.api_version = handle->api_version; 976 977 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 978 ret.code = KADM5_FAILURE; 979 goto error; 980 } 981 prime_arg = arg->exp; 982 if (prime_arg == NULL) 983 prime_arg = "*"; 984 985 if (!(name = get_clnt_name(rqstp))) { 986 ret.code = KADM5_FAILURE; 987 goto error; 988 } 989 990 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 991 name, 992 ACL_LIST, 993 NULL, 994 NULL)) { 995 ret.code = KADM5_AUTH_LIST; 996 997 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 998 "kadm5_get_principals", 999 prime_arg, client_name); 1000 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_principals", 1001 prime_arg, client_name, 1002 service_name, client_addr(rqstp, buf)); 1003 } else { 1004 ret.code = kadm5_get_principals((void *)handle, 1005 arg->exp, &ret.princs, 1006 &ret.count); 1007 1008 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1009 "kadm5_get_principals", 1010 prime_arg, client_name, ret.code); 1011 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_principals", 1012 prime_arg, 1013 ((ret.code == 0) ? "success" : error_message(ret.code)), 1014 client_name, service_name, client_addr(rqstp, buf)); 1015 } 1016 1017 error: 1018 if (name) 1019 gss_release_name(&min_stat, &name); 1020 free_server_handle(handle); 1021 if (client_name) 1022 free(client_name); 1023 if (service_name) 1024 free(service_name); 1025 return (&ret); 1026 } 1027 1028 generic_ret * 1029 chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp) 1030 { 1031 static generic_ret ret; 1032 char *prime_arg = NULL; 1033 char *client_name = NULL, *service_name = NULL; 1034 OM_uint32 min_stat; 1035 kadm5_server_handle_t handle; 1036 gss_name_t name = NULL; 1037 1038 xdr_free(xdr_generic_ret, (char *) &ret); 1039 1040 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1041 return &ret; 1042 1043 if ((ret.code = check_handle((void *)handle))) 1044 goto error; 1045 ret.api_version = handle->api_version; 1046 1047 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1048 ret.code = KADM5_FAILURE; 1049 goto error; 1050 } 1051 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1052 ret.code = KADM5_BAD_PRINCIPAL; 1053 goto error; 1054 } 1055 if (!(name = get_clnt_name(rqstp))) { 1056 ret.code = KADM5_FAILURE; 1057 goto error; 1058 } 1059 1060 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1061 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ, 1062 FALSE, 0, NULL, arg->pass); 1063 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1064 kadm5int_acl_check(handle->context, name, 1065 ACL_CHANGEPW, arg->princ, NULL)) { 1066 ret.code = kadm5_chpass_principal((void *)handle, arg->princ, 1067 arg->pass); 1068 } else { 1069 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1070 "kadm5_chpass_principal", 1071 prime_arg, client_name); 1072 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal", 1073 prime_arg, client_name, 1074 service_name, client_addr(rqstp, buf)); 1075 ret.code = KADM5_AUTH_CHANGEPW; 1076 } 1077 1078 if(ret.code != KADM5_AUTH_CHANGEPW) { 1079 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1080 "kadm5_chpass_principal", 1081 prime_arg, client_name, ret.code); 1082 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal", 1083 prime_arg, ((ret.code == 0) ? "success" : 1084 error_message(ret.code)), 1085 client_name, service_name, client_addr(rqstp, buf)); 1086 } 1087 1088 error: 1089 if (name) 1090 gss_release_name(&min_stat, &name); 1091 free_server_handle(handle); 1092 if (prime_arg) 1093 free(prime_arg); 1094 if (client_name) 1095 free(client_name); 1096 if (service_name) 1097 free(service_name); 1098 return (&ret); 1099 } 1100 1101 generic_ret * 1102 chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp) 1103 { 1104 static generic_ret ret; 1105 char *prime_arg = NULL; 1106 char *client_name = NULL, 1107 *service_name = NULL; 1108 OM_uint32 min_stat; 1109 kadm5_server_handle_t handle; 1110 gss_name_t name = NULL; 1111 1112 xdr_free(xdr_generic_ret, (char *) &ret); 1113 1114 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1115 return &ret; 1116 1117 if ((ret.code = check_handle((void *)handle))) 1118 goto error; 1119 ret.api_version = handle->api_version; 1120 1121 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1122 ret.code = KADM5_FAILURE; 1123 goto error; 1124 } 1125 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1126 ret.code = KADM5_BAD_PRINCIPAL; 1127 goto error; 1128 } 1129 if (!(name = get_clnt_name(rqstp))) { 1130 ret.code = KADM5_FAILURE; 1131 goto error; 1132 } 1133 1134 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1135 ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ, 1136 arg->keepold, 1137 arg->n_ks_tuple, 1138 arg->ks_tuple, 1139 arg->pass); 1140 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1141 kadm5int_acl_check(handle->context, name, 1142 ACL_CHANGEPW, arg->princ, NULL)) { 1143 ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ, 1144 arg->keepold, 1145 arg->n_ks_tuple, 1146 arg->ks_tuple, 1147 arg->pass); 1148 } else { 1149 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_chpass_principal", 1150 prime_arg, client_name, service_name, 1151 client_addr(rqstp, buf)); 1152 ret.code = KADM5_AUTH_CHANGEPW; 1153 } 1154 1155 if(ret.code != KADM5_AUTH_CHANGEPW) { 1156 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_chpass_principal", 1157 prime_arg, ((ret.code == 0) ? "success" : 1158 error_message(ret.code)), 1159 client_name, service_name, 1160 client_addr(rqstp, buf)); 1161 } 1162 1163 error: 1164 if (name) 1165 gss_release_name(&min_stat, &name); 1166 free_server_handle(handle); 1167 if (client_name) 1168 free(client_name); 1169 if (service_name) 1170 free(service_name); 1171 if (prime_arg) 1172 free(prime_arg); 1173 return (&ret); 1174 } 1175 1176 #ifdef SUNWOFF 1177 generic_ret * 1178 setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp) 1179 { 1180 static generic_ret ret; 1181 char *prime_arg = NULL; 1182 char *client_name = NULL, 1183 *service_name = NULL; 1184 OM_uint32 min_stat; 1185 kadm5_server_handle_t handle; 1186 gss_name_t name = NULL; 1187 1188 xdr_free(xdr_generic_ret, (char *) &ret); 1189 1190 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1191 return &ret; 1192 1193 if ((ret.code = check_handle((void *)handle))) 1194 goto error; 1195 ret.api_version = handle->api_version; 1196 1197 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1198 ret.code = KADM5_FAILURE; 1199 goto error; 1200 } 1201 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1202 ret.code = KADM5_BAD_PRINCIPAL; 1203 goto error; 1204 } 1205 if (!(name = get_clnt_name(rqstp))) { 1206 ret.code = KADM5_FAILURE; 1207 goto error; 1208 } 1209 1210 if (!(CHANGEPW_SERVICE(rqstp)) && 1211 kadm5int_acl_check(handle->context, name, 1212 ACL_SETKEY, arg->princ, NULL)) { 1213 ret.code = kadm5_setv4key_principal((void *)handle, arg->princ, 1214 arg->keyblock); 1215 } else { 1216 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setv4key_principal", 1217 prime_arg, client_name, service_name, 1218 client_addr(rqstp, buf)); 1219 ret.code = KADM5_AUTH_SETKEY; 1220 } 1221 1222 if(ret.code != KADM5_AUTH_SETKEY) { 1223 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setv4key_principal", 1224 prime_arg, ((ret.code == 0) ? "success" : 1225 error_message(ret.code)), 1226 client_name, service_name, 1227 client_addr(rqstp, buf)); 1228 } 1229 1230 error: 1231 if (name) 1232 gss_release_name(&min_stat, &name); 1233 free_server_handle(handle); 1234 if (client_name) 1235 free(client_name); 1236 if (service_name) 1237 free(service_name); 1238 if (prime_arg) 1239 free(prime_arg); 1240 return (&ret); 1241 } 1242 #endif 1243 1244 generic_ret * 1245 setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp) 1246 { 1247 static generic_ret ret; 1248 char *prime_arg; 1249 char *client_name, 1250 *service_name; 1251 OM_uint32 min_stat; 1252 kadm5_server_handle_t handle; 1253 gss_name_t name; 1254 1255 xdr_free(xdr_generic_ret, (char *) &ret); 1256 1257 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1258 return &ret; 1259 1260 if ((ret.code = check_handle((void *)handle))) 1261 goto error; 1262 ret.api_version = handle->api_version; 1263 1264 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1265 ret.code = KADM5_FAILURE; 1266 goto error; 1267 } 1268 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1269 ret.code = KADM5_BAD_PRINCIPAL; 1270 goto error; 1271 } 1272 if (!(name = get_clnt_name(rqstp))) { 1273 ret.code = KADM5_FAILURE; 1274 goto error; 1275 } 1276 1277 if (!(CHANGEPW_SERVICE(rqstp)) && 1278 kadm5int_acl_check(handle->context, name, ACL_SETKEY, arg->princ, NULL)) { 1279 ret.code = kadm5_setkey_principal((void *)handle, arg->princ, 1280 arg->keyblocks, arg->n_keys); 1281 } else { 1282 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal", 1283 prime_arg, client_name, service_name, 1284 client_addr(rqstp, buf)); 1285 ret.code = KADM5_AUTH_SETKEY; 1286 } 1287 1288 if(ret.code != KADM5_AUTH_SETKEY) { 1289 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal", 1290 prime_arg, ((ret.code == 0) ? "success" : 1291 error_message(ret.code)), 1292 client_name, service_name, 1293 client_addr(rqstp, buf)); 1294 } 1295 1296 error: 1297 if (name) 1298 gss_release_name(&min_stat, &name); 1299 free_server_handle(handle); 1300 if (client_name) 1301 free(client_name); 1302 if (service_name) 1303 free(service_name); 1304 if (prime_arg) 1305 free(prime_arg); 1306 return (&ret); 1307 } 1308 1309 generic_ret * 1310 setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp) 1311 { 1312 static generic_ret ret; 1313 char *prime_arg = NULL; 1314 char *client_name = NULL, 1315 *service_name = NULL; 1316 OM_uint32 min_stat; 1317 kadm5_server_handle_t handle; 1318 gss_name_t name = NULL; 1319 1320 xdr_free(xdr_generic_ret, (char *) &ret); 1321 1322 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1323 return &ret; 1324 1325 if ((ret.code = check_handle((void *)handle))) 1326 goto error; 1327 ret.api_version = handle->api_version; 1328 1329 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1330 ret.code = KADM5_FAILURE; 1331 goto error; 1332 } 1333 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1334 ret.code = KADM5_BAD_PRINCIPAL; 1335 goto error; 1336 } 1337 if (!(name = get_clnt_name(rqstp))) { 1338 ret.code = KADM5_FAILURE; 1339 goto error; 1340 } 1341 1342 if (!(CHANGEPW_SERVICE(rqstp)) && 1343 kadm5int_acl_check(handle->context, name, 1344 ACL_SETKEY, arg->princ, NULL)) { 1345 ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ, 1346 arg->keepold, 1347 arg->n_ks_tuple, 1348 arg->ks_tuple, 1349 arg->keyblocks, arg->n_keys); 1350 } else { 1351 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_setkey_principal", 1352 prime_arg, client_name, service_name, 1353 client_addr(rqstp, buf)); 1354 ret.code = KADM5_AUTH_SETKEY; 1355 } 1356 1357 if(ret.code != KADM5_AUTH_SETKEY) { 1358 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_setkey_principal", 1359 prime_arg, ((ret.code == 0) ? "success" : 1360 error_message(ret.code)), 1361 client_name, service_name, 1362 client_addr(rqstp, buf)); 1363 } 1364 1365 error: 1366 if (name) 1367 gss_release_name(&min_stat, &name); 1368 free_server_handle(handle); 1369 if (client_name) 1370 free(client_name); 1371 if (service_name) 1372 free(service_name); 1373 if (prime_arg) 1374 free(prime_arg); 1375 return &ret; 1376 } 1377 1378 chrand_ret * 1379 chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp) 1380 { 1381 static chrand_ret ret; 1382 krb5_keyblock *k; 1383 int nkeys; 1384 char *prime_arg = NULL, *funcname; 1385 char *client_name = NULL, *service_name = NULL; 1386 OM_uint32 min_stat; 1387 kadm5_server_handle_t handle; 1388 gss_name_t name = NULL; 1389 1390 xdr_free(xdr_chrand_ret, (char *) &ret); 1391 1392 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1393 return &ret; 1394 1395 if ((ret.code = check_handle((void *)handle))) 1396 goto error; 1397 1398 ret.api_version = handle->api_version; 1399 1400 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1401 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal"; 1402 1403 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1404 ret.code = KADM5_FAILURE; 1405 goto error; 1406 } 1407 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1408 ret.code = KADM5_BAD_PRINCIPAL; 1409 goto error; 1410 } 1411 if (!(name = get_clnt_name(rqstp))) { 1412 ret.code = KADM5_FAILURE; 1413 goto error; 1414 } 1415 1416 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1417 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ, 1418 FALSE, 0, NULL, &k, &nkeys); 1419 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1420 kadm5int_acl_check(handle->context, name, 1421 ACL_CHANGEPW, arg->princ, NULL)) { 1422 ret.code = kadm5_randkey_principal((void *)handle, arg->princ, 1423 &k, &nkeys); 1424 } else { 1425 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1426 funcname, prime_arg, client_name); 1427 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname, 1428 prime_arg, client_name, service_name, 1429 client_addr(rqstp, buf)); 1430 ret.code = KADM5_AUTH_CHANGEPW; 1431 } 1432 1433 if(ret.code == KADM5_OK) { 1434 if (handle->api_version == KADM5_API_VERSION_1) { 1435 krb5_copy_keyblock_contents(handle->context, k, &ret.key); 1436 krb5_free_keyblock(handle->context, k); 1437 } else { 1438 ret.keys = k; 1439 ret.n_keys = nkeys; 1440 } 1441 } 1442 1443 if(ret.code != KADM5_AUTH_CHANGEPW) { 1444 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1445 funcname, prime_arg, client_name, ret.code); 1446 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname, 1447 prime_arg, ((ret.code == 0) ? "success" : 1448 error_message(ret.code)), 1449 client_name, service_name, client_addr(rqstp, buf)); 1450 } 1451 1452 error: 1453 if (name) 1454 gss_release_name(&min_stat, &name); 1455 free_server_handle(handle); 1456 if (prime_arg) 1457 free(prime_arg); 1458 if (client_name) 1459 free(client_name); 1460 if (service_name) 1461 free(service_name); 1462 return &ret; 1463 } 1464 1465 chrand_ret * 1466 chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp) 1467 { 1468 static chrand_ret ret; 1469 krb5_keyblock *k; 1470 int nkeys; 1471 char *prime_arg = NULL, *funcname; 1472 char *client_name = NULL, 1473 *service_name = NULL; 1474 OM_uint32 min_stat; 1475 kadm5_server_handle_t handle; 1476 gss_name_t name = NULL; 1477 1478 xdr_free(xdr_chrand_ret, (char *) &ret); 1479 1480 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1481 return &ret; 1482 1483 if ((ret.code = check_handle((void *)handle))) 1484 goto error; 1485 ret.api_version = handle->api_version; 1486 1487 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1488 "kadm5_randkey_principal (V1)" : "kadm5_randkey_principal"; 1489 1490 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1491 ret.code = KADM5_FAILURE; 1492 goto error; 1493 } 1494 if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) { 1495 ret.code = KADM5_BAD_PRINCIPAL; 1496 goto error; 1497 } 1498 if (!(name = get_clnt_name(rqstp))) { 1499 ret.code = KADM5_FAILURE; 1500 goto error; 1501 } 1502 1503 if (cmp_gss_krb5_name(handle, name, arg->princ)) { 1504 ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ, 1505 arg->keepold, 1506 arg->n_ks_tuple, 1507 arg->ks_tuple, 1508 &k, &nkeys); 1509 } else if (!(CHANGEPW_SERVICE(rqstp)) && 1510 kadm5int_acl_check(handle->context, name, 1511 ACL_CHANGEPW, arg->princ, NULL)) { 1512 ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ, 1513 arg->keepold, 1514 arg->n_ks_tuple, 1515 arg->ks_tuple, 1516 &k, &nkeys); 1517 } else { 1518 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname, 1519 prime_arg, client_name, service_name, 1520 client_addr(rqstp, buf)); 1521 ret.code = KADM5_AUTH_CHANGEPW; 1522 } 1523 1524 if(ret.code == KADM5_OK) { 1525 if (handle->api_version == KADM5_API_VERSION_1) { 1526 krb5_copy_keyblock_contents(handle->context, k, &ret.key); 1527 krb5_free_keyblock(handle->context, k); 1528 } else { 1529 ret.keys = k; 1530 ret.n_keys = nkeys; 1531 } 1532 } 1533 1534 if(ret.code != KADM5_AUTH_CHANGEPW) { 1535 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname, 1536 prime_arg, ((ret.code == 0) ? "success" : 1537 error_message(ret.code)), 1538 client_name, service_name, 1539 client_addr(rqstp, buf)); 1540 } 1541 1542 error: 1543 if (name) 1544 gss_release_name(&min_stat, &name); 1545 free_server_handle(handle); 1546 if (client_name) 1547 free(client_name); 1548 if (service_name) 1549 free(service_name); 1550 if (prime_arg) 1551 free(prime_arg); 1552 return (&ret); 1553 } 1554 1555 generic_ret * 1556 create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp) 1557 { 1558 static generic_ret ret; 1559 char *prime_arg = NULL; 1560 char *client_name = NULL, *service_name = NULL; 1561 OM_uint32 min_stat; 1562 kadm5_server_handle_t handle; 1563 gss_name_t name = NULL; 1564 1565 xdr_free(xdr_generic_ret, (char *) &ret); 1566 1567 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1568 return &ret; 1569 1570 if ((ret.code = check_handle((void *)handle))) 1571 goto error; 1572 1573 ret.api_version = handle->api_version; 1574 1575 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1576 ret.code = KADM5_FAILURE; 1577 goto error; 1578 } 1579 prime_arg = arg->rec.policy; 1580 1581 if (!(name = get_clnt_name(rqstp))) { 1582 ret.code = KADM5_FAILURE; 1583 goto error; 1584 } 1585 1586 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1587 name, 1588 ACL_ADD, NULL, NULL)) { 1589 ret.code = KADM5_AUTH_ADD; 1590 1591 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1592 "kadm5_create_policy", 1593 prime_arg, client_name); 1594 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_create_policy", 1595 prime_arg, client_name, 1596 service_name, client_addr(rqstp, buf)); 1597 1598 } else { 1599 ret.code = kadm5_create_policy((void *)handle, &arg->rec, 1600 arg->mask); 1601 1602 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1603 "kadm5_create_policy", 1604 prime_arg, client_name, ret.code); 1605 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_create_policy", 1606 ((prime_arg == NULL) ? "(null)" : prime_arg), 1607 ((ret.code == 0) ? "success" : error_message(ret.code)), 1608 client_name, service_name, client_addr(rqstp, buf)); 1609 } 1610 1611 error: 1612 if (name) 1613 gss_release_name(&min_stat, &name); 1614 free_server_handle(handle); 1615 if (client_name) 1616 free(client_name); 1617 if (service_name) 1618 free(service_name); 1619 return &ret; 1620 } 1621 1622 generic_ret * 1623 delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp) 1624 { 1625 static generic_ret ret; 1626 char *prime_arg = NULL; 1627 char *client_name = NULL, *service_name = NULL; 1628 OM_uint32 min_stat; 1629 kadm5_server_handle_t handle; 1630 gss_name_t name = NULL; 1631 1632 xdr_free(xdr_generic_ret, (char *) &ret); 1633 1634 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1635 return &ret; 1636 1637 if ((ret.code = check_handle((void *)handle))) 1638 goto error; 1639 ret.api_version = handle->api_version; 1640 1641 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1642 ret.code = KADM5_FAILURE; 1643 goto error; 1644 } 1645 prime_arg = arg->name; 1646 1647 if (!(name = get_clnt_name(rqstp))) { 1648 ret.code = KADM5_FAILURE; 1649 goto error; 1650 } 1651 1652 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1653 name, 1654 ACL_DELETE, NULL, NULL)) { 1655 1656 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1657 "kadm5_delete_policy", 1658 prime_arg, client_name); 1659 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_delete_policy", 1660 prime_arg, client_name, service_name, 1661 client_addr(rqstp, buf)); 1662 ret.code = KADM5_AUTH_DELETE; 1663 } else { 1664 ret.code = kadm5_delete_policy((void *)handle, arg->name); 1665 1666 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1667 "kadm5_delete_policy", 1668 prime_arg, client_name, ret.code); 1669 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_delete_policy", 1670 ((prime_arg == NULL) ? "(null)" : prime_arg), 1671 ((ret.code == 0) ? "success" : error_message(ret.code)), 1672 client_name, service_name, client_addr(rqstp, buf)); 1673 } 1674 1675 error: 1676 if (name) 1677 gss_release_name(&min_stat, &name); 1678 free_server_handle(handle); 1679 if (client_name) 1680 free(client_name); 1681 if (service_name) 1682 free(service_name); 1683 return &ret; 1684 } 1685 1686 generic_ret * 1687 modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp) 1688 { 1689 static generic_ret ret; 1690 char *prime_arg = NULL; 1691 char *client_name = NULL, *service_name = NULL; 1692 OM_uint32 min_stat; 1693 kadm5_server_handle_t handle; 1694 gss_name_t name = NULL; 1695 1696 xdr_free(xdr_generic_ret, (char *) &ret); 1697 1698 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1699 return &ret; 1700 1701 if ((ret.code = check_handle((void *)handle))) 1702 goto error; 1703 ret.api_version = handle->api_version; 1704 1705 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1706 ret.code = KADM5_FAILURE; 1707 goto error; 1708 } 1709 prime_arg = arg->rec.policy; 1710 1711 if (!(name = get_clnt_name(rqstp))) { 1712 ret.code = KADM5_FAILURE; 1713 goto error; 1714 } 1715 1716 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1717 name, 1718 ACL_MODIFY, NULL, NULL)) { 1719 1720 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1721 "kadm5_modify_policy", 1722 prime_arg, client_name); 1723 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_modify_policy", 1724 prime_arg, client_name, 1725 service_name, client_addr(rqstp, buf)); 1726 ret.code = KADM5_AUTH_MODIFY; 1727 } else { 1728 ret.code = kadm5_modify_policy((void *)handle, &arg->rec, 1729 arg->mask); 1730 1731 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1732 "kadm5_modify_policy", 1733 prime_arg, client_name, ret.code); 1734 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_modify_policy", 1735 ((prime_arg == NULL) ? "(null)" : prime_arg), 1736 ((ret.code == 0) ? "success" : error_message(ret.code)), 1737 client_name, service_name, client_addr(rqstp, buf)); 1738 } 1739 1740 error: 1741 if (name) 1742 gss_release_name(&min_stat, &name); 1743 free_server_handle(handle); 1744 if (client_name) 1745 free(client_name); 1746 if (service_name) 1747 free(service_name); 1748 return (&ret); 1749 } 1750 1751 gpol_ret * 1752 get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp) 1753 { 1754 static gpol_ret ret; 1755 kadm5_ret_t ret2; 1756 char *prime_arg = NULL, *funcname; 1757 char *client_name = NULL, *service_name = NULL; 1758 OM_uint32 min_stat; 1759 kadm5_policy_ent_t e; 1760 kadm5_principal_ent_rec caller_ent; 1761 krb5_principal caller; 1762 kadm5_server_handle_t handle; 1763 gss_name_t name = NULL; 1764 1765 xdr_free(xdr_gpol_ret, (char *) &ret); 1766 1767 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1768 return &ret; 1769 1770 if ((ret.code = check_handle((void *) handle))) 1771 goto error; 1772 1773 ret.api_version = handle->api_version; 1774 1775 funcname = handle->api_version == KADM5_API_VERSION_1 ? 1776 "kadm5_get_policy (V1)" : "kadm5_get_policy"; 1777 1778 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1779 ret.code = KADM5_FAILURE; 1780 goto error; 1781 } 1782 prime_arg = arg->name; 1783 ret.code = KADM5_AUTH_GET; 1784 1785 if (!(name = get_clnt_name(rqstp))) { 1786 ret.code = KADM5_FAILURE; 1787 goto error; 1788 } 1789 1790 if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context, 1791 name, 1792 ACL_INQUIRE, NULL, NULL)) 1793 ret.code = KADM5_OK; 1794 else { 1795 ret.code = kadm5_get_principal(handle->lhandle, 1796 handle->current_caller, 1797 &caller_ent, 1798 KADM5_PRINCIPAL_NORMAL_MASK); 1799 if (ret.code == KADM5_OK) { 1800 if (caller_ent.aux_attributes & KADM5_POLICY && 1801 strcmp(caller_ent.policy, arg->name) == 0) { 1802 ret.code = KADM5_OK; 1803 } else ret.code = KADM5_AUTH_GET; 1804 ret2 = kadm5_free_principal_ent(handle->lhandle, 1805 &caller_ent); 1806 ret.code = ret.code ? ret.code : ret2; 1807 } 1808 } 1809 1810 if (ret.code == KADM5_OK) { 1811 if (handle->api_version == KADM5_API_VERSION_1) { 1812 ret.code = kadm5_get_policy_v1((void *)handle, arg->name, &e); 1813 if(ret.code == KADM5_OK) { 1814 memcpy(&ret.rec, e, sizeof(kadm5_policy_ent_rec)); 1815 free(e); 1816 } 1817 } else { 1818 ret.code = kadm5_get_policy((void *)handle, arg->name, 1819 &ret.rec); 1820 } 1821 1822 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1823 funcname, prime_arg, client_name, ret.code); 1824 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, funcname, 1825 ((prime_arg == NULL) ? "(null)" : prime_arg), 1826 ((ret.code == 0) ? "success" : error_message(ret.code)), 1827 client_name, service_name, client_addr(rqstp, buf)); 1828 } else { 1829 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1830 funcname, prime_arg, client_name); 1831 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, funcname, 1832 prime_arg, client_name, 1833 service_name, client_addr(rqstp, buf)); 1834 } 1835 1836 error: 1837 if (name) 1838 gss_release_name(&min_stat, &name); 1839 free_server_handle(handle); 1840 if (client_name) 1841 free(client_name); 1842 if (service_name) 1843 free(service_name); 1844 return (&ret); 1845 1846 } 1847 1848 gpols_ret * 1849 get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp) 1850 { 1851 static gpols_ret ret; 1852 char *prime_arg = NULL; 1853 char *client_name = NULL, *service_name = NULL; 1854 OM_uint32 min_stat; 1855 kadm5_server_handle_t handle; 1856 gss_name_t name = NULL; 1857 1858 xdr_free(xdr_gpols_ret, (char *) &ret); 1859 1860 if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle))) 1861 return &ret; 1862 1863 if ((ret.code = check_handle((void *)handle))) 1864 goto error; 1865 1866 ret.api_version = handle->api_version; 1867 1868 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1869 ret.code = KADM5_FAILURE; 1870 goto error; 1871 } 1872 prime_arg = arg->exp; 1873 if (prime_arg == NULL) 1874 prime_arg = "*"; 1875 1876 if (!(name = get_clnt_name(rqstp))) { 1877 ret.code = KADM5_FAILURE; 1878 goto error; 1879 } 1880 1881 if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context, 1882 name, 1883 ACL_LIST, NULL, NULL)) { 1884 ret.code = KADM5_AUTH_LIST; 1885 1886 audit_kadmind_unauth(rqstp->rq_xprt, l_port, 1887 "kadm5_get_policies", 1888 prime_arg, client_name); 1889 krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_policies", 1890 prime_arg, client_name, service_name, 1891 client_addr(rqstp, buf)); 1892 } else { 1893 ret.code = kadm5_get_policies((void *)handle, 1894 arg->exp, &ret.pols, 1895 &ret.count); 1896 1897 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1898 "kadm5_get_policies", 1899 prime_arg, client_name, ret.code); 1900 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_policies", 1901 prime_arg, 1902 ((ret.code == 0) ? "success" : error_message(ret.code)), 1903 client_name, service_name, client_addr(rqstp, buf)); 1904 } 1905 1906 error: 1907 if (name) 1908 gss_release_name(&min_stat, &name); 1909 free_server_handle(handle); 1910 if (client_name) 1911 free(client_name); 1912 if (service_name) 1913 free(service_name); 1914 return (&ret); 1915 } 1916 1917 getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp) 1918 { 1919 static getprivs_ret ret; 1920 char *client_name = NULL, *service_name = NULL; 1921 OM_uint32 min_stat; 1922 kadm5_server_handle_t handle; 1923 gss_name_t name = NULL; 1924 1925 xdr_free(xdr_getprivs_ret, (char *) &ret); 1926 1927 if ((ret.code = new_server_handle(*arg, rqstp, &handle))) 1928 return &ret; 1929 1930 if ((ret.code = check_handle((void *)handle))) 1931 goto error; 1932 1933 ret.api_version = handle->api_version; 1934 1935 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1936 ret.code = KADM5_FAILURE; 1937 goto error; 1938 } 1939 if (!(name = get_clnt_name(rqstp))) { 1940 ret.code = KADM5_FAILURE; 1941 goto error; 1942 } 1943 1944 ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name); 1945 1946 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1947 "kadm5_get_privs", NULL, client_name, 1948 ret.code); 1949 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_privs", 1950 client_name, 1951 ((ret.code == 0) ? "success" : error_message(ret.code)), 1952 client_name, service_name, client_addr(rqstp, buf)); 1953 1954 error: 1955 if (name) 1956 gss_release_name(&min_stat, &name); 1957 free_server_handle(handle); 1958 if (client_name) 1959 free(client_name); 1960 if (service_name) 1961 free(service_name); 1962 return (&ret); 1963 } 1964 1965 generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp) 1966 { 1967 static generic_ret ret; 1968 char *client_name, *service_name; 1969 kadm5_server_handle_t handle; 1970 1971 xdr_free(xdr_generic_ret, (char *) &ret); 1972 1973 if ((ret.code = new_server_handle(*arg, rqstp, &handle))) 1974 return &ret; 1975 if (! (ret.code = check_handle((void *)handle))) { 1976 ret.api_version = handle->api_version; 1977 } 1978 1979 free_server_handle(handle); 1980 1981 if (setup_gss_names(rqstp, &client_name, &service_name) < 0) { 1982 ret.code = KADM5_FAILURE; 1983 return &ret; 1984 } 1985 1986 audit_kadmind_auth(rqstp->rq_xprt, l_port, 1987 (ret.api_version == KADM5_API_VERSION_1 ? 1988 "kadm5_init (V1)" : "kadm5_init"), 1989 NULL, client_name, ret.code); 1990 krb5_klog_syslog(LOG_NOTICE, LOG_DONE, 1991 (ret.api_version == KADM5_API_VERSION_1 ? 1992 "kadm5_init (V1)" : "kadm5_init"), 1993 client_name, 1994 (ret.code == 0) ? "success" : error_message(ret.code), 1995 client_name, service_name, client_addr(rqstp, buf)); 1996 free(client_name); 1997 free(service_name); 1998 1999 return (&ret); 2000 } 2001