svn rev #24266: branches/plugins2/src/ include/krb5/ lib/kadm5/ lib/kadm5/srv/
ghudson@MIT.EDU
ghudson at MIT.EDU
Sat Aug 28 18:39:40 EDT 2010
http://src.mit.edu/fisheye/changelog/krb5/?cs=24266
Commit By: ghudson
Log Message:
Revise the password quality pluggable interface to match the project
page:
* Modules receive the policy name but not the policy object.
* Enforcement of password policy is out of the interface's scope.
* Built-in modules are: empty, dict, hesiod, princ.
* The consumer API loader takes care of open/close, so there is only
a wrapper function for check.
The project page is at:
http://k5wiki.kerberos.org/wiki/Projects/Password_quality_pluggable_interface
Changed Files:
U branches/plugins2/src/include/krb5/pwqual_plugin.h
U branches/plugins2/src/lib/kadm5/server_internal.h
U branches/plugins2/src/lib/kadm5/srv/Makefile.in
U branches/plugins2/src/lib/kadm5/srv/pwqual.c
U branches/plugins2/src/lib/kadm5/srv/pwqual_dict.c
A branches/plugins2/src/lib/kadm5/srv/pwqual_empty.c
A branches/plugins2/src/lib/kadm5/srv/pwqual_hesiod.c
D branches/plugins2/src/lib/kadm5/srv/pwqual_policy.c
A branches/plugins2/src/lib/kadm5/srv/pwqual_princ.c
U branches/plugins2/src/lib/kadm5/srv/server_misc.c
Modified: branches/plugins2/src/include/krb5/pwqual_plugin.h
===================================================================
--- branches/plugins2/src/include/krb5/pwqual_plugin.h 2010-08-28 20:20:14 UTC (rev 24265)
+++ branches/plugins2/src/include/krb5/pwqual_plugin.h 2010-08-28 22:39:40 UTC (rev 24266)
@@ -51,8 +51,6 @@
#include <krb5/krb5.h>
#include <krb5/plugin.h>
-#include <kadm5/admin.h>
-#include <kdb.h>
/* An abstract type for password quality module data. */
typedef struct krb5_pwqual_moddata_st *krb5_pwqual_moddata;
@@ -65,12 +63,14 @@
(*krb5_pwqual_open_fn)(krb5_context context, const char *dict_file,
krb5_pwqual_moddata *data);
-/* Mandatory: Check a password for the principal princ, possibly making use
- * of the password policy given by policy. Return an error if the password
- * check fails. */
+/*
+ * Mandatory: Check a password for the principal princ, which has an associated
+ * password policy named policy_name (or no associated policy if policy_name is
+ * NULL). Return an error if the password check fails.
+ */
typedef krb5_error_code
(*krb5_pwqual_check_fn)(krb5_context context, krb5_pwqual_moddata data,
- const char *password, kadm5_policy_ent_t policy,
+ const char *password, const char *policy_name,
krb5_principal princ);
/* Optional: Release resources used by module data. */
Modified: branches/plugins2/src/lib/kadm5/server_internal.h
===================================================================
--- branches/plugins2/src/lib/kadm5/server_internal.h 2010-08-28 20:20:14 UTC (rev 24265)
+++ branches/plugins2/src/lib/kadm5/server_internal.h 2010-08-28 22:39:40 UTC (rev 24266)
@@ -158,32 +158,23 @@
/*** Password quality plugin consumer interface ***/
-/* Load the available password quality plugins and store the result into
- * *handles. Free the result with k5_pwqual_free_handles. */
+/* Load all available password quality plugin modules, bind each module to the
+ * realm's dictionary file, and store the result into *handles. Free the
+ * result with k5_pwqual_free_handles. */
krb5_error_code
-k5_pwqual_load(krb5_context context, pwqual_handle **handles);
+k5_pwqual_load(krb5_context context, pwqual_handle **handles,
+ const char *dict_file);
-/* Release a handle list allocated by k5_pwqual_load. All modules must have
- * been closed by the caller. */
-krb5_error_code
+/* Release a handle list allocated by k5_pwqual_load. */
+void
k5_pwqual_free_handles(krb5_context context, pwqual_handle *handles);
-/* Initialize a password quality plugin, possibly using the realm's configured
- * dictionary filename. */
+/* Check a password using a password quality plugin module. */
krb5_error_code
-k5_pwqual_open(krb5_context context, pwqual_handle handle,
- const char *dict_file);
-
-/* Check a password using a password quality plugin. */
-krb5_error_code
k5_pwqual_check(krb5_context context, pwqual_handle handle,
- const char *password, kadm5_policy_ent_t policy,
+ const char *password, const char *policy_name,
krb5_principal princ);
-/* Release the memory used by a password quality plugin. */
-void
-k5_pwqual_close(krb5_context context, pwqual_handle handle);
-
/*** initvt functions for built-in password quality modules ***/
/* The dict module checks passwords against the realm's dictionary. */
@@ -191,9 +182,20 @@
pwqual_dict_initvt(krb5_context context, int maj_ver, int min_ver,
krb5_plugin_vtable vtable);
-/* The policy module enforces password policy constraints. */
+/* The empty module rejects empty passwords (even with no password policy). */
krb5_error_code
-pwqual_policy_initvt(krb5_context context, int maj_ver, int min_ver,
+pwqual_empty_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable);
+
+/* The hesiod module checks passwords against GECOS fields from Hesiod passwd
+ * information (only if the tree was built with Hesiod support). */
+krb5_error_code
+pwqual_hesiod_initvt(krb5_context context, int maj_ver, int min_ver,
krb5_plugin_vtable vtable);
+/* The princ module checks passwords against principal components. */
+krb5_error_code
+pwqual_princ_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable);
+
#endif /* __KADM5_SERVER_INTERNAL_H__ */
Modified: branches/plugins2/src/lib/kadm5/srv/Makefile.in
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/Makefile.in 2010-08-28 20:20:14 UTC (rev 24265)
+++ branches/plugins2/src/lib/kadm5/srv/Makefile.in 2010-08-28 22:39:40 UTC (rev 24266)
@@ -29,7 +29,9 @@
SRCS = $(srcdir)/pwqual.c \
$(srcdir)/pwqual_dict.c \
- $(srcdir)/pwqual_policy.c \
+ $(srcdir)/pwqual_empty.c \
+ $(srcdir)/pwqual_hesiod.c \
+ $(srcdir)/pwqual_princ.c \
$(srcdir)/svr_policy.c \
$(srcdir)/svr_principal.c \
$(srcdir)/server_acl.c \
@@ -42,7 +44,9 @@
OBJS = pwqual.$(OBJEXT) \
pwqual_dict.$(OBJEXT) \
- pwqual_policy.$(OBJECT) \
+ pwqual_empty.$(OBJEXT) \
+ pwqual_hesiod.$(OBJEXT) \
+ pwqual_princ.$(OBJEXT) \
svr_policy.$(OBJEXT) \
svr_principal.$(OBJEXT) \
server_acl.$(OBJEXT) \
@@ -56,7 +60,9 @@
STLIBOBJS = \
pwqual.o \
pwqual_dict.o \
- pwqual_policy.o \
+ pwqual_empty.o \
+ pwqual_hesiod.o \
+ pwqual_princ.o \
svr_policy.o \
svr_principal.o \
server_acl.o \
Modified: branches/plugins2/src/lib/kadm5/srv/pwqual.c
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/pwqual.c 2010-08-28 20:20:14 UTC (rev 24265)
+++ branches/plugins2/src/lib/kadm5/srv/pwqual.c 2010-08-28 22:39:40 UTC (rev 24266)
@@ -25,7 +25,7 @@
* or implied warranty.
*
*
- * Consumer interface for password quality plugins
+ * Consumer interface for password quality plugins.
*/
#include "k5-int.h"
@@ -38,7 +38,8 @@
};
krb5_error_code
-k5_pwqual_load(krb5_context context, pwqual_handle **handles)
+k5_pwqual_load(krb5_context context, pwqual_handle **handles,
+ const char *dict_file)
{
krb5_error_code ret;
krb5_plugin_initvt_fn *modules = NULL, *mod;
@@ -55,60 +56,60 @@
if (list == NULL)
goto cleanup;
- /* For each module, allocate a handle and initialize its vtable. Skip
- * modules which don't successfully initialize. */
+ /* For each module, allocate a handle, initialize its vtable, and bind the
+ * dictionary filename. */
count = 0;
for (mod = modules; *mod != NULL; mod++) {
handle = k5alloc(sizeof(*handle), &ret);
if (handle == NULL)
goto cleanup;
ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt);
- if (ret == 0)
- list[count++] = handle;
- else
+ if (ret != 0) { /* Failed vtable init is non-fatal. */
free(handle);
+ continue;
+ }
+ handle->data = NULL;
+ if (handle->vt.open != NULL) {
+ ret = handle->vt.open(context, dict_file, &handle->data);
+ if (ret != 0) /* Failed dictionary binding is fatal. */
+ goto cleanup;
+ }
+ list[count++] = handle;
+ list[count] = NULL;
+ handle = NULL;
}
+ list[count] = NULL;
*handles = list;
list = NULL;
cleanup:
+ free(handle);
k5_plugin_free_modules(context, modules);
k5_pwqual_free_handles(context, list);
return ret;
}
-krb5_error_code
+void
k5_pwqual_free_handles(krb5_context context, pwqual_handle *handles)
{
- /* It's the caller's responsibility to close each handle, so all of the
- * module data should be freed by now, leaving only the list itself. */
+ pwqual_handle *hp, handle;
+
+ if (handles == NULL)
+ return;
+ for (hp = handles; *hp != NULL; hp++) {
+ handle = *hp;
+ if (handle->vt.close != NULL)
+ handle->vt.close(context, handle->data);
+ }
free(handles);
}
krb5_error_code
-k5_pwqual_open(krb5_context context, pwqual_handle handle,
- const char *dict_file)
-{
- if (handle->data != NULL)
- return EINVAL;
- if (handle->vt.open == NULL)
- return 0;
- return handle->vt.open(context, dict_file, &handle->data);
-}
-
-krb5_error_code
k5_pwqual_check(krb5_context context, pwqual_handle handle,
- const char *password, kadm5_policy_ent_t policy,
+ const char *password, const char *policy_name,
krb5_principal princ)
{
- return handle->vt.check(context, handle->data, password, policy, princ);
+ return handle->vt.check(context, handle->data, password, policy_name,
+ princ);
}
-
-void
-k5_pwqual_close(krb5_context context, pwqual_handle handle)
-{
- if (handle->vt.close)
- handle->vt.close(context, handle->data);
- handle->data = NULL;
-}
Modified: branches/plugins2/src/lib/kadm5/srv/pwqual_dict.c
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/pwqual_dict.c 2010-08-28 20:20:14 UTC (rev 24265)
+++ branches/plugins2/src/lib/kadm5/srv/pwqual_dict.c 2010-08-28 22:39:40 UTC (rev 24266)
@@ -1,16 +1,38 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
+ * lib/kadm5/srv/pwqual_dict.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * Dictionary initialization and lookup code is (see top-level NOTICE file for
+ * license):
+ *
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header$
+ *
+ * Password quality module to look up passwords within the realm dictionary.
*/
-/* Password quality module to look up paswords within the realm dictionary. */
-
-#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header$";
-#endif
-
#include "k5-platform.h"
#include <krb5/pwqual_plugin.h>
#include <sys/types.h>
@@ -191,15 +213,13 @@
* against the dictionary, as well as against principal components. */
static krb5_error_code
dict_check(krb5_context context, krb5_pwqual_moddata data,
- const char *password, kadm5_policy_ent_t policy,
+ const char *password, const char *policy_name,
krb5_principal princ)
{
dict_moddata dict = (dict_moddata)data;
- int i, n;
- char *cp;
/* Don't check the dictionary for principals with no password policy. */
- if (policy == NULL)
+ if (policy_name == NULL)
return 0;
/* Check against words in the dictionary if we successfully loaded one. */
@@ -208,16 +228,6 @@
word_compare) != NULL)
return KADM5_PASS_Q_DICT;
- /* Check against components of the principal. */
- n = krb5_princ_size(handle->context, princ);
- cp = krb5_princ_realm(handle->context, princ)->data;
- if (strcasecmp(cp, password) == 0)
- return KADM5_PASS_Q_DICT;
- for (i = 0; i < n; i++) {
- cp = krb5_princ_component(handle->context, princ, i)->data;
- if (strcasecmp(cp, password) == 0)
- return KADM5_PASS_Q_DICT;
- }
return 0;
}
Added: branches/plugins2/src/lib/kadm5/srv/pwqual_empty.c
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/pwqual_empty.c (rev 0)
+++ branches/plugins2/src/lib/kadm5/srv/pwqual_empty.c 2010-08-28 22:39:40 UTC (rev 24266)
@@ -0,0 +1,58 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/kadm5/srv/pwqual_empty.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Password quality module to reject empty passwords.
+ */
+
+#include "k5-platform.h"
+#include <krb5/pwqual_plugin.h>
+#include "server_internal.h"
+
+static krb5_error_code
+empty_check(krb5_context context, krb5_pwqual_moddata data,
+ const char *password, const char *policy_name,
+ krb5_principal princ)
+{
+ /* Unlike other built-in modules, this one operates even for principals
+ * with no password policy. */
+ if (*password == '\0')
+ return KADM5_PASS_Q_TOOSHORT;
+ return 0;
+}
+
+krb5_error_code
+pwqual_empty_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ krb5_pwqual_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (krb5_pwqual_vtable)vtable;
+ vt->check = empty_check;
+ return 0;
+}
Added: branches/plugins2/src/lib/kadm5/srv/pwqual_hesiod.c
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/pwqual_hesiod.c (rev 0)
+++ branches/plugins2/src/lib/kadm5/srv/pwqual_hesiod.c 2010-08-28 22:39:40 UTC (rev 24266)
@@ -0,0 +1,133 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/kadm5/srv/pwqual_hesiod.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Password quality module to check passwords against GECOS fields of Hesiod
+ * passwd information, if the tree is compiled with Hesiod support.
+ */
+
+#include "k5-platform.h"
+#include <krb5/pwqual_plugin.h>
+#include "server_internal.h"
+#include <ctype.h>
+
+#ifdef HESIOD
+#include <pwd.h>
+
+static char *
+reverse(char *str, char *newstr, size_t newstr_size)
+{
+ char *p, *q;
+ size_t i;
+
+ i = strlen(str);
+ if (i >= newstr_size)
+ i = newstr_size - 1;
+ p = str + i - 1;
+ q = newstr;
+ q[i] = '\0';
+ for (; i > 0; i--)
+ *q++ = *p--;
+
+ return newstr;
+}
+
+static int
+str_check_gecos(char *gecos, const char *pwstr)
+{
+ char *cp, *ncp, *tcp, revbuf[80];
+
+ for (cp = gecos; *cp; ) {
+ /* Skip past punctuation */
+ for (; *cp; cp++)
+ if (isalnum(*cp))
+ break;
+
+ /* Skip to the end of the word */
+ for (ncp = cp; *ncp; ncp++) {
+ if (!isalnum(*ncp) && *ncp != '\'')
+ break;
+ }
+
+ /* Delimit end of word */
+ if (*ncp)
+ *ncp++ = '\0';
+
+ /* Check word to see if it's the password */
+ if (*cp) {
+ if (!strcasecmp(pwstr, cp))
+ return 1;
+ tcp = reverse(cp, revbuf, sizeof(revbuf));
+ if (!strcasecmp(pwstr, tcp))
+ return 1;
+ cp = ncp;
+ } else
+ break;
+ }
+ return 0;
+}
+#endif /* HESIOD */
+
+static krb5_error_code
+hesiod_check(krb5_context context, krb5_pwqual_moddata data,
+ const char *password, const char *policy_name,
+ krb5_principal princ)
+{
+#ifdef HESIOD
+ extern struct passwd *hes_getpwnam();
+ struct passwd *ent;
+ int i, n;
+ const char *cp;
+
+ /* Don't check for principals with no password policy. */
+ if (policy_name == NULL)
+ return 0;
+
+ n = krb5_princ_size(handle->context, princ);
+ for (i = 0; i < n; i++) {
+ cp = krb5_princ_component(handle->context, princ, i)->data;
+ if (strcasecmp(cp, password) == 0)
+ return KADM5_PASS_Q_DICT;
+ ent = hes_getpwnam(cp);
+ if (ent && ent->pw_gecos && str_check_gecos(ent->pw_gecos, password))
+ return KADM5_PASS_Q_DICT;
+ }
+#endif /* HESIOD */
+ return 0;
+}
+
+krb5_error_code
+pwqual_hesiod_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ krb5_pwqual_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (krb5_pwqual_vtable)vtable;
+ vt->check = hesiod_check;
+ return 0;
+}
Added: branches/plugins2/src/lib/kadm5/srv/pwqual_princ.c
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/pwqual_princ.c (rev 0)
+++ branches/plugins2/src/lib/kadm5/srv/pwqual_princ.c 2010-08-28 22:39:40 UTC (rev 24266)
@@ -0,0 +1,72 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/kadm5/srv/pwqual_princ.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Password quality module to check passwords against principal components.
+ */
+
+#include "k5-platform.h"
+#include <krb5/pwqual_plugin.h>
+#include "server_internal.h"
+
+static krb5_error_code
+princ_check(krb5_context context, krb5_pwqual_moddata data,
+ const char *password, const char *policy_name,
+ krb5_principal princ)
+{
+ int i, n;
+ char *cp;
+
+ /* Don't check for principals with no password policy. */
+ if (policy_name == NULL)
+ return 0;
+
+ /* Check against components of the principal. */
+ n = krb5_princ_size(handle->context, princ);
+ cp = krb5_princ_realm(handle->context, princ)->data;
+ if (strcasecmp(cp, password) == 0)
+ return KADM5_PASS_Q_DICT;
+ for (i = 0; i < n; i++) {
+ cp = krb5_princ_component(handle->context, princ, i)->data;
+ if (strcasecmp(cp, password) == 0)
+ return KADM5_PASS_Q_DICT;
+ }
+
+ return 0;
+}
+
+krb5_error_code
+pwqual_princ_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ krb5_pwqual_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (krb5_pwqual_vtable)vtable;
+ vt->check = princ_check;
+ return 0;
+}
Modified: branches/plugins2/src/lib/kadm5/srv/server_misc.c
===================================================================
--- branches/plugins2/src/lib/kadm5/srv/server_misc.c 2010-08-28 20:20:14 UTC (rev 24265)
+++ branches/plugins2/src/lib/kadm5/srv/server_misc.c 2010-08-28 22:39:40 UTC (rev 24266)
@@ -1,14 +1,34 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * check_against_policy code is originally (see top-level NOTICE file for
+ * license):
+ *
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header$
*/
-#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header$";
-#endif
-
#include "k5-int.h"
#include <kdb.h>
#include <ctype.h>
@@ -37,51 +57,86 @@
init_pwqual(kadm5_server_handle_t handle)
{
krb5_error_code ret;
- pwqual_handle *list, *h;
+ pwqual_handle *list;
const char *dict_file = NULL;
+ /* Register the built-in password quality modules. */
ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
"dict", pwqual_dict_initvt);
if (ret != 0)
return ret;
-
ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
- "policy", pwqual_policy_initvt);
+ "empty", pwqual_empty_initvt);
if (ret != 0)
return ret;
-
- ret = k5_pwqual_load(handle->context, &list);
+ ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
+ "hesiod", pwqual_hesiod_initvt);
if (ret != 0)
return ret;
+ ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
+ "princ", pwqual_princ_initvt);
+ if (ret != 0)
+ return ret;
+ /* Load all available password quality modules. */
if (handle->params.mask & KADM5_CONFIG_DICT_FILE)
dict_file = handle->params.dict_file;
+ ret = k5_pwqual_load(handle->context, &list, dict_file);
+ if (ret != 0)
+ return ret;
- for (h = list; *h != NULL; h++) {
- ret = k5_pwqual_open(handle->context, *h, dict_file);
- if (ret != 0) {
- /* Close any previously opened modules and error out. */
- for (; h > list; h--)
- k5_pwqual_close(handle->context, *(h - 1));
- k5_pwqual_free_handles(handle->context, list);
- return ret;
- }
- }
-
handle->qual_handles = list;
return 0;
}
-/* Check a password against all available password quality plugin modules. */
+/* Check that a password meets the quality constraints given in pol. */
+static kadm5_ret_t
+check_against_policy(kadm5_server_handle_t handle, const char *password,
+ kadm5_policy_ent_t pol)
+{
+ int hasupper = 0, haslower = 0, hasdigit = 0, haspunct = 0, hasspec = 0;
+ int c, nclasses;
+
+ /* Check against the policy's minimum length. */
+ if (strlen(password) < (size_t)pol->pw_min_length)
+ return KADM5_PASS_Q_TOOSHORT;
+
+ /* Check against the policy's minimum number of character classes. */
+ while ((c = (unsigned char)*password++) != '\0') {
+ if (islower(c))
+ haslower = 1;
+ else if (isupper(c))
+ hasupper = 1;
+ else if (isdigit(c))
+ hasdigit = 1;
+ else if (ispunct(c))
+ haspunct = 1;
+ else
+ hasspec = 1;
+ }
+ nclasses = hasupper + haslower + hasdigit + haspunct + hasspec;
+ if (nclasses < pol->pw_min_classes)
+ return KADM5_PASS_Q_CLASS;
+ return KADM5_OK;
+}
+
+/* Check a password against all available password quality plugin modules
+ * and against policy. */
kadm5_ret_t
passwd_check(kadm5_server_handle_t handle, const char *password,
kadm5_policy_ent_t policy, krb5_principal princ)
{
krb5_error_code ret;
pwqual_handle *h;
+ const char *polname = (policy == NULL) ? NULL : policy->policy;
+ if (policy != NULL) {
+ ret = check_against_policy(handle, password, policy);
+ if (ret != 0)
+ return ret;
+ }
for (h = handle->qual_handles; *h != NULL; h++) {
- ret = k5_pwqual_check(handle->context, *h, password, policy, princ);
+ ret = k5_pwqual_check(handle->context, *h, password, polname, princ);
if (ret != 0)
return ret;
}
@@ -91,10 +146,6 @@
void
destroy_pwqual(kadm5_server_handle_t handle)
{
- pwqual_handle *h;
-
- for (h = handle->qual_handles; *h != NULL; h++)
- k5_pwqual_close(handle->context, *h);
k5_pwqual_free_handles(handle->context, handle->qual_handles);
handle->qual_handles = NULL;
}
More information about the cvs-krb5
mailing list