6fe3bd37d9
Not complete yet. Missing ltb-project-openldap-ppolicy
776 lines
21 KiB
Diff
776 lines
21 KiB
Diff
From 26002bd1d02d871e3c0526f3a0b7b99e25f3564c Mon Sep 17 00:00:00 2001
|
|
From: babak sarashki <babak.sarashki@windriver.com>
|
|
Date: Tue, 5 Nov 2019 18:02:38 -0800
|
|
Subject: [PATCH] ltb project openldap ppolicy check password 1.1
|
|
|
|
From stx 1901 openldap src RPM 2.4.44
|
|
Upstream at https://github.com/ltb-project/openldap-ppolicy-check-password.git
|
|
---
|
|
.../INSTALL | 31 ++
|
|
.../LICENSE | 50 ++
|
|
.../Makefile | 48 ++
|
|
.../README | 146 ++++++
|
|
.../check_password.c | 447 ++++++++++++++++++
|
|
5 files changed, 722 insertions(+)
|
|
create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/INSTALL
|
|
create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/LICENSE
|
|
create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/Makefile
|
|
create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/README
|
|
create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/check_password.c
|
|
|
|
diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/INSTALL b/ltb-project-openldap-ppolicy-check-password-1.1/INSTALL
|
|
new file mode 100644
|
|
index 0000000..eb2dab4
|
|
--- /dev/null
|
|
+++ b/ltb-project-openldap-ppolicy-check-password-1.1/INSTALL
|
|
@@ -0,0 +1,31 @@
|
|
+INSTALLATION
|
|
+============
|
|
+
|
|
+Build dependencies
|
|
+------------------
|
|
+cracklib header files (link with -lcrack). The Makefile does not look for
|
|
+cracklib; you may need to provide the paths manually.
|
|
+
|
|
+Build
|
|
+-----
|
|
+Use the provided Makefile to build the module.
|
|
+
|
|
+Copy the resulting check_password.so into the OpenLDAP modulepath.
|
|
+
|
|
+Or, change the installation path to match with the OpenLDAP module path in the
|
|
+Makefile and use 'make install'.
|
|
+
|
|
+
|
|
+USAGE
|
|
+=====
|
|
+Add objectClass 'pwdPolicyChecker' with an attribute
|
|
+
|
|
+ pwdCheckModule: check_password.so
|
|
+
|
|
+to a password policy entry.
|
|
+
|
|
+The module depends on a working cracklib installation including wordlist files.
|
|
+If the wordlist files are not readable, the cracklib check will be skipped
|
|
+silently.
|
|
+
|
|
+But you can use this module without cracklib, just checks for syntatic checks.
|
|
diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/LICENSE b/ltb-project-openldap-ppolicy-check-password-1.1/LICENSE
|
|
new file mode 100644
|
|
index 0000000..03f692b
|
|
--- /dev/null
|
|
+++ b/ltb-project-openldap-ppolicy-check-password-1.1/LICENSE
|
|
@@ -0,0 +1,50 @@
|
|
+OpenLDAP Public License
|
|
+
|
|
+The OpenLDAP Public License
|
|
+ Version 2.8.1, 25 November 2003
|
|
+
|
|
+Redistribution and use of this software and associated documentation
|
|
+("Software"), with or without modification, are permitted provided
|
|
+that the following conditions are met:
|
|
+
|
|
+1. Redistributions in source form must retain copyright statements
|
|
+ and notices,
|
|
+
|
|
+2. Redistributions in binary form must reproduce applicable copyright
|
|
+ statements and notices, this list of conditions, and the following
|
|
+ disclaimer in the documentation and/or other materials provided
|
|
+ with the distribution, and
|
|
+
|
|
+3. Redistributions must contain a verbatim copy of this document.
|
|
+
|
|
+The OpenLDAP Foundation may revise this license from time to time.
|
|
+Each revision is distinguished by a version number. You may use
|
|
+this Software under terms of this license revision or under the
|
|
+terms of any subsequent revision of the license.
|
|
+
|
|
+THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
|
|
+CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
+SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
|
|
+OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
+POSSIBILITY OF SUCH DAMAGE.
|
|
+
|
|
+The names of the authors and copyright holders must not be used in
|
|
+advertising or otherwise to promote the sale, use or other dealing
|
|
+in this Software without specific, written prior permission. Title
|
|
+to copyright in this Software shall at all times remain with copyright
|
|
+holders.
|
|
+
|
|
+OpenLDAP is a registered trademark of the OpenLDAP Foundation.
|
|
+
|
|
+Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
|
|
+California, USA. All rights reserved. Permission to copy and
|
|
+distribute verbatim copies of this document is granted.
|
|
+
|
|
diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/Makefile b/ltb-project-openldap-ppolicy-check-password-1.1/Makefile
|
|
new file mode 100644
|
|
index 0000000..91de40b
|
|
--- /dev/null
|
|
+++ b/ltb-project-openldap-ppolicy-check-password-1.1/Makefile
|
|
@@ -0,0 +1,48 @@
|
|
+# contrib/slapd-modules/check_password/Makefile
|
|
+# Copyright 2007 Michael Steinmann, Calivia. All Rights Reserved.
|
|
+# Updated by Pierre-Yves Bonnetain, B&A Consultants, 2008
|
|
+#
|
|
+
|
|
+CC=gcc
|
|
+
|
|
+# Where to look for the CrackLib dictionaries
|
|
+#
|
|
+CRACKLIB=/usr/share/cracklib/pw_dict
|
|
+
|
|
+# Path to the configuration file
|
|
+#
|
|
+CONFIG=/etc/openldap/check_password.conf
|
|
+
|
|
+CFLAGS+=-fpic \
|
|
+ -DHAVE_CRACKLIB -DCRACKLIB_DICTPATH="\"$(CRACKLIB)\"" \
|
|
+ -DCONFIG_FILE="\"$(CONFIG)\"" \
|
|
+ -DDEBUG
|
|
+
|
|
+LDAP_LIB=-lldap_r -llber
|
|
+
|
|
+# Comment out this line if you do NOT want to use the cracklib.
|
|
+# You may have to add an -Ldirectory if the libcrak is not in a standard
|
|
+# location
|
|
+#
|
|
+CRACKLIB_LIB=-lcrack
|
|
+
|
|
+LIBS=$(LDAP_LIB) $(CRACKLIB_LIB)
|
|
+
|
|
+LIBDIR=/usr/lib/openldap/
|
|
+
|
|
+
|
|
+all: check_password
|
|
+
|
|
+check_password.o:
|
|
+ $(CC) $(CFLAGS) -c $(LDAP_INC) check_password.c
|
|
+
|
|
+check_password: clean check_password.o
|
|
+ $(CC) $(LDFLAGS) -shared -o check_password.so check_password.o $(CRACKLIB_LIB)
|
|
+
|
|
+install: check_password
|
|
+ cp -f check_password.so ../../../usr/lib/openldap/modules/
|
|
+
|
|
+clean:
|
|
+ $(RM) check_password.o check_password.so check_password.lo
|
|
+ $(RM) -r .libs
|
|
+
|
|
diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/README b/ltb-project-openldap-ppolicy-check-password-1.1/README
|
|
new file mode 100644
|
|
index 0000000..10191c2
|
|
--- /dev/null
|
|
+++ b/ltb-project-openldap-ppolicy-check-password-1.1/README
|
|
@@ -0,0 +1,146 @@
|
|
+
|
|
+check_password.c - OpenLDAP pwdChecker library
|
|
+
|
|
+2007-06-06 Michael Steinmann <msl@calivia.com>
|
|
+2008-01-30 Pierre-Yves Bonnetain <py.bonnetain@ba-cst.com>
|
|
+2009 Clement Oudot <clem.oudot@gmail.com> - LTB-project
|
|
+2009 Jerome HUET - LTB-project
|
|
+
|
|
+check_password.c is an OpenLDAP pwdPolicyChecker module used to check the
|
|
+strength and quality of user-provided passwords.
|
|
+
|
|
+This module is used as an extension of the OpenLDAP password policy controls,
|
|
+see slapo-ppolicy(5) section pwdCheckModule.
|
|
+
|
|
+check_password.c will run a number of checks on the passwords to ensure minimum
|
|
+strength and quality requirements are met. Passwords that do not meet these
|
|
+requirements are rejected.
|
|
+
|
|
+
|
|
+Password checks
|
|
+---------------
|
|
+ - passwords shorter than 6 characters are rejected if cracklib is used (because
|
|
+ cracklib WILL reject them).
|
|
+
|
|
+ - syntactic checks controls how many different character classes are used
|
|
+ (lower, upper, digit and punctuation characters). The minimum number of
|
|
+ classes is defined in a configuration file. You can set the minimum for each
|
|
+ class.
|
|
+
|
|
+ - passwords are checked against cracklib if cracklib is enabled at compile
|
|
+ time. It can be disabled in configuration file.
|
|
+
|
|
+INSTALLATION
|
|
+------------
|
|
+Use the provided Makefile to build the module.
|
|
+
|
|
+Compilation constants :
|
|
+
|
|
+CONFIG_FILE : Path to the configuration file.
|
|
+ Defaults to /etc/openldap/check_password.conf
|
|
+
|
|
+DEBUG : If defined, check_password will syslog() its actions.
|
|
+
|
|
+Build dependencies
|
|
+cracklib header files (link with -lcrack). The Makefile does not look for
|
|
+cracklib; you may need to provide the paths manually.
|
|
+
|
|
+Install into the slapd server module path. Change the installation
|
|
+path to match with the OpenLDAP module path in the Makefile.
|
|
+
|
|
+The module may be defined with slapd.conf parameter "modulepath".
|
|
+
|
|
+USAGE
|
|
+-----
|
|
+To use this module you need to add objectClass pwdPolicyChecker with an
|
|
+attribute 'pwdCheckModule: check_password.so' to a password policy entry.
|
|
+
|
|
+The module depends on a working cracklib installation including wordlist files.
|
|
+If the wordlist files are not readable, the cracklib check will be skipped
|
|
+silently.
|
|
+
|
|
+Note: pwdPolicyChecker modules are loaded on *every* password change operation.
|
|
+
|
|
+Configuration
|
|
+-------------
|
|
+The configuration file (/etc/openldap/check_password.conf by default) contains
|
|
+parameters for the module. If the file is not found, parameters are given their
|
|
+default value.
|
|
+
|
|
+The syntax of the file is :
|
|
+
|
|
+parameter value
|
|
+
|
|
+with spaces being delimiters. Parameter names ARE case sensitive (this may
|
|
+change in the future).
|
|
+
|
|
+Current parameters :
|
|
+
|
|
+- useCracklib: integer. Default value: 1. Set it to 0 to disable cracklib verification.
|
|
+ It has no effect if cracklib is not included at compile time.
|
|
+
|
|
+- minPoints: integer. Default value: 3. Minimum number of quality points a new
|
|
+ password must have to be accepted. One quality point is awarded for each character
|
|
+ class used in the password.
|
|
+
|
|
+- minUpper: integer. Defaut value: 0. Minimum upper characters expected.
|
|
+
|
|
+- minLower: integer. Defaut value: 0. Minimum lower characters expected.
|
|
+
|
|
+- minDigit: integer. Defaut value: 0. Minimum digit characters expected.
|
|
+
|
|
+- minPunct: integer. Defaut value: 0. Minimum punctuation characters expected.
|
|
+
|
|
+Logs
|
|
+----
|
|
+If a user password is rejected by an OpenLDAP pwdChecker module, the user will
|
|
+*not* get a detailed error message, this is by design.
|
|
+
|
|
+Typical user message from ldappasswd(5):
|
|
+ Result: Constraint violation (19)
|
|
+ Additional info: Password fails quality checking policy
|
|
+
|
|
+A more detailed message is written to the server log.
|
|
+
|
|
+Server log:
|
|
+ check_password_quality: module error: (check_password.so)
|
|
+ Password for dn=".." does not pass required number of strength checks (2 of 3)
|
|
+
|
|
+
|
|
+Caveats
|
|
+-------
|
|
+Runtime errors with this module (such as cracklib configuration problems) may
|
|
+bring down the slapd process.
|
|
+
|
|
+Use at your own risk.
|
|
+
|
|
+
|
|
+TODO
|
|
+----
|
|
+* use proper malloc function, see ITS#4998
|
|
+
|
|
+
|
|
+HISTORY
|
|
+-------
|
|
+* 2009-10-30 Clement OUDOT - LTB-project
|
|
+ Version 1.1
|
|
+ - Apply patch from Jerome HUET for minUpper/minLower/minDigit/minPunct
|
|
+
|
|
+* 2009-02-05 Clement Oudot <clem.oudot@gmail.com> - LINAGORA Group
|
|
+ Version 1.0.3
|
|
+ - Add useCracklib parameter in config file (with help of Pascal Pejac)
|
|
+ - Prefix log messages with "check_password: "
|
|
+ - Log what character type is found for quality checking
|
|
+
|
|
+* 2008-01-31 Pierre-Yves Bonnetain <py.bonnetain@ba-cst.com>
|
|
+ Version 1.0.2
|
|
+ - Several bug fixes.
|
|
+ - Add external config file
|
|
+
|
|
+* 2007-06-06 Michael Steinmann <msl@calivia.com>
|
|
+ Version 1.0.1
|
|
+ - add dn to error messages
|
|
+
|
|
+* 2007-06-02 Michael Steinmann <msl@calivia.com>
|
|
+ Version 1.0
|
|
+
|
|
diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/check_password.c b/ltb-project-openldap-ppolicy-check-password-1.1/check_password.c
|
|
new file mode 100644
|
|
index 0000000..f4dd1cb
|
|
--- /dev/null
|
|
+++ b/ltb-project-openldap-ppolicy-check-password-1.1/check_password.c
|
|
@@ -0,0 +1,447 @@
|
|
+/*
|
|
+ * check_password.c for OpenLDAP
|
|
+ *
|
|
+ * See LICENSE, README and INSTALL files
|
|
+ */
|
|
+
|
|
+#include <string.h>
|
|
+#include <ctype.h>
|
|
+#include <portable.h>
|
|
+#include <slap.h>
|
|
+
|
|
+#ifdef HAVE_CRACKLIB
|
|
+#include <crack.h>
|
|
+#endif
|
|
+
|
|
+#if defined(DEBUG)
|
|
+#include <syslog.h>
|
|
+#endif
|
|
+
|
|
+#ifndef CRACKLIB_DICTPATH
|
|
+#define CRACKLIB_DICTPATH "/usr/share/cracklib/pw_dict"
|
|
+#endif
|
|
+
|
|
+#ifndef CONFIG_FILE
|
|
+#define CONFIG_FILE "/etc/openldap/check_password.conf"
|
|
+#endif
|
|
+
|
|
+#define DEFAULT_QUALITY 3
|
|
+#define DEFAULT_CRACKLIB 1
|
|
+#define MEMORY_MARGIN 50
|
|
+#define MEM_INIT_SZ 64
|
|
+#define FILENAME_MAXLEN 512
|
|
+
|
|
+#define PASSWORD_TOO_SHORT_SZ \
|
|
+ "Password for dn=\"%s\" is too short (%d/6)"
|
|
+#define PASSWORD_QUALITY_SZ \
|
|
+ "Password for dn=\"%s\" does not pass required number of strength checks for the required character sets (%d of %d)"
|
|
+#define BAD_PASSWORD_SZ \
|
|
+ "Bad password for dn=\"%s\" because %s"
|
|
+#define UNKNOWN_ERROR_SZ \
|
|
+ "An unknown error occurred, please see your systems administrator"
|
|
+
|
|
+typedef int (*validator) (char*);
|
|
+static int read_config_file ();
|
|
+static validator valid_word (char *);
|
|
+static int set_quality (char *);
|
|
+static int set_cracklib (char *);
|
|
+
|
|
+int check_password (char *pPasswd, char **ppErrStr, Entry *pEntry);
|
|
+
|
|
+struct config_entry {
|
|
+ char* key;
|
|
+ char* value;
|
|
+ char* def_value;
|
|
+} config_entries[] = { { "minPoints", NULL, "3"},
|
|
+ { "useCracklib", NULL, "1"},
|
|
+ { "minUpper", NULL, "0"},
|
|
+ { "minLower", NULL, "0"},
|
|
+ { "minDigit", NULL, "0"},
|
|
+ { "minPunct", NULL, "0"},
|
|
+ { NULL, NULL, NULL }};
|
|
+
|
|
+int get_config_entry_int(char* entry) {
|
|
+ struct config_entry* centry = config_entries;
|
|
+
|
|
+ int i = 0;
|
|
+ char* key = centry[i].key;
|
|
+ while (key != NULL) {
|
|
+ if ( strncmp(key, entry, strlen(key)) == 0 ) {
|
|
+ if ( centry[i].value == NULL ) {
|
|
+ return atoi(centry[i].def_value);
|
|
+ }
|
|
+ else {
|
|
+ return atoi(centry[i].value);
|
|
+ }
|
|
+ }
|
|
+ i++;
|
|
+ key = centry[i].key;
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+void dealloc_config_entries() {
|
|
+ struct config_entry* centry = config_entries;
|
|
+
|
|
+ int i = 0;
|
|
+ while (centry[i].key != NULL) {
|
|
+ if ( centry[i].value != NULL ) {
|
|
+ ber_memfree(centry[i].value);
|
|
+ }
|
|
+ i++;
|
|
+ }
|
|
+}
|
|
+
|
|
+char* chomp(char *s)
|
|
+{
|
|
+ char* t = ber_memalloc(strlen(s)+1);
|
|
+ strncpy (t,s,strlen(s)+1);
|
|
+
|
|
+ if ( t[strlen(t)-1] == '\n' ) {
|
|
+ t[strlen(t)-1] = '\0';
|
|
+ }
|
|
+
|
|
+ return t;
|
|
+}
|
|
+
|
|
+static int set_quality (char *value)
|
|
+{
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_INFO, "check_password: Setting quality to [%s]", value);
|
|
+#endif
|
|
+
|
|
+ /* No need to require more quality than we can check for. */
|
|
+ if (!isdigit(*value) || (int) (value[0] - '0') > 4) return DEFAULT_QUALITY;
|
|
+ return (int) (value[0] - '0');
|
|
+
|
|
+}
|
|
+
|
|
+static int set_cracklib (char *value)
|
|
+{
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_INFO, "check_password: Setting cracklib usage to [%s]", value);
|
|
+#endif
|
|
+
|
|
+
|
|
+ return (int) (value[0] - '0');
|
|
+
|
|
+}
|
|
+
|
|
+static int set_digit (char *value)
|
|
+{
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_INFO, "check_password: Setting parameter to [%s]", value);
|
|
+#endif
|
|
+ if (!isdigit(*value) || (int) (value[0] - '0') > 9) return 0;
|
|
+ return (int) (value[0] - '0');
|
|
+}
|
|
+
|
|
+static validator valid_word (char *word)
|
|
+{
|
|
+ struct {
|
|
+ char * parameter;
|
|
+ validator dealer;
|
|
+ } list[] = { { "minPoints", set_quality },
|
|
+ { "useCracklib", set_cracklib },
|
|
+ { "minUpper", set_digit },
|
|
+ { "minLower", set_digit },
|
|
+ { "minDigit", set_digit },
|
|
+ { "minPunct", set_digit },
|
|
+ { NULL, NULL } };
|
|
+ int index = 0;
|
|
+
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Validating parameter [%s]", word);
|
|
+#endif
|
|
+
|
|
+ while (list[index].parameter != NULL) {
|
|
+ if (strlen(word) == strlen(list[index].parameter) &&
|
|
+ strcmp(list[index].parameter, word) == 0) {
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Parameter accepted.");
|
|
+#endif
|
|
+ return list[index].dealer;
|
|
+ }
|
|
+ index++;
|
|
+ }
|
|
+
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Parameter rejected.");
|
|
+#endif
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static int read_config_file ()
|
|
+{
|
|
+ FILE * config;
|
|
+ char * line;
|
|
+ int returnValue = -1;
|
|
+
|
|
+ line = ber_memcalloc(260, sizeof(char));
|
|
+
|
|
+ if ( line == NULL ) {
|
|
+ return returnValue;
|
|
+ }
|
|
+
|
|
+ if ( (config = fopen(CONFIG_FILE, "r")) == NULL) {
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_ERR, "check_password: Opening file %s failed", CONFIG_FILE);
|
|
+#endif
|
|
+
|
|
+ ber_memfree(line);
|
|
+ return returnValue;
|
|
+ }
|
|
+
|
|
+ returnValue = 0;
|
|
+
|
|
+ while (fgets(line, 256, config) != NULL) {
|
|
+ char *start = line;
|
|
+ char *word, *value;
|
|
+ validator dealer;
|
|
+
|
|
+#if defined(DEBUG)
|
|
+ /* Debug traces to syslog. */
|
|
+ syslog(LOG_DEBUG, "check_password: Got line |%s|", line);
|
|
+#endif
|
|
+
|
|
+ while (isspace(*start) && isascii(*start)) start++;
|
|
+
|
|
+ /* If we've got punctuation, just skip the line. */
|
|
+ if ( ispunct(*start)) {
|
|
+#if defined(DEBUG)
|
|
+ /* Debug traces to syslog. */
|
|
+ syslog(LOG_DEBUG, "check_password: Skipped line |%s|", line);
|
|
+#endif
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if( isascii(*start)) {
|
|
+
|
|
+ struct config_entry* centry = config_entries;
|
|
+ int i = 0;
|
|
+ char* keyWord = centry[i].key;
|
|
+ if ((word = strtok(start, " \t")) && (value = strtok(NULL, " \t"))) {
|
|
+ while ( keyWord != NULL ) {
|
|
+ if ((strncmp(keyWord,word,strlen(keyWord)) == 0) && (dealer = valid_word(word)) ) {
|
|
+
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Word = %s, value = %s", word, value);
|
|
+#endif
|
|
+
|
|
+ centry[i].value = chomp(value);
|
|
+ break;
|
|
+ }
|
|
+ i++;
|
|
+ keyWord = centry[i].key;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ fclose(config);
|
|
+ ber_memfree(line);
|
|
+
|
|
+ return returnValue;
|
|
+}
|
|
+
|
|
+static int realloc_error_message (char ** target, int curlen, int nextlen)
|
|
+{
|
|
+ if (curlen < nextlen + MEMORY_MARGIN) {
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_WARNING, "check_password: Reallocating szErrStr from %d to %d",
|
|
+ curlen, nextlen + MEMORY_MARGIN);
|
|
+#endif
|
|
+ ber_memfree(*target);
|
|
+ curlen = nextlen + MEMORY_MARGIN;
|
|
+ *target = (char *) ber_memalloc(curlen);
|
|
+ }
|
|
+
|
|
+ return curlen;
|
|
+}
|
|
+
|
|
+int
|
|
+check_password (char *pPasswd, char **ppErrStr, Entry *pEntry)
|
|
+{
|
|
+
|
|
+ char *szErrStr = (char *) ber_memalloc(MEM_INIT_SZ);
|
|
+ int mem_len = MEM_INIT_SZ;
|
|
+
|
|
+ int nLen;
|
|
+ int nLower = 0;
|
|
+ int nUpper = 0;
|
|
+ int nDigit = 0;
|
|
+ int nPunct = 0;
|
|
+ int minLower = 0;
|
|
+ int minUpper = 0;
|
|
+ int minDigit = 0;
|
|
+ int minPunct = 0;
|
|
+ int nQuality = 0;
|
|
+ int i;
|
|
+
|
|
+ /* Set a sensible default to keep original behaviour. */
|
|
+ int minQuality = DEFAULT_QUALITY;
|
|
+ int useCracklib = DEFAULT_CRACKLIB;
|
|
+
|
|
+ /** bail out early as cracklib will reject passwords shorter
|
|
+ * than 6 characters
|
|
+ */
|
|
+
|
|
+ nLen = strlen (pPasswd);
|
|
+ if ( nLen < 6) {
|
|
+ mem_len = realloc_error_message(&szErrStr, mem_len,
|
|
+ strlen(PASSWORD_TOO_SHORT_SZ) +
|
|
+ strlen(pEntry->e_name.bv_val) + 1);
|
|
+ sprintf (szErrStr, PASSWORD_TOO_SHORT_SZ, pEntry->e_name.bv_val, nLen);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if (read_config_file() == -1) {
|
|
+ syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE);
|
|
+ }
|
|
+
|
|
+ minQuality = get_config_entry_int("minPoints");
|
|
+ useCracklib = get_config_entry_int("useCracklib");
|
|
+ minUpper = get_config_entry_int("minUpper");
|
|
+ minLower = get_config_entry_int("minLower");
|
|
+ minDigit = get_config_entry_int("minDigit");
|
|
+ minPunct = get_config_entry_int("minPunct");
|
|
+
|
|
+ /** The password must have at least minQuality strength points with one
|
|
+ * point for the first occurrance of a lower, upper, digit and
|
|
+ * punctuation character
|
|
+ */
|
|
+
|
|
+ for ( i = 0; i < nLen; i++ ) {
|
|
+
|
|
+ if ( islower (pPasswd[i]) ) {
|
|
+ minLower--;
|
|
+ if ( !nLower && (minLower < 1)) {
|
|
+ nLower = 1; nQuality++;
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Found lower character - quality raise %d", nQuality);
|
|
+#endif
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if ( isupper (pPasswd[i]) ) {
|
|
+ minUpper--;
|
|
+ if ( !nUpper && (minUpper < 1)) {
|
|
+ nUpper = 1; nQuality++;
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Found upper character - quality raise %d", nQuality);
|
|
+#endif
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if ( isdigit (pPasswd[i]) ) {
|
|
+ minDigit--;
|
|
+ if ( !nDigit && (minDigit < 1)) {
|
|
+ nDigit = 1; nQuality++;
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Found digit character - quality raise %d", nQuality);
|
|
+#endif
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if ( ispunct (pPasswd[i]) ) {
|
|
+ minPunct--;
|
|
+ if ( !nPunct && (minPunct < 1)) {
|
|
+ nPunct = 1; nQuality++;
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_DEBUG, "check_password: Found punctuation character - quality raise %d", nQuality);
|
|
+#endif
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * If you have a required field, then it should be required in the strength
|
|
+ * checks.
|
|
+ */
|
|
+
|
|
+ if (
|
|
+ (minLower > 0 ) ||
|
|
+ (minUpper > 0 ) ||
|
|
+ (minDigit > 0 ) ||
|
|
+ (minPunct > 0 ) ||
|
|
+ (nQuality < minQuality)
|
|
+ ) {
|
|
+ mem_len = realloc_error_message(&szErrStr, mem_len,
|
|
+ strlen(PASSWORD_QUALITY_SZ) +
|
|
+ strlen(pEntry->e_name.bv_val) + 2);
|
|
+ sprintf (szErrStr, PASSWORD_QUALITY_SZ, pEntry->e_name.bv_val,
|
|
+ nQuality, minQuality);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+#ifdef HAVE_CRACKLIB
|
|
+
|
|
+ /** Check password with cracklib */
|
|
+
|
|
+ if ( useCracklib > 0 ) {
|
|
+ int j = 0;
|
|
+ FILE* fp;
|
|
+ char filename[FILENAME_MAXLEN];
|
|
+ char const* ext[] = { "hwm", "pwd", "pwi" };
|
|
+ int nErr = 0;
|
|
+
|
|
+ /**
|
|
+ * Silently fail when cracklib wordlist is not found
|
|
+ */
|
|
+
|
|
+ for ( j = 0; j < 3; j++ ) {
|
|
+
|
|
+ snprintf (filename, FILENAME_MAXLEN - 1, "%s.%s", \
|
|
+ CRACKLIB_DICTPATH, ext[j]);
|
|
+
|
|
+ if (( fp = fopen ( filename, "r")) == NULL ) {
|
|
+
|
|
+ nErr = 1;
|
|
+ break;
|
|
+
|
|
+ } else {
|
|
+
|
|
+ fclose (fp);
|
|
+
|
|
+ }
|
|
+ }
|
|
+
|
|
+ char *r;
|
|
+ if ( nErr == 0) {
|
|
+
|
|
+ r = (char *) FascistCheck (pPasswd, CRACKLIB_DICTPATH);
|
|
+ if ( r != NULL ) {
|
|
+ mem_len = realloc_error_message(&szErrStr, mem_len,
|
|
+ strlen(BAD_PASSWORD_SZ) +
|
|
+ strlen(pEntry->e_name.bv_val) +
|
|
+ strlen(r));
|
|
+ sprintf (szErrStr, BAD_PASSWORD_SZ, pEntry->e_name.bv_val, r);
|
|
+ goto fail;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ else {
|
|
+#if defined(DEBUG)
|
|
+ syslog(LOG_NOTICE, "check_password: Cracklib verification disabled by configuration");
|
|
+#endif
|
|
+ }
|
|
+
|
|
+#endif
|
|
+ dealloc_config_entries();
|
|
+ *ppErrStr = strdup ("");
|
|
+ ber_memfree(szErrStr);
|
|
+ return (LDAP_SUCCESS);
|
|
+
|
|
+fail:
|
|
+ dealloc_config_entries();
|
|
+ *ppErrStr = strdup (szErrStr);
|
|
+ ber_memfree(szErrStr);
|
|
+ return (EXIT_FAILURE);
|
|
+
|
|
+}
|
|
--
|
|
2.17.1
|
|
|