]> eyrie.org Git - kerberos/krb5-strength.git/blob - plugin/heimdal.c
Merge commit 'upstream/1.0' into debian
[kerberos/krb5-strength.git] / plugin / heimdal.c
1 /*
2  * Heimdal shared module API.
3  *
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.
10  *
11  * Of course, the external Heimdal strength checking program can be used
12  * instead.
13  *
14  * Written by Russ Allbery <rra@stanford.edu>
15  * Copyright 2009 Board of Trustees, Leland Stanford Jr. Unversity
16  *
17  * See LICENSE for licensing terms.
18  */
19
20 #include <config.h>
21 #include <portable/system.h>
22
23 #include <errno.h>
24 #include <krb5.h>
25
26 #include <plugin/api.h>
27
28 /* Skip this entire file if not building with Heimdal. */
29 #ifdef HAVE_KRB5_REALM
30
31 /* Used for unused parameters to silence gcc warnings. */
32 #define UNUSED  __attribute__((__unused__))
33
34 /* kadm5-pwcheck.h isn't always installed by Heimdal. */
35 # ifdef HAVE_KADM5_PWCHECK_H
36 #  include <kadm5-pwcheck.h>
37 # else
38 #  define KADM5_PASSWD_VERSION_V1 1
39
40 typedef int
41 (*kadm5_passwd_quality_check_func)(krb5_context context,
42                                    krb5_principal principal,
43                                    krb5_data *password,
44                                    const char *tuning,
45                                    char *message,
46                                    size_t length);
47
48 struct kadm5_pw_policy_check_func {
49     const char *name;
50     kadm5_passwd_quality_check_func func;
51 };
52
53 struct kadm5_pw_policy_verifier {
54     const char *name;
55     int version;
56     const char *vendor;
57     const struct kadm5_pw_policy_check_func *funcs;
58 };
59 # endif /* !HAVE_KADM5_PWCHECK_H */
60
61 /*
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.
65  */
66 static int
67 heimdal_pwcheck(krb5_context context, krb5_principal principal,
68                 krb5_data *password, const char *tuning UNUSED, char *message,
69                 size_t length)
70 {
71     void *data;
72     char *pastring;
73     char *name = NULL;
74     char *dictionary = NULL;
75     krb5_error_code status;
76     int result;
77
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",
82                 length);
83         return 1;
84     }
85     status = krb5_unparse_name(context, principal, &name);
86     if (status != 0) {
87         strlcpy(message, "Cannot unparse principal name", length);
88         return 1;
89     }
90     pastring = malloc(password->length + 1);
91     if (pastring == NULL) {
92         snprintf(message, length, "Cannot allocate memory: %s",
93                  strerror(errno));
94         return 1;
95     }
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));
101         free(pastring);
102         return 1;
103     }
104     result = pwcheck_check(data, pastring, name, message, length);
105     free(pastring);
106     pwcheck_close(data);
107     return result;
108 }
109
110 /* The public symbol that Heimdal looks for. */
111 static struct kadm5_pw_policy_check_func functions[] = {
112     { "krb5-strength", heimdal_pwcheck },
113     { NULL, NULL }
114 };
115 struct kadm5_pw_policy_verifier kadm5_password_verifier = {
116     "krb5-strength",
117     KADM5_PASSWD_VERSION_V1,
118     "Russ Allbery",
119     functions
120 };
121
122 #endif /* HAVE_KRB5_REALM */