Add an OpenAFS config file parser
authorSimon Wilkinson <sxw@your-file-system.com>
Tue, 27 Apr 2010 21:53:47 +0000 (22:53 +0100)
committerDerrick Brashear <shadow@dementia.org>
Wed, 26 May 2010 16:38:04 +0000 (09:38 -0700)
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 <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/util/Makefile.in
src/util/afsutil_prototypes.h
src/util/krb5_locl.h [new file with mode: 0644]

index c39998f..82ba680 100644 (file)
@@ -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
 
index 919cfc6..c881ff4 100644 (file)
@@ -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 (file)
index 0000000..f6fde3a
--- /dev/null
@@ -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 <afsconfig.h>
+#include <afs/stds.h>
+
+#include <time.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <assert.h>
+
+#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;
+}
+