]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
upgrade ppm to 2.1 release (references #ITS9814)
authorDavid Coutadeur <david.coutadeur@gmail.com>
Tue, 22 Mar 2022 18:15:37 +0000 (19:15 +0100)
committerDavid Coutadeur <david.coutadeur@gmail.com>
Tue, 22 Mar 2022 18:15:37 +0000 (19:15 +0100)
Reject password if it contains tokens from an attribute of the LDAP entry https://github.com/ltb-project/ppm/issues/17

contrib/slapd-modules/ppm/CHANGELOG.md
contrib/slapd-modules/ppm/ppm.c
contrib/slapd-modules/ppm/ppm.example
contrib/slapd-modules/ppm/ppm.h
contrib/slapd-modules/ppm/ppm.md
contrib/slapd-modules/ppm/slapm-ppm.5

index d0e4ed732b2ef137c345b3cdac8f0b04c99ba105..4ccb34fc4cbb163703ff2986c057c1406df726eb 100644 (file)
@@ -1,5 +1,8 @@
 # CHANGELOG
 
+* 2022-03-22 David Coutadeur <david.coutadeur@gmail.com>
+  Reject password if it contains tokens from an attribute of the LDAP entry #17 
+  Version 2.1
 * 2021-02-23 David Coutadeur <david.coutadeur@gmail.com>
   remove maxLength attribute (#21)
   adapt the readme and documentation of ppm (#22)
index 6d6013214a40efd61ef08aaa1b355386ac8f3ff5..ded597b4368f3c3b0a516ed8fa4d5f247e38db12 100644 (file)
@@ -427,6 +427,88 @@ containsRDN(char* passwd, char* DN)
     return 0;
 }
 
+// Does the password contains a token from an attribute?
+int
+containsAttributes(char* passwd, Entry* pEntry, char* checkAttributes)
+{
+    char checkAttrs[VALUE_MAX_LEN];
+    char val[VALUE_MAX_LEN];
+    char * token;
+    char * tk;
+    Attribute *a;
+    int i;
+    regex_t regex;
+    int reti;
+
+    // Parse all attributes in the LDAP entry
+    for ( a = pEntry->e_attrs; a != NULL; a = a->a_next ) {
+
+        // Parse all attributes in checkAttributes parameter
+        strcpy_safe(checkAttrs, checkAttributes, VALUE_MAX_LEN);
+        token = strtok(checkAttrs, ",\0");
+        while (token != NULL)
+        {
+            // if attribute to check is found in LDAP entry
+            if( strcmp(a->a_desc->ad_cname.bv_val, token) == 0 )
+            {
+                ppm_log(LOG_NOTICE, "ppm: check password against %s attribute", token);
+                // parse attribute values
+                for ( i = 0; a->a_vals[i].bv_val != NULL; i++ )
+                {
+                    strcpy_safe(val, a->a_vals[i].bv_val, VALUE_MAX_LEN);
+                    ppm_log(LOG_NOTICE,
+                            "ppm: check password against %s attribute value",
+                            a->a_vals[i].bv_val);
+                    
+                    // Search for each token in the attribute
+                    tk = strtok(val, ATTR_TOKENS_DELIMITERS);
+
+                    while (tk != NULL)
+                    {
+                        if (strlen(tk) > 2)
+                        {
+                            ppm_log(LOG_NOTICE,
+                                    "ppm: Checking if %s part of value %s of attribute %s matches the password",
+                                    tk,
+                                    a->a_vals[i].bv_val,
+                                    a->a_desc->ad_cname.bv_val);
+                            // Compile regular expression 
+                            reti = regcomp(&regex, tk, REG_ICASE);
+                            if (reti) {
+                              ppm_log(LOG_ERR, "ppm: Cannot compile regex: %s", tk);
+                              return 0;
+                            }
+
+                            // Execute regular expression: does password
+                            // contains the token extracted from the attr value?
+                            reti = regexec(&regex, passwd, 0, NULL, 0);
+                            if (!reti)
+                            { 
+                              regfree(&regex);
+                              return 1;
+                            }
+        
+                            regfree(&regex);
+                          }
+                          else
+                          { 
+                            ppm_log(LOG_NOTICE,
+                                    "ppm: %s part of value %s of attribute %s is too short to be checked",
+                                    tk,
+                                    a->a_vals[i].bv_val,
+                                    a->a_desc->ad_cname.bv_val);
+                          }
+                          tk = strtok(NULL, ATTR_TOKENS_DELIMITERS);
+                        }
+                }
+            }
+            token = strtok(NULL, ",\0");
+        }
+    }
+    return 0;
+}
+
 
 int
 check_password(char *pPasswd, struct berval *ppErrmsg, Entry *e, void *pArg)
@@ -447,6 +529,7 @@ check_password(char *pPasswd, struct berval *ppErrmsg, Entry *e, void *pArg)
     char* res;
     int minQuality;
     int checkRDN;
+    char checkAttributes[VALUE_MAX_LEN];
     char forbiddenChars[VALUE_MAX_LEN];
     int nForbiddenChars = 0;
     int nQuality = 0;
@@ -516,8 +599,11 @@ check_password(char *pPasswd, struct berval *ppErrmsg, Entry *e, void *pArg)
         {"class-special", typeStr,
          {.sVal = "<>,?;.:/!§ù%*µ^¨$£²&é~\"#'{([-|è`_\\ç^à@)]°=}+"}, 0, 1
          }
+        ,
+        {"checkAttributes", typeStr, {.sVal = ""}, 0, 0
+         }
     };
-    numParam = 10;
+    numParam = 11;
 
     #ifdef PPM_READ_FILE
       /* Read configuration file (DEPRECATED) */
@@ -537,6 +623,9 @@ check_password(char *pPasswd, struct berval *ppErrmsg, Entry *e, void *pArg)
     strcpy_safe(cracklibDict,
                 getValue(fileConf, numParam, "cracklibDict")->sVal,
                 VALUE_MAX_LEN);
+    strcpy_safe(checkAttributes,
+                getValue(fileConf, numParam, "checkAttributes")->sVal,
+                VALUE_MAX_LEN);
 
 
     /*The password must have at least minQuality strength points with one
@@ -674,6 +763,18 @@ check_password(char *pPasswd, struct berval *ppErrmsg, Entry *e, void *pArg)
         goto fail;
     }
 
+    // Password checking done, now looking for checkAttributes criteria
+    if (containsAttributes(pPasswd, pEntry, checkAttributes))
+    // A token from an attribute is found in password: goto fail
+    {
+        mem_len = realloc_error_message(origmsg, &szErrStr, mem_len,
+                                        strlen(ATTR_TOKEN_FOUND) +
+                                        strlen(pEntry->e_nname.bv_val));
+        sprintf(szErrStr, ATTR_TOKEN_FOUND, pEntry->e_nname.bv_val);
+
+        goto fail;
+    }
+
     szErrStr[0] = '\0';
     return (LDAP_SUCCESS);
 
index 10cf132091939daa1c9ff67cb4a57a001924e543..a0cb321396add55461d2f92dada1a262c2e56d6a 100644 (file)
@@ -15,7 +15,7 @@
 #   cn: default
 #   pwdMinLength: 6
 #   pwdCheckModule: /usr/local/lib/ppm.so
-#   pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKZm9yYmlkZGVuQ2hhcnMKbWF4Q29uc2VjdXRpdmVQZXJDbGFzcyAwCnVzZUNyYWNrbGliIDAKY3JhY2tsaWJEaWN0IC92YXIvY2FjaGUvY3JhY2tsaWIvY3JhY2tsaWJfZGljdApjbGFzcy11cHBlckNhc2UgQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMCAxCmNsYXNzLWxvd2VyQ2FzZSBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiAwIDEKY2xhc3MtZGlnaXQgMDEyMzQ1Njc4OSAwIDEKY2xhc3Mtc3BlY2lhbCA8Piw/Oy46LyHCp8O5JSrCtV7CqCTCo8KyJsOpfiIjJ3soWy18w6hgX1zDp17DoEApXcKwPX0rIDAgMQ==
+#   pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKY2hlY2tBdHRyaWJ1dGVzCmZvcmJpZGRlbkNoYXJzCm1heENvbnNlY3V0aXZlUGVyQ2xhc3MgMAp1c2VDcmFja2xpYiAwCmNyYWNrbGliRGljdCAvdmFyL2NhY2hlL2NyYWNrbGliL2NyYWNrbGliX2RpY3QKY2xhc3MtdXBwZXJDYXNlIEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIDAgMQpjbGFzcy1sb3dlckNhc2UgYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogMCAxCmNsYXNzLWRpZ2l0IDAxMjM0NTY3ODkgMCAxCmNsYXNzLXNwZWNpYWwgPD4sPzsuOi8hwqfDuSUqwrVewqgkwqPCsibDqX4iIyd7KFstfMOoYF9cw6dew6BAKV3CsD19KyAwIDEK
 #
 # Different parameters are separated by a linefeed (\n)
 # Parameters starting with a # are ignored
@@ -41,6 +41,17 @@ minQuality 3
 # Tokens are separated by these delimiters : space tabulation _ - , ; £
 checkRDN 0
 
+# checkAttributes parameter
+# Format:
+# checkRDN [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 _ - , ; @
+# For example, if uid="the wonderful entry",
+# password must not contain "the", nor "wonderful", nor "entry"
+checkAttributes
+
 # forbiddenChars parameter
 # Format:
 # forbiddenChars [CHARACTERS_FORBIDDEN]
index 049623483f027805b2401a67ea4ca56993f76826..bdfd519e0697f1eefd70500dd66cdd6f8e5446d8 100644 (file)
 
 #define CONF_MAX_SIZE                      50
 #define PARAM_MAX_LEN                      32
-#define VALUE_MAX_LEN                      128
+#define VALUE_MAX_LEN                      512
 #define ATTR_NAME_MAX_LEN                  150
 
 #define PARAM_PREFIX_CLASS                "class-"
 #define TOKENS_DELIMITERS                 " ,;-_£\t"
+#define ATTR_TOKENS_DELIMITERS            " ,;-_@\t"
 
 
 #define DEBUG_MSG_MAX_LEN                 256
@@ -54,6 +55,8 @@
   "Password for dn=\"%s\" contains %d forbidden characters in %s"
 #define RDN_TOKEN_FOUND \
   "Password for dn=\"%s\" contains tokens from the RDN"
+#define ATTR_TOKEN_FOUND \
+  "Password for dn=\"%s\" is too simple: it contains part of an attribute"
 #define GENERIC_ERROR \
   "Error while checking password"
 #define PASSWORD_CRACKLIB \
@@ -80,9 +83,10 @@ typedef struct params {
 
 // allowed parameters loaded into configuration structure
 // it also contains the type of the corresponding value
-params allowedParameters[7] = {
+params allowedParameters[8] = {
     {"^minQuality", typeInt},
     {"^checkRDN", typeInt},
+    {"^checkAttributes", typeStr},
     {"^forbiddenChars", typeStr},
     {"^maxConsecutivePerClass", typeInt},
     {"^useCracklib", typeInt},
index 5b1accb31f5abc459df7ceb381008710911cdafe..b5a94228fb4fa5cf81a0e54d94dd0d6cbed14a0e 100644 (file)
@@ -42,7 +42,7 @@ sn: default
 cn: default
 pwdMinLength: 6
 pwdCheckModule: /usr/local/lib/ppm.so
-pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKZm9yYmlkZGVuQ2hhcnMKbWF4Q29uc2VjdXRpdmVQZXJDbGFzcyAwCnVzZUNyYWNrbGliIDAKY3JhY2tsaWJEaWN0IC92YXIvY2FjaGUvY3JhY2tsaWIvY3JhY2tsaWJfZGljdApjbGFzcy11cHBlckNhc2UgQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMCAxCmNsYXNzLWxvd2VyQ2FzZSBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiAwIDEKY2xhc3MtZGlnaXQgMDEyMzQ1Njc4OSAwIDEKY2xhc3Mtc3BlY2lhbCA8Piw/Oy46LyHCp8O5JSrCtV7CqCTCo8KyJsOpfiIjJ3soWy18w6hgX1zDp17DoEApXcKwPX0rIDAgMQ==
+pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKY2hlY2tBdHRyaWJ1dGVzCmZvcmJpZGRlbkNoYXJzCm1heENvbnNlY3V0aXZlUGVyQ2xhc3MgMAp1c2VDcmFja2xpYiAwCmNyYWNrbGliRGljdCAvdmFyL2NhY2hlL2NyYWNrbGliL2NyYWNrbGliX2RpY3QKY2xhc3MtdXBwZXJDYXNlIEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIDAgMQpjbGFzcy1sb3dlckNhc2UgYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogMCAxCmNsYXNzLWRpZ2l0IDAxMjM0NTY3ODkgMCAxCmNsYXNzLXNwZWNpYWwgPD4sPzsuOi8hwqfDuSUqwrVewqgkwqPCsibDqX4iIyd7KFstfMOoYF9cw6dew6BAKV3CsD19KyAwIDEK
 ```
 
 
@@ -86,6 +86,8 @@ rejected.
 
 - if a password contains tokens from the RDN, then it is rejected.
 
+- if a password contains tokens from defined attributes, then it is rejected.
+
 - if a password does not pass cracklib check, then it is rejected.
 
 
@@ -138,6 +140,17 @@ minQuality 3
 # Tokens are separated by the following delimiters : space tabulation _ - , ; £
 checkRDN 0
 
+# checkAttributes parameter
+# Format:
+# checkRDN [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 _ - , ; @
+# For example, if uid="the wonderful entry",
+# password must not contain "the", nor "wonderful", nor "entry"
+checkAttributes
+
 # forbiddenChars parameter
 # Format:
 # forbiddenChars [CHARACTERS_FORBIDDEN]
@@ -189,6 +202,7 @@ With this policy:
 minQuality 4
 forbiddenChars .?,
 checkRDN 1
+checkAttributes mail
 class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 5
 class-lowerCase abcdefghijklmnopqrstuvwxyz 0 12
 class-digit 0123456789 0 1
@@ -205,6 +219,9 @@ the password **ThereIsNoCowLevel)** is working, because:
 but it won't work for the user uid=John Cowlevel,ou=people,cn=example,cn=com,
 because the token "Cowlevel" from his RDN exists in the password (case insensitive).
 
+Also, it won't work for a mail attribute containing: "thereis@domain.com"
+because the part "thereis" matches the password.
+
 
 # LOGS
 
@@ -222,88 +239,56 @@ A more detailed message is written to the server log.
 Server log:
 
 ```
-Feb 26 14:46:10 debian-11-64 slapd[1981]: conn=1000 op=16 MOD dn="uid=user,ou=persons,dc=my-domain,dc=com"
-Feb 26 14:46:10 debian-11-64 slapd[1981]: conn=1000 op=16 MOD attr=userPassword
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: entry uid=user,ou=persons,dc=my-domain,dc=com
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Reading pwdCheckModuleArg attribute
-Feb 26 14:46:10 debian-11-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_dictionary]#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 dictionary 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-11-64 slapd[1981]: ppm: Parsing pwdCheckModuleArg attribute
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # minQuality parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # minQuality [NUMBER]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-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-11-64 slapd[1981]: ppm: get line: # defines the minimum point numbers for the password to be accepted.
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: minQuality 3
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 3
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # checkRDN parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # checkRDN [0 | 1]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-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-11-64 slapd[1981]: ppm: get line: # Tokens are separated by the following delimiters : space tabulation _ - , ; £
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: checkRDN 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = checkRDN, value = 0, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # forbiddenChars parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # forbiddenChars [CHARACTERS_FORBIDDEN]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Defines the forbidden characters list (no separator).
-Feb 26 14:46:10 debian-11-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-11-64 slapd[1981]: ppm: get line: forbiddenChars
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: No value, goto next parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # maxConsecutivePerClass parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # maxConsecutivePerClass [NUMBER]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Defines the maximum number of consecutive character allowed for any class
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: maxConsecutivePerClass 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = maxConsecutivePerClass, value = 0, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # useCracklib parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # useCracklib [0 | 1]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # If set to 1, the password must pass the cracklib check
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: useCracklib 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = useCracklib, value = 0, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # cracklibDict parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # cracklibDict [path_to_cracklib_dictionary]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # directory+filename-prefix that your version of CrackLib will go hunting for
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # For example, /var/pw_dict resolves as /var/pw_dict.pwd,
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # /var/pw_dict.pwi and /var/pw_dict.hwm dictionary files
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: cracklibDict /var/cache/cracklib/cracklib_dict
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = cracklibDict, value = /var/cache/cracklib/cracklib_dict, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: /var/cache/cracklib/cracklib_dict
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # classes parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # class-[CLASS_NAME] [CHARACTERS_DEFINING_CLASS] [MIN] [MIN_FOR_POINT]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # [CHARACTERS_DEFINING_CLASS]: characters defining the class (no separator)
-Feb 26 14:46:10 debian-11-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-11-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-11-64 slapd[1981]: ppm: get line: class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: abcdefghijklmnopqrstuvwxyz
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: class-digit 0123456789 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0123456789
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: class-special <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-special, value = <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: 1 point granted for class class-lowerCase
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: 1 point granted for class class-digit
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Reallocating szErrStr from 64 to 173
-Feb 26 14:46:10 debian-11-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-11-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)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 fd=13 ACCEPT from IP=[::1]:49322 (IP=[::]:389)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=0 BIND dn="uid=daniel.jackson,ou=people,dc=my-domain,dc=com" method=128
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=0 BIND dn="uid=daniel.jackson,ou=people,dc=my-domain,dc=com" mech=SIMPLE bind_ssf=0 ssf=0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: connection_input: conn=1000 deferring operation: binding
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=0 RESULT tag=97 err=0 qtime=0.000047 etime=0.157388 text=
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=1 MOD dn="uid=jack.oneill,ou=people,dc=my-domain,dc=com"
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=1 MOD attr=userPassword
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: entry uid=jack.oneill,ou=people,dc=my-domain,dc=com
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Reading pwdCheckModuleArg attribute
+Mar 22 17:08:23 debian-11-64 slapd[79222]: 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#012class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1#012class-digit 0123456789 0 1#012class-special <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Parsing pwdCheckModuleArg attribute
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: minQuality 3
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 3
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: checkRDN 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = checkRDN, value = 0, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: checkAttributes mail,uid
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = checkAttributes, value = mail,uid, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: mail,uid
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: forbiddenChars
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: No value, goto next parameter
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: maxConsecutivePerClass 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = maxConsecutivePerClass, value = 0, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: useCracklib 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = useCracklib, value = 0, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: cracklibDict /var/cache/cracklib/cracklib_dict
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = cracklibDict, value = /var/cache/cracklib/cracklib_dict, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: /var/cache/cracklib/cracklib_dict
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: abcdefghijklmnopqrstuvwxyz
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-digit 0123456789 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0123456789
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-special <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+ 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-special, value = <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: <>,?;.:/!§ù%*µ^¨$£²&é~"#'{([-|è`_\ç^à@)]°=}+
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: 1 point granted for class class-upperCase
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: 1 point granted for class class-lowerCase
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Reallocating szErrStr from 64 to 179
+Mar 22 17:08:23 debian-11-64 slapd[79222]: check_password_quality: module error: (/usr/local/openldap/libexec/openldap/ppm.so) Password for dn="uid=jack.oneill,ou=people,dc=my-domain,dc=com" does not pass required number of strength checks (2 of 3).[1]
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=1 RESULT tag=103 err=19 qtime=0.000668 etime=0.004593 text=Password for dn="uid=jack.oneill,ou=people,dc=my-domain,dc=com" does not pass required number of strength checks (2 of 3)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=2 UNBIND
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 fd=13 closed
 ```
 
 
index 10e9c8d4472790a7b562c9b3c14ab738288d8739..5db191fae8cd7914705dd52bfcb4a3d0b13fa44c 100644 (file)
@@ -38,7 +38,7 @@ sn: default
 cn: default
 pwdMinLength: 6
 pwdCheckModule: /usr/local/lib/ppm.so
-pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKZm9yYmlkZGVuQ2hhcnMKbWF4Q29uc2VjdXRpdmVQZXJDbGFzcyAwCnVzZUNyYWNrbGliIDAKY3JhY2tsaWJEaWN0IC92YXIvY2FjaGUvY3JhY2tsaWIvY3JhY2tsaWJfZGljdApjbGFzcy11cHBlckNhc2UgQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMCAxCmNsYXNzLWxvd2VyQ2FzZSBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiAwIDEKY2xhc3MtZGlnaXQgMDEyMzQ1Njc4OSAwIDEKY2xhc3Mtc3BlY2lhbCA8Piw/Oy46LyHCp8O5JSrCtV7CqCTCo8KyJsOpfiIjJ3soWy18w6hgX1zDp17DoEApXcKwPX0rIDAgMQ==
+pwdCheckModuleArg:: bWluUXVhbGl0eSAzCmNoZWNrUkROIDAKY2hlY2tBdHRyaWJ1dGVzCmZvcmJpZGRlbkNoYXJzCm1heENvbnNlY3V0aXZlUGVyQ2xhc3MgMAp1c2VDcmFja2xpYiAwCmNyYWNrbGliRGljdCAvdmFyL2NhY2hlL2NyYWNrbGliL2NyYWNrbGliX2RpY3QKY2xhc3MtdXBwZXJDYXNlIEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIDAgMQpjbGFzcy1sb3dlckNhc2UgYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogMCAxCmNsYXNzLWRpZ2l0IDAxMjM0NTY3ODkgMCAxCmNsYXNzLXNwZWNpYWwgPD4sPzsuOi8hwqfDuSUqwrVewqgkwqPCsibDqX4iIyd7KFstfMOoYF9cw6dew6BAKV3CsD19KyAwIDEK
 \f[R]
 .fi
 .PP
@@ -84,6 +84,9 @@ 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
@@ -138,6 +141,17 @@ minQuality 3
 # Tokens are separated by the following delimiters : space tabulation _ - , ; \[Po]
 checkRDN 0
 
+# checkAttributes parameter
+# Format:
+# checkRDN [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]
@@ -191,6 +205,7 @@ With this policy:
 minQuality 4
 forbiddenChars .?,
 checkRDN 1
+checkAttributes mail
 class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 5
 class-lowerCase abcdefghijklmnopqrstuvwxyz 0 12
 class-digit 0123456789 0 1
@@ -212,6 +227,10 @@ 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
@@ -232,88 +251,56 @@ Server log:
 .IP
 .nf
 \f[C]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: conn=1000 op=16 MOD dn=\[dq]uid=user,ou=persons,dc=my-domain,dc=com\[dq]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: conn=1000 op=16 MOD attr=userPassword
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: entry uid=user,ou=persons,dc=my-domain,dc=com
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Reading pwdCheckModuleArg attribute
-Feb 26 14:46:10 debian-11-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 _ - , ; \[Po]#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_dictionary]#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 dictionary 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 <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+ 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Parsing pwdCheckModuleArg attribute
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # minQuality parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # minQuality [NUMBER]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-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-11-64 slapd[1981]: ppm: get line: # defines the minimum point numbers for the password to be accepted.
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: minQuality 3
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 3
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # checkRDN parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # checkRDN [0 | 1]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-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-11-64 slapd[1981]: ppm: get line: # Tokens are separated by the following delimiters : space tabulation _ - , ; \[Po]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: checkRDN 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = checkRDN, value = 0, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # forbiddenChars parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # forbiddenChars [CHARACTERS_FORBIDDEN]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Defines the forbidden characters list (no separator).
-Feb 26 14:46:10 debian-11-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-11-64 slapd[1981]: ppm: get line: forbiddenChars
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: No value, goto next parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # maxConsecutivePerClass parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # maxConsecutivePerClass [NUMBER]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Defines the maximum number of consecutive character allowed for any class
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: maxConsecutivePerClass 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = maxConsecutivePerClass, value = 0, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # useCracklib parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # useCracklib [0 | 1]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # If set to 1, the password must pass the cracklib check
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: useCracklib 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = useCracklib, value = 0, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # cracklibDict parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # cracklibDict [path_to_cracklib_dictionary]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # directory+filename-prefix that your version of CrackLib will go hunting for
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # For example, /var/pw_dict resolves as /var/pw_dict.pwd,
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # /var/pw_dict.pwi and /var/pw_dict.hwm dictionary files
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: cracklibDict /var/cache/cracklib/cracklib_dict
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = cracklibDict, value = /var/cache/cracklib/cracklib_dict, min = (null), minForPoint= (null)
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: /var/cache/cracklib/cracklib_dict
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # classes parameter
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Format:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # class-[CLASS_NAME] [CHARACTERS_DEFINING_CLASS] [MIN] [MIN_FOR_POINT]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # Description:
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: # [CHARACTERS_DEFINING_CLASS]: characters defining the class (no separator)
-Feb 26 14:46:10 debian-11-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-11-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-11-64 slapd[1981]: ppm: get line: class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: abcdefghijklmnopqrstuvwxyz
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: get line: class-digit 0123456789 0 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint= 1
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: 0123456789
-Feb 26 14:46:10 debian-11-64 slapd[1981]: 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
-Feb 26 14:46:10 debian-11-64 slapd[1981]: 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
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm:  Accepted replaced value: <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: 1 point granted for class class-lowerCase
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: 1 point granted for class class-digit
-Feb 26 14:46:10 debian-11-64 slapd[1981]: ppm: Reallocating szErrStr from 64 to 173
-Feb 26 14:46:10 debian-11-64 slapd[1981]: check_password_quality: module error: (/usr/local/lib/ppm.so) Password for dn=\[dq]uid=user,ou=persons,dc=my-domain,dc=com\[dq] does not pass required number of strength checks (2 of 3).[1]
-Feb 26 14:46:10 debian-11-64 slapd[1981]: conn=1000 op=16 RESULT tag=103 err=19 qtime=0.000020 etime=0.001496 text=Password for dn=\[dq]uid=user,ou=persons,dc=my-domain,dc=com\[dq] does not pass required number of strength checks (2 of 3)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 fd=13 ACCEPT from IP=[::1]:49322 (IP=[::]:389)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=0 BIND dn=\[dq]uid=daniel.jackson,ou=people,dc=my-domain,dc=com\[dq] method=128
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=0 BIND dn=\[dq]uid=daniel.jackson,ou=people,dc=my-domain,dc=com\[dq] mech=SIMPLE bind_ssf=0 ssf=0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: connection_input: conn=1000 deferring operation: binding
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=0 RESULT tag=97 err=0 qtime=0.000047 etime=0.157388 text=
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=1 MOD dn=\[dq]uid=jack.oneill,ou=people,dc=my-domain,dc=com\[dq]
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=1 MOD attr=userPassword
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: entry uid=jack.oneill,ou=people,dc=my-domain,dc=com
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Reading pwdCheckModuleArg attribute
+Mar 22 17:08:23 debian-11-64 slapd[79222]: 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#012class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1#012class-digit 0123456789 0 1#012class-special <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+ 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Parsing pwdCheckModuleArg attribute
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: minQuality 3
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = minQuality, value = 3, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 3
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: checkRDN 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = checkRDN, value = 0, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: checkAttributes mail,uid
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = checkAttributes, value = mail,uid, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: mail,uid
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: forbiddenChars
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: No value, goto next parameter
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: maxConsecutivePerClass 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = maxConsecutivePerClass, value = 0, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: useCracklib 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = useCracklib, value = 0, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: cracklibDict /var/cache/cracklib/cracklib_dict
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = cracklibDict, value = /var/cache/cracklib/cracklib_dict, min = (null), minForPoint= (null)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: /var/cache/cracklib/cracklib_dict
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-upperCase ABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-upperCase, value = ABCDEFGHIJKLMNOPQRSTUVWXYZ, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: ABCDEFGHIJKLMNOPQRSTUVWXYZ
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-lowerCase abcdefghijklmnopqrstuvwxyz 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-lowerCase, value = abcdefghijklmnopqrstuvwxyz, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: abcdefghijklmnopqrstuvwxyz
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: get line: class-digit 0123456789 0 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Param = class-digit, value = 0123456789, min = 0, minForPoint= 1
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: 0123456789
+Mar 22 17:08:23 debian-11-64 slapd[79222]: 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
+Mar 22 17:08:23 debian-11-64 slapd[79222]: 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
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm:  Accepted replaced value: <>,?;.:/!\[sc]\[`u]%*\[mc]\[ha]\[ad]$\[Po]\[S2]&\['e]\[ti]\[dq]#\[aq]{([-|\[`e]\[ga]_\[rs]\[,c]\[ha]\[`a]\[at])]\[de]=}+
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: 1 point granted for class class-upperCase
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: 1 point granted for class class-lowerCase
+Mar 22 17:08:23 debian-11-64 slapd[79222]: ppm: Reallocating szErrStr from 64 to 179
+Mar 22 17:08:23 debian-11-64 slapd[79222]: 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]
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=1 RESULT tag=103 err=19 qtime=0.000668 etime=0.004593 text=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)
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 op=2 UNBIND
+Mar 22 17:08:23 debian-11-64 slapd[79222]: conn=1000 fd=13 closed
 \f[R]
 .fi
 .SH TESTS