Move more config file code from krb5 to base
authorNicolas Williams <nico@twosigma.com>
Tue, 3 Mar 2020 04:26:17 +0000 (22:26 -0600)
committerNicolas Williams <nico@twosigma.com>
Fri, 24 Apr 2020 05:11:56 +0000 (00:11 -0500)
lib/base/NTMakefile
lib/base/context.c
lib/base/version-script.map
lib/krb5/context.c

index 2f30d050e80b5190ffeb96c474c0240af62323cd..71466779c326a54ea0097aa547622ef80e0b5f04 100644 (file)
@@ -90,7 +90,7 @@ libheimbase_OBJS =            \
 libheimbase_gen_OBJS= $(OBJ)\heim_err.obj
 
 $(LIBHEIMBASE): $(libheimbase_OBJS) $(libheimbase_gen_OBJS)
-       $(LIBCON_C) -OUT:$@ $(LIBROKEN) $(PTHREAD_LIB) Secur32.lib Shell32.lib Advapi32.lib @<<
+       $(LIBCON_C) -OUT:$@ $(LIBROKEN) $(PTHREAD_LIB) Secur32.lib Shell32.lib Advapi32.lib Shlwapi.lib @<<
 $(libheimbase_OBJS: =
 )
 $(libheimbase_gen_OBJS: =
index 1feabd8c65e877e91b24f519ff74a785420c5068..8bf0c1495d5d31097e0f63cd0fc0878587902442 100644 (file)
@@ -232,3 +232,207 @@ heim_set_debug_dest(heim_context context, heim_log_facility *fac)
     context->debug_dest = fac;
     return 0;
 }
