[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fedora-directory-commits
Subject:    =?utf-8?q?=5B389-commits=5D?= [389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50875 - Refactor
From:       pagure () pagure ! io
Date:       2020-04-08 10:05:19
Message-ID: 20200408100518.15821.72348 () pagure01 ! fedoraproject ! org
[Download RAW message or body]

This is an automated email from the git hooks/post-receive script.

spichugi pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.

The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
     new 0b88633  Issue 50875 - Refactor passwordUserAttributes's and \
passwordBadWords's code 0b88633 is described below

commit 0b886339959e9e16bf2633535d23726f223b87bd
Author: Simon Pichugin <spichugi@redhat.com>
AuthorDate: Sun Apr 5 21:19:11 2020 +0200

    Issue 50875 - Refactor passwordUserAttributes's and passwordBadWords's code
    
    Bug Description: Searches on cn=config takes values with spaces and
    makes multiple attributes out of them. If we set passwordUserAttributes
    to "cn uid givenname", it will transform it in a multi-valued attribute.
    
    Fix Description: Change passwordUserAttributes's and passwordBadWords's type
    to CONFIG_STRING (it was CONFIG_CHARRAY). Add an additional parameter
    to store the array (and use it in pw.c).
    The string and array processing is similar to nsslapd-allowed-sasl-mechanisms.
    Add tests for both attributes.
    
    https://pagure.io/389-ds-base/issue/50875
    
    Reviewed by: mreynolds, tbordaz, firstyear (Thanks!)
---
 .../tests/suites/password/pwdPolicy_syntax_test.py | 101 ++++++++++++--
 ldap/servers/slapd/back-ldbm/vlv.c                 |  14 --
 ldap/servers/slapd/libglobs.c                      | 151 +++++++++++++--------
 ldap/servers/slapd/proto-slap.h                    |   3 +
 ldap/servers/slapd/pw.c                            |  65 +++++----
 ldap/servers/slapd/slap.h                          |   6 +-
 ldap/servers/slapd/util.c                          |  11 ++
 7 files changed, 238 insertions(+), 113 deletions(-)

diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py \
b/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py index 82d1a97..291a6fd \
                100644
--- a/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
@@ -48,6 +48,7 @@ def create_user(topology_st):
         'gidNumber': '4000',
         'homeDirectory': '/home/user',
         'description': 'd_e_s_c',
+        'loginShell': USER_RDN,
         'userPassword': PASSWORD
     })
 
@@ -61,7 +62,8 @@ def setPolicy(inst, attr, value):
     value = str(value)
     inst.config.set(attr, value)
 
-    inst.simple_bind_s(USER_DN, PASSWORD)
+    policy = inst.config.get_attr_val_utf8(attr)
+    assert policy == value
 
 
 def resetPasswd(inst):
