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>
23 #include <plugin/api.h>
25 /* Skip this entire file if not building with Heimdal. */
26 #ifdef HAVE_KRB5_REALM
28 /* kadm5-pwcheck.h isn't always installed by Heimdal. */
29 # ifdef HAVE_KADM5_PWCHECK_H
30 # include <kadm5-pwcheck.h>
32 # define KADM5_PASSWD_VERSION_V1 1
35 (*kadm5_passwd_quality_check_func)(krb5_context context,
36 krb5_principal principal,
42 struct kadm5_pw_policy_check_func {
44 kadm5_passwd_quality_check_func func;
47 struct kadm5_pw_policy_verifier {
51 const struct kadm5_pw_policy_check_func *funcs;
53 # endif /* !HAVE_KADM5_PWCHECK_H */
56 * This is the single check function that we provide. It does the glue
57 * required to initialize our checks, convert the Heimdal arguments to the
58 * strings we expect, and return the result.
61 heimdal_pwcheck(krb5_context context, krb5_principal principal,
62 krb5_data *password, const char *tuning, char *message,
68 char *dictionary = NULL;
69 krb5_error_code status;
72 krb5_get_default_realm(ctx, &realm);
73 krb5_appdefault_string(ctx, "krb5-strength", principal->realm,
74 "password_dictionary", "", &dictionary);
75 if (dictionary == NULL || dictionary[0] == '\0') {
76 strlcpy(message, "password_dictionary not configured in krb5.conf",
80 status = krb5_unparse_name(context, principal, &name);
82 strlcpy(message, "Cannot unparse principal name", length);
85 pastring = malloc(password->length + 1);
86 if (pastring == NULL) {
87 snprintf(message, length, "Cannot allocate memory: %s",
91 memcpy(pastring, password->data, password->length);
92 pastring[password->length] = '\0';
93 if (pwcheck_init(&data, dictionary) != 0) {
94 snprintf(message, length, "Cannot initialize strength checking: %s",
99 result = pwcheck_check(data, pastring, name, message, length);
105 /* The public symbol that Heimdal looks for. */
106 static struct kadm5_pw_policy_check_func functions[] = {
107 { "krb5-strength", heimdal_pwcheck },
110 struct kadm5_pw_policy_verifier kadm5_password_verifier = {
112 KADM5_PASSWD_VERSION_V1,
117 #endif /* HAVE_KRB5_REALM */