context.c revision 107207
155682Smarkm/*
290926Snectar * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
555682Smarkm *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
955682Smarkm *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "krb5_locl.h"
35102644Snectar#include <com_err.h>
3655682Smarkm
37107207SnectarRCSID("$Id: context.c,v 1.81.2.1 2002/10/21 14:33:34 joda Exp $");
3855682Smarkm
3955682Smarkm#define INIT_FIELD(C, T, E, D, F)					\
4055682Smarkm    (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), 	\
4155682Smarkm						"libdefaults", F, NULL)
4255682Smarkm
4355682Smarkm/*
4455682Smarkm * Set the list of etypes `ret_etypes' from the configuration variable
4555682Smarkm * `name'
4655682Smarkm */
4755682Smarkm
4855682Smarkmstatic krb5_error_code
4955682Smarkmset_etypes (krb5_context context,
5055682Smarkm	    const char *name,
5155682Smarkm	    krb5_enctype **ret_enctypes)
5255682Smarkm{
5355682Smarkm    char **etypes_str;
54102644Snectar    krb5_enctype *etypes = NULL;
5555682Smarkm
5655682Smarkm    etypes_str = krb5_config_get_strings(context, NULL, "libdefaults",
5755682Smarkm					 name, NULL);
5855682Smarkm    if(etypes_str){
5955682Smarkm	int i, j, k;
6055682Smarkm	for(i = 0; etypes_str[i]; i++);
6155682Smarkm	etypes = malloc((i+1) * sizeof(*etypes));
6255682Smarkm	if (etypes == NULL) {
6355682Smarkm	    krb5_config_free_strings (etypes_str);
6478527Sassar	    krb5_set_error_string (context, "malloc: out of memory");
6555682Smarkm	    return ENOMEM;
6655682Smarkm	}
6755682Smarkm	for(j = 0, k = 0; j < i; j++) {
6855682Smarkm	    if(krb5_string_to_enctype(context, etypes_str[j], &etypes[k]) == 0)
6955682Smarkm		k++;
7055682Smarkm	}
7155682Smarkm	etypes[k] = ETYPE_NULL;
7255682Smarkm	krb5_config_free_strings(etypes_str);
73102644Snectar    }
74102644Snectar    *ret_enctypes = etypes;
7555682Smarkm    return 0;
7655682Smarkm}
7755682Smarkm
7855682Smarkm/*
7955682Smarkm * read variables from the configuration file and set in `context'
8055682Smarkm */
8155682Smarkm
8255682Smarkmstatic krb5_error_code
8355682Smarkminit_context_from_config_file(krb5_context context)
8455682Smarkm{
8590926Snectar    krb5_error_code ret;
8655682Smarkm    const char * tmp;
87102644Snectar    krb5_enctype *tmptypes;
8890926Snectar
8955682Smarkm    INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew");
9055682Smarkm    INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout");
9155682Smarkm    INIT_FIELD(context, int, max_retries, 3, "max_retries");
9255682Smarkm
9372445Sassar    INIT_FIELD(context, string, http_proxy, NULL, "http_proxy");
94102644Snectar
95102644Snectar    ret = set_etypes (context, "default_etypes", &tmptypes);
96102644Snectar    if(ret)
97102644Snectar	return ret;
98102644Snectar    free(context->etypes);
99102644Snectar    context->etypes = tmptypes;
100102644Snectar
101102644Snectar    ret = set_etypes (context, "default_etypes_des", &tmptypes);
102102644Snectar    if(ret)
103102644Snectar	return ret;
104102644Snectar    free(context->etypes_des);
105102644Snectar    context->etypes_des = tmptypes;
10655682Smarkm
10755682Smarkm    /* default keytab name */
108102644Snectar    tmp = NULL;
109102644Snectar    if(!issuid())
110102644Snectar	tmp = getenv("KRB5_KTNAME");
111102644Snectar    if(tmp != NULL)
112102644Snectar	context->default_keytab = tmp;
113102644Snectar    else
114102644Snectar	INIT_FIELD(context, string, default_keytab,
115102644Snectar		   KEYTAB_DEFAULT, "default_keytab_name");
11655682Smarkm
11778527Sassar    INIT_FIELD(context, string, default_keytab_modify,
11890926Snectar	       NULL, "default_keytab_modify_name");
11978527Sassar
12072445Sassar    INIT_FIELD(context, string, time_fmt,
12172445Sassar	       "%Y-%m-%dT%H:%M:%S", "time_format");
12255682Smarkm
12372445Sassar    INIT_FIELD(context, string, date_fmt,
12472445Sassar	       "%Y-%m-%d", "date_format");
12572445Sassar
12672445Sassar    INIT_FIELD(context, bool, log_utc,
12772445Sassar	       FALSE, "log_utc");
12872445Sassar
12972445Sassar
13072445Sassar
13155682Smarkm    /* init dns-proxy slime */
13255682Smarkm    tmp = krb5_config_get_string(context, NULL, "libdefaults",
13355682Smarkm				 "dns_proxy", NULL);
13455682Smarkm    if(tmp)
13555682Smarkm	roken_gethostby_setup(context->http_proxy, tmp);
136102644Snectar    krb5_free_host_realm (context, context->default_realms);
13755682Smarkm    context->default_realms = NULL;
13855682Smarkm
13955682Smarkm    {
14055682Smarkm	krb5_addresses addresses;
14155682Smarkm	char **adr, **a;
142102644Snectar
143102644Snectar	krb5_set_extra_addresses(context, NULL);
14455682Smarkm	adr = krb5_config_get_strings(context, NULL,
14555682Smarkm				      "libdefaults",
14655682Smarkm				      "extra_addresses",
14755682Smarkm				      NULL);
14855682Smarkm	memset(&addresses, 0, sizeof(addresses));
14955682Smarkm	for(a = adr; a && *a; a++) {
15090926Snectar	    ret = krb5_parse_address(context, *a, &addresses);
15190926Snectar	    if (ret == 0) {
15290926Snectar		krb5_add_extra_addresses(context, &addresses);
15390926Snectar		krb5_free_addresses(context, &addresses);
15490926Snectar	    }
15555682Smarkm	}
15655682Smarkm	krb5_config_free_strings(adr);
15790926Snectar
158102644Snectar	krb5_set_ignore_addresses(context, NULL);
15990926Snectar	adr = krb5_config_get_strings(context, NULL,
16090926Snectar				      "libdefaults",
16190926Snectar				      "ignore_addresses",
16290926Snectar				      NULL);
16390926Snectar	memset(&addresses, 0, sizeof(addresses));
16490926Snectar	for(a = adr; a && *a; a++) {
16590926Snectar	    ret = krb5_parse_address(context, *a, &addresses);
16690926Snectar	    if (ret == 0) {
16790926Snectar		krb5_add_ignore_addresses(context, &addresses);
16890926Snectar		krb5_free_addresses(context, &addresses);
16990926Snectar	    }
17090926Snectar	}
17190926Snectar	krb5_config_free_strings(adr);
17255682Smarkm    }
17355682Smarkm
17455682Smarkm    INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces");
17555682Smarkm    INIT_FIELD(context, int, fcache_vno, 0, "fcache_version");
176103423Snectar    /* prefer dns_lookup_kdc over srv_lookup. */
177103423Snectar    INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
178103423Snectar    INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc");
17955682Smarkm    return 0;
18055682Smarkm}
18155682Smarkm
18255682Smarkmkrb5_error_code
18355682Smarkmkrb5_init_context(krb5_context *context)
18455682Smarkm{
18555682Smarkm    krb5_context p;
18655682Smarkm    krb5_error_code ret;
187102644Snectar    char **files;
18855682Smarkm
189102644Snectar    p = calloc(1, sizeof(*p));
19055682Smarkm    if(!p)
19155682Smarkm	return ENOMEM;
19255682Smarkm
193102644Snectar    ret = krb5_get_default_config_files(&files);
194102644Snectar    if(ret)
195102644Snectar	goto out;
196102644Snectar    ret = krb5_set_config_files(p, files);
197102644Snectar    krb5_free_config_files(files);
198102644Snectar    if(ret)
199102644Snectar	goto out;
200102644Snectar
20155682Smarkm    /* init error tables */
20255682Smarkm    krb5_init_ets(p);
20355682Smarkm
204102644Snectar    p->cc_ops = NULL;
205102644Snectar    p->num_cc_ops = 0;
206102644Snectar    krb5_cc_register(p, &krb5_fcc_ops, TRUE);
207102644Snectar    krb5_cc_register(p, &krb5_mcc_ops, TRUE);
20855682Smarkm
209102644Snectar    p->num_kt_types = 0;
210102644Snectar    p->kt_types     = NULL;
211102644Snectar    krb5_kt_register (p, &krb5_fkt_ops);
212102644Snectar    krb5_kt_register (p, &krb5_mkt_ops);
213102644Snectar    krb5_kt_register (p, &krb5_akf_ops);
214102644Snectar    krb5_kt_register (p, &krb4_fkt_ops);
215102644Snectar    krb5_kt_register (p, &krb5_srvtab_fkt_ops);
216102644Snectar    krb5_kt_register (p, &krb5_any_ops);
21755682Smarkm
218102644Snectarout:
21972445Sassar    if(ret) {
22072445Sassar	krb5_free_context(p);
221102644Snectar	p = NULL;
22272445Sassar    }
22355682Smarkm    *context = p;
224102644Snectar    return ret;
22555682Smarkm}
22655682Smarkm
22755682Smarkmvoid
22855682Smarkmkrb5_free_context(krb5_context context)
22955682Smarkm{
23090926Snectar    free(context->etypes);
23190926Snectar    free(context->etypes_des);
23290926Snectar    krb5_free_host_realm (context, context->default_realms);
23390926Snectar    krb5_config_file_free (context, context->cf);
23490926Snectar    free_error_table (context->et_list);
23590926Snectar    free(context->cc_ops);
23690926Snectar    free(context->kt_types);
23790926Snectar    krb5_clear_error_string(context);
23890926Snectar    if(context->warn_dest != NULL)
23990926Snectar	krb5_closelog(context, context->warn_dest);
24090926Snectar    krb5_set_extra_addresses(context, NULL);
24190926Snectar    krb5_set_ignore_addresses(context, NULL);
24290926Snectar    free(context);
24355682Smarkm}
24455682Smarkm
245102644Snectarkrb5_error_code
246102644Snectarkrb5_set_config_files(krb5_context context, char **filenames)
247102644Snectar{
248102644Snectar    krb5_error_code ret;
249102644Snectar    krb5_config_binding *tmp = NULL;
250102644Snectar    while(filenames != NULL && *filenames != NULL && **filenames != '\0') {
251102644Snectar	ret = krb5_config_parse_file_multi(context, *filenames, &tmp);
252102644Snectar	if(ret != 0 && ret != ENOENT) {
253102644Snectar	    krb5_config_file_free(context, tmp);
254102644Snectar	    return ret;
255102644Snectar	}
256102644Snectar	filenames++;
257102644Snectar    }
258102644Snectar#if 0
259102644Snectar    /* with this enabled and if there are no config files, Kerberos is
260102644Snectar       considererd disabled */
261102644Snectar    if(tmp == NULL)
262107207Snectar	return ENXIO;
263102644Snectar#endif
264102644Snectar    krb5_config_file_free(context, context->cf);
265102644Snectar    context->cf = tmp;
266102644Snectar    ret = init_context_from_config_file(context);
267102644Snectar    return ret;
268102644Snectar}
269102644Snectar
270102644Snectarkrb5_error_code
271102644Snectarkrb5_get_default_config_files(char ***pfilenames)
272102644Snectar{
273102644Snectar    const char *p, *q;
274102644Snectar    char **pp;
275102644Snectar    int n, i;
276102644Snectar
277102644Snectar    const char *files = NULL;
278102644Snectar    if (pfilenames == NULL)
279102644Snectar        return EINVAL;
280102644Snectar    if(!issuid())
281102644Snectar	files = getenv("KRB5_CONFIG");
282102644Snectar    if (files == NULL)
283102644Snectar	files = krb5_config_file;
284102644Snectar
285102644Snectar    for(n = 0, p = files; strsep_copy(&p, ":", NULL, 0) != -1; n++);
286102644Snectar    pp = malloc((n + 1) * sizeof(*pp));
287102644Snectar    if(pp == NULL)
288102644Snectar	return ENOMEM;
289102644Snectar
290102644Snectar    n = 0;
291102644Snectar    p = files;
292102644Snectar    while(1) {
293102644Snectar	ssize_t l;
294102644Snectar	q = p;
295102644Snectar	l = strsep_copy(&q, ":", NULL, 0);
296102644Snectar	if(l == -1)
297102644Snectar	    break;
298102644Snectar	pp[n] = malloc(l + 1);
299102644Snectar	if(pp[n] == NULL) {
300102644Snectar	    krb5_free_config_files(pp);
301102644Snectar	    return ENOMEM;
302102644Snectar	}
303102644Snectar	l = strsep_copy(&p, ":", pp[n], l + 1);
304102644Snectar	for(i = 0; i < n; i++)
305102644Snectar	    if(strcmp(pp[i], pp[n]) == 0) {
306102644Snectar		free(pp[n]);
307102644Snectar		goto skip;
308102644Snectar	    }
309102644Snectar	n++;
310102644Snectar    skip:;
311102644Snectar    }
312102644Snectar    pp[n] = NULL;
313102644Snectar    *pfilenames = pp;
314102644Snectar    return 0;
315102644Snectar}
316102644Snectar
317102644Snectarvoid
318102644Snectarkrb5_free_config_files(char **filenames)
319102644Snectar{
320102644Snectar    char **p;
321102644Snectar    for(p = filenames; *p != NULL; p++)
322102644Snectar	free(*p);
323102644Snectar    free(filenames);
324102644Snectar}
325102644Snectar
32672445Sassar/*
32772445Sassar * set `etype' to a malloced list of the default enctypes
32872445Sassar */
32972445Sassar
33055682Smarkmstatic krb5_error_code
33178527Sassardefault_etypes(krb5_context context, krb5_enctype **etype)
33255682Smarkm{
33355682Smarkm    krb5_enctype p[] = {
33455682Smarkm	ETYPE_DES3_CBC_SHA1,
33555682Smarkm	ETYPE_DES3_CBC_MD5,
33672445Sassar	ETYPE_ARCFOUR_HMAC_MD5,
33755682Smarkm	ETYPE_DES_CBC_MD5,
33855682Smarkm	ETYPE_DES_CBC_MD4,
33955682Smarkm	ETYPE_DES_CBC_CRC,
34055682Smarkm	ETYPE_NULL
34155682Smarkm    };
34278527Sassar
34355682Smarkm    *etype = malloc(sizeof(p));
34478527Sassar    if(*etype == NULL) {
34578527Sassar	krb5_set_error_string (context, "malloc: out of memory");
34655682Smarkm	return ENOMEM;
34778527Sassar    }
34855682Smarkm    memcpy(*etype, p, sizeof(p));
34955682Smarkm    return 0;
35055682Smarkm}
35155682Smarkm
35255682Smarkmkrb5_error_code
35355682Smarkmkrb5_set_default_in_tkt_etypes(krb5_context context,
35455682Smarkm			       const krb5_enctype *etypes)
35555682Smarkm{
35655682Smarkm    int i;
35755682Smarkm    krb5_enctype *p = NULL;
35855682Smarkm
35955682Smarkm    if(etypes) {
36078527Sassar	for (i = 0; etypes[i]; ++i)
36178527Sassar	    if(!krb5_enctype_valid(context, etypes[i])) {
36278527Sassar		krb5_set_error_string(context, "enctype %d not supported",
36378527Sassar				      etypes[i]);
36455682Smarkm		return KRB5_PROG_ETYPE_NOSUPP;
36578527Sassar	    }
36655682Smarkm	++i;
36755682Smarkm	ALLOC(p, i);
36878527Sassar	if(!p) {
36978527Sassar	    krb5_set_error_string (context, "malloc: out of memory");
37055682Smarkm	    return ENOMEM;
37178527Sassar	}
37255682Smarkm	memmove(p, etypes, i * sizeof(krb5_enctype));
37355682Smarkm    }
37455682Smarkm    if(context->etypes)
37555682Smarkm	free(context->etypes);
37655682Smarkm    context->etypes = p;
37755682Smarkm    return 0;
37855682Smarkm}
37955682Smarkm
38055682Smarkm
38155682Smarkmkrb5_error_code
38255682Smarkmkrb5_get_default_in_tkt_etypes(krb5_context context,
38355682Smarkm			       krb5_enctype **etypes)
38455682Smarkm{
38555682Smarkm  krb5_enctype *p;
38655682Smarkm  int i;
38778527Sassar  krb5_error_code ret;
38855682Smarkm
38955682Smarkm  if(context->etypes) {
39055682Smarkm    for(i = 0; context->etypes[i]; i++);
39155682Smarkm    ++i;
39255682Smarkm    ALLOC(p, i);
39378527Sassar    if(!p) {
39478527Sassar      krb5_set_error_string (context, "malloc: out of memory");
39555682Smarkm      return ENOMEM;
39678527Sassar    }
39755682Smarkm    memmove(p, context->etypes, i * sizeof(krb5_enctype));
39878527Sassar  } else {
39978527Sassar    ret = default_etypes(context, &p);
40078527Sassar    if (ret)
40178527Sassar      return ret;
40278527Sassar  }
40355682Smarkm  *etypes = p;
40455682Smarkm  return 0;
40555682Smarkm}
40655682Smarkm
40755682Smarkmconst char *
40855682Smarkmkrb5_get_err_text(krb5_context context, krb5_error_code code)
40955682Smarkm{
41090926Snectar    const char *p = NULL;
41190926Snectar    if(context != NULL)
41290926Snectar	p = com_right(context->et_list, code);
41355682Smarkm    if(p == NULL)
41455682Smarkm	p = strerror(code);
41555682Smarkm    return p;
41655682Smarkm}
41755682Smarkm
41855682Smarkmvoid
41955682Smarkmkrb5_init_ets(krb5_context context)
42055682Smarkm{
42155682Smarkm    if(context->et_list == NULL){
42278527Sassar	krb5_add_et_list(context, initialize_krb5_error_table_r);
42378527Sassar	krb5_add_et_list(context, initialize_asn1_error_table_r);
42478527Sassar	krb5_add_et_list(context, initialize_heim_error_table_r);
42590926Snectar	krb5_add_et_list(context, initialize_k524_error_table_r);
42655682Smarkm    }
42755682Smarkm}
42855682Smarkm
42955682Smarkmvoid
43055682Smarkmkrb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
43155682Smarkm{
43255682Smarkm    context->use_admin_kdc = flag;
43355682Smarkm}
43455682Smarkm
43555682Smarkmkrb5_boolean
43655682Smarkmkrb5_get_use_admin_kdc (krb5_context context)
43755682Smarkm{
43855682Smarkm    return context->use_admin_kdc;
43955682Smarkm}
44055682Smarkm
44155682Smarkmkrb5_error_code
44255682Smarkmkrb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
44355682Smarkm{
44455682Smarkm
44555682Smarkm    if(context->extra_addresses)
44655682Smarkm	return krb5_append_addresses(context,
44755682Smarkm				     context->extra_addresses, addresses);
44855682Smarkm    else
44955682Smarkm	return krb5_set_extra_addresses(context, addresses);
45055682Smarkm}
45155682Smarkm
45255682Smarkmkrb5_error_code
45357419Smarkmkrb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
45455682Smarkm{
45590926Snectar    if(context->extra_addresses)
45655682Smarkm	krb5_free_addresses(context, context->extra_addresses);
45790926Snectar
45890926Snectar    if(addresses == NULL) {
45990926Snectar	if(context->extra_addresses != NULL) {
46090926Snectar	    free(context->extra_addresses);
46190926Snectar	    context->extra_addresses = NULL;
46290926Snectar	}
46390926Snectar	return 0;
46455682Smarkm    }
46555682Smarkm    if(context->extra_addresses == NULL) {
46655682Smarkm	context->extra_addresses = malloc(sizeof(*context->extra_addresses));
46778527Sassar	if(context->extra_addresses == NULL) {
46878527Sassar	    krb5_set_error_string (context, "malloc: out of memory");
46955682Smarkm	    return ENOMEM;
47078527Sassar	}
47155682Smarkm    }
47257419Smarkm    return krb5_copy_addresses(context, addresses, context->extra_addresses);
47355682Smarkm}
47455682Smarkm
47555682Smarkmkrb5_error_code
47655682Smarkmkrb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
47755682Smarkm{
47855682Smarkm    if(context->extra_addresses == NULL) {
47955682Smarkm	memset(addresses, 0, sizeof(*addresses));
48055682Smarkm	return 0;
48155682Smarkm    }
48290926Snectar    return krb5_copy_addresses(context,context->extra_addresses, addresses);
48355682Smarkm}
48455682Smarkm
48555682Smarkmkrb5_error_code
48690926Snectarkrb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
48790926Snectar{
48890926Snectar
48990926Snectar    if(context->ignore_addresses)
49090926Snectar	return krb5_append_addresses(context,
49190926Snectar				     context->ignore_addresses, addresses);
49290926Snectar    else
49390926Snectar	return krb5_set_ignore_addresses(context, addresses);
49490926Snectar}
49590926Snectar
49690926Snectarkrb5_error_code
49790926Snectarkrb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
49890926Snectar{
49990926Snectar    if(context->ignore_addresses)
50090926Snectar	krb5_free_addresses(context, context->ignore_addresses);
50190926Snectar    if(addresses == NULL) {
50290926Snectar	if(context->ignore_addresses != NULL) {
50390926Snectar	    free(context->ignore_addresses);
50490926Snectar	    context->ignore_addresses = NULL;
50590926Snectar	}
50690926Snectar	return 0;
50790926Snectar    }
50890926Snectar    if(context->ignore_addresses == NULL) {
50990926Snectar	context->ignore_addresses = malloc(sizeof(*context->ignore_addresses));
51090926Snectar	if(context->ignore_addresses == NULL) {
51190926Snectar	    krb5_set_error_string (context, "malloc: out of memory");
51290926Snectar	    return ENOMEM;
51390926Snectar	}
51490926Snectar    }
51590926Snectar    return krb5_copy_addresses(context, addresses, context->ignore_addresses);
51690926Snectar}
51790926Snectar
51890926Snectarkrb5_error_code
51990926Snectarkrb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
52090926Snectar{
52190926Snectar    if(context->ignore_addresses == NULL) {
52290926Snectar	memset(addresses, 0, sizeof(*addresses));
52390926Snectar	return 0;
52490926Snectar    }
52590926Snectar    return krb5_copy_addresses(context, context->ignore_addresses, addresses);
52690926Snectar}
52790926Snectar
52890926Snectarkrb5_error_code
52955682Smarkmkrb5_set_fcache_version(krb5_context context, int version)
53055682Smarkm{
53155682Smarkm    context->fcache_vno = version;
53255682Smarkm    return 0;
53355682Smarkm}
53455682Smarkm
53555682Smarkmkrb5_error_code
53655682Smarkmkrb5_get_fcache_version(krb5_context context, int *version)
53755682Smarkm{
53855682Smarkm    *version = context->fcache_vno;
53955682Smarkm    return 0;
54055682Smarkm}
541