LCOV - code coverage report
Current view: top level - source4/heimdal/lib/krb5 - context.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 313 550 56.9 %
Date: 2021-09-23 10:06:22 Functions: 25 46 54.3 %

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

Generated by: LCOV version 1.13