[Pkg-fedora-ds-maintainers] 389-ds-base: Changes to 'upstream'

Timo Aaltonen tjaalton at moszumanska.debian.org
Tue Oct 20 11:44:15 UTC 2015


 VERSION.sh                                               |    2 
 dirsrvtests/create_test.py                               |  137 
 dirsrvtests/data/ticket48212/example1k_posix.ldif        |17017 +++++++++++++++
 dirsrvtests/suites/acl/acl_test.py                       |  123 
 dirsrvtests/suites/basic/basic_test.py                   |   12 
 dirsrvtests/suites/betxns/betxn_test.py                  |   70 
 dirsrvtests/tickets/ticket47931_test.py                  |  207 
 dirsrvtests/tickets/ticket48212_test.py                  |  210 
 dirsrvtests/tickets/ticket48226_test.py                  |  239 
 dirsrvtests/tickets/ticket48228_test.py                  |  327 
 ldap/admin/src/logconv.pl                                |   79 
 ldap/admin/src/scripts/db2index.in                       |   16 
 ldap/admin/src/scripts/dbverify.in                       |   18 
 ldap/admin/src/scripts/remove-ds.pl.in                   |    5 
 ldap/admin/src/scripts/verify-db.pl.in                   |   17 
 ldap/servers/plugins/acl/acl.c                           |  121 
 ldap/servers/plugins/cos/cos_cache.c                     |    1 
 ldap/servers/plugins/memberof/memberof.c                 |  230 
 ldap/servers/plugins/memberof/memberof.h                 |    8 
 ldap/servers/plugins/memberof/memberof_config.c          |  251 
 ldap/servers/plugins/replication/windows_protocol_util.c |    4 
 ldap/servers/plugins/retrocl/retrocl.c                   |  183 
 ldap/servers/plugins/retrocl/retrocl.h                   |    4 
 ldap/servers/plugins/retrocl/retrocl_po.c                |   38 
 ldap/servers/slapd/back-ldbm/dbverify.c                  |   13 
 ldap/servers/slapd/back-ldbm/ldbm_attr.c                 |   11 
 ldap/servers/slapd/back-ldbm/ldbm_delete.c               |   27 
 ldap/servers/slapd/back-ldbm/ldif2ldbm.c                 |   74 
 ldap/servers/slapd/index_subsystem.c                     |    5 
 ldap/servers/slapd/main.c                                |   20 
 ldap/servers/slapd/opshared.c                            |   22 
 ldap/servers/slapd/pagedresults.c                        |   24 
 ldap/servers/slapd/pblock.c                              |   10 
 ldap/servers/slapd/proto-slap.h                          |    1 
 ldap/servers/slapd/pw.c                                  |  188 
 ldap/servers/slapd/slap.h                                |    2 
 ldap/servers/slapd/slapi-plugin.h                        |    3 
 ldap/servers/slapd/valueset.c                            |   11 
 man/man8/dbverify.8                                      |    3 
 man/man8/remove-ds.pl.8                                  |    5 
 40 files changed, 19179 insertions(+), 559 deletions(-)

New commits:
commit 670629e9a2e7537e840c0e5a5597c0ca7faffb7b
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Fri Sep 4 13:54:08 2015 -0700

    bump version to 1.3.3.13

diff --git a/VERSION.sh b/VERSION.sh
index 5ab6022..1ae68d2 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
 # PACKAGE_VERSION is constructed from these
 VERSION_MAJOR=1
 VERSION_MINOR=3
-VERSION_MAINT=3.12
+VERSION_MAINT=3.13
 # if this is a PRERELEASE, set VERSION_PREREL
 # otherwise, comment it out
 # be sure to include the dot prefix in the prerel

commit b6be68c54078ec17bf38e5186a26e9d71bbb9644
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Wed Sep 2 14:28:27 2015 -0700

    Ticket #48265 - Complex filter in a search request doen't work as expected. (regression)
    
    Description: commit c2658c14802783d0a8919783aa7123be9e749c18 to fix
    Ticket 47521 - Complex filter in a search request doen't work as expected.
    regressed this case:
      "(&(&(|(l=A)(l=B)(l=C))(|(C=D)(c=E)))(|(uid=*test*)(cn=*test*))(o=X))"
    in which a simple filter follows a complex filter which choice is
    different from the outer choice.  I.e., '|' for (uid=...)(cn=...)
    is different from the first '&'.
    
    The fix for 47521 solves this case:
      "(&(&(uid=A)(cn=B))(&(givenname=C))(mail=D)(&(description=E)))"
    in this case, (mail=D) used to be dropped from the filter in the
    function index_subsys_flatten_filter.
    
    The 47521 fix saved the simple filter "(mail=D)" in the 2nd example,
    but it forced to skip the complex filter with the different choice
    and converted the 1st example to:
      "(&(&(|(l=A)(l=B)(l=C))(|(C=D)(c=E)))(o=X))"
    This patch saves such a complex filter, as well.
    
    https://fedorahosted.org/389/ticket/48265
    
    Reviewed by mreynolds at redhat.com (Thank you, Mark!!)
    
    (cherry picked from commit 8c3d3e4648fbb5229e329e2154d46f1ae808ba02)
    (cherry picked from commit 3d9dbf2d441e551495a1f3169dc2020324c484b4)

