[2181] in Kerberos-V5-bugs
Implementation of appdefaults profile
daemon@ATHENA.MIT.EDU (Ken Hornstein)
Fri Aug 23 17:17:56 1996
To: krb5-bugs@MIT.EDU
Date: Fri, 23 Aug 1996 17:17:40 -0400
From: Ken Hornstein <kenh@cmf.nrl.navy.mil>
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <29934.840835031.1@nexus.cmf.nrl.navy.mil>
There was some discussion on kerberos@mit.edu (mostly between Sam Hartman
and myself) about a better way to do application-specific configuration
in krb5.conf. The attached patches implements this as per our discussion.
In a nutshell, you have something like:
[appdefaults]
option = foo
yourapp = {
option = bar
SOME.CELL = {
option = baz
}
}
SOME.CELL = {
option = blah
}
The priority is the following:
1) application-specific | realm-specific | option
2) application-specific | option
3) realm-specific | option
4) option
This lets you set defaults easily for a bunch of applications, but you
can tailor each application and realm specifically.
I'm not sure this belongs in util/profile.
Comments/suggestions are welcome. Also includes a patch for kinit that
uses this (it's ugly, unfortunately).
--Ken
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <29934.840835031.2@nexus.cmf.nrl.navy.mil>
Content-Description: Implementation of appdefaults profile parser
--- util/profile/Makefile.in.orig Fri Aug 23 14:27:02 1996
+++ util/profile/Makefile.in Fri Aug 23 14:28:30 1996
@@ -13,13 +13,15 @@
prof_file.$(OBJEXT) \
prof_parse.$(OBJEXT) \
prof_err.$(OBJEXT) \
- prof_init.$(OBJEXT)
+ prof_init.$(OBJEXT) \
+ prof_appdef.$(OBJEXT)
SRCS = $(srcdir)/prof_tree.c \
$(srcdir)/prof_file.c \
$(srcdir)/prof_parse.c \
prof_err.c \
- $(srcdir)/prof_init.c
+ $(srcdir)/prof_init.c \
+ $(srcdir)/prof_appdef.c
LIBS = ../et/libcom_err.$(LIBEXT)
@@ -92,4 +94,5 @@
prof_parse.o: $(srcdir)/prof_parse.c $(srcdir)/prof_int.h prof_err.h
prof_err.o: prof_err.c
prof_init.o: $(srcdir)/prof_init.c $(srcdir)/prof_int.h prof_err.h
+prof_appdef.o: $(srcdir)/prof_appdef.c $(srcdir)/prof_int.h prof_err.h
--- util/profile/prof_int.h.orig Fri Aug 23 14:15:12 1996
+++ util/profile/prof_int.h Fri Aug 23 15:34:21 1996
@@ -148,3 +148,12 @@
PROTOTYPE((profile_t profile, const char *name, const char *subname,
const char *subsubname, int def_val,
int *ret_default));
+
+extern void profile_appdefault_string
+ PROTOTYPE ((profile_t profile, const char *appname,
+ const char *realm, const char *option,
+ const char *def_val, char **ret_string));
+extern void profile_appdefault_boolean
+ PROTOTYPE ((profile_t profile, const char *appname,
+ const char *realm, const char *option,
+ int default_value, int *ret_value));
--- util/profile/profile.hin.orig Fri Aug 23 14:24:35 1996
+++ util/profile/profile.hin Fri Aug 23 15:04:43 1996
@@ -32,3 +32,11 @@
const char *subsubname, int def_val,
int *ret_default));
+extern void profile_appdefault_string
+ PROTOTYPE ((profile_t profile, const char *appname,
+ const char *realm, const char *option,
+ const char *def_val, char **ret_string));
+extern void profile_appdefault_boolean
+ PROTOTYPE ((profile_t profile, const char *appname,
+ const char *realm, const char *option,
+ int default_value, int *ret_value));
--- /dev/null Fri Aug 23 17:10:36 1996
+++ util/profile/prof_appdef.c Fri Aug 23 17:00:40 1996
@@ -0,0 +1,182 @@
+/*
+ * prof_appdef - routines designed to be called from applications to
+ * handle the [appdefaults] profile section
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "prof_int.h"
+
+/* Find a 4-byte integer type */
+#if (SIZEOF_SHORT == 4)
+typedef short prof_int32;
+#elif (SIZEOF_INT == 4)
+typedef int prof_int32;
+#elif (SIZEOF_LONG == 4)
+typedef int prof_int32;
+#else /* SIZEOF_LONG == 4 */
+error(do not have a 4-byte integer type)
+#endif /* SIZEOF_LONG == 4 */
+
+static char *conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0,
+};
+
+static char *conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0,
+};
+
+static int conf_boolean(s)
+ char *s;
+{
+ char **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 errcode_t appdefault_get(profile, appname, realm, option,
+ ret_value)
+ profile_t profile;
+ const char *appname, *realm, *option;
+ char **ret_value;
+{
+ const char *names[5];
+ char **nameval = NULL;
+ errcode_t retval;
+
+ /*
+ * Try number one:
+ *
+ * [appdefaults]
+ * app = {
+ * SOME.REALM = {
+ * option = <boolean>
+ * }
+ * }
+ */
+
+ names[0] = "appdefaults";
+ names[1] = appname;
+
+ if (realm) {
+ names[2] = realm;
+ 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 (realm) {
+ names[1] = realm;
+ 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 profile_appdefault_boolean(profile, appname, realm, option,
+ default_value, ret_value)
+ profile_t profile;
+ const char *appname, *realm, *option;
+ int default_value;
+ int *ret_value;
+{
+ char *string = NULL;
+ errcode_t retval;
+
+ retval = appdefault_get(profile, appname, realm, option, &string);
+
+ if (! retval && string) {
+ *ret_value = conf_boolean(string);
+ free(string);
+ } else
+ *ret_value = default_value;
+}
+
+void profile_appdefault_string(profile, appname, realm, option, default_value,
+ ret_value)
+ profile_t profile;
+ const char *appname, *realm, *option, *default_value;
+ char **ret_value;
+{
+ errcode_t retval;
+ char *string;
+
+ retval = appdefault_get(profile, appname, realm, option, &string);
+
+ if (! retval && string) {
+ *ret_value = string;
+ } else {
+ *ret_value = strdup(default_value);
+ }
+}
--- clients/kinit/kinit.c.orig Fri Aug 23 15:50:13 1996
+++ clients/kinit/kinit.c Fri Aug 23 17:07:59 1996
@@ -60,7 +60,7 @@
krb5_ccache ccache = NULL;
char *cache_name = NULL; /* -f option */
char *keytab_name = NULL; /* -t option */
- krb5_deltat lifetime = KRB5_DEFAULT_LIFE; /* -l option */
+ krb5_deltat lifetime = 0; /* -l option */
krb5_timestamp starttime = 0;
krb5_deltat rlife = 0;
int options = KRB5_DEFAULT_OPTIONS;
@@ -258,6 +258,32 @@
}
my_creds.server = server;
+
+ {
+#define MAX_REALM_LN 500
+ int forward;
+ char realm[MAX_REALM_LN];
+ strncpy(realm, krb5_princ_realm(kcontext, me)->data,
+ krb5_princ_realm(kcontext, me)->length);
+ profile_appdefault_boolean(kcontext->profile, "kinit", realm,
+ "forwardable", 0, &forward);
+ if (forward)
+ options |= KDC_OPT_FORWARDABLE;
+
+ if (!lifetime) {
+ char *lifetimestring;
+ profile_appdefault_string(kcontext->profile, "kinit", realm,
+ "default_lifetime", "10h 0m 0s",
+ &lifetimestring);
+ code = krb5_string_to_deltat(lifetimestring, &lifetime);
+ if (code != 0 || lifetime == 0) {
+ fprintf(stderr, "Bad lifetime value: %s\n",
+ lifetimestring);
+ exit(1);
+ }
+ free(lifetimestring);
+ }
+ }
if (options & KDC_OPT_POSTDATED) {
my_creds.times.starttime = starttime;
------- =_aaaaaaaaaa0--