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