From c81bb20711cd9abf833eb55c82d76885a65c44ea Mon Sep 17 00:00:00 2001 From: David Coutadeur Date: Wed, 24 Feb 2021 20:19:45 +0100 Subject: [PATCH] clean and homogenize ppm files for integration into contrib (issue #7832 !252) --- contrib/slapd-modules/ppm/INSTALL.md | 48 +++---- contrib/slapd-modules/ppm/Makefile | 80 +++++------ contrib/slapd-modules/ppm/NOTICES | 5 - contrib/slapd-modules/ppm/README.md | 128 ++++++++++++++---- contrib/slapd-modules/ppm/ppm.c | 4 +- .../ppm/{ppm.conf => ppm.example} | 33 ++++- contrib/slapd-modules/ppm/ppm.h | 2 +- contrib/slapd-modules/ppm/unit_tests.sh | 7 +- 8 files changed, 197 insertions(+), 110 deletions(-) delete mode 100644 contrib/slapd-modules/ppm/NOTICES rename contrib/slapd-modules/ppm/{ppm.conf => ppm.example} (62%) diff --git a/contrib/slapd-modules/ppm/INSTALL.md b/contrib/slapd-modules/ppm/INSTALL.md index 926335429f..c617478924 100644 --- a/contrib/slapd-modules/ppm/INSTALL.md +++ b/contrib/slapd-modules/ppm/INSTALL.md @@ -1,44 +1,46 @@ INSTALLATION ============ -Build dependencies +Dependencies ------------------ -OpenLDAP sources must be available. For an easier build, copy all ppm module -into contrib/slapd-modules OpenLDAP source directory. +ppm is provided along with OpenLDAP sources. By default, it is available into contrib/slapd-modules. + - make sure both OpenLDAP sources and ppm are available for building. + - install cracklib development files if you want to test passwords against cracklib + Build ----- -Be sure to have copied ppm module into contrib/slapd-modules OpenLDAP source -directory. - -Adapt the Makefile command to indicate: -OLDAP_SOURCES : should point to OpenLDAP source directory -CONFIG: where the ppm.conf example configuration file will finally stand +Enter contrib/slapd-modules/ppm directory + +You can optionally customize some variables if you don't want the default ones: +- prefix: prefix of the path where ppm is to be installed (default to /usr/local) +- libdir: where the ppm library is to be deployed (default to /lib under prefix) +- etcdir: where the ppm example policy is to be deployed (default to /etc/openldap under prefix) +- LDAP_SRC: path to OpenLDAP source directory +- Options in OPTS variable: + CONFIG_FILE: (DEPRECATED) path to a ppm configuration file (see PPM_READ_FILE in ppm.h) note: ppm configuration now lies into pwdCheckModuleArg password policy attribute - provided config file is only helpful as an example or for testing -LIBDIR: where the library will be installed -DEBUG: If defined, ppm logs its actions with syslog + provided example file is only helpful as an example or for testing + CRACKLIB: if defined, link against cracklib + DEBUG: If defined, ppm logs its actions with syslog -If necessary, you can also adapt some OpenLDAP source directories (if changed): -LDAP_INC : OpenLDAP headers directory -LDAP_LIBS : OpenLDAP built libraries directory -then type: +To build ppm, simply run these commands: +(based upon the default prefix /usr/local of OpenLDAP) ``` make clean -make CONFIG=/etc/openldap/ppm.conf OLDAP_SOURCES=../../.. +make make test -make install CONFIG=/etc/openldap/ppm.conf LIBDIR=/usr/lib/openldap +make install ``` - -For LTB build, use rather: +Here is an illustrative example showing how to overload some options: ``` make clean -make "CONFIG=/usr/local/openldap/etc/openldap/ppm.conf" "OLDAP_SOURCES=.." -make test -make install CONFIG=/usr/local/openldap/etc/openldap/ppm.conf LIBDIR=/usr/local/openldap/lib64 +make LDAP_SRC=../../.. prefix=/usr/local libdir=/usr/local/lib +make test LDAP_SRC=../../.. +make install prefix=/usr/local libdir=/usr/local/lib ``` diff --git a/contrib/slapd-modules/ppm/Makefile b/contrib/slapd-modules/ppm/Makefile index ac58210fc3..a5dfab4fee 100644 --- a/contrib/slapd-modules/ppm/Makefile +++ b/contrib/slapd-modules/ppm/Makefile @@ -2,66 +2,68 @@ # Copyright 2014 David Coutadeur, Paris. All Rights Reserved. # -CC=gcc +LDAP_SRC=../../.. +LDAP_BUILD=$(LDAP_SRC) +LDAP_INC=-I$(LDAP_SRC)/include \ + -I$(LDAP_SRC)/servers/slapd +LDAP_LIBS=-L$(LDAP_BUILD)/libraries/liblber/.libs \ + -L$(LDAP_BUILD)/libraries/libldap/.libs +LDAP_LIB=-lldap -llber +CRACK_LIB=-lcrack -# Path of OpenLDAP sources -OLDAP_SOURCES=../../.. -# Where the ppm configuration file should be installed -CONFIG=/etc/openldap/ppm.conf -# Path of OpenLDAP installed libs, where the ppm library should be installed -LIBDIR=/usr/lib/openldap +prefix=/usr/local +exec_prefix=$(prefix) +ldap_subdir=/openldap +libdir=$(exec_prefix)/lib +libexecdir=$(exec_prefix)/libexec +moduledir = $(libexecdir)$(ldap_subdir) +mandir = $(exec_prefix)/share/man +man5dir = $(mandir)/man5 +etcdir = $(exec_prefix)/etc$(ldap_subdir) + +CC=gcc +INSTALL = /usr/bin/install +PROGRAMS=ppm.so +TEST=ppm_test +EXAMPLE=ppm.example +TESTS=./unit_tests.sh OPT=-g -O2 -Wall -fpic \ - -DCONFIG_FILE="\"$(CONFIG)\"" \ + -DCONFIG_FILE="\"$(etcdir)/$(EXAMPLE)\"" \ + -DCRACKLIB \ -DDEBUG -# Where to find the OpenLDAP headers. - -LDAP_INC=-I$(OLDAP_SOURCES)/include \ - -I$(OLDAP_SOURCES)/servers/slapd - -# Where to find the OpenLDAP libraries. - -LDAP_LIBS=-L$(OLDAP_SOURCES)/libraries/liblber/.libs \ - -L$(OLDAP_SOURCES)/libraries/libldap/.libs +# don't link against cracklib if option -DCRACKLIB is not defined in OPT +ifeq (,$(findstring CRACKLIB,$(OPT))) + CRACK_LIB= +endif -CRACK_INC=-DCRACKLIB - -INCS=$(LDAP_INC) $(CRACK_INC) - -LDAP_LIB=-lldap -llber - -CRACK_LIB=-lcrack - -LIBS=$(LDAP_LIB) $(CRACK_LIB) - -TESTS=./unit_tests.sh -all: ppm ppm_test +all: ppm $(TEST) -ppm_test: - $(CC) -g $(LDAP_INC) $(LDAP_LIBS) -Wl,-rpath=. -o ppm_test ppm_test.c ppm.so $(LIBS) +$(TEST): + $(CC) -g $(LDAP_INC) $(LDAP_LIBS) -Wl,-rpath=. -o $(TEST) ppm_test.c $(PROGRAMS) $(LDAP_LIB) $(CRACK_LIB) ppm.o: - $(CC) $(OPT) -c $(INCS) ppm.c + $(CC) $(OPT) -c $(LDAP_INC) ppm.c ppm: ppm.o - $(CC) $(LDAP_INC) -shared -o ppm.so ppm.o $(CRACK_LIB) + $(CC) $(LDAP_INC) -shared -o $(PROGRAMS) ppm.o $(CRACK_LIB) install: ppm - cp -f ppm.so $(LIBDIR) - cp -f ppm_test $(LIBDIR) - cp -f ppm.conf $(CONFIG) + $(INSTALL) -m 644 $(PROGRAMS) $(libdir) + $(INSTALL) -m 755 $(TEST) $(libdir) + $(INSTALL) -m 644 $(EXAMPLE) $(etcdir)/ .PHONY: clean clean: - $(RM) -f ppm.o ppm.so ppm.lo ppm_test + $(RM) -f ppm.o $(PROGRAMS) ppm.lo $(TEST) $(RM) -rf .libs -test: ppm ppm_test - $(TESTS) +test: ppm $(TEST) + LDAP_SRC=$(LDAP_SRC) $(TESTS) diff --git a/contrib/slapd-modules/ppm/NOTICES b/contrib/slapd-modules/ppm/NOTICES deleted file mode 100644 index b1d4c572c2..0000000000 --- a/contrib/slapd-modules/ppm/NOTICES +++ /dev/null @@ -1,5 +0,0 @@ -The attached modifications to OpenLDAP Software are subject to the following notice: - -Copyright 2021 David Coutadeur -Redistribution and use in source and binary forms, with or without modification, are permitted only as authorized by the OpenLDAP Public License. - diff --git a/contrib/slapd-modules/ppm/README.md b/contrib/slapd-modules/ppm/README.md index 2464336585..9083a833fa 100644 --- a/contrib/slapd-modules/ppm/README.md +++ b/contrib/slapd-modules/ppm/README.md @@ -26,21 +26,25 @@ See INSTALL file USAGE ----- -Create a password policy entry and indicate the fresh compiled -library ppm.so: +Create a password policy entry and indicate the path of the ppm.so library +and the content of the desired policy. +Use a base64 tool to code / decode the content of the policy stored into +pwdCheckModuleArg. Here is an example: +``` dn: cn=default,ou=policies,dc=my-domain,dc=com objectClass: pwdPolicy +objectClass: top objectClass: pwdPolicyChecker objectClass: person -objectClass: top -cn: default -sn: default -pwdAttribute: userPassword pwdCheckQuality: 2 -... -pwdCheckModule: /path/to/new/ppm.so -pwdCheckModuleArg: [see configuration section] +pwdAttribute: userPassword +sn: default +cn: default +pwdMinLength: 6 +pwdCheckModule: /usr/local/lib/ppm.so +pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKZm9yYmlkZGVuQ2hhcnMKbWF4Q29uc2VjdXRpdmVQZXJDbGFzcyAwCnVzZUNyYWNrbGliIDAKY3JhY2tsaWJEaWN0IC92YXIvY2FjaGUvY3JhY2tsaWIvY3JhY2tsaWJfZGljdApjbGFzcy11cHBlckNhc2UgQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMCAxCmNsYXNzLWxvd2VyQ2FzZSBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiAwIDEKY2xhc3MtZGlnaXQgMDEyMzQ1Njc4OSAwIDEKY2xhc3Mtc3BlY2lhbCA8Piw/Oy46LyHCp8O5JSrCtV7CqCTCo8KyJsOpfiIjJ3soWy18w6hgX1zDp17DoEApXcKwPX0rIDAgMQ== +``` See slapo-ppolicy for more information, but to sum up: @@ -94,7 +98,7 @@ Configuration Since OpenLDAP 2.5 version, ppm configuration is held in a binary attribute of the password policy: pwdCheckModuleArg -The configuration file (/etc/openldap/ppm.conf by default) is to be +The example file (/etc/openldap/ppm.example by default) is to be considered as an example configuration, to import in the pwdCheckModuleArg attribute. It is also used for testing passwords with the test program provided. @@ -216,24 +220,88 @@ A more detailed message is written to the server log. Server log: ``` -Jul 27 20:09:14 machine slapd[20270]: ppm: Opening file /etc/openldap/ppm.conf -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null) -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted replaced value: 3 -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = forbiddenChars, value = , min = (null), minForPoint= (null) -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted replaced value: -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint= 5 -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint= 12 -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted replaced value: abcdefghijklmnopqrstuvwxyz -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint= 1 -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted replaced value: 0123456789 -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = class-special, value = <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+, min = 0, minForPoint= 1 -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted replaced value: <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ -Jul 27 20:09:14 machine slapd[20270]: ppm: Param = class-myClass, value = :), min = 1, minForPoint= 1 -Jul 27 20:09:14 machine slapd[20270]: ppm: Accepted new value: -Jul 27 20:09:14 machine slapd[20270]: ppm: 1 point granted for class class-upperCase -Jul 27 20:09:14 machine slapd[20270]: ppm: 1 point granted for class class-lowerCase -Jul 27 20:09:14 machine slapd[20270]: ppm: 1 point granted for class class-digit +Feb 26 14:46:10 debian-10-64 slapd[1981]: conn=1000 op=16 MOD dn="uid=user,ou=persons,dc=my-domain,dc=com" +Feb 26 14:46:10 debian-10-64 slapd[1981]: conn=1000 op=16 MOD attr=userPassword +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: entry uid=user,ou=persons,dc=my-domain,dc=com +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Reading pwdCheckModuleArg attribute +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: RAW configuration: # minQuality parameter#012# Format:#012# minQuality [NUMBER]#012# Description:#012# One point is granted for each class for which MIN_FOR_POINT criteria is fulfilled.#012# defines the minimum point numbers for the password to be accepted.#012minQuality 3#012#012# checkRDN parameter#012# Format:#012# checkRDN [0 | 1]#012# Description:#012# If set to 1, password must not contain a token from the RDN.#012# Tokens are separated by the following delimiters : space tabulation _ - , ; £#012checkRDN 0#012#012# forbiddenChars parameter#012# Format:#012# forbiddenChars [CHARACTERS_FORBIDDEN]#012# Description:#012# Defines the forbidden characters list (no separator).#012# If one of them is found in the password, then it is rejected.#012forbiddenChars#012#012# maxConsecutivePerClass parameter#012# Format:#012# maxConsecutivePerClass [NUMBER]#012# Description:#012# Defines the maximum number of consecutive character allowed for any class#012maxConsecutivePerClass 0#012#012# useCracklib parameter#012# Format:#012# useCracklib [0 | 1]#012# Description:#012# If set to 1, the password must pass the cracklib check#012useCracklib 0#012#012# cracklibDict parameter#012# Format:#012# cracklibDict [path_to_cracklib_dictionnary]#012# Description:#012# directory+filename-prefix that your version of CrackLib will go hunting for#012# For example, /var/pw_dict resolves as /var/pw_dict.pwd,#012# /var/pw_dict.pwi and /var/pw_dict.hwm dictionnary files#012cracklibDict /var/cache/cracklib/cracklib_dict#012#012# classes parameter#012# Format:#012# class-[CLASS_NAME] [CHARACTERS_DEFINING_CLASS] [MIN] [MIN_FOR_POINT]#012# Description:#012# [CHARACTERS_DEFINING_CLASS]: characters defining the class (no separator)#012# [MIN]: If at least [MIN] characters of this class is not found in the password, then it is rejected#012# [MIN_FOR_POINT]: one point is granted if password contains at least [MIN_FOR_POINT] character numbers of this class#012class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1#012class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1#012class-digit 0123456789 0 1#012class-special <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ 0 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Parsing pwdCheckModuleArg attribute +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # minQuality parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # minQuality [NUMBER] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # One point is granted for each class for which MIN_FOR_POINT criteria is fulfilled. +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # defines the minimum point numbers for the password to be accepted. +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: minQuality 3 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null) +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: 3 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # checkRDN parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # checkRDN [0 | 1] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # If set to 1, password must not contain a token from the RDN. +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Tokens are separated by the following delimiters : space tabulation _ - , ; £ +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: checkRDN 0 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = checkRDN, value = 0, min = (null), minForPoint= (null) +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: 0 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # forbiddenChars parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # forbiddenChars [CHARACTERS_FORBIDDEN] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Defines the forbidden characters list (no separator). +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # If one of them is found in the password, then it is rejected. +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: forbiddenChars +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: No value, goto next parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # maxConsecutivePerClass parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # maxConsecutivePerClass [NUMBER] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Defines the maximum number of consecutive character allowed for any class +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: maxConsecutivePerClass 0 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = maxConsecutivePerClass, value = 0, min = (null), minForPoint= (null) +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: 0 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # useCracklib parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # useCracklib [0 | 1] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # If set to 1, the password must pass the cracklib check +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: useCracklib 0 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = useCracklib, value = 0, min = (null), minForPoint= (null) +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: 0 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # cracklibDict parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # cracklibDict [path_to_cracklib_dictionnary] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # directory+filename-prefix that your version of CrackLib will go hunting for +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # For example, /var/pw_dict resolves as /var/pw_dict.pwd, +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # /var/pw_dict.pwi and /var/pw_dict.hwm dictionnary files +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: cracklibDict /var/cache/cracklib/cracklib_dict +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = cracklibDict, value = /var/cache/cracklib/cracklib_dict, min = (null), minForPoint= (null) +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: /var/cache/cracklib/cracklib_dict +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # classes parameter +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Format: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # class-[CLASS_NAME] [CHARACTERS_DEFINING_CLASS] [MIN] [MIN_FOR_POINT] +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # Description: +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # [CHARACTERS_DEFINING_CLASS]: characters defining the class (no separator) +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # [MIN]: If at least [MIN] characters of this class is not found in the password, then it is rejected +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: # [MIN_FOR_POINT]: one point is granted if password contains at least [MIN_FOR_POINT] character numbers of this class +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint= 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint= 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: abcdefghijklmnopqrstuvwxyz +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: class-digit 0123456789 0 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint= 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: 0123456789 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: get line: class-special <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ 0 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Param = class-special, value = <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+, min = 0, minForPoint= 1 +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Accepted replaced value: <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: 1 point granted for class class-lowerCase +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: 1 point granted for class class-digit +Feb 26 14:46:10 debian-10-64 slapd[1981]: ppm: Reallocating szErrStr from 64 to 173 +Feb 26 14:46:10 debian-10-64 slapd[1981]: check_password_quality: module error: (/usr/local/lib/ppm.so) Password for dn="uid=user,ou=persons,dc=my-domain,dc=com" does not pass required number of strength checks (2 of 3).[1] +Feb 26 14:46:10 debian-10-64 slapd[1981]: conn=1000 op=16 RESULT tag=103 err=19 qtime=0.000020 etime=0.001496 text=Password for dn="uid=user,ou=persons,dc=my-domain,dc=com" does not pass required number of strength checks (2 of 3) ``` @@ -244,8 +312,8 @@ There is a unit test script: "unit_tests.sh" that illustrates checking some pass It is possible to test one particular password using directly the test program: ``` -cd /usr/local/openldap/lib64 -LD_LIBRARY_PATH=. ./ppm_test "uid=test,ou=users,dc=my-domain,dc=com" "my_password" "/usr/local/openldap/etc/openldap/ppm.conf" && echo OK +cd /usr/local/lib +LD_LIBRARY_PATH=. ./ppm_test "uid=test,ou=users,dc=my-domain,dc=com" "my_password" "/usr/local/etc/openldap/ppm.example" && echo OK ``` diff --git a/contrib/slapd-modules/ppm/ppm.c b/contrib/slapd-modules/ppm/ppm.c index a4422e4749..7c4a54c227 100644 --- a/contrib/slapd-modules/ppm/ppm.c +++ b/contrib/slapd-modules/ppm/ppm.c @@ -190,7 +190,7 @@ typeParam(char* param) if (reti) { ppm_log(LOG_ERR, "ppm: Cannot compile regex: %s", allowedParameters[i].param); - exit(EXIT_FAILURE); + return n; } // Execute regular expression @@ -403,7 +403,7 @@ containsRDN(char* passwd, char* DN) reti = regcomp(®ex, token, REG_ICASE); if (reti) { ppm_log(LOG_ERR, "ppm: Cannot compile regex: %s", token); - exit(EXIT_FAILURE); + return 0; } // Execute regular expression diff --git a/contrib/slapd-modules/ppm/ppm.conf b/contrib/slapd-modules/ppm/ppm.example similarity index 62% rename from contrib/slapd-modules/ppm/ppm.conf rename to contrib/slapd-modules/ppm/ppm.example index 23993bcf65..9e30e72932 100644 --- a/contrib/slapd-modules/ppm/ppm.conf +++ b/contrib/slapd-modules/ppm/ppm.example @@ -1,3 +1,29 @@ +# Example of ppm configuration + +# Such configuration must be stored into pwdCheckModuleArg attribute +# of a password policy entry +# See slapo-ppolicy for more details +# Here is an example of such password policy: +# dn: cn=default,ou=policies,dc=my-domain,dc=com +# objectClass: pwdPolicy +# objectClass: top +# objectClass: pwdPolicyChecker +# objectClass: person +# pwdCheckQuality: 2 +# pwdAttribute: userPassword +# sn: default +# cn: default +# pwdMinLength: 6 +# pwdCheckModule: /usr/local/lib/ppm.so +# pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKZm9yYmlkZGVuQ2hhcnMKbWF4Q29uc2VjdXRpdmVQZXJDbGFzcyAwCnVzZUNyYWNrbGliIDAKY3JhY2tsaWJEaWN0IC92YXIvY2FjaGUvY3JhY2tsaWIvY3JhY2tsaWJfZGljdApjbGFzcy11cHBlckNhc2UgQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMCAxCmNsYXNzLWxvd2VyQ2FzZSBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiAwIDEKY2xhc3MtZGlnaXQgMDEyMzQ1Njc4OSAwIDEKY2xhc3Mtc3BlY2lhbCA8Piw/Oy46LyHCp8O5JSrCtV7CqCTCo8KyJsOpfiIjJ3soWy18w6hgX1zDp17DoEApXcKwPX0rIDAgMQ== +# +# Different parameters are separated by a linefeed (\n) +# Parameters starting with a # are ignored +# Use a base64 tool to code / decode the content of pwdCheckModuleArg + + + +# Parameters # minQuality parameter # Format: @@ -7,13 +33,6 @@ # defines the minimum point numbers for the password to be accepted. minQuality 3 -# maxLength parameter -# Format: -# maxLength [NUMBER] -# Description: -# The password must not be more than [NUMBER] long. 0 means no limit is set. -maxLength 0 - # checkRDN parameter # Format: # checkRDN [0 | 1] diff --git a/contrib/slapd-modules/ppm/ppm.h b/contrib/slapd-modules/ppm/ppm.h index b9931cbf77..25b360d974 100644 --- a/contrib/slapd-modules/ppm/ppm.h +++ b/contrib/slapd-modules/ppm/ppm.h @@ -25,7 +25,7 @@ /* config file parameters (DEPRECATED) */ #ifndef CONFIG_FILE -#define CONFIG_FILE "/etc/openldap/ppm.conf" +#define CONFIG_FILE "/etc/openldap/ppm.example" #endif #define FILENAME_MAX_LEN 512 diff --git a/contrib/slapd-modules/ppm/unit_tests.sh b/contrib/slapd-modules/ppm/unit_tests.sh index 80d66e0a36..c152c968e7 100755 --- a/contrib/slapd-modules/ppm/unit_tests.sh +++ b/contrib/slapd-modules/ppm/unit_tests.sh @@ -4,11 +4,12 @@ # -CONFIG_FILE="ppm.conf" +CONFIG_FILE="ppm.example" -OLDAP_SOURCES="../../.." +LDAP_SRC="${LDAP_SRC:-../../..}" +LDAP_BUILD=${LDAP_BUILD:-${LDAP_SRC}} CURRENT_DIR=$( dirname $0 ) -LIB_PATH="${LD_LIBRARY_PATH}:${CURRENT_DIR}:${OLDAP_SOURCES}/libraries/liblber/.libs:${OLDAP_SOURCES}/libraries/libldap/.libs" +LIB_PATH="${LD_LIBRARY_PATH}:${CURRENT_DIR}:${LDAP_BUILD}/libraries/liblber/.libs:${LDAP_BUILD}/libraries/libldap/.libs" RED='\033[0;31m' GREEN='\033[0;32m' -- 2.47.3