]> eyrie.org Git - kerberos/krb5-strength.git/blob - plugin/heimdal.c
Initial implementation of Heimdal plugin API
[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 <plugin/api.h>
24
25 /* Skip this entire file if not building with Heimdal. */
26 #ifdef HAVE_KRB5_REALM
27
28 /* kadm5-pwcheck.h isn't always installed by Heimdal. */
29 # ifdef HAVE_KADM5_PWCHECK_H
30 #  include <kadm5-pwcheck.h>
31 # else
32 #  define KADM5_PASSWD_VERSION_V1 1
33
34 typedef int
35 (*kadm5_passwd_quality_check_func)(krb5_context context,
36                                    krb5_principal principal,
37                                    krb5_data *password,
38                                    const char *tuning,
39                                    char *message,
40                                    size_t length);
41
42 struct kadm5_pw_policy_check_func {
43     const char *name;
44     kadm5_passwd_quality_check_func func;
45 };
46
47 struct kadm5_pw_policy_verifier {
48     const char *name;
49     int version;
50     const char *vendor;
51     const struct kadm5_pw_policy_check_func *funcs;
52 };
53 # endif /* !HAVE_KADM5_PWCHECK_H */
54
55 /*
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.
59  */
60 static int
61 heimdal_pwcheck(krb5_context context, krb5_principal principal,
62                 krb5_data *password, const char *tuning, char *message,
63                 size_t length)
64 {
65     void *data;
66     char *pastring;
67     char *name = NULL;
68     char *dictionary = NULL;
69     krb5_error_code status;
70     int result;
71
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",
77                 length);
78         return 1;
79     }
80     status = krb5_unparse_name(context, principal, &name);
81     if (status != 0) {
82         strlcpy(message, "Cannot unparse principal name", length);
83         return 1;
84     }
85     pastring = malloc(password->length + 1);
86     if (pastring == NULL) {
87         snprintf(message, length, "Cannot allocate memory: %s",
88                  strerror(errno));
89         return 1;
90     }
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",
95                 strerror(errno));
96         free(pastring);
97         return 1;
98     }
99     result = pwcheck_check(data, pastring, name, message, length);
100     free(pastring);
101     pwcheck_close(data);
102     return result;
103 }
104
105 /* The public symbol that Heimdal looks for. */
106 static struct kadm5_pw_policy_check_func functions[] = {
107     { "krb5-strength", heimdal_pwcheck },
108     { NULL, NULL }
109 };
110 struct kadm5_pw_policy_verifier kadm5_password_verifier = {
111     "krb5-strength",
112     KADM5_PASSWD_VERSION_V1,
113     "Russ Allbery",
114     functions
115 };
116
117 #endif /* HAVE_KRB5_REALM */