/*
* appdefault - routines designed to be called from applications to
* handle the [appdefaults] profile section
*/
#include <stdio.h>
#include <string.h>
#include "k5-int.h"
/*xxx Duplicating this is annoying; try to work on a better way.*/
static const char *const conf_yes[] = {
"y", "yes", "true", "t", "1", "on",
0,
};
static const char *const conf_no[] = {
"n", "no", "false", "nil", "0", "off",
0,
};
static int conf_boolean(char *s)
{
const char * const *p;
for(p=conf_yes; *p; p++) {
if (!strcasecmp(*p,s))
return 1;
}
for(p=conf_no; *p; p++) {
if (!strcasecmp(*p,s))
return 0;
}
/* Default to "no" */
return 0;
}
static krb5_error_code appdefault_get(krb5_context context, const char *appname, const krb5_data *realm, const char *option, char **ret_value)
{
profile_t profile;
const char *names[5];
char **nameval = NULL;
krb5_error_code retval;
const char * realmstr = realm?realm->data:NULL;
if (!context || (context->magic != KV5M_CONTEXT))
return KV5M_CONTEXT;
profile = context->profile;
/*
* Try number one:
*
* [appdefaults]
* app = {
* SOME.REALM = {
* option = <boolean>
* }
* }
*/
names[0] = "appdefaults";
names[1] = appname;
if (realmstr) {
names[2] = realmstr;
names[3] = option;
names[4] = 0;
retval = profile_get_values(profile, names, &nameval);
if (retval == 0 && nameval && nameval[0]) {
*ret_value = strdup(nameval[0]);
goto goodbye;
}
}
/*
* Try number two:
*
* [appdefaults]
* app = {
* option = <boolean>
* }
*/
names[2] = option;
names[3] = 0;
retval = profile_get_values(profile, names, &nameval);
if (retval == 0 && nameval && nameval[0]) {
*ret_value = strdup(nameval[0]);
goto goodbye;
}
/*
* Try number three:
*
* [appdefaults]
* realm = {
* option = <boolean>
*/
if (realmstr) {
names[1] = realmstr;
names[2] = option;
names[3] = 0;
retval = profile_get_values(profile, names, &nameval);
if (retval == 0 && nameval && nameval[0]) {
*ret_value = strdup(nameval[0]);
goto goodbye;
}
}
/*
* Try number four:
*
* [appdefaults]
* option = <boolean>
*/
names[1] = option;
names[2] = 0;
retval = profile_get_values(profile, names, &nameval);
if (retval == 0 && nameval && nameval[0]) {
*ret_value = strdup(nameval[0]);
} else {
return retval;
}
goodbye:
if (nameval) {
char **cpp;
for (cpp = nameval; *cpp; cpp++)
free(*cpp);
free(nameval);
}
return 0;
}
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)
{
char *string = NULL;
krb5_error_code retval;
retval = appdefault_get(context, appname, realm, option, &string);
if (! retval && string) {
*ret_value = conf_boolean(string);
free(string);
} else
*ret_value = default_value;
}
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)
{
krb5_error_code retval;
char *string;
retval = appdefault_get(context, appname, realm, option, &string);
if (! retval && string) {
*ret_value = string;
} else {
*ret_value = strdup(default_value);
}
}