diff --git a/ldap/servers/slapd/index_subsystem.c b/ldap/servers/slapd/index_subsystem.c
index eff908e..d0ba1bd 100644
--- a/ldap/servers/slapd/index_subsystem.c
+++ b/ldap/servers/slapd/index_subsystem.c
@@ -441,6 +441,11 @@ static void index_subsys_flatten_filter(Slapi_Filter *flist)
 				}
 				else
 				{
+					/* don't loose a nested filter having a different choice */
+					if (flast) {
+						flast->f_next = f;
+						flast = f;
+					}
 					fprev = f;
 					f = f->f_next;
 				}

commit 546aa6b1f4db1eefc426d3dcb6788f5251fd1e82
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Wed Sep 2 18:04:27 2015 -0700

    Ticket #47981 - COS cache doesn't properly mark vattr cache as invalid when there are multiple suffixes
    
    Description: commit 42e2df3858a4e14706d57b5c907d1d3768f4d970 for fixing
    icket 47981 accidentally added "break" to the while loop when a
    condition is satisfied:
      if(!cos_cache_add_dn_defs(suffixVals[valIndex]->bv_val ,pDefs))
    which skips the rest of the definitions.  This patch removes the
    "break".
    
    https://fedorahosted.org/389/ticket/47981
    
    Reviewed by mreynolds at redhat.com (Thank you, Mark!!)
    
    (cherry picked from commit 6557b820dca7980067afc2a33184197b2d154a51)
    (cherry picked from commit c1721f1d6e2344eefaec817ed47119c15c43fcfc)

diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index 7d8e877..6c1bec0 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -676,7 +676,6 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
 									{
 										*vattr_cacheable = -1;
 										cos_def_available = 1;
-										break;
 									}
 								}
 								valIndex++;

commit e7d3b2f120e0a3e9ce642733b803686fbcc49222
Author: Mark Reynolds <mreynolds at redhat.com>
Date:   Fri Aug 28 15:01:58 2015 -0400

    Ticket 47931 - lib389 test - memberof and retrocl deadlock
    
    Description:  lib389 test to verify deadlock is resolved by setting
                  the retrocl scope to a single backend.
    
    https://fedorahosted.org/389/ticket/47931
    
    Reviewed by: ?
    
    (cherry picked from commit 48470e7a6b0a350149ced0a1377e625b836dba64)

