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