aboutsummaryrefslogtreecommitdiff
path: root/client/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/options.c')
-rw-r--r--client/options.c126
1 files changed, 97 insertions, 29 deletions
diff --git a/client/options.c b/client/options.c
index 3c68cc7..f011b79 100644
--- a/client/options.c
+++ b/client/options.c
@@ -16,43 +16,98 @@
#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;
+ }
+ }
}
@@ -64,15 +119,28 @@ default_number(krb5_context ctx, const char *opt, int defval, int *result)
void
default_options(krb5_context ctx, struct options *options)
{
- int port;
+ 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);
- 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, &port);
- if (port <= 0 || port > 65535)
+ /* 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
+ } else {
options->port = (unsigned short) port;
- options->user = NULL;
+ }
+
+ /* Clean up. */
+ if (realm != NULL)
+ krb5_free_default_realm(ctx, realm);
}