2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
8 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
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.
16 * For further information, read the top-level Openvision
17 * copyright which is contained in the top-level MIT Kerberos
20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
28 * Copyright 1995,2001 by the Massachusetts Institute of Technology.
29 * All Rights Reserved.
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.
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.
53 * alt_prof.c - Implement alternate profile file handling.
56 #include <kadm5/admin.h>
57 #include "adm_proto.h"
61 #include <kdb/kdb_log.h>
63 krb5_error_code
kadm5_free_config_params();
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 " \
74 static krb5_key_salt_tuple
*copy_key_salt_tuple(ksalt
, len
)
75 krb5_key_salt_tuple
*ksalt
;
78 krb5_key_salt_tuple
*knew
;
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
));
89 * krb5_aprof_init() - Initialize alternate profile context.
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.
97 * error codes from profile_init()
100 krb5_aprof_init(fname
, envname
, acontextp
)
103 krb5_pointer
*acontextp
;
105 krb5_error_code kret
;
107 const char *kdc_config
;
108 size_t krb5_config_len
, kdc_config_len
;
113 kret
= krb5_get_default_config_files (&filenames
);
117 for (i
= 0; filenames
[i
] != NULL
; i
++)
118 krb5_config_len
+= strlen(filenames
[i
]) + 1;
122 || (kdc_config
= getenv(envname
)) == NULL
)
124 if (kdc_config
== NULL
)
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
);
134 strcpy(profile_path
, kdc_config
);
138 for (i
= 0; filenames
[i
] != NULL
; i
++) {
139 if (kdc_config_len
|| i
)
140 strcat(profile_path
, ":");
141 strcat(profile_path
, filenames
[i
]);
143 krb5_free_config_files(filenames
);
144 profile
= (profile_t
) NULL
;
145 kret
= profile_init_path(profile_path
, &profile
);
149 *acontextp
= profile
;
154 * krb5_aprof_getvals() - Get values from alternate profile.
157 * acontext - opaque context for alternate profile.
158 * hierarchy - hierarchy of value to retrieve.
159 * retdata - Returned data values.
162 * error codes from profile_get_values()
165 krb5_aprof_getvals(acontext
, hierarchy
, retdata
)
166 krb5_pointer acontext
;
167 const char **hierarchy
;
170 return(profile_get_values((profile_t
) acontext
,
176 * krb5_aprof_get_boolean()
179 * acontext - opaque context for alternate profile
180 * hierarchy - hierarchy of value to retrieve
181 * retdata - Returned data value
186 static krb5_error_code
187 string_to_boolean (const char *string
, krb5_boolean
*out
)
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" };
193 for (i
= 0; i
< sizeof(yes
)/sizeof(yes
[0]); i
++)
194 if (!strcasecmp(string
, yes
[i
])) {
198 for (i
= 0; i
< sizeof(no
)/sizeof(no
[0]); i
++)
199 if (!strcasecmp(string
, no
[i
])) {
203 return PROF_BAD_BOOLEAN
;
207 krb5_aprof_get_boolean(krb5_pointer acontext
, const char **hierarchy
,
208 int uselast
, krb5_boolean
*retdata
)
210 krb5_error_code kret
;
216 kret
= krb5_aprof_getvals (acontext
, hierarchy
, &values
);
226 kret
= string_to_boolean (valp
, &val
);
234 * krb5_aprof_get_deltat() - Get a delta time value from the alternate
238 * acontext - opaque context for alternate profile.
239 * hierarchy - hierarchy of value to retrieve.
240 * uselast - if true, use last value, otherwise use
242 * deltatp - returned delta time value.
245 * error codes from profile_get_values()
246 * error codes from krb5_string_to_deltat()
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
;
255 krb5_error_code kret
;
260 if (!(kret
= krb5_aprof_getvals(acontext
, hierarchy
, &values
))) {
263 for (idx
=0; values
[idx
]; idx
++);
267 kret
= krb5_string_to_deltat(valp
, deltatp
);
269 /* Free the string storage */
270 for (idx
=0; values
[idx
]; idx
++)
271 krb5_xfree(values
[idx
]);
278 * krb5_aprof_get_string() - Get a string value from the alternate
282 * acontext - opaque context for alternate profile.
283 * hierarchy - hierarchy of value to retrieve.
284 * uselast - if true, use last value, otherwise use
286 * stringp - returned string value.
289 * error codes from profile_get_values()
292 krb5_aprof_get_string(acontext
, hierarchy
, uselast
, stringp
)
293 krb5_pointer acontext
;
294 const char **hierarchy
;
295 krb5_boolean uselast
;
298 krb5_error_code kret
;
302 if (!(kret
= krb5_aprof_getvals(acontext
, hierarchy
, &values
))) {
305 for (idx
=0; values
[idx
]; idx
++);
309 *stringp
= values
[idx
];
311 /* Free the string storage */
312 for (i
=0; values
[i
]; i
++)
314 krb5_xfree(values
[i
]);
321 * krb5_aprof_get_int32() - Get a 32-bit integer value from the alternate
325 * acontext - opaque context for alternate profile.
326 * hierarchy - hierarchy of value to retrieve.
327 * uselast - if true, use last value, otherwise use
329 * intp - returned 32-bit integer value.
332 * error codes from profile_get_values()
333 * EINVAL - value is not an integer
336 krb5_aprof_get_int32(acontext
, hierarchy
, uselast
, intp
)
337 krb5_pointer acontext
;
338 const char **hierarchy
;
339 krb5_boolean uselast
;
342 krb5_error_code kret
;
346 if (!(kret
= krb5_aprof_getvals(acontext
, hierarchy
, &values
))) {
349 for (idx
=0; values
[idx
]; idx
++);
353 if (sscanf(values
[idx
], "%d", intp
) != 1)
356 /* Free the string storage */
357 for (idx
=0; values
[idx
]; idx
++)
358 krb5_xfree(values
[idx
]);
365 * krb5_aprof_finish() - Finish alternate profile context.
368 * acontext - opaque context for alternate profile.
371 * 0 on success, something else on failure.
374 krb5_aprof_finish(acontext
)
375 krb5_pointer acontext
;
377 profile_release(acontext
);
382 * Function: kadm5_get_config_params
384 * Purpose: Merge configuration parameters provided by the caller with
385 * values specified in configuration files and with default values.
389 * context (r) krb5_context to use
390 * profile (r) profile file to use
391 * envname (r) envname that contains a profile name to
393 * params_in (r) params structure containing user-supplied
395 * params_out (w) params structure to be filled in
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.
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.
409 krb5_error_code
kadm5_get_config_params(context
, use_kdc_config
,
410 params_in
, params_out
)
411 krb5_context context
;
413 kadm5_config_params
*params_in
, *params_out
;
418 krb5_pointer aprofile
= 0;
419 const char *hierarchy
[4];
422 kadm5_config_params params
, empty_params
;
424 krb5_error_code kret
= 0;
425 krb5_error_code dnsret
= 1;
427 #ifdef KRB5_DNS_LOOKUP
428 char dns_host
[MAX_DNS_NAMELEN
];
429 unsigned short dns_portno
;
431 memset((char *)&dns_realm
, 0, sizeof (dns_realm
));
432 #endif /* KRB5_DNS_LOOKUP */
434 memset((char *) ¶ms
, 0, sizeof(params
));
435 memset((char *) &empty_params
, 0, sizeof(empty_params
));
437 if (params_in
== NULL
) params_in
= &empty_params
;
439 if (params_in
->mask
& KADM5_CONFIG_REALM
) {
440 lrealm
= params
.realm
= strdup(params_in
->realm
);
442 params
.mask
|= KADM5_CONFIG_REALM
;
444 kret
= krb5_get_default_realm(context
, &lrealm
);
447 params
.realm
= lrealm
;
448 params
.mask
|= KADM5_CONFIG_REALM
;
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.
456 if (use_kdc_config
) {
457 filename
= DEFAULT_KDC_PROFILE
;
458 envname
= KDC_PROFILE_ENV
;
460 filename
= DEFAULT_PROFILE_PATH
;
461 envname
= "KRB5_CONFIG";
463 if (context
->profile_secure
== TRUE
) envname
= 0;
465 kret
= krb5_aprof_init(filename
, envname
, &aprofile
);
469 /* Initialize realm parameters */
470 hierarchy
[0] = "realms";
471 hierarchy
[1] = lrealm
;
472 hierarchy
[3] = (char *) NULL
;
474 #ifdef KRB5_DNS_LOOKUP
476 * Initialize realm info for (possible) DNS lookups.
478 dns_realm
.data
= strdup(lrealm
);
479 dns_realm
.length
= strlen(lrealm
);
481 #endif /* KRB5_DNS_LOOKUP */
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
;
494 #ifdef KRB5_DNS_LOOKUP
495 else if (strcmp(envname
, "KRB5_CONFIG") == 0) {
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
503 dnsret
= krb5_get_servername(context
, &dns_realm
,
504 "_kerberos-adm", "_udp",
505 dns_host
, &dns_portno
);
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
;
514 #endif /* KRB5_DNS_LOOKUP */
516 if ((params
.mask
& KADM5_CONFIG_ADMIN_SERVER
) && dnsret
) {
518 p
= strchr(params
.admin_server
, ':');
520 params
.kadmind_port
= atoi(p
+1);
521 params
.mask
|= KADM5_CONFIG_KADMIND_PORT
;
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
);
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
;
537 params
.dbname
= strdup(DEFAULT_KDB_FILE
);
539 params
.mask
|= KADM5_CONFIG_DBNAME
;
543 * admin database name and lockfile are now always derived from dbname
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
;
553 if (params
.mask
& KADM5_CONFIG_ADBNAME
) {
554 params
.admin_lockfile
= (char *) malloc(strlen(params
.admin_dbname
)
556 if (params
.admin_lockfile
) {
557 sprintf(params
.admin_lockfile
, "%s.lock", params
.admin_dbname
);
558 params
.mask
|= KADM5_CONFIG_ADB_LOCKFILE
;
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
;
577 params
.admin_keytab
= strdup(DEFAULT_KADM5_KEYTAB
);
578 if (params
.admin_keytab
)
579 params
.mask
|= KADM5_CONFIG_ADMIN_KEYTAB
;
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
);
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
;
593 params
.acl_file
= strdup(DEFAULT_KADM5_ACL_FILE
);
595 params
.mask
|= KADM5_CONFIG_ACL_FILE
;
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
;
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
,
619 params
.kadmind_port
= ivalue
;
620 params
.mask
|= KADM5_CONFIG_KADMIND_PORT
;
622 params
.kadmind_port
= DEFAULT_KADM5_PORT
;
623 params
.mask
|= KADM5_CONFIG_KADMIND_PORT
;
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
,
636 params
.kpasswd_port
= ivalue
;
637 params
.mask
|= KADM5_CONFIG_KPASSWD_PORT
;
639 params
.kpasswd_port
= DEFAULT_KPASSWD_PORT
;
640 params
.mask
|= KADM5_CONFIG_KPASSWD_PORT
;
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
;
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
;
668 params
.mask
|= KADM5_CONFIG_ENCTYPE
;
669 params
.enctype
= DEFAULT_KDC_ENCTYPE
;
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
;
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
;
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.
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
;
705 params
.max_life
= KRB5_INT32_MAX
;
706 params
.mask
|= KADM5_CONFIG_MAX_LIFE
;
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
;
715 params
.max_rlife
= KRB5_INT32_MAX
;
716 params
.mask
|= KADM5_CONFIG_MAX_RLIFE
;
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
;
731 params
.mask
|= KADM5_CONFIG_EXPIRATION
;
732 params
.expiration
= 0;
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
)) {
747 if ((ep
= strchr(sp
, (int) ',')) ||
748 (ep
= strchr(sp
, (int) ' ')) ||
749 (ep
= strchr(sp
, (int) '\t'))) {
750 /* Fill in trailing whitespace of sp */
752 while (isspace((int) *tp
) && (tp
> sp
)) {
758 /* Skip over trailing whitespace of ep */
759 while (isspace((int) *ep
) && (*ep
)) ep
++;
761 /* Convert this flag */
762 if (krb5_string_to_flags(sp
,
770 params
.mask
|= KADM5_CONFIG_FLAGS
;
773 params
.mask
|= KADM5_CONFIG_FLAGS
;
774 params
.flags
= KRB5_KDB_DEF_FLAGS
;
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
) {
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
;
796 krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
);
798 svalue
= strdup(DEFAULT_ENCTYPE_LIST
);
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 */
807 ¶ms
.num_keysalts
);
808 if (params
.num_keysalts
)
809 params
.mask
|= KADM5_CONFIG_ENCTYPES
;
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
);
823 krb5_aprof_get_string(aprofile
, hierarchy
,
825 if (svalue
== NULL
) {
826 #ifdef KRB5_DNS_LOOKUP
827 if (strcmp(envname
, "KRB5_CONFIG") == 0) {
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.
836 dnsret
= krb5_get_servername(context
,
837 &dns_realm
, "_kpasswd", "_udp",
838 dns_host
, &dns_portno
);
841 params
.kpasswd_server
=
843 if (params
.kpasswd_server
) {
845 KADM5_CONFIG_KPASSWD_SERVER
;
847 params
.kpasswd_port
= dns_portno
;
849 KADM5_CONFIG_KPASSWD_PORT
;
852 #endif /* KRB5_DNS_LOOKUP */
855 * If a unique 'kpasswd_server' is not specified,
856 * use the normal 'admin_server'.
858 if ((params
.mask
& KADM5_CONFIG_ADMIN_SERVER
) &&
860 params
.kpasswd_server
=
861 strdup(params
.admin_server
);
862 params
.mask
|= KADM5_CONFIG_KPASSWD_SERVER
;
866 params
.kpasswd_server
= svalue
;
867 params
.mask
|= KADM5_CONFIG_KPASSWD_SERVER
;
869 if ((p
= strchr(params
.kpasswd_server
, ':'))) {
870 params
.kpasswd_port
= atoi(p
+1);
871 params
.mask
|= KADM5_CONFIG_KPASSWD_PORT
;
877 hierarchy
[2] = "kpasswd_protocol";
879 /* default to current RPCSEC_GSS protocol */
880 params
.kpasswd_protocol
= KRB5_CHGPWD_RPCSEC
;
881 params
.mask
|= KADM5_CONFIG_KPASSWD_PROTOCOL
;
883 if (params_in
->mask
& KADM5_CONFIG_KPASSWD_PROTOCOL
) {
884 params
.mask
|= KADM5_CONFIG_KPASSWD_PROTOCOL
;
885 params
.kpasswd_protocol
= params_in
->kpasswd_protocol
;
890 krb5_aprof_get_string(aprofile
, hierarchy
,
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
;
907 * If the kpasswd_port is not yet defined, define it now.
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
;
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.
918 else if (params
.kpasswd_protocol
== KRB5_CHGPWD_RPCSEC
) {
919 params
.kpasswd_port
= DEFAULT_KADM5_PORT
;
922 * When using the Horowitz/IETF protocol for
923 * password changing, the default port is 464
924 * (officially recognized by IANA).
926 params
.kpasswd_port
= DEFAULT_KPASSWD_PORT
;
928 params
.mask
|= KADM5_CONFIG_KPASSWD_PORT
;
931 hierarchy
[2] = "sunw_dbprop_enable";
933 params
.iprop_enabled
= FALSE
;
934 params
.mask
|= KADM5_CONFIG_IPROP_ENABLED
;
936 if (params_in
->mask
& KADM5_CONFIG_IPROP_ENABLED
) {
937 params
.mask
|= KADM5_CONFIG_IPROP_ENABLED
;
938 params
.iprop_enabled
= params_in
->iprop_enabled
;
940 if (aprofile
&& !krb5_aprof_get_string(aprofile
, hierarchy
,
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
;
951 hierarchy
[2] = "sunw_dbprop_master_ulogsize";
953 params
.iprop_ulogsize
= DEF_ULOGENTRIES
;
954 params
.mask
|= KADM5_CONFIG_ULOG_SIZE
;
956 if (params_in
->mask
& KADM5_CONFIG_ULOG_SIZE
) {
957 params
.mask
|= KADM5_CONFIG_ULOG_SIZE
;
958 params
.iprop_ulogsize
= params_in
->iprop_ulogsize
;
960 if (aprofile
&& !krb5_aprof_get_int32(aprofile
, hierarchy
,
962 if (ivalue
> MAX_ULOGENTRIES
)
963 params
.iprop_ulogsize
= MAX_ULOGENTRIES
;
964 else if (ivalue
<= 0)
965 params
.iprop_ulogsize
= DEF_ULOGENTRIES
;
967 params
.iprop_ulogsize
= ivalue
;
968 params
.mask
|= KADM5_CONFIG_ULOG_SIZE
;
972 hierarchy
[2] = "sunw_dbprop_slave_poll";
974 params
.iprop_polltime
= strdup("2m");
975 if (params
.iprop_polltime
)
976 params
.mask
|= KADM5_CONFIG_POLL_TIME
;
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
;
985 if (aprofile
&& !krb5_aprof_get_string(aprofile
, hierarchy
,
987 if (params
.iprop_polltime
)
988 free(params
.iprop_polltime
);
989 params
.iprop_polltime
= strdup(svalue
);
990 params
.mask
|= KADM5_CONFIG_POLL_TIME
;
995 *params_out
= params
;
999 krb5_aprof_finish(aprofile
);
1001 kadm5_free_config_params(context
, ¶ms
);
1002 params_out
->mask
= 0;
1004 #ifdef KRB5_DNS_LOOKUP
1006 free(dns_realm
.data
);
1007 #endif /* KRB5_DNS_LOOKUP */
1012 * kadm5_free_config_params() - Free data allocated by above.
1016 kadm5_free_config_params(context
, params
)
1017 krb5_context context
;
1018 kadm5_config_params
*params
;
1021 if (params
->dbname
) {
1022 krb5_xfree(params
->dbname
);
1023 params
->dbname
= NULL
;
1025 if (params
->mkey_name
) {
1026 krb5_xfree(params
->mkey_name
);
1027 params
->mkey_name
= NULL
;
1029 if (params
->stash_file
) {
1030 krb5_xfree(params
->stash_file
);
1031 params
->stash_file
= NULL
;
1033 if (params
->keysalts
) {
1034 krb5_xfree(params
->keysalts
);
1035 params
->keysalts
= NULL
;
1036 params
->num_keysalts
= 0;
1038 if (params
->admin_keytab
) {
1039 free(params
->admin_keytab
);
1040 params
->admin_keytab
= NULL
;
1042 if (params
->dict_file
) {
1043 free(params
->dict_file
);
1044 params
->dict_file
= NULL
;
1046 if (params
->acl_file
) {
1047 free(params
->acl_file
);
1048 params
->acl_file
= NULL
;
1050 if (params
->realm
) {
1051 free(params
->realm
);
1052 params
->realm
= NULL
;
1054 if (params
->admin_dbname
) {
1055 free(params
->admin_dbname
);
1056 params
->admin_dbname
= NULL
;
1058 if (params
->admin_lockfile
) {
1059 free(params
->admin_lockfile
);
1060 params
->admin_lockfile
= NULL
;
1062 if (params
->admin_server
) {
1063 free(params
->admin_server
);
1064 params
->admin_server
= NULL
;
1066 if (params
->kpasswd_server
) {
1067 free(params
->kpasswd_server
);
1068 params
->kpasswd_server
= NULL
;
1070 if (params
->iprop_polltime
) {
1071 free(params
->iprop_polltime
);
1072 params
->iprop_polltime
= NULL
;
1079 kadm5_get_admin_service_name(krb5_context ctx
,
1084 krb5_error_code ret
;
1085 kadm5_config_params params_in
, params_out
;
1088 memset(¶ms_in
, 0, sizeof(params_in
));
1089 memset(¶ms_out
, 0, sizeof(params_out
));
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
);
1097 if (!(params_out
.mask
& KADM5_CONFIG_ADMIN_SERVER
)) {
1098 ret
= KADM5_MISSING_KRB5_CONF_PARAMS
;
1102 hp
= gethostbyname(params_out
.admin_server
);
1107 if (strlen(hp
->h_name
) + sizeof("kadmin/") > maxlen
) {
1111 sprintf(admin_name
, "kadmin/%s", hp
->h_name
);
1114 kadm5_free_config_params(ctx
, ¶ms_out
);
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)
1122 ***********************************************************************/
1125 * krb5_read_realm_params() - Read per-realm parameters from KDC
1126 * alternate profile.
1129 krb5_read_realm_params(kcontext
, realm
, rparamp
)
1130 krb5_context kcontext
;
1132 krb5_realm_params
**rparamp
;
1137 krb5_pointer aprofile
= 0;
1138 krb5_realm_params
*rparams
;
1139 const char *hierarchy
[4];
1142 krb5_boolean bvalue
;
1143 krb5_deltat dtvalue
;
1145 char *kdcprofile
= 0;
1148 krb5_error_code kret
;
1150 filename
= (kdcprofile
) ? kdcprofile
: DEFAULT_KDC_PROFILE
;
1151 envname
= (kdcenv
) ? kdcenv
: KDC_PROFILE_ENV
;
1153 if (kcontext
->profile_secure
== TRUE
) envname
= 0;
1155 rparams
= (krb5_realm_params
*) NULL
;
1157 lrealm
= strdup(realm
);
1159 kret
= krb5_get_default_realm(kcontext
, &lrealm
);
1164 kret
= krb5_aprof_init(filename
, envname
, &aprofile
);
1168 rparams
= (krb5_realm_params
*) malloc(sizeof(krb5_realm_params
));
1174 /* Initialize realm parameters */
1175 memset((char *) rparams
, 0, sizeof(krb5_realm_params
));
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
;
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
;
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
;
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;
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
;
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;
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
;
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;
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;
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;
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;
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
)) {
1258 rparams
->realm_flags
= 0;
1260 if ((ep
= strchr(sp
, (int) ',')) ||
1261 (ep
= strchr(sp
, (int) ' ')) ||
1262 (ep
= strchr(sp
, (int) '\t'))) {
1263 /* Fill in trailing whitespace of sp */
1265 while (isspace((int) *tp
) && (tp
< sp
)) {
1271 /* Skip over trailing whitespace of ep */
1272 while (isspace((int) *ep
) && (*ep
)) ep
++;
1274 /* Convert this flag */
1275 if (krb5_string_to_flags(sp
,
1278 &rparams
->realm_flags
))
1283 rparams
->realm_flags_valid
= 1;
1287 /* Get the value for the supported enctype/salttype matrix */
1290 * Solaris kerberos: updated this code to support default values for
1291 * the supported_enctypes.
1293 hierarchy
[2] = "supported_enctypes";
1295 krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
);
1298 * Set the default value if supported_enctypes was not explicitly
1299 * set in the kdc.conf.
1301 if (svalue
== NULL
) {
1302 svalue
= strdup(DEFAULT_ENCTYPE_LIST
);
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
);
1316 krb5_aprof_finish(aprofile
);
1321 krb5_free_realm_params(kcontext
, rparams
);
1329 * krb5_free_realm_params() - Free data allocated by above.
1332 krb5_free_realm_params(kcontext
, rparams
)
1333 krb5_context kcontext
;
1334 krb5_realm_params
*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
);