summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/lib/base/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/lib/base/context.c')
-rw-r--r--third_party/heimdal/lib/base/context.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/base/context.c b/third_party/heimdal/lib/base/context.c
new file mode 100644
index 0000000..f22ce94
--- /dev/null
+++ b/third_party/heimdal/lib/base/context.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2020 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "baselocl.h"
+
+#undef __attribute__
+#define __attribute__(X)
+
+heim_context
+heim_context_init(void)
+{
+ heim_context context;
+
+ if ((context = calloc(1, sizeof(*context))) == NULL)
+ return NULL;
+
+ context->homedir_access = !issuid();
+ context->log_utc = 1;
+ context->error_string = NULL;
+ context->debug_dest = NULL;
+ context->warn_dest = NULL;
+ context->log_dest = NULL;
+ context->time_fmt = NULL;
+ context->et_list = NULL;
+ return context;
+}
+
+void
+heim_context_free(heim_context *contextp)
+{
+ heim_context context = *contextp;
+
+ *contextp = NULL;
+ if (!context)
+ return;
+ heim_closelog(context, context->debug_dest);
+ heim_closelog(context, context->warn_dest);
+ heim_closelog(context, context->log_dest);
+ free_error_table(context->et_list);
+ free(context->time_fmt);
+ free(context->error_string);
+ free(context);
+}
+
+heim_error_code
+heim_add_et_list(heim_context context, void (*func)(struct et_list **))
+{
+ (*func)(&context->et_list);
+ return 0;
+}
+
+heim_error_code
+heim_context_set_time_fmt(heim_context context, const char *fmt)
+{
+ char *s;
+
+ if (fmt == NULL) {
+ free(context->time_fmt);
+ return 0;
+ }
+ if ((s = strdup(fmt)) == NULL)
+ return heim_enomem(context);
+ free(context->time_fmt);
+ context->time_fmt = s;
+ return 0;
+}
+
+const char *
+heim_context_get_time_fmt(heim_context context)
+{
+ return context->time_fmt ? context->time_fmt : "%Y-%m-%dT%H:%M:%S";
+}
+
+unsigned int
+heim_context_set_log_utc(heim_context context, unsigned int log_utc)
+{
+ unsigned int old = context->log_utc;
+
+ context->log_utc = log_utc ? 1 : 0;
+ return old;
+}
+
+int
+heim_context_get_log_utc(heim_context context)
+{
+ return context->log_utc;
+}
+
+unsigned int
+heim_context_set_homedir_access(heim_context context, unsigned int homedir_access)
+{
+ unsigned int old = context->homedir_access;
+
+ context->homedir_access = homedir_access ? 1 : 0;
+ return old;
+}
+
+unsigned int
+heim_context_get_homedir_access(heim_context context)
+{
+ return context->homedir_access;
+}
+
+heim_error_code
+heim_enomem(heim_context context)
+{
+ heim_set_error_message(context, ENOMEM, "malloc: out of memory");
+ return ENOMEM;
+}
+
+heim_log_facility *
+heim_get_log_dest(heim_context context)
+{
+ return context->log_dest;
+}
+
+heim_log_facility *
+heim_get_warn_dest(heim_context context)
+{
+ return context->warn_dest;
+}
+
+heim_log_facility *
+heim_get_debug_dest(heim_context context)
+{
+ return context->debug_dest;
+}
+
+heim_error_code
+heim_set_log_dest(heim_context context, heim_log_facility *fac)
+{
+ context->log_dest = heim_log_ref(fac);
+ return 0;
+}
+
+heim_error_code
+heim_set_warn_dest(heim_context context, heim_log_facility *fac)
+{
+ context->warn_dest = fac;
+ return 0;
+}
+
+heim_error_code
+heim_set_debug_dest(heim_context context, heim_log_facility *fac)
+{
+ context->debug_dest = fac;
+ return 0;
+}
+
+#ifndef PATH_SEP
+# define PATH_SEP ":"
+#endif
+
+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(const char *envvar)
+{
+ static const char *KeyName = "Software\\Heimdal"; /* XXX #define this */
+ const char *ValueName;
+ char *config_file = NULL;
+ LONG rcode;
+ HKEY key;
+
+ if (stricmp(envvar, "KRB5_CONFIG") == 0)
+ ValueName = "config";
+ else
+ ValueName = envvar;
+
+ 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, ValueName,
+ 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, ValueName,
+ 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(envvar);
+ 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 = 0;
+
+ *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
+ /*
+ * We always ignored errors from loading from the registry, so we still do.
+ */
+ heim_load_config_from_registry(context, REGPATH_KERBEROS,
+ REGPATH_HEIMDAL, res);
+
+#endif
+ return 0;
+}
+
+void
+heim_free_config_files(char **filenames)
+{
+ char **p;
+
+ for (p = filenames; p && *p != NULL; p++)
+ free(*p);
+ free(filenames);
+}