/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- set_etypes
- copy_etypes
- init_context_from_config_file
- cc_ops_register
- kt_ops_register
- krb5_init_context
- krb5_copy_context
- krb5_free_context
- krb5_set_config_files
- add_file
- krb5_prepend_config_files
- krb5_prepend_config_files_default
- krb5_get_default_config_files
- krb5_free_config_files
- krb5_kerberos_enctypes
- default_etypes
- krb5_set_default_in_tkt_etypes
- krb5_get_default_in_tkt_etypes
- krb5_get_err_text
- krb5_init_ets
- krb5_set_use_admin_kdc
- krb5_get_use_admin_kdc
- krb5_add_extra_addresses
- krb5_set_extra_addresses
- krb5_get_extra_addresses
- krb5_add_ignore_addresses
- krb5_set_ignore_addresses
- krb5_get_ignore_addresses
- krb5_set_fcache_version
- krb5_get_fcache_version
- krb5_is_thread_safe
- krb5_set_dns_canonicalize_hostname
- krb5_get_dns_canonicalize_hostname
- krb5_get_kdc_sec_offset
- krb5_set_kdc_sec_offset
- krb5_get_max_time_skew
- krb5_set_max_time_skew
1 /*
2 * Copyright (c) 1997 - 2005 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 "krb5_locl.h"
35 #include <com_err.h>
36
37 RCSID("$Id$");
38
39 #define INIT_FIELD(C, T, E, D, F) \
40 (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \
41 "libdefaults", F, NULL)
42
43 #define INIT_FLAG(C, O, V, D, F) \
44 do { \
45 if (krb5_config_get_bool_default((C), NULL, (D),"libdefaults", F, NULL)) { \
46 (C)->O |= V; \
47 } \
48 } while(0)
49
50 /*
51 * Set the list of etypes `ret_etypes' from the configuration variable
52 * `name'
53 */
54
55 static krb5_error_code
56 set_etypes (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
57 const char *name,
58 krb5_enctype **ret_enctypes)
59 {
60 char **etypes_str;
61 krb5_enctype *etypes = NULL;
62
63 etypes_str = krb5_config_get_strings(context, NULL, "libdefaults",
64 name, NULL);
65 if(etypes_str){
66 int i, j, k;
67 for(i = 0; etypes_str[i]; i++);
68 etypes = malloc((i+1) * sizeof(*etypes));
69 if (etypes == NULL) {
70 krb5_config_free_strings (etypes_str);
71 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
72 return ENOMEM;
73 }
74 for(j = 0, k = 0; j < i; j++) {
75 krb5_enctype e;
76 if(krb5_string_to_enctype(context, etypes_str[j], &e) != 0)
77 continue;
78 if (krb5_enctype_valid(context, e) != 0)
79 continue;
80 etypes[k++] = e;
81 }
82 etypes[k] = ETYPE_NULL;
83 krb5_config_free_strings(etypes_str);
84 }
85 *ret_enctypes = etypes;
86 return 0;
87 }
88
89 /*
90 *
91 */
92
93 static krb5_error_code
94 copy_etypes (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
95 krb5_enctype *enctypes,
96 krb5_enctype **ret_enctypes)
97 {
98 unsigned int i;
99
100 for (i = 0; enctypes[i]; i++)
101 ;
102 i++;
103
104 *ret_enctypes = malloc(sizeof(ret_enctypes[0]) * i);
105 if (*ret_enctypes == NULL) {
106 krb5_set_error_message(context, ENOMEM,
107 N_("malloc: out of memory", ""));
108 return ENOMEM;
109 }
110 memcpy(*ret_enctypes, enctypes, sizeof(ret_enctypes[0]) * i);
111 return 0;
112 }
113
114
115 /*
116 * read variables from the configuration file and set in `context'
117 */
118
119 static krb5_error_code
120 init_context_from_config_file(krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
121 {
122 krb5_error_code ret;
123 const char * tmp;
124 krb5_enctype *tmptypes;
125
126 INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew");
127 INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout");
128 INIT_FIELD(context, int, max_retries, 3, "max_retries");
129
130 INIT_FIELD(context, string, http_proxy, NULL, "http_proxy");
131
132 ret = set_etypes (context, "default_etypes", &tmptypes);
133 if(ret)
134 return ret;
135 free(context->etypes);
136 context->etypes = tmptypes;
137
138 ret = set_etypes (context, "default_etypes_des", &tmptypes);
139 if(ret)
140 return ret;
141 free(context->etypes_des);
142 context->etypes_des = tmptypes;
143
144 /* default keytab name */
145 tmp = NULL;
146 if(!issuid())
147 tmp = getenv("KRB5_KTNAME");
148 if(tmp != NULL)
149 context->default_keytab = tmp;
150 else
151 INIT_FIELD(context, string, default_keytab,
152 KEYTAB_DEFAULT, "default_keytab_name");
153
154 INIT_FIELD(context, string, default_keytab_modify,
155 NULL, "default_keytab_modify_name");
156
157 INIT_FIELD(context, string, time_fmt,
158 "%Y-%m-%dT%H:%M:%S", "time_format");
159
160 INIT_FIELD(context, string, date_fmt,
161 "%Y-%m-%d", "date_format");
162
163 INIT_FIELD(context, bool, log_utc,
164 FALSE, "log_utc");
165
166
167
168 /* init dns-proxy slime */
169 tmp = krb5_config_get_string(context, NULL, "libdefaults",
170 "dns_proxy", NULL);
171 if(tmp)
172 roken_gethostby_setup(context->http_proxy, tmp);
173 krb5_free_host_realm (context, context->default_realms);
174 context->default_realms = NULL;
175
176 {
177 krb5_addresses addresses;
178 char **adr, **a;
179
180 krb5_set_extra_addresses(context, NULL);
181 adr = krb5_config_get_strings(context, NULL,
182 "libdefaults",
183 "extra_addresses",
184 NULL);
185 memset(&addresses, 0, sizeof(addresses));
186 for(a = adr; a && *a; a++) {
187 ret = krb5_parse_address(context, *a, &addresses);
188 if (ret == 0) {
189 krb5_add_extra_addresses(context, &addresses);
190 krb5_free_addresses(context, &addresses);
191 }
192 }
193 krb5_config_free_strings(adr);
194
195 krb5_set_ignore_addresses(context, NULL);
196 adr = krb5_config_get_strings(context, NULL,
197 "libdefaults",
198 "ignore_addresses",
199 NULL);
200 memset(&addresses, 0, sizeof(addresses));
201 for(a = adr; a && *a; a++) {
202 ret = krb5_parse_address(context, *a, &addresses);
203 if (ret == 0) {
204 krb5_add_ignore_addresses(context, &addresses);
205 krb5_free_addresses(context, &addresses);
206 }
207 }
208 krb5_config_free_strings(adr);
209 }
210
211 INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces");
212 INIT_FIELD(context, int, fcache_vno, 0, "fcache_version");
213 /* prefer dns_lookup_kdc over srv_lookup. */
214 INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
215 INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc");
216 INIT_FIELD(context, int, large_msg_size, 1400, "large_message_size");
217 INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname");
218 INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac");
219 context->default_cc_name = NULL;
220 context->default_cc_name_set = 0;
221
222 ret = krb5_config_get_bool_default(context, NULL, FALSE,
223 "libdefaults",
224 "allow_weak_crypto", NULL);
225 if (ret) {
226 krb5_enctype_enable(context, ETYPE_DES_CBC_CRC);
227 krb5_enctype_enable(context, ETYPE_DES_CBC_MD4);
228 krb5_enctype_enable(context, ETYPE_DES_CBC_MD5);
229 krb5_enctype_enable(context, ETYPE_DES_CBC_NONE);
230 krb5_enctype_enable(context, ETYPE_DES_CFB64_NONE);
231 krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE);
232 }
233
234 return 0;
235 }
236
237 static krb5_error_code
238 cc_ops_register(krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
239 {
240 context->cc_ops = NULL;
241 context->num_cc_ops = 0;
242
243 krb5_cc_register(context, &krb5_acc_ops, TRUE);
244 krb5_cc_register(context, &krb5_fcc_ops, TRUE);
245 krb5_cc_register(context, &krb5_mcc_ops, TRUE);
246 #ifdef HAVE_SQLITE
247 krb5_cc_register(context, &krb5_scc_ops, TRUE);
248 #endif
249 #ifdef HAVE_KCM
250 krb5_cc_register(context, &krb5_kcm_ops, TRUE);
251 #endif
252 return 0;
253 }
254
255 static krb5_error_code
256 kt_ops_register(krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
257 {
258 context->num_kt_types = 0;
259 context->kt_types = NULL;
260
261 krb5_kt_register (context, &krb5_fkt_ops);
262 krb5_kt_register (context, &krb5_wrfkt_ops);
263 krb5_kt_register (context, &krb5_javakt_ops);
264 krb5_kt_register (context, &krb5_mkt_ops);
265 #ifndef HEIMDAL_SMALLER
266 krb5_kt_register (context, &krb5_akf_ops);
267 #endif
268 krb5_kt_register (context, &krb5_any_ops);
269 return 0;
270 }
271
272
273 /**
274 * Initializes the context structure and reads the configuration file
275 * /etc/krb5.conf. The structure should be freed by calling
276 * krb5_free_context() when it is no longer being used.
277 *
278 * @param context pointer to returned context
279 *
280 * @return Returns 0 to indicate success. Otherwise an errno code is
281 * returned. Failure means either that something bad happened during
282 * initialization (typically ENOMEM) or that Kerberos should not be
283 * used ENXIO.
284 *
285 * @ingroup krb5
286 */
287
288 krb5_error_code KRB5_LIB_FUNCTION
289 krb5_init_context(krb5_context *context)
/* [<][>][^][v][top][bottom][index][help] */
290 {
291 krb5_context p;
292 krb5_error_code ret;
293 char **files;
294
295 *context = NULL;
296
297 /* should have a run_once */
298 #if defined(HEIMDAL_LOCALEDIR)
299 bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR);
300 #endif
301
302 p = calloc(1, sizeof(*p));
303 if(!p)
304 return ENOMEM;
305
306 p->mutex = malloc(sizeof(HEIMDAL_MUTEX));
307 if (p->mutex == NULL) {
308 free(p);
309 return ENOMEM;
310 }
311 HEIMDAL_MUTEX_init(p->mutex);
312
313 ret = krb5_get_default_config_files(&files);
314 if(ret)
315 goto out;
316 ret = krb5_set_config_files(p, files);
317 krb5_free_config_files(files);
318 if(ret)
319 goto out;
320
321 /* init error tables */
322 krb5_init_ets(p);
323 cc_ops_register(p);
324 kt_ops_register(p);
325
326 out:
327 if(ret) {
328 krb5_free_context(p);
329 p = NULL;
330 }
331 *context = p;
332 return ret;
333 }
334
335 /**
336 * Make a copy for the Kerberos 5 context, allocated krb5_contex shoud
337 * be freed with krb5_free_context().
338 *
339 * @param in the Kerberos context to copy
340 * @param out the copy of the Kerberos, set to NULL error.
341 *
342 * @return Returns 0 to indicate success. Otherwise an kerberos et
343 * error code is returned, see krb5_get_error_message().
344 *
345 * @ingroup krb5
346 */
347
348 krb5_error_code KRB5_LIB_FUNCTION
349 krb5_copy_context(krb5_context context, krb5_context *out)
/* [<][>][^][v][top][bottom][index][help] */
350 {
351 krb5_error_code ret;
352 krb5_context p;
353
354 *out = NULL;
355
356 p = calloc(1, sizeof(*p));
357 if (p == NULL) {
358 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
359 return ENOMEM;
360 }
361
362 p->mutex = malloc(sizeof(HEIMDAL_MUTEX));
363 if (p->mutex == NULL) {
364 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
365 free(p);
366 return ENOMEM;
367 }
368 HEIMDAL_MUTEX_init(p->mutex);
369
370
371 if (context->default_cc_name)
372 p->default_cc_name = strdup(context->default_cc_name);
373 if (context->default_cc_name_env)
374 p->default_cc_name_env = strdup(context->default_cc_name_env);
375
376 if (context->etypes) {
377 ret = copy_etypes(context, context->etypes, &p->etypes);
378 if (ret)
379 goto out;
380 }
381 if (context->etypes_des) {
382 ret = copy_etypes(context, context->etypes_des, &p->etypes_des);
383 if (ret)
384 goto out;
385 }
386
387 if (context->default_realms) {
388 ret = krb5_copy_host_realm(context,
389 context->default_realms, &p->default_realms);
390 if (ret)
391 goto out;
392 }
393
394 ret = _krb5_config_copy(context, context->cf, &p->cf);
395 if (ret)
396 goto out;
397
398 /* XXX should copy */
399 krb5_init_ets(p);
400 cc_ops_register(p);
401 kt_ops_register(p);
402
403 #if 0 /* XXX */
404 if(context->warn_dest != NULL)
405 ;
406 #endif
407
408 ret = krb5_set_extra_addresses(p, context->extra_addresses);
409 if (ret)
410 goto out;
411 ret = krb5_set_extra_addresses(p, context->ignore_addresses);
412 if (ret)
413 goto out;
414
415 ret = _krb5_copy_send_to_kdc_func(p, context);
416 if (ret)
417 goto out;
418
419 *out = p;
420
421 return 0;
422
423 out:
424 krb5_free_context(p);
425 return ret;
426 }
427
428 /**
429 * Frees the krb5_context allocated by krb5_init_context().
430 *
431 * @param context context to be freed.
432 *
433 * @ingroup krb5
434 */
435
436 void KRB5_LIB_FUNCTION
437 krb5_free_context(krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
438 {
439 if (context->default_cc_name)
440 free(context->default_cc_name);
441 if (context->default_cc_name_env)
442 free(context->default_cc_name_env);
443 free(context->etypes);
444 free(context->etypes_des);
445 krb5_free_host_realm (context, context->default_realms);
446 krb5_config_file_free (context, context->cf);
447 free_error_table (context->et_list);
448 free(context->cc_ops);
449 free(context->kt_types);
450 krb5_clear_error_message(context);
451 if(context->warn_dest != NULL)
452 krb5_closelog(context, context->warn_dest);
453 krb5_set_extra_addresses(context, NULL);
454 krb5_set_ignore_addresses(context, NULL);
455 krb5_set_send_to_kdc_func(context, NULL, NULL);
456 if (context->mutex != NULL) {
457 HEIMDAL_MUTEX_destroy(context->mutex);
458 free(context->mutex);
459 }
460 memset(context, 0, sizeof(*context));
461 free(context);
462 }
463
464 /**
465 * Reinit the context from a new set of filenames.
466 *
467 * @param context context to add configuration too.
468 * @param filenames array of filenames, end of list is indicated with a NULL filename.
469 *
470 * @return Returns 0 to indicate success. Otherwise an kerberos et
471 * error code is returned, see krb5_get_error_message().
472 *
473 * @ingroup krb5
474 */
475
476 krb5_error_code KRB5_LIB_FUNCTION
477 krb5_set_config_files(krb5_context context, char **filenames)
/* [<][>][^][v][top][bottom][index][help] */
478 {
479 krb5_error_code ret;
480 krb5_config_binding *tmp = NULL;
481 while(filenames != NULL && *filenames != NULL && **filenames != '\0') {
482 ret = krb5_config_parse_file_multi(context, *filenames, &tmp);
483 if(ret != 0 && ret != ENOENT && ret != EACCES) {
484 krb5_config_file_free(context, tmp);
485 return ret;
486 }
487 filenames++;
488 }
489 #if 0
490 /* with this enabled and if there are no config files, Kerberos is
491 considererd disabled */
492 if(tmp == NULL)
493 return ENXIO;
494 #endif
495 krb5_config_file_free(context, context->cf);
496 context->cf = tmp;
497 ret = init_context_from_config_file(context);
498 return ret;
499 }
500
501 static krb5_error_code
502 add_file(char ***pfilenames, int *len, char *file)
/* [<][>][^][v][top][bottom][index][help] */
503 {
504 char **pp = *pfilenames;
505 int i;
506
507 for(i = 0; i < *len; i++) {
508 if(strcmp(pp[i], file) == 0) {
509 free(file);
510 return 0;
511 }
512 }
513
514 pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp));
515 if (pp == NULL) {
516 free(file);
517 return ENOMEM;
518 }
519
520 pp[*len] = file;
521 pp[*len + 1] = NULL;
522 *pfilenames = pp;
523 *len += 1;
524 return 0;
525 }
526
527 /*
528 * `pq' isn't free, it's up the the caller
529 */
530
531 krb5_error_code KRB5_LIB_FUNCTION
532 krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
/* [<][>][^][v][top][bottom][index][help] */
533 {
534 krb5_error_code ret;
535 const char *p, *q;
536 char **pp;
537 int len;
538 char *fn;
539
540 pp = NULL;
541
542 len = 0;
543 p = filelist;
544 while(1) {
545 ssize_t l;
546 q = p;
547 l = strsep_copy(&q, ":", NULL, 0);
548 if(l == -1)
549 break;
550 fn = malloc(l + 1);
551 if(fn == NULL) {
552 krb5_free_config_files(pp);
553 return ENOMEM;
554 }
555 l = strsep_copy(&p, ":", fn, l + 1);
556 ret = add_file(&pp, &len, fn);
557 if (ret) {
558 krb5_free_config_files(pp);
559 return ret;
560 }
561 }
562
563 if (pq != NULL) {
564 int i;
565
566 for (i = 0; pq[i] != NULL; i++) {
567 fn = strdup(pq[i]);
568 if (fn == NULL) {
569 krb5_free_config_files(pp);
570 return ENOMEM;
571 }
572 ret = add_file(&pp, &len, fn);
573 if (ret) {
574 krb5_free_config_files(pp);
575 return ret;
576 }
577 }
578 }
579
580 *ret_pp = pp;
581 return 0;
582 }
583
584 /**
585 * Prepend the filename to the global configuration list.
586 *
587 * @param filelist a filename to add to the default list of filename
588 * @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
589 *
590 * @return Returns 0 to indicate success. Otherwise an kerberos et
591 * error code is returned, see krb5_get_error_message().
592 *
593 * @ingroup krb5
594 */
595
596 krb5_error_code KRB5_LIB_FUNCTION
597 krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
/* [<][>][^][v][top][bottom][index][help] */
598 {
599 krb5_error_code ret;
600 char **defpp, **pp = NULL;
601
602 ret = krb5_get_default_config_files(&defpp);
603 if (ret)
604 return ret;
605
606 ret = krb5_prepend_config_files(filelist, defpp, &pp);
607 krb5_free_config_files(defpp);
608 if (ret) {
609 return ret;
610 }
611 *pfilenames = pp;
612 return 0;
613 }
614
615 /**
616 * Get the global configuration list.
617 *
618 * @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
619 *
620 * @return Returns 0 to indicate success. Otherwise an kerberos et
621 * error code is returned, see krb5_get_error_message().
622 *
623 * @ingroup krb5
624 */
625
626 krb5_error_code KRB5_LIB_FUNCTION
627 krb5_get_default_config_files(char ***pfilenames)
/* [<][>][^][v][top][bottom][index][help] */
628 {
629 const char *files = NULL;
630
631 if (pfilenames == NULL)
632 return EINVAL;
633 if(!issuid())
634 files = getenv("KRB5_CONFIG");
635 if (files == NULL)
636 files = krb5_config_file;
637
638 return krb5_prepend_config_files(files, NULL, pfilenames);
639 }
640
641 /**
642 * Free a list of configuration files.
643 *
644 * @param filenames list to be freed.
645 *
646 * @return Returns 0 to indicate success. Otherwise an kerberos et
647 * error code is returned, see krb5_get_error_message().
648 *
649 * @ingroup krb5
650 */
651
652 void KRB5_LIB_FUNCTION
653 krb5_free_config_files(char **filenames)
/* [<][>][^][v][top][bottom][index][help] */
654 {
655 char **p;
656 for(p = filenames; *p != NULL; p++)
657 free(*p);
658 free(filenames);
659 }
660
661 /**
662 * Returns the list of Kerberos encryption types sorted in order of
663 * most preferred to least preferred encryption type. Note that some
664 * encryption types might be disabled, so you need to check with
665 * krb5_enctype_valid() before using the encryption type.
666 *
667 * @return list of enctypes, terminated with ETYPE_NULL. Its a static
668 * array completed into the Kerberos library so the content doesn't
669 * need to be freed.
670 *
671 * @ingroup krb5
672 */
673
674 const krb5_enctype * KRB5_LIB_FUNCTION
675 krb5_kerberos_enctypes(krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
676 {
677 static const krb5_enctype p[] = {
678 ETYPE_AES256_CTS_HMAC_SHA1_96,
679 ETYPE_AES128_CTS_HMAC_SHA1_96,
680 ETYPE_DES3_CBC_SHA1,
681 ETYPE_DES3_CBC_MD5,
682 ETYPE_ARCFOUR_HMAC_MD5,
683 ETYPE_DES_CBC_MD5,
684 ETYPE_DES_CBC_MD4,
685 ETYPE_DES_CBC_CRC,
686 ETYPE_NULL
687 };
688 return p;
689 }
690
691 /*
692 * set `etype' to a malloced list of the default enctypes
693 */
694
695 static krb5_error_code
696 default_etypes(krb5_context context, krb5_enctype **etype)
/* [<][>][^][v][top][bottom][index][help] */
697 {
698 const krb5_enctype *p;
699 krb5_enctype *e = NULL, *ep;
700 int i, n = 0;
701
702 p = krb5_kerberos_enctypes(context);
703
704 for (i = 0; p[i] != ETYPE_NULL; i++) {
705 if (krb5_enctype_valid(context, p[i]) != 0)
706 continue;
707 ep = realloc(e, (n + 2) * sizeof(*e));
708 if (ep == NULL) {
709 free(e);
710 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
711 return ENOMEM;
712 }
713 e = ep;
714 e[n] = p[i];
715 e[n + 1] = ETYPE_NULL;
716 n++;
717 }
718 *etype = e;
719 return 0;
720 }
721
722 /**
723 * Set the default encryption types that will be use in communcation
724 * with the KDC, clients and servers.
725 *
726 * @param context Kerberos 5 context.
727 * @param etypes Encryption types, array terminated with ETYPE_NULL (0).
728 *
729 * @return Returns 0 to indicate success. Otherwise an kerberos et
730 * error code is returned, see krb5_get_error_message().
731 *
732 * @ingroup krb5
733 */
734
735 krb5_error_code KRB5_LIB_FUNCTION
736 krb5_set_default_in_tkt_etypes(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
737 const krb5_enctype *etypes)
738 {
739 krb5_enctype *p = NULL;
740 int i;
741
742 if(etypes) {
743 for (i = 0; etypes[i]; ++i) {
744 krb5_error_code ret;
745 ret = krb5_enctype_valid(context, etypes[i]);
746 if (ret)
747 return ret;
748 }
749 ++i;
750 ALLOC(p, i);
751 if(!p) {
752 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
753 return ENOMEM;
754 }
755 memmove(p, etypes, i * sizeof(krb5_enctype));
756 }
757 if(context->etypes)
758 free(context->etypes);
759 context->etypes = p;
760 return 0;
761 }
762
763 /**
764 * Get the default encryption types that will be use in communcation
765 * with the KDC, clients and servers.
766 *
767 * @param context Kerberos 5 context.
768 * @param etypes Encryption types, array terminated with
769 * ETYPE_NULL(0), caller should free array with krb5_xfree():
770 *
771 * @return Returns 0 to indicate success. Otherwise an kerberos et
772 * error code is returned, see krb5_get_error_message().
773 *
774 * @ingroup krb5
775 */
776
777 krb5_error_code KRB5_LIB_FUNCTION
778 krb5_get_default_in_tkt_etypes(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
779 krb5_enctype **etypes)
780 {
781 krb5_enctype *p;
782 int i;
783 krb5_error_code ret;
784
785 if(context->etypes) {
786 for(i = 0; context->etypes[i]; i++);
787 ++i;
788 ALLOC(p, i);
789 if(!p) {
790 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
791 return ENOMEM;
792 }
793 memmove(p, context->etypes, i * sizeof(krb5_enctype));
794 } else {
795 ret = default_etypes(context, &p);
796 if (ret)
797 return ret;
798 }
799 *etypes = p;
800 return 0;
801 }
802
803 /**
804 * Return the error string for the error code. The caller must not
805 * free the string.
806 *
807 * @param context Kerberos 5 context.
808 * @param code Kerberos error code.
809 *
810 * @return the error message matching code
811 *
812 * @ingroup krb5
813 */
814
815 const char* KRB5_LIB_FUNCTION
816 krb5_get_err_text(krb5_context context, krb5_error_code code)
/* [<][>][^][v][top][bottom][index][help] */
817 {
818 const char *p = NULL;
819 if(context != NULL)
820 p = com_right(context->et_list, code);
821 if(p == NULL)
822 p = strerror(code);
823 if (p == NULL)
824 p = "Unknown error";
825 return p;
826 }
827
828 /**
829 * Init the built-in ets in the Kerberos library.
830 *
831 * @param context kerberos context to add the ets too
832 *
833 * @ingroup krb5
834 */
835
836 void KRB5_LIB_FUNCTION
837 krb5_init_ets(krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
838 {
839 if(context->et_list == NULL){
840 krb5_add_et_list(context, initialize_krb5_error_table_r);
841 #if defined(HEIMDAL_LOCALEDIR)
842 bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR);
843 #endif
844
845 krb5_add_et_list(context, initialize_asn1_error_table_r);
846 #if defined(HEIMDAL_LOCALEDIR)
847 bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR);
848 #endif
849
850 krb5_add_et_list(context, initialize_heim_error_table_r);
851 #if defined(HEIMDAL_LOCALEDIR)
852 bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR);
853 #endif
854
855 krb5_add_et_list(context, initialize_k524_error_table_r);
856 #if defined(HEIMDAL_LOCALEDIR)
857 bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR);
858 #endif
859
860 #ifdef PKINIT
861 krb5_add_et_list(context, initialize_hx_error_table_r);
862 #if defined(HEIMDAL_LOCALEDIR)
863 bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR);
864 #endif
865 #endif
866 }
867 }
868
869 /**
870 * Make the kerberos library default to the admin KDC.
871 *
872 * @param context Kerberos 5 context.
873 * @param flag boolean flag to select if the use the admin KDC or not.
874 *
875 * @ingroup krb5
876 */
877
878 void KRB5_LIB_FUNCTION
879 krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
/* [<][>][^][v][top][bottom][index][help] */
880 {
881 context->use_admin_kdc = flag;
882 }
883
884 /**
885 * Make the kerberos library default to the admin KDC.
886 *
887 * @param context Kerberos 5 context.
888 *
889 * @return boolean flag to telling the context will use admin KDC as the default KDC.
890 *
891 * @ingroup krb5
892 */
893
894 krb5_boolean KRB5_LIB_FUNCTION
895 krb5_get_use_admin_kdc (krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
896 {
897 return context->use_admin_kdc;
898 }
899
900 /**
901 * Add extra address to the address list that the library will add to
902 * the client's address list when communicating with the KDC.
903 *
904 * @param context Kerberos 5 context.
905 * @param addresses addreses to add
906 *
907 * @return Returns 0 to indicate success. Otherwise an kerberos et
908 * error code is returned, see krb5_get_error_message().
909 *
910 * @ingroup krb5
911 */
912
913 krb5_error_code KRB5_LIB_FUNCTION
914 krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
/* [<][>][^][v][top][bottom][index][help] */
915 {
916
917 if(context->extra_addresses)
918 return krb5_append_addresses(context,
919 context->extra_addresses, addresses);
920 else
921 return krb5_set_extra_addresses(context, addresses);
922 }
923
924 /**
925 * Set extra address to the address list that the library will add to
926 * the client's address list when communicating with the KDC.
927 *
928 * @param context Kerberos 5 context.
929 * @param addresses addreses to set
930 *
931 * @return Returns 0 to indicate success. Otherwise an kerberos et
932 * error code is returned, see krb5_get_error_message().
933 *
934 * @ingroup krb5
935 */
936
937 krb5_error_code KRB5_LIB_FUNCTION
938 krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
/* [<][>][^][v][top][bottom][index][help] */
939 {
940 if(context->extra_addresses)
941 krb5_free_addresses(context, context->extra_addresses);
942
943 if(addresses == NULL) {
944 if(context->extra_addresses != NULL) {
945 free(context->extra_addresses);
946 context->extra_addresses = NULL;
947 }
948 return 0;
949 }
950 if(context->extra_addresses == NULL) {
951 context->extra_addresses = malloc(sizeof(*context->extra_addresses));
952 if(context->extra_addresses == NULL) {
953 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
954 return ENOMEM;
955 }
956 }
957 return krb5_copy_addresses(context, addresses, context->extra_addresses);
958 }
959
960 /**
961 * Get extra address to the address list that the library will add to
962 * the client's address list when communicating with the KDC.
963 *
964 * @param context Kerberos 5 context.
965 * @param addresses addreses to set
966 *
967 * @return Returns 0 to indicate success. Otherwise an kerberos et
968 * error code is returned, see krb5_get_error_message().
969 *
970 * @ingroup krb5
971 */
972
973 krb5_error_code KRB5_LIB_FUNCTION
974 krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
/* [<][>][^][v][top][bottom][index][help] */
975 {
976 if(context->extra_addresses == NULL) {
977 memset(addresses, 0, sizeof(*addresses));
978 return 0;
979 }
980 return krb5_copy_addresses(context,context->extra_addresses, addresses);
981 }
982
983 /**
984 * Add extra addresses to ignore when fetching addresses from the
985 * underlaying operating system.
986 *
987 * @param context Kerberos 5 context.
988 * @param addresses addreses to ignore
989 *
990 * @return Returns 0 to indicate success. Otherwise an kerberos et
991 * error code is returned, see krb5_get_error_message().
992 *
993 * @ingroup krb5
994 */
995
996 krb5_error_code KRB5_LIB_FUNCTION
997 krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
/* [<][>][^][v][top][bottom][index][help] */
998 {
999
1000 if(context->ignore_addresses)
1001 return krb5_append_addresses(context,
1002 context->ignore_addresses, addresses);
1003 else
1004 return krb5_set_ignore_addresses(context, addresses);
1005 }
1006
1007 /**
1008 * Set extra addresses to ignore when fetching addresses from the
1009 * underlaying operating system.
1010 *
1011 * @param context Kerberos 5 context.
1012 * @param addresses addreses to ignore
1013 *
1014 * @return Returns 0 to indicate success. Otherwise an kerberos et
1015 * error code is returned, see krb5_get_error_message().
1016 *
1017 * @ingroup krb5
1018 */
1019
1020 krb5_error_code KRB5_LIB_FUNCTION
1021 krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
/* [<][>][^][v][top][bottom][index][help] */
1022 {
1023 if(context->ignore_addresses)
1024 krb5_free_addresses(context, context->ignore_addresses);
1025 if(addresses == NULL) {
1026 if(context->ignore_addresses != NULL) {
1027 free(context->ignore_addresses);
1028 context->ignore_addresses = NULL;
1029 }
1030 return 0;
1031 }
1032 if(context->ignore_addresses == NULL) {
1033 context->ignore_addresses = malloc(sizeof(*context->ignore_addresses));
1034 if(context->ignore_addresses == NULL) {
1035 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
1036 return ENOMEM;
1037 }
1038 }
1039 return krb5_copy_addresses(context, addresses, context->ignore_addresses);
1040 }
1041
1042 /**
1043 * Get extra addresses to ignore when fetching addresses from the
1044 * underlaying operating system.
1045 *
1046 * @param context Kerberos 5 context.
1047 * @param addresses list addreses ignored
1048 *
1049 * @return Returns 0 to indicate success. Otherwise an kerberos et
1050 * error code is returned, see krb5_get_error_message().
1051 *
1052 * @ingroup krb5
1053 */
1054
1055 krb5_error_code KRB5_LIB_FUNCTION
1056 krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
/* [<][>][^][v][top][bottom][index][help] */
1057 {
1058 if(context->ignore_addresses == NULL) {
1059 memset(addresses, 0, sizeof(*addresses));
1060 return 0;
1061 }
1062 return krb5_copy_addresses(context, context->ignore_addresses, addresses);
1063 }
1064
1065 /**
1066 * Set version of fcache that the library should use.
1067 *
1068 * @param context Kerberos 5 context.
1069 * @param version version number.
1070 *
1071 * @return Returns 0 to indicate success. Otherwise an kerberos et
1072 * error code is returned, see krb5_get_error_message().
1073 *
1074 * @ingroup krb5
1075 */
1076
1077 krb5_error_code KRB5_LIB_FUNCTION
1078 krb5_set_fcache_version(krb5_context context, int version)
/* [<][>][^][v][top][bottom][index][help] */
1079 {
1080 context->fcache_vno = version;
1081 return 0;
1082 }
1083
1084 /**
1085 * Get version of fcache that the library should use.
1086 *
1087 * @param context Kerberos 5 context.
1088 * @param version version number.
1089 *
1090 * @return Returns 0 to indicate success. Otherwise an kerberos et
1091 * error code is returned, see krb5_get_error_message().
1092 *
1093 * @ingroup krb5
1094 */
1095
1096 krb5_error_code KRB5_LIB_FUNCTION
1097 krb5_get_fcache_version(krb5_context context, int *version)
/* [<][>][^][v][top][bottom][index][help] */
1098 {
1099 *version = context->fcache_vno;
1100 return 0;
1101 }
1102
1103 /**
1104 * Runtime check if the Kerberos library was complied with thread support.
1105 *
1106 * @return TRUE if the library was compiled with thread support, FALSE if not.
1107 *
1108 * @ingroup krb5
1109 */
1110
1111
1112 krb5_boolean KRB5_LIB_FUNCTION
1113 krb5_is_thread_safe(void)
/* [<][>][^][v][top][bottom][index][help] */
1114 {
1115 #ifdef ENABLE_PTHREAD_SUPPORT
1116 return TRUE;
1117 #else
1118 return FALSE;
1119 #endif
1120 }
1121
1122 /**
1123 * Set if the library should use DNS to canonicalize hostnames.
1124 *
1125 * @param context Kerberos 5 context.
1126 * @param flag if its dns canonicalizion is used or not.
1127 *
1128 * @ingroup krb5
1129 */
1130
1131 void KRB5_LIB_FUNCTION
1132 krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag)
/* [<][>][^][v][top][bottom][index][help] */
1133 {
1134 if (flag)
1135 context->flags |= KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
1136 else
1137 context->flags &= ~KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
1138 }
1139
1140 /**
1141 * Get if the library uses DNS to canonicalize hostnames.
1142 *
1143 * @param context Kerberos 5 context.
1144 *
1145 * @return return non zero if the library uses DNS to canonicalize hostnames.
1146 *
1147 * @ingroup krb5
1148 */
1149
1150 krb5_boolean KRB5_LIB_FUNCTION
1151 krb5_get_dns_canonicalize_hostname (krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
1152 {
1153 return (context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) ? 1 : 0;
1154 }
1155
1156 /**
1157 * Get current offset in time to the KDC.
1158 *
1159 * @param context Kerberos 5 context.
1160 * @param sec seconds part of offset.
1161 * @param usec micro seconds part of offset.
1162 *
1163 * @return returns zero
1164 *
1165 * @ingroup krb5
1166 */
1167
1168 krb5_error_code KRB5_LIB_FUNCTION
1169 krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
/* [<][>][^][v][top][bottom][index][help] */
1170 {
1171 if (sec)
1172 *sec = context->kdc_sec_offset;
1173 if (usec)
1174 *usec = context->kdc_usec_offset;
1175 return 0;
1176 }
1177
1178 /**
1179 * Set current offset in time to the KDC.
1180 *
1181 * @param context Kerberos 5 context.
1182 * @param sec seconds part of offset.
1183 * @param usec micro seconds part of offset.
1184 *
1185 * @return returns zero
1186 *
1187 * @ingroup krb5
1188 */
1189
1190 krb5_error_code KRB5_LIB_FUNCTION
1191 krb5_set_kdc_sec_offset (krb5_context context, int32_t sec, int32_t usec)
/* [<][>][^][v][top][bottom][index][help] */
1192 {
1193 context->kdc_sec_offset = sec;
1194 if (usec >= 0)
1195 context->kdc_usec_offset = usec;
1196 return 0;
1197 }
1198
1199 /**
1200 * Get max time skew allowed.
1201 *
1202 * @param context Kerberos 5 context.
1203 *
1204 * @return timeskew in seconds.
1205 *
1206 * @ingroup krb5
1207 */
1208
1209 time_t KRB5_LIB_FUNCTION
1210 krb5_get_max_time_skew (krb5_context context)
/* [<][>][^][v][top][bottom][index][help] */
1211 {
1212 return context->max_skew;
1213 }
1214
1215 /**
1216 * Set max time skew allowed.
1217 *
1218 * @param context Kerberos 5 context.
1219 * @param t timeskew in seconds.
1220 *
1221 * @ingroup krb5
1222 */
1223
1224 void KRB5_LIB_FUNCTION
1225 krb5_set_max_time_skew (krb5_context context, time_t t)
/* [<][>][^][v][top][bottom][index][help] */
1226 {
1227 context->max_skew = t;
1228 }