xref: /onnv-gate/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_profile.c (revision 7934:6aeeafc994de)
1*7934SMark.Phalan@Sun.COM /*
2*7934SMark.Phalan@Sun.COM  * COPYRIGHT (C) 2006,2007
3*7934SMark.Phalan@Sun.COM  * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
4*7934SMark.Phalan@Sun.COM  * ALL RIGHTS RESERVED
5*7934SMark.Phalan@Sun.COM  *
6*7934SMark.Phalan@Sun.COM  * Permission is granted to use, copy, create derivative works
7*7934SMark.Phalan@Sun.COM  * and redistribute this software and such derivative works
8*7934SMark.Phalan@Sun.COM  * for any purpose, so long as the name of The University of
9*7934SMark.Phalan@Sun.COM  * Michigan is not used in any advertising or publicity
10*7934SMark.Phalan@Sun.COM  * pertaining to the use of distribution of this software
11*7934SMark.Phalan@Sun.COM  * without specific, written prior authorization.  If the
12*7934SMark.Phalan@Sun.COM  * above copyright notice or any other identification of the
13*7934SMark.Phalan@Sun.COM  * University of Michigan is included in any copy of any
14*7934SMark.Phalan@Sun.COM  * portion of this software, then the disclaimer below must
15*7934SMark.Phalan@Sun.COM  * also be included.
16*7934SMark.Phalan@Sun.COM  *
17*7934SMark.Phalan@Sun.COM  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
18*7934SMark.Phalan@Sun.COM  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
19*7934SMark.Phalan@Sun.COM  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
20*7934SMark.Phalan@Sun.COM  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
21*7934SMark.Phalan@Sun.COM  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
22*7934SMark.Phalan@Sun.COM  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
23*7934SMark.Phalan@Sun.COM  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
24*7934SMark.Phalan@Sun.COM  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
25*7934SMark.Phalan@Sun.COM  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
26*7934SMark.Phalan@Sun.COM  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
27*7934SMark.Phalan@Sun.COM  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
28*7934SMark.Phalan@Sun.COM  * SUCH DAMAGES.
29*7934SMark.Phalan@Sun.COM  */
30*7934SMark.Phalan@Sun.COM 
31*7934SMark.Phalan@Sun.COM #include <stdio.h>
32*7934SMark.Phalan@Sun.COM #include <stdlib.h>
33*7934SMark.Phalan@Sun.COM #include <errno.h>
34*7934SMark.Phalan@Sun.COM #include <string.h>
35*7934SMark.Phalan@Sun.COM 
36*7934SMark.Phalan@Sun.COM #include "k5-int.h"
37*7934SMark.Phalan@Sun.COM #include "pkinit.h"
38*7934SMark.Phalan@Sun.COM 
39*7934SMark.Phalan@Sun.COM /*
40*7934SMark.Phalan@Sun.COM  * Routines for handling profile [config file] options
41*7934SMark.Phalan@Sun.COM  */
42*7934SMark.Phalan@Sun.COM 
43*7934SMark.Phalan@Sun.COM /* Forward prototypes */
44*7934SMark.Phalan@Sun.COM static int _krb5_conf_boolean(const char *s);
45*7934SMark.Phalan@Sun.COM 
46*7934SMark.Phalan@Sun.COM /*
47*7934SMark.Phalan@Sun.COM  * XXX
48*7934SMark.Phalan@Sun.COM  * The following is duplicated verbatim from src/lib/krb5/krb/get_in_tkt.c,
49*7934SMark.Phalan@Sun.COM  * which is duplicated from somewhere else. :-/
50*7934SMark.Phalan@Sun.COM  * XXX
51*7934SMark.Phalan@Sun.COM  */
52*7934SMark.Phalan@Sun.COM static const char *const conf_yes[] = {
53*7934SMark.Phalan@Sun.COM     "y", "yes", "true", "t", "1", "on",
54*7934SMark.Phalan@Sun.COM     0,
55*7934SMark.Phalan@Sun.COM };
56*7934SMark.Phalan@Sun.COM 
57*7934SMark.Phalan@Sun.COM static const char *const conf_no[] = {
58*7934SMark.Phalan@Sun.COM     "n", "no", "false", "nil", "0", "off",
59*7934SMark.Phalan@Sun.COM     0,
60*7934SMark.Phalan@Sun.COM };
61*7934SMark.Phalan@Sun.COM 
62*7934SMark.Phalan@Sun.COM static int
_krb5_conf_boolean(const char * s)63*7934SMark.Phalan@Sun.COM _krb5_conf_boolean(const char *s)
64*7934SMark.Phalan@Sun.COM {
65*7934SMark.Phalan@Sun.COM     const char *const *p;
66*7934SMark.Phalan@Sun.COM 
67*7934SMark.Phalan@Sun.COM     for(p=conf_yes; *p; p++) {
68*7934SMark.Phalan@Sun.COM 	if (strcasecmp(*p,s) == 0)
69*7934SMark.Phalan@Sun.COM 	    return 1;
70*7934SMark.Phalan@Sun.COM     }
71*7934SMark.Phalan@Sun.COM 
72*7934SMark.Phalan@Sun.COM     for(p=conf_no; *p; p++) {
73*7934SMark.Phalan@Sun.COM 	if (strcasecmp(*p,s) == 0)
74*7934SMark.Phalan@Sun.COM 	    return 0;
75*7934SMark.Phalan@Sun.COM     }
76*7934SMark.Phalan@Sun.COM 
77*7934SMark.Phalan@Sun.COM     /* Default to "no" */
78*7934SMark.Phalan@Sun.COM     return 0;
79*7934SMark.Phalan@Sun.COM }
80*7934SMark.Phalan@Sun.COM 
81*7934SMark.Phalan@Sun.COM /*
82*7934SMark.Phalan@Sun.COM  * XXX
83*7934SMark.Phalan@Sun.COM  * End duplicated code from src/lib/krb5/krb/get_in_tkt.c
84*7934SMark.Phalan@Sun.COM  * XXX
85*7934SMark.Phalan@Sun.COM  */
86*7934SMark.Phalan@Sun.COM 
87*7934SMark.Phalan@Sun.COM /*
88*7934SMark.Phalan@Sun.COM  * The following are based on krb5_libdefault_* functions in
89*7934SMark.Phalan@Sun.COM  * src/lib/krb5/krb/get_in_tkt.c
90*7934SMark.Phalan@Sun.COM  * N.B.  This assumes that context->default_realm has
91*7934SMark.Phalan@Sun.COM  * already been established.
92*7934SMark.Phalan@Sun.COM  */
93*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_kdcdefault_strings(krb5_context context,const char * realmname,const char * option,char *** ret_value)94*7934SMark.Phalan@Sun.COM pkinit_kdcdefault_strings(krb5_context context, const char *realmname,
95*7934SMark.Phalan@Sun.COM 			  const char *option, char ***ret_value)
96*7934SMark.Phalan@Sun.COM {
97*7934SMark.Phalan@Sun.COM     profile_t profile = NULL;
98*7934SMark.Phalan@Sun.COM     const char *names[5];
99*7934SMark.Phalan@Sun.COM     char **values = NULL;
100*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
101*7934SMark.Phalan@Sun.COM 
102*7934SMark.Phalan@Sun.COM     if (context == NULL)
103*7934SMark.Phalan@Sun.COM 	return KV5M_CONTEXT;
104*7934SMark.Phalan@Sun.COM 
105*7934SMark.Phalan@Sun.COM     profile = context->profile;
106*7934SMark.Phalan@Sun.COM 
107*7934SMark.Phalan@Sun.COM     if (realmname != NULL) {
108*7934SMark.Phalan@Sun.COM 	/*
109*7934SMark.Phalan@Sun.COM 	 * Try number one:
110*7934SMark.Phalan@Sun.COM 	 *
111*7934SMark.Phalan@Sun.COM 	 * [realms]
112*7934SMark.Phalan@Sun.COM 	 *	    REALM = {
113*7934SMark.Phalan@Sun.COM 	 *		option = <value>
114*7934SMark.Phalan@Sun.COM 	 *	    }
115*7934SMark.Phalan@Sun.COM 	 */
116*7934SMark.Phalan@Sun.COM 
117*7934SMark.Phalan@Sun.COM 	names[0] = "realms";
118*7934SMark.Phalan@Sun.COM 	names[1] = realmname;
119*7934SMark.Phalan@Sun.COM 	names[2] = option;
120*7934SMark.Phalan@Sun.COM 	names[3] = 0;
121*7934SMark.Phalan@Sun.COM 	retval = profile_get_values(profile, names, &values);
122*7934SMark.Phalan@Sun.COM 	if (retval == 0 && values != NULL)
123*7934SMark.Phalan@Sun.COM 	    goto goodbye;
124*7934SMark.Phalan@Sun.COM     }
125*7934SMark.Phalan@Sun.COM 
126*7934SMark.Phalan@Sun.COM     /*
127*7934SMark.Phalan@Sun.COM      * Try number two:
128*7934SMark.Phalan@Sun.COM      *
129*7934SMark.Phalan@Sun.COM      * [kdcdefaults]
130*7934SMark.Phalan@Sun.COM      *	    option = <value>
131*7934SMark.Phalan@Sun.COM      */
132*7934SMark.Phalan@Sun.COM 
133*7934SMark.Phalan@Sun.COM     names[0] = "kdcdefaults";
134*7934SMark.Phalan@Sun.COM     names[1] = option;
135*7934SMark.Phalan@Sun.COM     names[2] = 0;
136*7934SMark.Phalan@Sun.COM     retval = profile_get_values(profile, names, &values);
137*7934SMark.Phalan@Sun.COM     if (retval == 0 && values != NULL)
138*7934SMark.Phalan@Sun.COM 	goto goodbye;
139*7934SMark.Phalan@Sun.COM 
140*7934SMark.Phalan@Sun.COM goodbye:
141*7934SMark.Phalan@Sun.COM     if (values == NULL)
142*7934SMark.Phalan@Sun.COM 	retval = ENOENT;
143*7934SMark.Phalan@Sun.COM 
144*7934SMark.Phalan@Sun.COM     *ret_value = values;
145*7934SMark.Phalan@Sun.COM 
146*7934SMark.Phalan@Sun.COM     return retval;
147*7934SMark.Phalan@Sun.COM 
148*7934SMark.Phalan@Sun.COM }
149*7934SMark.Phalan@Sun.COM 
150*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_kdcdefault_string(krb5_context context,const char * realmname,const char * option,char ** ret_value)151*7934SMark.Phalan@Sun.COM pkinit_kdcdefault_string(krb5_context context, const char *realmname,
152*7934SMark.Phalan@Sun.COM 			 const char *option, char **ret_value)
153*7934SMark.Phalan@Sun.COM {
154*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
155*7934SMark.Phalan@Sun.COM     char **values = NULL;
156*7934SMark.Phalan@Sun.COM 
157*7934SMark.Phalan@Sun.COM     retval = pkinit_kdcdefault_strings(context, realmname, option, &values);
158*7934SMark.Phalan@Sun.COM     if (retval)
159*7934SMark.Phalan@Sun.COM 	return retval;
160*7934SMark.Phalan@Sun.COM 
161*7934SMark.Phalan@Sun.COM     if (values[0] == NULL) {
162*7934SMark.Phalan@Sun.COM 	retval = ENOENT;
163*7934SMark.Phalan@Sun.COM     } else {
164*7934SMark.Phalan@Sun.COM 	*ret_value = malloc(strlen(values[0]) + 1);
165*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
166*7934SMark.Phalan@Sun.COM 	if (*ret_value == NULL) {
167*7934SMark.Phalan@Sun.COM 	    pkiDebug(error_message(ENOMEM));
168*7934SMark.Phalan@Sun.COM 	    retval = ENOMEM;
169*7934SMark.Phalan@Sun.COM 	}
170*7934SMark.Phalan@Sun.COM 	else /* Solaris Kerberos */
171*7934SMark.Phalan@Sun.COM 	    (void) strlcpy(*ret_value, values[0], strlen(values[0]) + 1);
172*7934SMark.Phalan@Sun.COM     }
173*7934SMark.Phalan@Sun.COM 
174*7934SMark.Phalan@Sun.COM     profile_free_list(values);
175*7934SMark.Phalan@Sun.COM     return retval;
176*7934SMark.Phalan@Sun.COM }
177*7934SMark.Phalan@Sun.COM 
178*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_kdcdefault_boolean(krb5_context context,const char * realmname,const char * option,int default_value,int * ret_value)179*7934SMark.Phalan@Sun.COM pkinit_kdcdefault_boolean(krb5_context context, const char *realmname,
180*7934SMark.Phalan@Sun.COM 			  const char *option, int default_value, int *ret_value)
181*7934SMark.Phalan@Sun.COM {
182*7934SMark.Phalan@Sun.COM     char *string = NULL;
183*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
184*7934SMark.Phalan@Sun.COM 
185*7934SMark.Phalan@Sun.COM     retval = pkinit_kdcdefault_string(context, realmname, option, &string);
186*7934SMark.Phalan@Sun.COM 
187*7934SMark.Phalan@Sun.COM     if (retval == 0) {
188*7934SMark.Phalan@Sun.COM 	*ret_value = _krb5_conf_boolean(string);
189*7934SMark.Phalan@Sun.COM 	free(string);
190*7934SMark.Phalan@Sun.COM     } else
191*7934SMark.Phalan@Sun.COM 	*ret_value = default_value;
192*7934SMark.Phalan@Sun.COM 
193*7934SMark.Phalan@Sun.COM     return 0;
194*7934SMark.Phalan@Sun.COM }
195*7934SMark.Phalan@Sun.COM 
196*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_kdcdefault_integer(krb5_context context,const char * realmname,const char * option,int default_value,int * ret_value)197*7934SMark.Phalan@Sun.COM pkinit_kdcdefault_integer(krb5_context context, const char *realmname,
198*7934SMark.Phalan@Sun.COM 			  const char *option, int default_value, int *ret_value)
199*7934SMark.Phalan@Sun.COM {
200*7934SMark.Phalan@Sun.COM     char *string = NULL;
201*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
202*7934SMark.Phalan@Sun.COM 
203*7934SMark.Phalan@Sun.COM     retval = pkinit_kdcdefault_string(context, realmname, option, &string);
204*7934SMark.Phalan@Sun.COM 
205*7934SMark.Phalan@Sun.COM     if (retval == 0) {
206*7934SMark.Phalan@Sun.COM 	char *endptr;
207*7934SMark.Phalan@Sun.COM 	long l;
208*7934SMark.Phalan@Sun.COM 	l = strtol(string, &endptr, 0);
209*7934SMark.Phalan@Sun.COM 	if (endptr == string)
210*7934SMark.Phalan@Sun.COM 	    *ret_value = default_value;
211*7934SMark.Phalan@Sun.COM 	else
212*7934SMark.Phalan@Sun.COM 	    *ret_value = l;
213*7934SMark.Phalan@Sun.COM 	free(string);
214*7934SMark.Phalan@Sun.COM     } else
215*7934SMark.Phalan@Sun.COM 	*ret_value = default_value;
216*7934SMark.Phalan@Sun.COM 
217*7934SMark.Phalan@Sun.COM     return 0;
218*7934SMark.Phalan@Sun.COM }
219*7934SMark.Phalan@Sun.COM 
220*7934SMark.Phalan@Sun.COM 
221*7934SMark.Phalan@Sun.COM /*
222*7934SMark.Phalan@Sun.COM  * krb5_libdefault_string() is defined as static in
223*7934SMark.Phalan@Sun.COM  * src/lib/krb5/krb/get_in_tkt.c.  Create local versions of
224*7934SMark.Phalan@Sun.COM  * krb5_libdefault_* functions here.  We need a libdefaults_strings()
225*7934SMark.Phalan@Sun.COM  * function which is not currently supported there anyway.  Also,
226*7934SMark.Phalan@Sun.COM  * add the ability to supply a default value for the boolean and
227*7934SMark.Phalan@Sun.COM  * integer functions.
228*7934SMark.Phalan@Sun.COM  */
229*7934SMark.Phalan@Sun.COM 
230*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_libdefault_strings(krb5_context context,const krb5_data * realm,const char * option,char *** ret_value)231*7934SMark.Phalan@Sun.COM pkinit_libdefault_strings(krb5_context context, const krb5_data *realm,
232*7934SMark.Phalan@Sun.COM 			  const char *option, char ***ret_value)
233*7934SMark.Phalan@Sun.COM {
234*7934SMark.Phalan@Sun.COM     profile_t profile;
235*7934SMark.Phalan@Sun.COM     const char *names[5];
236*7934SMark.Phalan@Sun.COM     char **values = NULL;
237*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
238*7934SMark.Phalan@Sun.COM     char realmstr[1024];
239*7934SMark.Phalan@Sun.COM 
240*7934SMark.Phalan@Sun.COM     if (realm != NULL && realm->length > sizeof(realmstr)-1)
241*7934SMark.Phalan@Sun.COM 	return EINVAL;
242*7934SMark.Phalan@Sun.COM 
243*7934SMark.Phalan@Sun.COM     if (realm != NULL) {
244*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
245*7934SMark.Phalan@Sun.COM 	(void) strlcpy(realmstr, realm->data, realm->length + 1);
246*7934SMark.Phalan@Sun.COM 	realmstr[realm->length] = '\0';
247*7934SMark.Phalan@Sun.COM     }
248*7934SMark.Phalan@Sun.COM 
249*7934SMark.Phalan@Sun.COM     if (!context || (context->magic != KV5M_CONTEXT))
250*7934SMark.Phalan@Sun.COM 	return KV5M_CONTEXT;
251*7934SMark.Phalan@Sun.COM 
252*7934SMark.Phalan@Sun.COM     profile = context->profile;
253*7934SMark.Phalan@Sun.COM 
254*7934SMark.Phalan@Sun.COM 
255*7934SMark.Phalan@Sun.COM     if (realm != NULL) {
256*7934SMark.Phalan@Sun.COM 	/*
257*7934SMark.Phalan@Sun.COM 	 * Try number one:
258*7934SMark.Phalan@Sun.COM 	 *
259*7934SMark.Phalan@Sun.COM 	 * [libdefaults]
260*7934SMark.Phalan@Sun.COM 	 *	  REALM = {
261*7934SMark.Phalan@Sun.COM 	 *		  option = <value>
262*7934SMark.Phalan@Sun.COM 	 *	  }
263*7934SMark.Phalan@Sun.COM 	 */
264*7934SMark.Phalan@Sun.COM 
265*7934SMark.Phalan@Sun.COM 	names[0] = "libdefaults";
266*7934SMark.Phalan@Sun.COM 	names[1] = realmstr;
267*7934SMark.Phalan@Sun.COM 	names[2] = option;
268*7934SMark.Phalan@Sun.COM 	names[3] = 0;
269*7934SMark.Phalan@Sun.COM 	retval = profile_get_values(profile, names, &values);
270*7934SMark.Phalan@Sun.COM 	if (retval == 0 && values != NULL && values[0] != NULL)
271*7934SMark.Phalan@Sun.COM 	    goto goodbye;
272*7934SMark.Phalan@Sun.COM 
273*7934SMark.Phalan@Sun.COM 	/*
274*7934SMark.Phalan@Sun.COM 	 * Try number two:
275*7934SMark.Phalan@Sun.COM 	 *
276*7934SMark.Phalan@Sun.COM 	 * [realms]
277*7934SMark.Phalan@Sun.COM 	 *	REALM = {
278*7934SMark.Phalan@Sun.COM 	 *		option = <value>
279*7934SMark.Phalan@Sun.COM 	 *	}
280*7934SMark.Phalan@Sun.COM 	 */
281*7934SMark.Phalan@Sun.COM 
282*7934SMark.Phalan@Sun.COM 	names[0] = "realms";
283*7934SMark.Phalan@Sun.COM 	names[1] = realmstr;
284*7934SMark.Phalan@Sun.COM 	names[2] = option;
285*7934SMark.Phalan@Sun.COM 	names[3] = 0;
286*7934SMark.Phalan@Sun.COM 	retval = profile_get_values(profile, names, &values);
287*7934SMark.Phalan@Sun.COM 	if (retval == 0 && values != NULL && values[0] != NULL)
288*7934SMark.Phalan@Sun.COM 	    goto goodbye;
289*7934SMark.Phalan@Sun.COM     }
290*7934SMark.Phalan@Sun.COM 
291*7934SMark.Phalan@Sun.COM     /*
292*7934SMark.Phalan@Sun.COM      * Try number three:
293*7934SMark.Phalan@Sun.COM      *
294*7934SMark.Phalan@Sun.COM      * [libdefaults]
295*7934SMark.Phalan@Sun.COM      *	      option = <value>
296*7934SMark.Phalan@Sun.COM      */
297*7934SMark.Phalan@Sun.COM 
298*7934SMark.Phalan@Sun.COM     names[0] = "libdefaults";
299*7934SMark.Phalan@Sun.COM     names[1] = option;
300*7934SMark.Phalan@Sun.COM     names[2] = 0;
301*7934SMark.Phalan@Sun.COM     retval = profile_get_values(profile, names, &values);
302*7934SMark.Phalan@Sun.COM     if (retval == 0 && values != NULL && values[0] != NULL)
303*7934SMark.Phalan@Sun.COM 	goto goodbye;
304*7934SMark.Phalan@Sun.COM 
305*7934SMark.Phalan@Sun.COM goodbye:
306*7934SMark.Phalan@Sun.COM     if (values == NULL)
307*7934SMark.Phalan@Sun.COM 	return ENOENT;
308*7934SMark.Phalan@Sun.COM 
309*7934SMark.Phalan@Sun.COM     *ret_value = values;
310*7934SMark.Phalan@Sun.COM 
311*7934SMark.Phalan@Sun.COM     return retval;
312*7934SMark.Phalan@Sun.COM }
313*7934SMark.Phalan@Sun.COM 
314*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_libdefault_string(krb5_context context,const krb5_data * realm,const char * option,char ** ret_value)315*7934SMark.Phalan@Sun.COM pkinit_libdefault_string(krb5_context context, const krb5_data *realm,
316*7934SMark.Phalan@Sun.COM 			 const char *option, char **ret_value)
317*7934SMark.Phalan@Sun.COM {
318*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
319*7934SMark.Phalan@Sun.COM     char **values = NULL;
320*7934SMark.Phalan@Sun.COM 
321*7934SMark.Phalan@Sun.COM     retval = pkinit_libdefault_strings(context, realm, option, &values);
322*7934SMark.Phalan@Sun.COM     if (retval)
323*7934SMark.Phalan@Sun.COM 	return retval;
324*7934SMark.Phalan@Sun.COM 
325*7934SMark.Phalan@Sun.COM     if (values[0] == NULL) {
326*7934SMark.Phalan@Sun.COM 	retval = ENOENT;
327*7934SMark.Phalan@Sun.COM     } else {
328*7934SMark.Phalan@Sun.COM 	*ret_value = malloc(strlen(values[0]) + 1);
329*7934SMark.Phalan@Sun.COM 	if (*ret_value == NULL)
330*7934SMark.Phalan@Sun.COM 	    retval = ENOMEM;
331*7934SMark.Phalan@Sun.COM 	else /* Solaris Kerberos */
332*7934SMark.Phalan@Sun.COM 	    (void) strlcpy(*ret_value, values[0], strlen(values[0]) + 1);
333*7934SMark.Phalan@Sun.COM     }
334*7934SMark.Phalan@Sun.COM 
335*7934SMark.Phalan@Sun.COM     profile_free_list(values);
336*7934SMark.Phalan@Sun.COM     return retval;
337*7934SMark.Phalan@Sun.COM }
338*7934SMark.Phalan@Sun.COM 
339*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_libdefault_boolean(krb5_context context,const krb5_data * realm,const char * option,int default_value,int * ret_value)340*7934SMark.Phalan@Sun.COM pkinit_libdefault_boolean(krb5_context context, const krb5_data *realm,
341*7934SMark.Phalan@Sun.COM 			  const char *option, int default_value,
342*7934SMark.Phalan@Sun.COM 			  int *ret_value)
343*7934SMark.Phalan@Sun.COM {
344*7934SMark.Phalan@Sun.COM     char *string = NULL;
345*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
346*7934SMark.Phalan@Sun.COM 
347*7934SMark.Phalan@Sun.COM     retval = pkinit_libdefault_string(context, realm, option, &string);
348*7934SMark.Phalan@Sun.COM 
349*7934SMark.Phalan@Sun.COM    if (retval == 0) {
350*7934SMark.Phalan@Sun.COM 	*ret_value = _krb5_conf_boolean(string);
351*7934SMark.Phalan@Sun.COM 	free(string);
352*7934SMark.Phalan@Sun.COM     } else
353*7934SMark.Phalan@Sun.COM 	*ret_value = default_value;
354*7934SMark.Phalan@Sun.COM 
355*7934SMark.Phalan@Sun.COM     return 0;
356*7934SMark.Phalan@Sun.COM }
357*7934SMark.Phalan@Sun.COM 
358*7934SMark.Phalan@Sun.COM krb5_error_code
pkinit_libdefault_integer(krb5_context context,const krb5_data * realm,const char * option,int default_value,int * ret_value)359*7934SMark.Phalan@Sun.COM pkinit_libdefault_integer(krb5_context context, const krb5_data *realm,
360*7934SMark.Phalan@Sun.COM 			  const char *option, int default_value,
361*7934SMark.Phalan@Sun.COM 			  int *ret_value)
362*7934SMark.Phalan@Sun.COM {
363*7934SMark.Phalan@Sun.COM     char *string = NULL;
364*7934SMark.Phalan@Sun.COM     krb5_error_code retval;
365*7934SMark.Phalan@Sun.COM 
366*7934SMark.Phalan@Sun.COM     retval = pkinit_libdefault_string(context, realm, option, &string);
367*7934SMark.Phalan@Sun.COM 
368*7934SMark.Phalan@Sun.COM     if (retval == 0) {
369*7934SMark.Phalan@Sun.COM 	char *endptr;
370*7934SMark.Phalan@Sun.COM 	long l;
371*7934SMark.Phalan@Sun.COM 	l = strtol(string, &endptr, 0);
372*7934SMark.Phalan@Sun.COM 	if (endptr == string)
373*7934SMark.Phalan@Sun.COM 	    *ret_value = default_value;
374*7934SMark.Phalan@Sun.COM 	else
375*7934SMark.Phalan@Sun.COM 	    *ret_value = l;
376*7934SMark.Phalan@Sun.COM 	free(string);
377*7934SMark.Phalan@Sun.COM     }
378*7934SMark.Phalan@Sun.COM 
379*7934SMark.Phalan@Sun.COM     return retval;
380*7934SMark.Phalan@Sun.COM }
381