[389-ds-base] branch 389-ds-base-1.3.8 updated: BZ1518320 - entry cache crash fix cherry-pick error
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.8
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.8 by this push:
new 4e2ca67 BZ1518320 - entry cache crash fix cherry-pick error
4e2ca67 is described below
commit 4e2ca678f4cc16a2c742a9426679f5bb8e4f50b3
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri Jun 21 11:35:09 2019 -0400
BZ1518320 - entry cache crash fix cherry-pick error
Fix another cherry-pick error
---
configure.ac | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configure.ac b/configure.ac
index ea528ff..91d6d39 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,6 +72,9 @@ AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset])
+# These functions are *required* without option.
+AC_CHECK_FUNCS([clock_gettime], [], AC_MSG_ERROR([unable to locate required symbol clock_gettime]))
+
# This will detect if we need to add the LIBADD_DL value for us.
LT_LIB_DLLOAD
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch 389-ds-base-1.3.8 updated: BZ1518320 - entry cache crash fix
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.8
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.8 by this push:
new f34aed1 BZ1518320 - entry cache crash fix
f34aed1 is described below
commit f34aed1c3e2835acf2063d502cf078b57e6a255f
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri Jun 21 10:15:19 2019 -0400
BZ1518320 - entry cache crash fix
Description: Fix cherry-pick error
---
ldap/servers/slapd/time.c | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 2a38658..584bd1e 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -96,32 +96,6 @@ slapi_current_utc_time_hr(void)
return ltnow;
}
-struct timespec
-slapi_current_rel_time_hr(void)
-{
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- return now;
-}
-
-void
-slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff)
-{
- /* Now diff the two */
- time_t sec = a->tv_sec - b->tv_sec;
- int32_t nsec = a->tv_nsec - b->tv_nsec;
-
- if (nsec < 0) {
- /* It's negative so take one second */
- sec -= 1;
- /* And set nsec to to a whole value */
- nsec = 1000000000 - nsec;
- }
-
- diff->tv_sec = sec;
- diff->tv_nsec = nsec;
-}
-
time_t
slapi_current_utc_time(void)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch 389-ds-base-1.3.8 updated: BZ1518320 - entry cache crash fix
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.8
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.8 by this push:
new 8cf4488 BZ1518320 - entry cache crash fix
8cf4488 is described below
commit 8cf448806e77d28198963a2c1a4adb31e3342d4f
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Thu Jun 20 15:50:08 2019 -0400
BZ1518320 - entry cache crash fix
Description: THis patch is combination of all the entry cache fixes.
If these fixes are not enough, there is an experimental
"fix" that should prevent the crash. A message will be
logged that reports the crash was averted:
"(avoided crash, but cache was corrupted)"
The customer should monitor the errors log for this text,
and let GSS know if they see it.
---
configure.ac | 3 -
dirsrvtests/tests/suites/betxns/betxn_test.py | 57 +++++++++
ldap/servers/slapd/back-ldbm/back-ldbm.h | 68 ++++++-----
ldap/servers/slapd/back-ldbm/backentry.c | 2 +-
ldap/servers/slapd/back-ldbm/cache.c | 163 +++++++++++++++++++++++--
ldap/servers/slapd/back-ldbm/ldbm_add.c | 13 ++
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 12 ++
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 12 ++
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 22 +++-
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1 +
ldap/servers/slapd/slapi-plugin.h | 15 +++
ldap/servers/slapd/time.c | 26 ++++
12 files changed, 341 insertions(+), 53 deletions(-)
diff --git a/configure.ac b/configure.ac
index 91d6d39..ea528ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,9 +72,6 @@ AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset])
-# These functions are *required* without option.
-AC_CHECK_FUNCS([clock_gettime], [], AC_MSG_ERROR([unable to locate required symbol clock_gettime]))
-
# This will detect if we need to add the LIBADD_DL value for us.
LT_LIB_DLLOAD
diff --git a/dirsrvtests/tests/suites/betxns/betxn_test.py b/dirsrvtests/tests/suites/betxns/betxn_test.py
index 1754964..48181a9 100644
--- a/dirsrvtests/tests/suites/betxns/betxn_test.py
+++ b/dirsrvtests/tests/suites/betxns/betxn_test.py
@@ -8,6 +8,7 @@
#
import pytest
import six
+import ldap
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_st
@@ -248,6 +249,62 @@ def test_betxn_memberof(topology_st, dynamic_plugins):
log.info('test_betxn_memberof: PASSED')
+def test_betxn_modrdn_memberof(topology_st):
+ """Test modrdn operartions and memberOf
+
+ :id: 70d0b96e-b693-4bf7-bbf5-102a66ac5994
+
+ :setup: Standalone instance
+
+ :steps: 1. Enable and configure memberOf plugin
+ 2. Set memberofgroupattr="member" and memberofAutoAddOC="nsContainer"
+ 3. Create group and user outside of memberOf plugin scope
+ 4. Do modrdn to move group into scope
+ 5. Do modrdn to move group into scope (again)
+
+ :expectedresults:
+ 1. memberOf plugin plugin should be ON
+ 2. Set memberofgroupattr="member" and memberofAutoAddOC="nsContainer" should PASS
+ 3. Creating group and user should PASS
+ 4. Modrdn should fail with objectclass violation
+ 5. Second modrdn should also fail with objectclass violation
+ """
+
+ peoplebase = 'ou=people,%s' % DEFAULT_SUFFIX
+ memberof = MemberOfPlugin(topology_st.standalone)
+ memberof.enable()
+ memberof.set_autoaddoc('nsContainer') # Bad OC
+ memberof.set('memberOfEntryScope', peoplebase)
+ memberof.set('memberOfAllBackends', 'on')
+ topology_st.standalone.restart()
+
+ groups = Groups(topology_st.standalone, DEFAULT_SUFFIX)
+ group = groups.create(properties={
+ 'cn': 'group',
+ })
+
+ # Create user and add it to group
+ users = UserAccounts(topology_st.standalone, basedn=DEFAULT_SUFFIX)
+ user = users.create(properties=TEST_USER_PROPERTIES)
+ if not ds_is_older('1.3.7'):
+ user.remove('objectClass', 'nsMemberOf')
+
+ group.add_member(user.dn)
+
+ # Attempt modrdn that should fail, but the original entry should stay in the cache
+ with pytest.raises(ldap.OBJECTCLASS_VIOLATION):
+ group.rename('cn=group_to_people', newsuperior=peoplebase)
+
+ # Should fail, but not with NO_SUCH_OBJECT as the original entry should still be in the cache
+ with pytest.raises(ldap.OBJECTCLASS_VIOLATION):
+ group.rename('cn=group_to_people', newsuperior=peoplebase)
+
+ #
+ # Done
+ #
+ log.info('test_betxn_modrdn_memberof: PASSED')
+
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 4727961..3995085 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -310,36 +310,37 @@ typedef struct
#define CACHE_TYPE_ENTRY 0
#define CACHE_TYPE_DN 1
-struct backcommon
-{
- int ep_type; /* to distinguish backdn from backentry */
- struct backcommon *ep_lrunext; /* for the cache */
- struct backcommon *ep_lruprev; /* for the cache */
- ID ep_id; /* entry id */
- char ep_state; /* state in the cache */
-#define ENTRY_STATE_DELETED 0x1 /* entry is marked as deleted */
-#define ENTRY_STATE_CREATING 0x2 /* entry is being created; don't touch it */
-#define ENTRY_STATE_NOTINCACHE 0x4 /* cache_add failed; not in the cache */
- int ep_refcnt; /* entry reference cnt */
- size_t ep_size; /* for cache tracking */
+struct backcommon {
+ int ep_type; /* to distinguish backdn from backentry */
+ struct backcommon *ep_lrunext; /* for the cache */
+ struct backcommon *ep_lruprev; /* for the cache */
+ ID ep_id; /* entry id */
+ char ep_state; /* state in the cache */
+#define ENTRY_STATE_DELETED 0x1 /* entry is marked as deleted */
+#define ENTRY_STATE_CREATING 0x2 /* entry is being created; don't touch it */
+#define ENTRY_STATE_NOTINCACHE 0x4 /* cache_add failed; not in the cache */
+#define ENTRY_STATE_INVALID 0x8 /* cache entry is invalid and needs to be removed */
+ int ep_refcnt; /* entry reference cnt */
+ size_t ep_size; /* for cache tracking */
+ struct timespec ep_create_time; /* the time the entry was added to the cache */
};
/* From ep_type through ep_size MUST be identical to backcommon */
-struct backentry
-{
- int ep_type; /* to distinguish backdn from backentry */
- struct backcommon *ep_lrunext; /* for the cache */
- struct backcommon *ep_lruprev; /* for the cache */
- ID ep_id; /* entry id */
- char ep_state; /* state in the cache */
- int ep_refcnt; /* entry reference cnt */
- size_t ep_size; /* for cache tracking */
- Slapi_Entry *ep_entry; /* real entry */
- Slapi_Entry *ep_vlventry;
- void *ep_dn_link; /* linkage for the 3 hash */
- void *ep_id_link; /* tables used for */
- void *ep_uuid_link; /* looking up entries */
- PRMonitor *ep_mutexp; /* protection for mods; make it reentrant */
+struct backentry {
+ int ep_type; /* to distinguish backdn from backentry */
+ struct backcommon *ep_lrunext; /* for the cache */
+ struct backcommon *ep_lruprev; /* for the cache */
+ ID ep_id; /* entry id */
+ char ep_state; /* state in the cache */
+ int ep_refcnt; /* entry reference cnt */
+ size_t ep_size; /* for cache tracking */
+ struct timespec ep_create_time; /* the time the entry was added to the cache */
+ Slapi_Entry *ep_entry; /* real entry */
+ Slapi_Entry *ep_vlventry;
+ void * ep_dn_link; /* linkage for the 3 hash */
+ void * ep_id_link; /* tables used for */
+ void * ep_uuid_link; /* looking up entries */
+ PRMonitor *ep_mutexp; /* protection for mods; make it reentrant */
};
/* From ep_type through ep_size MUST be identical to backcommon */
@@ -348,12 +349,13 @@ struct backdn
int ep_type; /* to distinguish backdn from backentry */
struct backcommon *ep_lrunext; /* for the cache */
struct backcommon *ep_lruprev; /* for the cache */
- ID ep_id; /* entry id */
- char ep_state; /* state in the cache; share ENTRY_STATE_* */
- int ep_refcnt; /* entry reference cnt */
- size_t ep_size; /* for cache tracking */
- Slapi_DN *dn_sdn;
- void *dn_id_link; /* for hash table */
+ ID ep_id; /* entry id */
+ char ep_state; /* state in the cache; share ENTRY_STATE_* */
+ int ep_refcnt; /* entry reference cnt */
+ size_t ep_size; /* for cache tracking */
+ struct timespec ep_create_time; /* the time the entry was added to the cache */
+ Slapi_DN *dn_sdn;
+ void *dn_id_link; /* for hash table */
};
/* for the in-core cache of entries */
diff --git a/ldap/servers/slapd/back-ldbm/backentry.c b/ldap/servers/slapd/back-ldbm/backentry.c
index f2fe780..a1f3ca1 100644
--- a/ldap/servers/slapd/back-ldbm/backentry.c
+++ b/ldap/servers/slapd/back-ldbm/backentry.c
@@ -23,7 +23,7 @@ backentry_free(struct backentry **bep)
return;
}
ep = *bep;
- PR_ASSERT(ep->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_NOTINCACHE));
+ PR_ASSERT(ep->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_NOTINCACHE | ENTRY_STATE_INVALID));
if (ep->ep_entry != NULL) {
slapi_entry_free(ep->ep_entry);
}
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 86e1f7b..054766d 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -56,6 +56,11 @@
#define LOG(...)
#endif
+typedef enum {
+ ENTRY_CACHE,
+ DN_CACHE,
+} CacheType;
+
#define LRU_DETACH(cache, e) lru_detach((cache), (void *)(e))
#define CACHE_LRU_HEAD(cache, type) ((type)((cache)->c_lruhead))
@@ -185,6 +190,7 @@ new_hash(u_long size, u_long offset, HashFn hfn, HashTestFn tfn)
int
add_hash(Hashtable *ht, void *key, uint32_t keylen, void *entry, void **alt)
{
+ struct backcommon *back_entry = (struct backcommon *)entry;
u_long val, slot;
void *e;
@@ -202,6 +208,7 @@ add_hash(Hashtable *ht, void *key, uint32_t keylen, void *entry, void **alt)
e = HASH_NEXT(ht, e);
}
/* ok, it's not already there, so add it */
+ back_entry->ep_create_time = slapi_current_rel_time_hr();
HASH_NEXT(ht, entry) = ht->slot[slot];
ht->slot[slot] = entry;
return 1;
@@ -492,6 +499,126 @@ cache_make_hashes(struct cache *cache, int type)
}
}
+/*
+ * Helper function for flush_hash() to calculate if the entry should be
+ * removed from the cache.
+ */
+static int32_t
+flush_remove_entry(struct timespec *entry_time, struct timespec *start_time)
+{
+ struct timespec diff;
+
+ slapi_timespec_diff(entry_time, start_time, &diff);
+ if (diff.tv_sec >= 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Flush all the cache entries that were added after the "start time"
+ * This is called when a backend transaction plugin fails, and we need
+ * to remove all the possible invalid entries in the cache.
+ *
+ * If the ref count is 0, we can straight up remove it from the cache, but
+ * if the ref count is greater than 1, then the entry is currently in use.
+ * In the later case we set the entry state to ENTRY_STATE_INVALID, and
+ * when the owning thread cache_returns() the cache entry is automatically
+ * removed so another thread can not use/lock the invalid cache entry.
+ */
+static void
+flush_hash(struct cache *cache, struct timespec *start_time, int32_t type)
+{
+ Hashtable *ht = cache->c_idtable; /* start with the ID table as it's in both ENTRY and DN caches */
+ void *e, *laste = NULL;
+
+ cache_lock(cache);
+
+ for (size_t i = 0; i < ht->size; i++) {
+ e = ht->slot[i];
+ while (e) {
+ struct backcommon *entry = (struct backcommon *)e;
+ uint64_t remove_it = 0;
+ if (flush_remove_entry(&entry->ep_create_time, start_time)) {
+ /* Mark the entry to be removed */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash", "[%s] Removing entry id (%d)\n",
+ type ? "DN CACHE" : "ENTRY CACHE", entry->ep_id);
+ remove_it = 1;
+ }
+ laste = e;
+ e = HASH_NEXT(ht, e);
+
+ if (remove_it) {
+ /* since we have the cache lock we know we can trust refcnt */
+ entry->ep_state |= ENTRY_STATE_INVALID;
+ if (entry->ep_refcnt == 0) {
+ entry->ep_refcnt++;
+ lru_delete(cache, laste);
+ if (type == ENTRY_CACHE) {
+ entrycache_remove_int(cache, laste);
+ entrycache_return(cache, (struct backentry **)&laste);
+ } else {
+ dncache_remove_int(cache, laste);
+ dncache_return(cache, (struct backdn **)&laste);
+ }
+ } else {
+ /* Entry flagged for removal */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash",
+ "[%s] Flagging entry to be removed later: id (%d) refcnt: %d\n",
+ type ? "DN CACHE" : "ENTRY CACHE", entry->ep_id, entry->ep_refcnt);
+ }
+ }
+ }
+ }
+
+ if (type == ENTRY_CACHE) {
+ /* Also check the DN hashtable */
+ ht = cache->c_dntable;
+
+ for (size_t i = 0; i < ht->size; i++) {
+ e = ht->slot[i];
+ while (e) {
+ struct backcommon *entry = (struct backcommon *)e;
+ uint64_t remove_it = 0;
+ if (flush_remove_entry(&entry->ep_create_time, start_time)) {
+ /* Mark the entry to be removed */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash", "[ENTRY CACHE] Removing entry id (%d)\n",
+ entry->ep_id);
+ remove_it = 1;
+ }
+ laste = e;
+ e = HASH_NEXT(ht, e);
+
+ if (remove_it) {
+ /* since we have the cache lock we know we can trust refcnt */
+ entry->ep_state |= ENTRY_STATE_INVALID;
+ if (entry->ep_refcnt == 0) {
+ entry->ep_refcnt++;
+ lru_delete(cache, laste);
+ entrycache_remove_int(cache, laste);
+ entrycache_return(cache, (struct backentry **)&laste);
+ } else {
+ /* Entry flagged for removal */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash",
+ "[ENTRY CACHE] Flagging entry to be removed later: id (%d) refcnt: %d\n",
+ entry->ep_id, entry->ep_refcnt);
+ }
+ }
+ }
+ }
+ }
+
+ cache_unlock(cache);
+}
+
+void
+revert_cache(ldbm_instance *inst, struct timespec *start_time)
+{
+ flush_hash(&inst->inst_cache, start_time, ENTRY_CACHE);
+ flush_hash(&inst->inst_dncache, start_time, DN_CACHE);
+}
+
/* initialize the cache */
int
cache_init(struct cache *cache, uint64_t maxsize, long maxentries, int type)
@@ -1141,10 +1268,10 @@ entrycache_return(struct cache *cache, struct backentry **bep)
backentry_free(bep);
} else {
ASSERT(e->ep_refcnt > 0);
- if (!--e->ep_refcnt) {
- if (e->ep_state & ENTRY_STATE_DELETED) {
- const char *ndn = slapi_sdn_get_ndn(backentry_get_sdn(e));
- if (ndn) {
+ if (! --e->ep_refcnt) {
+ if (e->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_INVALID)) {
+ const char* ndn = slapi_sdn_get_ndn(backentry_get_sdn(e));
+ if (ndn){
/*
* State is "deleted" and there are no more references,
* so we need to remove the entry from the DN cache because
@@ -1154,6 +1281,13 @@ entrycache_return(struct cache *cache, struct backentry **bep)
LOG("entrycache_return -Failed to remove %s from dn table\n", ndn);
}
}
+ if (e->ep_state & ENTRY_STATE_INVALID) {
+ /* Remove it from the hash table before we free the back entry */
+ slapi_log_err(SLAPI_LOG_CACHE, "entrycache_return",
+ "Finally flushing invalid entry: %d (%s)\n",
+ e->ep_id, backentry_get_ndn(e));
+ entrycache_remove_int(cache, e);
+ }
backentry_free(bep);
} else {
lru_add(cache, e);
@@ -1535,11 +1669,11 @@ cache_lock_entry(struct cache *cache, struct backentry *e)
/* make sure entry hasn't been deleted now */
cache_lock(cache);
- if (e->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_NOTINCACHE)) {
- cache_unlock(cache);
- PR_ExitMonitor(e->ep_mutexp);
- LOG("<= cache_lock_entry (DELETED)\n");
- return RETRY_CACHE_LOCK;
+ if (e->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_NOTINCACHE | ENTRY_STATE_INVALID)) {
+ cache_unlock(cache);
+ PR_ExitMonitor(e->ep_mutexp);
+ LOG("<= cache_lock_entry (DELETED)\n");
+ return RETRY_CACHE_LOCK;
}
cache_unlock(cache);
@@ -1695,8 +1829,15 @@ dncache_return(struct cache *cache, struct backdn **bdn)
backdn_free(bdn);
} else {
ASSERT((*bdn)->ep_refcnt > 0);
- if (!--(*bdn)->ep_refcnt) {
- if ((*bdn)->ep_state & ENTRY_STATE_DELETED) {
+ if (! --(*bdn)->ep_refcnt) {
+ if ((*bdn)->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_INVALID)) {
+ if ((*bdn)->ep_state & ENTRY_STATE_INVALID) {
+ /* Remove it from the hash table before we free the back dn */
+ slapi_log_err(SLAPI_LOG_CACHE, "dncache_return",
+ "Finally flushing invalid entry: %d (%s)\n",
+ (*bdn)->ep_id, slapi_sdn_get_dn((*bdn)->dn_sdn));
+ dncache_remove_int(cache, (*bdn));
+ }
backdn_free(bdn);
} else {
lru_add(cache, (void *)*bdn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 32c8e71..d3c8cda 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -97,6 +97,8 @@ ldbm_back_add(Slapi_PBlock *pb)
PRUint64 conn_id;
int op_id;
int result_sent = 0;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -147,6 +149,13 @@ ldbm_back_add(Slapi_PBlock *pb)
slapi_entry_delete_values(e, numsubordinates, NULL);
dblayer_txn_init(li, &txn);
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -1239,6 +1248,10 @@ ldbm_back_add(Slapi_PBlock *pb)
goto common_return;
error_return:
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
+
if (addingentry_id_assigned) {
next_id_return(be, addingentry->ep_id);
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index f5f6c1e..80c53a3 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -79,6 +79,8 @@ ldbm_back_delete(Slapi_PBlock *pb)
ID tomb_ep_id = 0;
int result_sent = 0;
Connection *pb_conn;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -98,6 +100,13 @@ ldbm_back_delete(Slapi_PBlock *pb)
/* dblayer_txn_init needs to be called before "goto error_return" */
dblayer_txn_init(li, &txn);
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -1356,6 +1365,9 @@ commit_return:
goto common_return;
error_return:
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
if (tombstone) {
if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
tomb_ep_id = tombstone->ep_id; /* Otherwise, tombstone might have been freed. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index cc4319e..93ab0a9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -412,6 +412,8 @@ ldbm_back_modify(Slapi_PBlock *pb)
int fixup_tombstone = 0;
int ec_locked = 0;
int result_sent = 0;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
slapi_pblock_get(pb, SLAPI_BACKEND, &be);
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li);
@@ -424,6 +426,13 @@ ldbm_back_modify(Slapi_PBlock *pb)
fixup_tombstone = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_FIXUP);
dblayer_txn_init(li, &txn); /* must do this before first goto error_return */
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -887,6 +896,9 @@ ldbm_back_modify(Slapi_PBlock *pb)
goto common_return;
error_return:
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
if (postentry != NULL) {
slapi_entry_free(postentry);
postentry = NULL;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 684b040..4fff35a 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -97,6 +97,8 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
int op_id;
int result_sent = 0;
Connection *pb_conn = NULL;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -134,6 +136,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
/* dblayer_txn_init needs to be called before "goto error_return" */
dblayer_txn_init(li, &txn);
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -1276,6 +1285,10 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
goto common_return;
error_return:
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
/* result already sent above - just free stuff */
if (postentry) {
slapi_entry_free(postentry);
@@ -1353,6 +1366,10 @@ error_return:
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
}
slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
}
retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN);
@@ -1413,12 +1430,7 @@ common_return:
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
- /* remove the new entry from the cache if the op failed -
- otherwise, leave it in */
if (ec && inst) {
- if (retval && cache_is_in_cache(&inst->inst_cache, ec)) {
- CACHE_REMOVE(&inst->inst_cache, ec);
- }
CACHE_RETURN(&inst->inst_cache, &ec);
}
ec = NULL;
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index b56f6ef..e68765b 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -55,6 +55,7 @@ void cache_unlock_entry(struct cache *cache, struct backentry *e);
int cache_replace(struct cache *cache, void *oldptr, void *newptr);
int cache_has_otherref(struct cache *cache, void *bep);
int cache_is_in_cache(struct cache *cache, void *ptr);
+void revert_cache(ldbm_instance *inst, struct timespec *start_time);
#ifdef CACHE_DEBUG
void check_entry_cache(struct cache *cache, struct backentry *e);
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 54c195e..4859083 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6853,6 +6853,12 @@ void slapi_operation_time_expiry(Slapi_Operation *o, time_t timeout, struct time
*/
slapi_timer_result slapi_timespec_expire_check(struct timespec *expire);
+/**
+ * Returns the current system time as a hr clock
+ *
+ * \return timespec of the current monotonic time.
+ */
+struct timespec slapi_current_rel_time_hr(void);
/*
* Plugin and parameter block related macros (remainder of this file).
@@ -8296,6 +8302,15 @@ uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder);
/* helper function */
const char * slapi_fetch_attr(Slapi_Entry *e, const char *attrname, char *default_val);
+/**
+ * Diffs two timespects a - b into *diff. This is useful with
+ * clock_monotonic to find time taken to perform operations.
+ *
+ * \param struct timespec a the "end" time.
+ * \param struct timespec b the "start" time.
+ * \param struct timespec c the difference.
+ */
+void slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff);
#ifdef __cplusplus
}
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 584bd1e..2a38658 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -96,6 +96,32 @@ slapi_current_utc_time_hr(void)
return ltnow;
}
+struct timespec
+slapi_current_rel_time_hr(void)
+{
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return now;
+}
+
+void
+slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff)
+{
+ /* Now diff the two */
+ time_t sec = a->tv_sec - b->tv_sec;
+ int32_t nsec = a->tv_nsec - b->tv_nsec;
+
+ if (nsec < 0) {
+ /* It's negative so take one second */
+ sec -= 1;
+ /* And set nsec to to a whole value */
+ nsec = 1000000000 - nsec;
+ }
+
+ diff->tv_sec = sec;
+ diff->tv_nsec = nsec;
+}
+
time_t
slapi_current_utc_time(void)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch 389-ds-base-1.3.8 updated: Ticket 50329 - (2nd) Possible Security Issue: DOS due to ioblocktimeout not applying to TLS
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.8
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.8 by this push:
new e26704f Ticket 50329 - (2nd) Possible Security Issue: DOS due to ioblocktimeout not applying to TLS
e26704f is described below
commit e26704f00795c57b31e4200110d7cf010617e408
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Wed May 15 17:46:14 2019 +0200
Ticket 50329 - (2nd) Possible Security Issue: DOS due to ioblocktimeout not applying to TLS
Bug Description:
A secure socket is configured in blocking mode. If an event
is detected on a secure socket a worker tries to receive the request.
If handshake occurs during the read, it can hang longer than
ioblocktimeout because it takes into account the socket option
rather than the timeout used for the ssl_Recv
Fix Description:
The fix is specific to secure socket and set this socket option
to do non blocking IO.
https://pagure.io/389-ds-base/issue/50329
Reviewed by: ?
Platforms tested: F28, RHEL7.6
Flag Day: no
Doc impact: no
---
ldap/servers/slapd/daemon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index c77e1f1..b1d41c8 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -3191,7 +3191,7 @@ configure_pr_socket(PRFileDesc **pr_socket, int secure, int local)
if (secure) {
pr_socketoption.option = PR_SockOpt_Nonblocking;
- pr_socketoption.value.non_blocking = 0;
+ pr_socketoption.value.non_blocking = 1;
if (PR_SetSocketOption(*pr_socket, &pr_socketoption) == PR_FAILURE) {
PRErrorCode prerr = PR_GetError();
slapi_log_err(SLAPI_LOG_ERR,
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch 389-ds-base-1.3.8 updated: Issue 50426 - nsSSL3Ciphers is limited to 1024 characters
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.8
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.8 by this push:
new 7c74ce2 Issue 50426 - nsSSL3Ciphers is limited to 1024 characters
7c74ce2 is described below
commit 7c74ce2e339ec8b429f6268646d6a21a3cafab0a
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri Jun 7 09:21:31 2019 -0400
Issue 50426 - nsSSL3Ciphers is limited to 1024 characters
Bug Description: There was a hardcoded buffer for processing TLS ciphers.
Anything over 1024 characters was truncated and was not
applied.
Fix Description: Don't use a fixed size buffer and just use the entire
string. When printing errors about invalid format then
we must use a fixed sized buffer, but we will truncate
that log value as to not exceed the ssl logging function's
buffer, and still output a useful message.
ASAN approved
https://pagure.io/389-ds-base/issue/50426
Reviewed by: firstyear, tbordaz, and spichugi (Thanks!!!)
(cherry picked from commit 22f2f9a1502e63bb169b7d599b5a3b35ddb31b8a)
---
dirsrvtests/tests/suites/tls/cipher_test.py | 51 +++++++++++++++++++++++++++++
ldap/servers/slapd/ssl.c | 34 +++++++++----------
2 files changed, 66 insertions(+), 19 deletions(-)
diff --git a/dirsrvtests/tests/suites/tls/cipher_test.py b/dirsrvtests/tests/suites/tls/cipher_test.py
new file mode 100644
index 0000000..0589310
--- /dev/null
+++ b/dirsrvtests/tests/suites/tls/cipher_test.py
@@ -0,0 +1,51 @@
+import pytest
+import os
+from lib389.config import Encryption
+from lib389.topologies import topology_st as topo
+
+
+def test_long_cipher_list(topo):
+ """Test a long cipher list, and makre sure it is not truncated
+
+ :id: bc400f54-3966-49c8-b640-abbf4fb2377d
+ :setup: Standalone Instance
+ :steps:
+ 1. Set nsSSL3Ciphers to a very long list of ciphers
+ 2. Ciphers are applied correctly
+ :expectedresults:
+ 1. Success
+ 2. Success
+ """
+ ENABLED_CIPHER = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384::AES-GCM::AEAD::256"
+ DISABLED_CIPHER = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256::AES-GCM::AEAD::128"
+ CIPHER_LIST = (
+ "-all,-SSL_CK_RC4_128_WITH_MD5,-SSL_CK_RC4_128_EXPORT40_WITH_MD5,-SSL_CK_RC2_128_CBC_WITH_MD5,"
+ "-SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,-SSL_CK_DES_64_CBC_WITH_MD5,-SSL_CK_DES_192_EDE3_CBC_WITH_MD5,"
+ "-TLS_RSA_WITH_RC4_128_MD5,-TLS_RSA_WITH_RC4_128_SHA,-TLS_RSA_WITH_3DES_EDE_CBC_SHA,"
+ "-TLS_RSA_WITH_DES_CBC_SHA,-SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,-SSL_RSA_FIPS_WITH_DES_CBC_SHA,"
+ "-TLS_RSA_EXPORT_WITH_RC4_40_MD5,-TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,-TLS_RSA_WITH_NULL_MD5,"
+ "-TLS_RSA_WITH_NULL_SHA,-TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,-SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,"
+ "-SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,-SSL_FORTEZZA_DMS_WITH_NULL_SHA,-TLS_DHE_DSS_WITH_DES_CBC_SHA,"
+ "-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_DES_CBC_SHA,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,"
+ "+TLS_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,"
+ "+TLS_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,"
+ "-TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,-TLS_DHE_DSS_WITH_RC4_128_SHA,-TLS_ECDHE_RSA_WITH_RC4_128_SHA,"
+ "-TLS_RSA_WITH_NULL_SHA,-TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,-SSL_CK_DES_192_EDE3_CBC_WITH_MD5,"
+ "-TLS_RSA_WITH_RC4_128_MD5,-TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,"
+ "-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,+TLS_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
+ )
+
+ topo.standalone.enable_tls()
+ enc = Encryption(topo.standalone)
+ enc.set('nsSSL3Ciphers', CIPHER_LIST)
+ topo.standalone.restart()
+ enabled_ciphers = enc.get_attr_vals_utf8('nssslenabledciphers')
+ assert ENABLED_CIPHER in enabled_ciphers
+ assert DISABLED_CIPHER not in enabled_ciphers
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main(["-s", CURRENT_FILE])
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index b8eba2d..ed054db 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -95,7 +95,6 @@ static char *configDN = "cn=encryption,cn=config";
#define CIPHER_SET_ALLOWWEAKDHPARAM 0x200 /* allowWeakDhParam is on */
#define CIPHER_SET_DISALLOWWEAKDHPARAM 0x400 /* allowWeakDhParam is off */
-
#define CIPHER_SET_ISDEFAULT(flag) \
(((flag)&CIPHER_SET_DEFAULT) ? PR_TRUE : PR_FALSE)
#define CIPHER_SET_ISALL(flag) \
@@ -689,10 +688,12 @@ _conf_setciphers(char *setciphers, int flags)
active = 0;
break;
default:
- PR_snprintf(err, sizeof(err), "invalid ciphers <%s>: format is "
- "+cipher1,-cipher2...",
- raw);
- return slapi_ch_strdup(err);
+ if (strlen(raw) > MAGNUS_ERROR_LEN) {
+ PR_snprintf(err, sizeof(err) - 3, "%s...", raw);
+ return slapi_ch_smprintf("invalid ciphers <%s>: format is +cipher1,-cipher2...", err);
+ } else {
+ return slapi_ch_smprintf("invalid ciphers <%s>: format is +cipher1,-cipher2...", raw);
+ }
}
if ((t = strchr(setciphers, ',')))
*t++ = '\0';
@@ -1689,7 +1690,6 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
PRUint16 NSSVersionMax = enabledNSSVersions.max;
char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
char newmax[VERSION_STR_LENGTH];
- char cipher_string[1024];
int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER;
int_fast16_t renegotiation = (int_fast16_t)SSL_RENEGOTIATE_REQUIRES_XTN;
@@ -1730,21 +1730,17 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
"Ignoring it and set it to default.", val, configDN);
}
}
- slapi_ch_free((void **)&val);
+ slapi_ch_free_string(&val);
/* Set SSL cipher preferences */
- *cipher_string = 0;
- if (ciphers && (*ciphers) && PL_strcmp(ciphers, "blank"))
- PL_strncpyz(cipher_string, ciphers, sizeof(cipher_string));
- slapi_ch_free((void **)&ciphers);
-
- if (NULL != (val = _conf_setciphers(cipher_string, allowweakcipher))) {
+ if (NULL != (val = _conf_setciphers(ciphers, allowweakcipher))) {
errorCode = PR_GetError();
slapd_SSL_warn("Failed to set SSL cipher "
"preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
val, errorCode, slapd_pr_strerror(errorCode));
- slapi_ch_free((void **)&val);
+ slapi_ch_free_string(&val);
}
+ slapi_ch_free_string(&ciphers);
freeConfigEntry(&e);
/* Import pr fd into SSL */
@@ -1815,12 +1811,12 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
activation = slapi_entry_attr_get_charptr(e, "nssslactivation");
if ((!activation) || (!PL_strcasecmp(activation, "off"))) {
/* this family was turned off, goto next */
- slapi_ch_free((void **)&activation);
+ slapi_ch_free_string(&activation);
freeConfigEntry(&e);
continue;
}
- slapi_ch_free((void **)&activation);
+ slapi_ch_free_string(&activation);
token = slapi_entry_attr_get_charptr(e, "nsssltoken");
personality = slapi_entry_attr_get_charptr(e, "nssslpersonalityssl");
@@ -1837,8 +1833,8 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
"family information. Missing nsssltoken or"
"nssslpersonalityssl in %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
*family, errorCode, slapd_pr_strerror(errorCode));
- slapi_ch_free((void **)&token);
- slapi_ch_free((void **)&personality);
+ slapi_ch_free_string(&token);
+ slapi_ch_free_string(&personality);
freeConfigEntry(&e);
continue;
}
@@ -1865,7 +1861,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
"private key for cert %s of family %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
cert_name, *family,
errorCode, slapd_pr_strerror(errorCode));
- slapi_ch_free((void **)&personality);
+ slapi_ch_free_string(&personality);
CERT_DestroyCertificate(cert);
cert = NULL;
freeConfigEntry(&e);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch 389-ds-base-1.3.6 updated: BZ1518320 - entry cache crash fix
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.6
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.6 by this push:
new f071f26 BZ1518320 - entry cache crash fix
f071f26 is described below
commit f071f260be70fe0ddb568e19fdf25f9c95b4ddad
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Thu Jun 20 15:50:08 2019 -0400
BZ1518320 - entry cache crash fix
Description: THis patch is combination of all the entry cache fixes.
If these fixes are not enough, there is an experimental
"fix" that should prevent the crash. A message will be
logged that reports the crash was averted:
"(avoided crash, but cache was corrupted)"
The customer should monitor the errors log for this text,
and let GSS know if they see it.
---
configure.ac | 2 +-
dirsrvtests/tests/suites/betxns/betxn_test.py | 57 ++++++++++
ldap/servers/slapd/back-ldbm/back-ldbm.h | 4 +
ldap/servers/slapd/back-ldbm/backentry.c | 2 +-
ldap/servers/slapd/back-ldbm/cache.c | 147 ++++++++++++++++++++++++-
ldap/servers/slapd/back-ldbm/ldbm_add.c | 14 +++
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 22 +++-
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 12 ++
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 24 +++-
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1 +
ldap/servers/slapd/slapi-plugin.h | 15 +++
ldap/servers/slapd/time.c | 26 +++++
12 files changed, 313 insertions(+), 13 deletions(-)
diff --git a/configure.ac b/configure.ac
index 17831a6..ee9dc01 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,7 +70,7 @@ AC_FUNC_STAT
AC_FUNC_STRERROR_R
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([clock_gettime endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset])
+AC_CHECK_FUNCS([endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset])
# This will detect if we need to add the LIBADD_DL value for us.
LT_LIB_DLLOAD
diff --git a/dirsrvtests/tests/suites/betxns/betxn_test.py b/dirsrvtests/tests/suites/betxns/betxn_test.py
index ed8acbf..0f3d767 100644
--- a/dirsrvtests/tests/suites/betxns/betxn_test.py
+++ b/dirsrvtests/tests/suites/betxns/betxn_test.py
@@ -8,6 +8,7 @@
#
import pytest
import six
+import ldap
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_st
@@ -195,6 +196,62 @@ def test_betxn_memberof(topology_st):
log.info('test_betxn_memberof: PASSED')
+def test_betxn_modrdn_memberof(topology_st):
+ """Test modrdn operartions and memberOf
+
+ :id: 70d0b96e-b693-4bf7-bbf5-102a66ac5994
+
+ :setup: Standalone instance
+
+ :steps: 1. Enable and configure memberOf plugin
+ 2. Set memberofgroupattr="member" and memberofAutoAddOC="nsContainer"
+ 3. Create group and user outside of memberOf plugin scope
+ 4. Do modrdn to move group into scope
+ 5. Do modrdn to move group into scope (again)
+
+ :expectedresults:
+ 1. memberOf plugin plugin should be ON
+ 2. Set memberofgroupattr="member" and memberofAutoAddOC="nsContainer" should PASS
+ 3. Creating group and user should PASS
+ 4. Modrdn should fail with objectclass violation
+ 5. Second modrdn should also fail with objectclass violation
+ """
+
+ peoplebase = 'ou=people,%s' % DEFAULT_SUFFIX
+ memberof = MemberOfPlugin(topology_st.standalone)
+ memberof.enable()
+ memberof.set_autoaddoc('nsContainer') # Bad OC
+ memberof.set('memberOfEntryScope', peoplebase)
+ memberof.set('memberOfAllBackends', 'on')
+ topology_st.standalone.restart()
+
+ groups = Groups(topology_st.standalone, DEFAULT_SUFFIX)
+ group = groups.create(properties={
+ 'cn': 'group',
+ })
+
+ # Create user and add it to group
+ users = UserAccounts(topology_st.standalone, basedn=DEFAULT_SUFFIX)
+ user = users.create(properties=TEST_USER_PROPERTIES)
+ if not ds_is_older('1.3.7'):
+ user.remove('objectClass', 'nsMemberOf')
+
+ group.add_member(user.dn)
+
+ # Attempt modrdn that should fail, but the original entry should stay in the cache
+ with pytest.raises(ldap.OBJECTCLASS_VIOLATION):
+ group.rename('cn=group_to_people', newsuperior=peoplebase)
+
+ # Should fail, but not with NO_SUCH_OBJECT as the original entry should still be in the cache
+ with pytest.raises(ldap.OBJECTCLASS_VIOLATION):
+ group.rename('cn=group_to_people', newsuperior=peoplebase)
+
+ #
+ # Done
+ #
+ log.info('test_betxn_modrdn_memberof: PASSED')
+
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 0bb15e3..9e2819a 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -303,8 +303,10 @@ struct backcommon {
#define ENTRY_STATE_DELETED 0x1 /* entry is marked as deleted */
#define ENTRY_STATE_CREATING 0x2 /* entry is being created; don't touch it */
#define ENTRY_STATE_NOTINCACHE 0x4 /* cache_add failed; not in the cache */
+#define ENTRY_STATE_INVALID 0x8 /* cache entry is invalid and needs to be removed */
int ep_refcnt; /* entry reference cnt */
size_t ep_size; /* for cache tracking */
+ struct timespec ep_create_time; /* the time the entry was added to the cache */
};
/* From ep_type through ep_size MUST be identical to backcommon */
@@ -316,6 +318,7 @@ struct backentry {
char ep_state; /* state in the cache */
int ep_refcnt; /* entry reference cnt */
size_t ep_size; /* for cache tracking */
+ struct timespec ep_create_time; /* the time the entry was added to the cache */
Slapi_Entry *ep_entry; /* real entry */
Slapi_Entry *ep_vlventry;
void * ep_dn_link; /* linkage for the 3 hash */
@@ -333,6 +336,7 @@ struct backdn {
char ep_state; /* state in the cache; share ENTRY_STATE_* */
int ep_refcnt; /* entry reference cnt */
size_t ep_size; /* for cache tracking */
+ struct timespec ep_create_time; /* the time the entry was added to the cache */
Slapi_DN *dn_sdn;
void *dn_id_link; /* for hash table */
};
diff --git a/ldap/servers/slapd/back-ldbm/backentry.c b/ldap/servers/slapd/back-ldbm/backentry.c
index 844df58..8b76d91 100644
--- a/ldap/servers/slapd/back-ldbm/backentry.c
+++ b/ldap/servers/slapd/back-ldbm/backentry.c
@@ -23,7 +23,7 @@ backentry_free( struct backentry **bep )
return;
}
ep = *bep;
- PR_ASSERT(ep->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE));
+ PR_ASSERT(ep->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_NOTINCACHE | ENTRY_STATE_INVALID));
if ( ep->ep_entry != NULL ) {
slapi_entry_free( ep->ep_entry );
}
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 3e40eec..24f7795 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -55,6 +55,11 @@
#define LOG(...)
#endif
+typedef enum {
+ ENTRY_CACHE,
+ DN_CACHE,
+} CacheType;
+
#define LRU_DETACH(cache, e) lru_detach((cache), (void *)(e))
#define CACHE_LRU_HEAD(cache, type) ((type)((cache)->c_lruhead))
@@ -180,6 +185,7 @@ Hashtable *new_hash(u_long size, u_long offset, HashFn hfn,
int add_hash(Hashtable *ht, void *key, size_t keylen, void *entry,
void **alt)
{
+ struct backcommon *back_entry = (struct backcommon *)entry;
u_long val, slot;
void *e;
@@ -197,6 +203,7 @@ int add_hash(Hashtable *ht, void *key, size_t keylen, void *entry,
e = HASH_NEXT(ht, e);
}
/* ok, it's not already there, so add it */
+ back_entry->ep_create_time = slapi_current_rel_time_hr();
HASH_NEXT(ht, entry) = ht->slot[slot];
ht->slot[slot] = entry;
return 1;
@@ -487,6 +494,126 @@ static void cache_make_hashes(struct cache *cache, int type)
}
}
+/*
+ * Helper function for flush_hash() to calculate if the entry should be
+ * removed from the cache.
+ */
+static int32_t
+flush_remove_entry(struct timespec *entry_time, struct timespec *start_time)
+{
+ struct timespec diff;
+
+ slapi_timespec_diff(entry_time, start_time, &diff);
+ if (diff.tv_sec >= 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Flush all the cache entries that were added after the "start time"
+ * This is called when a backend transaction plugin fails, and we need
+ * to remove all the possible invalid entries in the cache.
+ *
+ * If the ref count is 0, we can straight up remove it from the cache, but
+ * if the ref count is greater than 1, then the entry is currently in use.
+ * In the later case we set the entry state to ENTRY_STATE_INVALID, and
+ * when the owning thread cache_returns() the cache entry is automatically
+ * removed so another thread can not use/lock the invalid cache entry.
+ */
+static void
+flush_hash(struct cache *cache, struct timespec *start_time, int32_t type)
+{
+ Hashtable *ht = cache->c_idtable; /* start with the ID table as it's in both ENTRY and DN caches */
+ void *e, *laste = NULL;
+
+ cache_lock(cache);
+
+ for (size_t i = 0; i < ht->size; i++) {
+ e = ht->slot[i];
+ while (e) {
+ struct backcommon *entry = (struct backcommon *)e;
+ uint64_t remove_it = 0;
+ if (flush_remove_entry(&entry->ep_create_time, start_time)) {
+ /* Mark the entry to be removed */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash", "[%s] Removing entry id (%d)\n",
+ type ? "DN CACHE" : "ENTRY CACHE", entry->ep_id);
+ remove_it = 1;
+ }
+ laste = e;
+ e = HASH_NEXT(ht, e);
+
+ if (remove_it) {
+ /* since we have the cache lock we know we can trust refcnt */
+ entry->ep_state |= ENTRY_STATE_INVALID;
+ if (entry->ep_refcnt == 0) {
+ entry->ep_refcnt++;
+ lru_delete(cache, laste);
+ if (type == ENTRY_CACHE) {
+ entrycache_remove_int(cache, laste);
+ entrycache_return(cache, (struct backentry **)&laste);
+ } else {
+ dncache_remove_int(cache, laste);
+ dncache_return(cache, (struct backdn **)&laste);
+ }
+ } else {
+ /* Entry flagged for removal */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash",
+ "[%s] Flagging entry to be removed later: id (%d) refcnt: %d\n",
+ type ? "DN CACHE" : "ENTRY CACHE", entry->ep_id, entry->ep_refcnt);
+ }
+ }
+ }
+ }
+
+ if (type == ENTRY_CACHE) {
+ /* Also check the DN hashtable */
+ ht = cache->c_dntable;
+
+ for (size_t i = 0; i < ht->size; i++) {
+ e = ht->slot[i];
+ while (e) {
+ struct backcommon *entry = (struct backcommon *)e;
+ uint64_t remove_it = 0;
+ if (flush_remove_entry(&entry->ep_create_time, start_time)) {
+ /* Mark the entry to be removed */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash", "[ENTRY CACHE] Removing entry id (%d)\n",
+ entry->ep_id);
+ remove_it = 1;
+ }
+ laste = e;
+ e = HASH_NEXT(ht, e);
+
+ if (remove_it) {
+ /* since we have the cache lock we know we can trust refcnt */
+ entry->ep_state |= ENTRY_STATE_INVALID;
+ if (entry->ep_refcnt == 0) {
+ entry->ep_refcnt++;
+ lru_delete(cache, laste);
+ entrycache_remove_int(cache, laste);
+ entrycache_return(cache, (struct backentry **)&laste);
+ } else {
+ /* Entry flagged for removal */
+ slapi_log_err(SLAPI_LOG_CACHE, "flush_hash",
+ "[ENTRY CACHE] Flagging entry to be removed later: id (%d) refcnt: %d\n",
+ entry->ep_id, entry->ep_refcnt);
+ }
+ }
+ }
+ }
+ }
+
+ cache_unlock(cache);
+}
+
+void
+revert_cache(ldbm_instance *inst, struct timespec *start_time)
+{
+ flush_hash(&inst->inst_cache, start_time, ENTRY_CACHE);
+ flush_hash(&inst->inst_dncache, start_time, DN_CACHE);
+}
+
/* initialize the cache */
int cache_init(struct cache *cache, size_t maxsize, long maxentries, int type)
{
@@ -1139,7 +1266,7 @@ entrycache_return(struct cache *cache, struct backentry **bep)
{
ASSERT(e->ep_refcnt > 0);
if (! --e->ep_refcnt) {
- if (e->ep_state & ENTRY_STATE_DELETED) {
+ if (e->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_INVALID)) {
const char* ndn = slapi_sdn_get_ndn(backentry_get_sdn(e));
if (ndn){
/*
@@ -1151,6 +1278,13 @@ entrycache_return(struct cache *cache, struct backentry **bep)
LOG("entrycache_return -Failed to remove %s from dn table\n", ndn);
}
}
+ if (e->ep_state & ENTRY_STATE_INVALID) {
+ /* Remove it from the hash table before we free the back entry */
+ slapi_log_err(SLAPI_LOG_CACHE, "entrycache_return",
+ "Finally flushing invalid entry: %d (%s)\n",
+ e->ep_id, backentry_get_ndn(e));
+ entrycache_remove_int(cache, e);
+ }
backentry_free(bep);
} else {
lru_add(cache, e);
@@ -1540,7 +1674,7 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
/* make sure entry hasn't been deleted now */
cache_lock(cache);
- if (e->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE)) {
+ if (e->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_NOTINCACHE | ENTRY_STATE_INVALID)) {
cache_unlock(cache);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n");
@@ -1708,7 +1842,14 @@ dncache_return(struct cache *cache, struct backdn **bdn)
{
ASSERT((*bdn)->ep_refcnt > 0);
if (! --(*bdn)->ep_refcnt) {
- if ((*bdn)->ep_state & ENTRY_STATE_DELETED) {
+ if ((*bdn)->ep_state & (ENTRY_STATE_DELETED | ENTRY_STATE_INVALID)) {
+ if ((*bdn)->ep_state & ENTRY_STATE_INVALID) {
+ /* Remove it from the hash table before we free the back dn */
+ slapi_log_err(SLAPI_LOG_CACHE, "dncache_return",
+ "Finally flushing invalid entry: %d (%s)\n",
+ (*bdn)->ep_id, slapi_sdn_get_dn((*bdn)->dn_sdn));
+ dncache_remove_int(cache, (*bdn));
+ }
backdn_free(bdn);
} else {
lru_add(cache, (void *)*bdn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 8acaaeb..0e6d496 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -94,6 +94,9 @@ ldbm_back_add( Slapi_PBlock *pb )
PRUint64 conn_id;
int op_id;
int result_sent = 0;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
+
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
}
@@ -131,6 +134,13 @@ ldbm_back_add( Slapi_PBlock *pb )
slapi_entry_delete_values( e, numsubordinates, NULL );
dblayer_txn_init(li,&txn);
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -1194,6 +1204,10 @@ ldbm_back_add( Slapi_PBlock *pb )
goto common_return;
error_return:
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
if ( addingentry_id_assigned )
{
next_id_return( be, addingentry->ep_id );
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index cfc18b0..8368cf3 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -79,6 +79,8 @@ ldbm_back_delete( Slapi_PBlock *pb )
ID tomb_ep_id = 0;
int result_sent = 0;
Connection *pb_conn;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -98,6 +100,13 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* dblayer_txn_init needs to be called before "goto error_return" */
dblayer_txn_init(li,&txn);
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -208,8 +217,13 @@ ldbm_back_delete( Slapi_PBlock *pb )
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
- if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
- CACHE_REMOVE(&inst->inst_cache, tombstone);
+ CACHE_REMOVE(&inst->inst_cache, tombstone); /* TEST FIX: Always remove tombstone from cache */
+ if (cache_is_in_cache(&inst->inst_cache, tombstone) == 0) {
+ /* This really should not happen - means there is cache corruption */
+ slapi_log_err(SLAPI_LOG_ALERT, "ldbm_back_delete",
+ "DEBUG [retry: %d] - tombstone NOT in cache (%s) orig dn (%s) state (%d), "
+ "but it should be in the cache (avoided crash, but cache was corrupted)\n",
+ retry_count, backentry_get_ndn(tombstone), dn, tombstone->ep_state);
}
CACHE_RETURN(&inst->inst_cache, &tombstone);
if (tombstone) {
@@ -1312,6 +1326,10 @@ ldbm_back_delete( Slapi_PBlock *pb )
goto common_return;
error_return:
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
if (tombstone) {
if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
tomb_ep_id = tombstone->ep_id; /* Otherwise, tombstone might have been freed. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 307f7c2..14c493a 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -393,6 +393,8 @@ ldbm_back_modify( Slapi_PBlock *pb )
int fixup_tombstone = 0;
int ec_locked = 0;
int result_sent = 0;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -405,6 +407,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
fixup_tombstone = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_FIXUP);
dblayer_txn_init(li,&txn); /* must do this before first goto error_return */
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -863,6 +871,10 @@ ldbm_back_modify( Slapi_PBlock *pb )
goto common_return;
error_return:
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
if ( postentry != NULL )
{
slapi_entry_free( postentry );
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 40d2415..c5d7a12 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -97,6 +97,8 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
int op_id;
int result_sent = 0;
Connection *pb_conn = NULL;
+ int32_t parent_op = 0;
+ struct timespec parent_time;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -134,6 +136,13 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/* dblayer_txn_init needs to be called before "goto error_return" */
dblayer_txn_init(li,&txn);
+
+ if (txn.back_txn_txn == NULL) {
+ /* This is the parent operation, get the time */
+ parent_op = 1;
+ parent_time = slapi_current_rel_time_hr();
+ }
+
/* the calls to perform searches require the parent txn if any
so set txn to the parent_txn until we begin the child transaction */
if (parent_txn) {
@@ -1326,6 +1335,10 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
goto common_return;
error_return:
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
/* result already sent above - just free stuff */
if (postentry) {
slapi_entry_free( postentry );
@@ -1410,6 +1423,10 @@ error_return:
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval );
}
slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
+ /* Revert the caches if this is the parent operation */
+ if (parent_op) {
+ revert_cache(inst, &parent_time);
+ }
}
/* Release SERIAL LOCK */
@@ -1469,13 +1486,8 @@ common_return:
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
- /* remove the new entry from the cache if the op failed -
- otherwise, leave it in */
if (ec && inst) {
- if (retval && cache_is_in_cache(&inst->inst_cache, ec)) {
- CACHE_REMOVE( &inst->inst_cache, ec );
- }
- CACHE_RETURN( &inst->inst_cache, &ec );
+ CACHE_RETURN(&inst->inst_cache, &ec);
}
ec = NULL;
}
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 86ef5cb..09c1226 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -61,6 +61,7 @@ void cache_unlock_entry(struct cache *cache, struct backentry *e);
int cache_replace(struct cache *cache, void *oldptr, void *newptr);
int cache_has_otherref(struct cache *cache, void *bep);
int cache_is_in_cache(struct cache *cache, void *ptr);
+void revert_cache(ldbm_instance *inst, struct timespec *start_time);
#ifdef CACHE_DEBUG
void check_entry_cache(struct cache *cache, struct backentry *e);
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index d37bc63..08e6a81 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6779,6 +6779,12 @@ int slapi_reslimit_get_integer_limit( Slapi_Connection *conn, int handle,
*/
time_t slapi_current_time( void );
+/**
+ * Returns the current system time as a hr clock
+ *
+ * \return timespec of the current monotonic time.
+ */
+struct timespec slapi_current_rel_time_hr(void);
/*
* Plugin and parameter block related macros (remainder of this file).
@@ -8086,6 +8092,15 @@ uint64_t slapi_atomic_incr_64(uint64_t *ptr, int memorder);
*/
uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder);
+/**
+ * Diffs two timespects a - b into *diff. This is useful with
+ * clock_monotonic to find time taken to perform operations.
+ *
+ * \param struct timespec a the "end" time.
+ * \param struct timespec b the "start" time.
+ * \param struct timespec c the difference.
+ */
+void slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff);
#ifdef __cplusplus
}
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 16467af..69ae303 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -144,6 +144,32 @@ slapi_current_time( void )
return current_time();
}
+struct timespec
+slapi_current_rel_time_hr(void)
+{
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return now;
+}
+
+void
+slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff)
+{
+ /* Now diff the two */
+ time_t sec = a->tv_sec - b->tv_sec;
+ int32_t nsec = a->tv_nsec - b->tv_nsec;
+
+ if (nsec < 0) {
+ /* It's negative so take one second */
+ sec -= 1;
+ /* And set nsec to to a whole value */
+ nsec = 1000000000 - nsec;
+ }
+
+ diff->tv_sec = sec;
+ diff->tv_nsec = nsec;
+}
+
time_t
time_plus_sec (time_t l, long r)
/* return the point in time 'r' seconds after 'l'. */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch master updated: Bump version to 1.4.1.4
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new 5f0d45a Bump version to 1.4.1.4
5f0d45a is described below
commit 5f0d45a37af613260adb1fc304a14f3077845801
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Jun 18 16:18:31 2019 -0400
Bump version to 1.4.1.4
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index be82b6b..48b99bd 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=4
-VERSION_MAINT=1.3
+VERSION_MAINT=1.4
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch 389-ds-base-1.4.0 updated: Issue 50431 - Fix regression from coverity fix
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 2c011ad Issue 50431 - Fix regression from coverity fix
2c011ad is described below
commit 2c011ad71a41b7eb172624d7a96e69105923e3e4
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Thu Jun 13 17:55:25 2019 -0400
Issue 50431 - Fix regression from coverity fix
Description: Fix a regression from the initial coverity commit
where we did not allow NULL pointers to set into
the pblock. They were false positives reported by
covscan.
https://pagure.io/389-ds-base/issue/50431
Reviewed by: mreynolds (one line commit rule)
(cherry picked from commit 054d32e7b697513124a37dade54828ec52397c1c)
---
ldap/servers/plugins/acl/acleffectiverights.c | 4 +---
ldap/servers/plugins/views/views.c | 4 +---
ldap/servers/slapd/back-ldbm/vlv_srch.c | 3 ++-
ldap/servers/slapd/dse.c | 6 ++----
ldap/servers/slapd/opshared.c | 3 +--
ldap/servers/slapd/plugin_internal_op.c | 3 +--
ldap/servers/slapd/plugin_syntax.c | 4 +---
7 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index 5dd46a0..8a34ac5 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -1030,9 +1030,7 @@ bailout:
* slapi_pblock_set() will free any previous data, and
* pblock_done() will free SLAPI_PB_RESULT_TEXT.
*/
- if (gerstr) {
- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr);
- }
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr);
if (!iscritical) {
/*
diff --git a/ldap/servers/plugins/views/views.c b/ldap/servers/plugins/views/views.c
index 5d84647..64e305a 100644
--- a/ldap/servers/plugins/views/views.c
+++ b/ldap/servers/plugins/views/views.c
@@ -1760,9 +1760,7 @@ view_search_rewrite_callback(Slapi_PBlock *pb)
#endif
/* make it happen */
- if (outFilter) {
- slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter);
- }
+ slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter);
ret = -2;
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c
index a775550..82cea4b 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
@@ -168,8 +168,9 @@ vlvSearch_init(struct vlvSearch *p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm
/* switch context back to the DSE backend */
slapi_pblock_set(pb, SLAPI_BACKEND, oldbe);
- if (oldbe)
+ if (oldbe) {
slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe->be_database);
+ }
}
/* make (&(parentid=idofbase)(|(originalfilter)(objectclass=referral))) */
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index 66aeabb..b8ee1cf 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -2443,8 +2443,7 @@ dse_delete(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi
dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, ec, NULL, &returncode, returntext);
done:
slapi_pblock_get(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, &orig_entry);
- if (ec)
- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec);
+ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec);
/* make sure OPRETURN and RESULT_CODE are set */
slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc);
if (returncode || rc) {
@@ -2485,8 +2484,7 @@ done:
rc = LDAP_UNWILLING_TO_PERFORM;
}
}
- if (orig_entry)
- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
+ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
slapi_send_ldap_result(pb, returncode, NULL, returntext, 0, NULL);
return dse_delete_return(returncode, ec);
}
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index dac42eb..dd69173 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -998,8 +998,7 @@ free_and_return_nolock:
slapi_sdn_free(&sdn);
}
slapi_sdn_free(&basesdn);
- if (orig_sdn)
- slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn);
+ slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn);
slapi_ch_free_string(&proxydn);
slapi_ch_free_string(&proxystr);
diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c
index 622daff..9da266b 100644
--- a/ldap/servers/slapd/plugin_internal_op.c
+++ b/ldap/servers/slapd/plugin_internal_op.c
@@ -368,8 +368,7 @@ seq_internal_callback_pb(Slapi_PBlock *pb, void *callback_data, plugin_result_ca
slapi_pblock_set(pb, SLAPI_BACKEND, be);
slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname);
- if (val)
- slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
+ slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
/* set actions taken to process the operation */
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index dc7106d..e208442 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -247,9 +247,7 @@ plugin_call_syntax_filter_sub_sv(
Operation *op = NULL;
/* to pass SLAPI_SEARCH_TIMELIMIT & SLAPI_OPINITATED_TIME */
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- if (op) {
- slapi_pblock_set(pipb, SLAPI_OPERATION, op);
- }
+ slapi_pblock_set(pipb, SLAPI_OPERATION, op);
}
rc = (*sub_fn)(pipb, fsub->sf_initial, fsub->sf_any, fsub->sf_final, va);
} else {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch master updated: Issue 50431 - Fix regression from coverity fix
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new 054d32e Issue 50431 - Fix regression from coverity fix
054d32e is described below
commit 054d32e7b697513124a37dade54828ec52397c1c
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Thu Jun 13 17:55:25 2019 -0400
Issue 50431 - Fix regression from coverity fix
Description: Fix a regression from the initial coverity commit
where we did not allow NULL pointers to set into
the pblock. They were false positives reported by
covscan.
https://pagure.io/389-ds-base/issue/50431
Reviewed by: mreynolds (one line commit rule)
---
ldap/servers/plugins/acl/acleffectiverights.c | 4 +---
ldap/servers/plugins/views/views.c | 4 +---
ldap/servers/slapd/back-ldbm/vlv_srch.c | 3 ++-
ldap/servers/slapd/dse.c | 6 ++----
ldap/servers/slapd/opshared.c | 3 +--
ldap/servers/slapd/plugin_internal_op.c | 3 +--
ldap/servers/slapd/plugin_syntax.c | 4 +---
7 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index 5dd46a0..8a34ac5 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -1030,9 +1030,7 @@ bailout:
* slapi_pblock_set() will free any previous data, and
* pblock_done() will free SLAPI_PB_RESULT_TEXT.
*/
- if (gerstr) {
- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr);
- }
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr);
if (!iscritical) {
/*
diff --git a/ldap/servers/plugins/views/views.c b/ldap/servers/plugins/views/views.c
index 5d84647..64e305a 100644
--- a/ldap/servers/plugins/views/views.c
+++ b/ldap/servers/plugins/views/views.c
@@ -1760,9 +1760,7 @@ view_search_rewrite_callback(Slapi_PBlock *pb)
#endif
/* make it happen */
- if (outFilter) {
- slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter);
- }
+ slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter);
ret = -2;
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c
index 1ac3e00..65b8766 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
@@ -168,8 +168,9 @@ vlvSearch_init(struct vlvSearch *p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm
/* switch context back to the DSE backend */
slapi_pblock_set(pb, SLAPI_BACKEND, oldbe);
- if (oldbe)
+ if (oldbe) {
slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe->be_database);
+ }
}
/* make (&(parentid=idofbase)(|(originalfilter)(objectclass=referral))) */
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index 1256843..8f2a14c 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -2530,8 +2530,7 @@ dse_delete(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi
dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, ec, NULL, &returncode, returntext);
done:
slapi_pblock_get(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, &orig_entry);
- if (ec)
- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec);
+ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec);
/* make sure OPRETURN and RESULT_CODE are set */
slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc);
if (returncode || rc) {
@@ -2572,8 +2571,7 @@ done:
rc = LDAP_UNWILLING_TO_PERFORM;
}
}
- if (orig_entry)
- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
+ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
slapi_send_ldap_result(pb, returncode, NULL, returntext, 0, NULL);
return dse_delete_return(returncode, ec);
}
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index dac42eb..dd69173 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -998,8 +998,7 @@ free_and_return_nolock:
slapi_sdn_free(&sdn);
}
slapi_sdn_free(&basesdn);
- if (orig_sdn)
- slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn);
+ slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn);
slapi_ch_free_string(&proxydn);
slapi_ch_free_string(&proxystr);
diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c
index 622daff..9da266b 100644
--- a/ldap/servers/slapd/plugin_internal_op.c
+++ b/ldap/servers/slapd/plugin_internal_op.c
@@ -368,8 +368,7 @@ seq_internal_callback_pb(Slapi_PBlock *pb, void *callback_data, plugin_result_ca
slapi_pblock_set(pb, SLAPI_BACKEND, be);
slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname);
- if (val)
- slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
+ slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
/* set actions taken to process the operation */
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index dc7106d..e208442 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -247,9 +247,7 @@ plugin_call_syntax_filter_sub_sv(
Operation *op = NULL;
/* to pass SLAPI_SEARCH_TIMELIMIT & SLAPI_OPINITATED_TIME */
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- if (op) {
- slapi_pblock_set(pipb, SLAPI_OPERATION, op);
- }
+ slapi_pblock_set(pipb, SLAPI_OPERATION, op);
}
rc = (*sub_fn)(pipb, fsub->sf_initial, fsub->sf_any, fsub->sf_final, va);
} else {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months
[389-ds-base] branch master updated: Issue 50417 - Fix missing quote in some legacy tools
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new 8af8e78 Issue 50417 - Fix missing quote in some legacy tools
8af8e78 is described below
commit 8af8e785500cdffed78454472497ea42859b5ad6
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Mon Jun 10 16:02:12 2019 -0400
Issue 50417 - Fix missing quote in some legacy tools
Description: A few scripts were missing a quote for the CONFIG_DIR var
https://pagure.io/389-ds-base/issue/50417
Reviewed by: mreynolds (one line commit rule)
---
ldap/admin/src/scripts/dbmon.sh.in | 2 +-
ldap/admin/src/scripts/dbverify.in | 2 +-
ldap/admin/src/scripts/restoreconfig.in | 2 +-
ldap/admin/src/scripts/suffix2instance.in | 2 +-
ldap/admin/src/scripts/vlvindex.in | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/ldap/admin/src/scripts/dbmon.sh.in b/ldap/admin/src/scripts/dbmon.sh.in
index be98646..aa4cb23 100644
--- a/ldap/admin/src/scripts/dbmon.sh.in
+++ b/ldap/admin/src/scripts/dbmon.sh.in
@@ -214,7 +214,7 @@ dodbmon() {
exit 1
fi
- CONFIG_DIR="@instconfigdir@/slapd-$instance
+ CONFIG_DIR="@instconfigdir@/slapd-$instance"
process_dse $CONFIG_DIR $$
file="/tmp/DSSharedLib.$$"
diff --git a/ldap/admin/src/scripts/dbverify.in b/ldap/admin/src/scripts/dbverify.in
index ecbbc1d..0f71c6b 100755
--- a/ldap/admin/src/scripts/dbverify.in
+++ b/ldap/admin/src/scripts/dbverify.in
@@ -64,7 +64,7 @@ then
exit 1
fi
-CONFIG_DIR="@instconfigdir@/slapd-$instance
+CONFIG_DIR="@instconfigdir@/slapd-$instance"
eval @sbindir@/ns-slapd dbverify -D $CONFIG_DIR $args
if [ $display_version = "yes" ]; then
diff --git a/ldap/admin/src/scripts/restoreconfig.in b/ldap/admin/src/scripts/restoreconfig.in
index 9e122df..90f8ae8 100755
--- a/ldap/admin/src/scripts/restoreconfig.in
+++ b/ldap/admin/src/scripts/restoreconfig.in
@@ -47,7 +47,7 @@ then
exit 1
fi
-CONFIG_DIR="@instconfigdir@/slapd-$instance
+CONFIG_DIR="@instconfigdir@/slapd-$instance"
conf_ldif=`ls -1t @localstatedir@/lib/@PACKAGE_NAME(a)/slapd-$instance/bak/$instance-*.ldif 2>/dev/null | head -1 `
if [ -z "$conf_ldif" ]
diff --git a/ldap/admin/src/scripts/suffix2instance.in b/ldap/admin/src/scripts/suffix2instance.in
index 2de3ed7..2353479 100755
--- a/ldap/admin/src/scripts/suffix2instance.in
+++ b/ldap/admin/src/scripts/suffix2instance.in
@@ -61,6 +61,6 @@ then
exit 1
fi
-CONFIG_DIR="@instconfigdir@/slapd-$instance
+CONFIG_DIR="@instconfigdir@/slapd-$instance"
eval @sbindir@/ns-slapd suffix2instance -D $CONFIG_DIR $args 2>&1
diff --git a/ldap/admin/src/scripts/vlvindex.in b/ldap/admin/src/scripts/vlvindex.in
index 145f13b..4de3c9a 100755
--- a/ldap/admin/src/scripts/vlvindex.in
+++ b/ldap/admin/src/scripts/vlvindex.in
@@ -68,6 +68,6 @@ then
exit 1
fi
-CONFIG_DIR="@instconfigdir@/slapd-$instance
+CONFIG_DIR="@instconfigdir@/slapd-$instance"
eval @sbindir@/ns-slapd db2index -D $CONFIG_DIR $args
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 10 months