Wednesday, April 8, 2020

[389-commits] [389-ds-base] branch 389-ds-base-1.4.2 updated: Issue 50875 - Refactor passwordUserAttributes's and passwordBadWords's code

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

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

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

commit 24c501db384b7927dbd339472e517dd38de4a70a
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 7d275eb..0a7143a 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -171,7 +171,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);


@@ -530,12 +529,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,
@@ -2896,70 +2895,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;
}
@@ -7281,13 +7328,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",
@@ -7296,15 +7343,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 */
@@ -8415,19 +8465,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 75259e4..ac02618 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 96ce7d4..b3bf87d 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1807,10 +1807,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

No comments:

Post a Comment