Path: blob/main/crypto/krb5/src/plugins/preauth/pkinit/pkinit_profile.c
34923 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* COPYRIGHT (C) 2006,20073* THE REGENTS OF THE UNIVERSITY OF MICHIGAN4* ALL RIGHTS RESERVED5*6* Permission is granted to use, copy, create derivative works7* and redistribute this software and such derivative works8* for any purpose, so long as the name of The University of9* Michigan is not used in any advertising or publicity10* pertaining to the use of distribution of this software11* without specific, written prior authorization. If the12* above copyright notice or any other identification of the13* University of Michigan is included in any copy of any14* portion of this software, then the disclaimer below must15* also be included.16*17* THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION18* FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY19* PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF20* MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING21* WITHOUT LIMITATION THE IMPLIED WARRANTIES OF22* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE23* REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE24* FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR25* CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING26* OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN27* IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGES.29*/3031#include "k5-int.h"32#include "pkinit.h"3334/*35* Routines for handling profile [config file] options36*/3738/* Forward prototypes */39static int _krb5_conf_boolean(const char *s);4041/*42* XXX43* The following is duplicated verbatim from src/lib/krb5/krb/get_in_tkt.c,44* which is duplicated from somewhere else. :-/45* XXX46*/47static const char *const conf_yes[] = {48"y", "yes", "true", "t", "1", "on",490,50};5152static const char *const conf_no[] = {53"n", "no", "false", "nil", "0", "off",540,55};5657static int58_krb5_conf_boolean(const char *s)59{60const char *const *p;6162for(p=conf_yes; *p; p++) {63if (strcasecmp(*p,s) == 0)64return 1;65}6667for(p=conf_no; *p; p++) {68if (strcasecmp(*p,s) == 0)69return 0;70}7172/* Default to "no" */73return 0;74}7576/*77* XXX78* End duplicated code from src/lib/krb5/krb/get_in_tkt.c79* XXX80*/8182/*83* The following are based on krb5_libdefault_* functions in84* src/lib/krb5/krb/get_in_tkt.c85* N.B. This assumes that context->default_realm has86* already been established.87*/88krb5_error_code89pkinit_kdcdefault_strings(krb5_context context, const char *realmname,90const char *option, char ***ret_value)91{92profile_t profile = NULL;93const char *names[5];94char **values = NULL;95krb5_error_code retval;9697if (context == NULL)98return KV5M_CONTEXT;99100profile = context->profile;101102if (realmname != NULL) {103/*104* Try number one:105*106* [realms]107* REALM = {108* option = <value>109* }110*/111112names[0] = KRB5_CONF_REALMS;113names[1] = realmname;114names[2] = option;115names[3] = 0;116retval = profile_get_values(profile, names, &values);117if (retval == 0 && values != NULL)118goto goodbye;119}120121/*122* Try number two:123*124* [kdcdefaults]125* option = <value>126*/127128names[0] = KRB5_CONF_KDCDEFAULTS;129names[1] = option;130names[2] = 0;131retval = profile_get_values(profile, names, &values);132if (retval == 0 && values != NULL)133goto goodbye;134135goodbye:136if (values == NULL)137retval = ENOENT;138139*ret_value = values;140141return retval;142143}144145krb5_error_code146pkinit_kdcdefault_string(krb5_context context, const char *realmname,147const char *option, char **ret_value)148{149krb5_error_code retval;150char **values = NULL;151152retval = pkinit_kdcdefault_strings(context, realmname, option, &values);153if (retval)154return retval;155156if (values[0] == NULL) {157retval = ENOENT;158} else {159*ret_value = strdup(values[0]);160if (*ret_value == NULL)161retval = ENOMEM;162}163164profile_free_list(values);165return retval;166}167168krb5_error_code169pkinit_kdcdefault_boolean(krb5_context context, const char *realmname,170const char *option, int default_value, int *ret_value)171{172char *string = NULL;173krb5_error_code retval;174175retval = pkinit_kdcdefault_string(context, realmname, option, &string);176177if (retval == 0) {178*ret_value = _krb5_conf_boolean(string);179free(string);180} else181*ret_value = default_value;182183return 0;184}185186krb5_error_code187pkinit_kdcdefault_integer(krb5_context context, const char *realmname,188const char *option, int default_value, int *ret_value)189{190char *string = NULL;191krb5_error_code retval;192193retval = pkinit_kdcdefault_string(context, realmname, option, &string);194195if (retval == 0) {196char *endptr;197long l;198l = strtol(string, &endptr, 0);199if (endptr == string)200*ret_value = default_value;201else202*ret_value = l;203free(string);204} else205*ret_value = default_value;206207return 0;208}209210211/*212* krb5_libdefault_string() is defined as static in213* src/lib/krb5/krb/get_in_tkt.c. Create local versions of214* krb5_libdefault_* functions here. We need a libdefaults_strings()215* function which is not currently supported there anyway. Also,216* add the ability to supply a default value for the boolean and217* integer functions.218*/219220krb5_error_code221pkinit_libdefault_strings(krb5_context context, const krb5_data *realm,222const char *option, char ***ret_value)223{224profile_t profile;225const char *names[5];226char **values = NULL;227krb5_error_code retval;228char realmstr[1024];229230if (realm != NULL && realm->length > sizeof(realmstr)-1)231return EINVAL;232233if (realm != NULL) {234strncpy(realmstr, realm->data, realm->length);235realmstr[realm->length] = '\0';236}237238if (!context || (context->magic != KV5M_CONTEXT))239return KV5M_CONTEXT;240241profile = context->profile;242243244if (realm != NULL) {245/*246* Try number one:247*248* [libdefaults]249* REALM = {250* option = <value>251* }252*/253254names[0] = KRB5_CONF_LIBDEFAULTS;255names[1] = realmstr;256names[2] = option;257names[3] = 0;258retval = profile_get_values(profile, names, &values);259if (retval == 0 && values != NULL && values[0] != NULL)260goto goodbye;261262/*263* Try number two:264*265* [realms]266* REALM = {267* option = <value>268* }269*/270271names[0] = KRB5_CONF_REALMS;272names[1] = realmstr;273names[2] = option;274names[3] = 0;275retval = profile_get_values(profile, names, &values);276if (retval == 0 && values != NULL && values[0] != NULL)277goto goodbye;278}279280/*281* Try number three:282*283* [libdefaults]284* option = <value>285*/286287names[0] = KRB5_CONF_LIBDEFAULTS;288names[1] = option;289names[2] = 0;290retval = profile_get_values(profile, names, &values);291if (retval == 0 && values != NULL && values[0] != NULL)292goto goodbye;293294goodbye:295if (values == NULL)296return ENOENT;297298*ret_value = values;299300return retval;301}302303krb5_error_code304pkinit_libdefault_string(krb5_context context, const krb5_data *realm,305const char *option, char **ret_value)306{307krb5_error_code retval;308char **values = NULL;309310retval = pkinit_libdefault_strings(context, realm, option, &values);311if (retval)312return retval;313314if (values[0] == NULL) {315retval = ENOENT;316} else {317*ret_value = strdup(values[0]);318if (*ret_value == NULL)319retval = ENOMEM;320}321322profile_free_list(values);323return retval;324}325326krb5_error_code327pkinit_libdefault_boolean(krb5_context context, const krb5_data *realm,328const char *option, int default_value,329int *ret_value)330{331char *string = NULL;332krb5_error_code retval;333334retval = pkinit_libdefault_string(context, realm, option, &string);335336if (retval == 0) {337*ret_value = _krb5_conf_boolean(string);338free(string);339} else340*ret_value = default_value;341342return 0;343}344345krb5_error_code346pkinit_libdefault_integer(krb5_context context, const krb5_data *realm,347const char *option, int default_value,348int *ret_value)349{350char *string = NULL;351krb5_error_code retval;352353retval = pkinit_libdefault_string(context, realm, option, &string);354355if (retval == 0) {356char *endptr;357long l;358l = strtol(string, &endptr, 0);359if (endptr == string)360*ret_value = default_value;361else362*ret_value = l;363free(string);364}365366return retval;367}368369370