/*
- * MIT Kerberos shared module API.
+ * Kerberos shared module API for MIT Kerberos 1.9 or later.
*
- * This is the glue required for a Heimdal password quality check via a
- * dynamically loaded module. Retrieves the dictionary path from krb5.conf.
- * This may change in later versions via a mechanism to pass profile
- * information from kadmind to the plugin.
+ * This is the glue required for a password quality check via a dynamically
+ * loaded module using the MIT Kerberos pwqual plugin interface.
*
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2010 Board of Trustees, Leland Stanford Jr. Unversity
+ * Written by Greg Hudson <ghudson@mit.edu>
+ * Copyright 2010 the Massachusetts Institute of Technology
+ * Copyright 2013
+ * The Board of Trustees of the Leland Stanford Junior University
*
- * See LICENSE for licensing terms.
+ * SPDX-License-Identifier: MIT
*/
#include <config.h>
+#include <portable/kadmin.h>
+#include <portable/krb5.h>
#include <portable/system.h>
#include <errno.h>
-#include <krb5.h>
+#ifdef HAVE_KRB5_PWQUAL_PLUGIN_H
+# include <krb5/pwqual_plugin.h>
+#endif
-#include <plugin/api.h>
+#include <plugin/internal.h>
+#include <util/macros.h>
-/* Skip this entire file if building with Heimdal. */
-#ifndef HAVE_KRB5_REALM
+/* Skip this entire file if building with Heimdal or pre-1.9 MIT. */
+#ifdef HAVE_KRB5_PWQUAL_PLUGIN_H
-/* Used for unused parameters to silence gcc warnings. */
-#define UNUSED __attribute__((__unused__))
-
-/* Allow for a build without the plugin header. */
-# ifdef HAVE_KRB5_PWCHECK_PLUGIN_H
-# include <krb5/pwcheck_plugin.h>
-# else
-typedef struct krb5plugin_kadmin_pwcheck_ftable_v0 {
- int minor_version;
- krb5_error_code (*init)(krb5_context, void **);
- void (*fini)(krb5_context, void *);
- int (*check)(krb5_context, void *, krb5_const_principal,
- const krb5_data *password);
-} krb5plugin_kadmin_pwcheck_ftable_v0;
-# endif /* !HAVE_KRB5_PWCHECK_PLUGIN_H */
+/* Prototype for the public interface. */
+krb5_error_code pwqual_strength_initvt(krb5_context, int, int,
+ krb5_plugin_vtable);
/*
* dictionary is, and then call pwcheck_init.
*/
static krb5_error_code
-init(krb5_context context, void **data)
+init(krb5_context ctx, const char *dictionary, krb5_pwqual_moddata *data)
{
- char *dictionary = NULL;
-
- krb5_appdefault_string(context, "krb5-strength", NULL,
- "password_dictionary", "", &dictionary);
- if (dictionary == NULL || dictionary[0] == '\0') {
- krb5_set_error_message(context, KRB5_PLUGIN_OP_NOTSUPP,
- "password_dictionary not configured in"
- " krb5.conf");
- return KRB5_PLUGIN_OP_NOTSUPP;
- }
- if (pwcheck_init(data, dictionary) != 0) {
- krb5_set_error_message(context, errno, "Cannot initialize strength"
- " checking with dictionary %s: %s", dictionary,
- strerror(errno));
- return errno;
- }
- return 0;
+ return strength_init(ctx, dictionary, data);
}
/*
- * Check the password. We need to transform the krb5_data struct and the
- * principal passed us by kadmind into nul-terminated strings for our check.
+ * Check the password. We need to transform the principal passed us by kadmind
+ * into a string for our check.
*/
static krb5_error_code
-check(krb5_context context, void *data, krb5_const_principal princ,
- const krb5_data *password)
+check(krb5_context ctx, krb5_pwqual_moddata data, const char *password,
+ const char *policy_name UNUSED, krb5_principal princ,
+ const char **languages UNUSED)
{
- char *pastring;
char *name = NULL;
- krb5_error_code status;
- char message[BUFSIZ];
-
- status = krb5_unparse_name(context, princ, &name);
- if (status != 0)
- return status;
- pastring = malloc(password->length + 1);
- if (pastring == NULL) {
- status = errno;
- krb5_set_error_message(context, status, "%s", strerror(status));
- krb5_free_unparsed_name(context, name);
- return status;
- }
- memcpy(pastring, password->data, password->length);
- pastring[password->length] = '\0';
- status = pwcheck_check(data, pastring, name, message, sizeof(message));
- if (status != 0)
- krb5_set_error_message(context, status, "%s", message);
- free(pastring);
- krb5_free_unparsed_name(context, name);
- return status;
+ krb5_error_code code;
+
+ code = krb5_unparse_name(ctx, princ, &name);
+ if (code != 0)
+ return code;
+ code = strength_check(ctx, data, name, password);
+ krb5_free_unparsed_name(ctx, name);
+ return code;
}
* Shut down the library.
*/
static void
-fini(krb5_context context UNUSED, void *data)
+fini(krb5_context ctx, krb5_pwqual_moddata data)
{
- pwcheck_close(data);
+ strength_close(ctx, data);
}
-/* The public symbol that MIT Kerberos looks for. */
-krb5plugin_kadmin_pwcheck_ftable_v0 kadmin_pwcheck_0 = {
- 0, init, fini, check
-};
+/*
+ * The public symbol that MIT Kerberos looks for. Builds and returns the
+ * vtable.
+ */
+krb5_error_code
+pwqual_strength_initvt(krb5_context context UNUSED, int maj_ver,
+ int min_ver UNUSED, krb5_plugin_vtable vtable)
+{
+ krb5_pwqual_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (krb5_pwqual_vtable) vtable;
+ vt->name = "krb5-strength";
+ vt->open = init;
+ vt->check = check;
+ vt->close = fini;
+ return 0;
+}
-#endif /* !HAVE_KRB5_REALM */
+#endif /* HAVE_KRB5_PWQUAL_PLUGIN_H */