@@ -84,6 +86,7 @@ def tryPassword(inst, policy_attr, value, reset_value, pw_bad, \
pw_good, msg):  """
 
     setPolicy(inst, policy_attr, value)
+    inst.simple_bind_s(USER_DN, PASSWORD)
     users = UserAccounts(inst, DEFAULT_SUFFIX)
     user = users.get(USER_RDN)
     try:
@@ -250,17 +253,17 @@ def test_basic(topology_st, create_user, password_policy):
 
         # Sequences
         tryPassword(topology_st.standalone, 'passwordMaxSequence', 3, 0, 'Za1_1234',
-                    '13_#Kad472h', 'Max montonic sequence is not allowed')
+                    '13_#Kad472h', 'Max monotonic sequence is not allowed')
         tryPassword(topology_st.standalone, 'passwordMaxSequence', 3, 0, 'Za1_4321',
-                    '13_#Kad472h', 'Max montonic sequence is not allowed')
+                    '13_#Kad472h', 'Max monotonic sequence is not allowed')
         tryPassword(topology_st.standalone, 'passwordMaxSequence', 3, 0, 'Za1_abcd',
-                    '13_#Kad472h', 'Max montonic sequence is not allowed')
+                    '13_#Kad472h', 'Max monotonic sequence is not allowed')
         tryPassword(topology_st.standalone, 'passwordMaxSequence', 3, 0, 'Za1_dcba',
-                    '13_#Kad472h', 'Max montonic sequence is not allowed')
+                    '13_#Kad472h', 'Max monotonic sequence is not allowed')
 
         # Sequence Sets
         tryPassword(topology_st.standalone, 'passwordMaxSeqSets', 2, 0, \
                'Za1_123--123',
-                    '13_#Kad472h', 'Max montonic sequence is not allowed')
+                    '13_#Kad472h', 'Max monotonic sequence is not allowed')
 
         # Max characters in a character class
         tryPassword(topology_st.standalone, 'passwordMaxClassChars', 3, 0, \
'Za1_9376', @@ -273,16 +276,94 @@ def test_basic(topology_st, create_user, \
                password_policy):
                     '13_#Kad472h', 'Too may consecutive characters from the same \
class')  
         # Bad words
-        tryPassword(topology_st.standalone, 'passwordBadWords', 'redhat fedora', \
                'none', 'Za1_redhat',
-                    '13_#Kad472h', 'Too may consecutive characters from the same \
                class')
-        tryPassword(topology_st.standalone, 'passwordBadWords', 'redhat fedora', \
'none', 'Za1_fedora', +        tryPassword(topology_st.standalone, \
                'passwordBadWords', 'redhat', 'none', 'Za1_redhat',
                     '13_#Kad472h', 'Too may consecutive characters from the same \
class')  
         # User Attributes
         tryPassword(topology_st.standalone, 'passwordUserAttributes', 'description', \
0, 'Za1_d_e_s_c',  '13_#Kad472h', 'Password found in user entry')
 
-    log.info('pwdPolicy tests PASSED')
+
+@pytest.mark.bz1816857
+@pytest.mark.ds50875
+@pytest.mark.skipif(ds_is_older("1.4.1.18"), reason="Not implemented")
+def test_config_set_few_user_attributes(topology_st, create_user, password_policy):
+    """Test that we can successfully set multiple values to passwordUserAttributes
+
+    :id: 188e0aee-6e29-4857-910c-27d5606f8c08
+    :setup: Standalone instance
+    :steps:
+        1. Set passwordUserAttributes to "description loginShell"
+        2. Verify passwordUserAttributes has the values
+        3. Verify passwordUserAttributes enforced the policy
+    :expectedresults:
+        1. Operation should be successful
+        2. Operation should be successful
+        3. Operation should be successful
+    """
+
+    standalone = topology_st.standalone
+
+    standalone.log.info('Set passwordUserAttributes to "description loginShell"')
+    standalone.config.set('passwordUserAttributes', 'description loginshell')
+
+    standalone.restart()
+
+    standalone.log.info("Verify passwordUserAttributes has the values")
+    user_attrs = standalone.config.get_attr_val_utf8('passwordUserAttributes')
+    assert "description" in user_attrs
+    assert "loginshell" in user_attrs
+    standalone.log.info("Reset passwordUserAttributes")
+    standalone.config.remove_all('passwordUserAttributes')
+
+    standalone.log.info("Verify passwordUserAttributes enforced the policy")
+    attributes = ['description, loginShell', 'description,loginShell', 'description \
loginShell'] +    values = ['Za1_d_e_s_c', f'Za1_{USER_RDN}', \
f'Za1_d_e_s_c{USER_RDN}'] +    for attr in attributes:
+        for value in values:
+            tryPassword(standalone, 'passwordUserAttributes', attr, 0, value,
+                        '13_#Kad472h', 'Password found in user entry')
+
+
+@pytest.mark.bz1816857
+@pytest.mark.ds50875
+@pytest.mark.skipif(ds_is_older("1.4.1.18"), reason="Not implemented")
+def test_config_set_few_bad_words(topology_st, create_user, password_policy):
+    """Test that we can successfully set multiple values to passwordBadWords
+
+    :id: 2977094c-921c-4b2f-af91-4c7a45ded48b
+    :setup: Standalone instance
+    :steps:
+        1. Set passwordBadWords to "fedora redhat"
+        2. Verify passwordBadWords has the values
+        3. Verify passwordBadWords enforced the policy
+    :expectedresults:
+        1. Operation should be successful
+        2. Operation should be successful
+        3. Operation should be successful
+    """
+
+    standalone = topology_st.standalone
+
+    standalone.log.info('Set passwordBadWords to "fedora redhat"')
+    standalone.config.set('passwordBadWords', 'fedora redhat')
+
+    standalone.restart()
+
+    standalone.log.info("Verify passwordBadWords has the values")
+    user_attrs = standalone.config.get_attr_val_utf8('passwordBadWords')
+    assert "fedora" in user_attrs
+    assert "redhat" in user_attrs
+    standalone.log.info("Reset passwordBadWords")
+    standalone.config.remove_all('passwordBadWords')
+
+    standalone.log.info("Verify passwordBadWords enforced the policy")
+    attributes = ['redhat, fedora', 'redhat,fedora', 'redhat fedora']
+    values = ['Za1_redhat_fedora', 'Za1_fedora', 'Za1_redhat']
+    for attr in attributes:
+        for value in values:
+            tryPassword(standalone, 'passwordBadWords', attr, 'none', value,
+                        '13_#Kad472h', 'Too may consecutive characters from the same \
class')  
 
 if __name__ == '__main__':
diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c
index b50bb5a..ef7f26e 100644
--- a/ldap/servers/slapd/back-ldbm/vlv.c
+++ b/ldap/servers/slapd/back-ldbm/vlv.c
@@ -1962,20 +1962,6 @@ vlv_find_index_by_filter(struct backend *be, const char *base, \
Slapi_Filter *f)  return vlv_find_index_by_filter_txn(be, base, f, NULL);
 }
 
-/* replace c with c2 in string -- probably exists somewhere but I can't find it \
                slapi maybe? */
-
-static void
-replace_char(char *name, char c, char c2)
-{
-    int x;
-
-    for (x = 0; name[x] != '\0'; x++) {
-        if (c == name[x]) {
-            name[x] = c2;
-        }
-    }
-}
-
 /* similar to what the console GUI does */
 
 char *
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index d1d8801..7810389 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -166,7 +166,6 @@ typedef enum {
 
 static int32_t config_set_onoff(const char *attrname, char *value, int32_t \
*configvalue, char *errorbuf, int apply);  static int config_set_schemareplace(const \
                char *attrname, char *value, char *errorbuf, int apply);
-static void remove_commas(char *str);
 static int invalid_sasl_mech(char *str);
 
 
@@ -525,12 +524,12 @@ static struct config_get_and_set
     {CONFIG_PW_USERATTRS_ATTRIBUTE, config_set_pw_user_attrs,
      NULL, 0,
      (void **)&global_slapdFrontendConfig.pw_policy.pw_cmp_attrs,
-     CONFIG_CHARRAY, NULL, NULL},
+     CONFIG_STRING, NULL, "", NULL},
     /* password bad work list */
     {CONFIG_PW_BAD_WORDS_ATTRIBUTE, config_set_pw_bad_words,
      NULL, 0,
      (void **)&global_slapdFrontendConfig.pw_policy.pw_bad_words,
-     CONFIG_CHARRAY, NULL, NULL},
+     CONFIG_STRING, NULL, "", NULL},
     /* password max sequence */
     {CONFIG_PW_MAX_SEQ_ATTRIBUTE, config_set_pw_max_seq,
      NULL, 0,
@@ -2886,70 +2885,118 @@ config_set_pw_dict_path(const char *attrname, char *value, \
char *errorbuf, int a  return retVal;
 }
 
+char **
+config_get_pw_user_attrs_array(void)
+{
+    /*
+     * array of password user attributes. If is null, returns NULL thanks to \
ch_array_dup. +     * Caller must free!
+     */
+    char **retVal;
+    slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+    CFG_LOCK_READ(slapdFrontendConfig);
+    retVal = slapi_ch_array_dup(slapdFrontendConfig->pw_policy.pw_cmp_attrs_array);
+    CFG_UNLOCK_READ(slapdFrontendConfig);
+
+    return retVal;
+}
+
 int32_t
 config_set_pw_user_attrs(const char *attrname, char *value, char *errorbuf, int \
apply)  {
     int retVal = LDAP_SUCCESS;
-    char **attrs = NULL;
     slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
 
     if (config_value_is_null(attrname, value, errorbuf, 0)) {
         value = NULL;
     }
     if (apply) {
-        if (value) {
+        /* During a reset, the value is "", so we have to handle this case. */
+        if (strcmp(value, "") != 0) {
+            char **nval_array;
+            char *nval = slapi_ch_strdup(value);
+            /* A separate variable is used because slapi_str2charray_ext can change \
it and nval'd become corrupted */ +            char *tmp_array_nval = \
slapi_ch_strdup(nval); +
+            /* We should accept comma-separated lists but slapi_str2charray_ext will \
process only space-separated */ +            replace_char(tmp_array_nval, ',', ' ');
             /* Take list of attributes and break it up into a char array */
-            char *attr = NULL;
-            char *token = NULL;
-            char *next = NULL;
-
-            token = slapi_ch_strdup(value);
-            for (attr = ldap_utf8strtok_r(token, " ", &next); attr != NULL;
-                 attr = ldap_utf8strtok_r(NULL, " ", &next))
-            {
-                slapi_ch_array_add(&attrs, slapi_ch_strdup(attr));
-            }
-            slapi_ch_free_string(&token);
-        }
+            nval_array = slapi_str2charray_ext(tmp_array_nval, " ", 0);
+            slapi_ch_free_string(&tmp_array_nval);
 
-        CFG_LOCK_WRITE(slapdFrontendConfig);
-        slapi_ch_array_free(slapdFrontendConfig->pw_policy.pw_cmp_attrs);
-        slapdFrontendConfig->pw_policy.pw_cmp_attrs = attrs;
-        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+            CFG_LOCK_WRITE(slapdFrontendConfig);
+            slapi_ch_free_string(&slapdFrontendConfig->pw_policy.pw_cmp_attrs);
+            slapi_ch_array_free(slapdFrontendConfig->pw_policy.pw_cmp_attrs_array);
+            slapdFrontendConfig->pw_policy.pw_cmp_attrs = nval;
+            slapdFrontendConfig->pw_policy.pw_cmp_attrs_array = nval_array;
+            CFG_UNLOCK_WRITE(slapdFrontendConfig);
+        } else {
+            CFG_LOCK_WRITE(slapdFrontendConfig);
+            slapi_ch_free_string(&slapdFrontendConfig->pw_policy.pw_cmp_attrs);
+            slapi_ch_array_free(slapdFrontendConfig->pw_policy.pw_cmp_attrs_array);
+            slapdFrontendConfig->pw_policy.pw_cmp_attrs = NULL;
+            slapdFrontendConfig->pw_policy.pw_cmp_attrs_array = NULL;
+            CFG_UNLOCK_WRITE(slapdFrontendConfig);
+         }
     }
     return retVal;
 }
 
+char **
+config_get_pw_bad_words_array(void)
+{
+    /*
+     * array of words to reject. If is null, returns NULL thanks to ch_array_dup.
+     * Caller must free!
+     */
+    char **retVal;
+    slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+    CFG_LOCK_READ(slapdFrontendConfig);
+    retVal = slapi_ch_array_dup(slapdFrontendConfig->pw_policy.pw_bad_words_array);
+    CFG_UNLOCK_READ(slapdFrontendConfig);
+
+    return retVal;
+}
+
 int32_t
 config_set_pw_bad_words(const char *attrname, char *value, char *errorbuf, int \
apply)  {
     int retVal = LDAP_SUCCESS;
-    char **words = NULL;
     slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
 
     if (config_value_is_null(attrname, value, errorbuf, 0)) {
         value = NULL;
     }
     if (apply) {
-        if (value) {
+        /* During a reset, the value is "", so we have to handle this case. */
+        if (strcmp(value, "") != 0) {
+            char **nval_array;
+            char *nval = slapi_ch_strdup(value);
+            /* A separate variable is used because slapi_str2charray_ext can change \
it and nval'd become corrupted */ +            char *tmp_array_nval = \
slapi_ch_strdup(nval); +
+            /* We should accept comma-separated lists but slapi_str2charray_ext will \
process only space-separated */ +            replace_char(tmp_array_nval, ',', ' ');
             /* Take list of attributes and break it up into a char array */
-            char *word = NULL;
-            char *token = NULL;
-            char *next = NULL;
-
-            token = slapi_ch_strdup(value);
-            for (word = ldap_utf8strtok_r(token, " ", &next); word != NULL;
-                 word = ldap_utf8strtok_r(NULL, " ", &next))
-            {
-                slapi_ch_array_add(&words, slapi_ch_strdup(word));
-            }
-            slapi_ch_free_string(&token);
-        }
+            nval_array = slapi_str2charray_ext(tmp_array_nval, " ", 0);
+            slapi_ch_free_string(&tmp_array_nval);
 
-        CFG_LOCK_WRITE(slapdFrontendConfig);
-        slapi_ch_array_free(slapdFrontendConfig->pw_policy.pw_bad_words);
-        slapdFrontendConfig->pw_policy.pw_bad_words = words;
-        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+            CFG_LOCK_WRITE(slapdFrontendConfig);
+            slapi_ch_free_string(&slapdFrontendConfig->pw_policy.pw_bad_words);
+            slapi_ch_array_free(slapdFrontendConfig->pw_policy.pw_bad_words_array);
+            slapdFrontendConfig->pw_policy.pw_bad_words = nval;
+            slapdFrontendConfig->pw_policy.pw_bad_words_array = nval_array;
+            CFG_UNLOCK_WRITE(slapdFrontendConfig);
+        } else {
+            CFG_LOCK_WRITE(slapdFrontendConfig);
+            slapi_ch_free_string(&slapdFrontendConfig->pw_policy.pw_bad_words);
+            slapi_ch_array_free(slapdFrontendConfig->pw_policy.pw_bad_words_array);
+            slapdFrontendConfig->pw_policy.pw_bad_words = NULL;
+            slapdFrontendConfig->pw_policy.pw_bad_words_array = NULL;
+            CFG_UNLOCK_WRITE(slapdFrontendConfig);
+         }
     }
     return retVal;
 }
@@ -7271,13 +7318,13 @@ config_set_allowed_sasl_mechs(const char *attrname, char \
*value, char *errorbuf  
     /* During a reset, the value is "", so we have to handle this case. */
     if (strcmp(value, "") != 0) {
+        char **nval_array;
         char *nval = slapi_ch_strdup(value);
         /* A separate variable is used because slapi_str2charray_ext can change it \
and nval'd become corrupted */  char *tmp_array_nval;
 
         /* cyrus sasl doesn't like comma separated lists */
-        remove_commas(nval);
-        tmp_array_nval = slapi_ch_strdup(nval);
+        replace_char(nval, ',', ' ');
 
         if (invalid_sasl_mech(nval)) {
             slapi_log_err(SLAPI_LOG_ERR, "config_set_allowed_sasl_mechs",
@@ -7286,15 +7333,18 @@ config_set_allowed_sasl_mechs(const char *attrname, char \
*value, char *errorbuf  "digits, hyphens, or underscores\n",
                           nval);
             slapi_ch_free_string(&nval);
-            slapi_ch_free_string(&tmp_array_nval);
             return LDAP_UNWILLING_TO_PERFORM;
         }
+
+        tmp_array_nval = slapi_ch_strdup(nval);
+        nval_array = slapi_str2charray_ext(tmp_array_nval, " ", 0);
+        slapi_ch_free_string(&tmp_array_nval);
+
         CFG_LOCK_WRITE(slapdFrontendConfig);
         slapi_ch_free_string(&slapdFrontendConfig->allowed_sasl_mechs);
         slapi_ch_array_free(slapdFrontendConfig->allowed_sasl_mechs_array);
         slapdFrontendConfig->allowed_sasl_mechs = nval;
-        slapdFrontendConfig->allowed_sasl_mechs_array = \
                slapi_str2charray_ext(tmp_array_nval, " ", 0);
-        slapi_ch_free_string(&tmp_array_nval);
+        slapdFrontendConfig->allowed_sasl_mechs_array = nval_array;
         CFG_UNLOCK_WRITE(slapdFrontendConfig);
     } else {
         /* If this value is "", we need to set the list to *all* possible mechs */
@@ -8405,19 +8455,6 @@ slapi_err2string(int result)
     return ldap_err2string(result);
 }
 
-/* replace commas with spaces */
-static void
-remove_commas(char *str)
-{
-    int i;
-
-    for (i = 0; str && str[i]; i++) {
-        if (str[i] == ',') {
-            str[i] = ' ';
-        }
-    }
-}
-
 /*
  * Check the SASL mechanism values
  *
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 5964719..1bcc222 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -304,7 +304,9 @@ int config_set_pw_syntax(const char *attrname, char *value, char \
*errorbuf, int  int32_t config_set_pw_palindrome(const char *attrname, char *value, \
char *errorbuf, int apply);  int32_t config_set_pw_dict_check(const char *attrname, \
char *value, char *errorbuf, int apply);  int32_t config_set_pw_dict_path(const char \
*attrname, char *value, char *errorbuf, int apply); +char \
**config_get_pw_user_attrs_array(void);  int32_t config_set_pw_user_attrs(const char \
*attrname, char *value, char *errorbuf, int apply); +char \
**config_get_pw_bad_words_array(void);  int32_t config_set_pw_bad_words(const char \
*attrname, char *value, char *errorbuf, int apply);  int32_t \
config_set_pw_max_seq_sets(const char *attrname, char *value, char *errorbuf, int \
apply);  int32_t config_set_pw_max_seq(const char *attrname, char *value, char \
*errorbuf, int apply); @@ -851,6 +853,7 @@ void slapd_nasty(char *str, int c, int \
err);  int strarray2str(char **a, char *buf, size_t buflen, int include_quotes);
 int slapd_chown_if_not_owner(const char *filename, uid_t uid, gid_t gid);
 int slapd_comp_path(char *p0, char *p1);
+void replace_char(char *name, char c, char c2);
 
 
 /*
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index 2e11caa..238c9e0 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -1068,6 +1068,7 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, \
Slapi_Value **vals, c  int num_repeated = 0;
             int max_repeated = 0;
             int num_categories = 0;
+            char **bad_words_array;
 
             pwd = (char *)slapi_value_get_string(vals[i]);
 
@@ -1089,13 +1090,16 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, \
Slapi_Value **vals, c  }
 
             /* Check for bad words */
-            if (pwpolicy->pw_bad_words) {
-                for (size_t b = 0; pwpolicy->pw_bad_words && \
                pwpolicy->pw_bad_words[b]; b++) {
-                    if (strcasestr(pwd, pwpolicy->pw_bad_words[b])) {
+            bad_words_array = config_get_pw_bad_words_array();
+            if (bad_words_array) {
+                for (size_t b = 0; bad_words_array && bad_words_array[b]; b++) {
+                    if (strcasestr(pwd, bad_words_array[b])) {
                         report_pw_violation(pb, pwresponse_req, "Password contains a \
restricted word"); +                        charray_free(bad_words_array);
                         return (1);
                     }
                 }
+                charray_free(bad_words_array);
             }
 
             /* Check for sequences */
@@ -1310,6 +1314,7 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, \
Slapi_Value **vals, c  
     /* check for trivial words if syntax checking is enabled */
     if (pwpolicy->pw_syntax == LDAP_ON) {
+        char **user_attrs_array;
         /* e is null if this is an add operation*/
         if (check_trivial_words(pb, e, vals, "uid", pwpolicy->pw_mintokenlength, \
                smods) == 1 ||
             check_trivial_words(pb, e, vals, "cn", pwpolicy->pw_mintokenlength, \
smods) == 1 || @@ -1324,15 +1329,18 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const \
Slapi_DN *sdn, Slapi_Value **vals, c  return 1;
         }
         /* Check user attributes */
-        if (pwpolicy->pw_cmp_attrs) {
-            for (size_t a = 0; pwpolicy->pw_cmp_attrs && pwpolicy->pw_cmp_attrs[a]; \
                a++) {
-                if (check_trivial_words(pb, e, vals, pwpolicy->pw_cmp_attrs[a], \
pwpolicy->pw_mintokenlength, smods) == 1 ){ +        user_attrs_array = \
config_get_pw_user_attrs_array(); +        if (user_attrs_array) {
+            for (size_t a = 0; user_attrs_array && user_attrs_array[a]; a++) {
+                if (check_trivial_words(pb, e, vals, user_attrs_array[a], \
pwpolicy->pw_mintokenlength, smods) == 1 ){  if (mod_op) {
                         slapi_entry_free(e);
                     }
+                    charray_free(user_attrs_array);
                     return 1;
                 }
             }
+            charray_free(user_attrs_array);
         }
     }
 
@@ -2237,35 +2245,32 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
                     }
                 } else if (!strcasecmp(attr_name, "passwordUserAttributes")) {
                     if ((sval = attr_get_present_values(attr))) {
-                        char **attrs = NULL;
-                        char *attr = NULL;
-                        char *token = NULL;
-                        char *next = NULL;
-
-                        token = slapi_ch_strdup(slapi_value_get_string(*sval));
-                        for (attr = ldap_utf8strtok_r(token, " ", &next); attr != \
                NULL;
-                             attr = ldap_utf8strtok_r(NULL, " ", &next))
-                        {
-                            slapi_ch_array_add(&attrs, slapi_ch_strdup(attr));
-                        }
-                        slapi_ch_free_string(&token);
+                        char *attrs = \
slapi_ch_strdup(slapi_value_get_string(*sval)); +                        /* we need a \
separate string because it gets corrupted after slapi_str2charray_ext */ +            \
char *tmp_array_attrs = slapi_ch_strdup(attrs); +
+                        /* we should accept comma-separated lists but \
slapi_str2charray_ext will process only space-separated */ +                        \
replace_char(tmp_array_attrs, ',', ' '); +
                         pwdpolicy->pw_cmp_attrs = attrs;
+                        /* Take list of attributes and break it up into a char array \
*/ +                        pwdpolicy->pw_cmp_attrs_array = \
slapi_str2charray_ext(tmp_array_attrs, " ", 0); +                        \
slapi_ch_free_string(&tmp_array_attrs);  }
                 }  else if (!strcasecmp(attr_name, "passwordBadWords")) {
                     if ((sval = attr_get_present_values(attr))) {
-                        char **words = NULL;
-                        char *word = NULL;
-                        char *token = NULL;
-                        char *next = NULL;
-
-                        token = slapi_ch_strdup(slapi_value_get_string(*sval));
-                        for (word = ldap_utf8strtok_r(token, " ", &next); word != \
                NULL;
-                             word = ldap_utf8strtok_r(NULL, " ", &next))
-                        {
-                            slapi_ch_array_add(&words, slapi_ch_strdup(word));
-                        }
-                        slapi_ch_free_string(&token);
+                        char *words = \
slapi_ch_strdup(slapi_value_get_string(*sval)); +                        /* we need a \
separate string because it gets corrupted after slapi_str2charray_ext */ +            \
char *tmp_array_words = slapi_ch_strdup(words); +
+                        /* we should accept comma-separated lists but \
slapi_str2charray_ext will process only space-separated */ +                        \
replace_char(tmp_array_words, ',', ' '); +
                         pwdpolicy->pw_bad_words = words;
+                        /* Take list of attributes and break it up into a char array \
*/ +                        pwdpolicy->pw_bad_words_array = \
slapi_str2charray_ext(tmp_array_words, " ", 0); +
+                        slapi_ch_free_string(&tmp_array_words);
                     }
                 } else if (!strcasecmp(attr_name, "passwordMaxSequence")) {
                     if ((sval = attr_get_present_values(attr))) {
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index b24f9cb..71ccdad 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1814,10 +1814,12 @@ typedef struct passwordpolicyarray
                                      the same character class. */
     slapi_onoff_t pw_check_dict;
     char *pw_dict_path;           /* custom dictionary */
-    char **pw_cmp_attrs;          /* Space-separated list of attributes to see if \
the +    char *pw_cmp_attrs;           /* Comma-separated list of attributes to see \
                if the
                                      attribute values (and reversed values) in the \
                entry
                                      are contained in the new password. */
-    char **pw_bad_words;          /* Space-separated list of words to reject */
+    char **pw_cmp_attrs_array;    /* Array of password user attributes */
+    char *pw_bad_words;           /* Comma-separated list of words to reject */
+    char **pw_bad_words_array;    /* Array of words to reject */
 
     slapi_onoff_t pw_exp;
     slapi_onoff_t pw_send_expiring;
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index e1219c5..5ef1cd9 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -467,6 +467,17 @@ slapi_escape_filter_value(char *filter_str, int len)
     }
 }
 
+/* replace c with c2 in str */
+void
+replace_char(char *str, char c, char c2)
+{
+    for (size_t i = 0; (str != NULL) && (str[i] != NULL); i++) {
+        if (c == str[i]) {
+            str[i] = c2;
+        }
+    }
+}
+
 /*
 ** This function takes a quoted attribute value of the form "abc",
 ** and strips off the enclosing quotes.  It also deals with quoted

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
389-commits mailing list -- 389-commits@lists.fedoraproject.org
To unsubscribe send an email to 389-commits-leave@lists.fedoraproject.org
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/389-commits@lists.fedoraproject.org



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic