1   /*
   2 |  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
   2 |  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
   3    * Use is subject to license terms.
   4    */
   5   
   6 | #pragma ident        "@(#)alt_prof.c        1.13        04/09/08 SMI"
   6 | #pragma ident        "@(#)alt_prof.c        1.12        04/03/19 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    * lib/kadm/alt_prof.c
  28    *
  29    * Copyright 1995 by the Massachusetts Institute of Technology.
  30    * All Rights Reserved.
  31    *
  32    * Export of this software from the United States of America may
  33    *   require a specific license from the United States Government.
  34    *   It is the responsibility of any person or organization contemplating
  35    *   export to obtain such a license before exporting.
  36    *
  37    * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  38    * distribute this software and its documentation for any purpose and
  39    * without fee is hereby granted, provided that the above copyright
  40    * notice appear in all copies and that both that copyright notice and
  41    * this permission notice appear in supporting documentation, and that
  42    * the name of M.I.T. not be used in advertising or publicity pertaining
  43    * to distribution of the software without specific, written prior
  44    * permission.  M.I.T. makes no representations about the suitability of
  45    * this software for any purpose.  It is provided "as is" without express
  46    * or implied warranty.
  47    *
  48    */
  49   
  50   /*
  51    * alt_prof.c - Implement alternate profile file handling.
  52    */
  53   #include <k5-int.h>
  54   #include <kadm5/admin.h>
  55   #include <adm_proto.h>
  56   #include <stdio.h>
  57   #include <ctype.h>
  58   #include <os-proto.h>
  59 + #include <kdb/kdb_log.h>
  60   
  61   krb5_error_code kadm5_free_config_params();
  62   
  63   #define        DEFAULT_ENCTYPE_LIST \
  64           "aes256-cts-hmac-sha1-96:normal " \
  65           "aes128-cts-hmac-sha1-96:normal " \
  66           "des3-cbc-hmac-sha1-kd:normal " \
  67           "arcfour-hmac-md5:normal " \
  68           "des-cbc-md5:normal " \
  69           "des-cbc-crc:normal"
  70   
  71   /*
  72    * krb5_aprof_init()        - Initialize alternate profile context.
  73    *
  74    * Parameters:
  75    *        fname                - default file name of the profile.
  76    *        envname                - environment variable name which can override fname.
  77    *        acontextp        - Pointer to opaque context for alternate profile.
  78    *
  79    * Returns:
  80    *        error codes from profile_init()
  81    */
  82   krb5_error_code
  83   krb5_aprof_init(fname, envname, acontextp)
  84   char                *fname;
  85   char                *envname;
  86   krb5_pointer        *acontextp;
  87   {
  88           krb5_error_code        kret;
  89           const char                *namelist[2];
  90           profile_t                profile;
  91   
  92           namelist[1] = (char *)NULL;
  93           profile = (profile_t)NULL;
  94           if (envname) {
  95                   if ((namelist[0] = getenv(envname))) {
  96                           kret = profile_init(namelist, &profile);
  97                           if (kret)
  98                                   return (kret);
  99                           *acontextp = (krb5_pointer) profile;
 100                           return (0);
 101                   }
 102           }
 103           profile = (profile_t)NULL;
 104           if (fname) {
 105                   kret = profile_init_path(fname, &profile);
 106                   if (kret == ENOENT) {
 107                           profile = 0;
 108                   } else if (kret)
 109                           return (kret);
 110                   *acontextp = (krb5_pointer) profile;
 111                   return (0);
 112           }
 113           return (0);
 114   }

 ----Unchanged portion omitted----

 285   
 286   /*
 287    * Function: kadm5_get_config_params
 288    *
 289    * Purpose: Merge configuration parameters provided by the caller with
 290    * values specified in configuration files and with default values.
 291    *
 292    * Arguments:
 293    *
 294    *        context(r) krb5_context to use
 295    *        profile(r) profile file to use
 296    *        envname(r) envname that contains a profile name to
 297    *                        override profile
 298    *        params_in(r) params structure containing user-supplied
 299    *                        values, or NULL
 300    *        params_out(w) params structure to be filled in
 301    *
 302    * Effects:
 303    *
 304    * The fields and mask of params_out are filled in with values
 305    * obtained from params_in, the specified profile, and default
 306    * values.  Only and all fields specified in params_out->mask are
 307    * set.  The context of params_out must be freed with
 308    * kadm5_free_config_params.
 309    *
 310    * params_in and params_out may be the same pointer.  However, all pointers
 311    * in params_in for which the mask is set will be re-assigned to newly copied
 312    * versions, overwriting the old pointer value.
 313    */
 314   krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
 315                                           params_in, params_out)
 316   krb5_context                context;
 317   char                        *kdcprofile;
 318   char                        *kdcenv;
 319   kadm5_config_params        *params_in, *params_out;
 320   {
 321           char                *filename;
 322           char                *envname;
 323           char                *lrealm;
 324           krb5_pointer        aprofile = 0;
 325           const char        *hierarchy[4];
 326           char                *svalue;
 327           krb5_int32                ivalue;
 328           kadm5_config_params params, empty_params;
 329   
 330           krb5_error_code        kret = 0;
 331           krb5_error_code dnsret = 1;
 332   
 333   #ifdef KRB5_DNS_LOOKUP
 334           char dns_host[MAX_DNS_NAMELEN];
 335           unsigned short dns_portno;
 336           krb5_data dns_realm;
 337   #endif /* KRB5_DNS_LOOKUP */
 338   
 339           memset((char *)&params, 0, sizeof (params));
 340           memset((char *)&empty_params, 0, sizeof (empty_params));
 341   
 342           if (params_in == NULL) params_in = &empty_params;
 343   
 344           if (params_in->mask & KADM5_CONFIG_REALM) {
 345                   lrealm = params.realm = strdup(params_in->realm);
 346                   if (params.realm)
 347                           params.mask |= KADM5_CONFIG_REALM;
 348           } else {
 349                   kret = krb5_get_default_realm(context, &lrealm);
 350                   if (kret)
 351                           goto cleanup;
 352                   params.realm = lrealm;
 353                   params.mask |= KADM5_CONFIG_REALM;
 354           }
 355           if (params_in->mask & KADM5_CONFIG_PROFILE) {
 356                   filename = params.profile = strdup(params_in->profile);
 357                   if (params.profile)
 358                           params.mask |= KADM5_CONFIG_PROFILE;
 359                   envname = NULL;
 360           } else {
 361                   /*
 362                    * XXX These defaults should to work on both client and
 363                    * server.  kadm5_get_config_params can be implemented as a
 364                    * wrapper function in each library that provides correct
 365                    * defaults for NULL values.
 366                    */
 367                   filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
 368                   envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV;
 369                   if (context->profile_secure == TRUE) envname = 0;
 370           }
 371   
 372           kret = krb5_aprof_init(filename, envname, &aprofile);
 373           if (kret)
 374                   goto cleanup;
 375   
 376           /* Initialize realm parameters */
 377           hierarchy[0] = "realms";
 378           hierarchy[1] = lrealm;
 379           hierarchy[3] = (char *)NULL;
 380   
 381   #ifdef KRB5_DNS_LOOKUP
 382           /*
 383            * Initialize realm info for (possible) DNS lookups.
 384            */
 385           dns_realm.data = strdup(lrealm);
 386           dns_realm.length = strlen(lrealm);
 387           dns_realm.magic = 0;
 388   #endif /* KRB5_DNS_LOOKUP */
 389   
 390           /* Get the value for the admin server */
 391           hierarchy[2] = "admin_server";
 392           if (params_in->mask & KADM5_CONFIG_ADMIN_SERVER) {
 393                   params.admin_server = strdup(params_in->admin_server);
 394                   if (params.admin_server)
 395                           params.mask |= KADM5_CONFIG_ADMIN_SERVER;
 396           } else if (aprofile &&
 397                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 398                   params.admin_server = svalue;
 399                   params.mask |= KADM5_CONFIG_ADMIN_SERVER;
 400           }
 401   #ifdef KRB5_DNS_LOOKUP
 402           else if (strcmp(envname, "KRB5_CONFIG") == 0) {
 403                   /*
 404                    * Solaris Kerberos: only do DNS lookup for admin_server if this
 405                    * is a krb5.conf type of config file.  Note, the filename may
 406                    * not be /etc/krb5/krb5.conf so we assume that the KRB5_CONFIG
 407                    * envname string will consistently indicate the type of config
 408                    * file.
 409                    */
 410                   dnsret = krb5_get_servername(context, &dns_realm,
 411                                           "_kerberos-adm", "_udp",
 412                                           dns_host, &dns_portno);
 413                   if (dnsret == 0) {
 414                           params.admin_server = strdup(dns_host);
 415                           if (params.admin_server)
 416                                   params.mask |= KADM5_CONFIG_ADMIN_SERVER;
 417                           params.kadmind_port = dns_portno;
 418                           params.mask |= KADM5_CONFIG_KADMIND_PORT;
 419                   }
 420           }
 421   #endif /* KRB5_DNS_LOOKUP */
 422   
 423           if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) && dnsret) {
 424                   char *p;
 425                   if (p = strchr(params.admin_server, ':')) {
 426                           params.kadmind_port = atoi(p+1);
 427                           params.mask |= KADM5_CONFIG_KADMIND_PORT;
 428                           *p = '\0';
 429                   }
 430           }
 431   
 432           /* Get the value for the database */
 433           hierarchy[2] = "database_name";
 434           if (params_in->mask & KADM5_CONFIG_DBNAME) {
 435                   params.dbname = strdup(params_in->dbname);
 436                   if (params.dbname)
 437                           params.mask |= KADM5_CONFIG_DBNAME;
 438           } else if (aprofile &&
 439                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 440                   params.dbname = svalue;
 441                   params.mask |= KADM5_CONFIG_DBNAME;
 442           } else {
 443                   params.dbname = strdup(DEFAULT_KDB_FILE);
 444                   if (params.dbname)
 445                           params.mask |= KADM5_CONFIG_DBNAME;
 446           }
 447   
 448           /*
 449            * admin database name and lockfile are now always derived from dbname
 450            */
 451           if (params.mask & KADM5_CONFIG_DBNAME) {
 452                   params.admin_dbname = (char *)malloc(strlen(params.dbname)
 453                                                       + 7);
 454                   if (params.admin_dbname) {
 455                           sprintf(params.admin_dbname, "%s.kadm5",
 456                                   params.dbname);
 457                           params.mask |= KADM5_CONFIG_ADBNAME;
 458                   }
 459           }
 460   
 461           if (params.mask & KADM5_CONFIG_ADBNAME) {
 462                   params.admin_lockfile =
 463                           (char *)malloc(strlen(params.admin_dbname)+ 6);
 464                   if (params.admin_lockfile) {
 465                           sprintf(params.admin_lockfile, "%s.lock",
 466                                   params.admin_dbname);
 467                           params.mask |= KADM5_CONFIG_ADB_LOCKFILE;
 468                   }
 469           }
 470   
 471           /* Get the value for the admin(policy) database lock file */
 472           hierarchy[2] = "admin_keytab";
 473           if (params_in->mask & KADM5_CONFIG_ADMIN_KEYTAB) {
 474                   params.admin_keytab = strdup(params_in->admin_keytab);
 475                   if (params.admin_keytab)
 476                           params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
 477           } else if (aprofile &&
 478                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 479                   params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
 480                   params.admin_keytab = svalue;
 481           } else if (params.admin_keytab = (char *)getenv("KRB5_KTNAME")) {
 482                   params.admin_keytab = strdup(params.admin_keytab);
 483                   if (params.admin_keytab)
 484                           params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
 485           } else {
 486                   params.admin_keytab = strdup(DEFAULT_KADM5_KEYTAB);
 487                   if (params.admin_keytab)
 488                           params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
 489           }
 490   
 491           /* Get the name of the acl file */
 492           hierarchy[2] = "acl_file";
 493           if (params_in->mask & KADM5_CONFIG_ACL_FILE) {
 494                   params.acl_file = strdup(params_in->acl_file);
 495                   if (params.acl_file)
 496                           params.mask |= KADM5_CONFIG_ACL_FILE;
 497           } else if (aprofile &&
 498                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 499                   params.mask |= KADM5_CONFIG_ACL_FILE;
 500                   params.acl_file = svalue;
 501           } else {
 502                   params.acl_file = strdup(DEFAULT_KADM5_ACL_FILE);
 503                   if (params.acl_file)
 504                           params.mask |= KADM5_CONFIG_ACL_FILE;
 505           }
 506   
 507           /* Get the name of the dict file */
 508           hierarchy[2] = "dict_file";
 509           if (params_in->mask & KADM5_CONFIG_DICT_FILE) {
 510                   params.dict_file = strdup(params_in->dict_file);
 511                   if (params.dict_file)
 512                           params.mask |= KADM5_CONFIG_DICT_FILE;
 513           } else if (aprofile &&
 514                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 515                   params.mask |= KADM5_CONFIG_DICT_FILE;
 516                   params.dict_file = svalue;
 517           }
 518   
 519           /* Get the value for the kadmind port */
 520           if (! (params.mask & KADM5_CONFIG_KADMIND_PORT)) {
 521                   hierarchy[2] = "kadmind_port";
 522                   if (params_in->mask & KADM5_CONFIG_KADMIND_PORT) {
 523                           params.mask |= KADM5_CONFIG_KADMIND_PORT;
 524                           params.kadmind_port = params_in->kadmind_port;
 525                   } else if (aprofile &&
 526                           !krb5_aprof_get_int32(aprofile, hierarchy, TRUE,
 527                                               &ivalue)) {
 528                           params.kadmind_port = ivalue;
 529                           params.mask |= KADM5_CONFIG_KADMIND_PORT;
 530                   } else {
 531                           params.kadmind_port = DEFAULT_KADM5_PORT;
 532                           params.mask |= KADM5_CONFIG_KADMIND_PORT;
 533                   }
 534           }
 535   
 536           /* Get the value for the master key name */
 537           hierarchy[2] = "master_key_name";
 538           if (params_in->mask & KADM5_CONFIG_MKEY_NAME) {
 539                   params.mkey_name = strdup(params_in->mkey_name);
 540                   if (params.mkey_name)
 541                           params.mask |= KADM5_CONFIG_MKEY_NAME;
 542           } else if (aprofile &&
 543                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 544                   params.mask |= KADM5_CONFIG_MKEY_NAME;
 545                   params.mkey_name = svalue;
 546           }
 547   
 548           /* Get the value for the master key type */
 549           hierarchy[2] = "master_key_type";
 550           if (params_in->mask & KADM5_CONFIG_ENCTYPE) {
 551                   params.mask |= KADM5_CONFIG_ENCTYPE;
 552                   params.enctype = params_in->enctype;
 553           } else if (aprofile &&
 554                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 555                   if (!krb5_string_to_enctype(svalue, &params.enctype)) {
 556                           params.mask |= KADM5_CONFIG_ENCTYPE;
 557                           krb5_xfree(svalue);
 558                   }
 559           } else {
 560                   params.mask |= KADM5_CONFIG_ENCTYPE;
 561                   params.enctype = DEFAULT_KDC_ENCTYPE;
 562           }
 563   
 564           /* Get the value for mkey_from_kbd */
 565           if (params_in->mask & KADM5_CONFIG_MKEY_FROM_KBD) {
 566                   params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
 567                   params.mkey_from_kbd = params_in->mkey_from_kbd;
 568           }
 569   
 570           /* Get the value for the stashfile */
 571           hierarchy[2] = "key_stash_file";
 572           if (params_in->mask & KADM5_CONFIG_STASH_FILE) {
 573                   params.stash_file = strdup(params_in->stash_file);
 574                   if (params.stash_file)
 575                           params.mask |= KADM5_CONFIG_STASH_FILE;
 576           } else if (aprofile &&
 577                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 578                   params.mask |= KADM5_CONFIG_STASH_FILE;
 579                   params.stash_file = svalue;
 580           }
 581   
 582           /*
 583            * Get the value for maximum ticket lifetime.
 584            * See SEAM documentation or the Bug ID 4184504
 585            * We have changed the logic so that the entries are
 586            * created in the database with the maximum duration
 587            * for life and renew life KRB5_INT32_MAX
 588            * However this wil get negotiated down when
 589            * as or tgs request is processed by KDC.
 590            */
 591           hierarchy[2] = "max_life";
 592           if (params_in->mask & KADM5_CONFIG_MAX_LIFE) {
 593                   params.mask |= KADM5_CONFIG_MAX_LIFE;
 594                   params.max_life = params_in->max_life;
 595           } else {
 596                   params.mask |= KADM5_CONFIG_MAX_LIFE;
 597                   params.max_life = KRB5_INT32_MAX;
 598           }
 599   
 600           /* Get the value for maximum renewable ticket lifetime. */
 601           hierarchy[2] = "max_renewable_life";
 602           if (params_in->mask & KADM5_CONFIG_MAX_RLIFE) {
 603                   params.mask |= KADM5_CONFIG_MAX_RLIFE;
 604                   params.max_rlife = params_in->max_rlife;
 605           } else {
 606                   params.mask |= KADM5_CONFIG_MAX_RLIFE;
 607                   params.max_rlife =  KRB5_INT32_MAX;
 608           }
 609   
 610           /* Get the value for the default principal expiration */
 611           hierarchy[2] = "default_principal_expiration";
 612           if (params_in->mask & KADM5_CONFIG_EXPIRATION) {
 613                   params.mask |= KADM5_CONFIG_EXPIRATION;
 614                   params.expiration = params_in->expiration;
 615           } else if (aprofile &&
 616                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 617                   if (!krb5_string_to_timestamp(svalue, &params.expiration)) {
 618                           params.mask |= KADM5_CONFIG_EXPIRATION;
 619                           krb5_xfree(svalue);
 620                   }
 621           } else {
 622                   params.mask |= KADM5_CONFIG_EXPIRATION;
 623                   params.expiration = 0;
 624           }
 625   
 626           /* Get the value for the default principal flags */
 627           hierarchy[2] = "default_principal_flags";
 628           if (params_in->mask & KADM5_CONFIG_FLAGS) {
 629                   params.mask |= KADM5_CONFIG_FLAGS;
 630                   params.flags = params_in->flags;
 631           } else if (aprofile &&
 632                   !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
 633                   char *sp, *ep, *tp;
 634   
 635                   sp = svalue;
 636                   params.flags = 0;
 637                   while (sp) {
 638                           if ((ep = strchr(sp, (int)', ')) ||
 639                               (ep = strchr(sp, (int)' ')) ||
 640                               (ep = strchr(sp, (int)'\t'))) {
 641                                   /* Fill in trailing whitespace of sp */
 642                                   tp = ep - 1;
 643                                   while (isspace(*tp) && (tp < sp)) {
 644                                           *tp = '\0';
 645                                           tp--;
 646                                   }
 647                                   *ep = '\0';
 648                                   ep++;
 649                                   /* Skip over trailing whitespace of ep */
 650                                   while (isspace(*ep) && (*ep)) ep++;
 651                           }
 652                           /* Convert this flag */
 653                           if (krb5_string_to_flags(sp,
 654                                                   "+",
 655                                                   "-",
 656                                                   &params.flags))
 657                                   break;
 658                           sp = ep;
 659                   }
 660                   if (!sp)
 661                           params.mask |= KADM5_CONFIG_FLAGS;
 662                   krb5_xfree(svalue);
 663           } else {
 664                   params.mask |= KADM5_CONFIG_FLAGS;
 665                   params.flags = KRB5_KDB_DEF_FLAGS;
 666           }
 667   
 668           /* Get the value for the supported enctype/salttype matrix */
 669           hierarchy[2] = "supported_enctypes";
 670           if (params_in->mask & KADM5_CONFIG_ENCTYPES) {
 671                   params.mask |= KADM5_CONFIG_ENCTYPES;
 672                   if (params_in->num_keysalts > 0) {
 673                       params.keysalts = malloc(params_in->num_keysalts *
 674                               sizeof (*params.keysalts));
 675                       if (params.keysalts == NULL) {
 676                           kret = ENOMEM;
 677                           goto cleanup;
 678                       }
 679                       (void) memcpy(params.keysalts, params_in->keysalts,
 680                               (params_in->num_keysalts *
 681                               sizeof (*params.keysalts)));
 682                       params.num_keysalts = params_in->num_keysalts;
 683                   }
 684           } else {
 685                   svalue = NULL;
 686                   if (aprofile)
 687                           krb5_aprof_get_string(aprofile, hierarchy,
 688                                               TRUE, &svalue);
 689                   if (svalue == NULL)
 690                           svalue = strdup(DEFAULT_ENCTYPE_LIST);
 691   
 692                   params.keysalts = NULL;
 693                   params.num_keysalts = 0;
 694                   krb5_string_to_keysalts(svalue,
 695                                           ", \t", /* Tuple separators        */
 696                                           ":.-",        /* Key/salt separators        */
 697                                           0,        /* No duplicates        */
 698                                           &params.keysalts,
 699                                           &params.num_keysalts);
 700                   if (params.num_keysalts)
 701                           params.mask |= KADM5_CONFIG_ENCTYPES;
 702   
 703                   if (svalue)
 704                           krb5_xfree(svalue);
 705           }
 706   
 707           hierarchy[2] = "kpasswd_server";
 708           if (params_in->mask & KADM5_CONFIG_KPASSWD_SERVER) {
 709                   params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
 710                   params.kpasswd_server = strdup(params_in->kpasswd_server);
 711           } else {
 712                   svalue = NULL;
 713   
 714                   if (aprofile)
 715                           krb5_aprof_get_string(aprofile, hierarchy,
 716                                               TRUE, &svalue);
 717                   if (svalue == NULL) {
 718   #ifdef KRB5_DNS_LOOKUP
 719                           if (strcmp(envname, "KRB5_CONFIG") == 0) {
 720                                   /*
 721                                    * Solaris Kerberos: only do DNS lookup for
 722                                    * kpasswd_server if this is a krb5.conf type of
 723                                    * config file.  Note, the filename may not be
 724                                    * /etc/krb5/krb5.conf so we assume that the
 725                                    * KRB5_CONFIG envname string will consistently
 726                                    * indicate the type of config file.
 727                                    */
 728                                   dnsret = krb5_get_servername(context,
 729                                       &dns_realm, "_kpasswd", "_udp",
 730                                       dns_host, &dns_portno);
 731   
 732                                   if (dnsret == 0) {
 733                                           params.kpasswd_server =
 734                                               strdup(dns_host);
 735                                           if (params.kpasswd_server) {
 736                                                   params.mask |=
 737                                                       KADM5_CONFIG_KPASSWD_SERVER;
 738                                           }
 739                                           params.kpasswd_port = dns_portno;
 740                                           params.mask |=
 741                                               KADM5_CONFIG_KPASSWD_PORT;
 742                                   }
 743                           }
 744   #endif /* KRB5_DNS_LOOKUP */
 745   
 746                           /*
 747                            * If a unique 'kpasswd_server' is not specified,
 748                            * use the normal 'admin_server'.
 749                            */
 750                           if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) &&
 751                                       dnsret) {
 752                                   params.kpasswd_server =
 753                                           strdup(params.admin_server);
 754                                   params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
 755                           }
 756                   } else {
 757                           char *p;
 758                           params.kpasswd_server = svalue;
 759                           params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
 760   
 761                           if ((p = strchr(params.kpasswd_server, ':'))) {
 762                                   params.kpasswd_port = atoi(p+1);
 763                                   params.mask |= KADM5_CONFIG_KPASSWD_PORT;
 764                                   *p = '\0';
 765                           }
 766                   }
 767           }
 768   
 769           hierarchy[2] = "kpasswd_protocol";
 770   
 771           /* default to current RPCSEC_GSS protocol */
 772           params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC;
 773           params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
 774   
 775           if (params_in->mask & KADM5_CONFIG_KPASSWD_PROTOCOL) {
 776                   params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
 777                   params.kpasswd_protocol = params_in->kpasswd_protocol;
 778           } else {
 779                   svalue = NULL;
 780   
 781                   if (aprofile)
 782                           krb5_aprof_get_string(aprofile, hierarchy,
 783                                               TRUE, &svalue);
 784                   if (svalue != NULL) {
 785                           if (strcasecmp(svalue, "RPCSEC_GSS") == 0) {
 786                                   params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC;
 787                                   params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
 788                           } else if (strcasecmp(svalue, "SET_CHANGE") == 0) {
 789                                   params.kpasswd_protocol =
 790                                           KRB5_CHGPWD_CHANGEPW_V2;
 791                                   params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
 792                           }
 793                   }
 794                   if (svalue)
 795                           krb5_xfree(svalue);
 796           }
 797   
 798           /*
 799            * If the kpasswd_port is not yet defined, define it now.
 800            */
 801           if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) {
 802                   if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT)
 803                           params.kpasswd_port = params_in->kpasswd_port;
 804                   /*
 805                    * If kpasswd_port is not explicitly defined,
 806                    * determine the port to use based on the protocol.
 807                    * The alternative protocol uses a different port
 808                    * than the standard admind port.
 809                    */
 810                   else if (params.kpasswd_protocol == KRB5_CHGPWD_RPCSEC) {
 811                           params.kpasswd_port = DEFAULT_KADM5_PORT;
 812                   } else {
 813                           /*
 814                            * When using the Horowitz/IETF protocol for
 815                            * password changing, the default port is 464
 816                            * (officially recognized by IANA).
 817                            */
 818                           params.kpasswd_port = DEFAULT_KPASSWD_PORT;
 819                   }
 820                   params.mask |= KADM5_CONFIG_KPASSWD_PORT;
 821           }
 822   
 823 +         hierarchy[2] = "sunw_dbprop_enable";
 824 + 
 825 +         params.iprop_enabled = FALSE;
 826 +         params.mask |= KADM5_CONFIG_IPROP_ENABLED;
 827 + 
 828 +         if (params_in->mask & KADM5_CONFIG_IPROP_ENABLED) {
 829 +                 params.mask |= KADM5_CONFIG_IPROP_ENABLED;
 830 +                 params.iprop_enabled = params_in->iprop_enabled;
 831 +         } else {
 832 +                 if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy,
 833 +                     TRUE, &svalue)) {
 834 +                         if (strncasecmp(svalue, "Y", 1) == 0)
 835 +                                 params.iprop_enabled = TRUE;
 836 +                         if (strncasecmp(svalue, "true", 4) == 0)
 837 +                                 params.iprop_enabled = TRUE;
 838 +                         params.mask |= KADM5_CONFIG_IPROP_ENABLED;
 839 +                         krb5_xfree(svalue);
 840 +                 }
 841 +         }
 842 + 
 843 +         hierarchy[2] = "sunw_dbprop_master_ulogsize";
 844 + 
 845 +         params.iprop_ulogsize = DEF_ULOGENTRIES;
 846 +         params.mask |= KADM5_CONFIG_ULOG_SIZE;
 847 + 
 848 +         if (params_in->mask & KADM5_CONFIG_ULOG_SIZE) {
 849 +                 params.mask |= KADM5_CONFIG_ULOG_SIZE;
 850 +                 params.iprop_ulogsize = params_in->iprop_ulogsize;
 851 +         } else {
 852 +                 if (aprofile && !krb5_aprof_get_int32(aprofile, hierarchy,
 853 +                     TRUE, &ivalue)) {
 854 +                         if (ivalue > MAX_ULOGENTRIES)
 855 +                                 params.iprop_ulogsize = MAX_ULOGENTRIES;
 856 +                         else if (ivalue <= 0)
 857 +                                 params.iprop_ulogsize = DEF_ULOGENTRIES;
 858 +                         else
 859 +                                 params.iprop_ulogsize = ivalue;
 860 +                         params.mask |= KADM5_CONFIG_ULOG_SIZE;
 861 +                 }
 862 +         }
 863 + 
 864 +         hierarchy[2] = "sunw_dbprop_slave_poll";
 865 + 
 866 +         params.iprop_polltime = "2m";
 867 +         params.mask |= KADM5_CONFIG_POLL_TIME;
 868 + 
 869 +         if (params_in->mask & KADM5_CONFIG_POLL_TIME) {
 870 +                 params.iprop_polltime = strdup(params_in->iprop_polltime);
 871 +                 if (params.iprop_polltime)
 872 +                         params.mask |= KADM5_CONFIG_POLL_TIME;
 873 +         } else {
 874 +                 if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy,
 875 +                     TRUE, &svalue)) {
 876 +                         params.iprop_polltime = strdup(svalue);
 877 +                         params.mask |= KADM5_CONFIG_POLL_TIME;
 878 +                         krb5_xfree(svalue);
 879 +                 }
 880 +         }
 881 + 
 882           *params_out = params;
 883   
 884   cleanup:
 885           if (aprofile)
 886                   krb5_aprof_finish(aprofile);
 887           if (kret) {
 888                   (void) kadm5_free_config_params(context, &params);
 889                   params_out->mask = 0;
 890           }
 891   #ifdef KRB5_DNS_LOOKUP
 892           if (dns_realm.data)
 893                   free(dns_realm.data);
 894   #endif /* KRB5_DNS_LOOKUP */
 895   
 896           return (kret);
 897   }

 ----Unchanged portion omitted----