+
+#define PATH_SEP ":"
+
+static heim_error_code
+add_file(char ***pfilenames, int *len, char *file)
+{
+    char **pp = *pfilenames;
+    int i;
+
+    for(i = 0; i < *len; i++) {
+        if(strcmp(pp[i], file) == 0) {
+            free(file);
+            return 0;
+        }
+    }
+
+    pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp));
+    if (pp == NULL) {
+        free(file);
+        return ENOMEM;
+    }
+
+    pp[*len] = file;
+    pp[*len + 1] = NULL;
+    *pfilenames = pp;
+    *len += 1;
+    return 0;
+}
+
+#ifdef WIN32
+static char *
+get_default_config_config_files_from_registry(void)
+{
+    static const char *KeyName = "Software\\Heimdal"; /* XXX #define this */
+    char *config_file = NULL;
+    LONG rcode;
+    HKEY key;
+
+    rcode = RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, &key);
+    if (rcode == ERROR_SUCCESS) {
+        config_file = heim_parse_reg_value_as_multi_string(NULL, key, "config",
+                                                           REG_NONE, 0, PATH_SEP);
+        RegCloseKey(key);
+    }
+
+    if (config_file)
+        return config_file;
+
+    rcode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &key);
+    if (rcode == ERROR_SUCCESS) {
+        config_file = heim_parse_reg_value_as_multi_string(NULL, key, "config",
+                                                           REG_NONE, 0, PATH_SEP);
+        RegCloseKey(key);
+    }
+
+    return config_file;
+}
+#endif
+
+heim_error_code
+heim_prepend_config_files(const char *filelist,
+                          char **pq,
+                          char ***ret_pp)
+{
+    heim_error_code ret;
+    const char *p, *q;
+    char **pp;
+    int len;
+    char *fn;
+
+    pp = NULL;
+
+    len = 0;
+    p = filelist;
+    while(1) {
+        ssize_t l;
+        q = p;
+        l = strsep_copy(&q, PATH_SEP, NULL, 0);
+        if(l == -1)
+            break;
+        fn = malloc(l + 1);
+        if(fn == NULL) {
+            heim_free_config_files(pp);
+            return ENOMEM;
+        }
+        (void) strsep_copy(&p, PATH_SEP, fn, l + 1);
+        ret = add_file(&pp, &len, fn);
+        if (ret) {
+            heim_free_config_files(pp);
+            return ret;
+        }
+    }
+
+    if (pq != NULL) {
+        int i;
+
+        for (i = 0; pq[i] != NULL; i++) {
+            fn = strdup(pq[i]);
+            if (fn == NULL) {
+                heim_free_config_files(pp);
+                return ENOMEM;
+            }
+            ret = add_file(&pp, &len, fn);
+            if (ret) {
+                heim_free_config_files(pp);
+                return ret;
+            }
+        }
+    }
+
+    *ret_pp = pp;
+    return 0;
+}
+
+heim_error_code
+heim_prepend_config_files_default(const char *prepend,
+                                  const char *def,
+                                  const char *envvar,
+                                  char ***pfilenames)
+{
+    heim_error_code ret;
+    char **defpp, **pp = NULL;
+
+    ret = heim_get_default_config_files(def, envvar, &defpp);
+    if (ret)
+        return ret;
+
+    ret = heim_prepend_config_files(prepend, defpp, &pp);
+    heim_free_config_files(defpp);
+    if (ret) {
+        return ret;
+    }
+    *pfilenames = pp;
+    return 0;
+}
+
+heim_error_code
+heim_get_default_config_files(const char *def,
+                              const char *envvar,
+                              char ***pfilenames)
+{
+    const char *files = NULL;
+
+    files = secure_getenv(envvar);
+
+#ifdef _WIN32
+    if (files == NULL) {
+        char * reg_files;
+        reg_files = get_default_config_config_files_from_registry();
+        if (reg_files != NULL) {
+            heim_error_code code;
+
+            code = heim_prepend_config_files(reg_files, NULL, pfilenames);
+            free(reg_files);
+
+            return code;
+        }
+    }
+#endif
+
+    if (files == NULL)
+        files = def;
+    return heim_prepend_config_files(files, NULL, pfilenames);
+}
+
+#ifdef _WIN32
+#define REGPATH_KERBEROS "SOFTWARE\\Kerberos"
+#define REGPATH_HEIMDAL  "SOFTWARE\\Heimdal"
+#endif
+
+heim_error_code
+heim_set_config_files(heim_context context, char **filenames,
+                      heim_config_binding **res)
+{
+    heim_error_code ret;
+
+    *res = NULL;
+    while (filenames != NULL && *filenames != NULL && **filenames != '\0') {
+        ret = heim_config_parse_file_multi(context, *filenames, res);
+        if (ret != 0 && ret != ENOENT && ret != EACCES && ret != EPERM
+            && ret != HEIM_ERR_CONFIG_BADFORMAT) {
+            heim_config_file_free(context, *res);
+            *res = NULL;
+            return ret;
+        }
+        filenames++;
+    }
+
+#ifdef _WIN32
+    heim_load_config_from_registry(context, REGPATH_KERBEROS,
+                                   REGPATH_HEIMDAL, res);
+#endif
+    return ret;
+}
+
+void
+heim_free_config_files(char **filenames)
+{
+    char **p;
+
+    for (p = filenames; p && *p != NULL; p++)
+        free(*p);
+    free(filenames);
+}
index 2d10bab6c5af3bec2cfca90c1c347f58091658ab..e541435343cc1fd91f08b6b545f45d69c6106447 100644 (file)
@@ -1,4 +1,3 @@
-
 HEIMDAL_BASE_1.0 {
        global:
                _bsearch_file;
@@ -117,8 +116,10 @@ HEIMDAL_BASE_1.0 {
                heim_error_get_code;
                heim_expand_path_tokens;
                heim_expand_path_tokensv;
+               heim_free_config_files;
                heim_free_error_message;
                heim_get_debug_dest;
+               heim_get_default_config_files;
                heim_get_error_message;
                heim_get_hash;
                _heim_get_isa;
@@ -149,9 +150,12 @@ HEIMDAL_BASE_1.0 {
                heim_path_vget;
                heim_plugin_register;
                heim_plugin_run_f;
+               heim_prepend_config_files;
+               heim_prepend_config_files_default;
                heim_prepend_error_message;
                heim_release;
                heim_retain;
+               heim_set_config_files;
                heim_set_debug_dest;
                heim_set_error_message;
                heim_set_warn_dest;
index 804460f55281f4af7c246237edc8394f390ad60b..4ca90a8cbcf4631319e122a6d34cb2e02a397952 100644 (file)
@@ -712,11 +712,6 @@ krb5_free_context(krb5_context context)
     free(context);
 }
 
-#ifdef _WIN32
-#define REGPATH_KERBEROS "SOFTWARE\\Kerberos"
-#define REGPATH_HEIMDAL  "SOFTWARE\\Heimdal"
-#endif
-
 /**
  * Reinit the context from a new set of filenames.
  *
@@ -733,31 +728,10 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_set_config_files(krb5_context context, char **filenames)
 {
     krb5_error_code ret;
-    krb5_config_binding *tmp = NULL;
-    while(filenames != NULL && *filenames != NULL && **filenames != '\0') {
-       ret = krb5_config_parse_file_multi(context, *filenames, &tmp);
-       if (ret != 0 && ret != ENOENT && ret != EACCES && ret != EPERM
-           && ret != KRB5_CONFIG_BADFORMAT) {
-           krb5_config_file_free(context, tmp);
-           return ret;
-       }
-       filenames++;
-    }
-#if 0
-    /* with this enabled and if there are no config files, Kerberos is
-       considererd disabled */
-    if(tmp == NULL)
-       return ENXIO;
-#endif
-
-#ifdef _WIN32
-    heim_load_config_from_registry(context->hcontext, REGPATH_KERBEROS,
-                                   REGPATH_HEIMDAL, &tmp);
-#endif
 
-    krb5_config_file_free(context, context->cf);
-    context->cf = tmp;
-    ret = init_context_from_config_file(context);
+    if ((ret = heim_set_config_files(context->hcontext, filenames,
+                                     &context->cf)) == 0)
+        ret = init_context_from_config_file(context);
     return ret;
 }
 
@@ -830,54 +804,7 @@ add_file(char ***pfilenames, int *len, char *file)
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
 {
-    krb5_error_code ret;
-    const char *p, *q;
-    char **pp;
-    int len;
-    char *fn;
-
-    pp = NULL;
-
-    len = 0;
-    p = filelist;
-    while(1) {
-       ssize_t l;
-       q = p;
-       l = strsep_copy(&q, PATH_SEP, NULL, 0);
-       if(l == -1)
-           break;
-       fn = malloc(l + 1);
-       if(fn == NULL) {
-           krb5_free_config_files(pp);
-           return ENOMEM;
-       }
-       (void)strsep_copy(&p, PATH_SEP, fn, l + 1);
-       ret = add_file(&pp, &len, fn);
-       if (ret) {
-           krb5_free_config_files(pp);
-           return ret;
-       }
-    }
-
-    if (pq != NULL) {
-       int i;
-
-       for (i = 0; pq[i] != NULL; i++) {
-           fn = strdup(pq[i]);
-           if (fn == NULL) {
-               krb5_free_config_files(pp);
-               return ENOMEM;
-           }
-           ret = add_file(&pp, &len, fn);
-           if (ret) {
-               krb5_free_config_files(pp);
-               return ret;
-           }
-       }
-    }
-
-    *ret_pp = pp;
-    return 0;
+    return heim_prepend_config_files(filelist, pq, ret_pp);
 }
 
 /**
@@ -895,61 +822,10 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
 {
-    krb5_error_code ret;
-    char **defpp, **pp = NULL;
-
-    ret = krb5_get_default_config_files(&defpp);
-    if (ret)
-       return ret;
-
-    ret = krb5_prepend_config_files(filelist, defpp, &pp);
-    krb5_free_config_files(defpp);
-    if (ret) {
-       return ret;
-    }
-    *pfilenames = pp;
-    return 0;
-}
-
-#ifdef _WIN32
-
-/**
- * Checks the registry for configuration file location
- *
- * Kerberos for Windows and other legacy Kerberos applications expect
- * to find the configuration file location in the
- * SOFTWARE\MIT\Kerberos registry key under the value "config".
- */
-KRB5_LIB_FUNCTION char * KRB5_LIB_CALL
-_krb5_get_default_config_config_files_from_registry()
-{
-    static const char * KeyName = "Software\\MIT\\Kerberos";
-    char *config_file = NULL;
-    LONG rcode;
-    HKEY key;
-
-    rcode = RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, &key);
-    if (rcode == ERROR_SUCCESS) {
-        config_file = heim_parse_reg_value_as_multi_string(NULL, key, "config",
-                                                           REG_NONE, 0, PATH_SEP);
-        RegCloseKey(key);
-    }
-
-    if (config_file)
-        return config_file;
-
-    rcode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &key);
-    if (rcode == ERROR_SUCCESS) {
-        config_file = heim_parse_reg_value_as_multi_string(NULL, key, "config",
-                                                           REG_NONE, 0, PATH_SEP);
-        RegCloseKey(key);
-    }
-
-    return config_file;
+    return heim_prepend_config_files_default(filelist, krb5_config_file,
+                                             "KRB5_CONFIG", pfilenames);
 }
 
