From c3f85a084b5b07d4c289cecda92d319e9d94cb7f Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Tue, 27 Apr 2010 22:53:47 +0100 Subject: [PATCH] Add an OpenAFS config file parser This adds a Kerberos INI style config file parser to OpenAFS, using the parser contained in Heimdal as a base. Currently, it only exports a very small number of functions, but exporting further functions is simply a matter of adding additional shims to hide the Kerberos context and other specifics. Note that we don't want to just use the parser as a library because firstly, we don't want OpenAFS to have a Kerberos dependency (as other crypto mechanisms will, and do, exist). Secondly, MIT and Heimdal use a different API here, so we would have to shim anyway. Also, our own parser means that we don't need to worry about passing in the krb5 context, and all of the issues that that presents. Change-Id: Ic0a5ddf03266c454827c6505d5f6ffefcddd2614 Reviewed-on: http://gerrit.openafs.org/1935 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/util/Makefile.in | 6 +- src/util/afsutil_prototypes.h | 9 ++ src/util/krb5_locl.h | 168 ++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/util/krb5_locl.h diff --git a/src/util/Makefile.in b/src/util/Makefile.in index c39998fd6..82ba680fb 100644 --- a/src/util/Makefile.in +++ b/src/util/Makefile.in @@ -14,7 +14,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ HELPER_SPLINT=@HELPER_SPLINT@ -objects = assert.o base64.o casestrcpy.o ktime.o volparse.o hostparse.o \ +objects = assert.o base64.o casestrcpy.o config_file.o ktime.o volparse.o \ + hostparse.o \ hputil.o kreltime.o isathing.o get_krbrlm.o uuid.o serverLog.o \ dirpath.o fileutil.o netutils.o flipbase64.o fstab.o \ afs_atomlist.o afs_lhash.o snprintf.o strlcat.o strlcpy.o strnlen.o \ @@ -155,6 +156,9 @@ fstab.o: ${srcdir}/fstab.c ${includes} base64.o: ${srcdir}/base64.c ${includes} ${CCOBJ} ${CFLAGS} -c ${srcdir}/base64.c +config_file.o : ${TOP_SRCDIR}/external/heimdal/krb5/config_file.c + ${CCOBJ} ${CFLAGS} -c ${TOP_SRCDIR}/external/heimdal/krb5/config_file.c + hostparse.o: ${srcdir}/hostparse.c ${includes} ${CCOBJ} ${CFLAGS} -c ${srcdir}/hostparse.c diff --git a/src/util/afsutil_prototypes.h b/src/util/afsutil_prototypes.h index 919cfc6a3..c881ff4a9 100644 --- a/src/util/afsutil_prototypes.h +++ b/src/util/afsutil_prototypes.h @@ -35,6 +35,15 @@ extern char *strcompose(char *buf, size_t len, ...); extern void stolower(char *s); extern void stoupper(char *s); +/* config_file.c && krb5_locl.h */ +typedef struct afs_config_section_struct afs_config_section; +extern int afs_config_parse_file_multi(const char *, afs_config_section **); +extern int afs_config_parse_file(const char *, afs_config_section **); +extern int afs_config_file_free(afs_config_section *s); +extern const char* fs_config_get_string(const afs_config_section *, ...); +extern int afs_config_get_bool(const afs_config_section *, ...); +extern int afs_config_get_int(const afs_config_section *c, ...); + /* daemon.c */ #ifndef HAVE_DAEMON int daemon(int nochdir, int noclose); diff --git a/src/util/krb5_locl.h b/src/util/krb5_locl.h new file mode 100644 index 000000000..f6fde3ab7 --- /dev/null +++ b/src/util/krb5_locl.h @@ -0,0 +1,168 @@ + +/* This header file transforms the Heimdal config_parse.c profile + * parser into an AFS profile parser, hiding the krb5-ness of the parser + * behind the scenes. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define KRB5_LIB_FUNCTION static AFS_UNUSED +#define KRB5_LIB_CALL + +/* This value shouldn't be hard coded */ +#define KRB5_CONFIG_BADFORMAT (-1765328248L) + +#define N_(X,Y) X + +struct krb5_config_binding { + enum { krb5_config_string, krb5_config_list } type; + char *name; + struct krb5_config_binding *next; + union { + char *string; + struct krb5_config_binding *list; + void *generic; + } u; +}; + +typedef struct krb5_config_binding krb5_config_binding; + +typedef krb5_config_binding krb5_config_section; +typedef krb5_config_section afs_config_section; + +struct krb5_context_data { + krb5_config_section *cf; +}; + +typedef struct krb5_context_data * krb5_context; +typedef int krb5_error_code; +typedef int krb5_boolean; +typedef time_t krb5_deltat; + +static const void *_krb5_config_vget(krb5_context, + const krb5_config_section *, int, + va_list); +static const void *_krb5_config_vget_next(krb5_context, + const krb5_config_section *, + const krb5_config_binding **, + int, va_list); +static const char *krb5_config_vget_string(krb5_context, + const krb5_config_section *, + va_list); +static const krb5_config_binding * krb5_config_vget_list + (krb5_context, const krb5_config_section *, va_list); +static krb5_error_code krb5_config_parse_file_multi + (krb5_context, const char *, krb5_config_section **); +static krb5_error_code krb5_config_parse_file + (krb5_context, const char *, krb5_config_section **); +static krb5_error_code krb5_config_file_free + (krb5_context, krb5_config_section *); +static krb5_boolean krb5_config_vget_bool + (krb5_context, const krb5_config_section *,va_list); +static int krb5_config_vget_int + (krb5_context, const krb5_config_section *, va_list); + +static krb5_error_code +krb5_string_to_deltat(const char *str, krb5_deltat *t) { + return 1; +} + +static void krb5_clear_error_message(krb5_context context) { + return; +} + +static void krb5_set_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, ...) { + return; +} + +/* Play it safe, by saying we're always suid. */ +static int issuid(void) { + return 1; +} + +static int _krb5_homedir_access(krb5_context context) { + return 0; +} + +static krb5_error_code +krb5_abortx(krb5_context context, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + vfprintf(stderr, fmt, ap); + va_end(ap); + + abort(); +} + +/* Wrappers */ + +int +afs_config_parse_file_multi(const char *fname, afs_config_section **res) { + return krb5_config_parse_file_multi(NULL, fname, res); +} + +int +afs_config_parse_file(const char *fname, afs_config_section **res) { + return krb5_config_parse_file(NULL, fname, res); +} + +int +afs_config_file_free(afs_config_section *s) { + return krb5_config_file_free(NULL, s); +} + +const char* +afs_config_get_string(const afs_config_section *c, ...) +{ + const char *ret; + va_list args; + + assert(c != NULL); + + va_start(args, c); + ret = krb5_config_vget_string (NULL, c, args); + va_end(args); + return ret; +} + +int +afs_config_get_bool(const afs_config_section *c, ...) +{ + va_list ap; + krb5_boolean ret; + + assert(c != NULL); + + va_start(ap, c); + ret = krb5_config_vget_bool (NULL, c, ap); + va_end(ap); + return ret; +} + +int +afs_config_get_int(const krb5_config_section *c, ...) +{ + va_list ap; + int ret; + + assert(c != NULL); + + va_start(ap, c); + ret = krb5_config_vget_int (NULL, c, ap); + va_end(ap); + return ret; +} + -- 2.39.5