1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
/*
* Retrieve configuratin settings from krb5.conf.
*
* Provided here are functions to retrieve boolean, numeric, and string
* settings from krb5.conf. This wraps the somewhat awkward
* krb5_appdefaults_* functions.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
#include <portable/krb5.h>
#include <portable/system.h>
#include <errno.h>
#include <plugin/internal.h>
#include <util/macros.h>
/* The representation of the realm differs between MIT and Kerberos. */
#ifdef HAVE_KRB5_REALM
typedef krb5_realm realm_type;
#else
typedef krb5_data *realm_type;
#endif
/*
* Obtain the default realm and translate it into the format required by
* krb5_appdefault_*. This is obnoxious for MIT Kerberos, which returns the
* default realm as a string but expects the realm as a krb5_data type when
* calling krb5_appdefault_*.
*/
#ifdef HAVE_KRB5_REALM
static realm_type
default_realm(krb5_context ctx)
{
krb5_error_code code;
realm_type realm;
code = krb5_get_default_realm(ctx, &realm);
if (code != 0)
realm = NULL;
return realm;
}
#else /* !HAVE_KRB5_REALM */
static realm_type
default_realm(krb5_context ctx)
{
char *realm = NULL;
krb5_error_code code;
krb5_data *realm_data;
realm_data = calloc(1, sizeof(krb5_data));
if (realm_data == NULL)
return NULL;
code = krb5_get_default_realm(ctx, &realm);
if (code != 0) {
free(realm);
return NULL;
}
realm_data->magic = KV5M_DATA;
realm_data->data = strdup(realm);
if (realm_data->data == NULL) {
free(realm_data);
krb5_free_default_realm(ctx, realm);
return NULL;
}
realm_data->length = strlen(realm);
krb5_free_default_realm(ctx, realm);
return realm_data;
}
#endif /* !HAVE_KRB5_REALM */
/*
* Free the default realm data in whatever form it was generated for the calls
* to krb5_appdefault_*.
*/
#ifdef HAVE_KRB5_REALM
static void
free_default_realm(krb5_context ctx UNUSED, realm_type realm)
{
krb5_free_default_realm(ctx, realm);
}
#else /* !HAVE_KRB5_REALM */
static void
free_default_realm(krb5_context ctx UNUSED, realm_type realm)
{
free(realm->data);
free(realm);
}
#endif /* !HAVE_KRB5_REALM */
/*
* Load a boolean option from Kerberos appdefaults. Takes the Kerberos
* context, the option, and the result location.
*/
void
sync_config_boolean(krb5_context ctx, const char *opt, bool *result)
{
realm_type realm;
int tmp;
/*
* The MIT version of krb5_appdefault_boolean takes an int * and the
* Heimdal version takes a krb5_boolean *, so hope that Heimdal always
* defines krb5_boolean to int or this will require more portability work.
*/
realm = default_realm(ctx);
krb5_appdefault_boolean(ctx, "krb5-sync", realm, opt, *result, &tmp);
*result = tmp;
free_default_realm(ctx, realm);
}
/*
* Load a list option from Kerberos appdefaults. Takes the Kerberos context,
* the option, and the result location. The option is read as a string and
* the split on spaces and tabs into a list.
*
* This requires an annoying workaround because one cannot specify a default
* value of NULL with MIT Kerberos, since MIT Kerberos unconditionally calls
* strdup on the default value. There's also no way to determine if memory
* allocation failed while parsing or while setting the default value.
*/
krb5_error_code
sync_config_list(krb5_context ctx, const char *opt, struct vector **result)
{
realm_type realm;
char *value = NULL;
/* Obtain the string from [appdefaults]. */
realm = default_realm(ctx);
krb5_appdefault_string(ctx, "krb5-sync", realm, opt, "", &value);
free_default_realm(ctx, realm);
/* If we got something back, store it in result. */
if (value != NULL) {
if (value[0] != '\0') {
*result = sync_vector_split_multi(value, " \t", *result);
if (*result == NULL)
return sync_error_system(ctx, "cannot allocate memory");
}
krb5_free_string(ctx, value);
}
return 0;
}
/*
* Load a string option from Kerberos appdefaults. Takes the Kerberos
* context, the option, and the result location.
*
* This requires an annoying workaround because one cannot specify a default
* value of NULL with MIT Kerberos, since MIT Kerberos unconditionally calls
* strdup on the default value. There's also no way to determine if memory
* allocation failed while parsing or while setting the default value, so we
* don't return an error code.
*/
void
sync_config_string(krb5_context ctx, const char *opt, char **result)
{
realm_type realm;
char *value = NULL;
/* Obtain the string from [appdefaults]. */
realm = default_realm(ctx);
krb5_appdefault_string(ctx, "krb5-sync", realm, opt, "", &value);
free_default_realm(ctx, realm);
/* If we got something back, store it in result. */
if (value != NULL) {
if (value[0] != '\0') {
free(*result);
*result = strdup(value);
}
krb5_free_string(ctx, value);
}
}
|