gss: pass GSS_C_NO_OID name type through to mechanism
[heimdal.git] / lib / base / context.c
blobfb9b442ce1e43218088b62cba17bb49f2fd4a825
1 /*
2 * Copyright (c) 2020 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "baselocl.h"
36 #undef __attribute__
37 #define __attribute__(X)
39 heim_context
40 heim_context_init(void)
42 heim_context context;
44 if ((context = calloc(1, sizeof(*context))) == NULL)
45 return NULL;
47 context->homedir_access = !issuid();
48 context->log_utc = 1;
49 context->error_string = NULL;
50 context->debug_dest = NULL;
51 context->warn_dest = NULL;
52 context->log_dest = NULL;
53 context->time_fmt = NULL;
54 context->et_list = NULL;
55 return context;
58 void
59 heim_context_free(heim_context *contextp)
61 heim_context context = *contextp;
63 *contextp = NULL;
64 if (!context)
65 return;
66 heim_closelog(context, context->debug_dest);
67 heim_closelog(context, context->warn_dest);
68 heim_closelog(context, context->log_dest);
69 free_error_table(context->et_list);
70 free(context->time_fmt);
71 free(context->error_string);
72 free(context);
75 heim_error_code
76 heim_add_et_list(heim_context context, void (*func)(struct et_list **))
78 (*func)(&context->et_list);
79 return 0;
82 heim_error_code
83 heim_context_set_time_fmt(heim_context context, const char *fmt)
85 char *s;
87 if (fmt == NULL) {
88 free(context->time_fmt);
89 return 0;
91 if ((s = strdup(fmt)) == NULL)
92 return heim_enomem(context);
93 free(context->time_fmt);
94 context->time_fmt = s;
95 return 0;
98 const char *
99 heim_context_get_time_fmt(heim_context context)
101 return context->time_fmt ? context->time_fmt : "%Y-%m-%dT%H:%M:%S";
104 unsigned int
105 heim_context_set_log_utc(heim_context context, unsigned int log_utc)
107 unsigned int old = context->log_utc;
109 context->log_utc = log_utc ? 1 : 0;
110 return old;
114 heim_context_get_log_utc(heim_context context)
116 return context->log_utc;
119 unsigned int
120 heim_context_set_homedir_access(heim_context context, unsigned int homedir_access)
122 unsigned int old = context->homedir_access;
124 context->homedir_access = homedir_access ? 1 : 0;
125 return old;
128 unsigned int
129 heim_context_get_homedir_access(heim_context context)
131 return context->homedir_access;
134 heim_error_code
135 heim_enomem(heim_context context)
137 heim_set_error_message(context, ENOMEM, "malloc: out of memory");
138 return ENOMEM;
141 heim_log_facility *
142 heim_get_log_dest(heim_context context)
144 return context->log_dest;
147 heim_log_facility *
148 heim_get_warn_dest(heim_context context)
150 return context->warn_dest;
153 heim_log_facility *
154 heim_get_debug_dest(heim_context context)
156 return context->debug_dest;
159 heim_error_code
160 heim_set_log_dest(heim_context context, heim_log_facility *fac)
162 context->log_dest = fac;
163 return 0;
166 heim_error_code
167 heim_set_warn_dest(heim_context context, heim_log_facility *fac)
169 context->warn_dest = fac;
170 return 0;
173 heim_error_code
174 heim_set_debug_dest(heim_context context, heim_log_facility *fac)
176 context->debug_dest = fac;
177 return 0;
180 #ifndef PATH_SEP
181 # define PATH_SEP ":"
182 #endif
184 static heim_error_code
185 add_file(char ***pfilenames, int *len, char *file)
187 char **pp = *pfilenames;
188 int i;
190 for(i = 0; i < *len; i++) {
191 if(strcmp(pp[i], file) == 0) {
192 free(file);
193 return 0;
197 pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp));
198 if (pp == NULL) {
199 free(file);
200 return ENOMEM;
203 pp[*len] = file;
204 pp[*len + 1] = NULL;
205 *pfilenames = pp;
206 *len += 1;
207 return 0;
210 #ifdef WIN32
211 static char *
212 get_default_config_config_files_from_registry(const char *envvar)
214 static const char *KeyName = "Software\\Heimdal"; /* XXX #define this */
215 const char *ValueName;
216 char *config_file = NULL;
217 LONG rcode;
218 HKEY key;
220 if (stricmp(envvar, "KRB5_CONFIG") == 0)
221 ValueName = "config";
222 else
223 ValueName = envvar;
225 rcode = RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, &key);
226 if (rcode == ERROR_SUCCESS) {
227 config_file = heim_parse_reg_value_as_multi_string(NULL, key, ValueName,
228 REG_NONE, 0, PATH_SEP);
229 RegCloseKey(key);
232 if (config_file)
233 return config_file;
235 rcode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &key);
236 if (rcode == ERROR_SUCCESS) {
237 config_file = heim_parse_reg_value_as_multi_string(NULL, key, ValueName,
238 REG_NONE, 0, PATH_SEP);
239 RegCloseKey(key);
242 return config_file;
244 #endif
246 heim_error_code
247 heim_prepend_config_files(const char *filelist,
248 char **pq,
249 char ***ret_pp)
251 heim_error_code ret;
252 const char *p, *q;
253 char **pp;
254 int len;
255 char *fn;
257 pp = NULL;
259 len = 0;
260 p = filelist;
261 while(1) {
262 ssize_t l;
263 q = p;
264 l = strsep_copy(&q, PATH_SEP, NULL, 0);
265 if(l == -1)
266 break;
267 fn = malloc(l + 1);
268 if(fn == NULL) {
269 heim_free_config_files(pp);
270 return ENOMEM;
272 (void) strsep_copy(&p, PATH_SEP, fn, l + 1);
273 ret = add_file(&pp, &len, fn);
274 if (ret) {
275 heim_free_config_files(pp);
276 return ret;
280 if (pq != NULL) {
281 int i;
283 for (i = 0; pq[i] != NULL; i++) {
284 fn = strdup(pq[i]);
285 if (fn == NULL) {
286 heim_free_config_files(pp);
287 return ENOMEM;
289 ret = add_file(&pp, &len, fn);
290 if (ret) {
291 heim_free_config_files(pp);
292 return ret;
297 *ret_pp = pp;
298 return 0;
301 heim_error_code
302 heim_prepend_config_files_default(const char *prepend,
303 const char *def,
304 const char *envvar,
305 char ***pfilenames)
307 heim_error_code ret;
308 char **defpp, **pp = NULL;
310 ret = heim_get_default_config_files(def, envvar, &defpp);
311 if (ret)
312 return ret;
314 ret = heim_prepend_config_files(prepend, defpp, &pp);
315 heim_free_config_files(defpp);
316 if (ret) {
317 return ret;
319 *pfilenames = pp;
320 return 0;
323 heim_error_code
324 heim_get_default_config_files(const char *def,
325 const char *envvar,
326 char ***pfilenames)
328 const char *files = NULL;
330 files = secure_getenv(envvar);
332 #ifdef _WIN32
333 if (files == NULL) {
334 char * reg_files;
335 reg_files = get_default_config_config_files_from_registry(envvar);
336 if (reg_files != NULL) {
337 heim_error_code code;
339 code = heim_prepend_config_files(reg_files, NULL, pfilenames);
340 free(reg_files);
342 return code;
345 #endif
347 if (files == NULL)
348 files = def;
349 return heim_prepend_config_files(files, NULL, pfilenames);
352 #ifdef _WIN32
353 #define REGPATH_KERBEROS "SOFTWARE\\Kerberos"
354 #define REGPATH_HEIMDAL "SOFTWARE\\Heimdal"
355 #endif
357 heim_error_code
358 heim_set_config_files(heim_context context, char **filenames,
359 heim_config_binding **res)
361 heim_error_code ret = 0;
363 *res = NULL;
364 while (filenames != NULL && *filenames != NULL && **filenames != '\0') {
365 ret = heim_config_parse_file_multi(context, *filenames, res);
366 if (ret != 0 && ret != ENOENT && ret != EACCES && ret != EPERM
367 && ret != HEIM_ERR_CONFIG_BADFORMAT) {
368 heim_config_file_free(context, *res);
369 *res = NULL;
370 return ret;
372 filenames++;
375 #ifdef _WIN32
377 * We always ignored errors from loading from the registry, so we still do.
379 heim_load_config_from_registry(context, REGPATH_KERBEROS,
380 REGPATH_HEIMDAL, res);
382 #endif
383 return 0;
386 void
387 heim_free_config_files(char **filenames)
389 char **p;
391 for (p = filenames; p && *p != NULL; p++)
392 free(*p);
393 free(filenames);