diff options
author | Russ Allbery <eagle@eyrie.org> | 2018-06-03 16:58:02 -0700 |
---|---|---|
committer | Russ Allbery <eagle@eyrie.org> | 2018-06-03 16:58:02 -0700 |
commit | edf31eba414d9a105791c076fb1444a78d210dff (patch) | |
tree | 2bac18fa3b71593e616061a0fbcbfdd6ab26a255 /client/options.c | |
parent | 4b3f858ef567c0d12511e7fea2a56f08f2729635 (diff) | |
parent | 68c4b05c268cd6e358cc41c8feb44bc2c7fcb898 (diff) |
New upstream version 1.4
Diffstat (limited to 'client/options.c')
-rw-r--r-- | client/options.c | 131 |
1 files changed, 103 insertions, 28 deletions
diff --git a/client/options.c b/client/options.c index ae88485..7b1f04e 100644 --- a/client/options.c +++ b/client/options.c @@ -5,53 +5,109 @@ * file for both wallet and wallet-rekey. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2006, 2007, 2008, 2010 + * Copyright 2018 Russ Allbery <eagle@eyrie.org> + * Copyright 2006-2008, 2010 * The Board of Trustees of the Leland Stanford Junior University * - * See LICENSE for licensing terms. + * SPDX-License-Identifier: MIT */ #include <config.h> #include <portable/krb5.h> #include <portable/system.h> +#include <errno.h> + #include <client/internal.h> +#include <util/messages.h> /* - * Load a string option from Kerberos appdefaults. This requires an annoying - * workaround because one cannot specify a default value of NULL. + * Load a number option from Kerberos appdefaults. Takes the Kerberos + * context, the realm, the option, and the result location. The native + * interface doesn't support numbers, so we actually read a string and then + * convert. */ static void -default_string(krb5_context ctx, const char *opt, const char *defval, - char **result) +default_number(krb5_context ctx, const char *realm, const char *opt, + long defval, long *result) { - if (defval == NULL) - defval = ""; - krb5_appdefault_string(ctx, "wallet", NULL, opt, defval, result); - if (*result != NULL && (*result)[0] == '\0') { - free(*result); - *result = NULL; + char *tmp = NULL; + char *end; + long value; +#ifdef HAVE_KRB5_REALM + krb5_const_realm rdata = realm; +#else + krb5_data realm_struct; + const krb5_data *rdata; + + if (realm == NULL) + rdata = NULL; + else { + rdata = &realm_struct; + realm_struct.magic = KV5M_DATA; + realm_struct.data = (void *) realm; + realm_struct.length = (unsigned int) strlen(realm); } +#endif + + *result = defval; + krb5_appdefault_string(ctx, "wallet", rdata, opt, "", &tmp); + if (tmp != NULL && tmp[0] != '\0') { + errno = 0; + value = strtol(tmp, &end, 10); + if (errno != 0 || *end != '\0') + warn("invalid number in krb5.conf setting for %s: %s", opt, tmp); + else + *result = value; + } + free(tmp); } /* - * Load a number option from Kerberos appdefaults. The native interface - * doesn't support numbers, so we actually read a string and then convert. + * Load a string option from Kerberos appdefaults. Takes the Kerberos + * context, the realm, 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. */ static void -default_number(krb5_context ctx, const char *opt, int defval, int *result) +default_string(krb5_context ctx, const char *realm, const char *opt, + const char *defval, char **result) { - char *tmp = NULL; + char *value = NULL; +#ifdef HAVE_KRB5_REALM + krb5_const_realm rdata = realm; +#else + krb5_data realm_struct; + const krb5_data *rdata; - krb5_appdefault_string(ctx, "wallet", NULL, opt, "", &tmp); - if (tmp != NULL && tmp[0] != '\0') - *result = atoi(tmp); - else - *result = defval; - if (tmp != NULL) - free(tmp); + if (realm == NULL) + rdata = NULL; + else { + rdata = &realm_struct; + realm_struct.magic = KV5M_DATA; + realm_struct.data = (void *) realm; + realm_struct.length = (unsigned int) strlen(realm); + } +#endif + + if (defval == NULL) + defval = ""; + krb5_appdefault_string(ctx, "wallet", rdata, opt, defval, &value); + if (value != NULL) { + if (value[0] == '\0') + free(value); + else { + if (*result != NULL) + free(*result); + *result = value; + } + } } @@ -63,9 +119,28 @@ default_number(krb5_context ctx, const char *opt, int defval, int *result) void default_options(krb5_context ctx, struct options *options) { - default_string(ctx, "wallet_type", "wallet", &options->type); - default_string(ctx, "wallet_server", WALLET_SERVER, &options->server); - default_string(ctx, "wallet_principal", NULL, &options->principal); - default_number(ctx, "wallet_port", WALLET_PORT, &options->port); - options->user = NULL; + long port; + char *realm = NULL; + + /* Having no local realm may be intentional, so don't report an error. */ + krb5_get_default_realm(ctx, &realm); + + /* Load the options. */ + default_string(ctx, realm, "wallet_type", "wallet", &options->type); + default_string(ctx, realm, "wallet_server", WALLET_SERVER, + &options->server); + default_string(ctx, realm, "wallet_principal", NULL, &options->principal); + default_number(ctx, realm, "wallet_port", WALLET_PORT, &port); + + /* Additional checks on the option values. */ + if (port != WALLET_PORT && (port <= 0 || port > 65535)) { + warn("invalid number in krb5.conf setting for wallet_port: %ld", port); + options->port = WALLET_PORT; + } else { + options->port = (unsigned short) port; + } + + /* Clean up. */ + if (realm != NULL) + krb5_free_default_realm(ctx, realm); } |