1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 9 * 10 * Openvision retains the copyright to derivative works of 11 * this source code. Do *NOT* create a derivative of this 12 * source code before consulting with your legal department. 13 * Do *NOT* integrate *ANY* of this source code into another 14 * product before consulting with your legal department. 15 * 16 * For further information, read the top-level Openvision 17 * copyright which is contained in the top-level MIT Kerberos 18 * copyright. 19 * 20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 21 * 22 */ 23 24 25 /* 26 * lib/kadm/alt_prof.c 27 * 28 * Copyright 1995,2001 by the Massachusetts Institute of Technology. 29 * All Rights Reserved. 30 * 31 * Export of this software from the United States of America may 32 * require a specific license from the United States Government. 33 * It is the responsibility of any person or organization contemplating 34 * export to obtain such a license before exporting. 35 * 36 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 37 * distribute this software and its documentation for any purpose and 38 * without fee is hereby granted, provided that the above copyright 39 * notice appear in all copies and that both that copyright notice and 40 * this permission notice appear in supporting documentation, and that 41 * the name of M.I.T. not be used in advertising or publicity pertaining 42 * to distribution of the software without specific, written prior 43 * permission. Furthermore if you modify this software you must label 44 * your software as modified software and not distribute it in such a 45 * fashion that it might be confused with the original M.I.T. software. 46 * M.I.T. makes no representations about the suitability of 47 * this software for any purpose. It is provided "as is" without express 48 * or implied warranty. 49 * 50 */ 51 52 /* 53 * alt_prof.c - Implement alternate profile file handling. 54 */ 55 #include "k5-int.h" 56 #include <kadm5/admin.h> 57 #include "adm_proto.h" 58 #include <stdio.h> 59 #include <ctype.h> 60 #include <os-proto.h> 61 #include <kdb/kdb_log.h> 62 63 krb5_error_code kadm5_free_config_params(); 64 65 #define DEFAULT_ENCTYPE_LIST \ 66 "aes256-cts-hmac-sha1-96:normal " \ 67 "aes128-cts-hmac-sha1-96:normal " \ 68 "des3-cbc-hmac-sha1-kd:normal " \ 69 "arcfour-hmac-md5:normal " \ 70 "arcfour-hmac-md5-exp:normal " \ 71 "des-cbc-md5:normal " \ 72 "des-cbc-crc:normal" 73 74 static krb5_key_salt_tuple *copy_key_salt_tuple(ksalt, len) 75 krb5_key_salt_tuple *ksalt; 76 krb5_int32 len; 77 { 78 krb5_key_salt_tuple *knew; 79 80 if((knew = (krb5_key_salt_tuple *) 81 malloc((len ) * sizeof(krb5_key_salt_tuple)))) { 82 memcpy(knew, ksalt, len * sizeof(krb5_key_salt_tuple)); 83 return knew; 84 } 85 return 0; 86 } 87 88 /* 89 * krb5_aprof_init() - Initialize alternate profile context. 90 * 91 * Parameters: 92 * fname - default file name of the profile. 93 * envname - environment variable name which can override fname. 94 * acontextp - Pointer to opaque context for alternate profile. 95 * 96 * Returns: 97 * error codes from profile_init() 98 */ 99 krb5_error_code 100 krb5_aprof_init(fname, envname, acontextp) 101 char *fname; 102 char *envname; 103 krb5_pointer *acontextp; 104 { 105 krb5_error_code kret; 106 profile_t profile; 107 const char *kdc_config; 108 size_t krb5_config_len, kdc_config_len; 109 char *profile_path; 110 char **filenames; 111 int i; 112 113 kret = krb5_get_default_config_files (&filenames); 114 if (kret) 115 return kret; 116 krb5_config_len = 0; 117 for (i = 0; filenames[i] != NULL; i++) 118 krb5_config_len += strlen(filenames[i]) + 1; 119 if (i > 0) 120 krb5_config_len--; 121 if (envname == NULL 122 || (kdc_config = getenv(envname)) == NULL) 123 kdc_config = fname; 124 if (kdc_config == NULL) 125 kdc_config_len = 0; 126 else 127 kdc_config_len = strlen(kdc_config); 128 profile_path = malloc(2 + krb5_config_len + kdc_config_len); 129 if (profile_path == NULL) { 130 krb5_free_config_files(filenames); 131 return errno; 132 } 133 if (kdc_config_len) 134 strcpy(profile_path, kdc_config); 135 else 136 profile_path[0] = 0; 137 if (krb5_config_len) 138 for (i = 0; filenames[i] != NULL; i++) { 139 if (kdc_config_len || i) 140 strcat(profile_path, ":"); 141 strcat(profile_path, filenames[i]); 142 } 143 krb5_free_config_files(filenames); 144 profile = (profile_t) NULL; 145 kret = profile_init_path(profile_path, &profile); 146 free(profile_path); 147 if (kret) 148 return kret; 149 *acontextp = profile; 150 return 0; 151 } 152 153 /* 154 * krb5_aprof_getvals() - Get values from alternate profile. 155 * 156 * Parameters: 157 * acontext - opaque context for alternate profile. 158 * hierarchy - hierarchy of value to retrieve. 159 * retdata - Returned data values. 160 * 161 * Returns: 162 * error codes from profile_get_values() 163 */ 164 krb5_error_code 165 krb5_aprof_getvals(acontext, hierarchy, retdata) 166 krb5_pointer acontext; 167 const char **hierarchy; 168 char ***retdata; 169 { 170 return(profile_get_values((profile_t) acontext, 171 hierarchy, 172 retdata)); 173 } 174 175 /* 176 * krb5_aprof_get_boolean() 177 * 178 * Parameters: 179 * acontext - opaque context for alternate profile 180 * hierarchy - hierarchy of value to retrieve 181 * retdata - Returned data value 182 * Returns: 183 * error codes 184 */ 185 186 static krb5_error_code 187 string_to_boolean (const char *string, krb5_boolean *out) 188 { 189 static const char *const yes[] = { "y", "yes", "true", "t", "1", "on" }; 190 static const char *const no[] = { "n", "no", "false", "f", "nil", "0", "off" }; 191 int i; 192 193 for (i = 0; i < sizeof(yes)/sizeof(yes[0]); i++) 194 if (!strcasecmp(string, yes[i])) { 195 *out = 1; 196 return 0; 197 } 198 for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) 199 if (!strcasecmp(string, no[i])) { 200 *out = 0; 201 return 0; 202 } 203 return PROF_BAD_BOOLEAN; 204 } 205 206 krb5_error_code 207 krb5_aprof_get_boolean(krb5_pointer acontext, const char **hierarchy, 208 int uselast, krb5_boolean *retdata) 209 { 210 krb5_error_code kret; 211 char **values; 212 char *valp; 213 int idx; 214 krb5_boolean val; 215 216 kret = krb5_aprof_getvals (acontext, hierarchy, &values); 217 if (kret) 218 return kret; 219 idx = 0; 220 if (uselast) { 221 while (values[idx]) 222 idx++; 223 idx--; 224 } 225 valp = values[idx]; 226 kret = string_to_boolean (valp, &val); 227 if (kret) 228 return kret; 229 *retdata = val; 230 return 0; 231 } 232 233 /* 234 * krb5_aprof_get_deltat() - Get a delta time value from the alternate 235 * profile. 236 * 237 * Parameters: 238 * acontext - opaque context for alternate profile. 239 * hierarchy - hierarchy of value to retrieve. 240 * uselast - if true, use last value, otherwise use 241 * first value found. 242 * deltatp - returned delta time value. 243 * 244 * Returns: 245 * error codes from profile_get_values() 246 * error codes from krb5_string_to_deltat() 247 */ 248 krb5_error_code 249 krb5_aprof_get_deltat(acontext, hierarchy, uselast, deltatp) 250 krb5_pointer acontext; 251 const char **hierarchy; 252 krb5_boolean uselast; 253 krb5_deltat *deltatp; 254 { 255 krb5_error_code kret; 256 char **values; 257 char *valp; 258 int idx; 259 260 if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) { 261 idx = 0; 262 if (uselast) { 263 for (idx=0; values[idx]; idx++); 264 idx--; 265 } 266 valp = values[idx]; 267 kret = krb5_string_to_deltat(valp, deltatp); 268 269 /* Free the string storage */ 270 for (idx=0; values[idx]; idx++) 271 krb5_xfree(values[idx]); 272 krb5_xfree(values); 273 } 274 return(kret); 275 } 276 277 /* 278 * krb5_aprof_get_string() - Get a string value from the alternate 279 * profile. 280 * 281 * Parameters: 282 * acontext - opaque context for alternate profile. 283 * hierarchy - hierarchy of value to retrieve. 284 * uselast - if true, use last value, otherwise use 285 * first value found. 286 * stringp - returned string value. 287 * 288 * Returns: 289 * error codes from profile_get_values() 290 */ 291 krb5_error_code 292 krb5_aprof_get_string(acontext, hierarchy, uselast, stringp) 293 krb5_pointer acontext; 294 const char **hierarchy; 295 krb5_boolean uselast; 296 char **stringp; 297 { 298 krb5_error_code kret; 299 char **values; 300 int idx, i; 301 302 if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) { 303 idx = 0; 304 if (uselast) { 305 for (idx=0; values[idx]; idx++); 306 idx--; 307 } 308 309 *stringp = values[idx]; 310 311 /* Free the string storage */ 312 for (i=0; values[i]; i++) 313 if (i != idx) 314 krb5_xfree(values[i]); 315 krb5_xfree(values); 316 } 317 return(kret); 318 } 319 320 /* 321 * krb5_aprof_get_int32() - Get a 32-bit integer value from the alternate 322 * profile. 323 * 324 * Parameters: 325 * acontext - opaque context for alternate profile. 326 * hierarchy - hierarchy of value to retrieve. 327 * uselast - if true, use last value, otherwise use 328 * first value found. 329 * intp - returned 32-bit integer value. 330 * 331 * Returns: 332 * error codes from profile_get_values() 333 * EINVAL - value is not an integer 334 */ 335 krb5_error_code 336 krb5_aprof_get_int32(acontext, hierarchy, uselast, intp) 337 krb5_pointer acontext; 338 const char **hierarchy; 339 krb5_boolean uselast; 340 krb5_int32 *intp; 341 { 342 krb5_error_code kret; 343 char **values; 344 int idx; 345 346 if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) { 347 idx = 0; 348 if (uselast) { 349 for (idx=0; values[idx]; idx++); 350 idx--; 351 } 352 353 if (sscanf(values[idx], "%d", intp) != 1) 354 kret = EINVAL; 355 356 /* Free the string storage */ 357 for (idx=0; values[idx]; idx++) 358 krb5_xfree(values[idx]); 359 krb5_xfree(values); 360 } 361 return(kret); 362 } 363 364 /* 365 * krb5_aprof_finish() - Finish alternate profile context. 366 * 367 * Parameter: 368 * acontext - opaque context for alternate profile. 369 * 370 * Returns: 371 * 0 on success, something else on failure. 372 */ 373 krb5_error_code 374 krb5_aprof_finish(acontext) 375 krb5_pointer acontext; 376 { 377 profile_release(acontext); 378 return(0); 379 } 380 381 /* 382 * Function: kadm5_get_config_params 383 * 384 * Purpose: Merge configuration parameters provided by the caller with 385 * values specified in configuration files and with default values. 386 * 387 * Arguments: 388 * 389 * context (r) krb5_context to use 390 * profile (r) profile file to use 391 * envname (r) envname that contains a profile name to 392 * override profile 393 * params_in (r) params structure containing user-supplied 394 * values, or NULL 395 * params_out (w) params structure to be filled in 396 * 397 * Effects: 398 * 399 * The fields and mask of params_out are filled in with values 400 * obtained from params_in, the specified profile, and default 401 * values. Only and all fields specified in params_out->mask are 402 * set. The context of params_out must be freed with 403 * kadm5_free_config_params. 404 * 405 * params_in and params_out may be the same pointer. However, all pointers 406 * in params_in for which the mask is set will be re-assigned to newly copied 407 * versions, overwriting the old pointer value. 408 */ 409 krb5_error_code kadm5_get_config_params(context, use_kdc_config, 410 params_in, params_out) 411 krb5_context context; 412 int use_kdc_config; 413 kadm5_config_params *params_in, *params_out; 414 { 415 char *filename; 416 char *envname; 417 char *lrealm; 418 krb5_pointer aprofile = 0; 419 const char *hierarchy[4]; 420 char *svalue; 421 krb5_int32 ivalue; 422 kadm5_config_params params, empty_params; 423 424 krb5_error_code kret = 0; 425 krb5_error_code dnsret = 1; 426 427 #ifdef KRB5_DNS_LOOKUP 428 char dns_host[MAX_DNS_NAMELEN]; 429 unsigned short dns_portno; 430 krb5_data dns_realm; 431 memset((char *)&dns_realm, 0, sizeof (dns_realm)); 432 #endif /* KRB5_DNS_LOOKUP */ 433 434 memset((char *) ¶ms, 0, sizeof(params)); 435 memset((char *) &empty_params, 0, sizeof(empty_params)); 436 437 if (params_in == NULL) params_in = &empty_params; 438 439 if (params_in->mask & KADM5_CONFIG_REALM) { 440 lrealm = params.realm = strdup(params_in->realm); 441 if (params.realm) 442 params.mask |= KADM5_CONFIG_REALM; 443 } else { 444 kret = krb5_get_default_realm(context, &lrealm); 445 if (kret) 446 goto cleanup; 447 params.realm = lrealm; 448 params.mask |= KADM5_CONFIG_REALM; 449 } 450 /* 451 * XXX These defaults should to work on both client and 452 * server. kadm5_get_config_params can be implemented as a 453 * wrapper function in each library that provides correct 454 * defaults for NULL values. 455 */ 456 if (use_kdc_config) { 457 filename = DEFAULT_KDC_PROFILE; 458 envname = KDC_PROFILE_ENV; 459 } else { 460 filename = DEFAULT_PROFILE_PATH; 461 envname = "KRB5_CONFIG"; 462 } 463 if (context->profile_secure == TRUE) envname = 0; 464 465 kret = krb5_aprof_init(filename, envname, &aprofile); 466 if (kret) 467 goto cleanup; 468 469 /* Initialize realm parameters */ 470 hierarchy[0] = "realms"; 471 hierarchy[1] = lrealm; 472 hierarchy[3] = (char *) NULL; 473 474 #ifdef KRB5_DNS_LOOKUP 475 /* 476 * Initialize realm info for (possible) DNS lookups. 477 */ 478 dns_realm.data = strdup(lrealm); 479 dns_realm.length = strlen(lrealm); 480 dns_realm.magic = 0; 481 #endif /* KRB5_DNS_LOOKUP */ 482 483 /* Get the value for the admin server */ 484 hierarchy[2] = "admin_server"; 485 if (params_in->mask & KADM5_CONFIG_ADMIN_SERVER) { 486 params.admin_server = strdup(params_in->admin_server); 487 if (params.admin_server) 488 params.mask |= KADM5_CONFIG_ADMIN_SERVER; 489 } else if (aprofile && 490 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 491 params.admin_server = svalue; 492 params.mask |= KADM5_CONFIG_ADMIN_SERVER; 493 } 494 #ifdef KRB5_DNS_LOOKUP 495 else if (strcmp(envname, "KRB5_CONFIG") == 0) { 496 /* 497 * Solaris Kerberos: only do DNS lookup for admin_server if this 498 * is a krb5.conf type of config file. Note, the filename may 499 * not be /etc/krb5/krb5.conf so we assume that the KRB5_CONFIG 500 * envname string will consistently indicate the type of config 501 * file. 502 */ 503 dnsret = krb5_get_servername(context, &dns_realm, 504 "_kerberos-adm", "_udp", 505 dns_host, &dns_portno); 506 if (dnsret == 0) { 507 params.admin_server = strdup(dns_host); 508 if (params.admin_server) 509 params.mask |= KADM5_CONFIG_ADMIN_SERVER; 510 params.kadmind_port = dns_portno; 511 params.mask |= KADM5_CONFIG_KADMIND_PORT; 512 } 513 } 514 #endif /* KRB5_DNS_LOOKUP */ 515 516 if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) && dnsret) { 517 char *p; 518 p = strchr(params.admin_server, ':'); 519 if (p) { 520 params.kadmind_port = atoi(p+1); 521 params.mask |= KADM5_CONFIG_KADMIND_PORT; 522 *p = '\0'; 523 } 524 } 525 526 /* Get the value for the database */ 527 hierarchy[2] = "database_name"; 528 if (params_in->mask & KADM5_CONFIG_DBNAME) { 529 params.dbname = strdup(params_in->dbname); 530 if (params.dbname) 531 params.mask |= KADM5_CONFIG_DBNAME; 532 } else if (aprofile && 533 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 534 params.dbname = svalue; 535 params.mask |= KADM5_CONFIG_DBNAME; 536 } else { 537 params.dbname = strdup(DEFAULT_KDB_FILE); 538 if (params.dbname) 539 params.mask |= KADM5_CONFIG_DBNAME; 540 } 541 542 /* 543 * admin database name and lockfile are now always derived from dbname 544 */ 545 if (params.mask & KADM5_CONFIG_DBNAME) { 546 params.admin_dbname = (char *) malloc(strlen(params.dbname) + 7); 547 if (params.admin_dbname) { 548 sprintf(params.admin_dbname, "%s.kadm5", params.dbname); 549 params.mask |= KADM5_CONFIG_ADBNAME; 550 } 551 } 552 553 if (params.mask & KADM5_CONFIG_ADBNAME) { 554 params.admin_lockfile = (char *) malloc(strlen(params.admin_dbname) 555 + 6); 556 if (params.admin_lockfile) { 557 sprintf(params.admin_lockfile, "%s.lock", params.admin_dbname); 558 params.mask |= KADM5_CONFIG_ADB_LOCKFILE; 559 } 560 } 561 562 /* Get the value for the admin (policy) database lock file*/ 563 hierarchy[2] = "admin_keytab"; 564 if (params_in->mask & KADM5_CONFIG_ADMIN_KEYTAB) { 565 params.admin_keytab = strdup(params_in->admin_keytab); 566 if (params.admin_keytab) 567 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB; 568 } else if (aprofile && 569 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 570 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB; 571 params.admin_keytab = svalue; 572 } else if ((params.admin_keytab = (char *) getenv("KRB5_KTNAME"))) { 573 params.admin_keytab = strdup(params.admin_keytab); 574 if (params.admin_keytab) 575 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB; 576 } else { 577 params.admin_keytab = strdup(DEFAULT_KADM5_KEYTAB); 578 if (params.admin_keytab) 579 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB; 580 } 581 582 /* Get the name of the acl file */ 583 hierarchy[2] = "acl_file"; 584 if (params_in->mask & KADM5_CONFIG_ACL_FILE) { 585 params.acl_file = strdup(params_in->acl_file); 586 if (params.acl_file) 587 params.mask |= KADM5_CONFIG_ACL_FILE; 588 } else if (aprofile && 589 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 590 params.mask |= KADM5_CONFIG_ACL_FILE; 591 params.acl_file = svalue; 592 } else { 593 params.acl_file = strdup(DEFAULT_KADM5_ACL_FILE); 594 if (params.acl_file) 595 params.mask |= KADM5_CONFIG_ACL_FILE; 596 } 597 598 /* Get the name of the dict file */ 599 hierarchy[2] = "dict_file"; 600 if (params_in->mask & KADM5_CONFIG_DICT_FILE) { 601 params.dict_file = strdup(params_in->dict_file); 602 if (params.dict_file) 603 params.mask |= KADM5_CONFIG_DICT_FILE; 604 } else if (aprofile && 605 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 606 params.mask |= KADM5_CONFIG_DICT_FILE; 607 params.dict_file = svalue; 608 } 609 610 /* Get the value for the kadmind port */ 611 if (! (params.mask & KADM5_CONFIG_KADMIND_PORT)) { 612 hierarchy[2] = "kadmind_port"; 613 if (params_in->mask & KADM5_CONFIG_KADMIND_PORT) { 614 params.mask |= KADM5_CONFIG_KADMIND_PORT; 615 params.kadmind_port = params_in->kadmind_port; 616 } else if (aprofile && 617 !krb5_aprof_get_int32(aprofile, hierarchy, TRUE, 618 &ivalue)) { 619 params.kadmind_port = ivalue; 620 params.mask |= KADM5_CONFIG_KADMIND_PORT; 621 } else { 622 params.kadmind_port = DEFAULT_KADM5_PORT; 623 params.mask |= KADM5_CONFIG_KADMIND_PORT; 624 } 625 } 626 627 /* Get the value for the kpasswd port */ 628 if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) { 629 hierarchy[2] = "kpasswd_port"; 630 if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT) { 631 params.mask |= KADM5_CONFIG_KPASSWD_PORT; 632 params.kpasswd_port = params_in->kpasswd_port; 633 } else if (aprofile && 634 !krb5_aprof_get_int32(aprofile, hierarchy, TRUE, 635 &ivalue)) { 636 params.kpasswd_port = ivalue; 637 params.mask |= KADM5_CONFIG_KPASSWD_PORT; 638 } else { 639 params.kpasswd_port = DEFAULT_KPASSWD_PORT; 640 params.mask |= KADM5_CONFIG_KPASSWD_PORT; 641 } 642 } 643 644 /* Get the value for the master key name */ 645 hierarchy[2] = "master_key_name"; 646 if (params_in->mask & KADM5_CONFIG_MKEY_NAME) { 647 params.mkey_name = strdup(params_in->mkey_name); 648 if (params.mkey_name) 649 params.mask |= KADM5_CONFIG_MKEY_NAME; 650 } else if (aprofile && 651 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 652 params.mask |= KADM5_CONFIG_MKEY_NAME; 653 params.mkey_name = svalue; 654 } 655 656 /* Get the value for the master key type */ 657 hierarchy[2] = "master_key_type"; 658 if (params_in->mask & KADM5_CONFIG_ENCTYPE) { 659 params.mask |= KADM5_CONFIG_ENCTYPE; 660 params.enctype = params_in->enctype; 661 } else if (aprofile && 662 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 663 if (!krb5_string_to_enctype(svalue, ¶ms.enctype)) { 664 params.mask |= KADM5_CONFIG_ENCTYPE; 665 krb5_xfree(svalue); 666 } 667 } else { 668 params.mask |= KADM5_CONFIG_ENCTYPE; 669 params.enctype = DEFAULT_KDC_ENCTYPE; 670 } 671 672 /* Get the value for mkey_from_kbd */ 673 if (params_in->mask & KADM5_CONFIG_MKEY_FROM_KBD) { 674 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD; 675 params.mkey_from_kbd = params_in->mkey_from_kbd; 676 } 677 678 /* Get the value for the stashfile */ 679 hierarchy[2] = "key_stash_file"; 680 if (params_in->mask & KADM5_CONFIG_STASH_FILE) { 681 params.stash_file = strdup(params_in->stash_file); 682 if (params.stash_file) 683 params.mask |= KADM5_CONFIG_STASH_FILE; 684 } else if (aprofile && 685 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 686 params.mask |= KADM5_CONFIG_STASH_FILE; 687 params.stash_file = svalue; 688 } 689 690 /* 691 * Solaris Kerberos 692 * Get the value for maximum ticket lifetime. 693 * See SEAM documentation or the Bug ID 4184504 694 * We have changed the logic so that the entries are 695 * created in the database with the maximum duration 696 * for life and renew life KRB5_INT32_MAX 697 * However this wil get negotiated down when 698 * as or tgs request is processed by KDC. 699 */ 700 hierarchy[2] = "max_life"; 701 if (params_in->mask & KADM5_CONFIG_MAX_LIFE) { 702 params.mask |= KADM5_CONFIG_MAX_LIFE; 703 params.max_life = params_in->max_life; 704 } else { 705 params.max_life = KRB5_INT32_MAX; 706 params.mask |= KADM5_CONFIG_MAX_LIFE; 707 } 708 709 /* Get the value for maximum renewable ticket lifetime. */ 710 hierarchy[2] = "max_renewable_life"; 711 if (params_in->mask & KADM5_CONFIG_MAX_RLIFE) { 712 params.mask |= KADM5_CONFIG_MAX_RLIFE; 713 params.max_rlife = params_in->max_rlife; 714 } else { 715 params.max_rlife = KRB5_INT32_MAX; 716 params.mask |= KADM5_CONFIG_MAX_RLIFE; 717 } 718 719 /* Get the value for the default principal expiration */ 720 hierarchy[2] = "default_principal_expiration"; 721 if (params_in->mask & KADM5_CONFIG_EXPIRATION) { 722 params.mask |= KADM5_CONFIG_EXPIRATION; 723 params.expiration = params_in->expiration; 724 } else if (aprofile && 725 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 726 if (!krb5_string_to_timestamp(svalue, ¶ms.expiration)) { 727 params.mask |= KADM5_CONFIG_EXPIRATION; 728 krb5_xfree(svalue); 729 } 730 } else { 731 params.mask |= KADM5_CONFIG_EXPIRATION; 732 params.expiration = 0; 733 } 734 735 /* Get the value for the default principal flags */ 736 hierarchy[2] = "default_principal_flags"; 737 if (params_in->mask & KADM5_CONFIG_FLAGS) { 738 params.mask |= KADM5_CONFIG_FLAGS; 739 params.flags = params_in->flags; 740 } else if (aprofile && 741 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 742 char *sp, *ep, *tp; 743 744 sp = svalue; 745 params.flags = 0; 746 while (sp) { 747 if ((ep = strchr(sp, (int) ',')) || 748 (ep = strchr(sp, (int) ' ')) || 749 (ep = strchr(sp, (int) '\t'))) { 750 /* Fill in trailing whitespace of sp */ 751 tp = ep - 1; 752 while (isspace((int) *tp) && (tp > sp)) { 753 *tp = '\0'; 754 tp--; 755 } 756 *ep = '\0'; 757 ep++; 758 /* Skip over trailing whitespace of ep */ 759 while (isspace((int) *ep) && (*ep)) ep++; 760 } 761 /* Convert this flag */ 762 if (krb5_string_to_flags(sp, 763 "+", 764 "-", 765 ¶ms.flags)) 766 break; 767 sp = ep; 768 } 769 if (!sp) 770 params.mask |= KADM5_CONFIG_FLAGS; 771 krb5_xfree(svalue); 772 } else { 773 params.mask |= KADM5_CONFIG_FLAGS; 774 params.flags = KRB5_KDB_DEF_FLAGS; 775 } 776 777 /* Get the value for the supported enctype/salttype matrix */ 778 hierarchy[2] = "supported_enctypes"; 779 if (params_in->mask & KADM5_CONFIG_ENCTYPES) { 780 params.mask |= KADM5_CONFIG_ENCTYPES; 781 if (params_in->num_keysalts > 0) { 782 params.keysalts = malloc(params_in->num_keysalts * 783 sizeof (*params.keysalts)); 784 if (params.keysalts == NULL) { 785 kret = ENOMEM; 786 goto cleanup; 787 } 788 (void) memcpy(params.keysalts, params_in->keysalts, 789 (params_in->num_keysalts * 790 sizeof (*params.keysalts))); 791 params.num_keysalts = params_in->num_keysalts; 792 } 793 } else { 794 svalue = NULL; 795 if (aprofile) 796 krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); 797 if (svalue == NULL) 798 svalue = strdup(DEFAULT_ENCTYPE_LIST); 799 800 params.keysalts = NULL; 801 params.num_keysalts = 0; 802 krb5_string_to_keysalts(svalue, 803 ", \t",/* Tuple separators */ 804 ":.-", /* Key/salt separators */ 805 0, /* No duplicates */ 806 ¶ms.keysalts, 807 ¶ms.num_keysalts); 808 if (params.num_keysalts) 809 params.mask |= KADM5_CONFIG_ENCTYPES; 810 811 if (svalue) 812 krb5_xfree(svalue); 813 } 814 815 hierarchy[2] = "kpasswd_server"; 816 if (params_in->mask & KADM5_CONFIG_KPASSWD_SERVER) { 817 params.mask |= KADM5_CONFIG_KPASSWD_SERVER; 818 params.kpasswd_server = strdup(params_in->kpasswd_server); 819 } else { 820 svalue = NULL; 821 822 if (aprofile) 823 krb5_aprof_get_string(aprofile, hierarchy, 824 TRUE, &svalue); 825 if (svalue == NULL) { 826 #ifdef KRB5_DNS_LOOKUP 827 if (strcmp(envname, "KRB5_CONFIG") == 0) { 828 /* 829 * Solaris Kerberos: only do DNS lookup for 830 * kpasswd_server if this is a krb5.conf type of 831 * config file. Note, the filename may not be 832 * /etc/krb5/krb5.conf so we assume that the 833 * KRB5_CONFIG envname string will consistently 834 * indicate the type of config file. 835 */ 836 dnsret = krb5_get_servername(context, 837 &dns_realm, "_kpasswd", "_udp", 838 dns_host, &dns_portno); 839 840 if (dnsret == 0) { 841 params.kpasswd_server = 842 strdup(dns_host); 843 if (params.kpasswd_server) { 844 params.mask |= 845 KADM5_CONFIG_KPASSWD_SERVER; 846 } 847 params.kpasswd_port = dns_portno; 848 params.mask |= 849 KADM5_CONFIG_KPASSWD_PORT; 850 } 851 } 852 #endif /* KRB5_DNS_LOOKUP */ 853 854 /* 855 * If a unique 'kpasswd_server' is not specified, 856 * use the normal 'admin_server'. 857 */ 858 if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) && 859 dnsret) { 860 params.kpasswd_server = 861 strdup(params.admin_server); 862 params.mask |= KADM5_CONFIG_KPASSWD_SERVER; 863 } 864 } else { 865 char *p; 866 params.kpasswd_server = svalue; 867 params.mask |= KADM5_CONFIG_KPASSWD_SERVER; 868 869 if ((p = strchr(params.kpasswd_server, ':'))) { 870 params.kpasswd_port = atoi(p+1); 871 params.mask |= KADM5_CONFIG_KPASSWD_PORT; 872 *p = '\0'; 873 } 874 } 875 } 876 877 hierarchy[2] = "kpasswd_protocol"; 878 879 /* default to current RPCSEC_GSS protocol */ 880 params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC; 881 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL; 882 883 if (params_in->mask & KADM5_CONFIG_KPASSWD_PROTOCOL) { 884 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL; 885 params.kpasswd_protocol = params_in->kpasswd_protocol; 886 } else { 887 svalue = NULL; 888 889 if (aprofile) 890 krb5_aprof_get_string(aprofile, hierarchy, 891 TRUE, &svalue); 892 if (svalue != NULL) { 893 if (strcasecmp(svalue, "RPCSEC_GSS") == 0) { 894 params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC; 895 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL; 896 } else if (strcasecmp(svalue, "SET_CHANGE") == 0) { 897 params.kpasswd_protocol = 898 KRB5_CHGPWD_CHANGEPW_V2; 899 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL; 900 } 901 } 902 if (svalue) 903 krb5_xfree(svalue); 904 } 905 906 /* 907 * If the kpasswd_port is not yet defined, define it now. 908 */ 909 if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) { 910 if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT) 911 params.kpasswd_port = params_in->kpasswd_port; 912 /* 913 * If kpasswd_port is not explicitly defined, 914 * determine the port to use based on the protocol. 915 * The alternative protocol uses a different port 916 * than the standard admind port. 917 */ 918 else if (params.kpasswd_protocol == KRB5_CHGPWD_RPCSEC) { 919 params.kpasswd_port = DEFAULT_KADM5_PORT; 920 } else { 921 /* 922 * When using the Horowitz/IETF protocol for 923 * password changing, the default port is 464 924 * (officially recognized by IANA). 925 */ 926 params.kpasswd_port = DEFAULT_KPASSWD_PORT; 927 } 928 params.mask |= KADM5_CONFIG_KPASSWD_PORT; 929 } 930 931 hierarchy[2] = "sunw_dbprop_enable"; 932 933 params.iprop_enabled = FALSE; 934 params.mask |= KADM5_CONFIG_IPROP_ENABLED; 935 936 if (params_in->mask & KADM5_CONFIG_IPROP_ENABLED) { 937 params.mask |= KADM5_CONFIG_IPROP_ENABLED; 938 params.iprop_enabled = params_in->iprop_enabled; 939 } else { 940 if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy, 941 TRUE, &svalue)) { 942 if (strncasecmp(svalue, "Y", 1) == 0) 943 params.iprop_enabled = TRUE; 944 if (strncasecmp(svalue, "true", 4) == 0) 945 params.iprop_enabled = TRUE; 946 params.mask |= KADM5_CONFIG_IPROP_ENABLED; 947 krb5_xfree(svalue); 948 } 949 } 950 951 hierarchy[2] = "sunw_dbprop_master_ulogsize"; 952 953 params.iprop_ulogsize = DEF_ULOGENTRIES; 954 params.mask |= KADM5_CONFIG_ULOG_SIZE; 955 956 if (params_in->mask & KADM5_CONFIG_ULOG_SIZE) { 957 params.mask |= KADM5_CONFIG_ULOG_SIZE; 958 params.iprop_ulogsize = params_in->iprop_ulogsize; 959 } else { 960 if (aprofile && !krb5_aprof_get_int32(aprofile, hierarchy, 961 TRUE, &ivalue)) { 962 if (ivalue > MAX_ULOGENTRIES) 963 params.iprop_ulogsize = MAX_ULOGENTRIES; 964 else if (ivalue <= 0) 965 params.iprop_ulogsize = DEF_ULOGENTRIES; 966 else 967 params.iprop_ulogsize = ivalue; 968 params.mask |= KADM5_CONFIG_ULOG_SIZE; 969 } 970 } 971 972 hierarchy[2] = "sunw_dbprop_slave_poll"; 973 974 params.iprop_polltime = strdup("2m"); 975 if (params.iprop_polltime) 976 params.mask |= KADM5_CONFIG_POLL_TIME; 977 978 if (params_in->mask & KADM5_CONFIG_POLL_TIME) { 979 if (params.iprop_polltime) 980 free(params.iprop_polltime); 981 params.iprop_polltime = strdup(params_in->iprop_polltime); 982 if (params.iprop_polltime) 983 params.mask |= KADM5_CONFIG_POLL_TIME; 984 } else { 985 if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy, 986 TRUE, &svalue)) { 987 if (params.iprop_polltime) 988 free(params.iprop_polltime); 989 params.iprop_polltime = strdup(svalue); 990 params.mask |= KADM5_CONFIG_POLL_TIME; 991 krb5_xfree(svalue); 992 } 993 } 994 995 *params_out = params; 996 997 cleanup: 998 if (aprofile) 999 krb5_aprof_finish(aprofile); 1000 if (kret) { 1001 kadm5_free_config_params(context, ¶ms); 1002 params_out->mask = 0; 1003 } 1004 #ifdef KRB5_DNS_LOOKUP 1005 if (dns_realm.data) 1006 free(dns_realm.data); 1007 #endif /* KRB5_DNS_LOOKUP */ 1008 1009 return(kret); 1010 } 1011 /* 1012 * kadm5_free_config_params() - Free data allocated by above. 1013 */ 1014 /*ARGSUSED*/ 1015 krb5_error_code 1016 kadm5_free_config_params(context, params) 1017 krb5_context context; 1018 kadm5_config_params *params; 1019 { 1020 if (params) { 1021 if (params->dbname) { 1022 krb5_xfree(params->dbname); 1023 params->dbname = NULL; 1024 } 1025 if (params->mkey_name) { 1026 krb5_xfree(params->mkey_name); 1027 params->mkey_name = NULL; 1028 } 1029 if (params->stash_file) { 1030 krb5_xfree(params->stash_file); 1031 params->stash_file = NULL; 1032 } 1033 if (params->keysalts) { 1034 krb5_xfree(params->keysalts); 1035 params->keysalts = NULL; 1036 params->num_keysalts = 0; 1037 } 1038 if (params->admin_keytab) { 1039 free(params->admin_keytab); 1040 params->admin_keytab = NULL; 1041 } 1042 if (params->dict_file) { 1043 free(params->dict_file); 1044 params->dict_file = NULL; 1045 } 1046 if (params->acl_file) { 1047 free(params->acl_file); 1048 params->acl_file = NULL; 1049 } 1050 if (params->realm) { 1051 free(params->realm); 1052 params->realm = NULL; 1053 } 1054 if (params->admin_dbname) { 1055 free(params->admin_dbname); 1056 params->admin_dbname = NULL; 1057 } 1058 if (params->admin_lockfile) { 1059 free(params->admin_lockfile); 1060 params->admin_lockfile = NULL; 1061 } 1062 if (params->admin_server) { 1063 free(params->admin_server); 1064 params->admin_server = NULL; 1065 } 1066 if (params->kpasswd_server) { 1067 free(params->kpasswd_server); 1068 params->kpasswd_server = NULL; 1069 } 1070 if (params->iprop_polltime) { 1071 free(params->iprop_polltime); 1072 params->iprop_polltime = NULL; 1073 } 1074 } 1075 return (0); 1076 } 1077 1078 krb5_error_code 1079 kadm5_get_admin_service_name(krb5_context ctx, 1080 char *realm_in, 1081 char *admin_name, 1082 size_t maxlen) 1083 { 1084 krb5_error_code ret; 1085 kadm5_config_params params_in, params_out; 1086 struct hostent *hp; 1087 1088 memset(¶ms_in, 0, sizeof(params_in)); 1089 memset(¶ms_out, 0, sizeof(params_out)); 1090 1091 params_in.mask |= KADM5_CONFIG_REALM; 1092 params_in.realm = realm_in; 1093 ret = kadm5_get_config_params(ctx, 0, ¶ms_in, ¶ms_out); 1094 if (ret) 1095 return ret; 1096 1097 if (!(params_out.mask & KADM5_CONFIG_ADMIN_SERVER)) { 1098 ret = KADM5_MISSING_KRB5_CONF_PARAMS; 1099 goto err_params; 1100 } 1101 1102 hp = gethostbyname(params_out.admin_server); 1103 if (hp == NULL) { 1104 ret = errno; 1105 goto err_params; 1106 } 1107 if (strlen(hp->h_name) + sizeof("kadmin/") > maxlen) { 1108 ret = ENOMEM; 1109 goto err_params; 1110 } 1111 sprintf(admin_name, "kadmin/%s", hp->h_name); 1112 1113 err_params: 1114 kadm5_free_config_params(ctx, ¶ms_out); 1115 return ret; 1116 } 1117 1118 /*********************************************************************** 1119 * This is the old krb5_realm_read_params, which I mutated into 1120 * kadm5_get_config_params but which old code (kdb5_* and krb5kdc) 1121 * still uses. 1122 ***********************************************************************/ 1123 1124 /* 1125 * krb5_read_realm_params() - Read per-realm parameters from KDC 1126 * alternate profile. 1127 */ 1128 krb5_error_code 1129 krb5_read_realm_params(kcontext, realm, rparamp) 1130 krb5_context kcontext; 1131 char *realm; 1132 krb5_realm_params **rparamp; 1133 { 1134 char *filename; 1135 char *envname; 1136 char *lrealm; 1137 krb5_pointer aprofile = 0; 1138 krb5_realm_params *rparams; 1139 const char *hierarchy[4]; 1140 char *svalue; 1141 krb5_int32 ivalue; 1142 krb5_boolean bvalue; 1143 krb5_deltat dtvalue; 1144 1145 char *kdcprofile = 0; 1146 char *kdcenv = 0; 1147 1148 krb5_error_code kret; 1149 1150 filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE; 1151 envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV; 1152 1153 if (kcontext->profile_secure == TRUE) envname = 0; 1154 1155 rparams = (krb5_realm_params *) NULL; 1156 if (realm) 1157 lrealm = strdup(realm); 1158 else { 1159 kret = krb5_get_default_realm(kcontext, &lrealm); 1160 if (kret) 1161 goto cleanup; 1162 } 1163 1164 kret = krb5_aprof_init(filename, envname, &aprofile); 1165 if (kret) 1166 goto cleanup; 1167 1168 rparams = (krb5_realm_params *) malloc(sizeof(krb5_realm_params)); 1169 if (rparams == 0) { 1170 kret = ENOMEM; 1171 goto cleanup; 1172 } 1173 1174 /* Initialize realm parameters */ 1175 memset((char *) rparams, 0, sizeof(krb5_realm_params)); 1176 1177 /* Get the value for the database */ 1178 hierarchy[0] = "realms"; 1179 hierarchy[1] = lrealm; 1180 hierarchy[2] = "database_name"; 1181 hierarchy[3] = (char *) NULL; 1182 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) 1183 rparams->realm_dbname = svalue; 1184 1185 /* Get the value for the KDC port list */ 1186 hierarchy[2] = "kdc_ports"; 1187 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) 1188 rparams->realm_kdc_ports = svalue; 1189 hierarchy[2] = "kdc_tcp_ports"; 1190 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) 1191 rparams->realm_kdc_tcp_ports = svalue; 1192 1193 /* Get the name of the acl file */ 1194 hierarchy[2] = "acl_file"; 1195 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) 1196 rparams->realm_acl_file = svalue; 1197 1198 /* Get the value for the kadmind port */ 1199 hierarchy[2] = "kadmind_port"; 1200 if (!krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) { 1201 rparams->realm_kadmind_port = ivalue; 1202 rparams->realm_kadmind_port_valid = 1; 1203 } 1204 1205 /* Get the value for the master key name */ 1206 hierarchy[2] = "master_key_name"; 1207 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) 1208 rparams->realm_mkey_name = svalue; 1209 1210 /* Get the value for the master key type */ 1211 hierarchy[2] = "master_key_type"; 1212 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 1213 if (!krb5_string_to_enctype(svalue, &rparams->realm_enctype)) 1214 rparams->realm_enctype_valid = 1; 1215 krb5_xfree(svalue); 1216 } 1217 1218 /* Get the value for the stashfile */ 1219 hierarchy[2] = "key_stash_file"; 1220 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) 1221 rparams->realm_stash_file = svalue; 1222 1223 /* Get the value for maximum ticket lifetime. */ 1224 hierarchy[2] = "max_life"; 1225 if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) { 1226 rparams->realm_max_life = dtvalue; 1227 rparams->realm_max_life_valid = 1; 1228 } 1229 1230 /* Get the value for maximum renewable ticket lifetime. */ 1231 hierarchy[2] = "max_renewable_life"; 1232 if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) { 1233 rparams->realm_max_rlife = dtvalue; 1234 rparams->realm_max_rlife_valid = 1; 1235 } 1236 1237 /* Get the value for the default principal expiration */ 1238 hierarchy[2] = "default_principal_expiration"; 1239 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 1240 if (!krb5_string_to_timestamp(svalue, 1241 &rparams->realm_expiration)) 1242 rparams->realm_expiration_valid = 1; 1243 krb5_xfree(svalue); 1244 } 1245 1246 hierarchy[2] = "reject_bad_transit"; 1247 if (!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) { 1248 rparams->realm_reject_bad_transit = bvalue; 1249 rparams->realm_reject_bad_transit_valid = 1; 1250 } 1251 1252 /* Get the value for the default principal flags */ 1253 hierarchy[2] = "default_principal_flags"; 1254 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { 1255 char *sp, *ep, *tp; 1256 1257 sp = svalue; 1258 rparams->realm_flags = 0; 1259 while (sp) { 1260 if ((ep = strchr(sp, (int) ',')) || 1261 (ep = strchr(sp, (int) ' ')) || 1262 (ep = strchr(sp, (int) '\t'))) { 1263 /* Fill in trailing whitespace of sp */ 1264 tp = ep - 1; 1265 while (isspace((int) *tp) && (tp < sp)) { 1266 *tp = '\0'; 1267 tp--; 1268 } 1269 *ep = '\0'; 1270 ep++; 1271 /* Skip over trailing whitespace of ep */ 1272 while (isspace((int) *ep) && (*ep)) ep++; 1273 } 1274 /* Convert this flag */ 1275 if (krb5_string_to_flags(sp, 1276 "+", 1277 "-", 1278 &rparams->realm_flags)) 1279 break; 1280 sp = ep; 1281 } 1282 if (!sp) 1283 rparams->realm_flags_valid = 1; 1284 krb5_xfree(svalue); 1285 } 1286 1287 /* Get the value for the supported enctype/salttype matrix */ 1288 /* 1289 * SUNWresync121 1290 * Solaris kerberos: updated this code to support default values for 1291 * the supported_enctypes. 1292 */ 1293 hierarchy[2] = "supported_enctypes"; 1294 svalue = NULL; 1295 krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); 1296 1297 /* 1298 * Set the default value if supported_enctypes was not explicitly 1299 * set in the kdc.conf. 1300 */ 1301 if (svalue == NULL) { 1302 svalue = strdup(DEFAULT_ENCTYPE_LIST); 1303 } 1304 if (svalue != NULL) { 1305 krb5_string_to_keysalts(svalue, 1306 ", \t", /* Tuple separators */ 1307 ":.-", /* Key/salt separators */ 1308 0, /* No duplicates */ 1309 &rparams->realm_keysalts, 1310 &rparams->realm_num_keysalts); 1311 krb5_xfree(svalue); 1312 svalue = NULL; 1313 } 1314 cleanup: 1315 if (aprofile) 1316 krb5_aprof_finish(aprofile); 1317 if (lrealm) 1318 free(lrealm); 1319 if (kret) { 1320 if (rparams) 1321 krb5_free_realm_params(kcontext, rparams); 1322 rparams = 0; 1323 } 1324 *rparamp = rparams; 1325 return(kret); 1326 } 1327 1328 /* 1329 * krb5_free_realm_params() - Free data allocated by above. 1330 */ 1331 krb5_error_code 1332 krb5_free_realm_params(kcontext, rparams) 1333 krb5_context kcontext; 1334 krb5_realm_params *rparams; 1335 { 1336 if (rparams) { 1337 if (rparams->realm_profile) 1338 krb5_xfree(rparams->realm_profile); 1339 if (rparams->realm_dbname) 1340 krb5_xfree(rparams->realm_dbname); 1341 if (rparams->realm_mkey_name) 1342 krb5_xfree(rparams->realm_mkey_name); 1343 if (rparams->realm_stash_file) 1344 krb5_xfree(rparams->realm_stash_file); 1345 if (rparams->realm_keysalts) 1346 krb5_xfree(rparams->realm_keysalts); 1347 if (rparams->realm_kdc_ports) 1348 krb5_xfree(rparams->realm_kdc_ports); 1349 if (rparams->realm_kdc_tcp_ports) 1350 krb5_xfree(rparams->realm_kdc_tcp_ports); 1351 if (rparams->realm_acl_file) 1352 krb5_xfree(rparams->realm_acl_file); 1353 krb5_xfree(rparams); 1354 } 1355 return(0); 1356 } 1357 1358