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 free(params
.iprop_polltime
);
980 params
.iprop_polltime
= strdup(params_in
->iprop_polltime
);
981 if (params
.iprop_polltime
)
982 params
.mask
|= KADM5_CONFIG_POLL_TIME
;
984 if (aprofile
&& !krb5_aprof_get_string(aprofile
, hierarchy
,
986 free(params
.iprop_polltime
);
987 params
.iprop_polltime
= strdup(svalue
);
988 params
.mask
|= KADM5_CONFIG_POLL_TIME
;
993 *params_out
= params
;
997 krb5_aprof_finish(aprofile
);
999 kadm5_free_config_params(context
, ¶ms
);
1000 params_out
->mask
= 0;
1002 #ifdef KRB5_DNS_LOOKUP
1003 free(dns_realm
.data
);
1004 #endif /* KRB5_DNS_LOOKUP */
1009 * kadm5_free_config_params() - Free data allocated by above.
1013 kadm5_free_config_params(context
, params
)
1014 krb5_context context
;
1015 kadm5_config_params
*params
;
1018 if (params
->dbname
) {
1019 krb5_xfree(params
->dbname
);
1020 params
->dbname
= NULL
;
1022 if (params
->mkey_name
) {
1023 krb5_xfree(params
->mkey_name
);
1024 params
->mkey_name
= NULL
;
1026 if (params
->stash_file
) {
1027 krb5_xfree(params
->stash_file
);
1028 params
->stash_file
= NULL
;
1030 if (params
->keysalts
) {
1031 krb5_xfree(params
->keysalts
);
1032 params
->keysalts
= NULL
;
1033 params
->num_keysalts
= 0;
1035 if (params
->admin_keytab
) {
1036 free(params
->admin_keytab
);
1037 params
->admin_keytab
= NULL
;
1039 if (params
->dict_file
) {
1040 free(params
->dict_file
);
1041 params
->dict_file
= NULL
;
1043 if (params
->acl_file
) {
1044 free(params
->acl_file
);
1045 params
->acl_file
= NULL
;
1047 if (params
->realm
) {
1048 free(params
->realm
);
1049 params
->realm
= NULL
;
1051 if (params
->admin_dbname
) {
1052 free(params
->admin_dbname
);
1053 params
->admin_dbname
= NULL
;
1055 if (params
->admin_lockfile
) {
1056 free(params
->admin_lockfile
);
1057 params
->admin_lockfile
= NULL
;
1059 if (params
->admin_server
) {
1060 free(params
->admin_server
);
1061 params
->admin_server
= NULL
;
1063 if (params
->kpasswd_server
) {
1064 free(params
->kpasswd_server
);
1065 params
->kpasswd_server
= NULL
;
1067 if (params
->iprop_polltime
) {
1068 free(params
->iprop_polltime
);
1069 params
->iprop_polltime
= NULL
;
1076 kadm5_get_admin_service_name(krb5_context ctx
,
1081 krb5_error_code ret
;
1082 kadm5_config_params params_in
, params_out
;
1085 memset(¶ms_in
, 0, sizeof(params_in
));
1086 memset(¶ms_out
, 0, sizeof(params_out
));
1088 params_in
.mask
|= KADM5_CONFIG_REALM
;
1089 params_in
.realm
= realm_in
;
1090 ret
= kadm5_get_config_params(ctx
, 0, ¶ms_in
, ¶ms_out
);
1094 if (!(params_out
.mask
& KADM5_CONFIG_ADMIN_SERVER
)) {
1095 ret
= KADM5_MISSING_KRB5_CONF_PARAMS
;
1099 hp
= gethostbyname(params_out
.admin_server
);
1104 if (strlen(hp
->h_name
) + sizeof("kadmin/") > maxlen
) {
1108 sprintf(admin_name
, "kadmin/%s", hp
->h_name
);
1111 kadm5_free_config_params(ctx
, ¶ms_out
);
1115 /***********************************************************************
1116 * This is the old krb5_realm_read_params, which I mutated into
1117 * kadm5_get_config_params but which old code (kdb5_* and krb5kdc)
1119 ***********************************************************************/
1122 * krb5_read_realm_params() - Read per-realm parameters from KDC
1123 * alternate profile.
1126 krb5_read_realm_params(kcontext
, realm
, rparamp
)
1127 krb5_context kcontext
;
1129 krb5_realm_params
**rparamp
;
1134 krb5_pointer aprofile
= 0;
1135 krb5_realm_params
*rparams
;
1136 const char *hierarchy
[4];
1139 krb5_boolean bvalue
;
1140 krb5_deltat dtvalue
;
1142 char *kdcprofile
= 0;
1145 krb5_error_code kret
;
1147 filename
= (kdcprofile
) ? kdcprofile
: DEFAULT_KDC_PROFILE
;
1148 envname
= (kdcenv
) ? kdcenv
: KDC_PROFILE_ENV
;
1150 if (kcontext
->profile_secure
== TRUE
) envname
= 0;
1152 rparams
= (krb5_realm_params
*) NULL
;
1154 lrealm
= strdup(realm
);
1156 kret
= krb5_get_default_realm(kcontext
, &lrealm
);
1161 kret
= krb5_aprof_init(filename
, envname
, &aprofile
);
1165 rparams
= (krb5_realm_params
*) malloc(sizeof(krb5_realm_params
));
1171 /* Initialize realm parameters */
1172 memset((char *) rparams
, 0, sizeof(krb5_realm_params
));
1174 /* Get the value for the database */
1175 hierarchy
[0] = "realms";
1176 hierarchy
[1] = lrealm
;
1177 hierarchy
[2] = "database_name";
1178 hierarchy
[3] = (char *) NULL
;
1179 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
))
1180 rparams
->realm_dbname
= svalue
;
1182 /* Get the value for the KDC port list */
1183 hierarchy
[2] = "kdc_ports";
1184 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
))
1185 rparams
->realm_kdc_ports
= svalue
;
1186 hierarchy
[2] = "kdc_tcp_ports";
1187 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
))
1188 rparams
->realm_kdc_tcp_ports
= svalue
;
1190 /* Get the name of the acl file */
1191 hierarchy
[2] = "acl_file";
1192 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
))
1193 rparams
->realm_acl_file
= svalue
;
1195 /* Get the value for the kadmind port */
1196 hierarchy
[2] = "kadmind_port";
1197 if (!krb5_aprof_get_int32(aprofile
, hierarchy
, TRUE
, &ivalue
)) {
1198 rparams
->realm_kadmind_port
= ivalue
;
1199 rparams
->realm_kadmind_port_valid
= 1;
1202 /* Get the value for the master key name */
1203 hierarchy
[2] = "master_key_name";
1204 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
))
1205 rparams
->realm_mkey_name
= svalue
;
1207 /* Get the value for the master key type */
1208 hierarchy
[2] = "master_key_type";
1209 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
)) {
1210 if (!krb5_string_to_enctype(svalue
, &rparams
->realm_enctype
))
1211 rparams
->realm_enctype_valid
= 1;
1215 /* Get the value for the stashfile */
1216 hierarchy
[2] = "key_stash_file";
1217 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
))
1218 rparams
->realm_stash_file
= svalue
;
1220 /* Get the value for maximum ticket lifetime. */
1221 hierarchy
[2] = "max_life";
1222 if (!krb5_aprof_get_deltat(aprofile
, hierarchy
, TRUE
, &dtvalue
)) {
1223 rparams
->realm_max_life
= dtvalue
;
1224 rparams
->realm_max_life_valid
= 1;
1227 /* Get the value for maximum renewable ticket lifetime. */
1228 hierarchy
[2] = "max_renewable_life";
1229 if (!krb5_aprof_get_deltat(aprofile
, hierarchy
, TRUE
, &dtvalue
)) {
1230 rparams
->realm_max_rlife
= dtvalue
;
1231 rparams
->realm_max_rlife_valid
= 1;
1234 /* Get the value for the default principal expiration */
1235 hierarchy
[2] = "default_principal_expiration";
1236 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
)) {
1237 if (!krb5_string_to_timestamp(svalue
,
1238 &rparams
->realm_expiration
))
1239 rparams
->realm_expiration_valid
= 1;
1243 hierarchy
[2] = "reject_bad_transit";
1244 if (!krb5_aprof_get_boolean(aprofile
, hierarchy
, TRUE
, &bvalue
)) {
1245 rparams
->realm_reject_bad_transit
= bvalue
;
1246 rparams
->realm_reject_bad_transit_valid
= 1;
1249 /* Get the value for the default principal flags */
1250 hierarchy
[2] = "default_principal_flags";
1251 if (!krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
)) {
1255 rparams
->realm_flags
= 0;
1257 if ((ep
= strchr(sp
, (int) ',')) ||
1258 (ep
= strchr(sp
, (int) ' ')) ||
1259 (ep
= strchr(sp
, (int) '\t'))) {
1260 /* Fill in trailing whitespace of sp */
1262 while (isspace((int) *tp
) && (tp
< sp
)) {
1268 /* Skip over trailing whitespace of ep */
1269 while (isspace((int) *ep
) && (*ep
)) ep
++;
1271 /* Convert this flag */
1272 if (krb5_string_to_flags(sp
,
1275 &rparams
->realm_flags
))
1280 rparams
->realm_flags_valid
= 1;
1284 /* Get the value for the supported enctype/salttype matrix */
1287 * Solaris kerberos: updated this code to support default values for
1288 * the supported_enctypes.
1290 hierarchy
[2] = "supported_enctypes";
1292 krb5_aprof_get_string(aprofile
, hierarchy
, TRUE
, &svalue
);
1295 * Set the default value if supported_enctypes was not explicitly
1296 * set in the kdc.conf.
1298 if (svalue
== NULL
) {
1299 svalue
= strdup(DEFAULT_ENCTYPE_LIST
);
1301 if (svalue
!= NULL
) {
1302 krb5_string_to_keysalts(svalue
,
1303 ", \t", /* Tuple separators */
1304 ":.-", /* Key/salt separators */
1305 0, /* No duplicates */
1306 &rparams
->realm_keysalts
,
1307 &rparams
->realm_num_keysalts
);
1313 krb5_aprof_finish(aprofile
);
1317 krb5_free_realm_params(kcontext
, rparams
);
1325 * krb5_free_realm_params() - Free data allocated by above.
1328 krb5_free_realm_params(kcontext
, rparams
)
1329 krb5_context kcontext
;
1330 krb5_realm_params
*rparams
;
1333 if (rparams
->realm_profile
)
1334 krb5_xfree(rparams
->realm_profile
);
1335 if (rparams
->realm_dbname
)
1336 krb5_xfree(rparams
->realm_dbname
);
1337 if (rparams
->realm_mkey_name
)
1338 krb5_xfree(rparams
->realm_mkey_name
);
1339 if (rparams
->realm_stash_file
)
1340 krb5_xfree(rparams
->realm_stash_file
);
1341 if (rparams
->realm_keysalts
)
1342 krb5_xfree(rparams
->realm_keysalts
);
1343 if (rparams
->realm_kdc_ports
)
1344 krb5_xfree(rparams
->realm_kdc_ports
);
1345 if (rparams
->realm_kdc_tcp_ports
)
1346 krb5_xfree(rparams
->realm_kdc_tcp_ports
);
1347 if (rparams
->realm_acl_file
)
1348 krb5_xfree(rparams
->realm_acl_file
);
1349 krb5_xfree(rparams
);