xref: /onnv-gate/usr/src/lib/krb5/kadm5/alt_prof.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
26426Smp153739  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
110Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
120Sstevel@tonic-gate  *	source code before consulting with your legal department.
130Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
140Sstevel@tonic-gate  *	product before consulting with your legal department.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  *	For further information, read the top-level Openvision
170Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
180Sstevel@tonic-gate  *	copyright.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  * lib/kadm/alt_prof.c
270Sstevel@tonic-gate  *
282881Smp153739  * Copyright 1995,2001 by the Massachusetts Institute of Technology.
290Sstevel@tonic-gate  * All Rights Reserved.
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * Export of this software from the United States of America may
320Sstevel@tonic-gate  *   require a specific license from the United States Government.
330Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
340Sstevel@tonic-gate  *   export to obtain such a license before exporting.
350Sstevel@tonic-gate  *
360Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
370Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
380Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
390Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
400Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
410Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
420Sstevel@tonic-gate  * to distribution of the software without specific, written prior
432881Smp153739  * permission.  Furthermore if you modify this software you must label
442881Smp153739  * your software as modified software and not distribute it in such a
452881Smp153739  * fashion that it might be confused with the original M.I.T. software.
462881Smp153739  * M.I.T. makes no representations about the suitability of
470Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
480Sstevel@tonic-gate  * or implied warranty.
490Sstevel@tonic-gate  *
500Sstevel@tonic-gate  */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /*
530Sstevel@tonic-gate  * alt_prof.c - Implement alternate profile file handling.
540Sstevel@tonic-gate  */
55*7934SMark.Phalan@Sun.COM #include "k5-int.h"
560Sstevel@tonic-gate #include <kadm5/admin.h>
57*7934SMark.Phalan@Sun.COM #include "adm_proto.h"
580Sstevel@tonic-gate #include <stdio.h>
590Sstevel@tonic-gate #include <ctype.h>
600Sstevel@tonic-gate #include <os-proto.h>
610Sstevel@tonic-gate #include <kdb/kdb_log.h>
620Sstevel@tonic-gate 
630Sstevel@tonic-gate krb5_error_code kadm5_free_config_params();
640Sstevel@tonic-gate 
650Sstevel@tonic-gate #define	DEFAULT_ENCTYPE_LIST \
660Sstevel@tonic-gate 	"aes256-cts-hmac-sha1-96:normal " \
670Sstevel@tonic-gate 	"aes128-cts-hmac-sha1-96:normal " \
680Sstevel@tonic-gate 	"des3-cbc-hmac-sha1-kd:normal " \
690Sstevel@tonic-gate 	"arcfour-hmac-md5:normal " \
7096Ssemery 	"arcfour-hmac-md5-exp:normal " \
710Sstevel@tonic-gate 	"des-cbc-md5:normal " \
720Sstevel@tonic-gate 	"des-cbc-crc:normal"
730Sstevel@tonic-gate 
copy_key_salt_tuple(ksalt,len)742881Smp153739 static krb5_key_salt_tuple *copy_key_salt_tuple(ksalt, len)
752881Smp153739 krb5_key_salt_tuple *ksalt;
762881Smp153739 krb5_int32 len;
772881Smp153739 {
782881Smp153739     krb5_key_salt_tuple *knew;
792881Smp153739 
802881Smp153739     if((knew = (krb5_key_salt_tuple *)
812881Smp153739 		malloc((len ) * sizeof(krb5_key_salt_tuple)))) {
822881Smp153739          memcpy(knew, ksalt, len * sizeof(krb5_key_salt_tuple));
832881Smp153739 	 return knew;
842881Smp153739     }
852881Smp153739     return 0;
862881Smp153739 }
872881Smp153739 
880Sstevel@tonic-gate /*
890Sstevel@tonic-gate  * krb5_aprof_init()	- Initialize alternate profile context.
900Sstevel@tonic-gate  *
910Sstevel@tonic-gate  * Parameters:
920Sstevel@tonic-gate  *	fname		- default file name of the profile.
930Sstevel@tonic-gate  *	envname		- environment variable name which can override fname.
940Sstevel@tonic-gate  *	acontextp	- Pointer to opaque context for alternate profile.
950Sstevel@tonic-gate  *
960Sstevel@tonic-gate  * Returns:
970Sstevel@tonic-gate  *	error codes from profile_init()
980Sstevel@tonic-gate  */
990Sstevel@tonic-gate krb5_error_code
krb5_aprof_init(fname,envname,acontextp)1000Sstevel@tonic-gate krb5_aprof_init(fname, envname, acontextp)
1012881Smp153739     char		*fname;
1022881Smp153739     char		*envname;
1032881Smp153739     krb5_pointer	*acontextp;
1040Sstevel@tonic-gate {
1052881Smp153739     krb5_error_code	kret;
1062881Smp153739     profile_t		profile;
107*7934SMark.Phalan@Sun.COM     const char *kdc_config;
108*7934SMark.Phalan@Sun.COM     size_t krb5_config_len, kdc_config_len;
109*7934SMark.Phalan@Sun.COM     char *profile_path;
110*7934SMark.Phalan@Sun.COM     char **filenames;
111*7934SMark.Phalan@Sun.COM     int i;
112*7934SMark.Phalan@Sun.COM 
113*7934SMark.Phalan@Sun.COM     kret = krb5_get_default_config_files (&filenames);
114*7934SMark.Phalan@Sun.COM     if (kret)
115*7934SMark.Phalan@Sun.COM 	return kret;
116*7934SMark.Phalan@Sun.COM     krb5_config_len = 0;
117*7934SMark.Phalan@Sun.COM     for (i = 0; filenames[i] != NULL; i++)
118*7934SMark.Phalan@Sun.COM 	krb5_config_len += strlen(filenames[i]) + 1;
119*7934SMark.Phalan@Sun.COM     if (i > 0)
120*7934SMark.Phalan@Sun.COM 	krb5_config_len--;
121*7934SMark.Phalan@Sun.COM     if (envname == NULL
122*7934SMark.Phalan@Sun.COM 	|| (kdc_config = getenv(envname)) == NULL)
123*7934SMark.Phalan@Sun.COM 	kdc_config = fname;
124*7934SMark.Phalan@Sun.COM     if (kdc_config == NULL)
125*7934SMark.Phalan@Sun.COM 	kdc_config_len = 0;
126*7934SMark.Phalan@Sun.COM     else
127*7934SMark.Phalan@Sun.COM 	kdc_config_len = strlen(kdc_config);
128*7934SMark.Phalan@Sun.COM     profile_path = malloc(2 + krb5_config_len + kdc_config_len);
129*7934SMark.Phalan@Sun.COM     if (profile_path == NULL) {
130*7934SMark.Phalan@Sun.COM 	krb5_free_config_files(filenames);
131*7934SMark.Phalan@Sun.COM 	return errno;
132*7934SMark.Phalan@Sun.COM     }
133*7934SMark.Phalan@Sun.COM     if (kdc_config_len)
134*7934SMark.Phalan@Sun.COM 	strcpy(profile_path, kdc_config);
135*7934SMark.Phalan@Sun.COM     else
136*7934SMark.Phalan@Sun.COM 	profile_path[0] = 0;
137*7934SMark.Phalan@Sun.COM     if (krb5_config_len)
138*7934SMark.Phalan@Sun.COM 	for (i = 0; filenames[i] != NULL; i++) {
139*7934SMark.Phalan@Sun.COM 	    if (kdc_config_len || i)
140*7934SMark.Phalan@Sun.COM 		strcat(profile_path, ":");
141*7934SMark.Phalan@Sun.COM 	    strcat(profile_path, filenames[i]);
142*7934SMark.Phalan@Sun.COM 	}
143*7934SMark.Phalan@Sun.COM     krb5_free_config_files(filenames);
1442881Smp153739     profile = (profile_t) NULL;
145*7934SMark.Phalan@Sun.COM     kret = profile_init_path(profile_path, &profile);
146*7934SMark.Phalan@Sun.COM     free(profile_path);
147*7934SMark.Phalan@Sun.COM     if (kret)
148*7934SMark.Phalan@Sun.COM 	return kret;
149*7934SMark.Phalan@Sun.COM     *acontextp = profile;
1502881Smp153739     return 0;
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate /*
1540Sstevel@tonic-gate  * krb5_aprof_getvals()	- Get values from alternate profile.
1550Sstevel@tonic-gate  *
1560Sstevel@tonic-gate  * Parameters:
1570Sstevel@tonic-gate  *	acontext	- opaque context for alternate profile.
1580Sstevel@tonic-gate  *	hierarchy	- hierarchy of value to retrieve.
1590Sstevel@tonic-gate  *	retdata		- Returned data values.
1600Sstevel@tonic-gate  *
1610Sstevel@tonic-gate  * Returns:
1620Sstevel@tonic-gate  * 	error codes from profile_get_values()
1630Sstevel@tonic-gate  */
1640Sstevel@tonic-gate krb5_error_code
krb5_aprof_getvals(acontext,hierarchy,retdata)1650Sstevel@tonic-gate krb5_aprof_getvals(acontext, hierarchy, retdata)
1662881Smp153739     krb5_pointer	acontext;
1672881Smp153739     const char		**hierarchy;
1682881Smp153739     char		***retdata;
1692881Smp153739 {
1702881Smp153739     return(profile_get_values((profile_t) acontext,
1712881Smp153739 			      hierarchy,
1722881Smp153739 			      retdata));
1732881Smp153739 }
1742881Smp153739 
1752881Smp153739 /*
1762881Smp153739  * krb5_aprof_get_boolean()
1772881Smp153739  *
1782881Smp153739  * Parameters:
1792881Smp153739  *	acontext	- opaque context for alternate profile
1802881Smp153739  *	hierarchy	- hierarchy of value to retrieve
1812881Smp153739  *	retdata		- Returned data value
1822881Smp153739  * Returns:
1832881Smp153739  *	error codes
1842881Smp153739  */
1852881Smp153739 
1862881Smp153739 static krb5_error_code
string_to_boolean(const char * string,krb5_boolean * out)1872881Smp153739 string_to_boolean (const char *string, krb5_boolean *out)
1880Sstevel@tonic-gate {
1892881Smp153739     static const char *const yes[] = { "y", "yes", "true", "t", "1", "on" };
1902881Smp153739     static const char *const no[] = { "n", "no", "false", "f", "nil", "0", "off" };
1912881Smp153739     int i;
1922881Smp153739 
1932881Smp153739     for (i = 0; i < sizeof(yes)/sizeof(yes[0]); i++)
1942881Smp153739 	if (!strcasecmp(string, yes[i])) {
1952881Smp153739 	    *out = 1;
1962881Smp153739 	    return 0;
1972881Smp153739 	}
1982881Smp153739     for (i = 0; i < sizeof(no)/sizeof(no[0]); i++)
1992881Smp153739 	if (!strcasecmp(string, no[i])) {
2002881Smp153739 	    *out = 0;
2012881Smp153739 	    return 0;
2022881Smp153739 	}
2032881Smp153739     return PROF_BAD_BOOLEAN;
2042881Smp153739 }
2052881Smp153739 
2062881Smp153739 krb5_error_code
krb5_aprof_get_boolean(krb5_pointer acontext,const char ** hierarchy,int uselast,krb5_boolean * retdata)2072881Smp153739 krb5_aprof_get_boolean(krb5_pointer acontext, const char **hierarchy,
2082881Smp153739 		       int uselast, krb5_boolean *retdata)
2092881Smp153739 {
2102881Smp153739     krb5_error_code kret;
2112881Smp153739     char **values;
2122881Smp153739     char *valp;
2132881Smp153739     int idx;
2142881Smp153739     krb5_boolean val;
2152881Smp153739 
2162881Smp153739     kret = krb5_aprof_getvals (acontext, hierarchy, &values);
2172881Smp153739     if (kret)
2182881Smp153739 	return kret;
2192881Smp153739     idx = 0;
2202881Smp153739     if (uselast) {
2212881Smp153739 	while (values[idx])
2222881Smp153739 	    idx++;
2232881Smp153739 	idx--;
2242881Smp153739     }
2252881Smp153739     valp = values[idx];
2262881Smp153739     kret = string_to_boolean (valp, &val);
2272881Smp153739     if (kret)
2282881Smp153739 	return kret;
2292881Smp153739     *retdata = val;
2302881Smp153739     return 0;
2310Sstevel@tonic-gate }
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate /*
2340Sstevel@tonic-gate  * krb5_aprof_get_deltat()	- Get a delta time value from the alternate
2350Sstevel@tonic-gate  *				  profile.
2360Sstevel@tonic-gate  *
2370Sstevel@tonic-gate  * Parameters:
2380Sstevel@tonic-gate  *	acontext		- opaque context for alternate profile.
2390Sstevel@tonic-gate  *	hierarchy		- hierarchy of value to retrieve.
2400Sstevel@tonic-gate  *	uselast			- if true, use last value, otherwise use
2410Sstevel@tonic-gate  *				  first value found.
2420Sstevel@tonic-gate  *	deltatp			- returned delta time value.
2430Sstevel@tonic-gate  *
2440Sstevel@tonic-gate  * Returns:
2450Sstevel@tonic-gate  * 	error codes from profile_get_values()
2460Sstevel@tonic-gate  *	error codes from krb5_string_to_deltat()
2470Sstevel@tonic-gate  */
2480Sstevel@tonic-gate krb5_error_code
krb5_aprof_get_deltat(acontext,hierarchy,uselast,deltatp)2490Sstevel@tonic-gate krb5_aprof_get_deltat(acontext, hierarchy, uselast, deltatp)
2502881Smp153739     krb5_pointer	acontext;
2512881Smp153739     const char		**hierarchy;
2522881Smp153739     krb5_boolean	uselast;
2532881Smp153739     krb5_deltat		*deltatp;
2540Sstevel@tonic-gate {
2552881Smp153739     krb5_error_code	kret;
2562881Smp153739     char		**values;
2572881Smp153739     char		*valp;
2582881Smp153739     int			idx;
2590Sstevel@tonic-gate 
2602881Smp153739     if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
2612881Smp153739 	idx = 0;
2622881Smp153739 	if (uselast) {
2632881Smp153739 	    for (idx=0; values[idx]; idx++);
2642881Smp153739 	    idx--;
2652881Smp153739 	}
2662881Smp153739 	valp = values[idx];
2672881Smp153739 	kret = krb5_string_to_deltat(valp, deltatp);
2680Sstevel@tonic-gate 
2692881Smp153739 	/* Free the string storage */
2702881Smp153739 	for (idx=0; values[idx]; idx++)
2712881Smp153739 	    krb5_xfree(values[idx]);
2722881Smp153739 	krb5_xfree(values);
2732881Smp153739     }
2742881Smp153739     return(kret);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate /*
2780Sstevel@tonic-gate  * krb5_aprof_get_string()	- Get a string value from the alternate
2790Sstevel@tonic-gate  *				  profile.
2800Sstevel@tonic-gate  *
2810Sstevel@tonic-gate  * Parameters:
2820Sstevel@tonic-gate  *	acontext		- opaque context for alternate profile.
2830Sstevel@tonic-gate  *	hierarchy		- hierarchy of value to retrieve.
2840Sstevel@tonic-gate  *	uselast			- if true, use last value, otherwise use
2850Sstevel@tonic-gate  *				  first value found.
2860Sstevel@tonic-gate  *	stringp			- returned string value.
2870Sstevel@tonic-gate  *
2880Sstevel@tonic-gate  * Returns:
2890Sstevel@tonic-gate  * 	error codes from profile_get_values()
2900Sstevel@tonic-gate  */
2910Sstevel@tonic-gate krb5_error_code
krb5_aprof_get_string(acontext,hierarchy,uselast,stringp)2920Sstevel@tonic-gate krb5_aprof_get_string(acontext, hierarchy, uselast, stringp)
2932881Smp153739     krb5_pointer	acontext;
2942881Smp153739     const char		**hierarchy;
2952881Smp153739     krb5_boolean	uselast;
2962881Smp153739     char		**stringp;
2970Sstevel@tonic-gate {
2982881Smp153739     krb5_error_code	kret;
2992881Smp153739     char		**values;
3002881Smp153739     int			idx, i;
3010Sstevel@tonic-gate 
3022881Smp153739     if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
3032881Smp153739 	idx = 0;
3042881Smp153739 	if (uselast) {
3052881Smp153739 	    for (idx=0; values[idx]; idx++);
3062881Smp153739 	    idx--;
3072881Smp153739 	}
3080Sstevel@tonic-gate 
3092881Smp153739 	*stringp = values[idx];
3100Sstevel@tonic-gate 
3112881Smp153739 	/* Free the string storage */
3122881Smp153739 	for (i=0; values[i]; i++)
3132881Smp153739 	    if (i != idx)
3142881Smp153739 		krb5_xfree(values[i]);
3152881Smp153739 	krb5_xfree(values);
3162881Smp153739     }
3172881Smp153739     return(kret);
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate /*
3210Sstevel@tonic-gate  * krb5_aprof_get_int32()	- Get a 32-bit integer value from the alternate
3220Sstevel@tonic-gate  *				  profile.
3230Sstevel@tonic-gate  *
3240Sstevel@tonic-gate  * Parameters:
3250Sstevel@tonic-gate  *	acontext		- opaque context for alternate profile.
3260Sstevel@tonic-gate  *	hierarchy		- hierarchy of value to retrieve.
3270Sstevel@tonic-gate  *	uselast			- if true, use last value, otherwise use
3280Sstevel@tonic-gate  *				  first value found.
3290Sstevel@tonic-gate  *	intp			- returned 32-bit integer value.
3300Sstevel@tonic-gate  *
3310Sstevel@tonic-gate  * Returns:
3320Sstevel@tonic-gate  * 	error codes from profile_get_values()
3330Sstevel@tonic-gate  *	EINVAL			- value is not an integer
3340Sstevel@tonic-gate  */
3350Sstevel@tonic-gate krb5_error_code
krb5_aprof_get_int32(acontext,hierarchy,uselast,intp)3360Sstevel@tonic-gate krb5_aprof_get_int32(acontext, hierarchy, uselast, intp)
3372881Smp153739     krb5_pointer	acontext;
3382881Smp153739     const char		**hierarchy;
3392881Smp153739     krb5_boolean	uselast;
3402881Smp153739     krb5_int32		*intp;
3410Sstevel@tonic-gate {
3422881Smp153739     krb5_error_code	kret;
3432881Smp153739     char		**values;
3442881Smp153739     int			idx;
3450Sstevel@tonic-gate 
3462881Smp153739     if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
3472881Smp153739 	idx = 0;
3482881Smp153739 	if (uselast) {
3492881Smp153739 	    for (idx=0; values[idx]; idx++);
3502881Smp153739 	    idx--;
3512881Smp153739 	}
3520Sstevel@tonic-gate 
3532881Smp153739 	if (sscanf(values[idx], "%d", intp) != 1)
3542881Smp153739 	    kret = EINVAL;
3550Sstevel@tonic-gate 
3562881Smp153739 	/* Free the string storage */
3572881Smp153739 	for (idx=0; values[idx]; idx++)
3582881Smp153739 	    krb5_xfree(values[idx]);
3592881Smp153739 	krb5_xfree(values);
3602881Smp153739     }
3612881Smp153739     return(kret);
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate /*
3650Sstevel@tonic-gate  * krb5_aprof_finish()	- Finish alternate profile context.
3660Sstevel@tonic-gate  *
3670Sstevel@tonic-gate  * Parameter:
3680Sstevel@tonic-gate  *	acontext	- opaque context for alternate profile.
3690Sstevel@tonic-gate  *
3700Sstevel@tonic-gate  * Returns:
3710Sstevel@tonic-gate  *	0 on success, something else on failure.
3720Sstevel@tonic-gate  */
3730Sstevel@tonic-gate krb5_error_code
krb5_aprof_finish(acontext)3740Sstevel@tonic-gate krb5_aprof_finish(acontext)
3752881Smp153739     krb5_pointer	acontext;
3760Sstevel@tonic-gate {
3772881Smp153739     profile_release(acontext);
3782881Smp153739     return(0);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate /*
3820Sstevel@tonic-gate  * Function: kadm5_get_config_params
3830Sstevel@tonic-gate  *
3840Sstevel@tonic-gate  * Purpose: Merge configuration parameters provided by the caller with
3850Sstevel@tonic-gate  * values specified in configuration files and with default values.
3860Sstevel@tonic-gate  *
3870Sstevel@tonic-gate  * Arguments:
3880Sstevel@tonic-gate  *
3892881Smp153739  *	context		(r) krb5_context to use
3902881Smp153739  *	profile		(r) profile file to use
3912881Smp153739  *	envname		(r) envname that contains a profile name to
3920Sstevel@tonic-gate  *			override profile
3932881Smp153739  *	params_in	(r) params structure containing user-supplied
3940Sstevel@tonic-gate  *			values, or NULL
3952881Smp153739  *	params_out	(w) params structure to be filled in
3960Sstevel@tonic-gate  *
3970Sstevel@tonic-gate  * Effects:
3980Sstevel@tonic-gate  *
3990Sstevel@tonic-gate  * The fields and mask of params_out are filled in with values
4000Sstevel@tonic-gate  * obtained from params_in, the specified profile, and default
4010Sstevel@tonic-gate  * values.  Only and all fields specified in params_out->mask are
4020Sstevel@tonic-gate  * set.  The context of params_out must be freed with
4030Sstevel@tonic-gate  * kadm5_free_config_params.
4040Sstevel@tonic-gate  *
4050Sstevel@tonic-gate  * params_in and params_out may be the same pointer.  However, all pointers
4060Sstevel@tonic-gate  * in params_in for which the mask is set will be re-assigned to newly copied
4070Sstevel@tonic-gate  * versions, overwriting the old pointer value.
4080Sstevel@tonic-gate  */
kadm5_get_config_params(context,use_kdc_config,params_in,params_out)409*7934SMark.Phalan@Sun.COM krb5_error_code kadm5_get_config_params(context, use_kdc_config,
4100Sstevel@tonic-gate 					params_in, params_out)
4112881Smp153739    krb5_context		context;
412*7934SMark.Phalan@Sun.COM    int			use_kdc_config;
4132881Smp153739    kadm5_config_params	*params_in, *params_out;
4140Sstevel@tonic-gate {
4152881Smp153739     char		*filename;
4162881Smp153739     char		*envname;
4172881Smp153739     char		*lrealm;
4182881Smp153739     krb5_pointer	aprofile = 0;
4192881Smp153739     const char		*hierarchy[4];
4202881Smp153739     char		*svalue;
4212881Smp153739     krb5_int32		ivalue;
4222881Smp153739     kadm5_config_params params, empty_params;
4230Sstevel@tonic-gate 
4242881Smp153739     krb5_error_code	kret = 0;
425*7934SMark.Phalan@Sun.COM     krb5_error_code dnsret = 1;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
4280Sstevel@tonic-gate 	char dns_host[MAX_DNS_NAMELEN];
4290Sstevel@tonic-gate 	unsigned short dns_portno;
4300Sstevel@tonic-gate 	krb5_data dns_realm;
4312968Smp153739 	memset((char *)&dns_realm, 0, sizeof (dns_realm));
4320Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
4330Sstevel@tonic-gate 
4342881Smp153739     memset((char *) &params, 0, sizeof(params));
4352881Smp153739     memset((char *) &empty_params, 0, sizeof(empty_params));
4360Sstevel@tonic-gate 
4372881Smp153739     if (params_in == NULL) params_in = &empty_params;
4380Sstevel@tonic-gate 
4392881Smp153739     if (params_in->mask & KADM5_CONFIG_REALM) {
4402881Smp153739 	 lrealm = params.realm = strdup(params_in->realm);
4412881Smp153739 	 if (params.realm)
4422881Smp153739 	      params.mask |= KADM5_CONFIG_REALM;
4432881Smp153739     } else {
4442881Smp153739 	 kret = krb5_get_default_realm(context, &lrealm);
4452881Smp153739 	 if (kret)
4462881Smp153739 	      goto cleanup;
4472881Smp153739 	 params.realm = lrealm;
4482881Smp153739 	 params.mask |= KADM5_CONFIG_REALM;
4492881Smp153739     }
450*7934SMark.Phalan@Sun.COM     /*
451*7934SMark.Phalan@Sun.COM      * XXX These defaults should to work on both client and
452*7934SMark.Phalan@Sun.COM      * server.  kadm5_get_config_params can be implemented as a
453*7934SMark.Phalan@Sun.COM      * wrapper function in each library that provides correct
454*7934SMark.Phalan@Sun.COM      * defaults for NULL values.
455*7934SMark.Phalan@Sun.COM      */
456*7934SMark.Phalan@Sun.COM     if (use_kdc_config) {
457*7934SMark.Phalan@Sun.COM 	filename = DEFAULT_KDC_PROFILE;
458*7934SMark.Phalan@Sun.COM 	envname = KDC_PROFILE_ENV;
4592881Smp153739     } else {
460*7934SMark.Phalan@Sun.COM 	filename = DEFAULT_PROFILE_PATH;
461*7934SMark.Phalan@Sun.COM 	envname = "KRB5_CONFIG";
4622881Smp153739     }
463*7934SMark.Phalan@Sun.COM     if (context->profile_secure == TRUE) envname = 0;
4640Sstevel@tonic-gate 
4652881Smp153739     kret = krb5_aprof_init(filename, envname, &aprofile);
4662881Smp153739     if (kret)
4672881Smp153739 	    goto cleanup;
4682881Smp153739 
4692881Smp153739     /* Initialize realm parameters */
4702881Smp153739     hierarchy[0] = "realms";
4712881Smp153739     hierarchy[1] = lrealm;
4722881Smp153739     hierarchy[3] = (char *) NULL;
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
4750Sstevel@tonic-gate 	/*
4760Sstevel@tonic-gate 	 * Initialize realm info for (possible) DNS lookups.
4770Sstevel@tonic-gate 	 */
4780Sstevel@tonic-gate 	dns_realm.data = strdup(lrealm);
4790Sstevel@tonic-gate 	dns_realm.length = strlen(lrealm);
4800Sstevel@tonic-gate 	dns_realm.magic = 0;
4810Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
4820Sstevel@tonic-gate 
4832881Smp153739     /* Get the value for the admin server */
4842881Smp153739     hierarchy[2] = "admin_server";
4852881Smp153739     if (params_in->mask & KADM5_CONFIG_ADMIN_SERVER) {
4862881Smp153739 	 params.admin_server = strdup(params_in->admin_server);
4872881Smp153739 	 if (params.admin_server)
4882881Smp153739 	      params.mask |= KADM5_CONFIG_ADMIN_SERVER;
4892881Smp153739     } else if (aprofile &&
4902881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
4912881Smp153739 	 params.admin_server = svalue;
4922881Smp153739 	 params.mask |= KADM5_CONFIG_ADMIN_SERVER;
4932881Smp153739     }
4940Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
4950Sstevel@tonic-gate 	else if (strcmp(envname, "KRB5_CONFIG") == 0) {
4960Sstevel@tonic-gate 		/*
4970Sstevel@tonic-gate 		 * Solaris Kerberos: only do DNS lookup for admin_server if this
4980Sstevel@tonic-gate 		 * is a krb5.conf type of config file.  Note, the filename may
4990Sstevel@tonic-gate 		 * not be /etc/krb5/krb5.conf so we assume that the KRB5_CONFIG
5000Sstevel@tonic-gate 		 * envname string will consistently indicate the type of config
5010Sstevel@tonic-gate 		 * file.
5020Sstevel@tonic-gate 		 */
5030Sstevel@tonic-gate 		dnsret = krb5_get_servername(context, &dns_realm,
5040Sstevel@tonic-gate 					"_kerberos-adm", "_udp",
5050Sstevel@tonic-gate 					dns_host, &dns_portno);
5060Sstevel@tonic-gate 		if (dnsret == 0) {
5070Sstevel@tonic-gate 			params.admin_server = strdup(dns_host);
5080Sstevel@tonic-gate 			if (params.admin_server)
5090Sstevel@tonic-gate 				params.mask |= KADM5_CONFIG_ADMIN_SERVER;
5100Sstevel@tonic-gate 			params.kadmind_port = dns_portno;
5110Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_KADMIND_PORT;
5120Sstevel@tonic-gate 		}
5130Sstevel@tonic-gate 	}
5140Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
5150Sstevel@tonic-gate 
5162881Smp153739     if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) && dnsret) {
5172881Smp153739 	 char *p;
5182881Smp153739 	 p = strchr(params.admin_server, ':');
5192881Smp153739 	 if (p) {
5202881Smp153739 	      params.kadmind_port = atoi(p+1);
5212881Smp153739 	      params.mask |= KADM5_CONFIG_KADMIND_PORT;
5222881Smp153739 	      *p = '\0';
5232881Smp153739 	 }
5242881Smp153739     }
5250Sstevel@tonic-gate 
5262881Smp153739     /* Get the value for the database */
5272881Smp153739     hierarchy[2] = "database_name";
5282881Smp153739     if (params_in->mask & KADM5_CONFIG_DBNAME) {
5292881Smp153739 	 params.dbname = strdup(params_in->dbname);
5302881Smp153739 	 if (params.dbname)
5312881Smp153739 	      params.mask |= KADM5_CONFIG_DBNAME;
5322881Smp153739     } else if (aprofile &&
5332881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
5342881Smp153739 	 params.dbname = svalue;
5352881Smp153739 	 params.mask |= KADM5_CONFIG_DBNAME;
5362881Smp153739     } else {
5372881Smp153739 	 params.dbname = strdup(DEFAULT_KDB_FILE);
5382881Smp153739 	 if (params.dbname)
5392881Smp153739 	      params.mask |= KADM5_CONFIG_DBNAME;
5402881Smp153739     }
5410Sstevel@tonic-gate 
5422881Smp153739     /*
5432881Smp153739      * admin database name and lockfile are now always derived from dbname
5442881Smp153739      */
5452881Smp153739     if (params.mask & KADM5_CONFIG_DBNAME) {
5462881Smp153739 	 params.admin_dbname = (char *) malloc(strlen(params.dbname) + 7);
5472881Smp153739 	 if (params.admin_dbname) {
5482881Smp153739 	      sprintf(params.admin_dbname, "%s.kadm5", params.dbname);
5492881Smp153739 	      params.mask |= KADM5_CONFIG_ADBNAME;
5502881Smp153739 	 }
5512881Smp153739     }
5520Sstevel@tonic-gate 
5532881Smp153739     if (params.mask & KADM5_CONFIG_ADBNAME) {
5542881Smp153739 	 params.admin_lockfile = (char *) malloc(strlen(params.admin_dbname)
5552881Smp153739 						 + 6);
5562881Smp153739 	 if (params.admin_lockfile) {
5572881Smp153739 	      sprintf(params.admin_lockfile, "%s.lock", params.admin_dbname);
5582881Smp153739 	      params.mask |= KADM5_CONFIG_ADB_LOCKFILE;
5592881Smp153739 	 }
5602881Smp153739     }
5612881Smp153739 
5622881Smp153739     /* Get the value for the admin (policy) database lock file*/
5632881Smp153739     hierarchy[2] = "admin_keytab";
5642881Smp153739     if (params_in->mask & KADM5_CONFIG_ADMIN_KEYTAB) {
5652881Smp153739 	 params.admin_keytab = strdup(params_in->admin_keytab);
5662881Smp153739 	 if (params.admin_keytab)
5672881Smp153739 	      params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
5682881Smp153739     } else if (aprofile &&
5692881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
5702881Smp153739 	 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
5712881Smp153739 	 params.admin_keytab = svalue;
5722881Smp153739     } else if ((params.admin_keytab = (char *) getenv("KRB5_KTNAME"))) {
5732881Smp153739 	 params.admin_keytab = strdup(params.admin_keytab);
5742881Smp153739 	 if (params.admin_keytab)
5752881Smp153739 	      params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
5762881Smp153739     } else {
5772881Smp153739 	 params.admin_keytab = strdup(DEFAULT_KADM5_KEYTAB);
5782881Smp153739 	 if (params.admin_keytab)
5792881Smp153739 	      params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
5802881Smp153739     }
5812881Smp153739 
5822881Smp153739     /* Get the name of the acl file */
5832881Smp153739     hierarchy[2] = "acl_file";
5842881Smp153739     if (params_in->mask & KADM5_CONFIG_ACL_FILE) {
5852881Smp153739 	 params.acl_file = strdup(params_in->acl_file);
5862881Smp153739 	 if (params.acl_file)
5872881Smp153739 	      params.mask |= KADM5_CONFIG_ACL_FILE;
5882881Smp153739     } else if (aprofile &&
5892881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
5902881Smp153739 	 params.mask |= KADM5_CONFIG_ACL_FILE;
5912881Smp153739 	 params.acl_file = svalue;
5922881Smp153739     } else {
5932881Smp153739 	 params.acl_file = strdup(DEFAULT_KADM5_ACL_FILE);
5942881Smp153739 	 if (params.acl_file)
5952881Smp153739 	      params.mask |= KADM5_CONFIG_ACL_FILE;
5962881Smp153739     }
5972881Smp153739 
5982881Smp153739     /* Get the name of the dict file */
5992881Smp153739     hierarchy[2] = "dict_file";
6002881Smp153739     if (params_in->mask & KADM5_CONFIG_DICT_FILE) {
6012881Smp153739 	 params.dict_file = strdup(params_in->dict_file);
6022881Smp153739 	 if (params.dict_file)
6032881Smp153739 	      params.mask |= KADM5_CONFIG_DICT_FILE;
6042881Smp153739     } else if (aprofile &&
6052881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
6062881Smp153739 	 params.mask |= KADM5_CONFIG_DICT_FILE;
6072881Smp153739 	 params.dict_file = svalue;
6082881Smp153739     }
6092881Smp153739 
6102881Smp153739     /* Get the value for the kadmind port */
6112881Smp153739     if (! (params.mask & KADM5_CONFIG_KADMIND_PORT)) {
6122881Smp153739 	 hierarchy[2] = "kadmind_port";
6132881Smp153739 	 if (params_in->mask & KADM5_CONFIG_KADMIND_PORT) {
6142881Smp153739 	      params.mask |= KADM5_CONFIG_KADMIND_PORT;
6152881Smp153739 	      params.kadmind_port = params_in->kadmind_port;
6162881Smp153739 	 } else if (aprofile &&
6172881Smp153739 		    !krb5_aprof_get_int32(aprofile, hierarchy, TRUE,
6182881Smp153739 					  &ivalue)) {
6192881Smp153739 	      params.kadmind_port = ivalue;
6202881Smp153739 	      params.mask |= KADM5_CONFIG_KADMIND_PORT;
6212881Smp153739 	 } else {
6222881Smp153739 	      params.kadmind_port = DEFAULT_KADM5_PORT;
6232881Smp153739 	      params.mask |= KADM5_CONFIG_KADMIND_PORT;
6242881Smp153739 	 }
6252881Smp153739     }
6262881Smp153739 
6272881Smp153739     /* Get the value for the kpasswd port */
6282881Smp153739     if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) {
6292881Smp153739 	hierarchy[2] = "kpasswd_port";
6302881Smp153739 	if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT) {
6312881Smp153739 	    params.mask |= KADM5_CONFIG_KPASSWD_PORT;
6322881Smp153739 	    params.kpasswd_port = params_in->kpasswd_port;
6330Sstevel@tonic-gate 	} else if (aprofile &&
6342881Smp153739 		   !krb5_aprof_get_int32(aprofile, hierarchy, TRUE,
6352881Smp153739 					 &ivalue)) {
6362881Smp153739 	    params.kpasswd_port = ivalue;
6372881Smp153739 	    params.mask |= KADM5_CONFIG_KPASSWD_PORT;
6380Sstevel@tonic-gate 	} else {
6392881Smp153739 	    params.kpasswd_port = DEFAULT_KPASSWD_PORT;
6402881Smp153739 	    params.mask |= KADM5_CONFIG_KPASSWD_PORT;
6410Sstevel@tonic-gate 	}
6422881Smp153739     }
6432881Smp153739 
6442881Smp153739     /* Get the value for the master key name */
6452881Smp153739 	 hierarchy[2] = "master_key_name";
6462881Smp153739     if (params_in->mask & KADM5_CONFIG_MKEY_NAME) {
6472881Smp153739 	 params.mkey_name = strdup(params_in->mkey_name);
6482881Smp153739 	 if (params.mkey_name)
6492881Smp153739 	      params.mask |= KADM5_CONFIG_MKEY_NAME;
6502881Smp153739     } else if (aprofile &&
6512881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
6522881Smp153739 	 params.mask |= KADM5_CONFIG_MKEY_NAME;
6532881Smp153739 	 params.mkey_name = svalue;
6542881Smp153739     }
6552881Smp153739 
6562881Smp153739     /* Get the value for the master key type */
6572881Smp153739     hierarchy[2] = "master_key_type";
6582881Smp153739     if (params_in->mask & KADM5_CONFIG_ENCTYPE) {
6592881Smp153739 	 params.mask |= KADM5_CONFIG_ENCTYPE;
6602881Smp153739 	 params.enctype = params_in->enctype;
6612881Smp153739     } else if (aprofile &&
6622881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
6632881Smp153739 	 if (!krb5_string_to_enctype(svalue, &params.enctype)) {
6642881Smp153739 	      params.mask |= KADM5_CONFIG_ENCTYPE;
6652881Smp153739 	      krb5_xfree(svalue);
6662881Smp153739 	 }
6672881Smp153739     } else {
6682881Smp153739 	 params.mask |= KADM5_CONFIG_ENCTYPE;
6692881Smp153739 	 params.enctype = DEFAULT_KDC_ENCTYPE;
6702881Smp153739     }
6712881Smp153739 
6722881Smp153739     /* Get the value for mkey_from_kbd */
6732881Smp153739     if (params_in->mask & KADM5_CONFIG_MKEY_FROM_KBD) {
6742881Smp153739 	 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
6752881Smp153739 	 params.mkey_from_kbd = params_in->mkey_from_kbd;
6762881Smp153739     }
6772881Smp153739 
6782881Smp153739     /* Get the value for the stashfile */
6792881Smp153739     hierarchy[2] = "key_stash_file";
6802881Smp153739     if (params_in->mask & KADM5_CONFIG_STASH_FILE) {
6812881Smp153739 	 params.stash_file = strdup(params_in->stash_file);
6822881Smp153739 	 if (params.stash_file)
6832881Smp153739 	      params.mask |= KADM5_CONFIG_STASH_FILE;
6842881Smp153739     } else if (aprofile &&
6852881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
6862881Smp153739 	 params.mask |= KADM5_CONFIG_STASH_FILE;
6872881Smp153739 	 params.stash_file = svalue;
6882881Smp153739     }
6892881Smp153739 
690*7934SMark.Phalan@Sun.COM 	/*
691*7934SMark.Phalan@Sun.COM 	 * Solaris Kerberos
6922881Smp153739 	 * Get the value for maximum ticket lifetime.
6930Sstevel@tonic-gate 	 * See SEAM documentation or the Bug ID 4184504
6940Sstevel@tonic-gate 	 * We have changed the logic so that the entries are
6950Sstevel@tonic-gate 	 * created in the database with the maximum duration
6960Sstevel@tonic-gate 	 * for life and renew life KRB5_INT32_MAX
6970Sstevel@tonic-gate 	 * However this wil get negotiated down when
6980Sstevel@tonic-gate 	 * as or tgs request is processed by KDC.
6990Sstevel@tonic-gate 	 */
7002881Smp153739     hierarchy[2] = "max_life";
7012881Smp153739     if (params_in->mask & KADM5_CONFIG_MAX_LIFE) {
7022881Smp153739 	 params.mask |= KADM5_CONFIG_MAX_LIFE;
7032881Smp153739 	 params.max_life = params_in->max_life;
7042881Smp153739     } else {
7052881Smp153739 	 params.max_life = KRB5_INT32_MAX;
7062881Smp153739 	 params.mask |= KADM5_CONFIG_MAX_LIFE;
7072881Smp153739     }
7082881Smp153739 
7092881Smp153739     /* Get the value for maximum renewable ticket lifetime. */
7102881Smp153739     hierarchy[2] = "max_renewable_life";
7112881Smp153739     if (params_in->mask & KADM5_CONFIG_MAX_RLIFE) {
7122881Smp153739 	 params.mask |= KADM5_CONFIG_MAX_RLIFE;
7132881Smp153739 	 params.max_rlife = params_in->max_rlife;
7142881Smp153739     } else {
7152881Smp153739 	 params.max_rlife =  KRB5_INT32_MAX;
7162881Smp153739 	 params.mask |= KADM5_CONFIG_MAX_RLIFE;
7172881Smp153739     }
7182881Smp153739 
7192881Smp153739     /* Get the value for the default principal expiration */
7202881Smp153739     hierarchy[2] = "default_principal_expiration";
7212881Smp153739     if (params_in->mask & KADM5_CONFIG_EXPIRATION) {
7222881Smp153739 	 params.mask |= KADM5_CONFIG_EXPIRATION;
7232881Smp153739 	 params.expiration = params_in->expiration;
7242881Smp153739     } else if (aprofile &&
7252881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
7262881Smp153739 	 if (!krb5_string_to_timestamp(svalue, &params.expiration)) {
7272881Smp153739 	      params.mask |= KADM5_CONFIG_EXPIRATION;
7282881Smp153739 	      krb5_xfree(svalue);
7292881Smp153739 	 }
7302881Smp153739     } else {
7312881Smp153739 	 params.mask |= KADM5_CONFIG_EXPIRATION;
7322881Smp153739 	 params.expiration = 0;
7332881Smp153739     }
7342881Smp153739 
7352881Smp153739     /* Get the value for the default principal flags */
7362881Smp153739     hierarchy[2] = "default_principal_flags";
7372881Smp153739     if (params_in->mask & KADM5_CONFIG_FLAGS) {
7382881Smp153739 	 params.mask |= KADM5_CONFIG_FLAGS;
7392881Smp153739 	 params.flags = params_in->flags;
7402881Smp153739     } else if (aprofile &&
7412881Smp153739 	       !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
7422881Smp153739 	 char *sp, *ep, *tp;
7432881Smp153739 
7442881Smp153739 	 sp = svalue;
7452881Smp153739 	 params.flags = 0;
7462881Smp153739 	 while (sp) {
7472881Smp153739 	      if ((ep = strchr(sp, (int) ',')) ||
7482881Smp153739 		  (ep = strchr(sp, (int) ' ')) ||
7492881Smp153739 		  (ep = strchr(sp, (int) '\t'))) {
7502881Smp153739 		   /* Fill in trailing whitespace of sp */
7512881Smp153739 		   tp = ep - 1;
7522881Smp153739 		   while (isspace((int) *tp) && (tp > sp)) {
7532881Smp153739 			*tp = '\0';
7542881Smp153739 			tp--;
7552881Smp153739 		   }
7562881Smp153739 		   *ep = '\0';
7572881Smp153739 		   ep++;
7582881Smp153739 		   /* Skip over trailing whitespace of ep */
7592881Smp153739 		   while (isspace((int) *ep) && (*ep)) ep++;
7602881Smp153739 	      }
7612881Smp153739 	      /* Convert this flag */
7622881Smp153739 	      if (krb5_string_to_flags(sp,
7632881Smp153739 				       "+",
7642881Smp153739 				       "-",
7652881Smp153739 				       &params.flags))
7662881Smp153739 		   break;
7672881Smp153739 	      sp = ep;
7682881Smp153739 	 }
7692881Smp153739 	 if (!sp)
7702881Smp153739 	      params.mask |= KADM5_CONFIG_FLAGS;
7712881Smp153739 	 krb5_xfree(svalue);
7722881Smp153739     } else {
7732881Smp153739 	 params.mask |= KADM5_CONFIG_FLAGS;
7742881Smp153739 	 params.flags = KRB5_KDB_DEF_FLAGS;
7752881Smp153739     }
7760Sstevel@tonic-gate 
7772881Smp153739     /* Get the value for the supported enctype/salttype matrix */
7782881Smp153739     hierarchy[2] = "supported_enctypes";
7792881Smp153739     if (params_in->mask & KADM5_CONFIG_ENCTYPES) {
7800Sstevel@tonic-gate 		params.mask |= KADM5_CONFIG_ENCTYPES;
7810Sstevel@tonic-gate 		if (params_in->num_keysalts > 0) {
7820Sstevel@tonic-gate 		    params.keysalts = malloc(params_in->num_keysalts *
7830Sstevel@tonic-gate 			    sizeof (*params.keysalts));
7840Sstevel@tonic-gate 		    if (params.keysalts == NULL) {
7850Sstevel@tonic-gate 			kret = ENOMEM;
7860Sstevel@tonic-gate 			goto cleanup;
7870Sstevel@tonic-gate 		    }
7880Sstevel@tonic-gate 		    (void) memcpy(params.keysalts, params_in->keysalts,
7890Sstevel@tonic-gate 			    (params_in->num_keysalts *
7900Sstevel@tonic-gate 			    sizeof (*params.keysalts)));
7912881Smp153739 		 params.num_keysalts = params_in->num_keysalts;
7922881Smp153739 	 }
7932881Smp153739     } else {
7942881Smp153739 	 svalue = NULL;
7952881Smp153739 	 if (aprofile)
7962881Smp153739 	      krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
7972881Smp153739 	 if (svalue == NULL)
7982881Smp153739 	     svalue = strdup(DEFAULT_ENCTYPE_LIST);
7990Sstevel@tonic-gate 
8002881Smp153739 	 params.keysalts = NULL;
8012881Smp153739 	 params.num_keysalts = 0;
8022881Smp153739 	 krb5_string_to_keysalts(svalue,
8032881Smp153739 				 ", \t",/* Tuple separators	*/
8042881Smp153739 				 ":.-",	/* Key/salt separators	*/
8052881Smp153739 				 0,	/* No duplicates	*/
8062881Smp153739 				 &params.keysalts,
8072881Smp153739 				 &params.num_keysalts);
8082881Smp153739 	 if (params.num_keysalts)
8092881Smp153739 	      params.mask |= KADM5_CONFIG_ENCTYPES;
8100Sstevel@tonic-gate 
8112881Smp153739 	 if (svalue)
8122881Smp153739 	      krb5_xfree(svalue);
8132881Smp153739     }
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 	hierarchy[2] = "kpasswd_server";
8160Sstevel@tonic-gate 	if (params_in->mask & KADM5_CONFIG_KPASSWD_SERVER) {
8170Sstevel@tonic-gate 		params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
8180Sstevel@tonic-gate 		params.kpasswd_server = strdup(params_in->kpasswd_server);
8190Sstevel@tonic-gate 	} else {
8200Sstevel@tonic-gate 		svalue = NULL;
8210Sstevel@tonic-gate 
8220Sstevel@tonic-gate 		if (aprofile)
8230Sstevel@tonic-gate 			krb5_aprof_get_string(aprofile, hierarchy,
8240Sstevel@tonic-gate 					    TRUE, &svalue);
8250Sstevel@tonic-gate 		if (svalue == NULL) {
8260Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
8270Sstevel@tonic-gate 			if (strcmp(envname, "KRB5_CONFIG") == 0) {
8280Sstevel@tonic-gate 				/*
8290Sstevel@tonic-gate 				 * Solaris Kerberos: only do DNS lookup for
8300Sstevel@tonic-gate 				 * kpasswd_server if this is a krb5.conf type of
8310Sstevel@tonic-gate 				 * config file.  Note, the filename may not be
8320Sstevel@tonic-gate 				 * /etc/krb5/krb5.conf so we assume that the
8330Sstevel@tonic-gate 				 * KRB5_CONFIG envname string will consistently
8340Sstevel@tonic-gate 				 * indicate the type of config file.
8350Sstevel@tonic-gate 				 */
8360Sstevel@tonic-gate 				dnsret = krb5_get_servername(context,
8370Sstevel@tonic-gate 				    &dns_realm, "_kpasswd", "_udp",
8380Sstevel@tonic-gate 				    dns_host, &dns_portno);
8390Sstevel@tonic-gate 
8400Sstevel@tonic-gate 				if (dnsret == 0) {
8410Sstevel@tonic-gate 					params.kpasswd_server =
8420Sstevel@tonic-gate 					    strdup(dns_host);
8430Sstevel@tonic-gate 					if (params.kpasswd_server) {
8440Sstevel@tonic-gate 						params.mask |=
8450Sstevel@tonic-gate 						    KADM5_CONFIG_KPASSWD_SERVER;
8460Sstevel@tonic-gate 					}
8470Sstevel@tonic-gate 					params.kpasswd_port = dns_portno;
8480Sstevel@tonic-gate 					params.mask |=
8490Sstevel@tonic-gate 					    KADM5_CONFIG_KPASSWD_PORT;
8500Sstevel@tonic-gate 				}
8510Sstevel@tonic-gate 			}
8520Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 			/*
8550Sstevel@tonic-gate 			 * If a unique 'kpasswd_server' is not specified,
8560Sstevel@tonic-gate 			 * use the normal 'admin_server'.
8570Sstevel@tonic-gate 			 */
8580Sstevel@tonic-gate 			if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) &&
8590Sstevel@tonic-gate 				    dnsret) {
8600Sstevel@tonic-gate 				params.kpasswd_server =
8610Sstevel@tonic-gate 					strdup(params.admin_server);
8620Sstevel@tonic-gate 				params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
8630Sstevel@tonic-gate 			}
8640Sstevel@tonic-gate 		} else {
8650Sstevel@tonic-gate 			char *p;
8660Sstevel@tonic-gate 			params.kpasswd_server = svalue;
8670Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 			if ((p = strchr(params.kpasswd_server, ':'))) {
8700Sstevel@tonic-gate 				params.kpasswd_port = atoi(p+1);
8710Sstevel@tonic-gate 				params.mask |= KADM5_CONFIG_KPASSWD_PORT;
8720Sstevel@tonic-gate 				*p = '\0';
8730Sstevel@tonic-gate 			}
8740Sstevel@tonic-gate 		}
8750Sstevel@tonic-gate 	}
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	hierarchy[2] = "kpasswd_protocol";
8780Sstevel@tonic-gate 
8790Sstevel@tonic-gate 	/* default to current RPCSEC_GSS protocol */
8800Sstevel@tonic-gate 	params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC;
8810Sstevel@tonic-gate 	params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate 	if (params_in->mask & KADM5_CONFIG_KPASSWD_PROTOCOL) {
8840Sstevel@tonic-gate 		params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
8850Sstevel@tonic-gate 		params.kpasswd_protocol = params_in->kpasswd_protocol;
8860Sstevel@tonic-gate 	} else {
8870Sstevel@tonic-gate 		svalue = NULL;
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate 		if (aprofile)
8900Sstevel@tonic-gate 			krb5_aprof_get_string(aprofile, hierarchy,
8910Sstevel@tonic-gate 					    TRUE, &svalue);
8920Sstevel@tonic-gate 		if (svalue != NULL) {
8930Sstevel@tonic-gate 			if (strcasecmp(svalue, "RPCSEC_GSS") == 0) {
8940Sstevel@tonic-gate 				params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC;
8950Sstevel@tonic-gate 				params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
8960Sstevel@tonic-gate 			} else if (strcasecmp(svalue, "SET_CHANGE") == 0) {
8970Sstevel@tonic-gate 				params.kpasswd_protocol =
8980Sstevel@tonic-gate 					KRB5_CHGPWD_CHANGEPW_V2;
8990Sstevel@tonic-gate 				params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
9000Sstevel@tonic-gate 			}
9010Sstevel@tonic-gate 		}
9020Sstevel@tonic-gate 		if (svalue)
9030Sstevel@tonic-gate 			krb5_xfree(svalue);
9040Sstevel@tonic-gate 	}
9050Sstevel@tonic-gate 
9060Sstevel@tonic-gate 	/*
9070Sstevel@tonic-gate 	 * If the kpasswd_port is not yet defined, define it now.
9080Sstevel@tonic-gate 	 */
9090Sstevel@tonic-gate 	if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) {
9100Sstevel@tonic-gate 		if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT)
9110Sstevel@tonic-gate 			params.kpasswd_port = params_in->kpasswd_port;
9120Sstevel@tonic-gate 		/*
9130Sstevel@tonic-gate 		 * If kpasswd_port is not explicitly defined,
9140Sstevel@tonic-gate 		 * determine the port to use based on the protocol.
9150Sstevel@tonic-gate 		 * The alternative protocol uses a different port
9160Sstevel@tonic-gate 		 * than the standard admind port.
9170Sstevel@tonic-gate 		 */
9180Sstevel@tonic-gate 		else if (params.kpasswd_protocol == KRB5_CHGPWD_RPCSEC) {
9190Sstevel@tonic-gate 			params.kpasswd_port = DEFAULT_KADM5_PORT;
9200Sstevel@tonic-gate 		} else {
9210Sstevel@tonic-gate 			/*
9220Sstevel@tonic-gate 			 * When using the Horowitz/IETF protocol for
9230Sstevel@tonic-gate 			 * password changing, the default port is 464
9240Sstevel@tonic-gate 			 * (officially recognized by IANA).
9250Sstevel@tonic-gate 			 */
9260Sstevel@tonic-gate 			params.kpasswd_port = DEFAULT_KPASSWD_PORT;
9270Sstevel@tonic-gate 		}
9280Sstevel@tonic-gate 		params.mask |= KADM5_CONFIG_KPASSWD_PORT;
9290Sstevel@tonic-gate 	}
9300Sstevel@tonic-gate 
9310Sstevel@tonic-gate 	hierarchy[2] = "sunw_dbprop_enable";
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	params.iprop_enabled = FALSE;
9340Sstevel@tonic-gate 	params.mask |= KADM5_CONFIG_IPROP_ENABLED;
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 	if (params_in->mask & KADM5_CONFIG_IPROP_ENABLED) {
9370Sstevel@tonic-gate 		params.mask |= KADM5_CONFIG_IPROP_ENABLED;
9380Sstevel@tonic-gate 		params.iprop_enabled = params_in->iprop_enabled;
9390Sstevel@tonic-gate 	} else {
9400Sstevel@tonic-gate 		if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy,
9410Sstevel@tonic-gate 		    TRUE, &svalue)) {
9420Sstevel@tonic-gate 			if (strncasecmp(svalue, "Y", 1) == 0)
9430Sstevel@tonic-gate 				params.iprop_enabled = TRUE;
9440Sstevel@tonic-gate 			if (strncasecmp(svalue, "true", 4) == 0)
9450Sstevel@tonic-gate 				params.iprop_enabled = TRUE;
9460Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_IPROP_ENABLED;
9470Sstevel@tonic-gate 			krb5_xfree(svalue);
9480Sstevel@tonic-gate 		}
9490Sstevel@tonic-gate 	}
9500Sstevel@tonic-gate 
9510Sstevel@tonic-gate 	hierarchy[2] = "sunw_dbprop_master_ulogsize";
9520Sstevel@tonic-gate 
9530Sstevel@tonic-gate 	params.iprop_ulogsize = DEF_ULOGENTRIES;
9540Sstevel@tonic-gate 	params.mask |= KADM5_CONFIG_ULOG_SIZE;
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate 	if (params_in->mask & KADM5_CONFIG_ULOG_SIZE) {
9570Sstevel@tonic-gate 		params.mask |= KADM5_CONFIG_ULOG_SIZE;
9580Sstevel@tonic-gate 		params.iprop_ulogsize = params_in->iprop_ulogsize;
9590Sstevel@tonic-gate 	} else {
9600Sstevel@tonic-gate 		if (aprofile && !krb5_aprof_get_int32(aprofile, hierarchy,
9610Sstevel@tonic-gate 		    TRUE, &ivalue)) {
9620Sstevel@tonic-gate 			if (ivalue > MAX_ULOGENTRIES)
9630Sstevel@tonic-gate 				params.iprop_ulogsize = MAX_ULOGENTRIES;
9640Sstevel@tonic-gate 			else if (ivalue <= 0)
9650Sstevel@tonic-gate 				params.iprop_ulogsize = DEF_ULOGENTRIES;
9660Sstevel@tonic-gate 			else
9670Sstevel@tonic-gate 				params.iprop_ulogsize = ivalue;
9680Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_ULOG_SIZE;
9690Sstevel@tonic-gate 		}
9700Sstevel@tonic-gate 	}
9710Sstevel@tonic-gate 
9720Sstevel@tonic-gate 	hierarchy[2] = "sunw_dbprop_slave_poll";
9730Sstevel@tonic-gate 
9746426Smp153739 	params.iprop_polltime = strdup("2m");
9756426Smp153739 	if (params.iprop_polltime)
9766426Smp153739 		params.mask |= KADM5_CONFIG_POLL_TIME;
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	if (params_in->mask & KADM5_CONFIG_POLL_TIME) {
9796426Smp153739 		if (params.iprop_polltime)
9806426Smp153739 			free(params.iprop_polltime);
9810Sstevel@tonic-gate 		params.iprop_polltime = strdup(params_in->iprop_polltime);
9820Sstevel@tonic-gate 		if (params.iprop_polltime)
9830Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_POLL_TIME;
9840Sstevel@tonic-gate 	} else {
9850Sstevel@tonic-gate 		if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy,
9860Sstevel@tonic-gate 		    TRUE, &svalue)) {
9876426Smp153739 			if (params.iprop_polltime)
9886426Smp153739 				free(params.iprop_polltime);
9890Sstevel@tonic-gate 			params.iprop_polltime = strdup(svalue);
9900Sstevel@tonic-gate 			params.mask |= KADM5_CONFIG_POLL_TIME;
9910Sstevel@tonic-gate 			krb5_xfree(svalue);
9920Sstevel@tonic-gate 		}
9930Sstevel@tonic-gate 	}
9940Sstevel@tonic-gate 
9950Sstevel@tonic-gate 	*params_out = params;
9960Sstevel@tonic-gate 
9970Sstevel@tonic-gate cleanup:
9982881Smp153739     if (aprofile)
9992881Smp153739 	krb5_aprof_finish(aprofile);
10002881Smp153739     if (kret) {
10012881Smp153739 	 kadm5_free_config_params(context, &params);
10022881Smp153739 	 params_out->mask = 0;
10032881Smp153739     }
10040Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
10050Sstevel@tonic-gate 	if (dns_realm.data)
10060Sstevel@tonic-gate 		free(dns_realm.data);
10070Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
10080Sstevel@tonic-gate 
10092881Smp153739     return(kret);
10100Sstevel@tonic-gate }
10110Sstevel@tonic-gate /*
10120Sstevel@tonic-gate  * kadm5_free_config_params()	- Free data allocated by above.
10130Sstevel@tonic-gate  */
10140Sstevel@tonic-gate /*ARGSUSED*/
10150Sstevel@tonic-gate krb5_error_code
kadm5_free_config_params(context,params)10160Sstevel@tonic-gate kadm5_free_config_params(context, params)
10172881Smp153739     krb5_context	context;
10182881Smp153739     kadm5_config_params	*params;
10190Sstevel@tonic-gate {
10202881Smp153739     if (params) {
1021*7934SMark.Phalan@Sun.COM 	if (params->dbname) {
1022*7934SMark.Phalan@Sun.COM 		krb5_xfree(params->dbname);
1023*7934SMark.Phalan@Sun.COM 		params->dbname = NULL;
1024*7934SMark.Phalan@Sun.COM 	}
1025*7934SMark.Phalan@Sun.COM 	if (params->mkey_name) {
1026*7934SMark.Phalan@Sun.COM 		krb5_xfree(params->mkey_name);
1027*7934SMark.Phalan@Sun.COM 		params->mkey_name = NULL;
1028*7934SMark.Phalan@Sun.COM 	}
1029*7934SMark.Phalan@Sun.COM 	if (params->stash_file) {
1030*7934SMark.Phalan@Sun.COM 		krb5_xfree(params->stash_file);
1031*7934SMark.Phalan@Sun.COM 		params->stash_file = NULL;
1032*7934SMark.Phalan@Sun.COM 	}
1033*7934SMark.Phalan@Sun.COM 	if (params->keysalts) {
1034*7934SMark.Phalan@Sun.COM 		krb5_xfree(params->keysalts);
1035*7934SMark.Phalan@Sun.COM 		params->keysalts = NULL;
1036*7934SMark.Phalan@Sun.COM 		params->num_keysalts = 0;
1037*7934SMark.Phalan@Sun.COM 	}
1038*7934SMark.Phalan@Sun.COM 	if (params->admin_keytab) {
1039*7934SMark.Phalan@Sun.COM 		free(params->admin_keytab);
1040*7934SMark.Phalan@Sun.COM 		params->admin_keytab = NULL;
1041*7934SMark.Phalan@Sun.COM 	}
1042*7934SMark.Phalan@Sun.COM 	if (params->dict_file) {
1043*7934SMark.Phalan@Sun.COM 		free(params->dict_file);
1044*7934SMark.Phalan@Sun.COM 		params->dict_file = NULL;
1045*7934SMark.Phalan@Sun.COM 	}
1046*7934SMark.Phalan@Sun.COM 	if (params->acl_file) {
1047*7934SMark.Phalan@Sun.COM 		free(params->acl_file);
1048*7934SMark.Phalan@Sun.COM 		params->acl_file = NULL;
1049*7934SMark.Phalan@Sun.COM 	}
1050*7934SMark.Phalan@Sun.COM 	if (params->realm) {
1051*7934SMark.Phalan@Sun.COM 		free(params->realm);
1052*7934SMark.Phalan@Sun.COM 		params->realm = NULL;
1053*7934SMark.Phalan@Sun.COM 	}
1054*7934SMark.Phalan@Sun.COM 	if (params->admin_dbname) {
1055*7934SMark.Phalan@Sun.COM 		free(params->admin_dbname);
1056*7934SMark.Phalan@Sun.COM 		params->admin_dbname = NULL;
1057*7934SMark.Phalan@Sun.COM 	}
1058*7934SMark.Phalan@Sun.COM 	if (params->admin_lockfile) {
1059*7934SMark.Phalan@Sun.COM 		free(params->admin_lockfile);
1060*7934SMark.Phalan@Sun.COM 		params->admin_lockfile = NULL;
1061*7934SMark.Phalan@Sun.COM 	}
1062*7934SMark.Phalan@Sun.COM 	if (params->admin_server) {
1063*7934SMark.Phalan@Sun.COM 		free(params->admin_server);
1064*7934SMark.Phalan@Sun.COM 		params->admin_server = NULL;
1065*7934SMark.Phalan@Sun.COM 	}
1066*7934SMark.Phalan@Sun.COM 	if (params->kpasswd_server) {
1067*7934SMark.Phalan@Sun.COM 		free(params->kpasswd_server);
1068*7934SMark.Phalan@Sun.COM 		params->kpasswd_server = NULL;
1069*7934SMark.Phalan@Sun.COM 	}
1070*7934SMark.Phalan@Sun.COM 	if (params->iprop_polltime) {
1071*7934SMark.Phalan@Sun.COM 		free(params->iprop_polltime);
1072*7934SMark.Phalan@Sun.COM 		params->iprop_polltime = NULL;
1073*7934SMark.Phalan@Sun.COM 	}
10740Sstevel@tonic-gate 	}
10750Sstevel@tonic-gate 	return (0);
10760Sstevel@tonic-gate }
10770Sstevel@tonic-gate 
10782881Smp153739 krb5_error_code
kadm5_get_admin_service_name(krb5_context ctx,char * realm_in,char * admin_name,size_t maxlen)10792881Smp153739 kadm5_get_admin_service_name(krb5_context ctx,
10802881Smp153739 			     char *realm_in,
10812881Smp153739 			     char *admin_name,
10822881Smp153739 			     size_t maxlen)
10832881Smp153739 {
10842881Smp153739     krb5_error_code ret;
10852881Smp153739     kadm5_config_params params_in, params_out;
10862881Smp153739     struct hostent *hp;
10872881Smp153739 
10882881Smp153739     memset(&params_in, 0, sizeof(params_in));
10892881Smp153739     memset(&params_out, 0, sizeof(params_out));
10902881Smp153739 
10912881Smp153739     params_in.mask |= KADM5_CONFIG_REALM;
10922881Smp153739     params_in.realm = realm_in;
1093*7934SMark.Phalan@Sun.COM     ret = kadm5_get_config_params(ctx, 0, &params_in, &params_out);
10942881Smp153739     if (ret)
10952881Smp153739 	return ret;
10962881Smp153739 
10972881Smp153739     if (!(params_out.mask & KADM5_CONFIG_ADMIN_SERVER)) {
10982881Smp153739 	ret = KADM5_MISSING_KRB5_CONF_PARAMS;
10992881Smp153739 	goto err_params;
11002881Smp153739     }
11012881Smp153739 
11022881Smp153739     hp = gethostbyname(params_out.admin_server);
11032881Smp153739     if (hp == NULL) {
11042881Smp153739 	ret = errno;
11052881Smp153739 	goto err_params;
11062881Smp153739     }
11072881Smp153739     if (strlen(hp->h_name) + sizeof("kadmin/") > maxlen) {
11082881Smp153739 	ret = ENOMEM;
11092881Smp153739 	goto err_params;
11102881Smp153739     }
11112881Smp153739     sprintf(admin_name, "kadmin/%s", hp->h_name);
11122881Smp153739 
11132881Smp153739 err_params:
11142881Smp153739     kadm5_free_config_params(ctx, &params_out);
11152881Smp153739     return ret;
11162881Smp153739 }
11172881Smp153739 
11182881Smp153739 /***********************************************************************
11190Sstevel@tonic-gate  * This is the old krb5_realm_read_params, which I mutated into
11202881Smp153739  * kadm5_get_config_params but which old code (kdb5_* and krb5kdc)
11210Sstevel@tonic-gate  * still uses.
11222881Smp153739  ***********************************************************************/
11230Sstevel@tonic-gate 
11240Sstevel@tonic-gate /*
11250Sstevel@tonic-gate  * krb5_read_realm_params()	- Read per-realm parameters from KDC
11260Sstevel@tonic-gate  *				  alternate profile.
11270Sstevel@tonic-gate  */
11280Sstevel@tonic-gate krb5_error_code
krb5_read_realm_params(kcontext,realm,rparamp)1129*7934SMark.Phalan@Sun.COM krb5_read_realm_params(kcontext, realm, rparamp)
11302881Smp153739     krb5_context	kcontext;
11312881Smp153739     char		*realm;
11322881Smp153739     krb5_realm_params	**rparamp;
11330Sstevel@tonic-gate {
11342881Smp153739     char		*filename;
11352881Smp153739     char		*envname;
11362881Smp153739     char		*lrealm;
11372881Smp153739     krb5_pointer	aprofile = 0;
11382881Smp153739     krb5_realm_params	*rparams;
11392881Smp153739     const char		*hierarchy[4];
11402881Smp153739     char		*svalue;
11412881Smp153739     krb5_int32		ivalue;
11422881Smp153739     krb5_boolean	bvalue;
11432881Smp153739     krb5_deltat		dtvalue;
11440Sstevel@tonic-gate 
1145*7934SMark.Phalan@Sun.COM     char		*kdcprofile = 0;
1146*7934SMark.Phalan@Sun.COM     char		*kdcenv = 0;
1147*7934SMark.Phalan@Sun.COM 
11482881Smp153739     krb5_error_code	kret;
11490Sstevel@tonic-gate 
11502881Smp153739     filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
11512881Smp153739     envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV;
11520Sstevel@tonic-gate 
11532881Smp153739     if (kcontext->profile_secure == TRUE) envname = 0;
11540Sstevel@tonic-gate 
11552881Smp153739     rparams = (krb5_realm_params *) NULL;
11562881Smp153739     if (realm)
11572881Smp153739 	lrealm = strdup(realm);
11582881Smp153739     else {
11592881Smp153739 	kret = krb5_get_default_realm(kcontext, &lrealm);
11602881Smp153739 	if (kret)
11612881Smp153739 	    goto cleanup;
11622881Smp153739     }
11630Sstevel@tonic-gate 
11642881Smp153739     kret = krb5_aprof_init(filename, envname, &aprofile);
11652881Smp153739     if (kret)
11662881Smp153739 	goto cleanup;
11672881Smp153739 
11682881Smp153739     rparams = (krb5_realm_params *) malloc(sizeof(krb5_realm_params));
11692881Smp153739     if (rparams == 0) {
11702881Smp153739 	kret = ENOMEM;
11712881Smp153739 	goto cleanup;
11722881Smp153739     }
11730Sstevel@tonic-gate 
11742881Smp153739     /* Initialize realm parameters */
11752881Smp153739     memset((char *) rparams, 0, sizeof(krb5_realm_params));
11760Sstevel@tonic-gate 
11772881Smp153739     /* Get the value for the database */
11782881Smp153739     hierarchy[0] = "realms";
11792881Smp153739     hierarchy[1] = lrealm;
11802881Smp153739     hierarchy[2] = "database_name";
11812881Smp153739     hierarchy[3] = (char *) NULL;
11822881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
11832881Smp153739 	rparams->realm_dbname = svalue;
11842881Smp153739 
11852881Smp153739     /* Get the value for the KDC port list */
11862881Smp153739     hierarchy[2] = "kdc_ports";
11872881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
11882881Smp153739 	rparams->realm_kdc_ports = svalue;
11892881Smp153739     hierarchy[2] = "kdc_tcp_ports";
11902881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
11912881Smp153739 	rparams->realm_kdc_tcp_ports = svalue;
11920Sstevel@tonic-gate 
11932881Smp153739     /* Get the name of the acl file */
11942881Smp153739     hierarchy[2] = "acl_file";
11952881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
11962881Smp153739 	rparams->realm_acl_file = svalue;
11972881Smp153739 
11982881Smp153739     /* Get the value for the kadmind port */
11992881Smp153739     hierarchy[2] = "kadmind_port";
12002881Smp153739     if (!krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
12012881Smp153739 	rparams->realm_kadmind_port = ivalue;
12022881Smp153739 	rparams->realm_kadmind_port_valid = 1;
12032881Smp153739     }
12042881Smp153739 
12052881Smp153739     /* Get the value for the master key name */
12062881Smp153739     hierarchy[2] = "master_key_name";
12072881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
12082881Smp153739 	rparams->realm_mkey_name = svalue;
12092881Smp153739 
12102881Smp153739     /* Get the value for the master key type */
12112881Smp153739     hierarchy[2] = "master_key_type";
12122881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
12132881Smp153739 	if (!krb5_string_to_enctype(svalue, &rparams->realm_enctype))
12142881Smp153739 	    rparams->realm_enctype_valid = 1;
12152881Smp153739 	krb5_xfree(svalue);
12162881Smp153739     }
12172881Smp153739 
12182881Smp153739     /* Get the value for the stashfile */
12192881Smp153739     hierarchy[2] = "key_stash_file";
12202881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
12212881Smp153739 	rparams->realm_stash_file = svalue;
12222881Smp153739 
12232881Smp153739     /* Get the value for maximum ticket lifetime. */
12242881Smp153739     hierarchy[2] = "max_life";
12252881Smp153739     if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
12262881Smp153739 	rparams->realm_max_life = dtvalue;
12272881Smp153739 	rparams->realm_max_life_valid = 1;
12282881Smp153739     }
12292881Smp153739 
12302881Smp153739     /* Get the value for maximum renewable ticket lifetime. */
12312881Smp153739     hierarchy[2] = "max_renewable_life";
12322881Smp153739     if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
12332881Smp153739 	rparams->realm_max_rlife = dtvalue;
12342881Smp153739 	rparams->realm_max_rlife_valid = 1;
12352881Smp153739     }
12362881Smp153739 
12372881Smp153739     /* Get the value for the default principal expiration */
12382881Smp153739     hierarchy[2] = "default_principal_expiration";
12392881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
12402881Smp153739 	if (!krb5_string_to_timestamp(svalue,
12412881Smp153739 				      &rparams->realm_expiration))
12422881Smp153739 	    rparams->realm_expiration_valid = 1;
12432881Smp153739 	krb5_xfree(svalue);
12442881Smp153739     }
12450Sstevel@tonic-gate 
12462881Smp153739     hierarchy[2] = "reject_bad_transit";
12472881Smp153739     if (!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
12482881Smp153739 	rparams->realm_reject_bad_transit = bvalue;
12492881Smp153739 	rparams->realm_reject_bad_transit_valid = 1;
12502881Smp153739     }
12510Sstevel@tonic-gate 
12522881Smp153739     /* Get the value for the default principal flags */
12532881Smp153739     hierarchy[2] = "default_principal_flags";
12542881Smp153739     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
12552881Smp153739 	char *sp, *ep, *tp;
12560Sstevel@tonic-gate 
12572881Smp153739 	sp = svalue;
12582881Smp153739 	rparams->realm_flags = 0;
12592881Smp153739 	while (sp) {
12602881Smp153739 	    if ((ep = strchr(sp, (int) ',')) ||
12612881Smp153739 		(ep = strchr(sp, (int) ' ')) ||
12622881Smp153739 		(ep = strchr(sp, (int) '\t'))) {
12632881Smp153739 		/* Fill in trailing whitespace of sp */
12642881Smp153739 		tp = ep - 1;
12652881Smp153739 		while (isspace((int) *tp) && (tp < sp)) {
12662881Smp153739 		    *tp = '\0';
12672881Smp153739 		    tp--;
12680Sstevel@tonic-gate 		}
12692881Smp153739 		*ep = '\0';
12702881Smp153739 		ep++;
12712881Smp153739 		/* Skip over trailing whitespace of ep */
12722881Smp153739 		while (isspace((int) *ep) && (*ep)) ep++;
12732881Smp153739 	    }
12742881Smp153739 	    /* Convert this flag */
12752881Smp153739 	    if (krb5_string_to_flags(sp,
12762881Smp153739 				     "+",
12772881Smp153739 				     "-",
12782881Smp153739 				     &rparams->realm_flags))
12792881Smp153739 		break;
12802881Smp153739 	    sp = ep;
12810Sstevel@tonic-gate 	}
12822881Smp153739 	if (!sp)
12832881Smp153739 	    rparams->realm_flags_valid = 1;
12842881Smp153739 	krb5_xfree(svalue);
12852881Smp153739     }
12860Sstevel@tonic-gate 
12870Sstevel@tonic-gate 	/* Get the value for the supported enctype/salttype matrix */
12880Sstevel@tonic-gate 	/*
12890Sstevel@tonic-gate 	 * SUNWresync121
12900Sstevel@tonic-gate 	 * Solaris kerberos: updated this code to support default values for
12910Sstevel@tonic-gate 	 * the supported_enctypes.
12920Sstevel@tonic-gate 	 */
12930Sstevel@tonic-gate 	hierarchy[2] = "supported_enctypes";
12940Sstevel@tonic-gate 	svalue = NULL;
12950Sstevel@tonic-gate 	krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
12960Sstevel@tonic-gate 
12970Sstevel@tonic-gate 	/*
12980Sstevel@tonic-gate 	 * Set the default value if supported_enctypes was not explicitly
12990Sstevel@tonic-gate 	 * set in the kdc.conf.
13000Sstevel@tonic-gate 	 */
13010Sstevel@tonic-gate 	if (svalue == NULL) {
13020Sstevel@tonic-gate 	    svalue = strdup(DEFAULT_ENCTYPE_LIST);
13030Sstevel@tonic-gate 	}
13040Sstevel@tonic-gate 	if (svalue != NULL) {
13050Sstevel@tonic-gate 	    krb5_string_to_keysalts(svalue,
13060Sstevel@tonic-gate 				    ", \t",	/* Tuple separators	*/
13070Sstevel@tonic-gate 				    ":.-",	/* Key/salt separators	*/
13080Sstevel@tonic-gate 				    0,	/* No duplicates	*/
13090Sstevel@tonic-gate 				    &rparams->realm_keysalts,
13100Sstevel@tonic-gate 				    &rparams->realm_num_keysalts);
13110Sstevel@tonic-gate 	    krb5_xfree(svalue);
13120Sstevel@tonic-gate 	    svalue = NULL;
13130Sstevel@tonic-gate 	}
13140Sstevel@tonic-gate cleanup:
13152881Smp153739     if (aprofile)
13162881Smp153739 	krb5_aprof_finish(aprofile);
13172881Smp153739     if (lrealm)
13182881Smp153739 	free(lrealm);
13192881Smp153739     if (kret) {
13202881Smp153739 	if (rparams)
13212881Smp153739 	    krb5_free_realm_params(kcontext, rparams);
13222881Smp153739 	rparams = 0;
13232881Smp153739     }
13242881Smp153739     *rparamp = rparams;
13252881Smp153739     return(kret);
13260Sstevel@tonic-gate }
13270Sstevel@tonic-gate 
13280Sstevel@tonic-gate /*
13290Sstevel@tonic-gate  * krb5_free_realm_params()	- Free data allocated by above.
13300Sstevel@tonic-gate  */
13310Sstevel@tonic-gate krb5_error_code
krb5_free_realm_params(kcontext,rparams)13320Sstevel@tonic-gate krb5_free_realm_params(kcontext, rparams)
13332881Smp153739     krb5_context	kcontext;
13342881Smp153739     krb5_realm_params	*rparams;
13350Sstevel@tonic-gate {
13362881Smp153739     if (rparams) {
13372881Smp153739 	if (rparams->realm_profile)
13382881Smp153739 	    krb5_xfree(rparams->realm_profile);
13392881Smp153739 	if (rparams->realm_dbname)
13402881Smp153739 	    krb5_xfree(rparams->realm_dbname);
13412881Smp153739 	if (rparams->realm_mkey_name)
13422881Smp153739 	    krb5_xfree(rparams->realm_mkey_name);
13432881Smp153739 	if (rparams->realm_stash_file)
13442881Smp153739 	    krb5_xfree(rparams->realm_stash_file);
13452881Smp153739 	if (rparams->realm_keysalts)
13462881Smp153739 	    krb5_xfree(rparams->realm_keysalts);
13472881Smp153739 	if (rparams->realm_kdc_ports)
13482881Smp153739 	    krb5_xfree(rparams->realm_kdc_ports);
13492881Smp153739 	if (rparams->realm_kdc_tcp_ports)
13502881Smp153739 	    krb5_xfree(rparams->realm_kdc_tcp_ports);
13512881Smp153739 	if (rparams->realm_acl_file)
13522881Smp153739 	    krb5_xfree(rparams->realm_acl_file);
13532881Smp153739 	krb5_xfree(rparams);
13542881Smp153739     }
13552881Smp153739     return(0);
13560Sstevel@tonic-gate }
13572881Smp153739 
1358