]> eyrie.org Git - kerberos/krb5-strength.git/blobdiff - plugin/cdb.c
Add SPDX-License-Identifier headers
[kerberos/krb5-strength.git] / plugin / cdb.c
index dc9f0d451405eea705a6e8aa2be6cf63eb47f309..7b268d95f848f8ce59e51d21c45453ce2ece396b 100644 (file)
@@ -8,11 +8,11 @@
  * or end, two characters removed from the start, two from the end, or one
  * character from both start and end.
  *
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
  * 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/system.h>
 
 #ifdef HAVE_CDB_H
-# include <cdb.h>
+#    include <cdb.h>
 #endif
 #include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
 
 #include <plugin/internal.h>
 #include <util/macros.h>
 
-/* Skip the rest of this file if CDB is not available. */
-#ifdef HAVE_CDB
 
 /*
- * Macro used to make password checks more readable.  Assumes that the found
- * and fail labels are available for the abort cases of finding a password or
- * failing to look it up.
+ * Stub for strength_init_cdb if not built with CDB support.
  */
-# define CHECK_PASSWORD(ctx, data, password)                    \
-    do {                                                        \
-        code = in_cdb_dictionary(ctx, data, password, &found);  \
-        if (code != 0)                                          \
-            goto fail;                                          \
-        if (found)                                              \
-            goto found;                                         \
-    } while (0)
+#ifndef HAVE_CDB
+krb5_error_code
+strength_init_cdb(krb5_context ctx, krb5_pwqual_moddata data UNUSED)
+{
+    char *path = NULL;
+
+    /* Get CDB dictionary path from krb5.conf. */
+    strength_config_string(ctx, "password_dictionary_cdb", &path);
+
+    /* If it was set, report an error, since we don't have CDB support. */
+    if (path == NULL)
+        return 0;
+    free(path);
+    krb5_set_error_message(ctx, KADM5_BAD_SERVER_PARAMS,
+                           "CDB dictionary requested but not built with CDB"
+                           " support");
+    return KADM5_BAD_SERVER_PARAMS;
+}
+#endif
+
 
+/* Skip the rest of this file if CDB is not available. */
+#ifdef HAVE_CDB
 
 /*
  * Look up a password in CDB and set the found parameter to true if it is
@@ -57,7 +69,8 @@ in_cdb_dictionary(krb5_context ctx, krb5_pwqual_moddata data,
 {
     int status;
 
-    status = cdb_find(&data->cdb, password, strlen(password));
+    *found = false;
+    status = cdb_find(&data->cdb, password, (unsigned int) strlen(password));
     if (status < 0)
         return strength_error_system(ctx, "cannot query CDB database");
     else {
@@ -67,6 +80,57 @@ in_cdb_dictionary(krb5_context ctx, krb5_pwqual_moddata data,
 }
 
 
+/*
+ * Initialize the CDB dictionary.  Opens the dictionary and sets up the
+ * TinyCDB state.  Returns 0 on success, non-zero on failure (and sets the
+ * error in the Kerberos context).  If not built with CDB support, always
+ * returns an error.
+ */
+krb5_error_code
+strength_init_cdb(krb5_context ctx, krb5_pwqual_moddata data)
+{
+    krb5_error_code code;
+    char *path = NULL;
+
+    /* Get CDB dictionary path from krb5.conf. */
+    strength_config_string(ctx, "password_dictionary_cdb", &path);
+
+    /* If there is no configured dictionary, nothing to do. */
+    if (path == NULL)
+        return 0;
+
+    /* Open the dictionary and initialize the CDB data. */
+    data->cdb_fd = open(path, O_RDONLY);
+    if (data->cdb_fd < 0)
+        return strength_error_system(ctx, "cannot open dictionary %s", path);
+    if (cdb_init(&data->cdb, data->cdb_fd) < 0) {
+        code = strength_error_system(ctx, "cannot init dictionary %s", path);
+        free(path);
+        close(data->cdb_fd);
+        data->cdb_fd = -1;
+        return code;
+    }
+    free(path);
+    data->have_cdb = true;
+    return 0;
+}
+
+
+/*
+ * Macro used to make password checks more readable.  Assumes that the found
+ * and fail labels are available for the abort cases of finding a password or
+ * failing to look it up.
+ */
+#    define CHECK_PASSWORD(ctx, data, password)                    \
+        do {                                                       \
+            code = in_cdb_dictionary(ctx, data, password, &found); \
+            if (code != 0)                                         \
+                goto fail;                                         \
+            if (found)                                             \
+                goto found;                                        \
+        } while (0)
+
+
 /*
  * Given a password, try the various transformations that we want to apply and
  * check for each of them in the dictionary.  Returns a Kerberos status code,
@@ -81,6 +145,10 @@ strength_check_cdb(krb5_context ctx, krb5_pwqual_moddata data,
     bool found;
     char *variant = NULL;
 
+    /* If we have no dictionary, there is nothing to do. */
+    if (!data->have_cdb)
+        return 0;
+
     /* Check the basic password. */
     CHECK_PASSWORD(ctx, data, password);