2 * Heimdal shared module API.
4 * This is the glue required for a Heimdal password quality check via a
5 * dynamically loaded module. Heimdal's shared module API doesn't have
6 * separate initialization and shutdown functions, so provide a self-contained
7 * function that looks up the dictionary path from krb5.conf and does all the
8 * work. This means that it does memory allocations on every call, which
9 * isn't ideal, but it's probably not that slow.
11 * Of course, the external Heimdal strength checking program can be used
14 * Written by Russ Allbery <rra@stanford.edu>
15 * Copyright 2009 Board of Trustees, Leland Stanford Jr. Unversity
17 * See LICENSE for licensing terms.
21 #include <portable/system.h>
26 #include <plugin/api.h>
28 /* Skip this entire file if not building with Heimdal. */
29 #ifdef HAVE_KRB5_REALM
31 /* Used for unused parameters to silence gcc warnings. */
32 #define UNUSED __attribute__((__unused__))
34 /* kadm5-pwcheck.h isn't always installed by Heimdal. */
35 # ifdef HAVE_KADM5_PWCHECK_H
36 # include <kadm5-pwcheck.h>
38 # define KADM5_PASSWD_VERSION_V1 1
41 (*kadm5_passwd_quality_check_func)(krb5_context context,
42 krb5_principal principal,
48 struct kadm5_pw_policy_check_func {
50 kadm5_passwd_quality_check_func func;
53 struct kadm5_pw_policy_verifier {
57 const struct kadm5_pw_policy_check_func *funcs;
59 # endif /* !HAVE_KADM5_PWCHECK_H */
62 * This is the single check function that we provide. It does the glue
63 * required to initialize our checks, convert the Heimdal arguments to the
64 * strings we expect, and return the result.
67 heimdal_pwcheck(krb5_context context, krb5_principal principal,
68 krb5_data *password, const char *tuning UNUSED, char *message,
74 char *dictionary = NULL;
75 krb5_error_code status;
78 krb5_appdefault_string(context, "krb5-strength", principal->realm,
79 "password_dictionary", "", &dictionary);
80 if (dictionary == NULL || dictionary[0] == '\0') {
81 strlcpy(message, "password_dictionary not configured in krb5.conf",
85 status = krb5_unparse_name(context, principal, &name);
87 strlcpy(message, "Cannot unparse principal name", length);
90 pastring = malloc(password->length + 1);
91 if (pastring == NULL) {
92 snprintf(message, length, "Cannot allocate memory: %s",
96 memcpy(pastring, password->data, password->length);
97 pastring[password->length] = '\0';
98 if (pwcheck_init(&data, dictionary) != 0) {
99 snprintf(message, length, "Cannot initialize strength checking"
100 " with dictionary %s: %s", dictionary, strerror(errno));
104 result = pwcheck_check(data, pastring, name, message, length);
110 /* The public symbol that Heimdal looks for. */
111 static struct kadm5_pw_policy_check_func functions[] = {
112 { "krb5-strength", heimdal_pwcheck },
115 struct kadm5_pw_policy_verifier kadm5_password_verifier = {
117 KADM5_PASSWD_VERSION_V1,
122 #endif /* HAVE_KRB5_REALM */