Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/krb5/context.c
34878 views
1
/*
2
* Copyright (c) 1997 - 2010 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
*
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
*
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* 3. Neither the name of the Institute nor the names of its contributors
20
* may be used to endorse or promote products derived from this software
21
* without specific prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* SUCH DAMAGE.
34
*/
35
36
#include "krb5_locl.h"
37
#include <assert.h>
38
#include <com_err.h>
39
40
#define INIT_FIELD(C, T, E, D, F) \
41
(C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \
42
"libdefaults", F, NULL)
43
44
#define INIT_FLAG(C, O, V, D, F) \
45
do { \
46
if (krb5_config_get_bool_default((C), NULL, (D),"libdefaults", F, NULL)) { \
47
(C)->O |= V; \
48
} \
49
} while(0)
50
51
/*
52
* Set the list of etypes `ret_etypes' from the configuration variable
53
* `name'
54
*/
55
56
static krb5_error_code
57
set_etypes (krb5_context context,
58
const char *name,
59
krb5_enctype **ret_enctypes)
60
{
61
char **etypes_str;
62
krb5_enctype *etypes = NULL;
63
64
etypes_str = krb5_config_get_strings(context, NULL, "libdefaults",
65
name, NULL);
66
if(etypes_str){
67
int i, j, k;
68
for(i = 0; etypes_str[i]; i++);
69
etypes = malloc((i+1) * sizeof(*etypes));
70
if (etypes == NULL) {
71
krb5_config_free_strings (etypes_str);
72
krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
73
return ENOMEM;
74
}
75
for(j = 0, k = 0; j < i; j++) {
76
krb5_enctype e;
77
if(krb5_string_to_enctype(context, etypes_str[j], &e) != 0)
78
continue;
79
if (krb5_enctype_valid(context, e) != 0)
80
continue;
81
etypes[k++] = e;
82
}
83
etypes[k] = ETYPE_NULL;
84
krb5_config_free_strings(etypes_str);
85
}
86
*ret_enctypes = etypes;
87
return 0;
88
}
89
90
/*
91
* read variables from the configuration file and set in `context'
92
*/
93
94
static krb5_error_code
95
init_context_from_config_file(krb5_context context)
96
{
97
krb5_error_code ret;
98
const char * tmp;
99
char **s;
100
krb5_enctype *tmptypes = NULL;
101
102
INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew");
103
INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout");
104
INIT_FIELD(context, int, max_retries, 3, "max_retries");
105
106
INIT_FIELD(context, string, http_proxy, NULL, "http_proxy");
107
108
ret = krb5_config_get_bool_default(context, NULL, FALSE,
109
"libdefaults",
110
"allow_weak_crypto", NULL);
111
if (ret) {
112
krb5_enctype_enable(context, ETYPE_DES_CBC_CRC);
113
krb5_enctype_enable(context, ETYPE_DES_CBC_MD4);
114
krb5_enctype_enable(context, ETYPE_DES_CBC_MD5);
115
krb5_enctype_enable(context, ETYPE_DES_CBC_NONE);
116
krb5_enctype_enable(context, ETYPE_DES_CFB64_NONE);
117
krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE);
118
}
119
120
ret = set_etypes (context, "default_etypes", &tmptypes);
121
if(ret)
122
return ret;
123
free(context->etypes);
124
context->etypes = tmptypes;
125
126
ret = set_etypes (context, "default_etypes_des", &tmptypes);
127
if(ret)
128
return ret;
129
free(context->etypes_des);
130
context->etypes_des = tmptypes;
131
132
ret = set_etypes (context, "default_as_etypes", &tmptypes);
133
if(ret)
134
return ret;
135
free(context->as_etypes);
136
context->as_etypes = tmptypes;
137
138
ret = set_etypes (context, "default_tgs_etypes", &tmptypes);
139
if(ret)
140
return ret;
141
free(context->tgs_etypes);
142
context->tgs_etypes = tmptypes;
143
144
ret = set_etypes (context, "permitted_enctypes", &tmptypes);
145
if(ret)
146
return ret;
147
free(context->permitted_enctypes);
148
context->permitted_enctypes = tmptypes;
149
150
/* default keytab name */
151
tmp = NULL;
152
if(!issuid())
153
tmp = getenv("KRB5_KTNAME");
154
if(tmp != NULL)
155
context->default_keytab = tmp;
156
else
157
INIT_FIELD(context, string, default_keytab,
158
KEYTAB_DEFAULT, "default_keytab_name");
159
160
INIT_FIELD(context, string, default_keytab_modify,
161
NULL, "default_keytab_modify_name");
162
163
INIT_FIELD(context, string, time_fmt,
164
"%Y-%m-%dT%H:%M:%S", "time_format");
165
166
INIT_FIELD(context, string, date_fmt,
167
"%Y-%m-%d", "date_format");
168
169
INIT_FIELD(context, bool, log_utc,
170
FALSE, "log_utc");
171
172
173
174
/* init dns-proxy slime */
175
tmp = krb5_config_get_string(context, NULL, "libdefaults",
176
"dns_proxy", NULL);
177
if(tmp)
178
roken_gethostby_setup(context->http_proxy, tmp);
179
krb5_free_host_realm (context, context->default_realms);
180
context->default_realms = NULL;
181
182
{
183
krb5_addresses addresses;
184
char **adr, **a;
185
186
krb5_set_extra_addresses(context, NULL);
187
adr = krb5_config_get_strings(context, NULL,
188
"libdefaults",
189
"extra_addresses",
190
NULL);
191
memset(&addresses, 0, sizeof(addresses));
192
for(a = adr; a && *a; a++) {
193
ret = krb5_parse_address(context, *a, &addresses);
194
if (ret == 0) {
195
krb5_add_extra_addresses(context, &addresses);
196
krb5_free_addresses(context, &addresses);
197
}
198
}
199
krb5_config_free_strings(adr);
200
201
krb5_set_ignore_addresses(context, NULL);
202
adr = krb5_config_get_strings(context, NULL,
203
"libdefaults",
204
"ignore_addresses",
205
NULL);
206
memset(&addresses, 0, sizeof(addresses));
207
for(a = adr; a && *a; a++) {
208
ret = krb5_parse_address(context, *a, &addresses);
209
if (ret == 0) {
210
krb5_add_ignore_addresses(context, &addresses);
211
krb5_free_addresses(context, &addresses);
212
}
213
}
214
krb5_config_free_strings(adr);
215
}
216
217
INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces");
218
INIT_FIELD(context, int, fcache_vno, 0, "fcache_version");
219
/* prefer dns_lookup_kdc over srv_lookup. */
220
INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
221
INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc");
222
INIT_FIELD(context, int, large_msg_size, 1400, "large_message_size");
223
INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname");
224
INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac");
225
context->default_cc_name = NULL;
226
context->default_cc_name_set = 0;
227
228
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
229
if(s) {
230
char **p;
231
krb5_initlog(context, "libkrb5", &context->debug_dest);
232
for(p = s; *p; p++)
233
krb5_addlog_dest(context, context->debug_dest, *p);
234
krb5_config_free_strings(s);
235
}
236
237
tmp = krb5_config_get_string(context, NULL, "libdefaults",
238
"check-rd-req-server", NULL);
239
if (tmp == NULL && !issuid())
240
tmp = getenv("KRB5_CHECK_RD_REQ_SERVER");
241
if(tmp) {
242
if (strcasecmp(tmp, "ignore") == 0)
243
context->flags |= KRB5_CTX_F_RD_REQ_IGNORE;
244
}
245
246
return 0;
247
}
248
249
static krb5_error_code
250
cc_ops_register(krb5_context context)
251
{
252
context->cc_ops = NULL;
253
context->num_cc_ops = 0;
254
255
#ifndef KCM_IS_API_CACHE
256
krb5_cc_register(context, &krb5_acc_ops, TRUE);
257
#endif
258
krb5_cc_register(context, &krb5_fcc_ops, TRUE);
259
krb5_cc_register(context, &krb5_mcc_ops, TRUE);
260
#ifdef HAVE_SCC
261
krb5_cc_register(context, &krb5_scc_ops, TRUE);
262
#endif
263
#ifdef HAVE_KCM
264
#ifdef KCM_IS_API_CACHE
265
krb5_cc_register(context, &krb5_akcm_ops, TRUE);
266
#endif
267
krb5_cc_register(context, &krb5_kcm_ops, TRUE);
268
#endif
269
_krb5_load_ccache_plugins(context);
270
return 0;
271
}
272
273
static krb5_error_code
274
cc_ops_copy(krb5_context context, const krb5_context src_context)
275
{
276
const krb5_cc_ops **cc_ops;
277
278
context->cc_ops = NULL;
279
context->num_cc_ops = 0;
280
281
if (src_context->num_cc_ops == 0)
282
return 0;
283
284
cc_ops = malloc(sizeof(cc_ops[0]) * src_context->num_cc_ops);
285
if (cc_ops == NULL) {
286
krb5_set_error_message(context, KRB5_CC_NOMEM,
287
N_("malloc: out of memory", ""));
288
return KRB5_CC_NOMEM;
289
}
290
291
memcpy(rk_UNCONST(cc_ops), src_context->cc_ops,
292
sizeof(cc_ops[0]) * src_context->num_cc_ops);
293
context->cc_ops = cc_ops;
294
context->num_cc_ops = src_context->num_cc_ops;
295
296
return 0;
297
}
298
299
static krb5_error_code
300
kt_ops_register(krb5_context context)
301
{
302
context->num_kt_types = 0;
303
context->kt_types = NULL;
304
305
krb5_kt_register (context, &krb5_fkt_ops);
306
krb5_kt_register (context, &krb5_wrfkt_ops);
307
krb5_kt_register (context, &krb5_javakt_ops);
308
krb5_kt_register (context, &krb5_mkt_ops);
309
#ifndef HEIMDAL_SMALLER
310
krb5_kt_register (context, &krb5_akf_ops);
311
#endif
312
krb5_kt_register (context, &krb5_any_ops);
313
return 0;
314
}
315
316
static krb5_error_code
317
kt_ops_copy(krb5_context context, const krb5_context src_context)
318
{
319
context->num_kt_types = 0;
320
context->kt_types = NULL;
321
322
if (src_context->num_kt_types == 0)
323
return 0;
324
325
context->kt_types = malloc(sizeof(context->kt_types[0]) * src_context->num_kt_types);
326
if (context->kt_types == NULL) {
327
krb5_set_error_message(context, ENOMEM,
328
N_("malloc: out of memory", ""));
329
return ENOMEM;
330
}
331
332
context->num_kt_types = src_context->num_kt_types;
333
memcpy(context->kt_types, src_context->kt_types,
334
sizeof(context->kt_types[0]) * src_context->num_kt_types);
335
336
return 0;
337
}
338
339
static const char *sysplugin_dirs[] = {
340
LIBDIR "/plugin/krb5",
341
#ifdef __APPLE__
342
"/Library/KerberosPlugins/KerberosFrameworkPlugins",
343
"/System/Library/KerberosPlugins/KerberosFrameworkPlugins",
344
#endif
345
NULL
346
};
347
348
static void
349
init_context_once(void *ctx)
350
{
351
krb5_context context = ctx;
352
353
_krb5_load_plugins(context, "krb5", sysplugin_dirs);
354
355
bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR);
356
}
357
358
359
/**
360
* Initializes the context structure and reads the configuration file
361
* /etc/krb5.conf. The structure should be freed by calling
362
* krb5_free_context() when it is no longer being used.
363
*
364
* @param context pointer to returned context
365
*
366
* @return Returns 0 to indicate success. Otherwise an errno code is
367
* returned. Failure means either that something bad happened during
368
* initialization (typically ENOMEM) or that Kerberos should not be
369
* used ENXIO.
370
*
371
* @ingroup krb5
372
*/
373
374
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
375
krb5_init_context(krb5_context *context)
376
{
377
static heim_base_once_t init_context = HEIM_BASE_ONCE_INIT;
378
krb5_context p;
379
krb5_error_code ret;
380
char **files;
381
382
*context = NULL;
383
384
p = calloc(1, sizeof(*p));
385
if(!p)
386
return ENOMEM;
387
388
p->mutex = malloc(sizeof(HEIMDAL_MUTEX));
389
if (p->mutex == NULL) {
390
free(p);
391
return ENOMEM;
392
}
393
HEIMDAL_MUTEX_init(p->mutex);
394
395
ret = fbsd_ossl_provider_load();
396
if(ret)
397
goto out;
398
399
p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;
400
401
ret = krb5_get_default_config_files(&files);
402
if(ret)
403
goto out;
404
ret = krb5_set_config_files(p, files);
405
krb5_free_config_files(files);
406
if(ret)
407
goto out;
408
409
/* init error tables */
410
krb5_init_ets(p);
411
cc_ops_register(p);
412
kt_ops_register(p);
413
414
#ifdef PKINIT
415
ret = hx509_context_init(&p->hx509ctx);
416
if (ret)
417
goto out;
418
#endif
419
if (rk_SOCK_INIT())
420
p->flags |= KRB5_CTX_F_SOCKETS_INITIALIZED;
421
422
out:
423
if(ret) {
424
krb5_free_context(p);
425
p = NULL;
426
} else {
427
heim_base_once_f(&init_context, p, init_context_once);
428
}
429
*context = p;
430
return ret;
431
}
432
433
#ifndef HEIMDAL_SMALLER
434
435
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
436
krb5_get_permitted_enctypes(krb5_context context,
437
krb5_enctype **etypes)
438
{
439
return krb5_get_default_in_tkt_etypes(context, KRB5_PDU_NONE, etypes);
440
}
441
442
/*
443
*
444
*/
445
446
static krb5_error_code
447
copy_etypes (krb5_context context,
448
krb5_enctype *enctypes,
449
krb5_enctype **ret_enctypes)
450
{
451
unsigned int i;
452
453
for (i = 0; enctypes[i]; i++)
454
;
455
i++;
456
457
*ret_enctypes = malloc(sizeof(ret_enctypes[0]) * i);
458
if (*ret_enctypes == NULL) {
459
krb5_set_error_message(context, ENOMEM,
460
N_("malloc: out of memory", ""));
461
return ENOMEM;
462
}
463
memcpy(*ret_enctypes, enctypes, sizeof(ret_enctypes[0]) * i);
464
return 0;
465
}
466
467
/**
468
* Make a copy for the Kerberos 5 context, the new krb5_context shoud
469
* be freed with krb5_free_context().
470
*
471
* @param context the Kerberos context to copy
472
* @param out the copy of the Kerberos, set to NULL error.
473
*
474
* @return Returns 0 to indicate success. Otherwise an kerberos et
475
* error code is returned, see krb5_get_error_message().
476
*
477
* @ingroup krb5
478
*/
479
480
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
481
krb5_copy_context(krb5_context context, krb5_context *out)
482
{
483
krb5_error_code ret;
484
krb5_context p;
485
486
*out = NULL;
487
488
p = calloc(1, sizeof(*p));
489
if (p == NULL) {
490
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
491
return ENOMEM;
492
}
493
494
p->mutex = malloc(sizeof(HEIMDAL_MUTEX));
495
if (p->mutex == NULL) {
496
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
497
free(p);
498
return ENOMEM;
499
}
500
HEIMDAL_MUTEX_init(p->mutex);
501
502
503
if (context->default_cc_name)
504
p->default_cc_name = strdup(context->default_cc_name);
505
if (context->default_cc_name_env)
506
p->default_cc_name_env = strdup(context->default_cc_name_env);
507
508
if (context->etypes) {
509
ret = copy_etypes(context, context->etypes, &p->etypes);
510
if (ret)
511
goto out;
512
}
513
if (context->etypes_des) {
514
ret = copy_etypes(context, context->etypes_des, &p->etypes_des);
515
if (ret)
516
goto out;
517
}
518
519
if (context->default_realms) {
520
ret = krb5_copy_host_realm(context,
521
context->default_realms, &p->default_realms);
522
if (ret)
523
goto out;
524
}
525
526
ret = _krb5_config_copy(context, context->cf, &p->cf);
527
if (ret)
528
goto out;
529
530
/* XXX should copy */
531
krb5_init_ets(p);
532
533
cc_ops_copy(p, context);
534
kt_ops_copy(p, context);
535
536
#if 0 /* XXX */
537
if(context->warn_dest != NULL)
538
;
539
if(context->debug_dest != NULL)
540
;
541
#endif
542
543
ret = krb5_set_extra_addresses(p, context->extra_addresses);
544
if (ret)
545
goto out;
546
ret = krb5_set_extra_addresses(p, context->ignore_addresses);
547
if (ret)
548
goto out;
549
550
ret = _krb5_copy_send_to_kdc_func(p, context);
551
if (ret)
552
goto out;
553
554
*out = p;
555
556
return 0;
557
558
out:
559
krb5_free_context(p);
560
return ret;
561
}
562
563
#endif
564
565
/**
566
* Frees the krb5_context allocated by krb5_init_context().
567
*
568
* @param context context to be freed.
569
*
570
* @ingroup krb5
571
*/
572
573
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
574
krb5_free_context(krb5_context context)
575
{
576
if (context->default_cc_name)
577
free(context->default_cc_name);
578
if (context->default_cc_name_env)
579
free(context->default_cc_name_env);
580
free(context->etypes);
581
free(context->etypes_des);
582
krb5_free_host_realm (context, context->default_realms);
583
krb5_config_file_free (context, context->cf);
584
free_error_table (context->et_list);
585
free(rk_UNCONST(context->cc_ops));
586
free(context->kt_types);
587
krb5_clear_error_message(context);
588
if(context->warn_dest != NULL)
589
krb5_closelog(context, context->warn_dest);
590
if(context->debug_dest != NULL)
591
krb5_closelog(context, context->debug_dest);
592
krb5_set_extra_addresses(context, NULL);
593
krb5_set_ignore_addresses(context, NULL);
594
krb5_set_send_to_kdc_func(context, NULL, NULL);
595
596
#ifdef PKINIT
597
if (context->hx509ctx)
598
hx509_context_free(&context->hx509ctx);
599
#endif
600
601
HEIMDAL_MUTEX_destroy(context->mutex);
602
free(context->mutex);
603
if (context->flags & KRB5_CTX_F_SOCKETS_INITIALIZED) {
604
rk_SOCK_EXIT();
605
}
606
607
memset(context, 0, sizeof(*context));
608
free(context);
609
}
610
611
/**
612
* Reinit the context from a new set of filenames.
613
*
614
* @param context context to add configuration too.
615
* @param filenames array of filenames, end of list is indicated with a NULL filename.
616
*
617
* @return Returns 0 to indicate success. Otherwise an kerberos et
618
* error code is returned, see krb5_get_error_message().
619
*
620
* @ingroup krb5
621
*/
622
623
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
624
krb5_set_config_files(krb5_context context, char **filenames)
625
{
626
krb5_error_code ret;
627
krb5_config_binding *tmp = NULL;
628
while(filenames != NULL && *filenames != NULL && **filenames != '\0') {
629
ret = krb5_config_parse_file_multi(context, *filenames, &tmp);
630
if(ret != 0 && ret != ENOENT && ret != EACCES && ret != EPERM) {
631
krb5_config_file_free(context, tmp);
632
return ret;
633
}
634
filenames++;
635
}
636
#if 0
637
/* with this enabled and if there are no config files, Kerberos is
638
considererd disabled */
639
if(tmp == NULL)
640
return ENXIO;
641
#endif
642
643
#ifdef _WIN32
644
_krb5_load_config_from_registry(context, &tmp);
645
#endif
646
647
krb5_config_file_free(context, context->cf);
648
context->cf = tmp;
649
ret = init_context_from_config_file(context);
650
return ret;
651
}
652
653
static krb5_error_code
654
add_file(char ***pfilenames, int *len, char *file)
655
{
656
char **pp = *pfilenames;
657
int i;
658
659
for(i = 0; i < *len; i++) {
660
if(strcmp(pp[i], file) == 0) {
661
free(file);
662
return 0;
663
}
664
}
665
666
pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp));
667
if (pp == NULL) {
668
free(file);
669
return ENOMEM;
670
}
671
672
pp[*len] = file;
673
pp[*len + 1] = NULL;
674
*pfilenames = pp;
675
*len += 1;
676
return 0;
677
}
678
679
/*
680
* `pq' isn't free, it's up the the caller
681
*/
682
683
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
684
krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
685
{
686
krb5_error_code ret;
687
const char *p, *q;
688
char **pp;
689
int len;
690
char *fn;
691
692
pp = NULL;
693
694
len = 0;
695
p = filelist;
696
while(1) {
697
ssize_t l;
698
q = p;
699
l = strsep_copy(&q, PATH_SEP, NULL, 0);
700
if(l == -1)
701
break;
702
fn = malloc(l + 1);
703
if(fn == NULL) {
704
krb5_free_config_files(pp);
705
return ENOMEM;
706
}
707
(void)strsep_copy(&p, PATH_SEP, fn, l + 1);
708
ret = add_file(&pp, &len, fn);
709
if (ret) {
710
krb5_free_config_files(pp);
711
return ret;
712
}
713
}
714
715
if (pq != NULL) {
716
int i;
717
718
for (i = 0; pq[i] != NULL; i++) {
719
fn = strdup(pq[i]);
720
if (fn == NULL) {
721
krb5_free_config_files(pp);
722
return ENOMEM;
723
}
724
ret = add_file(&pp, &len, fn);
725
if (ret) {
726
krb5_free_config_files(pp);
727
return ret;
728
}
729
}
730
}
731
732
*ret_pp = pp;
733
return 0;
734
}
735
736
/**
737
* Prepend the filename to the global configuration list.
738
*
739
* @param filelist a filename to add to the default list of filename
740
* @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
741
*
742
* @return Returns 0 to indicate success. Otherwise an kerberos et
743
* error code is returned, see krb5_get_error_message().
744
*
745
* @ingroup krb5
746
*/
747
748
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
749
krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
750
{
751
krb5_error_code ret;
752
char **defpp, **pp = NULL;
753
754
ret = krb5_get_default_config_files(&defpp);
755
if (ret)
756
return ret;
757
758
ret = krb5_prepend_config_files(filelist, defpp, &pp);
759
krb5_free_config_files(defpp);
760
if (ret) {
761
return ret;
762
}
763
*pfilenames = pp;
764
return 0;
765
}
766
767
#ifdef _WIN32
768
769
/**
770
* Checks the registry for configuration file location
771
*
772
* Kerberos for Windows and other legacy Kerberos applications expect
773
* to find the configuration file location in the
774
* SOFTWARE\MIT\Kerberos registry key under the value "config".
775
*/
776
char *
777
_krb5_get_default_config_config_files_from_registry()
778
{
779
static const char * KeyName = "Software\\MIT\\Kerberos";
780
char *config_file = NULL;
781
LONG rcode;
782
HKEY key;
783
784
rcode = RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, &key);
785
if (rcode == ERROR_SUCCESS) {
786
config_file = _krb5_parse_reg_value_as_multi_string(NULL, key, "config",
787
REG_NONE, 0, PATH_SEP);
788
RegCloseKey(key);
789
}
790
791
if (config_file)
792
return config_file;
793
794
rcode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &key);
795
if (rcode == ERROR_SUCCESS) {
796
config_file = _krb5_parse_reg_value_as_multi_string(NULL, key, "config",
797
REG_NONE, 0, PATH_SEP);
798
RegCloseKey(key);
799
}
800
801
return config_file;
802
}
803
804
#endif
805
806
/**
807
* Get the global configuration list.
808
*
809
* @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
810
*
811
* @return Returns 0 to indicate success. Otherwise an kerberos et
812
* error code is returned, see krb5_get_error_message().
813
*
814
* @ingroup krb5
815
*/
816
817
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
818
krb5_get_default_config_files(char ***pfilenames)
819
{
820
const char *files = NULL;
821
822
if (pfilenames == NULL)
823
return EINVAL;
824
if(!issuid())
825
files = getenv("KRB5_CONFIG");
826
827
#ifdef _WIN32
828
if (files == NULL) {
829
char * reg_files;
830
reg_files = _krb5_get_default_config_config_files_from_registry();
831
if (reg_files != NULL) {
832
krb5_error_code code;
833
834
code = krb5_prepend_config_files(reg_files, NULL, pfilenames);
835
free(reg_files);
836
837
return code;
838
}
839
}
840
#endif
841
842
if (files == NULL)
843
files = krb5_config_file;
844
845
return krb5_prepend_config_files(files, NULL, pfilenames);
846
}
847
848
/**
849
* Free a list of configuration files.
850
*
851
* @param filenames list, terminated with a NULL pointer, to be
852
* freed. NULL is an valid argument.
853
*
854
* @return Returns 0 to indicate success. Otherwise an kerberos et
855
* error code is returned, see krb5_get_error_message().
856
*
857
* @ingroup krb5
858
*/
859
860
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
861
krb5_free_config_files(char **filenames)
862
{
863
char **p;
864
for(p = filenames; p && *p != NULL; p++)
865
free(*p);
866
free(filenames);
867
}
868
869
/**
870
* Returns the list of Kerberos encryption types sorted in order of
871
* most preferred to least preferred encryption type. Note that some
872
* encryption types might be disabled, so you need to check with
873
* krb5_enctype_valid() before using the encryption type.
874
*
875
* @return list of enctypes, terminated with ETYPE_NULL. Its a static
876
* array completed into the Kerberos library so the content doesn't
877
* need to be freed.
878
*
879
* @ingroup krb5
880
*/
881
882
KRB5_LIB_FUNCTION const krb5_enctype * KRB5_LIB_CALL
883
krb5_kerberos_enctypes(krb5_context context)
884
{
885
static const krb5_enctype p[] = {
886
ETYPE_AES256_CTS_HMAC_SHA1_96,
887
ETYPE_AES128_CTS_HMAC_SHA1_96,
888
ETYPE_DES3_CBC_SHA1,
889
ETYPE_DES3_CBC_MD5,
890
ETYPE_ARCFOUR_HMAC_MD5,
891
ETYPE_DES_CBC_MD5,
892
ETYPE_DES_CBC_MD4,
893
ETYPE_DES_CBC_CRC,
894
ETYPE_NULL
895
};
896
return p;
897
}
898
899
/*
900
*
901
*/
902
903
static krb5_error_code
904
copy_enctypes(krb5_context context,
905
const krb5_enctype *in,
906
krb5_enctype **out)
907
{
908
krb5_enctype *p = NULL;
909
size_t m, n;
910
911
for (n = 0; in[n]; n++)
912
;
913
n++;
914
ALLOC(p, n);
915
if(p == NULL)
916
return krb5_enomem(context);
917
for (n = 0, m = 0; in[n]; n++) {
918
if (krb5_enctype_valid(context, in[n]) != 0)
919
continue;
920
p[m++] = in[n];
921
}
922
p[m] = KRB5_ENCTYPE_NULL;
923
if (m == 0) {
924
free(p);
925
krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
926
N_("no valid enctype set", ""));
927
return KRB5_PROG_ETYPE_NOSUPP;
928
}
929
*out = p;
930
return 0;
931
}
932
933
934
/*
935
* set `etype' to a malloced list of the default enctypes
936
*/
937
938
static krb5_error_code
939
default_etypes(krb5_context context, krb5_enctype **etype)
940
{
941
const krb5_enctype *p = krb5_kerberos_enctypes(context);
942
return copy_enctypes(context, p, etype);
943
}
944
945
/**
946
* Set the default encryption types that will be use in communcation
947
* with the KDC, clients and servers.
948
*
949
* @param context Kerberos 5 context.
950
* @param etypes Encryption types, array terminated with ETYPE_NULL (0).
951
*
952
* @return Returns 0 to indicate success. Otherwise an kerberos et
953
* error code is returned, see krb5_get_error_message().
954
*
955
* @ingroup krb5
956
*/
957
958
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
959
krb5_set_default_in_tkt_etypes(krb5_context context,
960
const krb5_enctype *etypes)
961
{
962
krb5_error_code ret;
963
krb5_enctype *p = NULL;
964
965
if(etypes) {
966
ret = copy_enctypes(context, etypes, &p);
967
if (ret)
968
return ret;
969
}
970
if(context->etypes)
971
free(context->etypes);
972
context->etypes = p;
973
return 0;
974
}
975
976
/**
977
* Get the default encryption types that will be use in communcation
978
* with the KDC, clients and servers.
979
*
980
* @param context Kerberos 5 context.
981
* @param etypes Encryption types, array terminated with
982
* ETYPE_NULL(0), caller should free array with krb5_xfree():
983
*
984
* @return Returns 0 to indicate success. Otherwise an kerberos et
985
* error code is returned, see krb5_get_error_message().
986
*
987
* @ingroup krb5
988
*/
989
990
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
991
krb5_get_default_in_tkt_etypes(krb5_context context,
992
krb5_pdu pdu_type,
993
krb5_enctype **etypes)
994
{
995
krb5_enctype *enctypes = NULL;
996
krb5_error_code ret;
997
krb5_enctype *p;
998
999
heim_assert(pdu_type == KRB5_PDU_AS_REQUEST ||
1000
pdu_type == KRB5_PDU_TGS_REQUEST ||
1001
pdu_type == KRB5_PDU_NONE, "pdu contant not as expected");
1002
1003
if (pdu_type == KRB5_PDU_AS_REQUEST && context->as_etypes != NULL)
1004
enctypes = context->as_etypes;
1005
else if (pdu_type == KRB5_PDU_TGS_REQUEST && context->tgs_etypes != NULL)
1006
enctypes = context->tgs_etypes;
1007
else if (context->etypes != NULL)
1008
enctypes = context->etypes;
1009
1010
if (enctypes != NULL) {
1011
ret = copy_enctypes(context, enctypes, &p);
1012
if (ret)
1013
return ret;
1014
} else {
1015
ret = default_etypes(context, &p);
1016
if (ret)
1017
return ret;
1018
}
1019
*etypes = p;
1020
return 0;
1021
}
1022
1023
/**
1024
* Init the built-in ets in the Kerberos library.
1025
*
1026
* @param context kerberos context to add the ets too
1027
*
1028
* @ingroup krb5
1029
*/
1030
1031
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
1032
krb5_init_ets(krb5_context context)
1033
{
1034
if(context->et_list == NULL){
1035
krb5_add_et_list(context, initialize_krb5_error_table_r);
1036
krb5_add_et_list(context, initialize_asn1_error_table_r);
1037
krb5_add_et_list(context, initialize_heim_error_table_r);
1038
1039
krb5_add_et_list(context, initialize_k524_error_table_r);
1040
1041
#ifdef COM_ERR_BINDDOMAIN_krb5
1042
bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR);
1043
bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR);
1044
bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR);
1045
bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR);
1046
#endif
1047
1048
#ifdef PKINIT
1049
krb5_add_et_list(context, initialize_hx_error_table_r);
1050
#ifdef COM_ERR_BINDDOMAIN_hx
1051
bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR);
1052
#endif
1053
#endif
1054
}
1055
}
1056
1057
/**
1058
* Make the kerberos library default to the admin KDC.
1059
*
1060
* @param context Kerberos 5 context.
1061
* @param flag boolean flag to select if the use the admin KDC or not.
1062
*
1063
* @ingroup krb5
1064
*/
1065
1066
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
1067
krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
1068
{
1069
context->use_admin_kdc = flag;
1070
}
1071
1072
/**
1073
* Make the kerberos library default to the admin KDC.
1074
*
1075
* @param context Kerberos 5 context.
1076
*
1077
* @return boolean flag to telling the context will use admin KDC as the default KDC.
1078
*
1079
* @ingroup krb5
1080
*/
1081
1082
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
1083
krb5_get_use_admin_kdc (krb5_context context)
1084
{
1085
return context->use_admin_kdc;
1086
}
1087
1088
/**
1089
* Add extra address to the address list that the library will add to
1090
* the client's address list when communicating with the KDC.
1091
*
1092
* @param context Kerberos 5 context.
1093
* @param addresses addreses to add
1094
*
1095
* @return Returns 0 to indicate success. Otherwise an kerberos et
1096
* error code is returned, see krb5_get_error_message().
1097
*
1098
* @ingroup krb5
1099
*/
1100
1101
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1102
krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
1103
{
1104
1105
if(context->extra_addresses)
1106
return krb5_append_addresses(context,
1107
context->extra_addresses, addresses);
1108
else
1109
return krb5_set_extra_addresses(context, addresses);
1110
}
1111
1112
/**
1113
* Set extra address to the address list that the library will add to
1114
* the client's address list when communicating with the KDC.
1115
*
1116
* @param context Kerberos 5 context.
1117
* @param addresses addreses to set
1118
*
1119
* @return Returns 0 to indicate success. Otherwise an kerberos et
1120
* error code is returned, see krb5_get_error_message().
1121
*
1122
* @ingroup krb5
1123
*/
1124
1125
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1126
krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
1127
{
1128
if(context->extra_addresses)
1129
krb5_free_addresses(context, context->extra_addresses);
1130
1131
if(addresses == NULL) {
1132
if(context->extra_addresses != NULL) {
1133
free(context->extra_addresses);
1134
context->extra_addresses = NULL;
1135
}
1136
return 0;
1137
}
1138
if(context->extra_addresses == NULL) {
1139
context->extra_addresses = malloc(sizeof(*context->extra_addresses));
1140
if(context->extra_addresses == NULL) {
1141
krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
1142
return ENOMEM;
1143
}
1144
}
1145
return krb5_copy_addresses(context, addresses, context->extra_addresses);
1146
}
1147
1148
/**
1149
* Get extra address to the address list that the library will add to
1150
* the client's address list when communicating with the KDC.
1151
*
1152
* @param context Kerberos 5 context.
1153
* @param addresses addreses to set
1154
*
1155
* @return Returns 0 to indicate success. Otherwise an kerberos et
1156
* error code is returned, see krb5_get_error_message().
1157
*
1158
* @ingroup krb5
1159
*/
1160
1161
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1162
krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
1163
{
1164
if(context->extra_addresses == NULL) {
1165
memset(addresses, 0, sizeof(*addresses));
1166
return 0;
1167
}
1168
return krb5_copy_addresses(context,context->extra_addresses, addresses);
1169
}
1170
1171
/**
1172
* Add extra addresses to ignore when fetching addresses from the
1173
* underlaying operating system.
1174
*
1175
* @param context Kerberos 5 context.
1176
* @param addresses addreses to ignore
1177
*
1178
* @return Returns 0 to indicate success. Otherwise an kerberos et
1179
* error code is returned, see krb5_get_error_message().
1180
*
1181
* @ingroup krb5
1182
*/
1183
1184
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1185
krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
1186
{
1187
1188
if(context->ignore_addresses)
1189
return krb5_append_addresses(context,
1190
context->ignore_addresses, addresses);
1191
else
1192
return krb5_set_ignore_addresses(context, addresses);
1193
}
1194
1195
/**
1196
* Set extra addresses to ignore when fetching addresses from the
1197
* underlaying operating system.
1198
*
1199
* @param context Kerberos 5 context.
1200
* @param addresses addreses to ignore
1201
*
1202
* @return Returns 0 to indicate success. Otherwise an kerberos et
1203
* error code is returned, see krb5_get_error_message().
1204
*
1205
* @ingroup krb5
1206
*/
1207
1208
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1209
krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
1210
{
1211
if(context->ignore_addresses)
1212
krb5_free_addresses(context, context->ignore_addresses);
1213
if(addresses == NULL) {
1214
if(context->ignore_addresses != NULL) {
1215
free(context->ignore_addresses);
1216
context->ignore_addresses = NULL;
1217
}
1218
return 0;
1219
}
1220
if(context->ignore_addresses == NULL) {
1221
context->ignore_addresses = malloc(sizeof(*context->ignore_addresses));
1222
if(context->ignore_addresses == NULL) {
1223
krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
1224
return ENOMEM;
1225
}
1226
}
1227
return krb5_copy_addresses(context, addresses, context->ignore_addresses);
1228
}
1229
1230
/**
1231
* Get extra addresses to ignore when fetching addresses from the
1232
* underlaying operating system.
1233
*
1234
* @param context Kerberos 5 context.
1235
* @param addresses list addreses ignored
1236
*
1237
* @return Returns 0 to indicate success. Otherwise an kerberos et
1238
* error code is returned, see krb5_get_error_message().
1239
*
1240
* @ingroup krb5
1241
*/
1242
1243
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1244
krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
1245
{
1246
if(context->ignore_addresses == NULL) {
1247
memset(addresses, 0, sizeof(*addresses));
1248
return 0;
1249
}
1250
return krb5_copy_addresses(context, context->ignore_addresses, addresses);
1251
}
1252
1253
/**
1254
* Set version of fcache that the library should use.
1255
*
1256
* @param context Kerberos 5 context.
1257
* @param version version number.
1258
*
1259
* @return Returns 0 to indicate success. Otherwise an kerberos et
1260
* error code is returned, see krb5_get_error_message().
1261
*
1262
* @ingroup krb5
1263
*/
1264
1265
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1266
krb5_set_fcache_version(krb5_context context, int version)
1267
{
1268
context->fcache_vno = version;
1269
return 0;
1270
}
1271
1272
/**
1273
* Get version of fcache that the library should use.
1274
*
1275
* @param context Kerberos 5 context.
1276
* @param version version number.
1277
*
1278
* @return Returns 0 to indicate success. Otherwise an kerberos et
1279
* error code is returned, see krb5_get_error_message().
1280
*
1281
* @ingroup krb5
1282
*/
1283
1284
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1285
krb5_get_fcache_version(krb5_context context, int *version)
1286
{
1287
*version = context->fcache_vno;
1288
return 0;
1289
}
1290
1291
/**
1292
* Runtime check if the Kerberos library was complied with thread support.
1293
*
1294
* @return TRUE if the library was compiled with thread support, FALSE if not.
1295
*
1296
* @ingroup krb5
1297
*/
1298
1299
1300
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
1301
krb5_is_thread_safe(void)
1302
{
1303
#ifdef ENABLE_PTHREAD_SUPPORT
1304
return TRUE;
1305
#else
1306
return FALSE;
1307
#endif
1308
}
1309
1310
/**
1311
* Set if the library should use DNS to canonicalize hostnames.
1312
*
1313
* @param context Kerberos 5 context.
1314
* @param flag if its dns canonicalizion is used or not.
1315
*
1316
* @ingroup krb5
1317
*/
1318
1319
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
1320
krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag)
1321
{
1322
if (flag)
1323
context->flags |= KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
1324
else
1325
context->flags &= ~KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
1326
}
1327
1328
/**
1329
* Get if the library uses DNS to canonicalize hostnames.
1330
*
1331
* @param context Kerberos 5 context.
1332
*
1333
* @return return non zero if the library uses DNS to canonicalize hostnames.
1334
*
1335
* @ingroup krb5
1336
*/
1337
1338
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
1339
krb5_get_dns_canonicalize_hostname (krb5_context context)
1340
{
1341
return (context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) ? 1 : 0;
1342
}
1343
1344
/**
1345
* Get current offset in time to the KDC.
1346
*
1347
* @param context Kerberos 5 context.
1348
* @param sec seconds part of offset.
1349
* @param usec micro seconds part of offset.
1350
*
1351
* @return returns zero
1352
*
1353
* @ingroup krb5
1354
*/
1355
1356
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1357
krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
1358
{
1359
if (sec)
1360
*sec = context->kdc_sec_offset;
1361
if (usec)
1362
*usec = context->kdc_usec_offset;
1363
return 0;
1364
}
1365
1366
/**
1367
* Set current offset in time to the KDC.
1368
*
1369
* @param context Kerberos 5 context.
1370
* @param sec seconds part of offset.
1371
* @param usec micro seconds part of offset.
1372
*
1373
* @return returns zero
1374
*
1375
* @ingroup krb5
1376
*/
1377
1378
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1379
krb5_set_kdc_sec_offset (krb5_context context, int32_t sec, int32_t usec)
1380
{
1381
context->kdc_sec_offset = sec;
1382
if (usec >= 0)
1383
context->kdc_usec_offset = usec;
1384
return 0;
1385
}
1386
1387
/**
1388
* Get max time skew allowed.
1389
*
1390
* @param context Kerberos 5 context.
1391
*
1392
* @return timeskew in seconds.
1393
*
1394
* @ingroup krb5
1395
*/
1396
1397
KRB5_LIB_FUNCTION time_t KRB5_LIB_CALL
1398
krb5_get_max_time_skew (krb5_context context)
1399
{
1400
return context->max_skew;
1401
}
1402
1403
/**
1404
* Set max time skew allowed.
1405
*
1406
* @param context Kerberos 5 context.
1407
* @param t timeskew in seconds.
1408
*
1409
* @ingroup krb5
1410
*/
1411
1412
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
1413
krb5_set_max_time_skew (krb5_context context, time_t t)
1414
{
1415
context->max_skew = t;
1416
}
1417
1418
/*
1419
* Init encryption types in len, val with etypes.
1420
*
1421
* @param context Kerberos 5 context.
1422
* @param pdu_type type of pdu
1423
* @param len output length of val.
1424
* @param val output array of enctypes.
1425
* @param etypes etypes to set val and len to, if NULL, use default enctypes.
1426
1427
* @return Returns 0 to indicate success. Otherwise an kerberos et
1428
* error code is returned, see krb5_get_error_message().
1429
*
1430
* @ingroup krb5
1431
*/
1432
1433
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1434
_krb5_init_etype(krb5_context context,
1435
krb5_pdu pdu_type,
1436
unsigned *len,
1437
krb5_enctype **val,
1438
const krb5_enctype *etypes)
1439
{
1440
krb5_error_code ret;
1441
1442
if (etypes == NULL)
1443
ret = krb5_get_default_in_tkt_etypes(context, pdu_type, val);
1444
else
1445
ret = copy_enctypes(context, etypes, val);
1446
if (ret)
1447
return ret;
1448
1449
if (len) {
1450
*len = 0;
1451
while ((*val)[*len] != KRB5_ENCTYPE_NULL)
1452
(*len)++;
1453
}
1454
return 0;
1455
}
1456
1457
/*
1458
* Allow homedir accces
1459
*/
1460
1461
static HEIMDAL_MUTEX homedir_mutex = HEIMDAL_MUTEX_INITIALIZER;
1462
static krb5_boolean allow_homedir = TRUE;
1463
1464
krb5_boolean
1465
_krb5_homedir_access(krb5_context context)
1466
{
1467
krb5_boolean allow;
1468
1469
#ifdef HAVE_GETEUID
1470
/* is never allowed for root */
1471
if (geteuid() == 0)
1472
return FALSE;
1473
#endif
1474
1475
if (context && (context->flags & KRB5_CTX_F_HOMEDIR_ACCESS) == 0)
1476
return FALSE;
1477
1478
HEIMDAL_MUTEX_lock(&homedir_mutex);
1479
allow = allow_homedir;
1480
HEIMDAL_MUTEX_unlock(&homedir_mutex);
1481
return allow;
1482
}
1483
1484
/**
1485
* Enable and disable home directory access on either the global state
1486
* or the krb5_context state. By calling krb5_set_home_dir_access()
1487
* with context set to NULL, the global state is configured otherwise
1488
* the state for the krb5_context is modified.
1489
*
1490
* For home directory access to be allowed, both the global state and
1491
* the krb5_context state have to be allowed.
1492
*
1493
* Administrator (root user), never uses the home directory.
1494
*
1495
* @param context a Kerberos 5 context or NULL
1496
* @param allow allow if TRUE home directory
1497
* @return the old value
1498
*
1499
* @ingroup krb5
1500
*/
1501
1502
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
1503
krb5_set_home_dir_access(krb5_context context, krb5_boolean allow)
1504
{
1505
krb5_boolean old;
1506
if (context) {
1507
old = (context->flags & KRB5_CTX_F_HOMEDIR_ACCESS) ? TRUE : FALSE;
1508
if (allow)
1509
context->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;
1510
else
1511
context->flags &= ~KRB5_CTX_F_HOMEDIR_ACCESS;
1512
} else {
1513
HEIMDAL_MUTEX_lock(&homedir_mutex);
1514
old = allow_homedir;
1515
allow_homedir = allow;
1516
HEIMDAL_MUTEX_unlock(&homedir_mutex);
1517
}
1518
1519
return old;
1520
}
1521
1522