LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/krb5 - init_creds.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 134 194 69.1 %
Date: 2024-04-21 15:09:00 Functions: 20 27 74.1 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2004 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             : 
      38             : #undef __attribute__
      39             : #define __attribute__(x)
      40             : 
      41             : /**
      42             :  * @page krb5_init_creds_intro The initial credential handing functions
      43             :  * @section section_krb5_init_creds Initial credential
      44             :  *
      45             :  * Functions to get initial credentials: @ref krb5_credential .
      46             :  */
      47             : 
      48             : /**
      49             :  * Allocate a new krb5_get_init_creds_opt structure, free with
      50             :  * krb5_get_init_creds_opt_free().
      51             :  *
      52             :  * @ingroup krb5_credential
      53             :  */
      54             : 
      55             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
      56       22753 : krb5_get_init_creds_opt_alloc(krb5_context context,
      57             :                               krb5_get_init_creds_opt **opt)
      58             : {
      59         585 :     krb5_get_init_creds_opt *o;
      60             : 
      61       22753 :     *opt = NULL;
      62       22753 :     o = calloc(1, sizeof(*o));
      63       22753 :     if (o == NULL)
      64           0 :         return krb5_enomem(context);
      65             : 
      66       22753 :     o->opt_private = calloc(1, sizeof(*o->opt_private));
      67       22753 :     if (o->opt_private == NULL) {
      68           0 :         free(o);
      69           0 :         return krb5_enomem(context);
      70             :     }
      71       22753 :     o->opt_private->refcount = 1;
      72       22753 :     *opt = o;
      73       22753 :     return 0;
      74             : }
      75             : 
      76             : /**
      77             :  * Free krb5_get_init_creds_opt structure.
      78             :  *
      79             :  * @ingroup krb5_credential
      80             :  */
      81             : 
      82             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
      83       22481 : krb5_get_init_creds_opt_free(krb5_context context,
      84             :                              krb5_get_init_creds_opt *opt)
      85             : {
      86       22481 :     if (opt == NULL || opt->opt_private == NULL)
      87          48 :         return;
      88       22433 :     if (opt->opt_private->refcount < 1) /* abort ? */
      89           0 :         return;
      90       22433 :     if (--opt->opt_private->refcount == 0) {
      91       22433 :         _krb5_get_init_creds_opt_free_pkinit(opt);
      92       22433 :         free(opt->opt_private->fast_armor_ccache_name);
      93       22433 :         free(opt->opt_private);
      94             :     }
      95       22433 :     memset(opt, 0, sizeof(*opt));
      96       22433 :     free(opt);
      97             : }
      98             : 
      99             : static int
     100       12046 : get_config_time (krb5_context context,
     101             :                  const char *realm,
     102             :                  const char *name,
     103             :                  int def)
     104             : {
     105         585 :     int ret;
     106             : 
     107       12046 :     ret = krb5_config_get_time (context, NULL,
     108             :                                 "realms",
     109             :                                 realm,
     110             :                                 name,
     111             :                                 NULL);
     112       12046 :     if (ret >= 0)
     113           0 :         return ret;
     114       12046 :     ret = krb5_config_get_time (context, NULL,
     115             :                                 "libdefaults",
     116             :                                 name,
     117             :                                 NULL);
     118       12046 :     if (ret >= 0)
     119           0 :         return ret;
     120       11461 :     return def;
     121             : }
     122             : 
     123             : static krb5_boolean
     124       24092 : get_config_bool (krb5_context context,
     125             :                  krb5_boolean def_value,
     126             :                  const char *realm,
     127             :                  const char *name)
     128             : {
     129        1170 :     krb5_boolean b;
     130             : 
     131       24092 :     b = krb5_config_get_bool_default(context, NULL, def_value,
     132             :                                      "realms", realm, name, NULL);
     133       24092 :     if (b != def_value)
     134           0 :         return b;
     135       24092 :     b = krb5_config_get_bool_default (context, NULL, def_value,
     136             :                                       "libdefaults", name, NULL);
     137       24092 :     if (b != def_value)
     138           0 :         return b;
     139       22922 :     return def_value;
     140             : }
     141             : 
     142             : /*
     143             :  * set all the values in `opt' to the appropriate values for
     144             :  * application `appname' (default to getprogname() if NULL), and realm
     145             :  * `realm'.  First looks in [appdefaults] but falls back to
     146             :  * [realms] or [libdefaults] for some of the values.
     147             :  */
     148             : 
     149             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     150       12046 : krb5_get_init_creds_opt_set_default_flags(krb5_context context,
     151             :                                           const char *appname,
     152             :                                           krb5_const_realm realm,
     153             :                                           krb5_get_init_creds_opt *opt)
     154             : {
     155         585 :     krb5_boolean b;
     156         585 :     time_t t;
     157             : 
     158       12046 :     b = get_config_bool (context, KRB5_FORWARDABLE_DEFAULT,
     159             :                          realm, "forwardable");
     160       12046 :     krb5_appdefault_boolean(context, appname, realm, "forwardable", b, &b);
     161       12046 :     krb5_get_init_creds_opt_set_forwardable(opt, b);
     162             : 
     163       12046 :     b = get_config_bool (context, FALSE, realm, "proxiable");
     164       12046 :     krb5_appdefault_boolean(context, appname, realm, "proxiable", b, &b);
     165       12046 :     krb5_get_init_creds_opt_set_proxiable (opt, b);
     166             : 
     167       12046 :     krb5_appdefault_time(context, appname, realm, "ticket_lifetime", 0, &t);
     168       12046 :     if (t == 0)
     169           0 :         t = get_config_time (context, realm, "ticket_lifetime", 0);
     170       12046 :     if(t != 0)
     171       12046 :         krb5_get_init_creds_opt_set_tkt_life(opt, t);
     172             : 
     173       12046 :     krb5_appdefault_time(context, appname, realm, "renew_lifetime", 0, &t);
     174       12046 :     if (t == 0)
     175       12046 :         t = get_config_time (context, realm, "renew_lifetime", 0);
     176       12046 :     if(t != 0)
     177           0 :         krb5_get_init_creds_opt_set_renew_life(opt, t);
     178             : 
     179       12046 :     krb5_appdefault_boolean(context, appname, realm, "no-addresses",
     180             :                             KRB5_ADDRESSLESS_DEFAULT, &b);
     181       12046 :     krb5_get_init_creds_opt_set_addressless (context, opt, b);
     182             : 
     183             : #if 0
     184             :     krb5_appdefault_boolean(context, appname, realm, "anonymous", FALSE, &b);
     185             :     krb5_get_init_creds_opt_set_anonymous (opt, b);
     186             : 
     187             :     krb5_get_init_creds_opt_set_etype_list(opt, enctype,
     188             :                                            etype_str.num_strings);
     189             : 
     190             :     krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
     191             :                                      krb5_data *salt);
     192             : 
     193             :     krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
     194             :                                              krb5_preauthtype *preauth_list,
     195             :                                              int preauth_list_length);
     196             : #endif
     197       12046 : }
     198             : 
     199             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     200           0 : krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt *opt,
     201             :                                                    int change_password_prompt)
     202             : {
     203           0 :         opt->flags |= KRB5_GET_INIT_CREDS_OPT_CHANGE_PASSWORD_PROMPT;
     204           0 :         opt->change_password_prompt = change_password_prompt;
     205           0 : }
     206             : 
     207             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     208       12166 : krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt,
     209             :                                      krb5_deltat tkt_life)
     210             : {
     211       12166 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_TKT_LIFE;
     212       12166 :     opt->tkt_life = tkt_life;
     213       12166 : }
     214             : 
     215             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     216        8668 : krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt,
     217             :                                        krb5_deltat renew_life)
     218             : {
     219        8668 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE;
     220        8668 :     opt->renew_life = renew_life;
     221        8668 : }
     222             : 
     223             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     224       20698 : krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt,
     225             :                                         int forwardable)
     226             : {
     227       20698 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_FORWARDABLE;
     228       20698 :     opt->forwardable = forwardable;
     229       20698 : }
     230             : 
     231             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     232       12059 : krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt,
     233             :                                       int proxiable)
     234             : {
     235       12059 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_PROXIABLE;
     236       12059 :     opt->proxiable = proxiable;
     237       12059 : }
     238             : 
     239             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     240          26 : krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
     241             :                                        krb5_enctype *etype_list,
     242             :                                        int etype_list_length)
     243             : {
     244          26 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST;
     245          26 :     opt->etype_list = etype_list;
     246          26 :     opt->etype_list_length = etype_list_length;
     247          26 : }
     248             : 
     249             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     250           3 : krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt,
     251             :                                          krb5_addresses *addresses)
     252             : {
     253           3 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST;
     254           3 :     opt->address_list = addresses;
     255           3 : }
     256             : 
     257             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     258           0 : krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
     259             :                                          krb5_preauthtype *preauth_list,
     260             :                                          int preauth_list_length)
     261             : {
     262           0 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST;
     263           0 :     opt->preauth_list_length = preauth_list_length;
     264           0 :     opt->preauth_list = preauth_list;
     265           0 : }
     266             : 
     267             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     268           0 : krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
     269             :                                  krb5_data *salt)
     270             : {
     271           0 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_SALT;
     272           0 :     opt->salt = salt;
     273           0 : }
     274             : 
     275             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     276         104 : krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt *opt,
     277             :                                       int anonymous)
     278             : {
     279         104 :     opt->flags |= KRB5_GET_INIT_CREDS_OPT_ANONYMOUS;
     280         104 :     opt->anonymous = anonymous;
     281         104 : }
     282             : 
     283             : static krb5_error_code
     284       56818 : require_ext_opt(krb5_context context,
     285             :                 krb5_get_init_creds_opt *opt,
     286             :                 const char *type)
     287             : {
     288       56818 :     if (opt->opt_private == NULL) {
     289           0 :         krb5_set_error_message(context, EINVAL,
     290           0 :                                N_("%s on non extendable opt", ""), type);
     291           0 :         return EINVAL;
     292             :     }
     293       55063 :     return 0;
     294             : }
     295             : 
     296             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     297           0 : krb5_get_init_creds_opt_set_pa_password(krb5_context context,
     298             :                                         krb5_get_init_creds_opt *opt,
     299             :                                         const char *password,
     300             :                                         krb5_s2k_proc key_proc)
     301             : {
     302           0 :     krb5_error_code ret;
     303           0 :     ret = require_ext_opt(context, opt, "init_creds_opt_set_pa_password");
     304           0 :     if (ret)
     305           0 :         return ret;
     306           0 :     opt->opt_private->password = password;
     307           0 :     opt->opt_private->key_proc = key_proc;
     308           0 :     return 0;
     309             : }
     310             : 
     311             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     312         198 : krb5_get_init_creds_opt_set_pac_request(krb5_context context,
     313             :                                         krb5_get_init_creds_opt *opt,
     314             :                                         krb5_boolean req_pac)
     315             : {
     316           0 :     krb5_error_code ret;
     317         198 :     ret = require_ext_opt(context, opt, "init_creds_opt_set_pac_req");
     318         198 :     if (ret)
     319           0 :         return ret;
     320         198 :     opt->opt_private->req_pac = req_pac ?
     321         198 :         KRB5_INIT_CREDS_TRISTATE_TRUE :
     322             :         KRB5_INIT_CREDS_TRISTATE_FALSE;
     323         198 :     return 0;
     324             : }
     325             : 
     326             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     327       12046 : krb5_get_init_creds_opt_set_addressless(krb5_context context,
     328             :                                         krb5_get_init_creds_opt *opt,
     329             :                                         krb5_boolean addressless)
     330             : {
     331         585 :     krb5_error_code ret;
     332       12046 :     ret = require_ext_opt(context, opt, "init_creds_opt_set_pac_req");
     333       12046 :     if (ret)
     334           0 :         return ret;
     335       12046 :     if (addressless)
     336       12046 :         opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_TRUE;
     337             :     else
     338           0 :         opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_FALSE;
     339       11461 :     return 0;
     340             : }
     341             : 
     342             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     343       22270 : krb5_get_init_creds_opt_set_canonicalize(krb5_context context,
     344             :                                          krb5_get_init_creds_opt *opt,
     345             :                                          krb5_boolean req)
     346             : {
     347         585 :     krb5_error_code ret;
     348       22270 :     ret = require_ext_opt(context, opt, "init_creds_opt_set_canonicalize");
     349       22270 :     if (ret)
     350           0 :         return ret;
     351       22270 :     if (req)
     352       21630 :         opt->opt_private->flags |= KRB5_INIT_CREDS_CANONICALIZE;
     353             :     else
     354         640 :         opt->opt_private->flags &= ~KRB5_INIT_CREDS_CANONICALIZE;
     355       21685 :     return 0;
     356             : }
     357             : 
     358             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     359       22304 : krb5_get_init_creds_opt_set_win2k(krb5_context context,
     360             :                                   krb5_get_init_creds_opt *opt,
     361             :                                   krb5_boolean req)
     362             : {
     363         585 :     krb5_error_code ret;
     364       22304 :     ret = require_ext_opt(context, opt, "init_creds_opt_set_win2k");
     365       22304 :     if (ret)
     366           0 :         return ret;
     367       22304 :     if (req) {
     368       21424 :         opt->opt_private->flags |= KRB5_INIT_CREDS_NO_C_CANON_CHECK;
     369       21424 :         opt->opt_private->flags |= KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK;
     370       21424 :         opt->opt_private->flags |= KRB5_INIT_CREDS_PKINIT_NO_KRBTGT_OTHERNAME_CHECK;
     371             :     } else {
     372         880 :         opt->opt_private->flags &= ~KRB5_INIT_CREDS_NO_C_CANON_CHECK;
     373         880 :         opt->opt_private->flags &= ~KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK;
     374         880 :         opt->opt_private->flags &= ~KRB5_INIT_CREDS_PKINIT_NO_KRBTGT_OTHERNAME_CHECK;
     375             :     }
     376       21719 :     return 0;
     377             : }
     378             : 
     379             : 
     380             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     381           0 : krb5_get_init_creds_opt_set_process_last_req(krb5_context context,
     382             :                                              krb5_get_init_creds_opt *opt,
     383             :                                              krb5_gic_process_last_req func,
     384             :                                              void *ctx)
     385             : {
     386           0 :     krb5_error_code ret;
     387           0 :     ret = require_ext_opt(context, opt, "init_creds_opt_set_process_last_req");
     388           0 :     if (ret)
     389           0 :         return ret;
     390             : 
     391           0 :     opt->opt_private->lr.func = func;
     392           0 :     opt->opt_private->lr.ctx = ctx;
     393             : 
     394           0 :     return 0;
     395             : }
     396             : 
     397             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     398          10 : krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
     399             :                                     krb5_get_init_creds_opt *opt,
     400             :                                     krb5_ccache fast_ccache)
     401             : {
     402           0 :     char *fast_ccache_name;
     403          10 :     int ret = krb5_cc_get_full_name(context,
     404             :                                     fast_ccache,
     405             :                                     &fast_ccache_name);
     406          10 :     if (ret)
     407           0 :             return ret;
     408             : 
     409          10 :     ret = krb5_get_init_creds_opt_set_fast_ccache_name(context,
     410             :                                                        opt,
     411             :                                                        fast_ccache_name);
     412          10 :     krb5_xfree(fast_ccache_name);
     413          10 :     return ret;
     414             : }
     415             : 
     416             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     417          10 : krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context,
     418             :                                              krb5_get_init_creds_opt *opt,
     419             :                                              const char *fast_ccache_name)
     420             : {
     421          10 :     if (opt->opt_private->fast_armor_ccache_name)
     422           0 :         free(opt->opt_private->fast_armor_ccache_name);
     423             : 
     424          10 :     opt->opt_private->fast_armor_ccache_name = strdup(fast_ccache_name);
     425          10 :     if (opt->opt_private->fast_armor_ccache_name == NULL)
     426           0 :         return krb5_enomem(context);
     427             : 
     428          10 :     return 0;
     429             : }
     430             : 
     431             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     432          10 : krb5_get_init_creds_opt_set_fast_flags(krb5_context context,
     433             :                                    krb5_get_init_creds_opt *opt,
     434             :                                    krb5_flags flags)
     435             : {
     436          10 :     heim_assert((flags & ~KRB5_FAST_PUBLIC_FLAGS) == 0, "invalid flags passed to krb5_get_init_creds_opt_set_fast_flags()");
     437          10 :     opt->opt_private->fast_flags = flags;
     438          10 :     return 0;
     439             : }
     440             : 
     441             : 
     442             : 
     443             : #ifndef HEIMDAL_SMALLER
     444             : 
     445             : /**
     446             :  * Deprecated: use krb5_get_init_creds_opt_alloc().
     447             :  *
     448             :  * The reason krb5_get_init_creds_opt_init() is deprecated is that
     449             :  * krb5_get_init_creds_opt is a static structure and for ABI reason it
     450             :  * can't grow, ie can't add new functionality.
     451             :  *
     452             :  * @ingroup krb5_deprecated
     453             :  */
     454             : 
     455             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     456           0 : krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
     457             :     KRB5_DEPRECATED_FUNCTION("Use krb5_get_init_creds_opt_alloc instead")
     458             : {
     459           0 :     memset (opt, 0, sizeof(*opt));
     460           0 : }
     461             : 
     462             : /**
     463             :  * Deprecated: use the new krb5_init_creds_init() and
     464             :  * krb5_init_creds_get_error().
     465             :  *
     466             :  * @ingroup krb5_deprecated
     467             :  */
     468             : 
     469             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     470           0 : krb5_get_init_creds_opt_get_error(krb5_context context,
     471             :                                   krb5_get_init_creds_opt *opt,
     472             :                                   KRB_ERROR **error)
     473             :     KRB5_DEPRECATED_FUNCTION("Use X instead")
     474             : {
     475           0 :     *error = calloc(1, sizeof(**error));
     476           0 :     if (*error == NULL)
     477           0 :         return krb5_enomem(context);
     478             : 
     479           0 :     return 0;
     480             : }
     481             : 
     482             : #endif /* HEIMDAL_SMALLER */

Generated by: LCOV version 1.14