Line data Source code
1 : /*
2 : * Copyright (c) 2020 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
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.
16 : *
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.
20 : *
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.
32 : */
33 :
34 : #include "baselocl.h"
35 :
36 : #undef __attribute__
37 : #define __attribute__(X)
38 :
39 : heim_context
40 1584004 : heim_context_init(void)
41 : {
42 39020 : heim_context context;
43 :
44 1584004 : if ((context = calloc(1, sizeof(*context))) == NULL)
45 0 : return NULL;
46 :
47 1584004 : context->homedir_access = !issuid();
48 1584004 : context->log_utc = 1;
49 1584004 : context->error_string = NULL;
50 1584004 : context->debug_dest = NULL;
51 1584004 : context->warn_dest = NULL;
52 1584004 : context->log_dest = NULL;
53 1584004 : context->time_fmt = NULL;
54 1584004 : context->et_list = NULL;
55 1584004 : return context;
56 : }
57 :
58 : void
59 1506342 : heim_context_free(heim_context *contextp)
60 : {
61 1506342 : heim_context context = *contextp;
62 :
63 1506342 : *contextp = NULL;
64 1506342 : if (!context)
65 0 : return;
66 1506342 : heim_closelog(context, context->debug_dest);
67 1506342 : heim_closelog(context, context->warn_dest);
68 1506342 : heim_closelog(context, context->log_dest);
69 1506342 : free_error_table(context->et_list);
70 1506342 : free(context->time_fmt);
71 1506342 : free(context->error_string);
72 1506342 : free(context);
73 : }
74 :
75 : heim_error_code
76 4788602 : heim_add_et_list(heim_context context, void (*func)(struct et_list **))
77 : {
78 4788602 : (*func)(&context->et_list);
79 4788602 : return 0;
80 : }
81 :
82 : heim_error_code
83 0 : heim_context_set_time_fmt(heim_context context, const char *fmt)
84 : {
85 0 : char *s;
86 :
87 0 : if (fmt == NULL) {
88 0 : free(context->time_fmt);
89 0 : return 0;
90 : }
91 0 : if ((s = strdup(fmt)) == NULL)
92 0 : return heim_enomem(context);
93 0 : free(context->time_fmt);
94 0 : context->time_fmt = s;
95 0 : return 0;
96 : }
97 :
98 : const char *
99 2182483 : heim_context_get_time_fmt(heim_context context)
100 : {
101 2182483 : return context->time_fmt ? context->time_fmt : "%Y-%m-%dT%H:%M:%S";
102 : }
103 :
104 : unsigned int
105 792002 : heim_context_set_log_utc(heim_context context, unsigned int log_utc)
106 : {
107 792002 : unsigned int old = context->log_utc;
108 :
109 792002 : context->log_utc = log_utc ? 1 : 0;
110 792002 : return old;
111 : }
112 :
113 : int
114 2182483 : heim_context_get_log_utc(heim_context context)
115 : {
116 2182483 : return context->log_utc;
117 : }
118 :
119 : unsigned int
120 0 : heim_context_set_homedir_access(heim_context context, unsigned int homedir_access)
121 : {
122 0 : unsigned int old = context->homedir_access;
123 :
124 0 : context->homedir_access = homedir_access ? 1 : 0;
125 0 : return old;
126 : }
127 :
128 : unsigned int
129 792122 : heim_context_get_homedir_access(heim_context context)
130 : {
131 792122 : return context->homedir_access;
132 : }
133 :
134 : heim_error_code
135 0 : heim_enomem(heim_context context)
136 : {
137 0 : heim_set_error_message(context, ENOMEM, "malloc: out of memory");
138 0 : return ENOMEM;
139 : }
140 :
141 : heim_log_facility *
142 0 : heim_get_log_dest(heim_context context)
143 : {
144 0 : return context->log_dest;
145 : }
146 :
147 : heim_log_facility *
148 1553 : heim_get_warn_dest(heim_context context)
149 : {
150 1553 : return context->warn_dest;
151 : }
152 :
153 : heim_log_facility *
154 5863884 : heim_get_debug_dest(heim_context context)
155 : {
156 5863884 : return context->debug_dest;
157 : }
158 :
159 : heim_error_code
160 0 : heim_set_log_dest(heim_context context, heim_log_facility *fac)
161 : {
162 0 : context->log_dest = heim_log_ref(fac);
163 0 : return 0;
164 : }
165 :
166 : heim_error_code
167 1104727 : heim_set_warn_dest(heim_context context, heim_log_facility *fac)
168 : {
169 1104727 : context->warn_dest = fac;
170 1104727 : return 0;
171 : }
172 :
173 : heim_error_code
174 5 : heim_set_debug_dest(heim_context context, heim_log_facility *fac)
175 : {
176 5 : context->debug_dest = fac;
177 5 : return 0;
178 : }
179 :
180 : #ifndef PATH_SEP
181 : # define PATH_SEP ":"
182 : #endif
183 :
184 : static heim_error_code
185 4829696 : add_file(char ***pfilenames, int *len, char *file)
186 : {
187 4829696 : char **pp = *pfilenames;
188 117538 : int i;
189 :
190 6485308 : for(i = 0; i < *len; i++) {
191 2930282 : if(strcmp(pp[i], file) == 0) {
192 1274670 : free(file);
193 1274670 : return 0;
194 : }
195 : }
196 :
197 3555026 : pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp));
198 3555026 : if (pp == NULL) {
199 0 : free(file);
200 0 : return ENOMEM;
201 : }
202 :
203 3555026 : pp[*len] = file;
204 3555026 : pp[*len + 1] = NULL;
205 3555026 : *pfilenames = pp;
206 3555026 : *len += 1;
207 3555026 : return 0;
208 : }
209 :
210 : #ifdef WIN32
211 : static char *
212 : get_default_config_config_files_from_registry(const char *envvar)
213 : {
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;
219 :
220 : if (stricmp(envvar, "KRB5_CONFIG") == 0)
221 : ValueName = "config";
222 : else
223 : ValueName = envvar;
224 :
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);
230 : }
231 :
232 : if (config_file)
233 : return config_file;
234 :
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);
240 : }
241 :
242 : return config_file;
243 : }
244 : #endif
245 :
246 : heim_error_code
247 2691596 : heim_prepend_config_files(const char *filelist,
248 : char **pq,
249 : char ***ret_pp)
250 : {
251 65332 : heim_error_code ret;
252 65332 : const char *p, *q;
253 65332 : char **pp;
254 65332 : int len;
255 65332 : char *fn;
256 :
257 2691596 : pp = NULL;
258 :
259 2691596 : len = 0;
260 2691596 : p = filelist;
261 4341172 : while(1) {
262 169708 : ssize_t l;
263 6967436 : q = p;
264 6967436 : l = strsep_copy(&q, PATH_SEP, NULL, 0);
265 6967436 : if(l == -1)
266 2626264 : break;
267 4275840 : fn = malloc(l + 1);
268 4275840 : if(fn == NULL) {
269 0 : heim_free_config_files(pp);
270 0 : return ENOMEM;
271 : }
272 4275840 : (void) strsep_copy(&p, PATH_SEP, fn, l + 1);
273 4275840 : ret = add_file(&pp, &len, fn);
274 4275840 : if (ret) {
275 0 : heim_free_config_files(pp);
276 0 : return ret;
277 : }
278 : }
279 :
280 2691596 : if (pq != NULL) {
281 : int i;
282 :
283 1107652 : for (i = 0; pq[i] != NULL; i++) {
284 553856 : fn = strdup(pq[i]);
285 553856 : if (fn == NULL) {
286 0 : heim_free_config_files(pp);
287 0 : return ENOMEM;
288 : }
289 553856 : ret = add_file(&pp, &len, fn);
290 553856 : if (ret) {
291 0 : heim_free_config_files(pp);
292 0 : return ret;
293 : }
294 : }
295 : }
296 :
297 2691596 : *ret_pp = pp;
298 2691596 : return 0;
299 : }
300 :
301 : heim_error_code
302 553796 : heim_prepend_config_files_default(const char *prepend,
303 : const char *def,
304 : const char *envvar,
305 : char ***pfilenames)
306 : {
307 13156 : heim_error_code ret;
308 553796 : char **defpp, **pp = NULL;
309 :
310 553796 : ret = heim_get_default_config_files(def, envvar, &defpp);
311 553796 : if (ret)
312 0 : return ret;
313 :
314 553796 : ret = heim_prepend_config_files(prepend, defpp, &pp);
315 553796 : heim_free_config_files(defpp);
316 553796 : if (ret) {
317 0 : return ret;
318 : }
319 553796 : *pfilenames = pp;
320 553796 : return 0;
321 : }
322 :
323 : heim_error_code
324 2137800 : heim_get_default_config_files(const char *def,
325 : const char *envvar,
326 : char ***pfilenames)
327 : {
328 2137800 : const char *files = NULL;
329 :
330 2137800 : files = secure_getenv(envvar);
331 :
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;
338 :
339 : code = heim_prepend_config_files(reg_files, NULL, pfilenames);
340 : free(reg_files);
341 :
342 : return code;
343 : }
344 : }
345 : #endif
346 :
347 2137800 : if (files == NULL)
348 792122 : files = def;
349 2137800 : return heim_prepend_config_files(files, NULL, pfilenames);
350 : }
351 :
352 : #ifdef _WIN32
353 : #define REGPATH_KERBEROS "SOFTWARE\\Kerberos"
354 : #define REGPATH_HEIMDAL "SOFTWARE\\Heimdal"
355 : #endif
356 :
357 : heim_error_code
358 2137800 : heim_set_config_files(heim_context context, char **filenames,
359 : heim_config_binding **res)
360 : {
361 2137800 : heim_error_code ret = 0;
362 :
363 2137800 : *res = NULL;
364 5138970 : while (filenames != NULL && *filenames != NULL && **filenames != '\0') {
365 3001170 : ret = heim_config_parse_file_multi(context, *filenames, res);
366 3001170 : if (ret != 0 && ret != ENOENT && ret != EACCES && ret != EPERM
367 0 : && ret != HEIM_ERR_CONFIG_BADFORMAT) {
368 0 : heim_config_file_free(context, *res);
369 0 : *res = NULL;
370 0 : return ret;
371 : }
372 3001170 : filenames++;
373 : }
374 :
375 : #ifdef _WIN32
376 : /*
377 : * We always ignored errors from loading from the registry, so we still do.
378 : */
379 : heim_load_config_from_registry(context, REGPATH_KERBEROS,
380 : REGPATH_HEIMDAL, res);
381 :
382 : #endif
383 2085624 : return 0;
384 : }
385 :
386 : void
387 2691596 : heim_free_config_files(char **filenames)
388 : {
389 65332 : char **p;
390 :
391 6246622 : for (p = filenames; p && *p != NULL; p++)
392 3555026 : free(*p);
393 2691596 : free(filenames);
394 2691596 : }
|