diff --git a/dirsrvtests/tickets/ticket47931_test.py b/dirsrvtests/tickets/ticket47931_test.py
new file mode 100644
index 0000000..9aa54fc
--- /dev/null
+++ b/dirsrvtests/tickets/ticket47931_test.py
@@ -0,0 +1,207 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+import threading
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+SECOND_SUFFIX = "dc=deadlock"
+SECOND_BACKEND = "deadlock"
+RETROCL_PLUGIN_DN = ('cn=' + PLUGIN_RETRO_CHANGELOG + ',cn=plugins,cn=config')
+MEMBEROF_PLUGIN_DN = ('cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config')
+GROUP_DN = ("cn=group," + DEFAULT_SUFFIX)
+MEMBER_DN_COMP = "uid=member"
+TIME_OUT = 5
+
+
+class TopologyStandalone(object):
+    def __init__(self, standalone):
+        standalone.open()
+        self.standalone = standalone
+
+
+class modifySecondBackendThread(threading.Thread):
+    def __init__(self, inst, timeout):
+        threading.Thread.__init__(self)
+        self.daemon = True
+        self.inst = inst
+        self.timeout = timeout
+
+    def run(self):
+        conn = self.inst.openConnection()
+        conn.set_option(ldap.OPT_TIMEOUT, self.timeout)
+        log.info('Modify second suffix...')
+        for x in range(0, 5000):
+            try:
+                conn.modify_s(SECOND_SUFFIX,
+                              [(ldap.MOD_REPLACE,
+                                'description',
+                                'new description')])
+            except ldap.LDAPError as e:
+                log.fatal('Failed to modify second suffix - error: %s' %
+                          (e.message['desc']))
+                assert False
+
+        conn.close()
+        log.info('Finished modifying second suffix')
+
+
+ at pytest.fixture(scope="module")
+def topology(request):
+    global installation1_prefix
+    if installation1_prefix:
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+    # Creating standalone instance ...
+    standalone = DirSrv(verbose=False)
+    args_instance[SER_HOST] = HOST_STANDALONE
+    args_instance[SER_PORT] = PORT_STANDALONE
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+    args_standalone = args_instance.copy()
+    standalone.allocate(args_standalone)
+    instance_standalone = standalone.exists()
+    if instance_standalone:
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    # Delete each instance in the end
+    def fin():
+        standalone.delete()
+    request.addfinalizer(fin)
+
+    # Clear out the tmp dir
+    standalone.clearTmpDir(__file__)
+
+    return TopologyStandalone(standalone)
+
+
+def test_ticket47931(topology):
+    """Test Retro Changelog and MemberOf deadlock fix.
+       Verification steps:
+           - Enable retro cl and memberOf.
+           - Create two backends: A & B.
+           - Configure retrocl scoping for backend A.
+           - Configure memberOf plugin for uniquemember
+           - Create group in backend A.
+           - In parallel, add members to the group on A, and make modifications
+             to entries in backend B.
+           - Make sure the server does not hang during the updates to both
+             backends.
+
+    """
+
+    # Enable dynamic plugins to make plugin configuration easier
+    try:
+        topology.standalone.modify_s(DN_CONFIG,
+                                     [(ldap.MOD_REPLACE,
+                                       'nsslapd-dynamic-plugins',
+                                       'on')])
+    except ldap.LDAPError as e:
+        ldap.error('Failed to enable dynamic plugins! ' + e.message['desc'])
+        assert False
+
+    # Enable the plugins
+    topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+    topology.standalone.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+
+    # Create second backend
+    topology.standalone.backend.create(SECOND_SUFFIX, {BACKEND_NAME: SECOND_BACKEND})
+    topology.standalone.mappingtree.create(SECOND_SUFFIX, bename=SECOND_BACKEND)
+
+    # Create the root node of the second backend
+    try:
+        topology.standalone.add_s(Entry((SECOND_SUFFIX,
+                                  {'objectclass': 'top domain'.split(),
+                                   'dc': 'deadlock'})))
+    except ldap.LDAPError as e:
+        log.fatal('Failed to create suffix entry: error ' + e.message['desc'])
+        assert False
+
+    # Configure retrocl scope
+    try:
+        topology.standalone.modify_s(RETROCL_PLUGIN_DN,
+                                     [(ldap.MOD_REPLACE,
+                                       'nsslapd-include-suffix',
+                                       DEFAULT_SUFFIX)])
+    except ldap.LDAPError as e:
+        ldap.error('Failed to configure retrocl plugin: ' + e.message['desc'])
+        assert False
+
+    # Configure memberOf group attribute
+    try:
+        topology.standalone.modify_s(MEMBEROF_PLUGIN_DN,
+                                     [(ldap.MOD_REPLACE,
+                                       'memberofgroupattr',
+                                       'uniquemember')])
+    except ldap.LDAPError as e:
+        log.fatal('Failed to configure memberOf plugin: error ' + e.message['desc'])
+        assert False
+
+    # Create group
+    try:
+        topology.standalone.add_s(Entry((GROUP_DN,
+                                         {'objectclass': 'top extensibleObject'.split(),
+                                          'cn': 'group'})))
+    except ldap.LDAPError as e:
+        log.fatal('Failed to add grouo: error ' + e.message['desc'])
+        assert False
+
+    # Create 1500 entries (future members of the group)
+    for idx in range(1, 1500):
+        try:
+            USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
+            topology.standalone.add_s(Entry((USER_DN,
+                                             {'objectclass': 'top extensibleObject'.split(),
+                                              'uid': 'member%d' % (x)})))
+        except ldap.LDAPError as e:
+            log.fatal('Failed to add user (%s): error %s' % (USER_DN, e.message['desc']))
+            assert False
+
+    # Modify second backend (separate thread)
+    mod_backend_thrd = modifySecondBackendThread(topology.standalone, TIME_OUT)
+    mod_backend_thrd.start()
+
+    # Add members to the group - set timeout
+    log.info('Adding members to the group...')
+    topology.standalone.set_option(ldap.OPT_TIMEOUT, TIME_OUT)
+    for idx in range(1, 1500):
+        try:
+            MEMBER_VAL = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
+            topology.standalone.modify_s(GROUP_DN,
+                                         [(ldap.MOD_ADD,
+                                           'uniquemember',
+                                           MEMBER_VAL)])
+        except ldap.TIMEOUT:
+            log.fatal('Deadlock!  Bug verification failed.')
+            assert False
+        except ldap.LDAPError as e:
+            log.fatal('Failed to update group(not a deadlock) member (%s) - error: %s' %
+                      (MEMBER_VAL, e.message['desc']))
+            assert False
+    log.info('Finished adding members to the group.')
+
+    # Wait for the thread to finish
+    mod_backend_thrd.join()
+
+    # No timeout, test passed!
+    log.info('Test complete\n')
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)
\ No newline at end of file

commit f10e2e633ad9c55bc2b42bceef3f9635d7ac5b7c
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Thu Aug 27 17:04:53 2015 -0700

    Ticket #48252 - db2index creates index entry from deleted records
    
    Description: Commit ca4d38dff3bd820af2bf60c9bcc82fd64aac2556 fixing
    ticket #48252 introduced memory leaks.
    . nstombstone_vals needs to be allocated just once and freed at the end.
    . when skipping to index an entry for being a tombstone, the entry needs
      to be freed.
    
    https://fedorahosted.org/389/ticket/48252
    
    Reviewed by rmeggins at redhat.com (Thank you, Rich!!)
    
    (cherry picked from commit 4277f2ba4f1bb24efc771ea0fa02354654db255c)
    (cherry picked from commit 8c9c2fcb14843089a7b5abd02ab1738249b64516)

diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 5d18bfc..68e596b 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1708,6 +1708,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
     back_txn         txn;
     ID               suffixid = NOID; /* holds the id of the suffix entry */
     Slapi_Value      **nstombstone_vals = NULL;
+    int              istombstone = 0;
 
     LDAPDebug( LDAP_DEBUG_TRACE, "=> ldbm_back_ldbm2index\n", 0, 0, 0 );
     if ( g_get_shutdown() || c_get_shutdown() ) {
@@ -2192,8 +2193,11 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
             const CSN *tombstone_csn = entry_get_deletion_csn(ep->ep_entry);
             char deletion_csn_str[CSN_STRSIZE];
 
-            nstombstone_vals = (Slapi_Value **) slapi_ch_calloc(2, sizeof(Slapi_Value *));
-            *nstombstone_vals = slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
+            istombstone = 1;
+            if (!nstombstone_vals) {
+                nstombstone_vals = (Slapi_Value **) slapi_ch_calloc(2, sizeof(Slapi_Value *));
+                *nstombstone_vals = slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
+            }
             if (tombstone_csn) {
                 if (!run_from_cmdline) {
                     rc = dblayer_txn_begin(be, NULL, &txn);
@@ -2248,15 +2252,18 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
                     }
                 }
             }
+        } else {
+            istombstone = 0;
         }
 
         /*
          * Update the attribute indexes
          */
         if (indexAttrs) {
-            if (nstombstone_vals && !(index_ext & (DB2INDEX_ENTRYRDN|DB2INDEX_OBJECTCLASS))) {
+            if (istombstone && !(index_ext & (DB2INDEX_ENTRYRDN|DB2INDEX_OBJECTCLASS))) {
                 /* if it is a tombstone entry, just entryrdn or "objectclass: nstombstone"
                  * need to be reindexed.  the to-be-indexed list does not contain them. */
+                backentry_free( &ep );
                 continue;
             }
             for (i = slapi_entry_first_attr(ep->ep_entry, &attr); i == 0;
@@ -2270,7 +2277,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
                         goto err_out;
                     }
                     if (slapi_attr_type_cmp(indexAttrs[j], type, SLAPI_TYPE_CMP_SUBTYPE) == 0) {
-                        if (nstombstone_vals) {
+                        if (istombstone) {
                             if (!slapi_attr_type_cmp(indexAttrs[j], SLAPI_ATTR_OBJECTCLASS, SLAPI_TYPE_CMP_SUBTYPE)) {
                                 is_tombstone_obj = 1; /* is tombstone && is objectclass. need to index "nstombstone"*/
                             } else if (slapi_attr_type_cmp(indexAttrs[j], LDBM_ENTRYRDN_STR, SLAPI_TYPE_CMP_SUBTYPE)) {
@@ -2354,7 +2361,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
         /*
          * If it is NOT a tombstone entry, update the Virtual List View indexes.
          */
-        for (vlvidx = 0; !nstombstone_vals && (vlvidx < numvlv); vlvidx++) {
+        for (vlvidx = 0; !istombstone && (vlvidx < numvlv); vlvidx++) {
             char *ai = "Unknown index";
 
             if ( g_get_shutdown() || c_get_shutdown() ) {
@@ -2579,6 +2586,7 @@ err_min:
         }
     }
 
+    valuearray_free(&nstombstone_vals);
     if (indexAttrs) {
         slapi_ch_free((void **)&indexAttrs);
     }

commit 90cf9fdbc8b71e68f615f8a72328c25e41a8fd0c
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Tue Aug 25 16:31:10 2015 -0700

    Ticket #48228 - wrong password check if passwordInHistory is decreased.
    
    Description: Regression was added by this commit:
      commit 1a119125856006543aae0520b5800a8b52c3b049
      Ticket #48228 - wrong password check if passwordInHistory is decreased.
    Compare function pw_history_cmp used in qsort did not check the correct
    address for the timestamp string, which made qsort return the password
    history in the wrong order.
    
    https://fedorahosted.org/389/ticket/48228
    
    Reviewed by rmeggins at redhat.com (Thank you, Rich!)
    
    (cherry picked from commit 391acfcf9a67b9b27ebbd98d1dfe30ef54a027c4)
    (cherry picked from commit 096b386663c949136095def77a7fb12eee64e542)

diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index 192584a..387ee5e 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -1121,8 +1121,6 @@ retry:
 static int
 pw_history_cmp(const void *h0, const void *h1)
 {
-	size_t h0sz = 0;
-	size_t h1sz = 0;
 	if (!h0) {
 		if (!h1) {
 			return 0;
@@ -1133,23 +1131,20 @@ pw_history_cmp(const void *h0, const void *h1)
 		if (!h1) {
 			return 1;
 		} else {
-			size_t delta;
-			h0sz = strlen(h0);
-			h1sz = strlen(h1);
-			delta = h0sz - h1sz;
-			if (!delta) {
-				return delta;
-			}
-			if (h0sz < GENERALIZED_TIME_LENGTH) {
+			char *h0str = *(char **)h0;
+			char *h1str = *(char **)h1;
+			size_t h0sz = strlen(h0str);
+			size_t h1sz = strlen(h1str);
+			if ((h0sz < GENERALIZED_TIME_LENGTH) ||
+			    (h1sz < GENERALIZED_TIME_LENGTH)) {
 				/* too short for the history str. */
-				return 0;
+				return h0sz - h1sz;
 			}
+			return PL_strncmp(h0str, h1str, GENERALIZED_TIME_LENGTH);
 		}
 	}
-	return PL_strncmp(h0, h1, GENERALIZED_TIME_LENGTH);
 }
 
-
 static int
 update_pw_history( Slapi_PBlock *pb, const Slapi_DN *sdn, char *old_pw )
 {

commit ef0a2954cba650364ba4c48038d69731ebe19387
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Fri Aug 21 12:10:27 2015 -0700

    Ticket #48252 - db2index creates index entry from deleted records
    
    Bug Description: When an entry is deleted, its indexed attribute values
    are also removed from each index file.  But if the entry is turned to be
    a tombstone entry, reindexing adds the removed attribute value back to
    the index file.
    
    Fix Description: In the reindexing function ldbm_back_ldbm2index, if the
    entry is a tombstone entry, it skips reindexing operation unless the target
    attribute is entryrdn or objectclass.  If it is reindexing the objectclass,
    it indexes just for the key "=nstombstone".
    
    https://fedorahosted.org/389/ticket/48252
    
    Reviewed by mreynolds at redhat.com (Thank you, Mark!!)
    
    (cherry picked from commit ca4d38dff3bd820af2bf60c9bcc82fd64aac2556)
    (cherry picked from commit 86b96278871d8b08f7c6a75379935c2183f6668f)

diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 51fa8e0..5d18bfc 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -54,9 +54,12 @@
 
 static char *sourcefile = "ldif2ldbm.c";
 
-#define DB2INDEX_ANCESTORID 0x1    /* index ancestorid */
-#define DB2INDEX_ENTRYRDN   0x2    /* index entryrdn */
-#define DB2LDIF_ENTRYRDN    0x4    /* export entryrdn */
+#define DB2INDEX_ANCESTORID  0x1    /* index ancestorid */
+#define DB2INDEX_ENTRYRDN    0x2    /* index entryrdn */
+#define DB2LDIF_ENTRYRDN     0x4    /* export entryrdn */
+#define DB2INDEX_OBJECTCLASS 0x10   /* for reindexing "objectclass: nstombstone" */
+
+#define LDIF2LDBM_EXTBITS(x) ((x) & 0xf)
 
 typedef struct _export_args {
     struct backentry *ep;
@@ -1704,6 +1707,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
     struct vlvIndex  *vlvip = NULL;
     back_txn         txn;
     ID               suffixid = NOID; /* holds the id of the suffix entry */
+    Slapi_Value      **nstombstone_vals = NULL;
 
     LDAPDebug( LDAP_DEBUG_TRACE, "=> ldbm_back_ldbm2index\n", 0, 0, 0 );
     if ( g_get_shutdown() || c_get_shutdown() ) {
@@ -1824,7 +1828,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
                 if (strcasecmp(attrs[i]+1, LDBM_ANCESTORID_STR) == 0) {
                     if (task) {
                         slapi_task_log_notice(task, "%s: Indexing %s",
-                                            inst->inst_name, LDBM_ENTRYRDN_STR);
+                                              inst->inst_name, LDBM_ANCESTORID_STR);
                     }
                     LDAPDebug2Args(LDAP_DEBUG_ANY, "%s: Indexing %s\n",
                                    inst->inst_name, LDBM_ANCESTORID_STR);
@@ -1877,6 +1881,9 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
                                        inst->inst_name, attrs[i] + 1);
                     }
                 } else {
+                    if (strcasecmp(attrs[i]+1, SLAPI_ATTR_OBJECTCLASS) == 0) {
+                        index_ext |= DB2INDEX_OBJECTCLASS;
+                    }
                     charray_add(&indexAttrs, attrs[i]+1);
                     ai->ai_indexmask |= INDEX_OFFLINE;
                     if (task) {
@@ -1922,7 +1929,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
      * idl composed from the ancestorid list, instead of traversing the
      * entire database.
      */
-    if (!indexAttrs && !index_ext && pvlv) {
+    if (!indexAttrs && !LDIF2LDBM_EXTBITS(index_ext) && pvlv) {
         int err;
         char **suffix_list = NULL;
 
@@ -2181,11 +2188,13 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
         /*
          * If this entry is a tombstone, update the 'nstombstonecsn' index
          */
-        if(ep->ep_entry->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE){
-            const CSN *tombstone_csn = NULL;
+        if (ep->ep_entry->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
+            const CSN *tombstone_csn = entry_get_deletion_csn(ep->ep_entry);
             char deletion_csn_str[CSN_STRSIZE];
 
-            if((tombstone_csn = entry_get_deletion_csn(ep->ep_entry))){
+            nstombstone_vals = (Slapi_Value **) slapi_ch_calloc(2, sizeof(Slapi_Value *));
+            *nstombstone_vals = slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
+            if (tombstone_csn) {
                 if (!run_from_cmdline) {
                     rc = dblayer_txn_begin(be, NULL, &txn);
                     if (0 != rc) {
@@ -2244,18 +2253,31 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
         /*
          * Update the attribute indexes
          */
-        if (indexAttrs != NULL) {
+        if (indexAttrs) {
+            if (nstombstone_vals && !(index_ext & (DB2INDEX_ENTRYRDN|DB2INDEX_OBJECTCLASS))) {
+                /* if it is a tombstone entry, just entryrdn or "objectclass: nstombstone"
+                 * need to be reindexed.  the to-be-indexed list does not contain them. */
+                continue;
+            }
             for (i = slapi_entry_first_attr(ep->ep_entry, &attr); i == 0;
                  i = slapi_entry_next_attr(ep->ep_entry, attr, &attr)) {
                 Slapi_Value **svals;
 
                 slapi_attr_get_type( attr, &type );
                 for ( j = 0; indexAttrs[j] != NULL; j++ ) {
+                    int is_tombstone_obj = 0;
                     if ( g_get_shutdown() || c_get_shutdown() ) {
                         goto err_out;
                     }
-                    if (slapi_attr_type_cmp(indexAttrs[j], type,
-                                            SLAPI_TYPE_CMP_SUBTYPE) == 0 ) {
+                    if (slapi_attr_type_cmp(indexAttrs[j], type, SLAPI_TYPE_CMP_SUBTYPE) == 0) {
+                        if (nstombstone_vals) {
+                            if (!slapi_attr_type_cmp(indexAttrs[j], SLAPI_ATTR_OBJECTCLASS, SLAPI_TYPE_CMP_SUBTYPE)) {
+                                is_tombstone_obj = 1; /* is tombstone && is objectclass. need to index "nstombstone"*/
+                            } else if (slapi_attr_type_cmp(indexAttrs[j], LDBM_ENTRYRDN_STR, SLAPI_TYPE_CMP_SUBTYPE)) {
+                                /* Entry is a tombstone && this index is not an entryrdn. */
+                                continue;
+                            }
+                        }
                         svals = attr_get_present_values(attr);
 
                         if (!run_from_cmdline) {
@@ -2279,10 +2301,12 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
                                 goto err_out;
                             }
                         }
-                        rc = index_addordel_values_sv(
-                            be, indexAttrs[j], svals,
-                            NULL, ep->ep_id, BE_INDEX_ADD, &txn);
-                        if (rc != 0) {
+                        if (is_tombstone_obj) {
+                            rc = index_addordel_values_sv(be, indexAttrs[j], nstombstone_vals, NULL, ep->ep_id, BE_INDEX_ADD, &txn);
+                        } else {
+                            rc = index_addordel_values_sv(be, indexAttrs[j], svals, NULL, ep->ep_id, BE_INDEX_ADD, &txn);
+                        }
+                        if (rc) {
                             LDAPDebug(LDAP_DEBUG_ANY,
                                 "%s: ERROR: failed to update index '%s'\n",
                                 inst->inst_name, indexAttrs[j], 0);
@@ -2328,18 +2352,16 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
         }
 
         /*
-         * Update the Virtual List View indexes
+         * If it is NOT a tombstone entry, update the Virtual List View indexes.
          */
-        for ( vlvidx = 0; vlvidx < numvlv; vlvidx++ ) {
+        for (vlvidx = 0; !nstombstone_vals && (vlvidx < numvlv); vlvidx++) {
             char *ai = "Unknown index";
 
             if ( g_get_shutdown() || c_get_shutdown() ) {
                 goto err_out;
             }
-            if(indexAttrs){
-                  if(indexAttrs[vlvidx]){
-                      ai = indexAttrs[vlvidx];
-                  }
+            if (indexAttrs && indexAttrs[vlvidx]) {
+                ai = indexAttrs[vlvidx];
             }
             if (!run_from_cmdline) {
                 rc = dblayer_txn_begin(be, NULL, &txn);
@@ -2393,7 +2415,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
         /*
          * Update the ancestorid and entryrdn index
          */
-        if (!entryrdn_get_noancestorid() && index_ext & DB2INDEX_ANCESTORID) {
+        if (!entryrdn_get_noancestorid() && (index_ext & DB2INDEX_ANCESTORID)) {
             rc = ldbm_ancestorid_index_entry(be, ep, BE_INDEX_ADD, NULL);
             if (rc != 0) {
                 LDAPDebug(LDAP_DEBUG_ANY,

commit 7f63b581fd035b0c13e068f5c0b8d78a5f1ad69d
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Thu Aug 20 17:01:28 2015 -0700

    Ticket #48254 - CLI db2index fails with usage errors
    
    Bug Description:
    1) CLI db2index had an issue in option handling, which accidentally
    added '=' at the end of the previous option.
    2) if a value of an option includes a white space, e.g., -T "by MCC
    ou=People dc=example dc=com", the value was not passed to the program
    as a string.
    
    Fix Description:
    1) Removed unnecessary '='.
    2) Quote $OPTARG which could include a white space, and call ns-slapd
       command line vai eval.
    
    https://fedorahosted.org/389/ticket/48254
    
    Reviewed by rmeggins at redhat.com (Thank you, Rich!!)
    
    (cherry picked from commit 3507c46c9f1156df11b6cf05eba695d81088b416)
    (cherry picked from commit a6d7e3bd29eb63def170f73dc21e967df230f20a)

diff --git a/ldap/admin/src/scripts/db2index.in b/ldap/admin/src/scripts/db2index.in
index a1321ea..9af8fc8 100755
--- a/ldap/admin/src/scripts/db2index.in
+++ b/ldap/admin/src/scripts/db2index.in
@@ -39,13 +39,13 @@ do
            benameopt="set";;
         s) args=$args" -s $OPTARG"
            includeSuffix="set";;
-        t) args=$args" -t $OPTARG";;
-        T) args=$args=" -T $OPTARG";;
-        d) args=$args=" -d $OPTARG";;
-        a) args=$args=" -a $OPTARG";;
-        x) args=$args=" -x $OPTARG";;
-        v) args=$args=" -v";;
-        S) args=$args=" -S";;
+        t) args=$args" -t "\"$OPTARG\";;
+        T) args=$args" -T "\"$OPTARG\";;
+        d) args=$args" -d $OPTARG";;
+        a) args=$args" -a $OPTARG";;
+        x) args=$args" -x $OPTARG";;
+        v) args=$args" -v";;
+        S) args=$args" -S";;
         D) args=$args" -D $OPTARG";;
         ?) usage
            exit 1;;
@@ -79,5 +79,5 @@ then
     usage
     exit 1
 else
-    @sbindir@/ns-slapd db2index -D $CONFIG_DIR $args
+    eval @sbindir@/ns-slapd db2index -D $CONFIG_DIR $args
 fi

commit 5c48f28d2d6c46aa3cd2883207c18002d01e4994
Author: Mark Reynolds <mreynolds at redhat.com>
Date:   Wed Aug 19 10:03:50 2015 -0400

    Ticket 47831 - remove debug logging from retro cl
    
    Description:  Instrumented debug logging was accidentally left in the source.
                  This logging is being removed.
    
    https://fedorahosted.org/389/ticket/47931
    
    Reviewed by: mreynolds
    
    (cherry picked from commit db7153f89bf3dda935e6ef4f175697bda32fe720)

diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c
index a60becc..23c6402 100644
--- a/ldap/servers/plugins/retrocl/retrocl_po.c
+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
@@ -186,14 +186,11 @@ write_replog_db(
     int	err = 0;
     int ret = LDAP_SUCCESS;
     int	i;
-    int mark = 0;
 
     if (!dn) {
         slapi_log_error( SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "write_replog_db: NULL dn\n");
         return ret;
     }
-    mark = (post_entry && retrocl_entry_in_scope(post_entry));
-    slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "post in scope (%d)\n",mark);
 
     if (post_entry){
         if(!retrocl_entry_in_scope(log_e) && !retrocl_entry_in_scope(post_entry)){

commit 895dc4f814eb67c9b14112f647eb452a313e2f89
Author: Simon Pichugin <spichugi at redhat.com>
Date:   Tue Aug 11 16:11:48 2015 +0200

    Ticket #47569 - Added a testcase to ACL testsuite
    
    Description: The attribute defined in the targetattr keyword of an ACI
    is checked against the schema to make sure it is a defined attribute
    when you are adding a new ACI.  If you want to use an attribute subtype,
    the ACI is rejected since the attribute with subtype is not defined in
    the schema.  We should strip off the subtype when we validate the
    targetattr keyword against the schema.
    
    Test description:
    1. Define two attributes in the schema
        - first will be a targetattr
        - second will be a userattr
    2. Add an ACI with an attribute subtype
        - or language subtype
        - or binary subtype
        - or pronunciation subtype
    
    Signed-off-by: Mark Reynolds <mreynolds at redhat.com>
    (cherry picked from commit 0c4eafbc945ae4252886ba8546665a79206f3f83)

diff --git a/dirsrvtests/suites/acl/acl_test.py b/dirsrvtests/suites/acl/acl_test.py
index 74bd6c8..b85ee22 100644
--- a/dirsrvtests/suites/acl/acl_test.py
+++ b/dirsrvtests/suites/acl/acl_test.py
@@ -43,43 +43,104 @@ def topology(request):
     standalone.create()
     standalone.open()
 
+    # Delete each instance in the end
+    def fin():
+        standalone.delete()
+    request.addfinalizer(fin)
+
     # Clear out the tmp dir
     standalone.clearTmpDir(__file__)
 
     return TopologyStandalone(standalone)
 
 
-def test_acl_init(topology):
-    '''
-    Write any test suite initialization here(if needed)
-    '''
-
-    return
-
-
-def test_acl_(topology):
-    '''
-    Write a single test here...
-    '''
-
-    return
-
-
-def test_acl_final(topology):
-    topology.standalone.delete()
-    log.info('acl test suite PASSED')
-
-
-def run_isolated():
-    global installation1_prefix
-    installation1_prefix = None
-
-    topo = topology(True)
-    test_acl_init(topo)
-    test_acl_(topo)
-    test_acl_final(topo)
+def add_attr(topology, attr_name):
+    """Adds attribute to the schema"""
+
+    ATTR_VALUE = """(NAME '%s' \
+                    DESC 'Attribute filteri-Multi-Valued' \
+                    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27)""" % attr_name
+    mod = [(ldap.MOD_ADD, 'attributeTypes', ATTR_VALUE)]
+
+    try:
+        topology.standalone.modify_s(DN_SCHEMA, mod)
+    except ldap.LDAPError, e:
+        log.fatal('Failed to add attr (%s): error (%s)' % (attr_name,
+                                                           e.message['desc']))
+        assert False
+
+
+ at pytest.fixture(params=["lang-ja", "binary", "phonetic"])
+def aci_with_attr_subtype(request, topology):
+    """Adds and deletes an ACI in the DEFAULT_SUFFIX"""
+
+    TARGET_ATTR = 'protectedOperation'
+    USER_ATTR = 'allowedToPerform'
+    SUBTYPE = request.param
+
+    log.info("========Executing test with '%s' subtype========" % SUBTYPE)
+    log.info("        Add a target attribute")
+    add_attr(topology, TARGET_ATTR)
+
+    log.info("        Add a user attribute")
+    add_attr(topology, USER_ATTR)
+
+    ACI_TARGET = '(targetattr=%s;%s)' % (TARGET_ATTR, SUBTYPE)
+    ACI_ALLOW = '(version 3.0; acl "test aci for subtypes"; allow (read) '
+    ACI_SUBJECT = 'userattr = "%s;%s#GROUPDN";)' % (USER_ATTR, SUBTYPE)
+    ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
+
+    log.info("        Add an ACI with attribute subtype")
+    mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
+    try:
+        topology.standalone.modify_s(DEFAULT_SUFFIX, mod)
+    except ldap.LDAPError, e:
+        log.fatal('Failed to add ACI: error (%s)' % (e.message['desc']))
+        assert False
+
+    def fin():
+        log.info("        Finally, delete an ACI with the '%s' subtype" %
+                                                       SUBTYPE)
+        mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
+        try:
+            topology.standalone.modify_s(DEFAULT_SUFFIX, mod)
+        except ldap.LDAPError, e:
+            log.fatal('Failed to delete ACI: error (%s)' % (e.message['desc']))
+            assert False
+    request.addfinalizer(fin)
+
+    return ACI_BODY
+
+
+def test_aci_attr_subtype_targetattr(topology, aci_with_attr_subtype):
+    """Checks, that ACIs allow attribute subtypes in the targetattr keyword
+
+    Test description:
+    1. Define two attributes in the schema
+        - first will be a targetattr
+        - second will be a userattr
+    2. Add an ACI with an attribute subtype
+        - or language subtype
+        - or binary subtype
+        - or pronunciation subtype
+    """
+
+    log.info("        Search for the added attribute")
+    try:
+        entries = topology.standalone.search_s(DEFAULT_SUFFIX,
+                                               ldap.SCOPE_BASE,
+                                               '(objectclass=*)', ['aci'])
+        entry = str(entries[0])
+        assert aci_with_attr_subtype in entry
+        log.info("        The added attribute was found")
+
+    except ldap.LDAPError, e:
+        log.fatal('Search failed, error: ' + e.message['desc'])
+        assert False
 
 
 if __name__ == '__main__':
-    run_isolated()
-
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)

commit dc2292408a571c488a78ded4f1c37ff5e445625c
Author: Mark Reynolds <mreynolds at redhat.com>
Date:   Thu Aug 13 16:44:19 2015 -0400

    Ticket 48248 - Use LDIF building function in basic test suite
    
    Description:  Use the new LDIF building function that properly sets
                  ownership and permissions of new ldif file
    
    https://fedorahosted.org/389/ticket/48248
    (cherry picked from commit dfb1c315d009e7a4c6798a7ae05f139b77d506dc)
    
    Conflicts:
    	dirsrvtests/suites/basic/basic_test.py

diff --git a/dirsrvtests/suites/basic/basic_test.py b/dirsrvtests/suites/basic/basic_test.py
index 18d079d..d35f7d9 100644
--- a/dirsrvtests/suites/basic/basic_test.py
+++ b/dirsrvtests/suites/basic/basic_test.py
@@ -1,3 +1,11 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---



More information about the Pkg-fedora-ds-maintainers mailing list