import 389-ds-base-1.4.3.8-7.module+el8.3.0+10310+6e88d919
This commit is contained in:
parent
b342bd146c
commit
6b2663c36d
@ -0,0 +1,95 @@
|
||||
From 340b81a59cee365e7300e57c1ca5f4866373954c Mon Sep 17 00:00:00 2001
|
||||
From: tbordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 16 Dec 2020 16:30:28 +0100
|
||||
Subject: [PATCH 1/4] Issue 4480 - Unexpected info returned to ldap request
|
||||
(#4491)
|
||||
|
||||
Bug description:
|
||||
If the bind entry does not exist, the bind result info
|
||||
reports that 'No such entry'. It should not give any
|
||||
information if the target entry exists or not
|
||||
|
||||
Fix description:
|
||||
Does not return any additional information during a bind
|
||||
|
||||
relates: https://github.com/389ds/389-ds-base/issues/4480
|
||||
|
||||
Reviewed by: William Brown, Viktor Ashirov, Mark Reynolds (thank you all)
|
||||
|
||||
Platforms tested: F31
|
||||
---
|
||||
dirsrvtests/tests/suites/basic/basic_test.py | 30 ++++++++++++++++++++
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 +-
|
||||
ldap/servers/slapd/result.c | 2 +-
|
||||
3 files changed, 32 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
|
||||
index 120207321..e9afa1e7e 100644
|
||||
--- a/dirsrvtests/tests/suites/basic/basic_test.py
|
||||
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
|
||||
@@ -1400,6 +1400,36 @@ def test_dscreate_multiple_dashes_name(dscreate_long_instance):
|
||||
assert not dscreate_long_instance.exists()
|
||||
|
||||
|
||||
+def test_bind_invalid_entry(topology_st):
|
||||
+ """Test the failing bind does not return information about the entry
|
||||
+
|
||||
+ :id: 5cd9b083-eea6-426b-84ca-83c26fc49a6f
|
||||
+
|
||||
+ :setup: Standalone instance
|
||||
+
|
||||
+ :steps:
|
||||
+ 1: bind as non existing entry
|
||||
+ 2: check that bind info does not report 'No such entry'
|
||||
+
|
||||
+ :expectedresults:
|
||||
+ 1: pass
|
||||
+ 2: pass
|
||||
+ """
|
||||
+
|
||||
+ topology_st.standalone.restart()
|
||||
+ INVALID_ENTRY="cn=foooo,%s" % DEFAULT_SUFFIX
|
||||
+ try:
|
||||
+ topology_st.standalone.simple_bind_s(INVALID_ENTRY, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.info('test_bind_invalid_entry: Failed to bind as %s (expected)' % INVALID_ENTRY)
|
||||
+ log.info('exception description: ' + e.args[0]['desc'])
|
||||
+ if 'info' in e.args[0]:
|
||||
+ log.info('exception info: ' + e.args[0]['info'])
|
||||
+ assert e.args[0]['desc'] == 'Invalid credentials'
|
||||
+ assert 'info' not in e.args[0]
|
||||
+ pass
|
||||
+
|
||||
+ log.info('test_bind_invalid_entry: PASSED')
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Run isolated
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
index 88c186359..dee5fc088 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
@@ -1266,7 +1266,7 @@ ldbm_config_search_entry_callback(Slapi_PBlock *pb __attribute__((unused)),
|
||||
if (attrs) {
|
||||
for (size_t i = 0; attrs[i]; i++) {
|
||||
if (ldbm_config_moved_attr(attrs[i])) {
|
||||
- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "at least one required attribute has been moved to the BDB scecific configuration entry");
|
||||
+ slapi_pblock_set(pb, SLAPI_RESULT_TEXT, "at least one required attribute has been moved to the BDB scecific configuration entry");
|
||||
break;
|
||||
}
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
||||
index 61efb6f8d..40c5dcc57 100644
|
||||
--- a/ldap/servers/slapd/result.c
|
||||
+++ b/ldap/servers/slapd/result.c
|
||||
@@ -355,7 +355,7 @@ send_ldap_result_ext(
|
||||
if (text) {
|
||||
pbtext = text;
|
||||
} else {
|
||||
- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &pbtext);
|
||||
+ slapi_pblock_get(pb, SLAPI_RESULT_TEXT, &pbtext);
|
||||
}
|
||||
|
||||
if (operation == NULL) {
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,782 @@
|
||||
From 2923940ffa0db88df986dd00d74ad812ccd71188 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 20 Jan 2021 16:42:15 -0500
|
||||
Subject: [PATCH 2/4] Issue 5442 - Search results are different between RHDS10
|
||||
and RHDS11
|
||||
|
||||
Bug Description: In 1.4.x we introduced a change that was overly strict about
|
||||
how a search on a non-existent subtree returned its error code.
|
||||
It was changed from returning an error 32 to an error 0 with
|
||||
zero entries returned.
|
||||
|
||||
Fix Description: When finding the entry and processing acl's make sure to
|
||||
gather the aci's that match the resource even if the resource
|
||||
does not exist. This requires some extra checks when processing
|
||||
the target attribute.
|
||||
|
||||
relates: https://github.com/389ds/389-ds-base/issues/4542
|
||||
|
||||
Reviewed by: firstyear, elkris, and tbordaz (Thanks!)
|
||||
|
||||
Apply Thierry's changes
|
||||
|
||||
round 2
|
||||
|
||||
Apply more suggestions from Thierry
|
||||
---
|
||||
dirsrvtests/tests/suites/acl/misc_test.py | 108 +++++++-
|
||||
ldap/servers/plugins/acl/acl.c | 296 ++++++++++------------
|
||||
ldap/servers/slapd/back-ldbm/findentry.c | 6 +-
|
||||
src/lib389/lib389/_mapped_object.py | 4 +-
|
||||
4 files changed, 239 insertions(+), 175 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/acl/misc_test.py b/dirsrvtests/tests/suites/acl/misc_test.py
|
||||
index 8f122b7a7..b64961c0c 100644
|
||||
--- a/dirsrvtests/tests/suites/acl/misc_test.py
|
||||
+++ b/dirsrvtests/tests/suites/acl/misc_test.py
|
||||
@@ -11,7 +11,7 @@
|
||||
import os
|
||||
import pytest
|
||||
|
||||
-from lib389._constants import DEFAULT_SUFFIX, PW_DM
|
||||
+from lib389._constants import DEFAULT_SUFFIX, PW_DM, DN_DM
|
||||
from lib389.idm.user import UserAccount, UserAccounts
|
||||
from lib389._mapped_object import DSLdapObject
|
||||
from lib389.idm.account import Accounts, Anonymous
|
||||
@@ -399,14 +399,112 @@ def test_do_bind_as_201_distinct_users(topo, clean, aci_of_user):
|
||||
user = uas.create_test_user(uid=i, gid=i)
|
||||
user.set('userPassword', PW_DM)
|
||||
|
||||
- for i in range(len(uas.list())):
|
||||
- uas.list()[i].bind(PW_DM)
|
||||
+ users = uas.list()
|
||||
+ for user in users:
|
||||
+ user.bind(PW_DM)
|
||||
|
||||
ACLPlugin(topo.standalone).replace("nsslapd-aclpb-max-selected-acls", '220')
|
||||
topo.standalone.restart()
|
||||
|
||||
- for i in range(len(uas.list())):
|
||||
- uas.list()[i].bind(PW_DM)
|
||||
+ users = uas.list()
|
||||
+ for user in users:
|
||||
+ user.bind(PW_DM)
|
||||
+
|
||||
+
|
||||
+def test_info_disclosure(request, topo):
|
||||
+ """Test that a search returns 32 when base entry does not exist
|
||||
+
|
||||
+ :id: f6dec4c2-65a3-41e4-a4c0-146196863333
|
||||
+ :setup: Standalone Instance
|
||||
+ :steps:
|
||||
+ 1. Add aci
|
||||
+ 2. Add test user
|
||||
+ 3. Bind as user and search for non-existent entry
|
||||
+ :expectedresults:
|
||||
+ 1. Success
|
||||
+ 2. Success
|
||||
+ 3. Error 32 is returned
|
||||
+ """
|
||||
+
|
||||
+ ACI_TARGET = "(targetattr = \"*\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX)
|
||||
+ ACI_ALLOW = "(version 3.0; acl \"Read/Search permission for all users\"; allow (read,search)"
|
||||
+ ACI_SUBJECT = "(userdn=\"ldap:///all\");)"
|
||||
+ ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
|
||||
+
|
||||
+ # Get current ACi's so we can restore them when we are done
|
||||
+ suffix = Domain(topo.standalone, DEFAULT_SUFFIX)
|
||||
+ preserved_acis = suffix.get_attr_vals_utf8('aci')
|
||||
+
|
||||
+ def finofaci():
|
||||
+ domain = Domain(topo.standalone, DEFAULT_SUFFIX)
|
||||
+ try:
|
||||
+ domain.remove_all('aci')
|
||||
+ domain.replace_values('aci', preserved_acis)
|
||||
+ except:
|
||||
+ pass
|
||||
+ request.addfinalizer(finofaci)
|
||||
+
|
||||
+ # Remove aci's
|
||||
+ suffix.remove_all('aci')
|
||||
+
|
||||
+ # Add test user
|
||||
+ USER_DN = "uid=test,ou=people," + DEFAULT_SUFFIX
|
||||
+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
|
||||
+ users.create(properties={
|
||||
+ 'uid': 'test',
|
||||
+ 'cn': 'test',
|
||||
+ 'sn': 'test',
|
||||
+ 'uidNumber': '1000',
|
||||
+ 'gidNumber': '2000',
|
||||
+ 'homeDirectory': '/home/test',
|
||||
+ 'userPassword': PW_DM
|
||||
+ })
|
||||
+
|
||||
+ # bind as user
|
||||
+ conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM)
|
||||
+
|
||||
+ # Search fo existing base DN
|
||||
+ test = Domain(conn, DEFAULT_SUFFIX)
|
||||
+ try:
|
||||
+ test.get_attr_vals_utf8_l('dc')
|
||||
+ assert False
|
||||
+ except IndexError:
|
||||
+ pass
|
||||
+
|
||||
+ # Search for a non existent bases
|
||||
+ subtree = Domain(conn, "ou=does_not_exist," + DEFAULT_SUFFIX)
|
||||
+ try:
|
||||
+ subtree.get_attr_vals_utf8_l('objectclass')
|
||||
+ except IndexError:
|
||||
+ pass
|
||||
+ subtree = Domain(conn, "ou=also does not exist,ou=does_not_exist," + DEFAULT_SUFFIX)
|
||||
+ try:
|
||||
+ subtree.get_attr_vals_utf8_l('objectclass')
|
||||
+ except IndexError:
|
||||
+ pass
|
||||
+ # Try ONE level search instead of BASE
|
||||
+ try:
|
||||
+ Accounts(conn, "ou=does_not_exist," + DEFAULT_SUFFIX).filter("(objectclass=top)", ldap.SCOPE_ONELEVEL)
|
||||
+ except IndexError:
|
||||
+ pass
|
||||
+
|
||||
+ # add aci
|
||||
+ suffix.add('aci', ACI)
|
||||
+
|
||||
+ # Search for a non existent entry which should raise an exception
|
||||
+ with pytest.raises(ldap.NO_SUCH_OBJECT):
|
||||
+ conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM)
|
||||
+ subtree = Domain(conn, "ou=does_not_exist," + DEFAULT_SUFFIX)
|
||||
+ subtree.get_attr_vals_utf8_l('objectclass')
|
||||
+ with pytest.raises(ldap.NO_SUCH_OBJECT):
|
||||
+ conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM)
|
||||
+ subtree = Domain(conn, "ou=also does not exist,ou=does_not_exist," + DEFAULT_SUFFIX)
|
||||
+ subtree.get_attr_vals_utf8_l('objectclass')
|
||||
+ with pytest.raises(ldap.NO_SUCH_OBJECT):
|
||||
+ conn = UserAccount(topo.standalone, USER_DN).bind(PW_DM)
|
||||
+ DN = "ou=also does not exist,ou=does_not_exist," + DEFAULT_SUFFIX
|
||||
+ Accounts(conn, DN).filter("(objectclass=top)", ldap.SCOPE_ONELEVEL, strict=True)
|
||||
+
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
|
||||
index 41a909a18..4e811f73a 100644
|
||||
--- a/ldap/servers/plugins/acl/acl.c
|
||||
+++ b/ldap/servers/plugins/acl/acl.c
|
||||
@@ -2111,10 +2111,11 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
aci_right = aci->aci_access;
|
||||
res_right = aclpb->aclpb_access;
|
||||
if (!(aci_right & res_right)) {
|
||||
- /* If we are looking for read/search and the acl has read/search
|
||||
- ** then go further because if targets match we may keep that
|
||||
- ** acl in the entry cache list.
|
||||
- */
|
||||
+ /*
|
||||
+ * If we are looking for read/search and the acl has read/search
|
||||
+ * then go further because if targets match we may keep that
|
||||
+ * acl in the entry cache list.
|
||||
+ */
|
||||
if (!((res_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)) &&
|
||||
(aci_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)))) {
|
||||
matches = ACL_FALSE;
|
||||
@@ -2122,30 +2123,29 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
- /* first Let's see if the entry is under the subtree where the
|
||||
- ** ACL resides. We can't let somebody affect a target beyond the
|
||||
- ** scope of where the ACL resides
|
||||
- ** Example: ACL is located in "ou=engineering, o=ace industry, c=us
|
||||
- ** but if the target is "o=ace industry, c=us", then we are in trouble.
|
||||
- **
|
||||
- ** If the aci is in the rootdse and the entry is not, then we do not
|
||||
- ** match--ie. acis in the rootdse do NOT apply below...for the moment.
|
||||
- **
|
||||
- */
|
||||
+ /*
|
||||
+ * First Let's see if the entry is under the subtree where the
|
||||
+ * ACL resides. We can't let somebody affect a target beyond the
|
||||
+ * scope of where the ACL resides
|
||||
+ * Example: ACL is located in "ou=engineering, o=ace industry, c=us
|
||||
+ * but if the target is "o=ace industry, c=us", then we are in trouble.
|
||||
+ *
|
||||
+ * If the aci is in the rootdse and the entry is not, then we do not
|
||||
+ * match--ie. acis in the rootdse do NOT apply below...for the moment.
|
||||
+ */
|
||||
res_ndn = slapi_sdn_get_ndn(aclpb->aclpb_curr_entry_sdn);
|
||||
aci_ndn = slapi_sdn_get_ndn(aci->aci_sdn);
|
||||
- if (!slapi_sdn_issuffix(aclpb->aclpb_curr_entry_sdn, aci->aci_sdn) || (!slapi_is_rootdse(res_ndn) && slapi_is_rootdse(aci_ndn))) {
|
||||
-
|
||||
- /* cant' poke around */
|
||||
+ if (!slapi_sdn_issuffix(aclpb->aclpb_curr_entry_sdn, aci->aci_sdn) ||
|
||||
+ (!slapi_is_rootdse(res_ndn) && slapi_is_rootdse(aci_ndn)))
|
||||
+ {
|
||||
+ /* can't poke around */
|
||||
matches = ACL_FALSE;
|
||||
goto acl__resource_match_aci_EXIT;
|
||||
}
|
||||
|
||||
/*
|
||||
- ** We have a single ACI which we need to find if it applies to
|
||||
- ** the resource or not.
|
||||
- */
|
||||
+ * We have a single ACI which we need to find if it applies to the resource or not.
|
||||
+ */
|
||||
if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) {
|
||||
char *avaType;
|
||||
struct berval *avaValue;
|
||||
@@ -2173,25 +2173,23 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
char *avaType;
|
||||
struct berval *avaValue;
|
||||
char logbuf[1024];
|
||||
-
|
||||
- /* We are evaluating the moddn permission.
|
||||
- * The aci contains target_to and target_from
|
||||
- *
|
||||
- * target_to filter must be checked against the resource ndn that was stored in
|
||||
- * aclpb->aclpb_curr_entry_sdn
|
||||
- *
|
||||
- * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn
|
||||
- * (sdn was stored in the pblock)
|
||||
- */
|
||||
+ /*
|
||||
+ * We are evaluating the moddn permission.
|
||||
+ * The aci contains target_to and target_from
|
||||
+ *
|
||||
+ * target_to filter must be checked against the resource ndn that was stored in
|
||||
+ * aclpb->aclpb_curr_entry_sdn
|
||||
+ *
|
||||
+ * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn
|
||||
+ * (sdn was stored in the pblock)
|
||||
+ */
|
||||
if (aci->target_to) {
|
||||
f = aci->target_to;
|
||||
dn_matched = ACL_TRUE;
|
||||
|
||||
/* Now check if the filter is a simple or substring filter */
|
||||
if (aci->aci_type & ACI_TARGET_MODDN_TO_PATTERN) {
|
||||
- /* This is a filter with substring
|
||||
- * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
|
||||
- */
|
||||
+ /* This is a filter with substring e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com */
|
||||
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_to substring: %s\n",
|
||||
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
if ((rv = acl_match_substring(f, (char *)res_ndn, 0 /* match suffix */)) != ACL_TRUE) {
|
||||
@@ -2204,9 +2202,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- /* This is a filter without substring
|
||||
- * e.g. ldap:///cn=accounts,dc=example,dc=com
|
||||
- */
|
||||
+ /* This is a filter without substring e.g. ldap:///cn=accounts,dc=example,dc=com */
|
||||
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_to: %s\n",
|
||||
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
slapi_filter_get_ava(f, &avaType, &avaValue);
|
||||
@@ -2230,8 +2226,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
/* Now check if the filter is a simple or substring filter */
|
||||
if (aci->aci_type & ACI_TARGET_MODDN_FROM_PATTERN) {
|
||||
/* This is a filter with substring
|
||||
- * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
|
||||
- */
|
||||
+ * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
|
||||
+ */
|
||||
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_from substring: %s\n",
|
||||
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
if ((rv = acl_match_substring(f, (char *)slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), 0 /* match suffix */)) != ACL_TRUE) {
|
||||
@@ -2243,11 +2239,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
goto acl__resource_match_aci_EXIT;
|
||||
}
|
||||
}
|
||||
-
|
||||
} else {
|
||||
- /* This is a filter without substring
|
||||
- * e.g. ldap:///cn=accounts,dc=example,dc=com
|
||||
- */
|
||||
+ /* This is a filter without substring e.g. ldap:///cn=accounts,dc=example,dc=com */
|
||||
slapi_log_err(SLAPI_LOG_ACL, plugin_name, "acl__resource_match_aci - moddn target_from: %s\n",
|
||||
slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
if (!slapi_dn_issuffix(slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), avaValue->bv_val)) {
|
||||
@@ -2269,10 +2262,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
}
|
||||
|
||||
if (aci->aci_type & ACI_TARGET_PATTERN) {
|
||||
-
|
||||
f = aci->target;
|
||||
dn_matched = ACL_TRUE;
|
||||
-
|
||||
if ((rv = acl_match_substring(f, (char *)res_ndn, 0 /* match suffux */)) != ACL_TRUE) {
|
||||
dn_matched = ACL_FALSE;
|
||||
if (rv == ACL_ERR) {
|
||||
@@ -2296,7 +2287,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
|
||||
/*
|
||||
* Is it a (target="ldap://cn=*,($dn),o=sun.com") kind of thing.
|
||||
- */
|
||||
+ */
|
||||
if (aci->aci_type & ACI_TARGET_MACRO_DN) {
|
||||
/*
|
||||
* See if the ($dn) component matches the string and
|
||||
@@ -2306,8 +2297,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* entry is the same one don't recalculate it--
|
||||
* this flag only works for search right now, could
|
||||
* also optimise for mods by making it work for mods.
|
||||
- */
|
||||
-
|
||||
+ */
|
||||
if ((aclpb->aclpb_res_type & ACLPB_NEW_ENTRY) == 0) {
|
||||
/*
|
||||
* Here same entry so just look up the matched value,
|
||||
@@ -2356,8 +2346,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* If there is already an entry for this aci in this
|
||||
* aclpb then remove it--it's an old value for a
|
||||
* different entry.
|
||||
- */
|
||||
-
|
||||
+ */
|
||||
acl_ht_add_and_freeOld(aclpb->aclpb_macro_ht,
|
||||
(PLHashNumber)aci->aci_index,
|
||||
matched_val);
|
||||
@@ -2381,30 +2370,27 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
}
|
||||
|
||||
/*
|
||||
- ** Here, if there's a targetfilter field, see if it matches.
|
||||
- **
|
||||
- ** The commented out code below was an erroneous attempt to skip
|
||||
- ** this test. It is wrong because: 1. you need to store
|
||||
- ** whether the last test matched or not (you cannot just assume it did)
|
||||
- ** and 2. It may not be the same aci, so the previous matched
|
||||
- ** value is a function of the aci.
|
||||
- ** May be interesting to build such a cache...but no evidence for
|
||||
- ** for that right now. See Bug 383424.
|
||||
- **
|
||||
- **
|
||||
- ** && ((aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_LIST) ||
|
||||
- ** (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY))
|
||||
- */
|
||||
+ * Here, if there's a targetfilter field, see if it matches.
|
||||
+ *
|
||||
+ * The commented out code below was an erroneous attempt to skip
|
||||
+ * this test. It is wrong because: 1. you need to store
|
||||
+ * whether the last test matched or not (you cannot just assume it did)
|
||||
+ * and 2. It may not be the same aci, so the previous matched
|
||||
+ * value is a function of the aci.
|
||||
+ * May be interesting to build such a cache...but no evidence for
|
||||
+ * for that right now. See Bug 383424.
|
||||
+ *
|
||||
+ *
|
||||
+ * && ((aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_LIST) ||
|
||||
+ * (aclpb->aclpb_res_type & ACLPB_NEW_ENTRY))
|
||||
+ */
|
||||
if (aci->aci_type & ACI_TARGET_FILTER) {
|
||||
int filter_matched = ACL_TRUE;
|
||||
-
|
||||
/*
|
||||
* Check for macros.
|
||||
* For targetfilter we need to fake the lasinfo structure--it's
|
||||
* created "naturally" for subjects but not targets.
|
||||
- */
|
||||
-
|
||||
-
|
||||
+ */
|
||||
if (aci->aci_type & ACI_TARGET_FILTER_MACRO_DN) {
|
||||
|
||||
lasInfo *lasinfo = NULL;
|
||||
@@ -2419,11 +2405,9 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
ACL_EVAL_TARGET_FILTER);
|
||||
slapi_ch_free((void **)&lasinfo);
|
||||
} else {
|
||||
-
|
||||
-
|
||||
if (slapi_vattr_filter_test(NULL, aclpb->aclpb_curr_entry,
|
||||
aci->targetFilter,
|
||||
- 0 /*don't do acess chk*/) != 0) {
|
||||
+ 0 /*don't do access check*/) != 0) {
|
||||
filter_matched = ACL_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -2450,7 +2434,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* Check to see if we need to evaluate any targetattrfilters.
|
||||
* They look as follows:
|
||||
* (targetattrfilters="add=sn:(sn=rob) && gn:(gn!=byrne),
|
||||
- * del=sn:(sn=rob) && gn:(gn=byrne)")
|
||||
+ * del=sn:(sn=rob) && gn:(gn=byrne)")
|
||||
*
|
||||
* For ADD/DELETE:
|
||||
* If theres's a targetattrfilter then each add/del filter
|
||||
@@ -2458,29 +2442,25 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* by each value of the attribute in the entry.
|
||||
*
|
||||
* For MODIFY:
|
||||
- * If there's a targetattrfilter then the add/del filter
|
||||
+ * If there's a targetattrfilter then the add/del filter
|
||||
* must be satisfied by the attribute to be added/deleted.
|
||||
* (MODIFY acl is evaluated one value at a time).
|
||||
*
|
||||
*
|
||||
- */
|
||||
-
|
||||
+ */
|
||||
if (((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
|
||||
(aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
|
||||
((aclpb->aclpb_access & SLAPI_ACL_DELETE) &&
|
||||
- (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) {
|
||||
-
|
||||
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)))
|
||||
+ {
|
||||
Targetattrfilter **attrFilterArray = NULL;
|
||||
-
|
||||
Targetattrfilter *attrFilter = NULL;
|
||||
-
|
||||
Slapi_Attr *attr_ptr = NULL;
|
||||
Slapi_Value *sval;
|
||||
const struct berval *attrVal;
|
||||
int k;
|
||||
int done;
|
||||
|
||||
-
|
||||
if ((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
|
||||
(aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) {
|
||||
|
||||
@@ -2497,28 +2477,20 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
|
||||
while (attrFilterArray && attrFilterArray[num_attrs] && attr_matched) {
|
||||
attrFilter = attrFilterArray[num_attrs];
|
||||
-
|
||||
/*
|
||||
- * If this filter applies to an attribute in the entry,
|
||||
- * apply it to the entry.
|
||||
- * Otherwise just ignore it.
|
||||
- *
|
||||
- */
|
||||
-
|
||||
- if (slapi_entry_attr_find(aclpb->aclpb_curr_entry,
|
||||
- attrFilter->attr_str,
|
||||
- &attr_ptr) == 0) {
|
||||
-
|
||||
+ * If this filter applies to an attribute in the entry,
|
||||
+ * apply it to the entry.
|
||||
+ * Otherwise just ignore it.
|
||||
+ *
|
||||
+ */
|
||||
+ if (slapi_entry_attr_find(aclpb->aclpb_curr_entry, attrFilter->attr_str, &attr_ptr) == 0) {
|
||||
/*
|
||||
- * This is an applicable filter.
|
||||
- * The filter is to be appplied to the entry being added
|
||||
- * or deleted.
|
||||
- * The filter needs to be satisfied by _each_ occurence
|
||||
- * of the attribute in the entry--otherwise you
|
||||
- * could satisfy the filter and then put loads of other
|
||||
- * values in on the back of it.
|
||||
- */
|
||||
-
|
||||
+ * This is an applicable filter.
|
||||
+ * The filter is to be applied to the entry being added or deleted.
|
||||
+ * The filter needs to be satisfied by _each_ occurrence of the
|
||||
+ * attribute in the entry--otherwise you could satisfy the filter
|
||||
+ * and then put loads of other values in on the back of it.
|
||||
+ */
|
||||
sval = NULL;
|
||||
attrVal = NULL;
|
||||
k = slapi_attr_first_value(attr_ptr, &sval);
|
||||
@@ -2528,12 +2500,11 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
|
||||
if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry,
|
||||
attrFilter->attr_str,
|
||||
- (struct berval *)attrVal) == LDAP_SUCCESS) {
|
||||
-
|
||||
+ (struct berval *)attrVal) == LDAP_SUCCESS)
|
||||
+ {
|
||||
attr_matched = acl__test_filter(aclpb->aclpb_filter_test_entry,
|
||||
attrFilter->filter,
|
||||
- 1 /* Do filter sense evaluation below */
|
||||
- );
|
||||
+ 1 /* Do filter sense evaluation below */);
|
||||
done = !attr_matched;
|
||||
slapi_entry_free(aclpb->aclpb_filter_test_entry);
|
||||
}
|
||||
@@ -2542,19 +2513,19 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
} /* while */
|
||||
|
||||
/*
|
||||
- * Here, we applied an applicable filter to the entry.
|
||||
- * So if attr_matched is ACL_TRUE then every value
|
||||
- * of the attribute in the entry satisfied the filter.
|
||||
- * Otherwise, attr_matched is ACL_FALSE and not every
|
||||
- * value satisfied the filter, so we will teminate the
|
||||
- * scan of the filter list.
|
||||
- */
|
||||
+ * Here, we applied an applicable filter to the entry.
|
||||
+ * So if attr_matched is ACL_TRUE then every value
|
||||
+ * of the attribute in the entry satisfied the filter.
|
||||
+ * Otherwise, attr_matched is ACL_FALSE and not every
|
||||
+ * value satisfied the filter, so we will terminate the
|
||||
+ * scan of the filter list.
|
||||
+ */
|
||||
}
|
||||
|
||||
num_attrs++;
|
||||
} /* while */
|
||||
|
||||
-/*
|
||||
+ /*
|
||||
* Here, we've applied all the applicable filters to the entry.
|
||||
* Each one must have been satisfied by all the values of the attribute.
|
||||
* The result of this is stored in attr_matched.
|
||||
@@ -2585,7 +2556,8 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
} else if (((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
|
||||
(aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
|
||||
((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
|
||||
- (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS))) {
|
||||
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)))
|
||||
+ {
|
||||
/*
|
||||
* Here, it's a modify add/del and we have attr filters.
|
||||
* So, we need to scan the add/del filter list to find the filter
|
||||
@@ -2629,11 +2601,10 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* Otherwise, ignore the targetattrfilters.
|
||||
*/
|
||||
if (found) {
|
||||
-
|
||||
if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry,
|
||||
aclpb->aclpb_curr_attrEval->attrEval_name,
|
||||
- aclpb->aclpb_curr_attrVal) == LDAP_SUCCESS) {
|
||||
-
|
||||
+ aclpb->aclpb_curr_attrVal) == LDAP_SUCCESS)
|
||||
+ {
|
||||
attr_matched = acl__test_filter(aclpb->aclpb_filter_test_entry,
|
||||
attrFilter->filter,
|
||||
1 /* Do filter sense evaluation below */
|
||||
@@ -2651,20 +2622,21 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* Here this attribute appeared and was matched in a
|
||||
* targetattrfilters list, so record this fact so we do
|
||||
* not have to scan the targetattr list for the attribute.
|
||||
- */
|
||||
+ */
|
||||
|
||||
attr_matched_in_targetattrfilters = 1;
|
||||
}
|
||||
} /* targetvaluefilters */
|
||||
|
||||
|
||||
- /* There are 3 cases by which acis are selected.
|
||||
- ** 1) By scanning the whole list and picking based on the resource.
|
||||
- ** 2) By picking a subset of the list which will be used for the whole
|
||||
- ** acl evaluation.
|
||||
- ** 3) A finer granularity, i.e, a selected list of acls which will be
|
||||
- ** used for only that entry's evaluation.
|
||||
- */
|
||||
+ /*
|
||||
+ * There are 3 cases by which acis are selected.
|
||||
+ * 1) By scanning the whole list and picking based on the resource.
|
||||
+ * 2) By picking a subset of the list which will be used for the whole
|
||||
+ * acl evaluation.
|
||||
+ * 3) A finer granularity, i.e, a selected list of acls which will be
|
||||
+ * used for only that entry's evaluation.
|
||||
+ */
|
||||
if (!(skip_attrEval) && (aclpb->aclpb_state & ACLPB_SEARCH_BASED_ON_ENTRY_LIST) &&
|
||||
(res_right & SLAPI_ACL_SEARCH) &&
|
||||
((aci->aci_access & SLAPI_ACL_READ) || (aci->aci_access & SLAPI_ACL_SEARCH))) {
|
||||
@@ -2680,7 +2652,6 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
/* If we are suppose to skip attr eval, then let's skip it */
|
||||
if ((aclpb->aclpb_access & SLAPI_ACL_SEARCH) && (!skip_attrEval) &&
|
||||
(aclpb->aclpb_res_type & ACLPB_NEW_ENTRY)) {
|
||||
@@ -2697,9 +2668,10 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
goto acl__resource_match_aci_EXIT;
|
||||
}
|
||||
|
||||
- /* We need to check again because we don't want to select this handle
|
||||
- ** if the right doesn't match for now.
|
||||
- */
|
||||
+ /*
|
||||
+ * We need to check again because we don't want to select this handle
|
||||
+ * if the right doesn't match for now.
|
||||
+ */
|
||||
if (!(aci_right & res_right)) {
|
||||
matches = ACL_FALSE;
|
||||
goto acl__resource_match_aci_EXIT;
|
||||
@@ -2718,20 +2690,16 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
* rbyrneXXX if we had a proper permission for modrdn eg SLAPI_ACL_MODRDN
|
||||
* then we would not need this crappy way of telling it was a MODRDN
|
||||
* request ie. SLAPI_ACL_WRITE && !(c_attrEval).
|
||||
- */
|
||||
-
|
||||
+ */
|
||||
c_attrEval = aclpb->aclpb_curr_attrEval;
|
||||
|
||||
/*
|
||||
* If we've already matched on targattrfilter then do not
|
||||
* bother to look at the attrlist.
|
||||
- */
|
||||
-
|
||||
+ */
|
||||
if (!attr_matched_in_targetattrfilters) {
|
||||
-
|
||||
/* match target attr */
|
||||
- if ((c_attrEval) &&
|
||||
- (aci->aci_type & ACI_TARGET_ATTR)) {
|
||||
+ if ((c_attrEval) && (aci->aci_type & ACI_TARGET_ATTR)) {
|
||||
/* there is a target ATTR */
|
||||
Targetattr **attrArray = aci->targetAttr;
|
||||
Targetattr *attr = NULL;
|
||||
@@ -2773,46 +2741,43 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
matches = (attr_matched ? ACL_TRUE : ACL_FALSE);
|
||||
}
|
||||
|
||||
-
|
||||
aclpb->aclpb_state &= ~ACLPB_ATTR_STAR_MATCHED;
|
||||
/* figure out how it matched, i.e star matched */
|
||||
- if (matches && star_matched && num_attrs == 1 &&
|
||||
- !(aclpb->aclpb_state & ACLPB_FOUND_ATTR_RULE))
|
||||
+ if (matches && star_matched && num_attrs == 1 && !(aclpb->aclpb_state & ACLPB_FOUND_ATTR_RULE)) {
|
||||
aclpb->aclpb_state |= ACLPB_ATTR_STAR_MATCHED;
|
||||
- else {
|
||||
+ } else {
|
||||
/* we are here means that there is a specific
|
||||
- ** attr in the rule for this resource.
|
||||
- ** We need to avoid this case
|
||||
- ** Rule 1: (targetattr = "uid")
|
||||
- ** Rule 2: (targetattr = "*")
|
||||
- ** we cannot use STAR optimization
|
||||
- */
|
||||
+ * attr in the rule for this resource.
|
||||
+ * We need to avoid this case
|
||||
+ * Rule 1: (targetattr = "uid")
|
||||
+ * Rule 2: (targetattr = "*")
|
||||
+ * we cannot use STAR optimization
|
||||
+ */
|
||||
aclpb->aclpb_state |= ACLPB_FOUND_ATTR_RULE;
|
||||
aclpb->aclpb_state &= ~ACLPB_ATTR_STAR_MATCHED;
|
||||
}
|
||||
- } else if ((c_attrEval) ||
|
||||
- (aci->aci_type & ACI_TARGET_ATTR)) {
|
||||
+ } else if ((c_attrEval) || (aci->aci_type & ACI_TARGET_ATTR)) {
|
||||
if ((aci_right & ACL_RIGHTS_TARGETATTR_NOT_NEEDED) &&
|
||||
(aclpb->aclpb_access & ACL_RIGHTS_TARGETATTR_NOT_NEEDED)) {
|
||||
/*
|
||||
- ** Targetattr rule doesn't make any sense
|
||||
- ** in this case. So select this rule
|
||||
- ** default: matches = ACL_TRUE;
|
||||
- */
|
||||
+ * Targetattr rule doesn't make any sense
|
||||
+ * in this case. So select this rule
|
||||
+ * default: matches = ACL_TRUE;
|
||||
+ */
|
||||
;
|
||||
- } else if (aci_right & SLAPI_ACL_WRITE &&
|
||||
+ } else if ((aci_right & SLAPI_ACL_WRITE) &&
|
||||
(aci->aci_type & ACI_TARGET_ATTR) &&
|
||||
!(c_attrEval) &&
|
||||
(aci->aci_type & ACI_HAS_ALLOW_RULE)) {
|
||||
/* We need to handle modrdn operation. Modrdn doesn't
|
||||
- ** change any attrs but changes the RDN and so (attr=NULL).
|
||||
- ** Here we found an acl which has a targetattr but
|
||||
- ** the resource doesn't need one. In that case, we should
|
||||
- ** consider this acl.
|
||||
- ** the opposite is true if it is a deny rule, only a deny without
|
||||
- ** any targetattr should deny modrdn
|
||||
- ** default: matches = ACL_TRUE;
|
||||
- */
|
||||
+ * change any attrs but changes the RDN and so (attr=NULL).
|
||||
+ * Here we found an acl which has a targetattr but
|
||||
+ * the resource doesn't need one. In that case, we should
|
||||
+ * consider this acl.
|
||||
+ * the opposite is true if it is a deny rule, only a deny without
|
||||
+ * any targetattr should deny modrdn
|
||||
+ * default: matches = ACL_TRUE;
|
||||
+ */
|
||||
;
|
||||
} else {
|
||||
matches = ACL_FALSE;
|
||||
@@ -2821,16 +2786,16 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a
|
||||
} /* !attr_matched_in_targetattrfilters */
|
||||
|
||||
/*
|
||||
- ** Here we are testing if we find a entry test rule (which should
|
||||
- ** be rare). In that case, just remember it. An entry test rule
|
||||
- ** doesn't have "(targetattr)".
|
||||
- */
|
||||
+ * Here we are testing if we find a entry test rule (which should
|
||||
+ * be rare). In that case, just remember it. An entry test rule
|
||||
+ * doesn't have "(targetattr)".
|
||||
+ */
|
||||
if ((aclpb->aclpb_state & ACLPB_EVALUATING_FIRST_ATTR) &&
|
||||
(!(aci->aci_type & ACI_TARGET_ATTR))) {
|
||||
aclpb->aclpb_state |= ACLPB_FOUND_A_ENTRY_TEST_RULE;
|
||||
}
|
||||
|
||||
-/*
|
||||
+ /*
|
||||
* Generic exit point for this routine:
|
||||
* matches is ACL_TRUE if the aci matches the target of the resource,
|
||||
* ACL_FALSE othrewise.
|
||||
@@ -2853,6 +2818,7 @@ acl__resource_match_aci_EXIT:
|
||||
|
||||
return (matches);
|
||||
}
|
||||
+
|
||||
/* Macro to determine if the cached result is valid or not. */
|
||||
#define ACL_CACHED_RESULT_VALID(result) \
|
||||
(((result & ACLPB_CACHE_READ_RES_ALLOW) && \
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/findentry.c b/ldap/servers/slapd/back-ldbm/findentry.c
|
||||
index 6e53a0aea..bff751c88 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/findentry.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/findentry.c
|
||||
@@ -93,7 +93,6 @@ find_entry_internal_dn(
|
||||
size_t tries = 0;
|
||||
int isroot = 0;
|
||||
int op_type;
|
||||
- char *errbuf = NULL;
|
||||
|
||||
/* get the managedsait ldap message control */
|
||||
slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
|
||||
@@ -207,8 +206,8 @@ find_entry_internal_dn(
|
||||
break;
|
||||
}
|
||||
if (acl_type > 0) {
|
||||
- err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type,
|
||||
- ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
|
||||
+ char *dummy_attr = "1.1";
|
||||
+ err = slapi_access_allowed(pb, me->ep_entry, dummy_attr, NULL, acl_type);
|
||||
}
|
||||
if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) {
|
||||
/*
|
||||
@@ -237,7 +236,6 @@ find_entry_internal_dn(
|
||||
CACHE_RETURN(&inst->inst_cache, &me);
|
||||
}
|
||||
|
||||
- slapi_ch_free_string(&errbuf);
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "find_entry_internal_dn", "<= Not found (%s)\n",
|
||||
slapi_sdn_get_dn(sdn));
|
||||
return (NULL);
|
||||
diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
|
||||
index c60837601..ca6ea6ef8 100644
|
||||
--- a/src/lib389/lib389/_mapped_object.py
|
||||
+++ b/src/lib389/lib389/_mapped_object.py
|
||||
@@ -1190,7 +1190,7 @@ class DSLdapObjects(DSLogging, DSLints):
|
||||
# Now actually commit the creation req
|
||||
return co.ensure_state(rdn, properties, self._basedn)
|
||||
|
||||
- def filter(self, search, scope=None):
|
||||
+ def filter(self, search, scope=None, strict=False):
|
||||
# This will yield and & filter for objectClass with as many terms as needed.
|
||||
if search:
|
||||
search_filter = _gen_and([self._get_objectclass_filter(), search])
|
||||
@@ -1211,5 +1211,7 @@ class DSLdapObjects(DSLogging, DSLints):
|
||||
insts = [self._entry_to_instance(dn=r.dn, entry=r) for r in results]
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
# There are no objects to select from, se we return an empty array
|
||||
+ if strict:
|
||||
+ raise ldap.NO_SUCH_OBJECT
|
||||
insts = []
|
||||
return insts
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,145 @@
|
||||
From 4fb3023a55529c9d5332e3425ae8da590a8ebb69 Mon Sep 17 00:00:00 2001
|
||||
From: tbordaz <tbordaz@redhat.com>
|
||||
Date: Mon, 1 Feb 2021 09:28:25 +0100
|
||||
Subject: [PATCH 3/4] Issue 4581 - A failed re-indexing leaves the database in
|
||||
broken state (#4582)
|
||||
|
||||
Bug description:
|
||||
During reindex the numsubordinates attribute is not updated in parent entries.
|
||||
The consequence is that the internal counter job->numsubordinates==0.
|
||||
Later when indexing the ancestorid, the server can show the progression of this
|
||||
indexing with a ratio using job->numsubordinates==0.
|
||||
Division with 0 -> SIGFPE
|
||||
|
||||
Fix description:
|
||||
if the numsubordinates is NULL, log a message without a division.
|
||||
|
||||
relates: https://github.com/389ds/389-ds-base/issues/4581
|
||||
|
||||
Reviewed by: Pierre Rogier, Mark Reynolds, Simon Pichugin, Teko Mihinto (thanks !!)
|
||||
|
||||
Platforms tested: F31
|
||||
---
|
||||
.../slapd/back-ldbm/db-bdb/bdb_import.c | 72 ++++++++++++++-----
|
||||
1 file changed, 54 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c
|
||||
index 15574e60f..9713b52f6 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c
|
||||
@@ -468,18 +468,30 @@ bdb_get_nonleaf_ids(backend *be, DB_TXN *txn, IDList **idl, ImportJob *job)
|
||||
}
|
||||
key_count++;
|
||||
if (!(key_count % PROGRESS_INTERVAL)) {
|
||||
- import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
- "Gathering ancestorid non-leaf IDs: processed %d%% (ID count %d)",
|
||||
- (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ if (job->numsubordinates) {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
+ "Gathering ancestorid non-leaf IDs: processed %d%% (ID count %d)",
|
||||
+ (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ } else {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
+ "Gathering ancestorid non-leaf IDs: processed %d ancestors...",
|
||||
+ key_count);
|
||||
+ }
|
||||
started_progress_logging = 1;
|
||||
}
|
||||
} while (ret == 0 && !(job->flags & FLAG_ABORT));
|
||||
|
||||
if (started_progress_logging) {
|
||||
/* finish what we started logging */
|
||||
- import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
- "Gathering ancestorid non-leaf IDs: processed %d%% (ID count %d)",
|
||||
- (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ if (job->numsubordinates) {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
+ "Gathering ancestorid non-leaf IDs: processed %d%% (ID count %d)",
|
||||
+ (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ } else {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
+ "Gathering ancestorid non-leaf IDs: processed %d ancestors",
|
||||
+ key_count);
|
||||
+ }
|
||||
}
|
||||
import_log_notice(job, SLAPI_LOG_INFO, "bdb_get_nonleaf_ids",
|
||||
"Finished gathering ancestorid non-leaf IDs.");
|
||||
@@ -660,9 +672,15 @@ bdb_ancestorid_default_create_index(backend *be, ImportJob *job)
|
||||
|
||||
key_count++;
|
||||
if (!(key_count % PROGRESS_INTERVAL)) {
|
||||
- import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
- "Creating ancestorid index: processed %d%% (ID count %d)",
|
||||
- (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ if (job->numsubordinates) {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
+ "Creating ancestorid index: processed %d%% (ID count %d)",
|
||||
+ (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ } else {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
+ "Creating ancestorid index: processed %d ancestors...",
|
||||
+ key_count);
|
||||
+ }
|
||||
started_progress_logging = 1;
|
||||
}
|
||||
|
||||
@@ -743,9 +761,15 @@ out:
|
||||
if (ret == 0) {
|
||||
if (started_progress_logging) {
|
||||
/* finish what we started logging */
|
||||
- import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
- "Creating ancestorid index: processed %d%% (ID count %d)",
|
||||
- (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ if (job->numsubordinates) {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
+ "Creating ancestorid index: processed %d%% (ID count %d)",
|
||||
+ (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ } else {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
+ "Creating ancestorid index: processed %d ancestors",
|
||||
+ key_count);
|
||||
+ }
|
||||
}
|
||||
import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_default_create_index",
|
||||
"Created ancestorid index (old idl).");
|
||||
@@ -869,9 +893,15 @@ bdb_ancestorid_new_idl_create_index(backend *be, ImportJob *job)
|
||||
|
||||
key_count++;
|
||||
if (!(key_count % PROGRESS_INTERVAL)) {
|
||||
- import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
- "Creating ancestorid index: progress %d%% (ID count %d)",
|
||||
- (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ if (job->numsubordinates) {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
+ "Creating ancestorid index: progress %d%% (ID count %d)",
|
||||
+ (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ } else {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
+ "Creating ancestorid index: progress %d ancestors...",
|
||||
+ key_count);
|
||||
+ }
|
||||
started_progress_logging = 1;
|
||||
}
|
||||
|
||||
@@ -932,9 +962,15 @@ out:
|
||||
if (ret == 0) {
|
||||
if (started_progress_logging) {
|
||||
/* finish what we started logging */
|
||||
- import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
- "Creating ancestorid index: processed %d%% (ID count %d)",
|
||||
- (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ if (job->numsubordinates) {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
+ "Creating ancestorid index: processed %d%% (ID count %d)",
|
||||
+ (key_count * 100 / job->numsubordinates), key_count);
|
||||
+ } else {
|
||||
+ import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
+ "Creating ancestorid index: processed %d ancestors",
|
||||
+ key_count);
|
||||
+ }
|
||||
}
|
||||
import_log_notice(job, SLAPI_LOG_INFO, "bdb_ancestorid_new_idl_create_index",
|
||||
"Created ancestorid index (new idl).");
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,163 @@
|
||||
From 861f17d2cb50fc649feee004be1ce08d2e3873f8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 9 Feb 2021 14:02:59 -0500
|
||||
Subject: [PATCH 4/4] Issue 4609 - CVE - info disclosure when authenticating
|
||||
|
||||
Description: If you bind as a user that does not exist. Error 49 is returned
|
||||
instead of error 32. As error 32 discloses that the entry does
|
||||
not exist. When you bind as an entry that does not have userpassword
|
||||
set then error 48 (inappropriate auth) is returned, but this
|
||||
discloses that the entry does indeed exist. Instead we should
|
||||
always return error 49, even if the password is not set in the
|
||||
entry. This way we do not disclose to an attacker if the Bind
|
||||
DN exists or not.
|
||||
|
||||
Relates: https://github.com/389ds/389-ds-base/issues/4609
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/suites/basic/basic_test.py | 72 +++++++++++++++++++-
|
||||
ldap/servers/slapd/back-ldbm/ldbm_bind.c | 4 +-
|
||||
ldap/servers/slapd/dse.c | 7 +-
|
||||
3 files changed, 78 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
|
||||
index e9afa1e7e..6244782fa 100644
|
||||
--- a/dirsrvtests/tests/suites/basic/basic_test.py
|
||||
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
from subprocess import check_output, PIPE, run
|
||||
from lib389 import DirSrv
|
||||
-from lib389.idm.user import UserAccounts
|
||||
+from lib389.idm.user import UserAccount, UserAccounts
|
||||
import pytest
|
||||
from lib389.tasks import *
|
||||
from lib389.utils import *
|
||||
@@ -1062,6 +1062,76 @@ def test_search_ou(topology_st):
|
||||
assert len(entries) == 0
|
||||
|
||||
|
||||
+def test_bind_invalid_entry(topology_st):
|
||||
+ """Test the failing bind does not return information about the entry
|
||||
+
|
||||
+ :id: 5cd9b083-eea6-426b-84ca-83c26fc49a6f
|
||||
+ :customerscenario: True
|
||||
+ :setup: Standalone instance
|
||||
+ :steps:
|
||||
+ 1: bind as non existing entry
|
||||
+ 2: check that bind info does not report 'No such entry'
|
||||
+ :expectedresults:
|
||||
+ 1: pass
|
||||
+ 2: pass
|
||||
+ """
|
||||
+
|
||||
+ topology_st.standalone.restart()
|
||||
+ INVALID_ENTRY="cn=foooo,%s" % DEFAULT_SUFFIX
|
||||
+ try:
|
||||
+ topology_st.standalone.simple_bind_s(INVALID_ENTRY, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.info('test_bind_invalid_entry: Failed to bind as %s (expected)' % INVALID_ENTRY)
|
||||
+ log.info('exception description: ' + e.args[0]['desc'])
|
||||
+ if 'info' in e.args[0]:
|
||||
+ log.info('exception info: ' + e.args[0]['info'])
|
||||
+ assert e.args[0]['desc'] == 'Invalid credentials'
|
||||
+ assert 'info' not in e.args[0]
|
||||
+ pass
|
||||
+
|
||||
+ log.info('test_bind_invalid_entry: PASSED')
|
||||
+
|
||||
+ # reset credentials
|
||||
+ topology_st.standalone.simple_bind_s(DN_DM, PW_DM)
|
||||
+
|
||||
+
|
||||
+def test_bind_entry_missing_passwd(topology_st):
|
||||
+ """
|
||||
+ :id: af209149-8fb8-48cb-93ea-3e82dd7119d2
|
||||
+ :setup: Standalone Instance
|
||||
+ :steps:
|
||||
+ 1. Bind as database entry that does not have userpassword set
|
||||
+ 2. Bind as database entry that does not exist
|
||||
+ 1. Bind as cn=config entry that does not have userpassword set
|
||||
+ 2. Bind as cn=config entry that does not exist
|
||||
+ :expectedresults:
|
||||
+ 1. Fails with error 49
|
||||
+ 2. Fails with error 49
|
||||
+ 3. Fails with error 49
|
||||
+ 4. Fails with error 49
|
||||
+ """
|
||||
+ user = UserAccount(topology_st.standalone, DEFAULT_SUFFIX)
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ # Bind as the suffix root entry which does not have a userpassword
|
||||
+ user.bind("some_password")
|
||||
+
|
||||
+ user = UserAccount(topology_st.standalone, "cn=not here," + DEFAULT_SUFFIX)
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ # Bind as the entry which does not exist
|
||||
+ user.bind("some_password")
|
||||
+
|
||||
+ # Test cn=config since it has its own code path
|
||||
+ user = UserAccount(topology_st.standalone, "cn=config")
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ # Bind as the config entry which does not have a userpassword
|
||||
+ user.bind("some_password")
|
||||
+
|
||||
+ user = UserAccount(topology_st.standalone, "cn=does not exist,cn=config")
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ # Bind as an entry under cn=config that does not exist
|
||||
+ user.bind("some_password")
|
||||
+
|
||||
+
|
||||
@pytest.mark.bz1044135
|
||||
@pytest.mark.ds47319
|
||||
def test_connection_buffer_size(topology_st):
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
||||
index fa450ecd5..38d115a32 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
||||
@@ -76,8 +76,8 @@ ldbm_back_bind(Slapi_PBlock *pb)
|
||||
case LDAP_AUTH_SIMPLE: {
|
||||
Slapi_Value cv;
|
||||
if (slapi_entry_attr_find(e->ep_entry, "userpassword", &attr) != 0) {
|
||||
- slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL,
|
||||
- NULL, 0, NULL);
|
||||
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set");
|
||||
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
||||
CACHE_RETURN(&inst->inst_cache, &e);
|
||||
rc = SLAPI_BIND_FAIL;
|
||||
goto bail;
|
||||
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
||||
index 0e22d3cec..0d3268046 100644
|
||||
--- a/ldap/servers/slapd/dse.c
|
||||
+++ b/ldap/servers/slapd/dse.c
|
||||
@@ -1443,7 +1443,8 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
|
||||
|
||||
ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK);
|
||||
if (ec == NULL) {
|
||||
- slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL);
|
||||
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not exist");
|
||||
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
||||
return (SLAPI_BIND_FAIL);
|
||||
}
|
||||
|
||||
@@ -1451,7 +1452,8 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
|
||||
case LDAP_AUTH_SIMPLE: {
|
||||
Slapi_Value cv;
|
||||
if (slapi_entry_attr_find(ec, "userpassword", &attr) != 0) {
|
||||
- slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL);
|
||||
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set");
|
||||
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
||||
slapi_entry_free(ec);
|
||||
return SLAPI_BIND_FAIL;
|
||||
}
|
||||
@@ -1459,6 +1461,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
|
||||
|
||||
slapi_value_init_berval(&cv, cred);
|
||||
if (slapi_pw_find_sv(bvals, &cv) != 0) {
|
||||
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
|
||||
slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
||||
slapi_entry_free(ec);
|
||||
value_done(&cv);
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,97 @@
|
||||
From 82db41ae6f76464a6ee3cbfdca8019bc809b3cf3 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <william@blackhats.net.au>
|
||||
Date: Thu, 26 Nov 2020 09:08:13 +1000
|
||||
Subject: [PATCH] Issue 4460 - BUG - lib389 should use system tls policy
|
||||
|
||||
Bug Description: Due to some changes in dsrc for tlsreqcert
|
||||
and how def open was structured in lib389, the system ldap.conf
|
||||
policy was ignored.
|
||||
|
||||
Fix Description: Default to using the system ldap.conf policy
|
||||
if undefined in lib389 or the tls_reqcert param in dsrc.
|
||||
|
||||
fixes: #4460
|
||||
|
||||
Author: William Brown <william@blackhats.net.au>
|
||||
|
||||
Review by: ???
|
||||
---
|
||||
src/lib389/lib389/__init__.py | 11 +++++++----
|
||||
src/lib389/lib389/cli_base/dsrc.py | 16 +++++++++-------
|
||||
2 files changed, 16 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py
|
||||
index 63d44b60a..dc18b2bfe 100644
|
||||
--- a/src/lib389/lib389/__init__.py
|
||||
+++ b/src/lib389/lib389/__init__.py
|
||||
@@ -962,7 +962,7 @@ class DirSrv(SimpleLDAPObject, object):
|
||||
# Now, we are still an allocated ds object so we can be re-installed
|
||||
self.state = DIRSRV_STATE_ALLOCATED
|
||||
|
||||
- def open(self, uri=None, saslmethod=None, sasltoken=None, certdir=None, starttls=False, connOnly=False, reqcert=ldap.OPT_X_TLS_HARD,
|
||||
+ def open(self, uri=None, saslmethod=None, sasltoken=None, certdir=None, starttls=False, connOnly=False, reqcert=None,
|
||||
usercert=None, userkey=None):
|
||||
'''
|
||||
It opens a ldap bound connection to dirsrv so that online
|
||||
@@ -1025,9 +1025,12 @@ class DirSrv(SimpleLDAPObject, object):
|
||||
try:
|
||||
# Note this sets LDAP.OPT not SELF. Because once self has opened
|
||||
# it can NOT change opts on reused (ie restart)
|
||||
- self.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, reqcert)
|
||||
- self.log.debug("Using certificate policy %s", reqcert)
|
||||
- self.log.debug("ldap.OPT_X_TLS_REQUIRE_CERT = %s", reqcert)
|
||||
+ if reqcert is not None:
|
||||
+ self.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, reqcert)
|
||||
+ self.log.debug("Using lib389 certificate policy %s", reqcert)
|
||||
+ else:
|
||||
+ self.log.debug("Using /etc/openldap/ldap.conf certificate policy")
|
||||
+ self.log.debug("ldap.OPT_X_TLS_REQUIRE_CERT = %s", self.get_option(ldap.OPT_X_TLS_REQUIRE_CERT))
|
||||
except ldap.LDAPError as e:
|
||||
self.log.fatal('TLS negotiation failed: %s', e)
|
||||
raise e
|
||||
diff --git a/src/lib389/lib389/cli_base/dsrc.py b/src/lib389/lib389/cli_base/dsrc.py
|
||||
index 9cad23437..8a4a2a55d 100644
|
||||
--- a/src/lib389/lib389/cli_base/dsrc.py
|
||||
+++ b/src/lib389/lib389/cli_base/dsrc.py
|
||||
@@ -45,7 +45,7 @@ def dsrc_arg_concat(args, dsrc_inst):
|
||||
'tls_cacertdir': None,
|
||||
'tls_cert': None,
|
||||
'tls_key': None,
|
||||
- 'tls_reqcert': ldap.OPT_X_TLS_HARD,
|
||||
+ 'tls_reqcert': None,
|
||||
'starttls': args.starttls,
|
||||
'prompt': False,
|
||||
'pwdfile': None,
|
||||
@@ -134,21 +134,23 @@ def dsrc_to_ldap(path, instance_name, log):
|
||||
dsrc_inst['binddn'] = config.get(instance_name, 'binddn', fallback=None)
|
||||
dsrc_inst['saslmech'] = config.get(instance_name, 'saslmech', fallback=None)
|
||||
if dsrc_inst['saslmech'] is not None and dsrc_inst['saslmech'] not in ['EXTERNAL', 'PLAIN']:
|
||||
- raise Exception("%s [%s] saslmech must be one of EXTERNAL or PLAIN" % (path, instance_name))
|
||||
+ raise ValueError("%s [%s] saslmech must be one of EXTERNAL or PLAIN" % (path, instance_name))
|
||||
|
||||
dsrc_inst['tls_cacertdir'] = config.get(instance_name, 'tls_cacertdir', fallback=None)
|
||||
dsrc_inst['tls_cert'] = config.get(instance_name, 'tls_cert', fallback=None)
|
||||
dsrc_inst['tls_key'] = config.get(instance_name, 'tls_key', fallback=None)
|
||||
- dsrc_inst['tls_reqcert'] = config.get(instance_name, 'tls_reqcert', fallback='hard')
|
||||
- if dsrc_inst['tls_reqcert'] not in ['never', 'allow', 'hard']:
|
||||
- raise Exception("dsrc tls_reqcert value invalid. %s [%s] tls_reqcert should be one of never, allow or hard" % (instance_name,
|
||||
- path))
|
||||
+ dsrc_inst['tls_reqcert'] = config.get(instance_name, 'tls_reqcert', fallback=None)
|
||||
if dsrc_inst['tls_reqcert'] == 'never':
|
||||
dsrc_inst['tls_reqcert'] = ldap.OPT_X_TLS_NEVER
|
||||
elif dsrc_inst['tls_reqcert'] == 'allow':
|
||||
dsrc_inst['tls_reqcert'] = ldap.OPT_X_TLS_ALLOW
|
||||
- else:
|
||||
+ elif dsrc_inst['tls_reqcert'] == 'hard':
|
||||
dsrc_inst['tls_reqcert'] = ldap.OPT_X_TLS_HARD
|
||||
+ elif dsrc_inst['tls_reqcert'] is None:
|
||||
+ # Use system value
|
||||
+ pass
|
||||
+ else:
|
||||
+ raise ValueError("dsrc tls_reqcert value invalid. %s [%s] tls_reqcert should be one of never, allow or hard" % (instance_name, path))
|
||||
dsrc_inst['starttls'] = config.getboolean(instance_name, 'starttls', fallback=False)
|
||||
dsrc_inst['pwdfile'] = None
|
||||
dsrc_inst['prompt'] = False
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,39 @@
|
||||
From 2d6ca042adcf0dc2bbf9b898d698bbf62514c4a5 Mon Sep 17 00:00:00 2001
|
||||
From: Firstyear <william@blackhats.net.au>
|
||||
Date: Fri, 4 Dec 2020 10:14:33 +1000
|
||||
Subject: [PATCH] Issue 4460 - BUG - add machine name to subject alt names in
|
||||
SSCA (#4472)
|
||||
|
||||
Bug Description: During SSCA creation, the server cert did not have
|
||||
the machine name, which meant that the cert would not work without
|
||||
reqcert = never.
|
||||
|
||||
Fix Description: Add the machine name as an alt name during SSCA
|
||||
creation. It is not guaranteed this value is correct, but it
|
||||
is better than nothing.
|
||||
|
||||
relates: https://github.com/389ds/389-ds-base/issues/4460
|
||||
|
||||
Author: William Brown <william@blackhats.net.au>
|
||||
|
||||
Review by: mreynolds389, droideck
|
||||
---
|
||||
src/lib389/lib389/instance/setup.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
|
||||
index 45c7dfdd4..21260ee20 100644
|
||||
--- a/src/lib389/lib389/instance/setup.py
|
||||
+++ b/src/lib389/lib389/instance/setup.py
|
||||
@@ -870,7 +870,7 @@ class SetupDs(object):
|
||||
tlsdb_inst = NssSsl(dbpath=os.path.join(etc_dirsrv_path, dir))
|
||||
tlsdb_inst.import_rsa_crt(ca)
|
||||
|
||||
- csr = tlsdb.create_rsa_key_and_csr()
|
||||
+ csr = tlsdb.create_rsa_key_and_csr(alt_names=[general['full_machine_name']])
|
||||
(ca, crt) = ssca.rsa_ca_sign_csr(csr)
|
||||
tlsdb.import_rsa_crt(ca, crt)
|
||||
if general['selinux']:
|
||||
--
|
||||
2.26.2
|
||||
|
@ -45,7 +45,7 @@ ExcludeArch: i686
|
||||
Summary: 389 Directory Server (base)
|
||||
Name: 389-ds-base
|
||||
Version: 1.4.3.8
|
||||
Release: %{?relprefix}6%{?prerel}%{?dist}
|
||||
Release: %{?relprefix}7%{?prerel}%{?dist}
|
||||
License: GPLv3+
|
||||
URL: https://www.port389.org
|
||||
Group: System Environment/Daemons
|
||||
@ -207,7 +207,12 @@ Patch30: 0030-ticket-2058-Add-keep-alive-entry-after-on-line-initi.patc
|
||||
Patch31: 0031-do-not-add-referrals-for-masters-with-different-data.patch
|
||||
Patch32: 0032-Issue-4383-Do-not-normalize-escaped-spaces-in-a-DN.patch
|
||||
Patch33: 0033-Issue-49300-entryUSN-is-duplicated-after-memberOf-op.patch
|
||||
|
||||
Patch34: 0034-Issue-4480-Unexpected-info-returned-to-ldap-request-.patch
|
||||
Patch35: 0035-Issue-5442-Search-results-are-different-between-RHDS.patch
|
||||
Patch36: 0036-Issue-4581-A-failed-re-indexing-leaves-the-database-.patch
|
||||
Patch37: 0037-Issue-4609-CVE-info-disclosure-when-authenticating.patch
|
||||
Patch38: 0038-Issue-4460-BUG-lib389-should-use-system-tls-policy.patch
|
||||
Patch39: 0039-Issue-4460-BUG-add-machine-name-to-subject-alt-names.patch
|
||||
|
||||
%description
|
||||
389 Directory Server is an LDAPv3 compliant server. The base package includes
|
||||
@ -825,15 +830,21 @@ exit 0
|
||||
%doc README.md
|
||||
|
||||
%changelog
|
||||
* Thu Mar 11 2021 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.8-7
|
||||
- Bump version to 1.4.3.8-7
|
||||
- Resolves: Bug 1908705 - CVE-2020-35518 389-ds:1.4/389-ds-base: information disclosure during the binding of a DN
|
||||
- Resolves: Bug 1936461 - A failed re-indexing leaves the database in broken state.
|
||||
- Resolves: Bug 1912481 - Server-Cert.crt created using dscreate has Subject:CN =localhost instead of hostname.
|
||||
|
||||
* Thu Dec 3 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.8-6
|
||||
- Bump version to 1.4.3.8-6
|
||||
- Resolves: Bug 1851973 - Duplicate entryUSN numbers for different LDAP entries in the same backend
|
||||
- Resolves: Bug 1888863 - group rdn with leading space char and add fails error 21 invalid syntax and delete fails error 32
|
||||
- Resolves: Bug 1859228 - do not add referrals for masters with different data generation
|
||||
- Resolves: Bug 1859227 - create keep alive entry after on line init
|
||||
- Resolves: Bug 1896850 - NULL dereference in revert_cache()
|
||||
- Resolves: Bug 1861504 - ds-replcheck crashes in offline mode
|
||||
- Resolves: Bug 1898850 - Entries conflict not resolved by replication
|
||||
- Resolves: Bug 1904348 - Duplicate entryUSN numbers for different LDAP entries in the same backend
|
||||
- Resolves: Bug 1904349 - group rdn with leading space char and add fails error 21 invalid syntax and delete fails error 32
|
||||
- Resolves: Bug 1904350 - do not add referrals for masters with different data generation
|
||||
- Resolves: Bug 1904351 - create keep alive entry after on line init
|
||||
- Resolves: Bug 1904352 - NULL dereference in revert_cache()
|
||||
- Resolves: Bug 1904353 - ds-replcheck crashes in offline mode
|
||||
- Resolves: Bug 1904347 - Entries conflict not resolved by replication
|
||||
|
||||
* Wed Aug 5 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.8-5
|
||||
- Bump version to 1.4.3.8-5
|
||||
|
Loading…
Reference in New Issue
Block a user