context.c revision 55682
1104862Sru/* 2114402Sru * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H�gskolan 3104862Sru * (Royal Institute of Technology, Stockholm, Sweden). 4104862Sru * All rights reserved. 5104862Sru * 6104862Sru * Redistribution and use in source and binary forms, with or without 7104862Sru * modification, are permitted provided that the following conditions 8104862Sru * are met: 9104862Sru * 10104862Sru * 1. Redistributions of source code must retain the above copyright 11104862Sru * notice, this list of conditions and the following disclaimer. 12104862Sru * 13104862Sru * 2. Redistributions in binary form must reproduce the above copyright 14104862Sru * notice, this list of conditions and the following disclaimer in the 15104862Sru * documentation and/or other materials provided with the distribution. 16104862Sru * 17104862Sru * 3. Neither the name of the Institute nor the names of its contributors 18104862Sru * may be used to endorse or promote products derived from this software 19104862Sru * without specific prior written permission. 20104862Sru * 21104862Sru * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22104862Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23114402Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24114402Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25114402Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26104862Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27114402Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28104862Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29104862Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30104862Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31104862Sru * SUCH DAMAGE. 32104862Sru */ 33104862Sru 34104862Sru#include "krb5_locl.h" 35104862Sru 36104862SruRCSID("$Id: context.c,v 1.51 1999/12/02 17:05:08 joda Exp $"); 37104862Sru 38104862Sru#define INIT_FIELD(C, T, E, D, F) \ 39104862Sru (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ 40104862Sru "libdefaults", F, NULL) 41104862Sru 42104862Sru#ifdef KRB4 43104862Sruextern krb5_kt_ops krb4_fkt_ops; 44104862Sru#endif 45104862Sru 46104862Sru/* 47104862Sru * Set the list of etypes `ret_etypes' from the configuration variable 48104862Sru * `name' 49104862Sru */ 50104862Sru 51104862Srustatic krb5_error_code 52104862Sruset_etypes (krb5_context context, 53104862Sru const char *name, 54104862Sru krb5_enctype **ret_enctypes) 55104862Sru{ 56104862Sru char **etypes_str; 57104862Sru krb5_enctype *etypes; 58104862Sru 59104862Sru etypes_str = krb5_config_get_strings(context, NULL, "libdefaults", 60104862Sru name, NULL); 61104862Sru if(etypes_str){ 62104862Sru int i, j, k; 63104862Sru for(i = 0; etypes_str[i]; i++); 64104862Sru etypes = malloc((i+1) * sizeof(*etypes)); 65104862Sru if (etypes == NULL) { 66104862Sru krb5_config_free_strings (etypes_str); 67104862Sru return ENOMEM; 68104862Sru } 69104862Sru for(j = 0, k = 0; j < i; j++) { 70104862Sru if(krb5_string_to_enctype(context, etypes_str[j], &etypes[k]) == 0) 71104862Sru k++; 72104862Sru } 73104862Sru etypes[k] = ETYPE_NULL; 74104862Sru krb5_config_free_strings(etypes_str); 75104862Sru *ret_enctypes = etypes; 76104862Sru } 77104862Sru return 0; 78104862Sru} 79104862Sru 80104862Sru/* 81104862Sru * read variables from the configuration file and set in `context' 82104862Sru */ 83104862Sru 84104862Srustatic krb5_error_code 85104862Sruinit_context_from_config_file(krb5_context context) 86104862Sru{ 87104862Sru const char * tmp; 88104862Sru INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew"); 89104862Sru INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout"); 90104862Sru INIT_FIELD(context, int, max_retries, 3, "max_retries"); 91104862Sru 92104862Sru context->http_proxy = krb5_config_get_string(context, NULL, "libdefaults", 93104862Sru "http_proxy", NULL); 94104862Sru 95104862Sru set_etypes (context, "default_etypes", &context->etypes); 96104862Sru set_etypes (context, "default_etypes_des", &context->etypes_des); 97104862Sru 98104862Sru /* default keytab name */ 99104862Sru context->default_keytab = krb5_config_get_string(context, NULL, 100104862Sru "libdefaults", 101104862Sru "default_keytab_name", 102104862Sru NULL); 103104862Sru if(context->default_keytab == NULL) 104104862Sru context->default_keytab = KEYTAB_DEFAULT; 105104862Sru 106104862Sru context->time_fmt = krb5_config_get_string(context, NULL, "libdefaults", 107104862Sru "time_format", NULL); 108104862Sru if(context->time_fmt == NULL) 109104862Sru context->time_fmt = "%d-%b-%Y %H:%M:%S"; 110104862Sru context->log_utc = krb5_config_get_bool(context, NULL, "libdefaults", 111104862Sru "log_utc", NULL); 112104862Sru 113104862Sru /* init dns-proxy slime */ 114104862Sru tmp = krb5_config_get_string(context, NULL, "libdefaults", 115104862Sru "dns_proxy", NULL); 116104862Sru if(tmp) 117104862Sru roken_gethostby_setup(context->http_proxy, tmp); 118104862Sru context->default_realms = NULL; 119104862Sru 120104862Sru { 121104862Sru krb5_addresses addresses; 122104862Sru char **adr, **a; 123104862Sru adr = krb5_config_get_strings(context, NULL, 124104862Sru "libdefaults", 125104862Sru "extra_addresses", 126104862Sru NULL); 127104862Sru memset(&addresses, 0, sizeof(addresses)); 128104862Sru for(a = adr; a && *a; a++) { 129104862Sru krb5_parse_address(context, *a, &addresses); 130104862Sru krb5_add_extra_addresses(context, &addresses); 131104862Sru krb5_free_addresses(context, &addresses); 132104862Sru } 133104862Sru krb5_config_free_strings(adr); 134104862Sru } 135104862Sru 136104862Sru INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces"); 137104862Sru INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup"); 138104862Sru INIT_FIELD(context, bool, srv_try_txt, FALSE, "srv_try_txt"); 139104862Sru INIT_FIELD(context, bool, srv_try_rfc2052, TRUE, "srv_try_rfc2052"); 140104862Sru INIT_FIELD(context, int, fcache_vno, 0, "fcache_version"); 141104862Sru 142104862Sru context->cc_ops = NULL; 143104862Sru context->num_cc_ops = 0; 144104862Sru krb5_cc_register(context, &krb5_fcc_ops, TRUE); 145104862Sru krb5_cc_register(context, &krb5_mcc_ops, TRUE); 146104862Sru 147104862Sru context->num_kt_types = 0; 148104862Sru context->kt_types = NULL; 149104862Sru krb5_kt_register (context, &krb5_fkt_ops); 150104862Sru krb5_kt_register (context, &krb5_mkt_ops); 151104862Sru#ifdef KRB4 152104862Sru krb5_kt_register (context, &krb4_fkt_ops); 153104862Sru#endif 154104862Sru krb5_kt_register (context, &krb5_akf_ops); 155104862Sru return 0; 156104862Sru} 157104862Sru 158104862Srukrb5_error_code 159104862Srukrb5_init_context(krb5_context *context) 160104862Sru{ 161104862Sru krb5_context p; 162104862Sru const char *config_file = NULL; 163104862Sru krb5_config_section *tmp_cf; 164104862Sru krb5_error_code ret; 165104862Sru 166104862Sru ALLOC(p, 1); 167104862Sru if(!p) 168104862Sru return ENOMEM; 169104862Sru memset(p, 0, sizeof(krb5_context_data)); 170104862Sru 171104862Sru /* init error tables */ 172104862Sru krb5_init_ets(p); 173104862Sru 174104862Sru if(!issuid()) 175104862Sru config_file = getenv("KRB5_CONFIG"); 176104862Sru if (config_file == NULL) 177104862Sru config_file = krb5_config_file; 178104862Sru 179104862Sru ret = krb5_config_parse_file (config_file, &tmp_cf); 180104862Sru 181104862Sru if (ret == 0) 182104862Sru p->cf = tmp_cf; 183104862Sru#if 0 184104862Sru else 185104862Sru krb5_warnx (p, "Unable to parse config file %s. Ignoring.", 186104862Sru config_file); /* XXX */ 187104862Sru#endif 188104862Sru 189104862Sru ret = init_context_from_config_file(p); 190114402Sru if(ret) 191104862Sru return ret; 192104862Sru 193104862Sru *context = p; 194104862Sru return 0; 195104862Sru} 196104862Sru 197104862Sruvoid 198104862Srukrb5_free_context(krb5_context context) 199104862Sru{ 200104862Sru int i; 201104862Sru 202104862Sru free(context->etypes); 203104862Sru free(context->etypes_des); 204104862Sru krb5_free_host_realm (context, context->default_realms); 205104862Sru krb5_config_file_free (context, context->cf); 206104862Sru free_error_table (context->et_list); 207104862Sru for(i = 0; i < context->num_cc_ops; ++i) 208104862Sru free(context->cc_ops[i].prefix); 209104862Sru free(context->cc_ops); 210104862Sru free(context->kt_types); 211104862Sru free(context); 212104862Sru} 213104862Sru 214104862Srustatic krb5_error_code 215104862Srudefault_etypes(krb5_enctype **etype) 216104862Sru{ 217104862Sru krb5_enctype p[] = { 218104862Sru ETYPE_DES3_CBC_SHA1, 219104862Sru ETYPE_DES3_CBC_MD5, 220104862Sru ETYPE_DES_CBC_MD5, 221104862Sru ETYPE_DES_CBC_MD4, 222104862Sru ETYPE_DES_CBC_CRC, 223104862Sru ETYPE_NULL 224104862Sru }; 225104862Sru *etype = malloc(sizeof(p)); 226104862Sru if(*etype == NULL) 227104862Sru return ENOMEM; 228104862Sru memcpy(*etype, p, sizeof(p)); 229104862Sru return 0; 230104862Sru} 231104862Sru 232104862Srukrb5_error_code 233104862Srukrb5_set_default_in_tkt_etypes(krb5_context context, 234104862Sru const krb5_enctype *etypes) 235104862Sru{ 236104862Sru int i; 237104862Sru krb5_enctype *p = NULL; 238104862Sru 239104862Sru if(etypes) { 240104862Sru i = 0; 241104862Sru while(etypes[i]) 242104862Sru if(!krb5_enctype_valid(context, etypes[i++])) 243104862Sru return KRB5_PROG_ETYPE_NOSUPP; 244104862Sru ++i; 245104862Sru ALLOC(p, i); 246104862Sru if(!p) 247114402Sru return ENOMEM; 248104862Sru memmove(p, etypes, i * sizeof(krb5_enctype)); 249104862Sru } 250104862Sru if(context->etypes) 251104862Sru free(context->etypes); 252104862Sru context->etypes = p; 253104862Sru return 0; 254104862Sru} 255104862Sru 256104862Sru 257104862Srukrb5_error_code 258104862Srukrb5_get_default_in_tkt_etypes(krb5_context context, 259104862Sru krb5_enctype **etypes) 260104862Sru{ 261104862Sru krb5_enctype *p; 262104862Sru int i; 263104862Sru 264104862Sru if(context->etypes) { 265104862Sru for(i = 0; context->etypes[i]; i++); 266104862Sru ++i; 267104862Sru ALLOC(p, i); 268104862Sru if(!p) 269104862Sru return ENOMEM; 270104862Sru memmove(p, context->etypes, i * sizeof(krb5_enctype)); 271104862Sru } else 272104862Sru if(default_etypes(&p)) 273104862Sru return ENOMEM; 274104862Sru *etypes = p; 275104862Sru return 0; 276104862Sru} 277104862Sru 278104862Sruconst char * 279104862Srukrb5_get_err_text(krb5_context context, krb5_error_code code) 280104862Sru{ 281104862Sru const char *p = com_right(context->et_list, code); 282104862Sru if(p == NULL) 283104862Sru p = strerror(code); 284104862Sru return p; 285104862Sru} 286104862Sru 287104862Sruvoid 288104862Srukrb5_init_ets(krb5_context context) 289104862Sru{ 290104862Sru if(context->et_list == NULL){ 291104862Sru initialize_krb5_error_table_r(&context->et_list); 292104862Sru initialize_asn1_error_table_r(&context->et_list); 293104862Sru initialize_heim_error_table_r(&context->et_list); 294104862Sru } 295104862Sru} 296104862Sru 297104862Sruvoid 298104862Srukrb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag) 299104862Sru{ 300104862Sru context->use_admin_kdc = flag; 301104862Sru} 302104862Sru 303104862Srukrb5_boolean 304104862Srukrb5_get_use_admin_kdc (krb5_context context) 305104862Sru{ 306104862Sru return context->use_admin_kdc; 307104862Sru} 308104862Sru 309104862Srukrb5_error_code 310104862Srukrb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses) 311104862Sru{ 312104862Sru 313104862Sru if(context->extra_addresses) 314104862Sru return krb5_append_addresses(context, 315104862Sru context->extra_addresses, addresses); 316104862Sru else 317104862Sru return krb5_set_extra_addresses(context, addresses); 318104862Sru} 319104862Sru 320104862Srukrb5_error_code 321104862Srukrb5_set_extra_addresses(krb5_context context, krb5_addresses *addresses) 322104862Sru{ 323104862Sru if(context->extra_addresses) { 324104862Sru krb5_free_addresses(context, context->extra_addresses); 325104862Sru free(context->extra_addresses); 326104862Sru } 327104862Sru if(context->extra_addresses == NULL) { 328104862Sru context->extra_addresses = malloc(sizeof(*context->extra_addresses)); 329104862Sru if(context->extra_addresses == NULL) 330104862Sru return ENOMEM; 331104862Sru } 332104862Sru return copy_HostAddresses(addresses, context->extra_addresses); 333104862Sru} 334104862Sru 335104862Srukrb5_error_code 336104862Srukrb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses) 337104862Sru{ 338104862Sru if(context->extra_addresses == NULL) { 339104862Sru memset(addresses, 0, sizeof(*addresses)); 340104862Sru return 0; 341104862Sru } 342104862Sru return copy_HostAddresses(context->extra_addresses, addresses); 343104862Sru} 344104862Sru 345104862Srukrb5_error_code 346104862Srukrb5_set_fcache_version(krb5_context context, int version) 347104862Sru{ 348104862Sru context->fcache_vno = version; 349104862Sru return 0; 350104862Sru} 351104862Sru 352104862Srukrb5_error_code 353104862Srukrb5_get_fcache_version(krb5_context context, int *version) 354104862Sru{ 355 *version = context->fcache_vno; 356 return 0; 357} 358