17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * appdefault - routines designed to be called from applications to
37c478bd9Sstevel@tonic-gate  *		 handle the [appdefaults] profile section
47c478bd9Sstevel@tonic-gate  */
5159d09a2SMark Phalan 
67c478bd9Sstevel@tonic-gate #include <stdio.h>
77c478bd9Sstevel@tonic-gate #include <string.h>
8159d09a2SMark Phalan #include "k5-int.h"
97c478bd9Sstevel@tonic-gate 
107c478bd9Sstevel@tonic-gate 
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate  /*xxx Duplicating this is annoying; try to work on a better way.*/
13159d09a2SMark Phalan static const char *const conf_yes[] = {
147c478bd9Sstevel@tonic-gate 	"y", "yes", "true", "t", "1", "on",
157c478bd9Sstevel@tonic-gate 	0,
167c478bd9Sstevel@tonic-gate };
177c478bd9Sstevel@tonic-gate 
18159d09a2SMark Phalan static const char *const conf_no[] = {
197c478bd9Sstevel@tonic-gate 	"n", "no", "false", "nil", "0", "off",
207c478bd9Sstevel@tonic-gate 	0,
217c478bd9Sstevel@tonic-gate };
227c478bd9Sstevel@tonic-gate 
conf_boolean(char * s)23505d05c7Sgtb static int conf_boolean(char *s)
247c478bd9Sstevel@tonic-gate {
25505d05c7Sgtb 	const char * const *p;
267c478bd9Sstevel@tonic-gate 	for(p=conf_yes; *p; p++) {
277c478bd9Sstevel@tonic-gate 		if (!strcasecmp(*p,s))
287c478bd9Sstevel@tonic-gate 			return 1;
297c478bd9Sstevel@tonic-gate 	}
307c478bd9Sstevel@tonic-gate 	for(p=conf_no; *p; p++) {
317c478bd9Sstevel@tonic-gate 		if (!strcasecmp(*p,s))
327c478bd9Sstevel@tonic-gate 		return 0;
337c478bd9Sstevel@tonic-gate 	}
347c478bd9Sstevel@tonic-gate 	/* Default to "no" */
357c478bd9Sstevel@tonic-gate 	return 0;
367c478bd9Sstevel@tonic-gate }
377c478bd9Sstevel@tonic-gate 
appdefault_get(krb5_context context,const char * appname,const krb5_data * realm,const char * option,char ** ret_value)38159d09a2SMark Phalan static krb5_error_code appdefault_get(krb5_context context, const char *appname, const krb5_data *realm, const char *option, char **ret_value)
397c478bd9Sstevel@tonic-gate {
407c478bd9Sstevel@tonic-gate         profile_t profile;
417c478bd9Sstevel@tonic-gate         const char *names[5];
427c478bd9Sstevel@tonic-gate 	char **nameval = NULL;
437c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
447c478bd9Sstevel@tonic-gate 	const char * realmstr =  realm?realm->data:NULL;
457c478bd9Sstevel@tonic-gate 
46*55fea89dSDan Cross 	    if (!context || (context->magic != KV5M_CONTEXT))
477c478bd9Sstevel@tonic-gate 	    return KV5M_CONTEXT;
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate 	    profile = context->profile;
50*55fea89dSDan Cross 
517c478bd9Sstevel@tonic-gate 	/*
527c478bd9Sstevel@tonic-gate 	 * Try number one:
537c478bd9Sstevel@tonic-gate 	 *
547c478bd9Sstevel@tonic-gate 	 * [appdefaults]
557c478bd9Sstevel@tonic-gate 	 *	app = {
567c478bd9Sstevel@tonic-gate 	 *		SOME.REALM = {
577c478bd9Sstevel@tonic-gate 	 *			option = <boolean>
587c478bd9Sstevel@tonic-gate 	 *		}
597c478bd9Sstevel@tonic-gate 	 *	}
607c478bd9Sstevel@tonic-gate 	 */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	names[0] = "appdefaults";
637c478bd9Sstevel@tonic-gate 	names[1] = appname;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	if (realmstr) {
667c478bd9Sstevel@tonic-gate 		names[2] = realmstr;
677c478bd9Sstevel@tonic-gate 		names[3] = option;
687c478bd9Sstevel@tonic-gate 		names[4] = 0;
697c478bd9Sstevel@tonic-gate 		retval = profile_get_values(profile, names, &nameval);
707c478bd9Sstevel@tonic-gate 		if (retval == 0 && nameval && nameval[0]) {
717c478bd9Sstevel@tonic-gate 			*ret_value = strdup(nameval[0]);
727c478bd9Sstevel@tonic-gate 			goto goodbye;
737c478bd9Sstevel@tonic-gate 		}
747c478bd9Sstevel@tonic-gate 	}
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 	/*
777c478bd9Sstevel@tonic-gate 	 * Try number two:
787c478bd9Sstevel@tonic-gate 	 *
797c478bd9Sstevel@tonic-gate 	 * [appdefaults]
807c478bd9Sstevel@tonic-gate 	 *	app = {
817c478bd9Sstevel@tonic-gate 	 *		option = <boolean>
827c478bd9Sstevel@tonic-gate 	 *      }
837c478bd9Sstevel@tonic-gate 	 */
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	names[2] = option;
867c478bd9Sstevel@tonic-gate 	names[3] = 0;
877c478bd9Sstevel@tonic-gate 	retval = profile_get_values(profile, names, &nameval);
887c478bd9Sstevel@tonic-gate 	if (retval == 0 && nameval && nameval[0]) {
897c478bd9Sstevel@tonic-gate 		*ret_value = strdup(nameval[0]);
907c478bd9Sstevel@tonic-gate 		goto goodbye;
917c478bd9Sstevel@tonic-gate 	}
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	/*
947c478bd9Sstevel@tonic-gate 	 * Try number three:
957c478bd9Sstevel@tonic-gate 	 *
967c478bd9Sstevel@tonic-gate 	 * [appdefaults]
977c478bd9Sstevel@tonic-gate 	 *	realm = {
987c478bd9Sstevel@tonic-gate 	 *		option = <boolean>
997c478bd9Sstevel@tonic-gate 	 */
100*55fea89dSDan Cross 
1017c478bd9Sstevel@tonic-gate 	if (realmstr) {
1027c478bd9Sstevel@tonic-gate 		names[1] = realmstr;
1037c478bd9Sstevel@tonic-gate 		names[2] = option;
1047c478bd9Sstevel@tonic-gate 		names[3] = 0;
1057c478bd9Sstevel@tonic-gate 		retval = profile_get_values(profile, names, &nameval);
1067c478bd9Sstevel@tonic-gate 		if (retval == 0 && nameval && nameval[0]) {
1077c478bd9Sstevel@tonic-gate 			*ret_value = strdup(nameval[0]);
1087c478bd9Sstevel@tonic-gate 			goto goodbye;
1097c478bd9Sstevel@tonic-gate 		}
1107c478bd9Sstevel@tonic-gate 	}
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	/*
1137c478bd9Sstevel@tonic-gate 	 * Try number four:
1147c478bd9Sstevel@tonic-gate 	 *
1157c478bd9Sstevel@tonic-gate 	 * [appdefaults]
1167c478bd9Sstevel@tonic-gate 	 *	option = <boolean>
1177c478bd9Sstevel@tonic-gate 	 */
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	names[1] = option;
1207c478bd9Sstevel@tonic-gate 	names[2] = 0;
1217c478bd9Sstevel@tonic-gate 	retval = profile_get_values(profile, names, &nameval);
1227c478bd9Sstevel@tonic-gate 	if (retval == 0 && nameval && nameval[0]) {
1237c478bd9Sstevel@tonic-gate 		*ret_value = strdup(nameval[0]);
1247c478bd9Sstevel@tonic-gate 	} else {
1257c478bd9Sstevel@tonic-gate 		return retval;
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate goodbye:
1297c478bd9Sstevel@tonic-gate 	if (nameval) {
1307c478bd9Sstevel@tonic-gate 		char **cpp;
1317c478bd9Sstevel@tonic-gate 		for (cpp = nameval; *cpp; cpp++)
1327c478bd9Sstevel@tonic-gate 			free(*cpp);
1337c478bd9Sstevel@tonic-gate 		free(nameval);
1347c478bd9Sstevel@tonic-gate 	}
1357c478bd9Sstevel@tonic-gate 	return 0;
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate 
138*55fea89dSDan Cross 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)139159d09a2SMark Phalan krb5_appdefault_boolean(krb5_context context, const char *appname, const krb5_data *realm, const char *option, int default_value, int *ret_value)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate 	char *string = NULL;
1427c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	retval = appdefault_get(context, appname, realm, option, &string);
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	if (! retval && string) {
1477c478bd9Sstevel@tonic-gate 		*ret_value = conf_boolean(string);
1487c478bd9Sstevel@tonic-gate 		free(string);
1497c478bd9Sstevel@tonic-gate 	} else
1507c478bd9Sstevel@tonic-gate 		*ret_value = default_value;
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
153*55fea89dSDan Cross 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)154159d09a2SMark Phalan krb5_appdefault_string(krb5_context context, const char *appname, const krb5_data *realm, const char *option, const char *default_value, char **ret_value)
155505d05c7Sgtb {
1567c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
1577c478bd9Sstevel@tonic-gate 	char *string;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	retval = appdefault_get(context, appname, realm, option, &string);
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	if (! retval && string) {
1627c478bd9Sstevel@tonic-gate 		*ret_value = string;
1637c478bd9Sstevel@tonic-gate 	} else {
1647c478bd9Sstevel@tonic-gate 		*ret_value = strdup(default_value);
1657c478bd9Sstevel@tonic-gate 	}
1667c478bd9Sstevel@tonic-gate }
167