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