1 /*
2  * appdefault - routines designed to be called from applications to
3  *		 handle the [appdefaults] profile section
4  */
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include "k5-int.h"
9 
10 
11 
12  /*xxx Duplicating this is annoying; try to work on a better way.*/
13 static const char *const conf_yes[] = {
14 	"y", "yes", "true", "t", "1", "on",
15 	0,
16 };
17 
18 static const char *const conf_no[] = {
19 	"n", "no", "false", "nil", "0", "off",
20 	0,
21 };
22 
conf_boolean(char * s)23 static int conf_boolean(char *s)
24 {
25 	const char * const *p;
26 	for(p=conf_yes; *p; p++) {
27 		if (!strcasecmp(*p,s))
28 			return 1;
29 	}
30 	for(p=conf_no; *p; p++) {
31 		if (!strcasecmp(*p,s))
32 		return 0;
33 	}
34 	/* Default to "no" */
35 	return 0;
36 }
37 
appdefault_get(krb5_context context,const char * appname,const krb5_data * realm,const char * option,char ** ret_value)38 static krb5_error_code appdefault_get(krb5_context context, const char *appname, const krb5_data *realm, const char *option, char **ret_value)
39 {
40         profile_t profile;
41         const char *names[5];
42 	char **nameval = NULL;
43 	krb5_error_code retval;
44 	const char * realmstr =  realm?realm->data:NULL;
45 
46 	    if (!context || (context->magic != KV5M_CONTEXT))
47 	    return KV5M_CONTEXT;
48 
49 	    profile = context->profile;
50 
51 	/*
52 	 * Try number one:
53 	 *
54 	 * [appdefaults]
55 	 *	app = {
56 	 *		SOME.REALM = {
57 	 *			option = <boolean>
58 	 *		}
59 	 *	}
60 	 */
61 
62 	names[0] = "appdefaults";
63 	names[1] = appname;
64 
65 	if (realmstr) {
66 		names[2] = realmstr;
67 		names[3] = option;
68 		names[4] = 0;
69 		retval = profile_get_values(profile, names, &nameval);
70 		if (retval == 0 && nameval && nameval[0]) {
71 			*ret_value = strdup(nameval[0]);
72 			goto goodbye;
73 		}
74 	}
75 
76 	/*
77 	 * Try number two:
78 	 *
79 	 * [appdefaults]
80 	 *	app = {
81 	 *		option = <boolean>
82 	 *      }
83 	 */
84 
85 	names[2] = option;
86 	names[3] = 0;
87 	retval = profile_get_values(profile, names, &nameval);
88 	if (retval == 0 && nameval && nameval[0]) {
89 		*ret_value = strdup(nameval[0]);
90 		goto goodbye;
91 	}
92 
93 	/*
94 	 * Try number three:
95 	 *
96 	 * [appdefaults]
97 	 *	realm = {
98 	 *		option = <boolean>
99 	 */
100 
101 	if (realmstr) {
102 		names[1] = realmstr;
103 		names[2] = option;
104 		names[3] = 0;
105 		retval = profile_get_values(profile, names, &nameval);
106 		if (retval == 0 && nameval && nameval[0]) {
107 			*ret_value = strdup(nameval[0]);
108 			goto goodbye;
109 		}
110 	}
111 
112 	/*
113 	 * Try number four:
114 	 *
115 	 * [appdefaults]
116 	 *	option = <boolean>
117 	 */
118 
119 	names[1] = option;
120 	names[2] = 0;
121 	retval = profile_get_values(profile, names, &nameval);
122 	if (retval == 0 && nameval && nameval[0]) {
123 		*ret_value = strdup(nameval[0]);
124 	} else {
125 		return retval;
126 	}
127 
128 goodbye:
129 	if (nameval) {
130 		char **cpp;
131 		for (cpp = nameval; *cpp; cpp++)
132 			free(*cpp);
133 		free(nameval);
134 	}
135 	return 0;
136 }
137 
138 void KRB5_CALLCONV
krb5_appdefault_boolean(krb5_context context,const char * appname,const krb5_data * realm,const char * option,int default_value,int * ret_value)139 krb5_appdefault_boolean(krb5_context context, const char *appname, const krb5_data *realm, const char *option, int default_value, int *ret_value)
140 {
141 	char *string = NULL;
142 	krb5_error_code retval;
143 
144 	retval = appdefault_get(context, appname, realm, option, &string);
145 
146 	if (! retval && string) {
147 		*ret_value = conf_boolean(string);
148 		free(string);
149 	} else
150 		*ret_value = default_value;
151 }
152 
153 void KRB5_CALLCONV
krb5_appdefault_string(krb5_context context,const char * appname,const krb5_data * realm,const char * option,const char * default_value,char ** ret_value)154 krb5_appdefault_string(krb5_context context, const char *appname, const krb5_data *realm, const char *option, const char *default_value, char **ret_value)
155 {
156 	krb5_error_code retval;
157 	char *string;
158 
159 	retval = appdefault_get(context, appname, realm, option, &string);
160 
161 	if (! retval && string) {
162 		*ret_value = string;
163 	} else {
164 		*ret_value = strdup(default_value);
165 	}
166 }
167