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 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 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 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 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