|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* COPYRIGHT (C) 2006,2007
|
|
Packit |
fd8b60 |
* THE REGENTS OF THE UNIVERSITY OF MICHIGAN
|
|
Packit |
fd8b60 |
* ALL RIGHTS RESERVED
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Permission is granted to use, copy, create derivative works
|
|
Packit |
fd8b60 |
* and redistribute this software and such derivative works
|
|
Packit |
fd8b60 |
* for any purpose, so long as the name of The University of
|
|
Packit |
fd8b60 |
* Michigan is not used in any advertising or publicity
|
|
Packit |
fd8b60 |
* pertaining to the use of distribution of this software
|
|
Packit |
fd8b60 |
* without specific, written prior authorization. If the
|
|
Packit |
fd8b60 |
* above copyright notice or any other identification of the
|
|
Packit |
fd8b60 |
* University of Michigan is included in any copy of any
|
|
Packit |
fd8b60 |
* portion of this software, then the disclaimer below must
|
|
Packit |
fd8b60 |
* also be included.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
|
|
Packit |
fd8b60 |
* FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
|
|
Packit |
fd8b60 |
* PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
|
|
Packit |
fd8b60 |
* MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
|
Packit |
fd8b60 |
* WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
|
|
Packit |
fd8b60 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
|
Packit |
fd8b60 |
* REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
|
|
Packit |
fd8b60 |
* FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
|
|
Packit |
fd8b60 |
* CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
|
|
Packit |
fd8b60 |
* OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
|
|
Packit |
fd8b60 |
* IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
|
|
Packit |
fd8b60 |
* SUCH DAMAGES.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include "k5-int.h"
|
|
Packit |
fd8b60 |
#include "pkinit.h"
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Routines for handling profile [config file] options
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Forward prototypes */
|
|
Packit |
fd8b60 |
static int _krb5_conf_boolean(const char *s);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* XXX
|
|
Packit |
fd8b60 |
* The following is duplicated verbatim from src/lib/krb5/krb/get_in_tkt.c,
|
|
Packit |
fd8b60 |
* which is duplicated from somewhere else. :-/
|
|
Packit |
fd8b60 |
* XXX
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static const char *const conf_yes[] = {
|
|
Packit |
fd8b60 |
"y", "yes", "true", "t", "1", "on",
|
|
Packit |
fd8b60 |
0,
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static const char *const conf_no[] = {
|
|
Packit |
fd8b60 |
"n", "no", "false", "nil", "0", "off",
|
|
Packit |
fd8b60 |
0,
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static int
|
|
Packit |
fd8b60 |
_krb5_conf_boolean(const char *s)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
const char *const *p;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for(p=conf_yes; *p; p++) {
|
|
Packit |
fd8b60 |
if (strcasecmp(*p,s) == 0)
|
|
Packit |
fd8b60 |
return 1;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for(p=conf_no; *p; p++) {
|
|
Packit |
fd8b60 |
if (strcasecmp(*p,s) == 0)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Default to "no" */
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* XXX
|
|
Packit |
fd8b60 |
* End duplicated code from src/lib/krb5/krb/get_in_tkt.c
|
|
Packit |
fd8b60 |
* XXX
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* The following are based on krb5_libdefault_* functions in
|
|
Packit |
fd8b60 |
* src/lib/krb5/krb/get_in_tkt.c
|
|
Packit |
fd8b60 |
* N.B. This assumes that context->default_realm has
|
|
Packit |
fd8b60 |
* already been established.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_kdcdefault_strings(krb5_context context, const char *realmname,
|
|
Packit |
fd8b60 |
const char *option, char ***ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
profile_t profile = NULL;
|
|
Packit |
fd8b60 |
const char *names[5];
|
|
Packit |
fd8b60 |
char **values = NULL;
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (context == NULL)
|
|
Packit |
fd8b60 |
return KV5M_CONTEXT;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
profile = context->profile;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (realmname != NULL) {
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Try number one:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* [realms]
|
|
Packit |
fd8b60 |
* REALM = {
|
|
Packit |
fd8b60 |
* option = <value>
|
|
Packit |
fd8b60 |
* }
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
names[0] = KRB5_CONF_REALMS;
|
|
Packit |
fd8b60 |
names[1] = realmname;
|
|
Packit |
fd8b60 |
names[2] = option;
|
|
Packit |
fd8b60 |
names[3] = 0;
|
|
Packit |
fd8b60 |
retval = profile_get_values(profile, names, &values);
|
|
Packit |
fd8b60 |
if (retval == 0 && values != NULL)
|
|
Packit |
fd8b60 |
goto goodbye;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Try number two:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* [kdcdefaults]
|
|
Packit |
fd8b60 |
* option = <value>
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
names[0] = KRB5_CONF_KDCDEFAULTS;
|
|
Packit |
fd8b60 |
names[1] = option;
|
|
Packit |
fd8b60 |
names[2] = 0;
|
|
Packit |
fd8b60 |
retval = profile_get_values(profile, names, &values);
|
|
Packit |
fd8b60 |
if (retval == 0 && values != NULL)
|
|
Packit |
fd8b60 |
goto goodbye;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
goodbye:
|
|
Packit |
fd8b60 |
if (values == NULL)
|
|
Packit |
fd8b60 |
retval = ENOENT;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*ret_value = values;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_kdcdefault_string(krb5_context context, const char *realmname,
|
|
Packit |
fd8b60 |
const char *option, char **ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
char **values = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
retval = pkinit_kdcdefault_strings(context, realmname, option, &values);
|
|
Packit |
fd8b60 |
if (retval)
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (values[0] == NULL) {
|
|
Packit |
fd8b60 |
retval = ENOENT;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
*ret_value = strdup(values[0]);
|
|
Packit |
fd8b60 |
if (*ret_value == NULL)
|
|
Packit |
fd8b60 |
retval = ENOMEM;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
profile_free_list(values);
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_kdcdefault_boolean(krb5_context context, const char *realmname,
|
|
Packit |
fd8b60 |
const char *option, int default_value, int *ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
char *string = NULL;
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
retval = pkinit_kdcdefault_string(context, realmname, option, &string);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (retval == 0) {
|
|
Packit |
fd8b60 |
*ret_value = _krb5_conf_boolean(string);
|
|
Packit |
fd8b60 |
free(string);
|
|
Packit |
fd8b60 |
} else
|
|
Packit |
fd8b60 |
*ret_value = default_value;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_kdcdefault_integer(krb5_context context, const char *realmname,
|
|
Packit |
fd8b60 |
const char *option, int default_value, int *ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
char *string = NULL;
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
retval = pkinit_kdcdefault_string(context, realmname, option, &string);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (retval == 0) {
|
|
Packit |
fd8b60 |
char *endptr;
|
|
Packit |
fd8b60 |
long l;
|
|
Packit |
fd8b60 |
l = strtol(string, &endptr, 0);
|
|
Packit |
fd8b60 |
if (endptr == string)
|
|
Packit |
fd8b60 |
*ret_value = default_value;
|
|
Packit |
fd8b60 |
else
|
|
Packit |
fd8b60 |
*ret_value = l;
|
|
Packit |
fd8b60 |
free(string);
|
|
Packit |
fd8b60 |
} else
|
|
Packit |
fd8b60 |
*ret_value = default_value;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* krb5_libdefault_string() is defined as static in
|
|
Packit |
fd8b60 |
* src/lib/krb5/krb/get_in_tkt.c. Create local versions of
|
|
Packit |
fd8b60 |
* krb5_libdefault_* functions here. We need a libdefaults_strings()
|
|
Packit |
fd8b60 |
* function which is not currently supported there anyway. Also,
|
|
Packit |
fd8b60 |
* add the ability to supply a default value for the boolean and
|
|
Packit |
fd8b60 |
* integer functions.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_libdefault_strings(krb5_context context, const krb5_data *realm,
|
|
Packit |
fd8b60 |
const char *option, char ***ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
profile_t profile;
|
|
Packit |
fd8b60 |
const char *names[5];
|
|
Packit |
fd8b60 |
char **values = NULL;
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
char realmstr[1024];
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (realm != NULL && realm->length > sizeof(realmstr)-1)
|
|
Packit |
fd8b60 |
return EINVAL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (realm != NULL) {
|
|
Packit |
fd8b60 |
strncpy(realmstr, realm->data, realm->length);
|
|
Packit |
fd8b60 |
realmstr[realm->length] = '\0';
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!context || (context->magic != KV5M_CONTEXT))
|
|
Packit |
fd8b60 |
return KV5M_CONTEXT;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
profile = context->profile;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (realm != NULL) {
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Try number one:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* [libdefaults]
|
|
Packit |
fd8b60 |
* REALM = {
|
|
Packit |
fd8b60 |
* option = <value>
|
|
Packit |
fd8b60 |
* }
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
names[0] = KRB5_CONF_LIBDEFAULTS;
|
|
Packit |
fd8b60 |
names[1] = realmstr;
|
|
Packit |
fd8b60 |
names[2] = option;
|
|
Packit |
fd8b60 |
names[3] = 0;
|
|
Packit |
fd8b60 |
retval = profile_get_values(profile, names, &values);
|
|
Packit |
fd8b60 |
if (retval == 0 && values != NULL && values[0] != NULL)
|
|
Packit |
fd8b60 |
goto goodbye;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Try number two:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* [realms]
|
|
Packit |
fd8b60 |
* REALM = {
|
|
Packit |
fd8b60 |
* option = <value>
|
|
Packit |
fd8b60 |
* }
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
names[0] = KRB5_CONF_REALMS;
|
|
Packit |
fd8b60 |
names[1] = realmstr;
|
|
Packit |
fd8b60 |
names[2] = option;
|
|
Packit |
fd8b60 |
names[3] = 0;
|
|
Packit |
fd8b60 |
retval = profile_get_values(profile, names, &values);
|
|
Packit |
fd8b60 |
if (retval == 0 && values != NULL && values[0] != NULL)
|
|
Packit |
fd8b60 |
goto goodbye;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Try number three:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* [libdefaults]
|
|
Packit |
fd8b60 |
* option = <value>
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
names[0] = KRB5_CONF_LIBDEFAULTS;
|
|
Packit |
fd8b60 |
names[1] = option;
|
|
Packit |
fd8b60 |
names[2] = 0;
|
|
Packit |
fd8b60 |
retval = profile_get_values(profile, names, &values);
|
|
Packit |
fd8b60 |
if (retval == 0 && values != NULL && values[0] != NULL)
|
|
Packit |
fd8b60 |
goto goodbye;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
goodbye:
|
|
Packit |
fd8b60 |
if (values == NULL)
|
|
Packit |
fd8b60 |
return ENOENT;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*ret_value = values;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_libdefault_string(krb5_context context, const krb5_data *realm,
|
|
Packit |
fd8b60 |
const char *option, char **ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
char **values = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
retval = pkinit_libdefault_strings(context, realm, option, &values);
|
|
Packit |
fd8b60 |
if (retval)
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (values[0] == NULL) {
|
|
Packit |
fd8b60 |
retval = ENOENT;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
*ret_value = strdup(values[0]);
|
|
Packit |
fd8b60 |
if (*ret_value == NULL)
|
|
Packit |
fd8b60 |
retval = ENOMEM;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
profile_free_list(values);
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_libdefault_boolean(krb5_context context, const krb5_data *realm,
|
|
Packit |
fd8b60 |
const char *option, int default_value,
|
|
Packit |
fd8b60 |
int *ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
char *string = NULL;
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
retval = pkinit_libdefault_string(context, realm, option, &string);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (retval == 0) {
|
|
Packit |
fd8b60 |
*ret_value = _krb5_conf_boolean(string);
|
|
Packit |
fd8b60 |
free(string);
|
|
Packit |
fd8b60 |
} else
|
|
Packit |
fd8b60 |
*ret_value = default_value;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
pkinit_libdefault_integer(krb5_context context, const krb5_data *realm,
|
|
Packit |
fd8b60 |
const char *option, int default_value,
|
|
Packit |
fd8b60 |
int *ret_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
char *string = NULL;
|
|
Packit |
fd8b60 |
krb5_error_code retval;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
retval = pkinit_libdefault_string(context, realm, option, &string);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (retval == 0) {
|
|
Packit |
fd8b60 |
char *endptr;
|
|
Packit |
fd8b60 |
long l;
|
|
Packit |
fd8b60 |
l = strtol(string, &endptr, 0);
|
|
Packit |
fd8b60 |
if (endptr == string)
|
|
Packit |
fd8b60 |
*ret_value = default_value;
|
|
Packit |
fd8b60 |
else
|
|
Packit |
fd8b60 |
*ret_value = l;
|
|
Packit |
fd8b60 |
free(string);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return retval;
|
|
Packit |
fd8b60 |
}
|