Blame src/plugins/preauth/pkinit/pkinit_profile.c

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
}