-#endif
-
 /**
  * Get the global configuration list.
  *
@@ -964,31 +840,10 @@ _krb5_get_default_config_config_files_from_registry()
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_get_default_config_files(char ***pfilenames)
 {
-    const char *files = NULL;
-
     if (pfilenames == NULL)
         return EINVAL;
-    files = secure_getenv("KRB5_CONFIG");
-
-#ifdef _WIN32
-    if (files == NULL) {
-        char * reg_files;
-        reg_files = _krb5_get_default_config_config_files_from_registry();
-        if (reg_files != NULL) {
-            krb5_error_code code;
-
-            code = krb5_prepend_config_files(reg_files, NULL, pfilenames);
-            free(reg_files);
-
-            return code;
-        }
-    }
-#endif
-
-    if (files == NULL)
-       files = krb5_config_file;
-
-    return krb5_prepend_config_files(files, NULL, pfilenames);
+    return heim_get_default_config_files(krb5_config_file, "KRB5_CONFIG",
+                                         pfilenames);
 }
 
 /**
@@ -1006,10 +861,7 @@ krb5_get_default_config_files(char ***pfilenames)
 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_free_config_files(char **filenames)
 {
-    char **p;
-    for(p = filenames; p && *p != NULL; p++)
-       free(*p);
-    free(filenames);
+    heim_free_config_files(filenames);
 }
 
 /**