mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-22 06:43:17 -05:00
353 lines
13 KiB
Groff
353 lines
13 KiB
Groff
.\" Automatically generated by Pandoc 2.9.2.1
|
|
.\"
|
|
.TH "ppm" "5" "August 24, 2021" "ppm" "File Formats Manual"
|
|
.hy
|
|
.SH NAME
|
|
.PP
|
|
ppm (Password Policy Module) - extension of the password policy overlay
|
|
.SH SYNOPSIS
|
|
.PP
|
|
ETCDIR/ppm.example
|
|
.SH DESCRIPTION
|
|
.PP
|
|
\f[B]ppm\f[R] is an OpenLDAP module for checking password quality when
|
|
they are modified.
|
|
Passwords are checked against the presence or absence of certain
|
|
character classes.
|
|
.PP
|
|
This module is used as an extension of the OpenLDAP password policy
|
|
controls, see slapo-ppolicy(5) section \f[B]pwdCheckModule\f[R].
|
|
.SH USAGE
|
|
.PP
|
|
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
|
|
\f[B]pwdCheckModuleArg\f[R].
|
|
.PP
|
|
Here is an example for OpenLDAP 2.6:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
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
|
|
pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKY2hlY2tBdHRyaWJ1dGVzCmZvcmJpZGRlbkNoYXJzCm1heENvbnNlY3V0aXZlUGVyQ2xhc3MgMAp1c2VDcmFja2xpYiAwCmNyYWNrbGliRGljdCAvdmFyL2NhY2hlL2NyYWNrbGliL2NyYWNrbGliX2RpY3QKY2xhc3MtdXBwZXJDYXNlIEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIDAgMSAwCmNsYXNzLWxvd2VyQ2FzZSBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiAwIDEgMApjbGFzcy1kaWdpdCAwMTIzNDU2Nzg5IDAgMSAwCmNsYXNzLXNwZWNpYWwgPD4sPzsuOi8hwqfDuSUqwrVewqgkwqPCsibDqX4iIyd7KFstfMOoYF9cw6dew6BAKV3CsD19KyAwIDEgMAoK
|
|
pwdUseCheckModule: TRUE
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
For OpenLDAP 2.5, you must add a \f[B]pwdCheckModule\f[R] attribute
|
|
pointing to the ppm module (for example /usr/local/lib/ppm.so), and
|
|
remove the \f[B]pwdUseCheckModule\f[R] attribute.
|
|
.PP
|
|
See \f[B]slapo-ppolicy\f[R] for more information, but to sum up:
|
|
.IP \[bu] 2
|
|
enable ppolicy overlay in your database.
|
|
.IP \[bu] 2
|
|
define a default password policy in OpenLDAP configuration or use
|
|
pwdPolicySubentry attribute to point to the given policy.
|
|
.PP
|
|
This example show the activation for a \f[B]slapd.conf\f[R] file for
|
|
OpenLDAP 2.6 (see \f[B]slapd-config\f[R] and \f[B]slapo-ppolicy\f[R] for
|
|
more information for \f[B]cn=config\f[R] configuration)
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
overlay ppolicy
|
|
ppolicy_default \[dq]cn=default,ou=policies,dc=my-domain,dc=com\[dq]
|
|
ppolicy_check_module /usr/local/openldap/libexec/openldap/ppm.so
|
|
#ppolicy_use_lockout # for having more infos about the lockout
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
For OpenLDAP 2.5, you must remove \f[B]ppolicy_check_module\f[R]
|
|
parameter as it is managed in the password policy definition
|
|
.SH FEATURES
|
|
.PP
|
|
Here are the main features:
|
|
.IP \[bu] 2
|
|
4 character classes are defined by default: upper case, lower case,
|
|
digits and special characters.
|
|
.IP \[bu] 2
|
|
more character classes can be defined, just write your own.
|
|
.IP \[bu] 2
|
|
passwords must match the amount of quality points.
|
|
A point is validated when at least m characters of the corresponding
|
|
character class are present in the password.
|
|
.IP \[bu] 2
|
|
passwords must have at least n of the corresponding character class
|
|
present, else they are rejected.
|
|
.IP \[bu] 2
|
|
passwords must have at the most x occurrences of characters from the
|
|
corresponding character class, else they are rejected.
|
|
.IP \[bu] 2
|
|
the three previous criteria are checked against any specific character
|
|
class defined.
|
|
.IP \[bu] 2
|
|
if a password contains any of the forbidden characters, then it is
|
|
rejected.
|
|
.IP \[bu] 2
|
|
if a password contains tokens from the RDN, then it is rejected.
|
|
.IP \[bu] 2
|
|
if a password contains tokens from defined attributes, then it is
|
|
rejected.
|
|
.IP \[bu] 2
|
|
if a password does not pass cracklib check, then it is rejected.
|
|
.SH CONFIGURATION
|
|
.PP
|
|
Since OpenLDAP 2.5 version, ppm configuration is held in a binary
|
|
attribute of the password policy: \f[B]pwdCheckModuleArg\f[R]
|
|
.PP
|
|
The example file (\f[B]/usr/local/etc/openldap/ppm.example\f[R] by default) is to be
|
|
considered as an example configuration, to import in the
|
|
\f[B]pwdCheckModuleArg\f[R] attribute.
|
|
It is also used for testing passwords with the test program provided.
|
|
.PP
|
|
If for some reasons, any parameter is not found, it will be given its
|
|
default value.
|
|
.PP
|
|
Note: you can still compile ppm to use the configuration file, by
|
|
enabling \f[B]PPM_READ_FILE\f[R] in \f[B]ppm.h\f[R] (but this is
|
|
deprecated now).
|
|
If you decide to do so, you can use the \f[B]PPM_CONFIG_FILE\f[R]
|
|
environment variable for overloading the configuration file path.
|
|
.PP
|
|
The syntax of a configuration line is:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
parameter value [min] [minForPoint] [max]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
with spaces being delimiters and Line Feed (LF) ending the line.
|
|
.PP
|
|
Parameter names \f[B]are\f[R] case sensitive.
|
|
.PP
|
|
Lines beginning by a \f[B]#\f[R] are considered as comments.
|
|
.PP
|
|
The default configuration is the following:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# minQuality parameter
|
|
# Format:
|
|
# minQuality [NUMBER]
|
|
# Description:
|
|
# One point is granted for each class for which MIN_FOR_POINT criteria is fulfilled.
|
|
# defines the minimum point numbers for the password to be accepted.
|
|
minQuality 3
|
|
|
|
# checkRDN parameter
|
|
# Format:
|
|
# checkRDN [0 | 1]
|
|
# Description:
|
|
# If set to 1, password must not contain a token from the RDN.
|
|
# Tokens are separated by the following delimiters : space tabulation _ - , ; \[Po]
|
|
checkRDN 0
|
|
|
|
# checkAttributes parameter
|
|
# Format:
|
|
# checkAttributes [ATTR1,ATTR2,...]
|
|
# Description:
|
|
# Password must not contain a token from the values in the given list of attributes
|
|
# Tokens are substrings of the values of the given attributes,
|
|
# delimited by: space tabulation _ - , ; \[at]
|
|
# For example, if uid=\[dq]the wonderful entry\[dq],
|
|
# password must not contain \[dq]the\[dq], nor \[dq]wonderful\[dq], nor \[dq]entry\[dq]
|
|
checkAttributes
|
|
|
|
# forbiddenChars parameter
|
|
# Format:
|
|
# forbiddenChars [CHARACTERS_FORBIDDEN]
|
|
# Description:
|
|
# Defines the forbidden characters list (no separator).
|
|
# If one of them is found in the password, then it is rejected.
|
|
forbiddenChars
|
|
|
|
# maxConsecutivePerClass parameter
|
|
# Format:
|
|
# maxConsecutivePerClass [NUMBER]
|
|
# Description:
|
|
# Defines the maximum number of consecutive character allowed for any class
|
|
maxConsecutivePerClass 0
|
|
|
|
# useCracklib parameter
|
|
# Format:
|
|
# useCracklib [0 | 1]
|
|
# Description:
|
|
# If set to 1, the password must pass the cracklib check
|
|
useCracklib 0
|
|
|
|
# cracklibDict parameter
|
|
# Format:
|
|
# cracklibDict [path_to_cracklib_dictionary]
|
|
# Description:
|
|
# directory+filename-prefix that your version of CrackLib will go hunting for
|
|
# For example, /var/pw_dict resolves as /var/pw_dict.pwd,
|
|
# /var/pw_dict.pwi and /var/pw_dict.hwm dictionary files
|
|
cracklibDict /var/cache/cracklib/cracklib_dict
|
|
|
|
# classes parameter
|
|
# Format:
|
|
# class-[CLASS_NAME] [CHARACTERS_DEFINING_CLASS] [MIN] [MIN_FOR_POINT] [MAX]
|
|
# Description:
|
|
# [CHARACTERS_DEFINING_CLASS]: characters defining the class (no separator)
|
|
# [MIN]: If at least [MIN] characters of this class is not found in the password, then it is rejected
|
|
# [MIN_FOR_POINT]: one point is granted if password contains at least [MIN_FOR_POINT] character numbers of this class
|
|
# [MAX]: if > [MAX] occurrences of characters from this class are found, then the password is rejected (0 means no maximum)
|
|
class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1 0
|
|
class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1 0
|
|
class-digit 0123456789 0 1 0
|
|
class-special <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+ 0 1 0
|
|
\f[R]
|
|
.fi
|
|
.SH EXAMPLE
|
|
.PP
|
|
With this policy:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
minQuality 4
|
|
forbiddenChars .?,
|
|
checkRDN 1
|
|
checkAttributes mail
|
|
class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 5 0
|
|
class-lowerCase abcdefghijklmnopqrstuvwxyz 0 12 0
|
|
class-digit 0123456789 0 1 0
|
|
class-special <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+ 0 1 0
|
|
class-myClass :) 1 1 0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
the password \f[B]ThereIsNoCowLevel)\f[R] is working, because:
|
|
.IP \[bu] 2
|
|
it has 4 character classes validated : upper, lower, special, and
|
|
myClass
|
|
.IP \[bu] 2
|
|
it has no character among .?,
|
|
.IP \[bu] 2
|
|
it has at least one character among : or )
|
|
.PP
|
|
but it won\[cq]t work for the user uid=John
|
|
Cowlevel,ou=people,cn=example,cn=com, because the token
|
|
\[lq]Cowlevel\[rq] from his RDN exists in the password (case
|
|
insensitive).
|
|
.PP
|
|
Also, it won\[cq]t work for a mail attribute containing:
|
|
\[lq]thereis\[at]domain.com\[rq] because the part \[lq]thereis\[rq]
|
|
matches the password.
|
|
.SH LOGS
|
|
.PP
|
|
If a user password is rejected by \f[B]ppm\f[R], the user will get this
|
|
type of message:
|
|
.PP
|
|
Typical user message from ldappasswd(5):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Result: Constraint violation (19)
|
|
Additional info: Password for dn=\[rs]\[dq]%s\[rs]\[dq] does not pass required number of strength checks (2 of 3)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
A more detailed message is written to the server log.
|
|
.PP
|
|
While evaluating a password change, you should observe something looking
|
|
at this in the logs:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
ppm: entry uid=jack.oneill,ou=people,dc=my-domain,dc=com
|
|
ppm: Reading pwdCheckModuleArg attribute
|
|
ppm: RAW configuration: minQuality 3#012checkRDN 0#012checkAttributes mail,uid#012forbiddenChars#012maxConsecutivePerClass 0#012useCracklib 0#012cracklibDict /var/cache/cracklib/cracklib_dict#012class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1 0#012class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1 0#012class-digit 0123456789 0 1 0#012class-special <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+ 0 1 0
|
|
ppm: Parsing pwdCheckModuleArg attribute
|
|
ppm: get line: minQuality 3
|
|
ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null)
|
|
ppm: Accepted replaced value: 3
|
|
ppm: get line: checkRDN 0
|
|
ppm: Param = checkRDN, value = 0, min = (null), minForPoint= (null)
|
|
ppm: Accepted replaced value: 0
|
|
ppm: get line: checkAttributes mail,uid
|
|
ppm: Param = checkAttributes, value = mail,uid, min = (null), minForPoint= (null)
|
|
ppm: Accepted replaced value: mail,uid
|
|
ppm: get line: forbiddenChars
|
|
ppm: No value, goto next parameter
|
|
ppm: get line: maxConsecutivePerClass 0
|
|
ppm: Param = maxConsecutivePerClass, value = 0, min = (null), minForPoint= (null)
|
|
ppm: Accepted replaced value: 0
|
|
ppm: get line: useCracklib 0
|
|
ppm: Param = useCracklib, value = 0, min = (null), minForPoint= (null)
|
|
ppm: Accepted replaced value: 0
|
|
ppm: get line: cracklibDict /var/cache/cracklib/cracklib_dict
|
|
ppm: Param = cracklibDict, value = /var/cache/cracklib/cracklib_dict, min = (null), minForPoint= (null)
|
|
ppm: Accepted replaced value: /var/cache/cracklib/cracklib_dict
|
|
ppm: get line: class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1 0
|
|
ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint = 1, max = 0
|
|
ppm: Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
ppm: get line: class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1 0
|
|
ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint = 1, max = 0
|
|
ppm: Accepted replaced value: abcdefghijklmnopqrstuvwxyz
|
|
ppm: get line: class-digit 0123456789 0 1 0
|
|
ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint = 1, max = 0
|
|
ppm: Accepted replaced value: 0123456789
|
|
ppm: get line: class-special <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+ 0 1 0
|
|
ppm: Param = class-special, value = <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+, min = 0, minForPoint = 1, max = 0
|
|
ppm: Accepted replaced value: <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+
|
|
ppm: 1 point granted for class class-upperCase
|
|
ppm: 1 point granted for class class-lowerCase
|
|
ppm: Reallocating szErrStr from 64 to 179
|
|
check_password_quality: module error: (/usr/local/openldap/libexec/openldap/ppm.so) Password for dn=\[dq]uid=jack.oneill,ou=people,dc=my-domain,dc=com\[dq] does not pass required number of strength checks (2 of 3).[1]
|
|
\f[R]
|
|
.fi
|
|
.SH TESTS
|
|
.PP
|
|
There is a unit test script: \f[B]unit_tests.sh\f[R] that illustrates
|
|
checking some passwords.
|
|
.PP
|
|
It is possible to test one particular password using directly the test
|
|
program:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cd /usr/local/lib
|
|
LD_LIBRARY_PATH=. ./ppm_test \[dq]uid=test,ou=users,dc=my-domain,dc=com\[dq] \[dq]my_password\[dq] \[dq]/usr/local/etc/openldap/ppm.example\[dq] && echo OK
|
|
\f[R]
|
|
.fi
|
|
.SH FILES
|
|
.PP
|
|
\f[B]/usr/local/etc/openldap/ppm.example\f[R]
|
|
.RS
|
|
.PP
|
|
example of ppm configuration to be inserted in
|
|
\f[B]pwdCheckModuleArg\f[R] attribute of given password policy
|
|
.RE
|
|
.PP
|
|
\f[B]ppm.so\f[R]
|
|
.RS
|
|
.PP
|
|
ppm library, loaded by the \f[B]pwdCheckModule\f[R] attribute of given
|
|
password policy (OpenLDAP 2.5) or by the \f[B]ppolicy_check_module\f[R]
|
|
/ \f[B]olcPPolicyCheckModule\f[R] parameters of the ppolicy overlay
|
|
(OpenLDAP 2.6)
|
|
.RE
|
|
.PP
|
|
\f[B]ppm_test\f[R]
|
|
.RS
|
|
.PP
|
|
small test program for checking password in a command-line
|
|
.RE
|
|
.SH SEE ALSO
|
|
.PP
|
|
\f[B]slapo-ppolicy\f[R](5), \f[B]slapd-config\f[R](5),
|
|
\f[B]slapd.conf\f[R](5)
|
|
.SH ACKNOWLEDGEMENTS
|
|
.PP
|
|
This module was developed in 2014-2022 by David Coutadeur.
|