[389-ds-base] branch 389-ds-base-1.4.0 updated: Ticket 50273 - reduce default replicaton agmt timeout
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new 951c499 Ticket 50273 - reduce default replicaton agmt timeout
951c499 is described below
commit 951c499d92a19030ac32fdd76f9b269b69fe313c
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Mon Mar 11 11:38:01 2019 -0400
Ticket 50273 - reduce default replicaton agmt timeout
Description: The default timeout of 10 minutes is just too long.
Change default to 2 minutes.
https://pagure.io/389-ds-base/issue/50273
Reviewed by: tbordaz(Thanks!)
(cherry picked from commit a703d1017716159f9c84b2c8f6fb0246f9a6a8a8)
---
ldap/servers/plugins/replication/repl5_agmt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 95584ce..53e6708 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -57,7 +57,7 @@
#include "cl5_api.h"
#include "slapi-plugin.h"
-#define DEFAULT_TIMEOUT 600 /* (seconds) default outbound LDAP connection */
+#define DEFAULT_TIMEOUT 120 /* (seconds) default outbound LDAP connection */
#define DEFAULT_FLOWCONTROL_WINDOW 1000 /* #entries sent without acknowledgment */
#define DEFAULT_FLOWCONTROL_PAUSE 2000 /* msec of pause when #entries sent witout acknowledgment */
#define STATUS_LEN 1024
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
5 years, 1 month
[389-ds-base] branch 389-ds-base-1.3.9 updated: Ticket 50091 - shadowWarning is not generated if passwordWarning is lower than 86400 seconds (1 day)
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.3.9
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.9 by this push:
new 0ef0383 Ticket 50091 - shadowWarning is not generated if passwordWarning is lower than 86400 seconds (1 day)
0ef0383 is described below
commit 0ef0383322302163fdea115515f82b64cabab505
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Fri Dec 14 17:42:22 2018 +0100
Ticket 50091 - shadowWarning is not generated if passwordWarning is lower than 86400 seconds (1 day)
Bug Description:
For a shadowAccount, if a password policy defines passwordWarning below 1 days (86400 seconds)
then the shadowWarning (in day) is not returned from the entry. In such case its value is '0'.
Fix Description:
The fix is to accept shadowWarning = 0 as valid value and return it
https://pagure.io/389-ds-base/issue/50091
Reviewed by: Mark Reynolds
Platforms tested: F27
Flag Day: no
Doc impact: no
---
ldap/servers/slapd/pw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index ec23ed1..11149f5 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -2844,7 +2844,7 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
shadowval = _MAX_SHADOW;
}
}
- if (shadowval > 0) {
+ if (shadowval >= 0) {
shwarn = slapi_entry_attr_get_charptr(*e, "shadowWarning");
if (shwarn) {
sval = strtoll(shwarn, NULL, 0);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
5 years, 1 month
[389-ds-base] branch 389-ds-base-1.3.9 updated: Ticket 50234 - one level search returns not matching entry
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
lkrispen pushed a commit to branch 389-ds-base-1.3.9
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.9 by this push:
new b831fe0 Ticket 50234 - one level search returns not matching entry
b831fe0 is described below
commit b831fe0d35a9692d10932b3c09bae5a10aaf204d
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
AuthorDate: Thu Feb 21 16:54:52 2019 +0100
Ticket 50234 - one level search returns not matching entry
Bug: if in a onelevel search the IDList for the parentid is smaller than the filter
threshold and smaller than the list generated by the search filter
then the intersection is aborted and all children are returned.
Fix: In the above case we need to set the flag that the filter evaluation
cannot be bypassed
Reviewed by: William, Thierry. Thanks
---
dirsrvtests/tests/tickets/ticket50234_test.py | 70 +++++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/idl_set.c | 1 +
2 files changed, 71 insertions(+)
diff --git a/dirsrvtests/tests/tickets/ticket50234_test.py b/dirsrvtests/tests/tickets/ticket50234_test.py
new file mode 100644
index 0000000..c605c45
--- /dev/null
+++ b/dirsrvtests/tests/tickets/ticket50234_test.py
@@ -0,0 +1,70 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2019 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+import time
+import ldap
+import pytest
+
+from lib389.topologies import topology_st
+
+from lib389._constants import DEFAULT_SUFFIX
+
+from lib389.idm.user import UserAccount, UserAccounts
+from lib389.idm.organizationalunit import OrganizationalUnit
+
+log = logging.getLogger(__name__)
+
+def test_ticket50234(topology_st):
+ """
+ The fix for ticket 50234
+
+
+ The test sequence is:
+ - create more than 10 entries with objectclass organizational units ou=org{}
+ - add an Account in one of them, eg below ou=org5
+ - do searches with search base ou=org5 and search filter "objectclass=organizationalunit"
+ - a subtree search should return 1 entry, the base entry
+ - a onelevel search should return no entry
+ """
+
+ log.info('Testing Ticket 50234 - onelvel search returns not matching entry')
+
+ for i in range(1,15):
+ ou = OrganizationalUnit(topology_st.standalone, "ou=Org{},{}".format(i, DEFAULT_SUFFIX))
+ ou.create(properties={'ou': 'Org'.format(i)})
+
+ properties = {
+ 'uid': 'Jeff Vedder',
+ 'cn': 'Jeff Vedder',
+ 'sn': 'user',
+ 'uidNumber': '1000',
+ 'gidNumber': '2000',
+ 'homeDirectory': '/home/' + 'JeffVedder',
+ 'userPassword': 'password'
+ }
+ user = UserAccount(topology_st.standalone, "cn=Jeff Vedder,ou=org5,{}".format(DEFAULT_SUFFIX))
+ user.create(properties=properties)
+
+ # in a subtree search the entry used as search base matches the filter and shoul be returned
+ ent = topology_st.standalone.getEntry("ou=org5,{}".format(DEFAULT_SUFFIX), ldap.SCOPE_SUBTREE, "(objectclass=organizationalunit)")
+
+ # in a onelevel search the only child is an useraccount which does not match the filter
+ # no entry should be returned, which would cause getEntry to raise an exception we need to handle
+ found = 1
+ try:
+ ent = topology_st.standalone.getEntry("ou=org5,{}".format(DEFAULT_SUFFIX), ldap.SCOPE_ONELEVEL, "(objectclass=organizationalunit)")
+ except ldap.NO_SUCH_OBJECT:
+ found = 0
+ assert (found == 0)
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
diff --git a/ldap/servers/slapd/back-ldbm/idl_set.c b/ldap/servers/slapd/back-ldbm/idl_set.c
index f9a900f..6b65867 100644
--- a/ldap/servers/slapd/back-ldbm/idl_set.c
+++ b/ldap/servers/slapd/back-ldbm/idl_set.c
@@ -371,6 +371,7 @@ idl_set_intersect(IDListSet *idl_set, backend *be)
result_list = idl_set->head;
} else if (idl_set->minimum->b_nids <= FILTER_TEST_THRESHOLD) {
result_list = idl_set->minimum;
+ slapi_be_set_flag(be, SLAPI_BE_FLAG_DONT_BYPASS_FILTERTEST);
/* Free the other IDLs which are not the minimum. */
IDList *next = NULL;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
5 years, 1 month
[389-ds-base] branch 389-ds-base-1.3.9 updated: Ticket 50232 - export creates not importable ldif file
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
lkrispen pushed a commit to branch 389-ds-base-1.3.9
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.9 by this push:
new 7dbf7d8 Ticket 50232 - export creates not importable ldif file
7dbf7d8 is described below
commit 7dbf7d8db68188a2ad2824e17a076897c736808c
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
AuthorDate: Wed Feb 20 10:11:15 2019 +0100
Ticket 50232 - export creates not importable ldif file
Bug: If the RUV entry hasa smaller entryid than the suffix entry it will be
exported before the suffix. If that ldif is used for import the RUV entry
is skipped and a new one generated with a different database generation
Fix: Before exporting the RUV check that the suffix is alread exported, if not
make the RUV entry pending and write it after all othere entries
Reviewed by: tbordaz, wbrown. Thanks
---
dirsrvtests/tests/tickets/ticket50232_test.py | 163 ++++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 58 ++++++++-
2 files changed, 219 insertions(+), 2 deletions(-)
diff --git a/dirsrvtests/tests/tickets/ticket50232_test.py b/dirsrvtests/tests/tickets/ticket50232_test.py
new file mode 100644
index 0000000..133ed0d
--- /dev/null
+++ b/dirsrvtests/tests/tickets/ticket50232_test.py
@@ -0,0 +1,163 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+
+import pytest
+# from lib389.tasks import *
+# from lib389.utils import *
+from lib389.topologies import topology_st
+from lib389.replica import ReplicationManager,Replicas
+
+from lib389._constants import DEFAULT_SUFFIX, BACKEND_NAME
+
+from lib389.idm.user import UserAccounts
+from lib389.idm.organization import Organization
+from lib389.idm.organizationalunit import OrganizationalUnit
+
+log = logging.getLogger(__name__)
+
+NORMAL_SUFFIX = 'o=normal'
+NORMAL_BACKEND_NAME = 'normal'
+REVERSE_SUFFIX = 'o=reverse'
+REVERSE_BACKEND_NAME = 'reverse'
+
+def _enable_replica(instance, suffix):
+
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ repl._ensure_changelog(instance)
+ replicas = Replicas(instance)
+ replicas.create(properties={
+ 'cn': 'replica',
+ 'nsDS5ReplicaRoot': suffix,
+ 'nsDS5ReplicaId': '1',
+ 'nsDS5Flags': '1',
+ 'nsDS5ReplicaType': '3'
+ })
+
+def _populate_suffix(instance, suffixname):
+
+ o = Organization(instance, 'o={}'.format(suffixname))
+ o.create(properties={
+ 'o': suffixname,
+ 'description': 'test'
+ })
+ ou = OrganizationalUnit(instance, 'ou=people,o={}'.format(suffixname))
+ ou.create(properties={
+ 'ou': 'people'
+ })
+
+def _get_replica_generation(instance, suffix):
+
+ replicas = Replicas(instance)
+ replica = replicas.get(suffix)
+ ruv = replica.get_ruv()
+ return ruv._data_generation
+
+def _test_export_import(instance, suffix, backend):
+
+ before_generation = _get_replica_generation(instance, suffix)
+
+ instance.stop()
+ instance.db2ldif(
+ bename=backend,
+ suffixes=[suffix],
+ excludeSuffixes=[],
+ encrypt=False,
+ repl_data=True,
+ outputfile="/tmp/output_file",
+ )
+ instance.ldif2db(
+ bename=None,
+ excludeSuffixes=None,
+ encrypt=False,
+ suffixes=[suffix],
+ import_file="/tmp/output_file",
+ )
+ instance.start()
+ after_generation = _get_replica_generation(instance, suffix)
+
+ assert (before_generation == after_generation)
+
+def test_ticket50232_normal(topology_st):
+ """
+ The fix for ticket 50232
+
+
+ The test sequence is:
+ - create suffix
+ - add suffix entry and some child entries
+ - "normally" done after populating suffix: enable replication
+ - get RUV and database generation
+ - export -r
+ - import
+ - get RUV and database generation
+ - assert database generation has not changed
+ """
+
+ log.info('Testing Ticket 50232 - export creates not imprtable ldif file, normal creation order')
+
+ topology_st.standalone.backend.create(NORMAL_SUFFIX, {BACKEND_NAME: NORMAL_BACKEND_NAME})
+ topology_st.standalone.mappingtree.create(NORMAL_SUFFIX, bename=NORMAL_BACKEND_NAME, parent=None)
+
+ _populate_suffix(topology_st.standalone, NORMAL_BACKEND_NAME)
+
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ repl._ensure_changelog(topology_st.standalone)
+ replicas = Replicas(topology_st.standalone)
+ replicas.create(properties={
+ 'cn': 'replica',
+ 'nsDS5ReplicaRoot': NORMAL_SUFFIX,
+ 'nsDS5ReplicaId': '1',
+ 'nsDS5Flags': '1',
+ 'nsDS5ReplicaType': '3'
+ })
+
+ _test_export_import(topology_st.standalone, NORMAL_SUFFIX, NORMAL_BACKEND_NAME)
+
+def test_ticket50232_reverse(topology_st):
+ """
+ The fix for ticket 50232
+
+
+ The test sequence is:
+ - create suffix
+ - enable replication before suffix enztry is added
+ - add suffix entry and some child entries
+ - get RUV and database generation
+ - export -r
+ - import
+ - get RUV and database generation
+ - assert database generation has not changed
+ """
+
+ log.info('Testing Ticket 50232 - export creates not imprtable ldif file, normal creation order')
+
+ #
+ # Setup Replication
+ #
+ log.info('Setting up replication...')
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ # repl.create_first_master(topology_st.standalone)
+ #
+ # enable dynamic plugins, memberof and retro cl plugin
+ #
+ topology_st.standalone.backend.create(REVERSE_SUFFIX, {BACKEND_NAME: REVERSE_BACKEND_NAME})
+ topology_st.standalone.mappingtree.create(REVERSE_SUFFIX, bename=REVERSE_BACKEND_NAME, parent=None)
+
+ _enable_replica(topology_st.standalone, REVERSE_SUFFIX)
+
+ _populate_suffix(topology_st.standalone, REVERSE_BACKEND_NAME)
+
+ _test_export_import(topology_st.standalone, REVERSE_SUFFIX, REVERSE_BACKEND_NAME)
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 11c020a..49fe7cd 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1103,6 +1103,7 @@ bail:
* (reunified at last)
*/
#define LDBM2LDIF_BUSY (-2)
+#define RUVRDN SLAPI_ATTR_UNIQUEID "=" RUV_STORAGE_ENTRY_UNIQUEID
int
ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
{
@@ -1111,6 +1112,7 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
DB *db = NULL;
DBC *dbc = NULL;
struct backentry *ep;
+ struct backentry *pending_ruv = NULL;
DBT key = {0};
DBT data = {0};
char *fname = NULL;
@@ -1146,6 +1148,8 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
static int load_dse = 1; /* We'd like to load dse just once. */
int server_running;
export_args eargs = {0};
+ int32_t suffix_written = 0;
+ int32_t skip_ruv = 0;
slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_ldbm2ldif", "=>\n");
@@ -1463,8 +1467,25 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
}
}
- if (0 != return_value)
+ if (DB_NOTFOUND == return_value) {
+ /* reached the end of the database,
+ * check if ruv is pending and write it
+ */
+ if (pending_ruv) {
+ eargs.ep = pending_ruv;
+ eargs.idindex = idindex;
+ eargs.cnt = &cnt;
+ eargs.lastcnt = &lastcnt;
+ rc = export_one_entry(li, inst, &eargs);
+ backentry_free(&pending_ruv);
+ }
+ break;
+ }
+
+ if (0 != return_value) {
+ /* error reading database */
break;
+ }
/* back to internal format */
temp_id = id_stored_to_internal((char *)key.data);
@@ -1501,7 +1522,30 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
rc = get_value_from_string((const char *)data.dptr,
LDBM_PARENTID_STR, &pid_str);
if (rc) {
- rc = 0; /* assume this is a suffix */
+ /* this could be a suffix or the RUV entry.
+ * If it is the ruv and the suffix is not written
+ * keep the ruv and export as last entry.
+ *
+ * The reason for this is that if the RUV entry is in the
+ * ldif before the suffix entry then at an attempt to import
+ * that ldif the RUV entry would be skipped because the parent
+ * does not exist. Later a new RUV would be generated with
+ * a different database generation and replication is broken
+ */
+ if (suffix_written) {
+ /* this must be the RUV, just continue and write it */
+ rc = 0;
+ } else if (0 == strcasecmp(rdn, RUVRDN)) {
+ /* this is the RUV and the suffix is not yet written
+ * make it pending and continue with next entry
+ */
+ skip_ruv = 1;
+ rc = 0;
+ } else {
+ /* this has to be the suffix */
+ suffix_written = 1;
+ rc = 0;
+ }
} else {
pid = (ID)strtol(pid_str, (char **)NULL, 10);
slapi_ch_free_string(&pid_str);
@@ -1614,6 +1658,16 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
continue;
}
+ if (skip_ruv) {
+ /* now we keep a copy of the ruv entry
+ * and continue with the next entry
+ */
+ pending_ruv = ep;
+ ep = NULL;
+ skip_ruv = 0;
+ continue;
+ }
+
eargs.ep = ep;
eargs.idindex = idindex;
eargs.cnt = &cnt;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
5 years, 1 month
[389-ds-base] branch 389-ds-base-1.4.0 updated: Ticket 50234 - one level search returns not matching entry
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
lkrispen pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new 0654777 Ticket 50234 - one level search returns not matching entry
0654777 is described below
commit 0654777e74e2b1f1c1b4ffe0cae43b666d6af0e0
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
AuthorDate: Thu Feb 21 16:54:52 2019 +0100
Ticket 50234 - one level search returns not matching entry
Bug: if in a onelevel search the IDList for the parentid is smaller than the filter
threshold and smaller than the list generated by the search filter
then the intersection is aborted and all children are returned.
Fix: In the above case we need to set the flag that the filter evaluation
cannot be bypassed
Reviewed by: William, Thierry. Thanks
---
dirsrvtests/tests/tickets/ticket50234_test.py | 70 +++++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/idl_set.c | 1 +
2 files changed, 71 insertions(+)
diff --git a/dirsrvtests/tests/tickets/ticket50234_test.py b/dirsrvtests/tests/tickets/ticket50234_test.py
new file mode 100644
index 0000000..c605c45
--- /dev/null
+++ b/dirsrvtests/tests/tickets/ticket50234_test.py
@@ -0,0 +1,70 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2019 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+import time
+import ldap
+import pytest
+
+from lib389.topologies import topology_st
+
+from lib389._constants import DEFAULT_SUFFIX
+
+from lib389.idm.user import UserAccount, UserAccounts
+from lib389.idm.organizationalunit import OrganizationalUnit
+
+log = logging.getLogger(__name__)
+
+def test_ticket50234(topology_st):
+ """
+ The fix for ticket 50234
+
+
+ The test sequence is:
+ - create more than 10 entries with objectclass organizational units ou=org{}
+ - add an Account in one of them, eg below ou=org5
+ - do searches with search base ou=org5 and search filter "objectclass=organizationalunit"
+ - a subtree search should return 1 entry, the base entry
+ - a onelevel search should return no entry
+ """
+
+ log.info('Testing Ticket 50234 - onelvel search returns not matching entry')
+
+ for i in range(1,15):
+ ou = OrganizationalUnit(topology_st.standalone, "ou=Org{},{}".format(i, DEFAULT_SUFFIX))
+ ou.create(properties={'ou': 'Org'.format(i)})
+
+ properties = {
+ 'uid': 'Jeff Vedder',
+ 'cn': 'Jeff Vedder',
+ 'sn': 'user',
+ 'uidNumber': '1000',
+ 'gidNumber': '2000',
+ 'homeDirectory': '/home/' + 'JeffVedder',
+ 'userPassword': 'password'
+ }
+ user = UserAccount(topology_st.standalone, "cn=Jeff Vedder,ou=org5,{}".format(DEFAULT_SUFFIX))
+ user.create(properties=properties)
+
+ # in a subtree search the entry used as search base matches the filter and shoul be returned
+ ent = topology_st.standalone.getEntry("ou=org5,{}".format(DEFAULT_SUFFIX), ldap.SCOPE_SUBTREE, "(objectclass=organizationalunit)")
+
+ # in a onelevel search the only child is an useraccount which does not match the filter
+ # no entry should be returned, which would cause getEntry to raise an exception we need to handle
+ found = 1
+ try:
+ ent = topology_st.standalone.getEntry("ou=org5,{}".format(DEFAULT_SUFFIX), ldap.SCOPE_ONELEVEL, "(objectclass=organizationalunit)")
+ except ldap.NO_SUCH_OBJECT:
+ found = 0
+ assert (found == 0)
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
diff --git a/ldap/servers/slapd/back-ldbm/idl_set.c b/ldap/servers/slapd/back-ldbm/idl_set.c
index f9a900f..6b65867 100644
--- a/ldap/servers/slapd/back-ldbm/idl_set.c
+++ b/ldap/servers/slapd/back-ldbm/idl_set.c
@@ -371,6 +371,7 @@ idl_set_intersect(IDListSet *idl_set, backend *be)
result_list = idl_set->head;
} else if (idl_set->minimum->b_nids <= FILTER_TEST_THRESHOLD) {
result_list = idl_set->minimum;
+ slapi_be_set_flag(be, SLAPI_BE_FLAG_DONT_BYPASS_FILTERTEST);
/* Free the other IDLs which are not the minimum. */
IDList *next = NULL;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
5 years, 1 month
[389-ds-base] branch 389-ds-base-1.4.0 updated: Ticket 50232 - export creates not importable ldif file
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
lkrispen pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new 0f78530 Ticket 50232 - export creates not importable ldif file
0f78530 is described below
commit 0f7853046b8c6487fd299e404c73172fec8437e6
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
AuthorDate: Wed Feb 20 10:11:15 2019 +0100
Ticket 50232 - export creates not importable ldif file
Bug: If the RUV entry hasa smaller entryid than the suffix entry it will be
exported before the suffix. If that ldif is used for import the RUV entry
is skipped and a new one generated with a different database generation
Fix: Before exporting the RUV check that the suffix is alread exported, if not
make the RUV entry pending and write it after all othere entries
Reviewed by: tbordaz, wbrown. Thanks
---
dirsrvtests/tests/tickets/ticket50232_test.py | 163 ++++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 58 ++++++++-
2 files changed, 219 insertions(+), 2 deletions(-)
diff --git a/dirsrvtests/tests/tickets/ticket50232_test.py b/dirsrvtests/tests/tickets/ticket50232_test.py
new file mode 100644
index 0000000..133ed0d
--- /dev/null
+++ b/dirsrvtests/tests/tickets/ticket50232_test.py
@@ -0,0 +1,163 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+
+import pytest
+# from lib389.tasks import *
+# from lib389.utils import *
+from lib389.topologies import topology_st
+from lib389.replica import ReplicationManager,Replicas
+
+from lib389._constants import DEFAULT_SUFFIX, BACKEND_NAME
+
+from lib389.idm.user import UserAccounts
+from lib389.idm.organization import Organization
+from lib389.idm.organizationalunit import OrganizationalUnit
+
+log = logging.getLogger(__name__)
+
+NORMAL_SUFFIX = 'o=normal'
+NORMAL_BACKEND_NAME = 'normal'
+REVERSE_SUFFIX = 'o=reverse'
+REVERSE_BACKEND_NAME = 'reverse'
+
+def _enable_replica(instance, suffix):
+
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ repl._ensure_changelog(instance)
+ replicas = Replicas(instance)
+ replicas.create(properties={
+ 'cn': 'replica',
+ 'nsDS5ReplicaRoot': suffix,
+ 'nsDS5ReplicaId': '1',
+ 'nsDS5Flags': '1',
+ 'nsDS5ReplicaType': '3'
+ })
+
+def _populate_suffix(instance, suffixname):
+
+ o = Organization(instance, 'o={}'.format(suffixname))
+ o.create(properties={
+ 'o': suffixname,
+ 'description': 'test'
+ })
+ ou = OrganizationalUnit(instance, 'ou=people,o={}'.format(suffixname))
+ ou.create(properties={
+ 'ou': 'people'
+ })
+
+def _get_replica_generation(instance, suffix):
+
+ replicas = Replicas(instance)
+ replica = replicas.get(suffix)
+ ruv = replica.get_ruv()
+ return ruv._data_generation
+
+def _test_export_import(instance, suffix, backend):
+
+ before_generation = _get_replica_generation(instance, suffix)
+
+ instance.stop()
+ instance.db2ldif(
+ bename=backend,
+ suffixes=[suffix],
+ excludeSuffixes=[],
+ encrypt=False,
+ repl_data=True,
+ outputfile="/tmp/output_file",
+ )
+ instance.ldif2db(
+ bename=None,
+ excludeSuffixes=None,
+ encrypt=False,
+ suffixes=[suffix],
+ import_file="/tmp/output_file",
+ )
+ instance.start()
+ after_generation = _get_replica_generation(instance, suffix)
+
+ assert (before_generation == after_generation)
+
+def test_ticket50232_normal(topology_st):
+ """
+ The fix for ticket 50232
+
+
+ The test sequence is:
+ - create suffix
+ - add suffix entry and some child entries
+ - "normally" done after populating suffix: enable replication
+ - get RUV and database generation
+ - export -r
+ - import
+ - get RUV and database generation
+ - assert database generation has not changed
+ """
+
+ log.info('Testing Ticket 50232 - export creates not imprtable ldif file, normal creation order')
+
+ topology_st.standalone.backend.create(NORMAL_SUFFIX, {BACKEND_NAME: NORMAL_BACKEND_NAME})
+ topology_st.standalone.mappingtree.create(NORMAL_SUFFIX, bename=NORMAL_BACKEND_NAME, parent=None)
+
+ _populate_suffix(topology_st.standalone, NORMAL_BACKEND_NAME)
+
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ repl._ensure_changelog(topology_st.standalone)
+ replicas = Replicas(topology_st.standalone)
+ replicas.create(properties={
+ 'cn': 'replica',
+ 'nsDS5ReplicaRoot': NORMAL_SUFFIX,
+ 'nsDS5ReplicaId': '1',
+ 'nsDS5Flags': '1',
+ 'nsDS5ReplicaType': '3'
+ })
+
+ _test_export_import(topology_st.standalone, NORMAL_SUFFIX, NORMAL_BACKEND_NAME)
+
+def test_ticket50232_reverse(topology_st):
+ """
+ The fix for ticket 50232
+
+
+ The test sequence is:
+ - create suffix
+ - enable replication before suffix enztry is added
+ - add suffix entry and some child entries
+ - get RUV and database generation
+ - export -r
+ - import
+ - get RUV and database generation
+ - assert database generation has not changed
+ """
+
+ log.info('Testing Ticket 50232 - export creates not imprtable ldif file, normal creation order')
+
+ #
+ # Setup Replication
+ #
+ log.info('Setting up replication...')
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ # repl.create_first_master(topology_st.standalone)
+ #
+ # enable dynamic plugins, memberof and retro cl plugin
+ #
+ topology_st.standalone.backend.create(REVERSE_SUFFIX, {BACKEND_NAME: REVERSE_BACKEND_NAME})
+ topology_st.standalone.mappingtree.create(REVERSE_SUFFIX, bename=REVERSE_BACKEND_NAME, parent=None)
+
+ _enable_replica(topology_st.standalone, REVERSE_SUFFIX)
+
+ _populate_suffix(topology_st.standalone, REVERSE_BACKEND_NAME)
+
+ _test_export_import(topology_st.standalone, REVERSE_SUFFIX, REVERSE_BACKEND_NAME)
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index a5c8c82..2266ea9 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1103,6 +1103,7 @@ bail:
* (reunified at last)
*/
#define LDBM2LDIF_BUSY (-2)
+#define RUVRDN SLAPI_ATTR_UNIQUEID "=" RUV_STORAGE_ENTRY_UNIQUEID
int
ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
{
@@ -1111,6 +1112,7 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
DB *db = NULL;
DBC *dbc = NULL;
struct backentry *ep;
+ struct backentry *pending_ruv = NULL;
DBT key = {0};
DBT data = {0};
char *fname = NULL;
@@ -1146,6 +1148,8 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
static int load_dse = 1; /* We'd like to load dse just once. */
int server_running;
export_args eargs = {0};
+ int32_t suffix_written = 0;
+ int32_t skip_ruv = 0;
slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_ldbm2ldif", "=>\n");
@@ -1463,8 +1467,25 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
}
}
- if (0 != return_value)
+ if (DB_NOTFOUND == return_value) {
+ /* reached the end of the database,
+ * check if ruv is pending and write it
+ */
+ if (pending_ruv) {
+ eargs.ep = pending_ruv;
+ eargs.idindex = idindex;
+ eargs.cnt = &cnt;
+ eargs.lastcnt = &lastcnt;
+ rc = export_one_entry(li, inst, &eargs);
+ backentry_free(&pending_ruv);
+ }
+ break;
+ }
+
+ if (0 != return_value) {
+ /* error reading database */
break;
+ }
/* back to internal format */
temp_id = id_stored_to_internal((char *)key.data);
@@ -1501,7 +1522,30 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
rc = get_value_from_string((const char *)data.dptr,
LDBM_PARENTID_STR, &pid_str);
if (rc) {
- rc = 0; /* assume this is a suffix */
+ /* this could be a suffix or the RUV entry.
+ * If it is the ruv and the suffix is not written
+ * keep the ruv and export as last entry.
+ *
+ * The reason for this is that if the RUV entry is in the
+ * ldif before the suffix entry then at an attempt to import
+ * that ldif the RUV entry would be skipped because the parent
+ * does not exist. Later a new RUV would be generated with
+ * a different database generation and replication is broken
+ */
+ if (suffix_written) {
+ /* this must be the RUV, just continue and write it */
+ rc = 0;
+ } else if (0 == strcasecmp(rdn, RUVRDN)) {
+ /* this is the RUV and the suffix is not yet written
+ * make it pending and continue with next entry
+ */
+ skip_ruv = 1;
+ rc = 0;
+ } else {
+ /* this has to be the suffix */
+ suffix_written = 1;
+ rc = 0;
+ }
} else {
pid = (ID)strtol(pid_str, (char **)NULL, 10);
slapi_ch_free_string(&pid_str);
@@ -1614,6 +1658,16 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb)
continue;
}
+ if (skip_ruv) {
+ /* now we keep a copy of the ruv entry
+ * and continue with the next entry
+ */
+ pending_ruv = ep;
+ ep = NULL;
+ skip_ruv = 0;
+ continue;
+ }
+
eargs.ep = ep;
eargs.idindex = idindex;
eargs.cnt = &cnt;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
5 years, 1 month