Coverage Report

Created: 2026-01-16 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/base/context.c
Line
Count
Source
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
heim_context_init(void)
41
0
{
42
0
    heim_context context;
43
44
0
    if ((context = calloc(1, sizeof(*context))) == NULL)
45
0
        return NULL;
46
47
0
    context->homedir_access = !issuid();
48
0
    context->log_utc = 1;
49
0
    context->error_string = NULL;
50
0
    context->debug_dest = NULL;
51
0
    context->warn_dest = NULL;
52
0
    context->log_dest = NULL;
53
0
    context->time_fmt = NULL;
54
0
    context->et_list = NULL;
55
0
    return context;
56
0
}
57
58
void
59
heim_context_free(heim_context *contextp)
60
0
{
61
0
    heim_context context = *contextp;
62
63
0
    *contextp = NULL;
64
0
    if (!context)
65
0
        return;
66
0
    heim_closelog(context, context->debug_dest);
67
0
    heim_closelog(context, context->warn_dest);
68
0
    heim_closelog(context, context->log_dest);
69
0
    free_error_table(context->et_list);
70
0
    free(context->time_fmt);
71
0
    free(context->error_string);
72
0
    free(context);
73
0
}
74
75
heim_error_code
76
heim_add_et_list(heim_context context, void (*func)(struct et_list **))
77
0
{
78
0
    (*func)(&context->et_list);
79
0
    return 0;
80
0
}
81
82
heim_error_code
83
heim_context_set_time_fmt(heim_context context, const char *fmt)
84
0
{
85
0
    char *s;
86
87
0
    if (fmt == NULL) {
88
0
        free(context->time_fmt);
89
0
        return 0;
90
0
    }
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
0
}
97
98
const char *
99
heim_context_get_time_fmt(heim_context context)
100
0
{
101
0
    return context->time_fmt ? context->time_fmt : "%Y-%m-%dT%H:%M:%S";
102
0
}
103
104
unsigned int
105
heim_context_set_log_utc(heim_context context, unsigned int log_utc)
106
0
{
107
0
    unsigned int old = context->log_utc;
108
109
0
    context->log_utc = log_utc ? 1 : 0;
110
0
    return old;
111
0
}
112
113
int
114
heim_context_get_log_utc(heim_context context)
115
0
{
116
0
    return context->log_utc;
117
0
}
118
119
unsigned int
120
heim_context_set_homedir_access(heim_context context, unsigned int homedir_access)
121
0
{
122
0
    unsigned int old = context->homedir_access;
123
124
0
    context->homedir_access = homedir_access ? 1 : 0;
125
0
    return old;
126
0
}
127
128
unsigned int
129
heim_context_get_homedir_access(heim_context context)
130
0
{
131
0
    return context->homedir_access;
132
0
}
133
134
heim_error_code
135
heim_enomem(heim_context context)
136
0
{
137
0
    heim_set_error_message(context, ENOMEM, "malloc: out of memory");
138
0
    return ENOMEM;
139
0
}
140
141
heim_log_facility *
142
heim_get_log_dest(heim_context context)
143
0
{
144
0
    return context->log_dest;
145
0
}
146
147
heim_log_facility *
148
heim_get_warn_dest(heim_context context)
149
0
{
150
0
    return context->warn_dest;
151
0
}
152
153
heim_log_facility *
154
heim_get_debug_dest(heim_context context)
155
0
{
156
0
    return context->debug_dest;
157
0
}
158
159
heim_error_code
160
heim_set_log_dest(heim_context context, heim_log_facility *fac)
161
0
{
162
0
    context->log_dest = heim_log_ref(fac);
163
0
    return 0;
164
0
}
165
166
heim_error_code
167
heim_set_warn_dest(heim_context context, heim_log_facility *fac)
168
0
{
169
0
    context->warn_dest = fac;
170
0
    return 0;
171
0
}
172
173
heim_error_code
174
heim_set_debug_dest(heim_context context, heim_log_facility *fac)
175
0
{
176
0
    context->debug_dest = fac;
177
0
    return 0;
178
0
}
179
180
#ifndef PATH_SEP
181
0
# define PATH_SEP ":"
182
#endif
183
184
static heim_error_code
185
add_file(char ***pfilenames, int *len, char *file)
186
0
{
187
0
    char **pp = *pfilenames;
188
0
    int i;
189
190
0
    for(i = 0; i < *len; i++) {
191
0
        if(strcmp(pp[i], file) == 0) {
192
0
            free(file);
193
0
            return 0;
194
0
        }
195
0
    }
196
197
0
    pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp));
