155682Smarkm/* 2178825Sdfr * Copyright (c) 1997 - 2005 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 37178825SdfrRCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $"); 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 43178825Sdfr#define INIT_FLAG(C, O, V, D, F) \ 44178825Sdfr do { \ 45178825Sdfr if (krb5_config_get_bool_default((C), NULL, (D),"libdefaults", F, NULL)) { \ 46178825Sdfr (C)->O |= V; \ 47178825Sdfr } \ 48178825Sdfr } while(0) 49178825Sdfr 5055682Smarkm/* 5155682Smarkm * Set the list of etypes `ret_etypes' from the configuration variable 5255682Smarkm * `name' 5355682Smarkm */ 5455682Smarkm 5555682Smarkmstatic krb5_error_code 5655682Smarkmset_etypes (krb5_context context, 5755682Smarkm const char *name, 5855682Smarkm krb5_enctype **ret_enctypes) 5955682Smarkm{ 6055682Smarkm char **etypes_str; 61102644Snectar krb5_enctype *etypes = NULL; 6255682Smarkm 6355682Smarkm etypes_str = krb5_config_get_strings(context, NULL, "libdefaults", 6455682Smarkm name, NULL); 6555682Smarkm if(etypes_str){ 6655682Smarkm int i, j, k; 6755682Smarkm for(i = 0; etypes_str[i]; i++); 6855682Smarkm etypes = malloc((i+1) * sizeof(*etypes)); 6955682Smarkm if (etypes == NULL) { 7055682Smarkm krb5_config_free_strings (etypes_str); 7178527Sassar krb5_set_error_string (context, "malloc: out of memory"); 7255682Smarkm return ENOMEM; 7355682Smarkm } 7455682Smarkm for(j = 0, k = 0; j < i; j++) { 75178825Sdfr krb5_enctype e; 76178825Sdfr if(krb5_string_to_enctype(context, etypes_str[j], &e) != 0) 77178825Sdfr continue; 78178825Sdfr if (krb5_enctype_valid(context, e) != 0) 79178825Sdfr continue; 80178825Sdfr etypes[k++] = e; 8155682Smarkm } 8255682Smarkm etypes[k] = ETYPE_NULL; 8355682Smarkm krb5_config_free_strings(etypes_str); 84102644Snectar } 85102644Snectar *ret_enctypes = etypes; 8655682Smarkm return 0; 8755682Smarkm} 8855682Smarkm 8955682Smarkm/* 9055682Smarkm * read variables from the configuration file and set in `context' 9155682Smarkm */ 9255682Smarkm 9355682Smarkmstatic krb5_error_code 9455682Smarkminit_context_from_config_file(krb5_context context) 9555682Smarkm{ 9690926Snectar krb5_error_code ret; 9755682Smarkm const char * tmp; 98102644Snectar krb5_enctype *tmptypes; 9990926Snectar 10055682Smarkm INIT_FIELD(context, time, max_skew, 5 * 60, "clockskew"); 10155682Smarkm INIT_FIELD(context, time, kdc_timeout, 3, "kdc_timeout"); 10255682Smarkm INIT_FIELD(context, int, max_retries, 3, "max_retries"); 10355682Smarkm 10472445Sassar INIT_FIELD(context, string, http_proxy, NULL, "http_proxy"); 105102644Snectar 106102644Snectar ret = set_etypes (context, "default_etypes", &tmptypes); 107102644Snectar if(ret) 108102644Snectar return ret; 109102644Snectar free(context->etypes); 110102644Snectar context->etypes = tmptypes; 111102644Snectar 112102644Snectar ret = set_etypes (context, "default_etypes_des", &tmptypes); 113102644Snectar if(ret) 114102644Snectar return ret; 115102644Snectar free(context->etypes_des); 116102644Snectar context->etypes_des = tmptypes; 11755682Smarkm 11855682Smarkm /* default keytab name */ 119102644Snectar tmp = NULL; 120102644Snectar if(!issuid()) 121102644Snectar tmp = getenv("KRB5_KTNAME"); 122102644Snectar if(tmp != NULL) 123102644Snectar context->default_keytab = tmp; 124102644Snectar else 125102644Snectar INIT_FIELD(context, string, default_keytab, 126102644Snectar KEYTAB_DEFAULT, "default_keytab_name"); 12755682Smarkm 12878527Sassar INIT_FIELD(context, string, default_keytab_modify, 12990926Snectar NULL, "default_keytab_modify_name"); 13078527Sassar 13172445Sassar INIT_FIELD(context, string, time_fmt, 13272445Sassar "%Y-%m-%dT%H:%M:%S", "time_format"); 13355682Smarkm 13472445Sassar INIT_FIELD(context, string, date_fmt, 13572445Sassar "%Y-%m-%d", "date_format"); 13672445Sassar 13772445Sassar INIT_FIELD(context, bool, log_utc, 13872445Sassar FALSE, "log_utc"); 13972445Sassar 14072445Sassar 14172445Sassar 14255682Smarkm /* init dns-proxy slime */ 14355682Smarkm tmp = krb5_config_get_string(context, NULL, "libdefaults", 14455682Smarkm "dns_proxy", NULL); 14555682Smarkm if(tmp) 14655682Smarkm roken_gethostby_setup(context->http_proxy, tmp); 147102644Snectar krb5_free_host_realm (context, context->default_realms); 14855682Smarkm context->default_realms = NULL; 14955682Smarkm 15055682Smarkm { 15155682Smarkm krb5_addresses addresses; 15255682Smarkm char **adr, **a; 153102644Snectar 154102644Snectar krb5_set_extra_addresses(context, NULL); 15555682Smarkm adr = krb5_config_get_strings(context, NULL, 15655682Smarkm "libdefaults", 15755682Smarkm "extra_addresses", 15855682Smarkm NULL); 15955682Smarkm memset(&addresses, 0, sizeof(addresses)); 16055682Smarkm for(a = adr; a && *a; a++) { 16190926Snectar ret = krb5_parse_address(context, *a, &addresses); 16290926Snectar if (ret == 0) { 16390926Snectar krb5_add_extra_addresses(context, &addresses); 16490926Snectar krb5_free_addresses(context, &addresses); 16590926Snectar } 16655682Smarkm } 16755682Smarkm krb5_config_free_strings(adr); 16890926Snectar 169102644Snectar krb5_set_ignore_addresses(context, NULL); 17090926Snectar adr = krb5_config_get_strings(context, NULL, 17190926Snectar "libdefaults", 17290926Snectar "ignore_addresses", 17390926Snectar NULL); 17490926Snectar memset(&addresses, 0, sizeof(addresses)); 17590926Snectar for(a = adr; a && *a; a++) { 17690926Snectar ret = krb5_parse_address(context, *a, &addresses); 17790926Snectar if (ret == 0) { 17890926Snectar krb5_add_ignore_addresses(context, &addresses); 17990926Snectar krb5_free_addresses(context, &addresses); 18090926Snectar } 18190926Snectar } 18290926Snectar krb5_config_free_strings(adr); 18355682Smarkm } 18455682Smarkm 18555682Smarkm INIT_FIELD(context, bool, scan_interfaces, TRUE, "scan_interfaces"); 18655682Smarkm INIT_FIELD(context, int, fcache_vno, 0, "fcache_version"); 187103423Snectar /* prefer dns_lookup_kdc over srv_lookup. */ 188103423Snectar INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup"); 189103423Snectar INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc"); 190178825Sdfr INIT_FIELD(context, int, large_msg_size, 1400, "large_message_size"); 191178825Sdfr INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname"); 192178825Sdfr INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac"); 193120945Snectar context->default_cc_name = NULL; 194178825Sdfr context->default_cc_name_set = 0; 19555682Smarkm return 0; 19655682Smarkm} 19755682Smarkm 198178825Sdfr/** 199178825Sdfr * Initializes the context structure and reads the configuration file 200178825Sdfr * /etc/krb5.conf. The structure should be freed by calling 201178825Sdfr * krb5_free_context() when it is no longer being used. 202178825Sdfr * 203178825Sdfr * @param context pointer to returned context 204178825Sdfr * 205178825Sdfr * @return Returns 0 to indicate success. Otherwise an errno code is 206178825Sdfr * returned. Failure means either that something bad happened during 207178825Sdfr * initialization (typically ENOMEM) or that Kerberos should not be 208178825Sdfr * used ENXIO. 209178825Sdfr * 210178825Sdfr * @ingroup krb5 211178825Sdfr */ 212178825Sdfr 213178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 21455682Smarkmkrb5_init_context(krb5_context *context) 21555682Smarkm{ 21655682Smarkm krb5_context p; 21755682Smarkm krb5_error_code ret; 218102644Snectar char **files; 21955682Smarkm 220178825Sdfr *context = NULL; 221178825Sdfr 222102644Snectar p = calloc(1, sizeof(*p)); 22355682Smarkm if(!p) 22455682Smarkm return ENOMEM; 22555682Smarkm 226178825Sdfr p->mutex = malloc(sizeof(HEIMDAL_MUTEX)); 227178825Sdfr if (p->mutex == NULL) { 228178825Sdfr free(p); 229178825Sdfr return ENOMEM; 230178825Sdfr } 231178825Sdfr HEIMDAL_MUTEX_init(p->mutex); 232178825Sdfr 233102644Snectar ret = krb5_get_default_config_files(&files); 234102644Snectar if(ret) 235102644Snectar goto out; 236102644Snectar ret = krb5_set_config_files(p, files); 237102644Snectar krb5_free_config_files(files); 238102644Snectar if(ret) 239102644Snectar goto out; 240102644Snectar 24155682Smarkm /* init error tables */ 24255682Smarkm krb5_init_ets(p); 24355682Smarkm 244102644Snectar p->cc_ops = NULL; 245102644Snectar p->num_cc_ops = 0; 246178825Sdfr krb5_cc_register(p, &krb5_acc_ops, TRUE); 247102644Snectar krb5_cc_register(p, &krb5_fcc_ops, TRUE); 248102644Snectar krb5_cc_register(p, &krb5_mcc_ops, TRUE); 249178825Sdfr#ifdef HAVE_KCM 250178825Sdfr krb5_cc_register(p, &krb5_kcm_ops, TRUE); 251178825Sdfr#endif 25255682Smarkm 253102644Snectar p->num_kt_types = 0; 254102644Snectar p->kt_types = NULL; 255102644Snectar krb5_kt_register (p, &krb5_fkt_ops); 256178825Sdfr krb5_kt_register (p, &krb5_wrfkt_ops); 257178825Sdfr krb5_kt_register (p, &krb5_javakt_ops); 258102644Snectar krb5_kt_register (p, &krb5_mkt_ops); 259102644Snectar krb5_kt_register (p, &krb5_akf_ops); 260102644Snectar krb5_kt_register (p, &krb4_fkt_ops); 261102644Snectar krb5_kt_register (p, &krb5_srvtab_fkt_ops); 262102644Snectar krb5_kt_register (p, &krb5_any_ops); 26355682Smarkm 264102644Snectarout: 26572445Sassar if(ret) { 26672445Sassar krb5_free_context(p); 267102644Snectar p = NULL; 26872445Sassar } 26955682Smarkm *context = p; 270102644Snectar return ret; 27155682Smarkm} 27255682Smarkm 273178825Sdfr/** 274178825Sdfr * Frees the krb5_context allocated by krb5_init_context(). 275178825Sdfr * 276178825Sdfr * @param context context to be freed. 277178825Sdfr * 278178825Sdfr * @ingroup krb5 279178825Sdfr*/ 280178825Sdfr 281178825Sdfrvoid KRB5_LIB_FUNCTION 28255682Smarkmkrb5_free_context(krb5_context context) 28355682Smarkm{ 284120945Snectar if (context->default_cc_name) 285120945Snectar free(context->default_cc_name); 286178825Sdfr if (context->default_cc_name_env) 287178825Sdfr free(context->default_cc_name_env); 28890926Snectar free(context->etypes); 28990926Snectar free(context->etypes_des); 29090926Snectar krb5_free_host_realm (context, context->default_realms); 29190926Snectar krb5_config_file_free (context, context->cf); 29290926Snectar free_error_table (context->et_list); 29390926Snectar free(context->cc_ops); 29490926Snectar free(context->kt_types); 29590926Snectar krb5_clear_error_string(context); 29690926Snectar if(context->warn_dest != NULL) 29790926Snectar krb5_closelog(context, context->warn_dest); 29890926Snectar krb5_set_extra_addresses(context, NULL); 29990926Snectar krb5_set_ignore_addresses(context, NULL); 300178825Sdfr krb5_set_send_to_kdc_func(context, NULL, NULL); 301178825Sdfr if (context->mutex != NULL) { 302178825Sdfr HEIMDAL_MUTEX_destroy(context->mutex); 303178825Sdfr free(context->mutex); 304178825Sdfr } 305178825Sdfr memset(context, 0, sizeof(*context)); 30690926Snectar free(context); 30755682Smarkm} 30855682Smarkm 309178825Sdfr/** 310178825Sdfr * Reinit the context from a new set of filenames. 311178825Sdfr * 312178825Sdfr * @param context context to add configuration too. 313178825Sdfr * @param filenames array of filenames, end of list is indicated with a NULL filename. 314178825Sdfr * 315178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 316178825Sdfr * error code is returned, see krb5_get_error_message(). 317178825Sdfr * 318178825Sdfr * @ingroup krb5 319178825Sdfr */ 320178825Sdfr 321178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 322102644Snectarkrb5_set_config_files(krb5_context context, char **filenames) 323102644Snectar{ 324102644Snectar krb5_error_code ret; 325102644Snectar krb5_config_binding *tmp = NULL; 326102644Snectar while(filenames != NULL && *filenames != NULL && **filenames != '\0') { 327102644Snectar ret = krb5_config_parse_file_multi(context, *filenames, &tmp); 328178825Sdfr if(ret != 0 && ret != ENOENT && ret != EACCES) { 329102644Snectar krb5_config_file_free(context, tmp); 330102644Snectar return ret; 331102644Snectar } 332102644Snectar filenames++; 333102644Snectar } 334102644Snectar#if 0 335102644Snectar /* with this enabled and if there are no config files, Kerberos is 336102644Snectar considererd disabled */ 337102644Snectar if(tmp == NULL) 338107207Snectar return ENXIO; 339102644Snectar#endif 340102644Snectar krb5_config_file_free(context, context->cf); 341102644Snectar context->cf = tmp; 342102644Snectar ret = init_context_from_config_file(context); 343102644Snectar return ret; 344102644Snectar} 345102644Snectar 346178825Sdfrstatic krb5_error_code 347178825Sdfradd_file(char ***pfilenames, int *len, char *file) 348102644Snectar{ 349178825Sdfr char **pp = *pfilenames; 350178825Sdfr int i; 351178825Sdfr 352178825Sdfr for(i = 0; i < *len; i++) { 353178825Sdfr if(strcmp(pp[i], file) == 0) { 354178825Sdfr free(file); 355178825Sdfr return 0; 356178825Sdfr } 357178825Sdfr } 358178825Sdfr 359178825Sdfr pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp)); 360178825Sdfr if (pp == NULL) { 361178825Sdfr free(file); 362178825Sdfr return ENOMEM; 363178825Sdfr } 364178825Sdfr 365178825Sdfr pp[*len] = file; 366178825Sdfr pp[*len + 1] = NULL; 367178825Sdfr *pfilenames = pp; 368178825Sdfr *len += 1; 369178825Sdfr return 0; 370178825Sdfr} 371178825Sdfr 372178825Sdfr/* 373178825Sdfr * `pq' isn't free, it's up the the caller 374178825Sdfr */ 375178825Sdfr 376178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 377178825Sdfrkrb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp) 378178825Sdfr{ 379178825Sdfr krb5_error_code ret; 380102644Snectar const char *p, *q; 381102644Snectar char **pp; 382178825Sdfr int len; 383178825Sdfr char *fn; 384102644Snectar 385178825Sdfr pp = NULL; 386102644Snectar 387178825Sdfr len = 0; 388178825Sdfr p = filelist; 389102644Snectar while(1) { 390102644Snectar ssize_t l; 391102644Snectar q = p; 392102644Snectar l = strsep_copy(&q, ":", NULL, 0); 393102644Snectar if(l == -1) 394102644Snectar break; 395178825Sdfr fn = malloc(l + 1); 396178825Sdfr if(fn == NULL) { 397102644Snectar krb5_free_config_files(pp); 398102644Snectar return ENOMEM; 399102644Snectar } 400178825Sdfr l = strsep_copy(&p, ":", fn, l + 1); 401178825Sdfr ret = add_file(&pp, &len, fn); 402178825Sdfr if (ret) { 403178825Sdfr krb5_free_config_files(pp); 404178825Sdfr return ret; 405178825Sdfr } 406178825Sdfr } 407178825Sdfr 408178825Sdfr if (pq != NULL) { 409178825Sdfr int i; 410178825Sdfr 411178825Sdfr for (i = 0; pq[i] != NULL; i++) { 412178825Sdfr fn = strdup(pq[i]); 413178825Sdfr if (fn == NULL) { 414178825Sdfr krb5_free_config_files(pp); 415178825Sdfr return ENOMEM; 416102644Snectar } 417178825Sdfr ret = add_file(&pp, &len, fn); 418178825Sdfr if (ret) { 419178825Sdfr krb5_free_config_files(pp); 420178825Sdfr return ret; 421178825Sdfr } 422178825Sdfr } 423102644Snectar } 424178825Sdfr 425178825Sdfr *ret_pp = pp; 426178825Sdfr return 0; 427178825Sdfr} 428178825Sdfr 429178825Sdfr/** 430178825Sdfr * Prepend the filename to the global configuration list. 431178825Sdfr * 432178825Sdfr * @param filelist a filename to add to the default list of filename 433178825Sdfr * @param pfilenames return array of filenames, should be freed with krb5_free_config_files(). 434178825Sdfr * 435178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 436178825Sdfr * error code is returned, see krb5_get_error_message(). 437178825Sdfr * 438178825Sdfr * @ingroup krb5 439178825Sdfr */ 440178825Sdfr 441178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 442178825Sdfrkrb5_prepend_config_files_default(const char *filelist, char ***pfilenames) 443178825Sdfr{ 444178825Sdfr krb5_error_code ret; 445178825Sdfr char **defpp, **pp = NULL; 446178825Sdfr 447178825Sdfr ret = krb5_get_default_config_files(&defpp); 448178825Sdfr if (ret) 449178825Sdfr return ret; 450178825Sdfr 451178825Sdfr ret = krb5_prepend_config_files(filelist, defpp, &pp); 452178825Sdfr krb5_free_config_files(defpp); 453178825Sdfr if (ret) { 454178825Sdfr return ret; 455178825Sdfr } 456102644Snectar *pfilenames = pp; 457102644Snectar return 0; 458102644Snectar} 459102644Snectar 460178825Sdfr/** 461178825Sdfr * Get the global configuration list. 462178825Sdfr * 463178825Sdfr * @param pfilenames return array of filenames, should be freed with krb5_free_config_files(). 464178825Sdfr * 465178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 466178825Sdfr * error code is returned, see krb5_get_error_message(). 467178825Sdfr * 468178825Sdfr * @ingroup krb5 469178825Sdfr */ 470178825Sdfr 471178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 472178825Sdfrkrb5_get_default_config_files(char ***pfilenames) 473178825Sdfr{ 474178825Sdfr const char *files = NULL; 475178825Sdfr 476178825Sdfr if (pfilenames == NULL) 477178825Sdfr return EINVAL; 478178825Sdfr if(!issuid()) 479178825Sdfr files = getenv("KRB5_CONFIG"); 480178825Sdfr if (files == NULL) 481178825Sdfr files = krb5_config_file; 482178825Sdfr 483178825Sdfr return krb5_prepend_config_files(files, NULL, pfilenames); 484178825Sdfr} 485178825Sdfr 486178825Sdfr/** 487178825Sdfr * Free a list of configuration files. 488178825Sdfr * 489178825Sdfr * @param filenames list to be freed. 490178825Sdfr * 491178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 492178825Sdfr * error code is returned, see krb5_get_error_message(). 493178825Sdfr * 494178825Sdfr * @ingroup krb5 495178825Sdfr */ 496178825Sdfr 497178825Sdfrvoid KRB5_LIB_FUNCTION 498102644Snectarkrb5_free_config_files(char **filenames) 499102644Snectar{ 500102644Snectar char **p; 501102644Snectar for(p = filenames; *p != NULL; p++) 502102644Snectar free(*p); 503102644Snectar free(filenames); 504102644Snectar} 505102644Snectar 506178825Sdfr/** 507178825Sdfr * Returns the list of Kerberos encryption types sorted in order of 508178825Sdfr * most preferred to least preferred encryption type. Note that some 509178825Sdfr * encryption types might be disabled, so you need to check with 510178825Sdfr * krb5_enctype_valid() before using the encryption type. 511178825Sdfr * 512178825Sdfr * @return list of enctypes, terminated with ETYPE_NULL. Its a static 513178825Sdfr * array completed into the Kerberos library so the content doesn't 514178825Sdfr * need to be freed. 515178825Sdfr * 516178825Sdfr * @ingroup krb5 51772445Sassar */ 51872445Sassar 519178825Sdfrconst krb5_enctype * KRB5_LIB_FUNCTION 520178825Sdfrkrb5_kerberos_enctypes(krb5_context context) 52155682Smarkm{ 522178825Sdfr static const krb5_enctype p[] = { 523178825Sdfr ETYPE_AES256_CTS_HMAC_SHA1_96, 524178825Sdfr ETYPE_AES128_CTS_HMAC_SHA1_96, 52555682Smarkm ETYPE_DES3_CBC_SHA1, 52655682Smarkm ETYPE_DES3_CBC_MD5, 52772445Sassar ETYPE_ARCFOUR_HMAC_MD5, 52855682Smarkm ETYPE_DES_CBC_MD5, 52955682Smarkm ETYPE_DES_CBC_MD4, 53055682Smarkm ETYPE_DES_CBC_CRC, 53155682Smarkm ETYPE_NULL 53255682Smarkm }; 533178825Sdfr return p; 534178825Sdfr} 53578527Sassar 536178825Sdfr/* 537178825Sdfr * set `etype' to a malloced list of the default enctypes 538178825Sdfr */ 539178825Sdfr 540178825Sdfrstatic krb5_error_code 541178825Sdfrdefault_etypes(krb5_context context, krb5_enctype **etype) 542178825Sdfr{ 543178825Sdfr const krb5_enctype *p; 544178825Sdfr krb5_enctype *e = NULL, *ep; 545178825Sdfr int i, n = 0; 546178825Sdfr 547178825Sdfr p = krb5_kerberos_enctypes(context); 548178825Sdfr 549178825Sdfr for (i = 0; p[i] != ETYPE_NULL; i++) { 550178825Sdfr if (krb5_enctype_valid(context, p[i]) != 0) 551178825Sdfr continue; 552178825Sdfr ep = realloc(e, (n + 2) * sizeof(*e)); 553178825Sdfr if (ep == NULL) { 554178825Sdfr free(e); 555178825Sdfr krb5_set_error_string (context, "malloc: out of memory"); 556178825Sdfr return ENOMEM; 557178825Sdfr } 558178825Sdfr e = ep; 559178825Sdfr e[n] = p[i]; 560178825Sdfr e[n + 1] = ETYPE_NULL; 561178825Sdfr n++; 56278527Sassar } 563178825Sdfr *etype = e; 56455682Smarkm return 0; 56555682Smarkm} 56655682Smarkm 567178825Sdfr/** 568178825Sdfr * Set the default encryption types that will be use in communcation 569178825Sdfr * with the KDC, clients and servers. 570178825Sdfr * 571178825Sdfr * @param context Kerberos 5 context. 572178825Sdfr * @param etypes Encryption types, array terminated with ETYPE_NULL (0). 573178825Sdfr * 574178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 575178825Sdfr * error code is returned, see krb5_get_error_message(). 576178825Sdfr * 577178825Sdfr * @ingroup krb5 578178825Sdfr */ 579178825Sdfr 580178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 58155682Smarkmkrb5_set_default_in_tkt_etypes(krb5_context context, 58255682Smarkm const krb5_enctype *etypes) 58355682Smarkm{ 584178825Sdfr krb5_enctype *p = NULL; 58555682Smarkm int i; 58655682Smarkm 58755682Smarkm if(etypes) { 588178825Sdfr for (i = 0; etypes[i]; ++i) { 589178825Sdfr krb5_error_code ret; 590178825Sdfr ret = krb5_enctype_valid(context, etypes[i]); 591178825Sdfr if (ret) 592178825Sdfr return ret; 593178825Sdfr } 59455682Smarkm ++i; 59555682Smarkm ALLOC(p, i); 59678527Sassar if(!p) { 59778527Sassar krb5_set_error_string (context, "malloc: out of memory"); 59855682Smarkm return ENOMEM; 59978527Sassar } 60055682Smarkm memmove(p, etypes, i * sizeof(krb5_enctype)); 60155682Smarkm } 60255682Smarkm if(context->etypes) 60355682Smarkm free(context->etypes); 60455682Smarkm context->etypes = p; 60555682Smarkm return 0; 60655682Smarkm} 60755682Smarkm 608178825Sdfr/** 609178825Sdfr * Get the default encryption types that will be use in communcation 610178825Sdfr * with the KDC, clients and servers. 611178825Sdfr * 612178825Sdfr * @param context Kerberos 5 context. 613178825Sdfr * @param etypes Encryption types, array terminated with 614178825Sdfr * ETYPE_NULL(0), caller should free array with krb5_xfree(): 615178825Sdfr * 616178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 617178825Sdfr * error code is returned, see krb5_get_error_message(). 618178825Sdfr * 619178825Sdfr * @ingroup krb5 620178825Sdfr */ 62155682Smarkm 622178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 62355682Smarkmkrb5_get_default_in_tkt_etypes(krb5_context context, 62455682Smarkm krb5_enctype **etypes) 62555682Smarkm{ 62655682Smarkm krb5_enctype *p; 62755682Smarkm int i; 62878527Sassar krb5_error_code ret; 62955682Smarkm 63055682Smarkm if(context->etypes) { 63155682Smarkm for(i = 0; context->etypes[i]; i++); 63255682Smarkm ++i; 63355682Smarkm ALLOC(p, i); 63478527Sassar if(!p) { 63578527Sassar krb5_set_error_string (context, "malloc: out of memory"); 63655682Smarkm return ENOMEM; 63778527Sassar } 63855682Smarkm memmove(p, context->etypes, i * sizeof(krb5_enctype)); 63978527Sassar } else { 64078527Sassar ret = default_etypes(context, &p); 64178527Sassar if (ret) 64278527Sassar return ret; 64378527Sassar } 64455682Smarkm *etypes = p; 64555682Smarkm return 0; 64655682Smarkm} 64755682Smarkm 648178825Sdfr/** 649178825Sdfr * Return the error string for the error code. The caller must not 650178825Sdfr * free the string. 651178825Sdfr * 652178825Sdfr * @param context Kerberos 5 context. 653178825Sdfr * @param code Kerberos error code. 654178825Sdfr * 655178825Sdfr * @return the error message matching code 656178825Sdfr * 657178825Sdfr * @ingroup krb5 658178825Sdfr */ 659178825Sdfr 660178825Sdfrconst char* KRB5_LIB_FUNCTION 66155682Smarkmkrb5_get_err_text(krb5_context context, krb5_error_code code) 66255682Smarkm{ 66390926Snectar const char *p = NULL; 66490926Snectar if(context != NULL) 66590926Snectar p = com_right(context->et_list, code); 66655682Smarkm if(p == NULL) 66755682Smarkm p = strerror(code); 668142403Snectar if (p == NULL) 669142403Snectar p = "Unknown error"; 67055682Smarkm return p; 67155682Smarkm} 67255682Smarkm 673178825Sdfr/** 674178825Sdfr * Init the built-in ets in the Kerberos library. 675178825Sdfr * 676178825Sdfr * @param context kerberos context to add the ets too 677178825Sdfr * 678178825Sdfr * @ingroup krb5 679178825Sdfr */ 680178825Sdfr 681178825Sdfrvoid KRB5_LIB_FUNCTION 68255682Smarkmkrb5_init_ets(krb5_context context) 68355682Smarkm{ 68455682Smarkm if(context->et_list == NULL){ 68578527Sassar krb5_add_et_list(context, initialize_krb5_error_table_r); 68678527Sassar krb5_add_et_list(context, initialize_asn1_error_table_r); 68778527Sassar krb5_add_et_list(context, initialize_heim_error_table_r); 68890926Snectar krb5_add_et_list(context, initialize_k524_error_table_r); 689178825Sdfr#ifdef PKINIT 690178825Sdfr krb5_add_et_list(context, initialize_hx_error_table_r); 691178825Sdfr#endif 69255682Smarkm } 69355682Smarkm} 69455682Smarkm 695178825Sdfr/** 696178825Sdfr * Make the kerberos library default to the admin KDC. 697178825Sdfr * 698178825Sdfr * @param context Kerberos 5 context. 699178825Sdfr * @param flag boolean flag to select if the use the admin KDC or not. 700178825Sdfr * 701178825Sdfr * @ingroup krb5 702178825Sdfr */ 703178825Sdfr 704178825Sdfrvoid KRB5_LIB_FUNCTION 70555682Smarkmkrb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag) 70655682Smarkm{ 70755682Smarkm context->use_admin_kdc = flag; 70855682Smarkm} 70955682Smarkm 710178825Sdfr/** 711178825Sdfr * Make the kerberos library default to the admin KDC. 712178825Sdfr * 713178825Sdfr * @param context Kerberos 5 context. 714178825Sdfr * 715178825Sdfr * @return boolean flag to telling the context will use admin KDC as the default KDC. 716178825Sdfr * 717178825Sdfr * @ingroup krb5 718178825Sdfr */ 719178825Sdfr 720178825Sdfrkrb5_boolean KRB5_LIB_FUNCTION 72155682Smarkmkrb5_get_use_admin_kdc (krb5_context context) 72255682Smarkm{ 72355682Smarkm return context->use_admin_kdc; 72455682Smarkm} 72555682Smarkm 726178825Sdfr/** 727178825Sdfr * Add extra address to the address list that the library will add to 728178825Sdfr * the client's address list when communicating with the KDC. 729178825Sdfr * 730178825Sdfr * @param context Kerberos 5 context. 731178825Sdfr * @param addresses addreses to add 732178825Sdfr * 733178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 734178825Sdfr * error code is returned, see krb5_get_error_message(). 735178825Sdfr * 736178825Sdfr * @ingroup krb5 737178825Sdfr */ 738178825Sdfr 739178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 74055682Smarkmkrb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses) 74155682Smarkm{ 74255682Smarkm 74355682Smarkm if(context->extra_addresses) 74455682Smarkm return krb5_append_addresses(context, 74555682Smarkm context->extra_addresses, addresses); 74655682Smarkm else 74755682Smarkm return krb5_set_extra_addresses(context, addresses); 74855682Smarkm} 74955682Smarkm 750178825Sdfr/** 751178825Sdfr * Set extra address to the address list that the library will add to 752178825Sdfr * the client's address list when communicating with the KDC. 753178825Sdfr * 754178825Sdfr * @param context Kerberos 5 context. 755178825Sdfr * @param addresses addreses to set 756178825Sdfr * 757178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 758178825Sdfr * error code is returned, see krb5_get_error_message(). 759178825Sdfr * 760178825Sdfr * @ingroup krb5 761178825Sdfr */ 762178825Sdfr 763178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 76457419Smarkmkrb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses) 76555682Smarkm{ 76690926Snectar if(context->extra_addresses) 76755682Smarkm krb5_free_addresses(context, context->extra_addresses); 76890926Snectar 76990926Snectar if(addresses == NULL) { 77090926Snectar if(context->extra_addresses != NULL) { 77190926Snectar free(context->extra_addresses); 77290926Snectar context->extra_addresses = NULL; 77390926Snectar } 77490926Snectar return 0; 77555682Smarkm } 77655682Smarkm if(context->extra_addresses == NULL) { 77755682Smarkm context->extra_addresses = malloc(sizeof(*context->extra_addresses)); 77878527Sassar if(context->extra_addresses == NULL) { 77978527Sassar krb5_set_error_string (context, "malloc: out of memory"); 78055682Smarkm return ENOMEM; 78178527Sassar } 78255682Smarkm } 78357419Smarkm return krb5_copy_addresses(context, addresses, context->extra_addresses); 78455682Smarkm} 78555682Smarkm 786178825Sdfr/** 787178825Sdfr * Get extra address to the address list that the library will add to 788178825Sdfr * the client's address list when communicating with the KDC. 789178825Sdfr * 790178825Sdfr * @param context Kerberos 5 context. 791178825Sdfr * @param addresses addreses to set 792178825Sdfr * 793178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 794178825Sdfr * error code is returned, see krb5_get_error_message(). 795178825Sdfr * 796178825Sdfr * @ingroup krb5 797178825Sdfr */ 798178825Sdfr 799178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 80055682Smarkmkrb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses) 80155682Smarkm{ 80255682Smarkm if(context->extra_addresses == NULL) { 80355682Smarkm memset(addresses, 0, sizeof(*addresses)); 80455682Smarkm return 0; 80555682Smarkm } 80690926Snectar return krb5_copy_addresses(context,context->extra_addresses, addresses); 80755682Smarkm} 80855682Smarkm 809178825Sdfr/** 810178825Sdfr * Add extra addresses to ignore when fetching addresses from the 811178825Sdfr * underlaying operating system. 812178825Sdfr * 813178825Sdfr * @param context Kerberos 5 context. 814178825Sdfr * @param addresses addreses to ignore 815178825Sdfr * 816178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 817178825Sdfr * error code is returned, see krb5_get_error_message(). 818178825Sdfr * 819178825Sdfr * @ingroup krb5 820178825Sdfr */ 821178825Sdfr 822178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 82390926Snectarkrb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses) 82490926Snectar{ 82590926Snectar 82690926Snectar if(context->ignore_addresses) 82790926Snectar return krb5_append_addresses(context, 82890926Snectar context->ignore_addresses, addresses); 82990926Snectar else 83090926Snectar return krb5_set_ignore_addresses(context, addresses); 83190926Snectar} 83290926Snectar 833178825Sdfr/** 834178825Sdfr * Set extra addresses to ignore when fetching addresses from the 835178825Sdfr * underlaying operating system. 836178825Sdfr * 837178825Sdfr * @param context Kerberos 5 context. 838178825Sdfr * @param addresses addreses to ignore 839178825Sdfr * 840178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 841178825Sdfr * error code is returned, see krb5_get_error_message(). 842178825Sdfr * 843178825Sdfr * @ingroup krb5 844178825Sdfr */ 845178825Sdfr 846178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 84790926Snectarkrb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses) 84890926Snectar{ 84990926Snectar if(context->ignore_addresses) 85090926Snectar krb5_free_addresses(context, context->ignore_addresses); 85190926Snectar if(addresses == NULL) { 85290926Snectar if(context->ignore_addresses != NULL) { 85390926Snectar free(context->ignore_addresses); 85490926Snectar context->ignore_addresses = NULL; 85590926Snectar } 85690926Snectar return 0; 85790926Snectar } 85890926Snectar if(context->ignore_addresses == NULL) { 85990926Snectar context->ignore_addresses = malloc(sizeof(*context->ignore_addresses)); 86090926Snectar if(context->ignore_addresses == NULL) { 86190926Snectar krb5_set_error_string (context, "malloc: out of memory"); 86290926Snectar return ENOMEM; 86390926Snectar } 86490926Snectar } 86590926Snectar return krb5_copy_addresses(context, addresses, context->ignore_addresses); 86690926Snectar} 86790926Snectar 868178825Sdfr/** 869178825Sdfr * Get extra addresses to ignore when fetching addresses from the 870178825Sdfr * underlaying operating system. 871178825Sdfr * 872178825Sdfr * @param context Kerberos 5 context. 873178825Sdfr * @param addresses list addreses ignored 874178825Sdfr * 875178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 876178825Sdfr * error code is returned, see krb5_get_error_message(). 877178825Sdfr * 878178825Sdfr * @ingroup krb5 879178825Sdfr */ 880178825Sdfr 881178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 88290926Snectarkrb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses) 88390926Snectar{ 88490926Snectar if(context->ignore_addresses == NULL) { 88590926Snectar memset(addresses, 0, sizeof(*addresses)); 88690926Snectar return 0; 88790926Snectar } 88890926Snectar return krb5_copy_addresses(context, context->ignore_addresses, addresses); 88990926Snectar} 89090926Snectar 891178825Sdfr/** 892178825Sdfr * Set version of fcache that the library should use. 893178825Sdfr * 894178825Sdfr * @param context Kerberos 5 context. 895178825Sdfr * @param version version number. 896178825Sdfr * 897178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 898178825Sdfr * error code is returned, see krb5_get_error_message(). 899178825Sdfr * 900178825Sdfr * @ingroup krb5 901178825Sdfr */ 902178825Sdfr 903178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 90455682Smarkmkrb5_set_fcache_version(krb5_context context, int version) 90555682Smarkm{ 90655682Smarkm context->fcache_vno = version; 90755682Smarkm return 0; 90855682Smarkm} 90955682Smarkm 910178825Sdfr/** 911178825Sdfr * Get version of fcache that the library should use. 912178825Sdfr * 913178825Sdfr * @param context Kerberos 5 context. 914178825Sdfr * @param version version number. 915178825Sdfr * 916178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 917178825Sdfr * error code is returned, see krb5_get_error_message(). 918178825Sdfr * 919178825Sdfr * @ingroup krb5 920178825Sdfr */ 921178825Sdfr 922178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 92355682Smarkmkrb5_get_fcache_version(krb5_context context, int *version) 92455682Smarkm{ 92555682Smarkm *version = context->fcache_vno; 92655682Smarkm return 0; 92755682Smarkm} 928178825Sdfr 929178825Sdfr/** 930178825Sdfr * Runtime check if the Kerberos library was complied with thread support. 931178825Sdfr * 932178825Sdfr * @return TRUE if the library was compiled with thread support, FALSE if not. 933178825Sdfr * 934178825Sdfr * @ingroup krb5 935178825Sdfr */ 936178825Sdfr 937178825Sdfr 938178825Sdfrkrb5_boolean KRB5_LIB_FUNCTION 939178825Sdfrkrb5_is_thread_safe(void) 940178825Sdfr{ 941178825Sdfr#ifdef ENABLE_PTHREAD_SUPPORT 942178825Sdfr return TRUE; 943178825Sdfr#else 944178825Sdfr return FALSE; 945178825Sdfr#endif 946178825Sdfr} 947178825Sdfr 948178825Sdfr/** 949178825Sdfr * Set if the library should use DNS to canonicalize hostnames. 950178825Sdfr * 951178825Sdfr * @param context Kerberos 5 context. 952178825Sdfr * @param flag if its dns canonicalizion is used or not. 953178825Sdfr * 954178825Sdfr * @ingroup krb5 955178825Sdfr */ 956178825Sdfr 957178825Sdfrvoid KRB5_LIB_FUNCTION 958178825Sdfrkrb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag) 959178825Sdfr{ 960178825Sdfr if (flag) 961178825Sdfr context->flags |= KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME; 962178825Sdfr else 963178825Sdfr context->flags &= ~KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME; 964178825Sdfr} 965178825Sdfr 966178825Sdfr/** 967178825Sdfr * Get if the library uses DNS to canonicalize hostnames. 968178825Sdfr * 969178825Sdfr * @param context Kerberos 5 context. 970178825Sdfr * 971178825Sdfr * @return return non zero if the library uses DNS to canonicalize hostnames. 972178825Sdfr * 973178825Sdfr * @ingroup krb5 974178825Sdfr */ 975178825Sdfr 976178825Sdfrkrb5_boolean KRB5_LIB_FUNCTION 977178825Sdfrkrb5_get_dns_canonicalize_hostname (krb5_context context) 978178825Sdfr{ 979178825Sdfr return (context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) ? 1 : 0; 980178825Sdfr} 981178825Sdfr 982178825Sdfr/** 983178825Sdfr * Get current offset in time to the KDC. 984178825Sdfr * 985178825Sdfr * @param context Kerberos 5 context. 986178825Sdfr * @param sec seconds part of offset. 987178825Sdfr * @param usec micro seconds part of offset. 988178825Sdfr * 989178825Sdfr * @return return non zero if the library uses DNS to canonicalize hostnames. 990178825Sdfr * 991178825Sdfr * @ingroup krb5 992178825Sdfr */ 993178825Sdfr 994178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 995178825Sdfrkrb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec) 996178825Sdfr{ 997178825Sdfr if (sec) 998178825Sdfr *sec = context->kdc_sec_offset; 999178825Sdfr if (usec) 1000178825Sdfr *usec = context->kdc_usec_offset; 1001178825Sdfr return 0; 1002178825Sdfr} 1003178825Sdfr 1004178825Sdfr/** 1005178825Sdfr * Get max time skew allowed. 1006178825Sdfr * 1007178825Sdfr * @param context Kerberos 5 context. 1008178825Sdfr * 1009178825Sdfr * @return timeskew in seconds. 1010178825Sdfr * 1011178825Sdfr * @ingroup krb5 1012178825Sdfr */ 1013178825Sdfr 1014178825Sdfrtime_t KRB5_LIB_FUNCTION 1015178825Sdfrkrb5_get_max_time_skew (krb5_context context) 1016178825Sdfr{ 1017178825Sdfr return context->max_skew; 1018178825Sdfr} 1019178825Sdfr 1020178825Sdfr/** 1021178825Sdfr * Set max time skew allowed. 1022178825Sdfr * 1023178825Sdfr * @param context Kerberos 5 context. 1024178825Sdfr * @param t timeskew in seconds. 1025178825Sdfr * 1026178825Sdfr * @ingroup krb5 1027178825Sdfr */ 1028178825Sdfr 1029178825Sdfrvoid KRB5_LIB_FUNCTION 1030178825Sdfrkrb5_set_max_time_skew (krb5_context context, time_t t) 1031178825Sdfr{ 1032178825Sdfr context->max_skew = t; 1033178825Sdfr} 1034