198
0
    if (pp == NULL) {
199
0
        free(file);
200
0
        return ENOMEM;
201
0
    }
202
203
0
    pp[*len] = file;
204
0
    pp[*len + 1] = NULL;
205
0
    *pfilenames = pp;
206
0
    *len += 1;
207
0
    return 0;
208
0
}
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
heim_prepend_config_files(const char *filelist,
248
                          char **pq,
249
                          char ***ret_pp)
250
0
{
251
0
    heim_error_code ret;
252
0
    const char *p, *q;
253
0
    char **pp;
254
0
    int len;
255
0
    char *fn;
256
257
0
    pp = NULL;
258
259
0
    len = 0;
260
0
    p = filelist;
261
0
    while(1) {
262
0
        ssize_t l;
263
0
        q = p;
264
0
        l = strsep_copy(&q, PATH_SEP, NULL, 0);
265
0
        if(l == -1)
266
0
            break;
267
0
        fn = malloc(l + 1);
268
0
        if(fn == NULL) {
269
0
            heim_free_config_files(pp);
270
0
            return ENOMEM;
271
0
        }
272
0
        (void) strsep_copy(&p, PATH_SEP, fn, l + 1);
273
0
        ret = add_file(&pp, &len, fn);
274
0
        if (ret) {
275
0
            heim_free_config_files(pp);
276
0
            return ret;
277
0
        }
278
0
    }
279
280
0
    if (pq != NULL) {
281
0
        int i;
282
283
0
        for (i = 0; pq[i] != NULL; i++) {
284
0
            fn = strdup(pq[i]);
285
0
            if (fn == NULL) {
286
0
                heim_free_config_files(pp);
287
0
                return ENOMEM;
288
0
            }
289
0
            ret = add_file(&pp, &len, fn);
290
0
            if (ret) {
291
0
                heim_free_config_files(pp);
292
0
                return ret;
293
0
            }
294
0
        }
295
0
    }
296
297
0
    *ret_pp = pp;
298
0
    return 0;
299
0
}
300
301
heim_error_code
302
heim_prepend_config_files_default(const char *prepend,
303
                                  const char *def,
304
                                  const char *envvar,
305
                                  char ***pfilenames)
306
0
{
307
0
    heim_error_code ret;
308
0
    char **defpp, **pp = NULL;
309
310
0
    ret = heim_get_default_config_files(def, envvar, &defpp);
311
0
    if (ret)
312
0
        return ret;
313
314
0
    ret = heim_prepend_config_files(prepend, defpp, &pp);
315
0
    heim_free_config_files(defpp);
316
0
    if (ret) {
317
0
        return ret;
318
0
    }
319
0
    *pfilenames = pp;
320
0
    return 0;
321
0
}
322
323
heim_error_code
324
heim_get_default_config_files(const char *def,
325
                              const char *envvar,
326
                              char ***pfilenames)
327
0
{
328
0
    const char *files = NULL;
329
330
0
    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
0
    if (files == NULL)
348
0
        files = def;
349
0
    return heim_prepend_config_files(files, NULL, pfilenames);
350
0
}
351
352
#ifdef _WIN32
353
#define REGPATH_KERBEROS "SOFTWARE\\Kerberos"
354
#define REGPATH_HEIMDAL  "SOFTWARE\\Heimdal"
355
#endif
356
357
heim_error_code
358
heim_set_config_files(heim_context context, char **filenames,
359
                      heim_config_binding **res)
360
0
{
361
0
    heim_error_code ret = 0;
362
363
0
    *res = NULL;
364
0
    while (filenames != NULL && *filenames != NULL && **filenames != '\0') {
365
0
        ret = heim_config_parse_file_multi(context, *filenames, res);
366
0
        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
0
        }
372
0
        filenames++;
373
0
    }
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
0
    return 0;
384
0
}
385
386
void
387
heim_free_config_files(char **filenames)
388
0
{
389
0
    char **p;
390
391
0
    for (p = filenames; p && *p != NULL; p++)
392
0
        free(*p);
393
0
    free(filenames);
394
0
}