From a2f18fa85c26c86de0b562d43ddf87c2f0994ba6 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 19 2015 15:59:48 +0000 Subject: import 389-ds-base-1.3.4.0-19.el7 --- diff --git a/.389-ds-base.metadata b/.389-ds-base.metadata index 39e4851..c23be8f 100644 --- a/.389-ds-base.metadata +++ b/.389-ds-base.metadata @@ -1 +1,2 @@ -952e538aa0fd95a4cbee5cf2bb2795fbed43a826 SOURCES/389-ds-base-1.3.3.1.tar.bz2 +edf4fc7da08f84699a07586e21d55856e5be7d4f SOURCES/389-ds-base-1.3.4.0.tar.bz2 +7e52309f61c38b241fcdaf0284559d683f3ba700 SOURCES/nunc-stans-0.1.5.tar.bz2 diff --git a/.gitignore b/.gitignore index a20c80c..61b66d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -SOURCES/389-ds-base-1.3.3.1.tar.bz2 +SOURCES/389-ds-base-1.3.4.0.tar.bz2 +SOURCES/nunc-stans-0.1.5.tar.bz2 diff --git a/SOURCES/0000-Ticket-47748-Simultaneous-adding-a-user-and-binding-.patch b/SOURCES/0000-Ticket-47748-Simultaneous-adding-a-user-and-binding-.patch deleted file mode 100644 index 049a080..0000000 --- a/SOURCES/0000-Ticket-47748-Simultaneous-adding-a-user-and-binding-.patch +++ /dev/null @@ -1,73 +0,0 @@ -From dc2157e3a4b04b522147a86477bbd974a9c0b63a Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 9 Sep 2014 12:45:58 -0700 -Subject: [PATCH 0/7] Ticket #47748 - Simultaneous adding a user and binding as - the user could fail in the password policy check - -Description: commit 4fc53e1a63222d0ff67c30a59f2cff4b535f90a8 fix for -Ticket #47748 introduced a bug: "Simple bind hangs after enabling -password policy". - -In do_bind, slapi_check_account_lock and need_new_pw overwrote the -return code from backend bind which is used later. This patch fixes -it not to override the return code. - -https://fedorahosted.org/389/ticket/47748 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 4f11606b02419c8ccdb319b8040e683af9109d1b) -(cherry picked from commit 8c82941c0f2b0b5d7fa698a1ca3e4f26245cf85a) ---- - ldap/servers/slapd/bind.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c -index 58a4e13..bc4aa24 100644 ---- a/ldap/servers/slapd/bind.c -+++ b/ldap/servers/slapd/bind.c -@@ -769,6 +769,7 @@ do_bind( Slapi_PBlock *pb ) - } - - if ( rc == SLAPI_BIND_SUCCESS ) { -+ int myrc = 0; - if (!auto_bind) { - /* - * There could be a race that bind_target_entry was not added -@@ -779,9 +780,9 @@ do_bind( Slapi_PBlock *pb ) - if (!bind_target_entry) { - bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn)); - if (bind_target_entry) { -- rc = slapi_check_account_lock(pb, bind_target_entry, -+ myrc = slapi_check_account_lock(pb, bind_target_entry, - pw_response_requested, 1, 1); -- if (1 == rc) { /* account is locked */ -+ if (1 == myrc) { /* account is locked */ - goto account_locked; - } - } else { -@@ -795,8 +796,8 @@ do_bind( Slapi_PBlock *pb ) - if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) { - /* check if need new password before sending - the bind success result */ -- rc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested); -- switch (rc) { -+ myrc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested); -+ switch (myrc) { - case 1: - (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); - break; -@@ -811,8 +812,8 @@ do_bind( Slapi_PBlock *pb ) - if (auth_response_requested) { - slapi_add_auth_response_control(pb, slapi_sdn_get_ndn(sdn)); - } -- if (-1 == rc) { -- /* neeed_new_pw failed; need_new_pw already send_ldap_result in it. */ -+ if (-1 == myrc) { -+ /* need_new_pw failed; need_new_pw already send_ldap_result in it. */ - goto free_and_return; - } - } else { /* anonymous */ --- -1.9.3 - diff --git a/SOURCES/0001-Ticket-47834-Tombstone_to_glue-if-parents-are-also-c.patch b/SOURCES/0001-Ticket-47834-Tombstone_to_glue-if-parents-are-also-c.patch deleted file mode 100644 index 6486e03..0000000 --- a/SOURCES/0001-Ticket-47834-Tombstone_to_glue-if-parents-are-also-c.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 2566e87a956938a6be3addc586fb2fe53cc8b9f8 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 8 Sep 2014 14:29:29 -0700 -Subject: [PATCH 1/7] Ticket #47834 - Tombstone_to_glue: if parents are also - converted to glue, the target entry's DN must be adjusted. - -Description: Previous fix for the ticket #47834 broke the CI test case -47815. - -The fix for 47815 removed the addingentry from the entry cache if -SLAPI_PLUGIN_BE_TXN_POST_ADD_FN failed. The #47834 patch accidentally -deleted the code. - -Instead of adding it back, this patch moves the deletion of the entry -from the entry cache to cover both cases SLAPI_PLUGIN_BE_TXN_POST_ADD -_FN successes or fails. - -https://fedorahosted.org/389/ticket/47834 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 7db4fa90caa543b59352046138f453236c0fd652) -(cherry picked from commit 78fdd6165cb2c9da4e30452ebdcdcf7aad3d30c7) ---- - ldap/servers/slapd/back-ldbm/ldbm_add.c | 59 ++++++++++++++++++++++++--------- - 1 file changed, 43 insertions(+), 16 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c -index 2f1b398..b74154a 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_add.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c -@@ -1209,21 +1209,6 @@ error_return: - { - next_id_return( be, addingentry->ep_id ); - } -- if ( addingentry ) -- { -- if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) { -- CACHE_REMOVE(&inst->inst_cache, addingentry); -- /* tell frontend not to free this entry */ -- slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); -- } -- else if (!cache_has_otherref(&inst->inst_cache, addingentry)) -- { -- if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */ -- backentry_clear_entry(addingentry); /* e is released in the frontend */ -- } -- } -- CACHE_RETURN( &inst->inst_cache, &addingentry ); -- } - if (rc == DB_RUNRECOVERY) { - dblayer_remember_disk_filled(li); - ldbm_nasty("Add",80,rc); -@@ -1244,6 +1229,20 @@ error_return: - } - diskfull_return: - if (disk_full) { -+ if ( addingentry ) { -+ if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) { -+ CACHE_REMOVE(&inst->inst_cache, addingentry); -+ /* tell frontend not to free this entry */ -+ slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); -+ } -+ else if (!cache_has_otherref(&inst->inst_cache, addingentry)) -+ { -+ if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */ -+ backentry_clear_entry(addingentry); /* e is released in the frontend */ -+ } -+ } -+ CACHE_RETURN( &inst->inst_cache, &addingentry ); -+ } - rc = return_on_disk_full(li); - } else { - /* It is safer not to abort when the transaction is not started. */ -@@ -1277,13 +1276,41 @@ diskfull_return: - } - slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message); - } -- -+ if ( addingentry ) { -+ if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) { -+ CACHE_REMOVE(&inst->inst_cache, addingentry); -+ /* tell frontend not to free this entry */ -+ slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); -+ } -+ else if (!cache_has_otherref(&inst->inst_cache, addingentry)) -+ { -+ if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */ -+ backentry_clear_entry(addingentry); /* e is released in the frontend */ -+ } -+ } -+ CACHE_RETURN( &inst->inst_cache, &addingentry ); -+ } - /* Release SERIAL LOCK */ - if (!noabort) { - dblayer_txn_abort(be, &txn); /* abort crashes in case disk full */ - } - /* txn is no longer valid - reset the txn pointer to the parent */ - slapi_pblock_set(pb, SLAPI_TXN, parent_txn); -+ } else { -+ if ( addingentry ) { -+ if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) { -+ CACHE_REMOVE(&inst->inst_cache, addingentry); -+ /* tell frontend not to free this entry */ -+ slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); -+ } -+ else if (!cache_has_otherref(&inst->inst_cache, addingentry)) -+ { -+ if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */ -+ backentry_clear_entry(addingentry); /* e is released in the frontend */ -+ } -+ } -+ CACHE_RETURN( &inst->inst_cache, &addingentry ); -+ } - } - if (!not_an_error) { - rc = SLAPI_FAIL_GENERAL; --- -1.9.3 - diff --git a/SOURCES/0001-Ticket-48203-Fix-coverity-issues-06-22-2015.patch b/SOURCES/0001-Ticket-48203-Fix-coverity-issues-06-22-2015.patch new file mode 100644 index 0000000..ee98694 --- /dev/null +++ b/SOURCES/0001-Ticket-48203-Fix-coverity-issues-06-22-2015.patch @@ -0,0 +1,89 @@ +From 97da9cb32b41d87d9dc5930a2ad931df559ae7f5 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 23 Jun 2015 14:48:13 -0700 +Subject: [PATCH 1/2] Ticket #48203 - Fix coverity issues - 06/22/2015 + +Description: +13294 Uninitialized scalar variable -- retrocl_init_trimming (introduced by #47669) +13293 Resource leak -- retrocl_init_trimming (introduced by #47669) + +2. Defect type: CHECKED_RETURN +50. ldap/servers/slapd/tools/ldclt/ldapfct.c:1945: +9. ldap/servers/slapd/tools/ldclt/ldapfct.c:952: + check_return: Calling "addErrorStat" without checking return value + (as is done elsewhere 26 out of 28 times). + +1. Defect type: COMPILER_WARNING +2. ldap/servers/slapd/daemon.c:1412:21: + warning: 'tp' may be used uninitialized in this function [-Wmaybe-uninitialized] + +https://fedorahosted.org/389/ticket/48203 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit 32d45c74231545ad91934147962bfb676dcdd391) +--- + ldap/servers/plugins/retrocl/retrocl_trim.c | 3 ++- + ldap/servers/slapd/daemon.c | 2 +- + ldap/servers/slapd/tools/ldclt/ldapfct.c | 4 ++-- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c +index 65f3015..b09f669 100644 +--- a/ldap/servers/plugins/retrocl/retrocl_trim.c ++++ b/ldap/servers/plugins/retrocl/retrocl_trim.c +@@ -412,7 +412,7 @@ void retrocl_housekeeping ( time_t cur_time, void *noarg ) + void retrocl_init_trimming (void) + { + const char *cl_maxage; +- time_t ageval; ++ time_t ageval = 0; /* Don't trim, by default */ + const char *cl_trim_interval; + + cl_maxage = retrocl_get_config_str(CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE); +@@ -425,6 +425,7 @@ void retrocl_init_trimming (void) + "retrocl_init_trimming: ignoring invalid %s value %s; " + "not trimming retro changelog.\n", + CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE, cl_maxage); ++ slapi_ch_free_string((char **)&cl_maxage); + return; + } + } +diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c +index 436f3d5..ba73da3 100644 +--- a/ldap/servers/slapd/daemon.c ++++ b/ldap/servers/slapd/daemon.c +@@ -1026,7 +1026,7 @@ void slapd_daemon( daemon_ports_t *ports ) + int threads; + int in_referral_mode = config_check_referral_mode(); + #ifdef ENABLE_NUNC_STANS +- ns_thrpool_t *tp; ++ ns_thrpool_t *tp = NULL; + struct ns_thrpool_config tp_config; + #endif + int connection_table_size = get_configured_connection_table_size(); +diff --git a/ldap/servers/slapd/tools/ldclt/ldapfct.c b/ldap/servers/slapd/tools/ldclt/ldapfct.c +index bc8c89d..f906c5a 100644 +--- a/ldap/servers/slapd/tools/ldclt/ldapfct.c ++++ b/ldap/servers/slapd/tools/ldclt/ldapfct.c +@@ -949,7 +949,7 @@ connectToServer ( + fprintf (stderr, "ldclt[%d]: T%03d: cannot ldap_unbind(), error=%d (%s)\n", + mctx.pid, tttctx->thrdNum, ret,strerror (ret)); + fflush (stderr); +- addErrorStat(ret); ++ (void)addErrorStat(ret); + return (-1); + } + tttctx->ldapCtx = NULL; +@@ -1942,7 +1942,7 @@ createMissingNodes ( + printf ("ldclt[%d]: T%03d: Cannot add (%s), error=%d (%s)\n", + mctx.pid, tttctx->thrdNum, nodeDN, ret, my_ldap_err2string (ret)); + fflush (stdout); +- addErrorStat(ret); ++ (void)addErrorStat(ret); + return (-1); + } + +-- +1.9.3 + diff --git a/SOURCES/0002-Ticket-47890-minor-memory-leaks-in-utilities.patch b/SOURCES/0002-Ticket-47890-minor-memory-leaks-in-utilities.patch deleted file mode 100644 index 3022e20..0000000 --- a/SOURCES/0002-Ticket-47890-minor-memory-leaks-in-utilities.patch +++ /dev/null @@ -1,89 +0,0 @@ -From ed7316fc2e770c4e0c877e220434489318735c76 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 9 Sep 2014 14:27:40 -0700 -Subject: [PATCH 2/7] Ticket #47890 - minor memory leaks in utilities - -Description: -tools/rsearch/nametable.c - if nt_push fails and the strdup'ed - string is not pushed to the table, - free the string. -tools/migratecred.c - free strdup'ed strings oldpath, newpath, - prefixCred, and pluginpath at the end of - the process. - -https://fedorahosted.org/389/ticket/47890 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 1279f0e0fe1d0f5456e42ef5b7a9f395f793cc9e) -(cherry picked from commit aa8ff4b066243f68175f2e664239b7db8747e1d1) ---- - ldap/servers/slapd/tools/migratecred.c | 13 ++++++++++++- - ldap/servers/slapd/tools/rsearch/nametable.c | 13 ++++++++----- - 2 files changed, 20 insertions(+), 6 deletions(-) - -diff --git a/ldap/servers/slapd/tools/migratecred.c b/ldap/servers/slapd/tools/migratecred.c -index 085a21a..c1e37bf 100644 ---- a/ldap/servers/slapd/tools/migratecred.c -+++ b/ldap/servers/slapd/tools/migratecred.c -@@ -163,6 +163,10 @@ main( int argc, char **argv) - - if ( !oldpath || !newpath || !cred ) - { -+ free(oldpath); -+ free(newpath); -+ free(prefixCred); -+ free(pluginpath); - usage(cmd); - } - -@@ -208,6 +212,10 @@ main( int argc, char **argv) - "DES Plugin", 1 /* report errors */ ); - if ( fct == NULL ) - { -+ free(oldpath); -+ free(newpath); -+ free(prefixCred); -+ free(pluginpath); - usage(cmd); - return(1); - } -@@ -215,7 +223,10 @@ main( int argc, char **argv) - newcred = (fct)(oldpath, newpath, cred); - - fprintf(stdout, "%s", newcred); -- -+ free(oldpath); -+ free(newpath); -+ free(prefixCred); -+ free(pluginpath); - return(0); - - } -diff --git a/ldap/servers/slapd/tools/rsearch/nametable.c b/ldap/servers/slapd/tools/rsearch/nametable.c -index e5d04cd..03a6ae1 100644 ---- a/ldap/servers/slapd/tools/rsearch/nametable.c -+++ b/ldap/servers/slapd/tools/rsearch/nametable.c -@@ -152,11 +152,14 @@ int nt_load(NameTable *nt, const char *filename) - if (!fd) return 0; - - while (PR_Available(fd) > 0) { -- char temp[4096], *s; -- if (PR_GetLine(fd, temp, sizeof(temp))) break; -- s = strdup(temp); -- if (!s) break; -- if (!nt_push(nt, s)) break; -+ char temp[4096], *s; -+ if (PR_GetLine(fd, temp, sizeof(temp))) break; -+ s = strdup(temp); -+ if (!s) break; -+ if (!nt_push(nt, s)) { -+ free(s); -+ break; -+ } - } - PR_Close(fd); - return nt->size; --- -1.9.3 - diff --git a/SOURCES/0002-Ticket-48195-Slow-replication-when-deleting-large-qu.patch b/SOURCES/0002-Ticket-48195-Slow-replication-when-deleting-large-qu.patch new file mode 100644 index 0000000..f6890db --- /dev/null +++ b/SOURCES/0002-Ticket-48195-Slow-replication-when-deleting-large-qu.patch @@ -0,0 +1,44 @@ +From 0ad9acb61f83244af02081ffd79c350af831f21c Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +Date: Thu, 18 Jun 2015 15:22:54 +0200 +Subject: [PATCH 2/2] Ticket 48195 - Slow replication when deleting large + quantities of multi-valued attributes + +https://fedorahosted.org/389/ticket/48195 + +In update resoultion for entry deletion, there is still use of valuearray_find() to find an existingvalue to update its csn. +with the fix for ticket #346 there exists slapi_valueset_find() which uses the possibility to do a binary search on the +values. +Fix: do not use valuearray_find + +Review: Rich, Thanks +(cherry picked from commit 09ab8c799fc3d87db7a5b3aa07eccf9b41ea43d5) +(cherry picked from commit a980b795ac03200fd01a2d05ce568691681d50ef) +--- + ldap/servers/slapd/valueset.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c +index 73208f5..0cf3ded 100644 +--- a/ldap/servers/slapd/valueset.c ++++ b/ldap/servers/slapd/valueset.c +@@ -1411,12 +1411,12 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a, + int del_index = -1, del_count = 0; + for (i=0;valuestoupdate[i]!=NULL;++i) + { +- int index= valuearray_find(a, vs->va, valuestoupdate[i]); +- if(index!=-1) ++ Slapi_Value *v = slapi_valueset_find(a, vs, valuestoupdate[i]); ++ if(v) + { +- value_update_csn(vs->va[index],t,csn); ++ value_update_csn(v,t,csn); + if (csnref_updated) +- valuestoupdate[i]->v_csnset = (CSNSet *)value_get_csnset(vs->va[index]); ++ valuestoupdate[i]->v_csnset = (CSNSet *)value_get_csnset(v); + valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]); + valuestoupdate[i]= NULL; + del_count++; +-- +1.9.3 + diff --git a/SOURCES/0003-Ticket-48212-Dynamic-nsMatchingRule-changes-had-no-e.patch b/SOURCES/0003-Ticket-48212-Dynamic-nsMatchingRule-changes-had-no-e.patch new file mode 100644 index 0000000..93e3d89 --- /dev/null +++ b/SOURCES/0003-Ticket-48212-Dynamic-nsMatchingRule-changes-had-no-e.patch @@ -0,0 +1,52 @@ +From 2ad324a00c8e429171d5c096a56c32aed3206466 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 1 Jul 2015 18:16:20 -0700 +Subject: [PATCH 3/7] Ticket #48212 - Dynamic nsMatchingRule changes had no + effect on the attrinfo thus following reindexing, as well. + +Description: When nsMatchingRule was dynamically updated in an index entry, +the value was set to the configuration but was not applied to the attribute +info. On-line reindexing following the nsMatchingRule change actually ignored +the setting. On the other hand, the standalone utility dbverify independently +picked up the nsMatchingRule from the configuration and generated the attribute +info, which expected the index reindexed based upon the new nsMatchingRule. But +it was actually not and dbverify reported the index corruption. + +This patch applies the changes to the attribute info when nsMatchingRule is +modified. + +https://fedorahosted.org/389/ticket/48212 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!) + +(cherry picked from commit d9679725e69df1d191864ca00bad6b79b13e7362) +(cherry picked from commit d15beff66fd28902bd8ca80af12ad76a7ecbe57d) +--- + ldap/servers/slapd/back-ldbm/ldbm_attr.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c +index 62ed6e1..092b6b5 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c +@@ -127,7 +127,16 @@ ainfo_dup( + attrinfo_delete_idlistinfo(&a->ai_idlistinfo); + a->ai_idlistinfo = b->ai_idlistinfo; + b->ai_idlistinfo = NULL; +- ++ ++ /* copy cmp functions and substr lengths */ ++ a->ai_key_cmp_fn = b->ai_key_cmp_fn; ++ a->ai_dup_cmp_fn = b->ai_dup_cmp_fn; ++ if (b->ai_substr_lens) { ++ size_t substrlen = sizeof(int) * INDEX_SUBSTRLEN; ++ a->ai_substr_lens = (int *)slapi_ch_calloc(1, substrlen); ++ memcpy(a->ai_substr_lens, b->ai_substr_lens, substrlen); ++ } ++ + return( 1 ); + } + +-- +1.9.3 + diff --git a/SOURCES/0003-fix-for-47885-did-not-always-return-a-response-contr.patch b/SOURCES/0003-fix-for-47885-did-not-always-return-a-response-contr.patch deleted file mode 100644 index 93e27f0..0000000 --- a/SOURCES/0003-fix-for-47885-did-not-always-return-a-response-contr.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 09f106acd0ad639965fdc1b97fd1718ce4eec355 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Wed, 10 Sep 2014 13:22:06 +0200 -Subject: [PATCH 3/7] fix for 47885 did not always return a response control - -reviewd by rich, thanks - -(cherry picked from commit 55e317f2a5d8fc488e7eeee6f2b4155298a45d25) ---- - ldap/servers/plugins/deref/deref.c | 30 ++++++++++++------------------ - 1 file changed, 12 insertions(+), 18 deletions(-) - -diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c -index 96d42e6..1bab0ab 100644 ---- a/ldap/servers/plugins/deref/deref.c -+++ b/ldap/servers/plugins/deref/deref.c -@@ -591,14 +591,13 @@ deref_values_free(Slapi_ValueSet** results, char** actual_type_name, int buffer_ - slapi_vattr_values_free(results, actual_type_name, buffer_flags); - } - --static int -+static void - deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, const char *derefattr, const char **attrs) - { - char **retattrs = NULL; - Slapi_PBlock *derefpb = NULL; - Slapi_Entry **entries = NULL; - int rc; -- int needcontrol = 0; - - /* If the access check on the attributes is done without retrieveing the entry - * it cannot handle acis which need teh entry, eg to apply a targetfilter rule -@@ -628,7 +627,6 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, - "The client does not have permission to read the requested " - "attributes in entry %s\n", derefdn); - } else { -- needcontrol = 1; - ber_printf(ctrlber, "{ss", derefattr, derefdn); /* begin DerefRes + derefAttr + derefVal */ - for (ii = 0; retattrs[ii]; ++ii) { - Slapi_Value *sv; -@@ -704,7 +702,6 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, - slapi_pblock_destroy(derefpb); - slapi_ch_free((void **)&retattrs); /* retattrs does not own the strings */ - -- return needcontrol; - } - - static int -@@ -718,7 +715,6 @@ deref_pre_entry(Slapi_PBlock *pb) - LDAPControl *ctrl = NULL; - const LDAPControl **searchctrls = NULL; - LDAPControl **newsearchctrls = NULL; -- int needcontrol = 0; - - if (!speclist) { - return 0; /* nothing to do */ -@@ -762,25 +758,23 @@ deref_pre_entry(Slapi_PBlock *pb) - for (; results && sv; idx = slapi_valueset_next_value(results, idx, &sv)) { - const char *derefdn = slapi_value_get_string(sv); - -- needcontrol += deref_do_deref_attr(pb, ctrlber, derefdn, spec->derefattr, (const char **)spec->attrs); -+ deref_do_deref_attr(pb, ctrlber, derefdn, spec->derefattr, (const char **)spec->attrs); - } - deref_values_free(&results, &actual_type_name, buffer_flags); - } - - ber_printf(ctrlber, "}"); /* end control val */ - -- if (needcontrol) { -- slapi_build_control(LDAP_CONTROL_X_DEREF, ctrlber, 0, &ctrl); -- /* get the list of controls */ -- slapi_pblock_get(pb, SLAPI_SEARCH_CTRLS, &searchctrls); -- /* dup them */ -- slapi_add_controls(&newsearchctrls, (LDAPControl **)searchctrls, 1); -- /* add our control */ -- slapi_add_control_ext(&newsearchctrls, ctrl, 0); -- ctrl = NULL; /* newsearchctrls owns it now */ -- /* set the controls in the pblock */ -- slapi_pblock_set(pb, SLAPI_SEARCH_CTRLS, newsearchctrls); -- } -+ slapi_build_control(LDAP_CONTROL_X_DEREF, ctrlber, 0, &ctrl); -+ /* get the list of controls */ -+ slapi_pblock_get(pb, SLAPI_SEARCH_CTRLS, &searchctrls); -+ /* dup them */ -+ slapi_add_controls(&newsearchctrls, (LDAPControl **)searchctrls, 1); -+ /* add our control */ -+ slapi_add_control_ext(&newsearchctrls, ctrl, 0); -+ ctrl = NULL; /* newsearchctrls owns it now */ -+ /* set the controls in the pblock */ -+ slapi_pblock_set(pb, SLAPI_SEARCH_CTRLS, newsearchctrls); - ber_free(ctrlber, 1); - - return 0; --- -1.9.3 - diff --git a/SOURCES/0004-Ticket-47838-harden-the-list-of-ciphers-available-by.patch b/SOURCES/0004-Ticket-47838-harden-the-list-of-ciphers-available-by.patch deleted file mode 100644 index b9cea64..0000000 --- a/SOURCES/0004-Ticket-47838-harden-the-list-of-ciphers-available-by.patch +++ /dev/null @@ -1,468 +0,0 @@ -From 2c550346512bc3dec27c9329f4902663759e4b65 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 11 Sep 2014 11:46:51 -0700 -Subject: [PATCH 4/7] Ticket #47838 - harden the list of ciphers available by - default - -Description: -1. Introducing a new attribute allowWeakCipher in "cn=encryption,cn=config". - allowWeakCipher: [on | off] - on -- allows weak ciphers. - Default setting for user specified ciphers. - off -- rejects weak ciphers. - Default setting for +all and default. - -2. allowWeakCipher is applied only to the user specified cipher suites - such as "nsSSL3Ciphers: +rsa_rc4_128_md5". - If allowWeakCipher is enabled and the user specified cipher is weak, - SSL alert is logged in the error log: - SSL alert: Cipher rsa_rc4_128_md5 is weak. It is enabled since - allowWeakCipher is "on" (default setting for the backward compatibility). - We strongly recommend to set it to "off". Please replace the value of - allowWeakCipher with "off" in the encryption config entry cn=encryption, - cn=config and restart the server. - -3. If specified cipher suite is not supported, ignore the cipher suite - and continue setting ciphers. - -https://fedorahosted.org/389/ticket/47838 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit 5f3c87e1380e56d76d4a4bef3af07633a8589891) -(cherry picked from commit 58cb12a7b8cf938c5a4b920c4a1ad1da02fecdb8) ---- - ldap/schema/01core389.ldif | 3 +- - ldap/servers/slapd/ssl.c | 262 +++++++++++++++++++++++++++------------------ - 2 files changed, 162 insertions(+), 103 deletions(-) - -diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif -index 1b8a70b..c7aec70 100644 ---- a/ldap/schema/01core389.ldif -+++ b/ldap/schema/01core389.ldif -@@ -128,6 +128,7 @@ attributeTypes: ( nsSSL3SessionTimeout-oid NAME 'nsSSL3SessionTimeout' DESC 'Net - attributeTypes: ( nsSSL2Ciphers-oid NAME 'nsSSL2Ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) - attributeTypes: ( nsSSL3Ciphers-oid NAME 'nsSSL3Ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) - attributeTypes: ( nsSSLSupportedCiphers-oid NAME 'nsSSLSupportedCiphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) -+attributeTypes: ( allowWeakCipher-oid NAME 'allowWeakCipher' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) - attributeTypes: ( nsSSLToken-oid NAME 'nsSSLToken' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) - attributeTypes: ( nsSSLPersonalitySSL-oid NAME 'nsSSLPersonalitySSL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) - attributeTypes: ( nsSSLActivation-oid NAME 'nsSSLActivation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) -@@ -316,7 +317,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC - objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) MAY ( nsSaslMapPriority ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' ) --objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers) X-ORIGIN 'Netscape' ) -+objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers $ allowWeakCipher) X-ORIGIN 'Netscape' ) - objectClasses: ( nsEncryptionModule-oid NAME 'nsEncryptionModule' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsSSLToken $ nsSSLPersonalityssl $ nsSSLActivation ) X-ORIGIN 'Netscape' ) - objectClasses: ( 2.16.840.1.113730.3.2.327 NAME 'rootDNPluginConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( rootdn-open-time $ rootdn-close-time $ rootdn-days-allowed $ rootdn-allow-host $ rootdn-deny-host $ rootdn-allow-ip $ rootdn-deny-ip ) X-ORIGIN 'Netscape' ) - objectClasses: ( 2.16.840.1.113730.3.2.328 NAME 'nsSchemaPolicy' DESC 'Netscape defined objectclass' SUP top MAY ( cn $ schemaUpdateObjectclassAccept $ schemaUpdateObjectclassReject $ schemaUpdateAttributeAccept $ schemaUpdateAttributeReject) X-ORIGIN 'Netscape Directory Server' ) -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 1a21df0..03b5904 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -119,7 +119,21 @@ static char * configDN = "cn=encryption,cn=config"; - #define FILE_PATHSEP '/' - - /* ----------------------- Multiple cipher support ------------------------ */ -- -+/* cipher set flags */ -+#define CIPHER_SET_ALL 0x1 -+#define CIPHER_SET_NONE 0x0 -+#define CIPHER_SET_DEFAULT 0x2 -+#define CIPHER_SET_CORE (CIPHER_SET_ALL|CIPHER_SET_DEFAULT|CIPHER_SET_NONE) -+#define CIPHER_SET_ALLOWWEAKCIPHER 0x10 /* can be or'ed with other CIPHER_SET flags */ -+ -+#define CIPHER_SET_ISDEFAULT(flag) \ -+ ((((flag)&CIPHER_SET_CORE) == CIPHER_SET_DEFAULT) ? PR_TRUE : PR_FALSE) -+#define CIPHER_SET_ISALL(flag) \ -+ ((((flag)&CIPHER_SET_CORE) == CIPHER_SET_ALL) ? PR_TRUE : PR_FALSE) -+#define CIPHER_SET_ALLOWSWEAKCIPHER(flag) \ -+ (((flag)&CIPHER_SET_ALLOWWEAKCIPHER) ? PR_TRUE : PR_FALSE) -+#define CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flag) \ -+ ((flag)&~CIPHER_SET_ALLOWWEAKCIPHER) - - /* flags */ - #define CIPHER_IS_DEFAULT 0x1 -@@ -158,7 +172,7 @@ static lookup_cipher _lookup_cipher[] = { - {"tls_rsa_3des_sha", "TLS_RSA_WITH_3DES_EDE_CBC_SHA"}, - {"rsa_fips_3des_sha", "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, - {"fips_3des_sha", "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, -- {"rsa_des_sha", "TLS_RSA_WITH_DES_CBC_SHA"}, -+ {"rsa_des_sha", "SSL_RSA_WITH_DES_CBC_SHA"}, - {"rsa_fips_des_sha", "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, - {"fips_des_sha", "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, /* ditto */ - {"rsa_rc4_40_md5", "TLS_RSA_EXPORT_WITH_RC4_40_MD5"}, -@@ -339,21 +353,20 @@ _conf_init_ciphers() - return; - } - --#define CIPHER_SET_ALL 1 --#define CIPHER_SET_NONE 0 --#define CIPHER_SET_DEFAULT 2 - /* -- * flag: 1 -- enable all -- * 0 -- disable all -- * 2 -- set default ciphers -+ * flag: CIPHER_SET_ALL -- enable all -+ * CIPHER_SET_NONE -- disable all -+ * CIPHER_SET_DEFAULT -- set default ciphers -+ * CIPHER_SET_ALLOW_WEAKCIPHER -- allow weak ciphers (can be or'ed with the ather CIPHER_SET flags) - */ - static void - _conf_setallciphers(int flag, char ***suplist, char ***unsuplist) - { - int x; - SECStatus rc; -- PRBool setdefault = (flag == CIPHER_SET_DEFAULT) ? PR_TRUE : PR_FALSE; -- PRBool enabled = (flag == CIPHER_SET_ALL) ? PR_TRUE : PR_FALSE; -+ PRBool setdefault = CIPHER_SET_ISDEFAULT(flag); -+ PRBool enabled = CIPHER_SET_ISALL(flag); -+ PRBool allowweakcipher = CIPHER_SET_ALLOWSWEAKCIPHER(flag); - PRBool setme = PR_FALSE; - const PRUint16 *implementedCiphers = SSL_GetImplementedCiphers(); - -@@ -361,8 +374,9 @@ _conf_setallciphers(int flag, char ***suplist, char ***unsuplist) - - for (x = 0; implementedCiphers && (x < SSL_NumImplementedCiphers); x++) { - if (_conf_ciphers[x].flags & CIPHER_IS_DEFAULT) { -+ /* certainly, not the first time. */ - setme = PR_TRUE; -- } else { -+ } else if (setdefault) { - /* - * SSL_CipherPrefGetDefault - * If the application has not previously set the default preference, -@@ -375,15 +389,16 @@ _conf_setallciphers(int flag, char ***suplist, char ***unsuplist) - _conf_ciphers[x].name); - continue; - } -- if (_conf_ciphers[x].flags & CIPHER_IS_WEAK) { -+ if (!allowweakcipher && (_conf_ciphers[x].flags & CIPHER_IS_WEAK)) { - setme = PR_FALSE; - } - _conf_ciphers[x].flags |= setme?CIPHER_IS_DEFAULT:0; -- } -- if (setdefault) { -- /* Use the NSS default settings */ - } else if (enabled && !(_conf_ciphers[x].flags & CIPHER_MUST_BE_DISABLED)) { -- setme = PR_TRUE; -+ if (!allowweakcipher && (_conf_ciphers[x].flags & CIPHER_IS_WEAK)) { -+ setme = PR_FALSE; -+ } else { -+ setme = PR_TRUE; -+ } - } else { - setme = PR_FALSE; - } -@@ -433,7 +448,7 @@ _conf_dumpciphers() - } - - char * --_conf_setciphers(char *ciphers) -+_conf_setciphers(char *ciphers, int flags) - { - char *t, err[MAGNUS_ERROR_LEN]; - int x, i, active; -@@ -445,7 +460,7 @@ _conf_setciphers(char *ciphers) - /* #47838: harden the list of ciphers available by default */ - /* Default is to activate all of them ==> none of them*/ - if (!ciphers || (ciphers[0] == '\0') || !PL_strcasecmp(ciphers, "default")) { -- _conf_setallciphers(CIPHER_SET_DEFAULT, NULL, NULL); -+ _conf_setallciphers((CIPHER_SET_DEFAULT|CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flags)), NULL, NULL); - slapd_SSL_warn("Security Initialization: Enabling default cipher set."); - _conf_dumpciphers(); - return NULL; -@@ -458,11 +473,11 @@ _conf_setciphers(char *ciphers) - * set of ciphers in the table. Right now there is no support for this - * from the console - */ -- _conf_setallciphers(CIPHER_SET_ALL, &suplist, NULL); -+ _conf_setallciphers(CIPHER_SET_ALL|CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flags), &suplist, NULL); - } else { - /* If "+all" is not in nsSSL3Ciphers value, disable all first, - * then enable specified ciphers. */ -- _conf_setallciphers(0 /* disabled */, NULL, NULL); -+ _conf_setallciphers(CIPHER_SET_NONE /* disabled */, NULL, NULL); - } - - t = ciphers; -@@ -482,12 +497,28 @@ _conf_setciphers(char *ciphers) - if( (t = strchr(ciphers, ',')) ) - *t++ = '\0'; - -- if(strcasecmp(ciphers, "all")) { /* if not all */ -+ if (strcasecmp(ciphers, "all")) { /* if not all */ - PRBool enabled = active ? PR_TRUE : PR_FALSE; - lookup = 1; -- for(x = 0; _conf_ciphers[x].name; x++) { -- if(!PL_strcasecmp(ciphers, _conf_ciphers[x].name)) { -+ for (x = 0; _conf_ciphers[x].name; x++) { -+ if (!PL_strcasecmp(ciphers, _conf_ciphers[x].name)) { -+ if (_conf_ciphers[x].flags & CIPHER_IS_WEAK) { -+ if (CIPHER_SET_ALLOWSWEAKCIPHER(flags)) { -+ slapd_SSL_warn("Cipher %s is weak. It is enabled since allowWeakCipher is \"on\" " -+ "(default setting for the backward compatibility). " -+ "We strongly recommend to set it to \"off\". " -+ "Please replace the value of allowWeakCipher with \"off\" in " -+ "the encryption config entry cn=encryption,cn=config and " -+ "restart the server.", ciphers); -+ } else { -+ /* if the cipher is weak and we don't allow weak cipher, -+ disable it. */ -+ enabled = PR_FALSE; -+ } -+ } - if (enabled) { -+ /* if the cipher is not weak or we allow weak cipher, -+ check fips. */ - enabled = cipher_check_fips(x, NULL, &unsuplist); - } - SSL_CipherPrefSetDefault(_conf_ciphers[x].num, enabled); -@@ -499,14 +530,33 @@ _conf_setciphers(char *ciphers) - for (i = 0; _lookup_cipher[i].alias; i++) { - if (!PL_strcasecmp(ciphers, _lookup_cipher[i].alias)) { - if (!_lookup_cipher[i].name[0]) { -- slapd_SSL_warn("Cipher suite %s is not available in NSS %d.%d", -- ciphers, NSS_VMAJOR, NSS_VMINOR); -- break; -+ slapd_SSL_warn("Cipher suite %s is not available in NSS %d.%d. Ignoring %s", -+ ciphers, NSS_VMAJOR, NSS_VMINOR, ciphers); -+ continue; - } - for (x = 0; _conf_ciphers[x].name; x++) { - if (!PL_strcasecmp(_lookup_cipher[i].name, _conf_ciphers[x].name)) { - if (enabled) { -- enabled = cipher_check_fips(x, NULL, &unsuplist); -+ if (_conf_ciphers[x].flags & CIPHER_IS_WEAK) { -+ if (CIPHER_SET_ALLOWSWEAKCIPHER(flags)) { -+ slapd_SSL_warn("Cipher %s is weak. " -+ "It is enabled since allowWeakCipher is \"on\" " -+ "(default setting for the backward compatibility). " -+ "We strongly recommend to set it to \"off\". " -+ "Please replace the value of allowWeakCipher with \"off\" in " -+ "the encryption config entry cn=encryption,cn=config and " -+ "restart the server.", ciphers); -+ } else { -+ /* if the cipher is weak and we don't allow weak cipher, -+ disable it. */ -+ enabled = PR_FALSE; -+ } -+ } -+ if (enabled) { -+ /* if the cipher is not weak or we allow weak cipher, -+ check fips. */ -+ enabled = cipher_check_fips(x, NULL, &unsuplist); -+ } - } - SSL_CipherPrefSetDefault(_conf_ciphers[x].num, enabled); - break; -@@ -1008,6 +1058,7 @@ slapd_ssl_init() - int rv = 0; - PK11SlotInfo *slot; - Slapi_Entry *entry = NULL; -+ int allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; - - /* Get general information */ - -@@ -1017,21 +1068,21 @@ slapd_ssl_init() - ciphers = slapi_entry_attr_get_charptr( entry, "nsssl3ciphers" ); - - /* We are currently using the value of sslSessionTimeout -- for ssl3SessionTimeout, see SSL_ConfigServerSessionIDCache() */ -+ for ssl3SessionTimeout, see SSL_ConfigServerSessionIDCache() */ - /* Note from Tom Weinstein on the meaning of the timeout: - - Timeouts are in seconds. '0' means use the default, which is -- 24hrs for SSL3 and 100 seconds for SSL2. -+ 24hrs for SSL3 and 100 seconds for SSL2. - */ - - if(!val) { - errorCode = PR_GetError(); - slapd_SSL_warn("Security Initialization: Failed to retrieve SSL " - "configuration information (" -- SLAPI_COMPONENT_NAME_NSPR " error %d - %s): " -- "nssslSessionTimeout: %s ", -- errorCode, slapd_pr_strerror(errorCode), -- (val ? "found" : "not found")); -+ SLAPI_COMPONENT_NAME_NSPR " error %d - %s): " -+ "nssslSessionTimeout: %s ", -+ errorCode, slapd_pr_strerror(errorCode), -+ (val ? "found" : "not found")); - slapi_ch_free((void **) &val); - slapi_ch_free((void **) &ciphers); - freeConfigEntry( &entry ); -@@ -1042,79 +1093,86 @@ slapd_ssl_init() - slapi_ch_free((void **) &val); - - if (svrcore_setup()) { -- freeConfigEntry( &entry ); -- return -1; -+ freeConfigEntry( &entry ); -+ return -1; - } - -- if((family_list = getChildren(configDN))) { -- char **family; -- char *token; -- char *activation; -+ val = slapi_entry_attr_get_charptr(entry, "allowWeakCipher"); -+ if (val && (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -+ !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no"))) { -+ allowweakcipher = 0; -+ } -+ slapi_ch_free((void **) &val); -+ -+ if ((family_list = getChildren(configDN))) { -+ char **family; -+ char *token; -+ char *activation; - -- for (family = family_list; *family; family++) { -+ for (family = family_list; *family; family++) { - -- token = NULL; -- activation = NULL; -+ token = NULL; -+ activation = NULL; - -- freeConfigEntry( &entry ); -+ freeConfigEntry( &entry ); - -- getConfigEntry( *family, &entry ); -- if ( entry == NULL ) { -- continue; -- } -+ getConfigEntry( *family, &entry ); -+ if ( entry == NULL ) { -+ continue; -+ } - -- activation = slapi_entry_attr_get_charptr( entry, "nssslactivation" ); -- if((!activation) || (!PL_strcasecmp(activation, "off"))) { -- /* this family was turned off, goto next */ -- slapi_ch_free((void **) &activation); -- continue; -- } -+ activation = slapi_entry_attr_get_charptr( entry, "nssslactivation" ); -+ if((!activation) || (!PL_strcasecmp(activation, "off"))) { -+ /* this family was turned off, goto next */ -+ slapi_ch_free((void **) &activation); -+ continue; -+ } - -- slapi_ch_free((void **) &activation); -- -- token = slapi_entry_attr_get_charptr( entry, "nsssltoken" ); -- if( token ) { -- if( !PL_strcasecmp(token, "internal") || -- !PL_strcasecmp(token, "internal (software)")) -- slot = slapd_pk11_getInternalKeySlot(); -- else -- slot = slapd_pk11_findSlotByName(token); -- } else { -- errorCode = PR_GetError(); -- slapd_SSL_warn("Security Initialization: Unable to get token (" -- SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -- errorCode, slapd_pr_strerror(errorCode)); -- freeChildren(family_list); -- freeConfigEntry( &entry ); -- return -1; -- } -+ slapi_ch_free((void **) &activation); - -- slapi_ch_free((void **) &token); -+ token = slapi_entry_attr_get_charptr( entry, "nsssltoken" ); -+ if ( token ) { -+ if (!PL_strcasecmp(token, "internal") || -+ !PL_strcasecmp(token, "internal (software)")) { -+ slot = slapd_pk11_getInternalKeySlot(); -+ } else { -+ slot = slapd_pk11_findSlotByName(token); -+ } -+ } else { -+ errorCode = PR_GetError(); -+ slapd_SSL_warn("Security Initialization: Unable to get token (" -+ SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -+ errorCode, slapd_pr_strerror(errorCode)); -+ freeChildren(family_list); -+ freeConfigEntry( &entry ); -+ return -1; -+ } - -- if (!slot) { -- errorCode = PR_GetError(); -- slapd_SSL_warn("Security Initialization: Unable to find slot (" -- SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -- errorCode, slapd_pr_strerror(errorCode)); -- freeChildren(family_list); -- freeConfigEntry( &entry ); -- return -1; -- } -- /* authenticate */ -- if(slapd_pk11_authenticate(slot, PR_TRUE, NULL) != SECSuccess) -- { -- errorCode = PR_GetError(); -- slapd_SSL_warn("Security Initialization: Unable to authenticate (" -- SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -- errorCode, slapd_pr_strerror(errorCode)); -- freeChildren(family_list); -- freeConfigEntry( &entry ); -- return -1; -- } -- } -- freeChildren( family_list ); -+ slapi_ch_free((void **) &token); -+ -+ if (!slot) { -+ errorCode = PR_GetError(); -+ slapd_SSL_warn("Security Initialization: Unable to find slot (" -+ SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -+ errorCode, slapd_pr_strerror(errorCode)); -+ freeChildren(family_list); -+ freeConfigEntry( &entry ); -+ return -1; -+ } -+ /* authenticate */ -+ if (slapd_pk11_authenticate(slot, PR_TRUE, NULL) != SECSuccess) { -+ errorCode = PR_GetError(); -+ slapd_SSL_warn("Security Initialization: Unable to authenticate (" -+ SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -+ errorCode, slapd_pr_strerror(errorCode)); -+ freeChildren(family_list); -+ freeConfigEntry( &entry ); -+ return -1; -+ } -+ } -+ freeChildren( family_list ); -+ freeConfigEntry( &entry ); - } -- freeConfigEntry( &entry ); - - /* ugaston- Cipher preferences must be set before any sslSocket is created - * for such sockets to take preferences into account. -@@ -1126,13 +1184,13 @@ slapd_ssl_init() - PL_strncpyz(cipher_string, ciphers, sizeof(cipher_string)); - slapi_ch_free((void **) &ciphers); - -- if( NULL != (val = _conf_setciphers(cipher_string)) ) { -- errorCode = PR_GetError(); -- slapd_SSL_warn("Security Initialization: Failed to set SSL cipher " -- "preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -- val, errorCode, slapd_pr_strerror(errorCode)); -- rv = 3; -- slapi_ch_free((void **) &val); -+ if ( NULL != (val = _conf_setciphers(cipher_string, allowweakcipher)) ) { -+ errorCode = PR_GetError(); -+ slapd_SSL_warn("Security Initialization: Failed to set SSL cipher " -+ "preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -+ val, errorCode, slapd_pr_strerror(errorCode)); -+ rv = 3; -+ slapi_ch_free((void **) &val); - } - - freeConfigEntry( &entry ); --- -1.9.3 - diff --git a/SOURCES/0004-Ticket-48212-CI-test-added-test-cases-for-ticket-482.patch b/SOURCES/0004-Ticket-48212-CI-test-added-test-cases-for-ticket-482.patch new file mode 100644 index 0000000..e3e8236 --- /dev/null +++ b/SOURCES/0004-Ticket-48212-CI-test-added-test-cases-for-ticket-482.patch @@ -0,0 +1,17261 @@ +From b9de59847038d4baecacfb911c21798f78e3c52a Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 1 Jul 2015 18:23:22 -0700 +Subject: [PATCH 4/7] Ticket #48212 - CI test: added test cases for ticket + 48212 + +Description: Dynamic nsMatchingRule changes had no effect on the attrinfo + thus following reindexing, as well. + +https://fedorahosted.org/389/ticket/48212 +(cherry picked from commit a533145d1dc3c11bb0aa7745f656049b287e501e) +(cherry picked from commit 0e079ab39f7ee3d5fe77b505fb40c647d149f1b0) +--- + dirsrvtests/data/ticket48212/example1k_posix.ldif | 17017 ++++++++++++++++++++ + dirsrvtests/tickets/ticket48212_test.py | 210 + + 2 files changed, 17227 insertions(+) + create mode 100644 dirsrvtests/data/ticket48212/example1k_posix.ldif + create mode 100644 dirsrvtests/tickets/ticket48212_test.py + +diff --git a/dirsrvtests/data/ticket48212/example1k_posix.ldif b/dirsrvtests/data/ticket48212/example1k_posix.ldif +new file mode 100644 +index 0000000..50000f2 +--- /dev/null ++++ b/dirsrvtests/data/ticket48212/example1k_posix.ldif +@@ -0,0 +1,17017 @@ ++dn: dc=example,dc=com ++objectClass: top ++objectClass: domain ++dc: example ++aci: (target=ldap:///dc=example,dc=com)(targetattr=*)(version 3.0; acl "acl1"; allow(write) userdn = "ldap:///self";) ++aci: (target=ldap:///dc=example,dc=com)(targetattr=*)(version 3.0; acl "acl2"; allow(read, search, compare) userdn = "ldap:///anyone";) ++ ++dn: ou=People,dc=example,dc=com ++objectClass: top ++objectClass: organizationalunit ++ou: People ++ ++dn: ou=Groups,dc=example,dc=com ++objectClass: top ++objectClass: organizationalunit ++ou: Groups ++ ++dn: cn=user0,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user0 ++sn: user0 ++uid: uid0 ++givenname: givenname0 ++description: description0 ++userPassword: password0 ++mail: uid0 ++uidnumber: 0 ++gidnumber: 0 ++homeDirectory: /home/uid0 ++ ++dn: cn=user1,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user1 ++sn: user1 ++uid: uid1 ++givenname: givenname1 ++description: description1 ++userPassword: password1 ++mail: uid1 ++uidnumber: 1 ++gidnumber: 1 ++homeDirectory: /home/uid1 ++ ++dn: cn=user2,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user2 ++sn: user2 ++uid: uid2 ++givenname: givenname2 ++description: description2 ++userPassword: password2 ++mail: uid2 ++uidnumber: 2 ++gidnumber: 2 ++homeDirectory: /home/uid2 ++ ++dn: cn=user3,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user3 ++sn: user3 ++uid: uid3 ++givenname: givenname3 ++description: description3 ++userPassword: password3 ++mail: uid3 ++uidnumber: 3 ++gidnumber: 3 ++homeDirectory: /home/uid3 ++ ++dn: cn=user4,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user4 ++sn: user4 ++uid: uid4 ++givenname: givenname4 ++description: description4 ++userPassword: password4 ++mail: uid4 ++uidnumber: 4 ++gidnumber: 4 ++homeDirectory: /home/uid4 ++ ++dn: cn=user5,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user5 ++sn: user5 ++uid: uid5 ++givenname: givenname5 ++description: description5 ++userPassword: password5 ++mail: uid5 ++uidnumber: 5 ++gidnumber: 5 ++homeDirectory: /home/uid5 ++ ++dn: cn=user6,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user6 ++sn: user6 ++uid: uid6 ++givenname: givenname6 ++description: description6 ++userPassword: password6 ++mail: uid6 ++uidnumber: 6 ++gidnumber: 6 ++homeDirectory: /home/uid6 ++ ++dn: cn=user7,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user7 ++sn: user7 ++uid: uid7 ++givenname: givenname7 ++description: description7 ++userPassword: password7 ++mail: uid7 ++uidnumber: 7 ++gidnumber: 7 ++homeDirectory: /home/uid7 ++ ++dn: cn=user8,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user8 ++sn: user8 ++uid: uid8 ++givenname: givenname8 ++description: description8 ++userPassword: password8 ++mail: uid8 ++uidnumber: 8 ++gidnumber: 8 ++homeDirectory: /home/uid8 ++ ++dn: cn=user9,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user9 ++sn: user9 ++uid: uid9 ++givenname: givenname9 ++description: description9 ++userPassword: password9 ++mail: uid9 ++uidnumber: 9 ++gidnumber: 9 ++homeDirectory: /home/uid9 ++ ++dn: cn=user10,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user10 ++sn: user10 ++uid: uid10 ++givenname: givenname10 ++description: description10 ++userPassword: password10 ++mail: uid10 ++uidnumber: 10 ++gidnumber: 10 ++homeDirectory: /home/uid10 ++ ++dn: cn=user11,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user11 ++sn: user11 ++uid: uid11 ++givenname: givenname11 ++description: description11 ++userPassword: password11 ++mail: uid11 ++uidnumber: 11 ++gidnumber: 11 ++homeDirectory: /home/uid11 ++ ++dn: cn=user12,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user12 ++sn: user12 ++uid: uid12 ++givenname: givenname12 ++description: description12 ++userPassword: password12 ++mail: uid12 ++uidnumber: 12 ++gidnumber: 12 ++homeDirectory: /home/uid12 ++ ++dn: cn=user13,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user13 ++sn: user13 ++uid: uid13 ++givenname: givenname13 ++description: description13 ++userPassword: password13 ++mail: uid13 ++uidnumber: 13 ++gidnumber: 13 ++homeDirectory: /home/uid13 ++ ++dn: cn=user14,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user14 ++sn: user14 ++uid: uid14 ++givenname: givenname14 ++description: description14 ++userPassword: password14 ++mail: uid14 ++uidnumber: 14 ++gidnumber: 14 ++homeDirectory: /home/uid14 ++ ++dn: cn=user15,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user15 ++sn: user15 ++uid: uid15 ++givenname: givenname15 ++description: description15 ++userPassword: password15 ++mail: uid15 ++uidnumber: 15 ++gidnumber: 15 ++homeDirectory: /home/uid15 ++ ++dn: cn=user16,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user16 ++sn: user16 ++uid: uid16 ++givenname: givenname16 ++description: description16 ++userPassword: password16 ++mail: uid16 ++uidnumber: 16 ++gidnumber: 16 ++homeDirectory: /home/uid16 ++ ++dn: cn=user17,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user17 ++sn: user17 ++uid: uid17 ++givenname: givenname17 ++description: description17 ++userPassword: password17 ++mail: uid17 ++uidnumber: 17 ++gidnumber: 17 ++homeDirectory: /home/uid17 ++ ++dn: cn=user18,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user18 ++sn: user18 ++uid: uid18 ++givenname: givenname18 ++description: description18 ++userPassword: password18 ++mail: uid18 ++uidnumber: 18 ++gidnumber: 18 ++homeDirectory: /home/uid18 ++ ++dn: cn=user19,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user19 ++sn: user19 ++uid: uid19 ++givenname: givenname19 ++description: description19 ++userPassword: password19 ++mail: uid19 ++uidnumber: 19 ++gidnumber: 19 ++homeDirectory: /home/uid19 ++ ++dn: cn=user20,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user20 ++sn: user20 ++uid: uid20 ++givenname: givenname20 ++description: description20 ++userPassword: password20 ++mail: uid20 ++uidnumber: 20 ++gidnumber: 20 ++homeDirectory: /home/uid20 ++ ++dn: cn=user21,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user21 ++sn: user21 ++uid: uid21 ++givenname: givenname21 ++description: description21 ++userPassword: password21 ++mail: uid21 ++uidnumber: 21 ++gidnumber: 21 ++homeDirectory: /home/uid21 ++ ++dn: cn=user22,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user22 ++sn: user22 ++uid: uid22 ++givenname: givenname22 ++description: description22 ++userPassword: password22 ++mail: uid22 ++uidnumber: 22 ++gidnumber: 22 ++homeDirectory: /home/uid22 ++ ++dn: cn=user23,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user23 ++sn: user23 ++uid: uid23 ++givenname: givenname23 ++description: description23 ++userPassword: password23 ++mail: uid23 ++uidnumber: 23 ++gidnumber: 23 ++homeDirectory: /home/uid23 ++ ++dn: cn=user24,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user24 ++sn: user24 ++uid: uid24 ++givenname: givenname24 ++description: description24 ++userPassword: password24 ++mail: uid24 ++uidnumber: 24 ++gidnumber: 24 ++homeDirectory: /home/uid24 ++ ++dn: cn=user25,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user25 ++sn: user25 ++uid: uid25 ++givenname: givenname25 ++description: description25 ++userPassword: password25 ++mail: uid25 ++uidnumber: 25 ++gidnumber: 25 ++homeDirectory: /home/uid25 ++ ++dn: cn=user26,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user26 ++sn: user26 ++uid: uid26 ++givenname: givenname26 ++description: description26 ++userPassword: password26 ++mail: uid26 ++uidnumber: 26 ++gidnumber: 26 ++homeDirectory: /home/uid26 ++ ++dn: cn=user27,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user27 ++sn: user27 ++uid: uid27 ++givenname: givenname27 ++description: description27 ++userPassword: password27 ++mail: uid27 ++uidnumber: 27 ++gidnumber: 27 ++homeDirectory: /home/uid27 ++ ++dn: cn=user28,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user28 ++sn: user28 ++uid: uid28 ++givenname: givenname28 ++description: description28 ++userPassword: password28 ++mail: uid28 ++uidnumber: 28 ++gidnumber: 28 ++homeDirectory: /home/uid28 ++ ++dn: cn=user29,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user29 ++sn: user29 ++uid: uid29 ++givenname: givenname29 ++description: description29 ++userPassword: password29 ++mail: uid29 ++uidnumber: 29 ++gidnumber: 29 ++homeDirectory: /home/uid29 ++ ++dn: cn=user30,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user30 ++sn: user30 ++uid: uid30 ++givenname: givenname30 ++description: description30 ++userPassword: password30 ++mail: uid30 ++uidnumber: 30 ++gidnumber: 30 ++homeDirectory: /home/uid30 ++ ++dn: cn=user31,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user31 ++sn: user31 ++uid: uid31 ++givenname: givenname31 ++description: description31 ++userPassword: password31 ++mail: uid31 ++uidnumber: 31 ++gidnumber: 31 ++homeDirectory: /home/uid31 ++ ++dn: cn=user32,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user32 ++sn: user32 ++uid: uid32 ++givenname: givenname32 ++description: description32 ++userPassword: password32 ++mail: uid32 ++uidnumber: 32 ++gidnumber: 32 ++homeDirectory: /home/uid32 ++ ++dn: cn=user33,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user33 ++sn: user33 ++uid: uid33 ++givenname: givenname33 ++description: description33 ++userPassword: password33 ++mail: uid33 ++uidnumber: 33 ++gidnumber: 33 ++homeDirectory: /home/uid33 ++ ++dn: cn=user34,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user34 ++sn: user34 ++uid: uid34 ++givenname: givenname34 ++description: description34 ++userPassword: password34 ++mail: uid34 ++uidnumber: 34 ++gidnumber: 34 ++homeDirectory: /home/uid34 ++ ++dn: cn=user35,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user35 ++sn: user35 ++uid: uid35 ++givenname: givenname35 ++description: description35 ++userPassword: password35 ++mail: uid35 ++uidnumber: 35 ++gidnumber: 35 ++homeDirectory: /home/uid35 ++ ++dn: cn=user36,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user36 ++sn: user36 ++uid: uid36 ++givenname: givenname36 ++description: description36 ++userPassword: password36 ++mail: uid36 ++uidnumber: 36 ++gidnumber: 36 ++homeDirectory: /home/uid36 ++ ++dn: cn=user37,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user37 ++sn: user37 ++uid: uid37 ++givenname: givenname37 ++description: description37 ++userPassword: password37 ++mail: uid37 ++uidnumber: 37 ++gidnumber: 37 ++homeDirectory: /home/uid37 ++ ++dn: cn=user38,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user38 ++sn: user38 ++uid: uid38 ++givenname: givenname38 ++description: description38 ++userPassword: password38 ++mail: uid38 ++uidnumber: 38 ++gidnumber: 38 ++homeDirectory: /home/uid38 ++ ++dn: cn=user39,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user39 ++sn: user39 ++uid: uid39 ++givenname: givenname39 ++description: description39 ++userPassword: password39 ++mail: uid39 ++uidnumber: 39 ++gidnumber: 39 ++homeDirectory: /home/uid39 ++ ++dn: cn=user40,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user40 ++sn: user40 ++uid: uid40 ++givenname: givenname40 ++description: description40 ++userPassword: password40 ++mail: uid40 ++uidnumber: 40 ++gidnumber: 40 ++homeDirectory: /home/uid40 ++ ++dn: cn=user41,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user41 ++sn: user41 ++uid: uid41 ++givenname: givenname41 ++description: description41 ++userPassword: password41 ++mail: uid41 ++uidnumber: 41 ++gidnumber: 41 ++homeDirectory: /home/uid41 ++ ++dn: cn=user42,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user42 ++sn: user42 ++uid: uid42 ++givenname: givenname42 ++description: description42 ++userPassword: password42 ++mail: uid42 ++uidnumber: 42 ++gidnumber: 42 ++homeDirectory: /home/uid42 ++ ++dn: cn=user43,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user43 ++sn: user43 ++uid: uid43 ++givenname: givenname43 ++description: description43 ++userPassword: password43 ++mail: uid43 ++uidnumber: 43 ++gidnumber: 43 ++homeDirectory: /home/uid43 ++ ++dn: cn=user44,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user44 ++sn: user44 ++uid: uid44 ++givenname: givenname44 ++description: description44 ++userPassword: password44 ++mail: uid44 ++uidnumber: 44 ++gidnumber: 44 ++homeDirectory: /home/uid44 ++ ++dn: cn=user45,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user45 ++sn: user45 ++uid: uid45 ++givenname: givenname45 ++description: description45 ++userPassword: password45 ++mail: uid45 ++uidnumber: 45 ++gidnumber: 45 ++homeDirectory: /home/uid45 ++ ++dn: cn=user46,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user46 ++sn: user46 ++uid: uid46 ++givenname: givenname46 ++description: description46 ++userPassword: password46 ++mail: uid46 ++uidnumber: 46 ++gidnumber: 46 ++homeDirectory: /home/uid46 ++ ++dn: cn=user47,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user47 ++sn: user47 ++uid: uid47 ++givenname: givenname47 ++description: description47 ++userPassword: password47 ++mail: uid47 ++uidnumber: 47 ++gidnumber: 47 ++homeDirectory: /home/uid47 ++ ++dn: cn=user48,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user48 ++sn: user48 ++uid: uid48 ++givenname: givenname48 ++description: description48 ++userPassword: password48 ++mail: uid48 ++uidnumber: 48 ++gidnumber: 48 ++homeDirectory: /home/uid48 ++ ++dn: cn=user49,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user49 ++sn: user49 ++uid: uid49 ++givenname: givenname49 ++description: description49 ++userPassword: password49 ++mail: uid49 ++uidnumber: 49 ++gidnumber: 49 ++homeDirectory: /home/uid49 ++ ++dn: cn=user50,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user50 ++sn: user50 ++uid: uid50 ++givenname: givenname50 ++description: description50 ++userPassword: password50 ++mail: uid50 ++uidnumber: 50 ++gidnumber: 50 ++homeDirectory: /home/uid50 ++ ++dn: cn=user51,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user51 ++sn: user51 ++uid: uid51 ++givenname: givenname51 ++description: description51 ++userPassword: password51 ++mail: uid51 ++uidnumber: 51 ++gidnumber: 51 ++homeDirectory: /home/uid51 ++ ++dn: cn=user52,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user52 ++sn: user52 ++uid: uid52 ++givenname: givenname52 ++description: description52 ++userPassword: password52 ++mail: uid52 ++uidnumber: 52 ++gidnumber: 52 ++homeDirectory: /home/uid52 ++ ++dn: cn=user53,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user53 ++sn: user53 ++uid: uid53 ++givenname: givenname53 ++description: description53 ++userPassword: password53 ++mail: uid53 ++uidnumber: 53 ++gidnumber: 53 ++homeDirectory: /home/uid53 ++ ++dn: cn=user54,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user54 ++sn: user54 ++uid: uid54 ++givenname: givenname54 ++description: description54 ++userPassword: password54 ++mail: uid54 ++uidnumber: 54 ++gidnumber: 54 ++homeDirectory: /home/uid54 ++ ++dn: cn=user55,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user55 ++sn: user55 ++uid: uid55 ++givenname: givenname55 ++description: description55 ++userPassword: password55 ++mail: uid55 ++uidnumber: 55 ++gidnumber: 55 ++homeDirectory: /home/uid55 ++ ++dn: cn=user56,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user56 ++sn: user56 ++uid: uid56 ++givenname: givenname56 ++description: description56 ++userPassword: password56 ++mail: uid56 ++uidnumber: 56 ++gidnumber: 56 ++homeDirectory: /home/uid56 ++ ++dn: cn=user57,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user57 ++sn: user57 ++uid: uid57 ++givenname: givenname57 ++description: description57 ++userPassword: password57 ++mail: uid57 ++uidnumber: 57 ++gidnumber: 57 ++homeDirectory: /home/uid57 ++ ++dn: cn=user58,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user58 ++sn: user58 ++uid: uid58 ++givenname: givenname58 ++description: description58 ++userPassword: password58 ++mail: uid58 ++uidnumber: 58 ++gidnumber: 58 ++homeDirectory: /home/uid58 ++ ++dn: cn=user59,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user59 ++sn: user59 ++uid: uid59 ++givenname: givenname59 ++description: description59 ++userPassword: password59 ++mail: uid59 ++uidnumber: 59 ++gidnumber: 59 ++homeDirectory: /home/uid59 ++ ++dn: cn=user60,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user60 ++sn: user60 ++uid: uid60 ++givenname: givenname60 ++description: description60 ++userPassword: password60 ++mail: uid60 ++uidnumber: 60 ++gidnumber: 60 ++homeDirectory: /home/uid60 ++ ++dn: cn=user61,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user61 ++sn: user61 ++uid: uid61 ++givenname: givenname61 ++description: description61 ++userPassword: password61 ++mail: uid61 ++uidnumber: 61 ++gidnumber: 61 ++homeDirectory: /home/uid61 ++ ++dn: cn=user62,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user62 ++sn: user62 ++uid: uid62 ++givenname: givenname62 ++description: description62 ++userPassword: password62 ++mail: uid62 ++uidnumber: 62 ++gidnumber: 62 ++homeDirectory: /home/uid62 ++ ++dn: cn=user63,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user63 ++sn: user63 ++uid: uid63 ++givenname: givenname63 ++description: description63 ++userPassword: password63 ++mail: uid63 ++uidnumber: 63 ++gidnumber: 63 ++homeDirectory: /home/uid63 ++ ++dn: cn=user64,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user64 ++sn: user64 ++uid: uid64 ++givenname: givenname64 ++description: description64 ++userPassword: password64 ++mail: uid64 ++uidnumber: 64 ++gidnumber: 64 ++homeDirectory: /home/uid64 ++ ++dn: cn=user65,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user65 ++sn: user65 ++uid: uid65 ++givenname: givenname65 ++description: description65 ++userPassword: password65 ++mail: uid65 ++uidnumber: 65 ++gidnumber: 65 ++homeDirectory: /home/uid65 ++ ++dn: cn=user66,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user66 ++sn: user66 ++uid: uid66 ++givenname: givenname66 ++description: description66 ++userPassword: password66 ++mail: uid66 ++uidnumber: 66 ++gidnumber: 66 ++homeDirectory: /home/uid66 ++ ++dn: cn=user67,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user67 ++sn: user67 ++uid: uid67 ++givenname: givenname67 ++description: description67 ++userPassword: password67 ++mail: uid67 ++uidnumber: 67 ++gidnumber: 67 ++homeDirectory: /home/uid67 ++ ++dn: cn=user68,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user68 ++sn: user68 ++uid: uid68 ++givenname: givenname68 ++description: description68 ++userPassword: password68 ++mail: uid68 ++uidnumber: 68 ++gidnumber: 68 ++homeDirectory: /home/uid68 ++ ++dn: cn=user69,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user69 ++sn: user69 ++uid: uid69 ++givenname: givenname69 ++description: description69 ++userPassword: password69 ++mail: uid69 ++uidnumber: 69 ++gidnumber: 69 ++homeDirectory: /home/uid69 ++ ++dn: cn=user70,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user70 ++sn: user70 ++uid: uid70 ++givenname: givenname70 ++description: description70 ++userPassword: password70 ++mail: uid70 ++uidnumber: 70 ++gidnumber: 70 ++homeDirectory: /home/uid70 ++ ++dn: cn=user71,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user71 ++sn: user71 ++uid: uid71 ++givenname: givenname71 ++description: description71 ++userPassword: password71 ++mail: uid71 ++uidnumber: 71 ++gidnumber: 71 ++homeDirectory: /home/uid71 ++ ++dn: cn=user72,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user72 ++sn: user72 ++uid: uid72 ++givenname: givenname72 ++description: description72 ++userPassword: password72 ++mail: uid72 ++uidnumber: 72 ++gidnumber: 72 ++homeDirectory: /home/uid72 ++ ++dn: cn=user73,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user73 ++sn: user73 ++uid: uid73 ++givenname: givenname73 ++description: description73 ++userPassword: password73 ++mail: uid73 ++uidnumber: 73 ++gidnumber: 73 ++homeDirectory: /home/uid73 ++ ++dn: cn=user74,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user74 ++sn: user74 ++uid: uid74 ++givenname: givenname74 ++description: description74 ++userPassword: password74 ++mail: uid74 ++uidnumber: 74 ++gidnumber: 74 ++homeDirectory: /home/uid74 ++ ++dn: cn=user75,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user75 ++sn: user75 ++uid: uid75 ++givenname: givenname75 ++description: description75 ++userPassword: password75 ++mail: uid75 ++uidnumber: 75 ++gidnumber: 75 ++homeDirectory: /home/uid75 ++ ++dn: cn=user76,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user76 ++sn: user76 ++uid: uid76 ++givenname: givenname76 ++description: description76 ++userPassword: password76 ++mail: uid76 ++uidnumber: 76 ++gidnumber: 76 ++homeDirectory: /home/uid76 ++ ++dn: cn=user77,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user77 ++sn: user77 ++uid: uid77 ++givenname: givenname77 ++description: description77 ++userPassword: password77 ++mail: uid77 ++uidnumber: 77 ++gidnumber: 77 ++homeDirectory: /home/uid77 ++ ++dn: cn=user78,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user78 ++sn: user78 ++uid: uid78 ++givenname: givenname78 ++description: description78 ++userPassword: password78 ++mail: uid78 ++uidnumber: 78 ++gidnumber: 78 ++homeDirectory: /home/uid78 ++ ++dn: cn=user79,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user79 ++sn: user79 ++uid: uid79 ++givenname: givenname79 ++description: description79 ++userPassword: password79 ++mail: uid79 ++uidnumber: 79 ++gidnumber: 79 ++homeDirectory: /home/uid79 ++ ++dn: cn=user80,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user80 ++sn: user80 ++uid: uid80 ++givenname: givenname80 ++description: description80 ++userPassword: password80 ++mail: uid80 ++uidnumber: 80 ++gidnumber: 80 ++homeDirectory: /home/uid80 ++ ++dn: cn=user81,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user81 ++sn: user81 ++uid: uid81 ++givenname: givenname81 ++description: description81 ++userPassword: password81 ++mail: uid81 ++uidnumber: 81 ++gidnumber: 81 ++homeDirectory: /home/uid81 ++ ++dn: cn=user82,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user82 ++sn: user82 ++uid: uid82 ++givenname: givenname82 ++description: description82 ++userPassword: password82 ++mail: uid82 ++uidnumber: 82 ++gidnumber: 82 ++homeDirectory: /home/uid82 ++ ++dn: cn=user83,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user83 ++sn: user83 ++uid: uid83 ++givenname: givenname83 ++description: description83 ++userPassword: password83 ++mail: uid83 ++uidnumber: 83 ++gidnumber: 83 ++homeDirectory: /home/uid83 ++ ++dn: cn=user84,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user84 ++sn: user84 ++uid: uid84 ++givenname: givenname84 ++description: description84 ++userPassword: password84 ++mail: uid84 ++uidnumber: 84 ++gidnumber: 84 ++homeDirectory: /home/uid84 ++ ++dn: cn=user85,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user85 ++sn: user85 ++uid: uid85 ++givenname: givenname85 ++description: description85 ++userPassword: password85 ++mail: uid85 ++uidnumber: 85 ++gidnumber: 85 ++homeDirectory: /home/uid85 ++ ++dn: cn=user86,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user86 ++sn: user86 ++uid: uid86 ++givenname: givenname86 ++description: description86 ++userPassword: password86 ++mail: uid86 ++uidnumber: 86 ++gidnumber: 86 ++homeDirectory: /home/uid86 ++ ++dn: cn=user87,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user87 ++sn: user87 ++uid: uid87 ++givenname: givenname87 ++description: description87 ++userPassword: password87 ++mail: uid87 ++uidnumber: 87 ++gidnumber: 87 ++homeDirectory: /home/uid87 ++ ++dn: cn=user88,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user88 ++sn: user88 ++uid: uid88 ++givenname: givenname88 ++description: description88 ++userPassword: password88 ++mail: uid88 ++uidnumber: 88 ++gidnumber: 88 ++homeDirectory: /home/uid88 ++ ++dn: cn=user89,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user89 ++sn: user89 ++uid: uid89 ++givenname: givenname89 ++description: description89 ++userPassword: password89 ++mail: uid89 ++uidnumber: 89 ++gidnumber: 89 ++homeDirectory: /home/uid89 ++ ++dn: cn=user90,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user90 ++sn: user90 ++uid: uid90 ++givenname: givenname90 ++description: description90 ++userPassword: password90 ++mail: uid90 ++uidnumber: 90 ++gidnumber: 90 ++homeDirectory: /home/uid90 ++ ++dn: cn=user91,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user91 ++sn: user91 ++uid: uid91 ++givenname: givenname91 ++description: description91 ++userPassword: password91 ++mail: uid91 ++uidnumber: 91 ++gidnumber: 91 ++homeDirectory: /home/uid91 ++ ++dn: cn=user92,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user92 ++sn: user92 ++uid: uid92 ++givenname: givenname92 ++description: description92 ++userPassword: password92 ++mail: uid92 ++uidnumber: 92 ++gidnumber: 92 ++homeDirectory: /home/uid92 ++ ++dn: cn=user93,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user93 ++sn: user93 ++uid: uid93 ++givenname: givenname93 ++description: description93 ++userPassword: password93 ++mail: uid93 ++uidnumber: 93 ++gidnumber: 93 ++homeDirectory: /home/uid93 ++ ++dn: cn=user94,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user94 ++sn: user94 ++uid: uid94 ++givenname: givenname94 ++description: description94 ++userPassword: password94 ++mail: uid94 ++uidnumber: 94 ++gidnumber: 94 ++homeDirectory: /home/uid94 ++ ++dn: cn=user95,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user95 ++sn: user95 ++uid: uid95 ++givenname: givenname95 ++description: description95 ++userPassword: password95 ++mail: uid95 ++uidnumber: 95 ++gidnumber: 95 ++homeDirectory: /home/uid95 ++ ++dn: cn=user96,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user96 ++sn: user96 ++uid: uid96 ++givenname: givenname96 ++description: description96 ++userPassword: password96 ++mail: uid96 ++uidnumber: 96 ++gidnumber: 96 ++homeDirectory: /home/uid96 ++ ++dn: cn=user97,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user97 ++sn: user97 ++uid: uid97 ++givenname: givenname97 ++description: description97 ++userPassword: password97 ++mail: uid97 ++uidnumber: 97 ++gidnumber: 97 ++homeDirectory: /home/uid97 ++ ++dn: cn=user98,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user98 ++sn: user98 ++uid: uid98 ++givenname: givenname98 ++description: description98 ++userPassword: password98 ++mail: uid98 ++uidnumber: 98 ++gidnumber: 98 ++homeDirectory: /home/uid98 ++ ++dn: cn=user99,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user99 ++sn: user99 ++uid: uid99 ++givenname: givenname99 ++description: description99 ++userPassword: password99 ++mail: uid99 ++uidnumber: 99 ++gidnumber: 99 ++homeDirectory: /home/uid99 ++ ++dn: cn=user100,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user100 ++sn: user100 ++uid: uid100 ++givenname: givenname100 ++description: description100 ++userPassword: password100 ++mail: uid100 ++uidnumber: 100 ++gidnumber: 100 ++homeDirectory: /home/uid100 ++ ++dn: cn=user101,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user101 ++sn: user101 ++uid: uid101 ++givenname: givenname101 ++description: description101 ++userPassword: password101 ++mail: uid101 ++uidnumber: 101 ++gidnumber: 101 ++homeDirectory: /home/uid101 ++ ++dn: cn=user102,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user102 ++sn: user102 ++uid: uid102 ++givenname: givenname102 ++description: description102 ++userPassword: password102 ++mail: uid102 ++uidnumber: 102 ++gidnumber: 102 ++homeDirectory: /home/uid102 ++ ++dn: cn=user103,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user103 ++sn: user103 ++uid: uid103 ++givenname: givenname103 ++description: description103 ++userPassword: password103 ++mail: uid103 ++uidnumber: 103 ++gidnumber: 103 ++homeDirectory: /home/uid103 ++ ++dn: cn=user104,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user104 ++sn: user104 ++uid: uid104 ++givenname: givenname104 ++description: description104 ++userPassword: password104 ++mail: uid104 ++uidnumber: 104 ++gidnumber: 104 ++homeDirectory: /home/uid104 ++ ++dn: cn=user105,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user105 ++sn: user105 ++uid: uid105 ++givenname: givenname105 ++description: description105 ++userPassword: password105 ++mail: uid105 ++uidnumber: 105 ++gidnumber: 105 ++homeDirectory: /home/uid105 ++ ++dn: cn=user106,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user106 ++sn: user106 ++uid: uid106 ++givenname: givenname106 ++description: description106 ++userPassword: password106 ++mail: uid106 ++uidnumber: 106 ++gidnumber: 106 ++homeDirectory: /home/uid106 ++ ++dn: cn=user107,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user107 ++sn: user107 ++uid: uid107 ++givenname: givenname107 ++description: description107 ++userPassword: password107 ++mail: uid107 ++uidnumber: 107 ++gidnumber: 107 ++homeDirectory: /home/uid107 ++ ++dn: cn=user108,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user108 ++sn: user108 ++uid: uid108 ++givenname: givenname108 ++description: description108 ++userPassword: password108 ++mail: uid108 ++uidnumber: 108 ++gidnumber: 108 ++homeDirectory: /home/uid108 ++ ++dn: cn=user109,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user109 ++sn: user109 ++uid: uid109 ++givenname: givenname109 ++description: description109 ++userPassword: password109 ++mail: uid109 ++uidnumber: 109 ++gidnumber: 109 ++homeDirectory: /home/uid109 ++ ++dn: cn=user110,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user110 ++sn: user110 ++uid: uid110 ++givenname: givenname110 ++description: description110 ++userPassword: password110 ++mail: uid110 ++uidnumber: 110 ++gidnumber: 110 ++homeDirectory: /home/uid110 ++ ++dn: cn=user111,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user111 ++sn: user111 ++uid: uid111 ++givenname: givenname111 ++description: description111 ++userPassword: password111 ++mail: uid111 ++uidnumber: 111 ++gidnumber: 111 ++homeDirectory: /home/uid111 ++ ++dn: cn=user112,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user112 ++sn: user112 ++uid: uid112 ++givenname: givenname112 ++description: description112 ++userPassword: password112 ++mail: uid112 ++uidnumber: 112 ++gidnumber: 112 ++homeDirectory: /home/uid112 ++ ++dn: cn=user113,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user113 ++sn: user113 ++uid: uid113 ++givenname: givenname113 ++description: description113 ++userPassword: password113 ++mail: uid113 ++uidnumber: 113 ++gidnumber: 113 ++homeDirectory: /home/uid113 ++ ++dn: cn=user114,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user114 ++sn: user114 ++uid: uid114 ++givenname: givenname114 ++description: description114 ++userPassword: password114 ++mail: uid114 ++uidnumber: 114 ++gidnumber: 114 ++homeDirectory: /home/uid114 ++ ++dn: cn=user115,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user115 ++sn: user115 ++uid: uid115 ++givenname: givenname115 ++description: description115 ++userPassword: password115 ++mail: uid115 ++uidnumber: 115 ++gidnumber: 115 ++homeDirectory: /home/uid115 ++ ++dn: cn=user116,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user116 ++sn: user116 ++uid: uid116 ++givenname: givenname116 ++description: description116 ++userPassword: password116 ++mail: uid116 ++uidnumber: 116 ++gidnumber: 116 ++homeDirectory: /home/uid116 ++ ++dn: cn=user117,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user117 ++sn: user117 ++uid: uid117 ++givenname: givenname117 ++description: description117 ++userPassword: password117 ++mail: uid117 ++uidnumber: 117 ++gidnumber: 117 ++homeDirectory: /home/uid117 ++ ++dn: cn=user118,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user118 ++sn: user118 ++uid: uid118 ++givenname: givenname118 ++description: description118 ++userPassword: password118 ++mail: uid118 ++uidnumber: 118 ++gidnumber: 118 ++homeDirectory: /home/uid118 ++ ++dn: cn=user119,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user119 ++sn: user119 ++uid: uid119 ++givenname: givenname119 ++description: description119 ++userPassword: password119 ++mail: uid119 ++uidnumber: 119 ++gidnumber: 119 ++homeDirectory: /home/uid119 ++ ++dn: cn=user120,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user120 ++sn: user120 ++uid: uid120 ++givenname: givenname120 ++description: description120 ++userPassword: password120 ++mail: uid120 ++uidnumber: 120 ++gidnumber: 120 ++homeDirectory: /home/uid120 ++ ++dn: cn=user121,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user121 ++sn: user121 ++uid: uid121 ++givenname: givenname121 ++description: description121 ++userPassword: password121 ++mail: uid121 ++uidnumber: 121 ++gidnumber: 121 ++homeDirectory: /home/uid121 ++ ++dn: cn=user122,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user122 ++sn: user122 ++uid: uid122 ++givenname: givenname122 ++description: description122 ++userPassword: password122 ++mail: uid122 ++uidnumber: 122 ++gidnumber: 122 ++homeDirectory: /home/uid122 ++ ++dn: cn=user123,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user123 ++sn: user123 ++uid: uid123 ++givenname: givenname123 ++description: description123 ++userPassword: password123 ++mail: uid123 ++uidnumber: 123 ++gidnumber: 123 ++homeDirectory: /home/uid123 ++ ++dn: cn=user124,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user124 ++sn: user124 ++uid: uid124 ++givenname: givenname124 ++description: description124 ++userPassword: password124 ++mail: uid124 ++uidnumber: 124 ++gidnumber: 124 ++homeDirectory: /home/uid124 ++ ++dn: cn=user125,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user125 ++sn: user125 ++uid: uid125 ++givenname: givenname125 ++description: description125 ++userPassword: password125 ++mail: uid125 ++uidnumber: 125 ++gidnumber: 125 ++homeDirectory: /home/uid125 ++ ++dn: cn=user126,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user126 ++sn: user126 ++uid: uid126 ++givenname: givenname126 ++description: description126 ++userPassword: password126 ++mail: uid126 ++uidnumber: 126 ++gidnumber: 126 ++homeDirectory: /home/uid126 ++ ++dn: cn=user127,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user127 ++sn: user127 ++uid: uid127 ++givenname: givenname127 ++description: description127 ++userPassword: password127 ++mail: uid127 ++uidnumber: 127 ++gidnumber: 127 ++homeDirectory: /home/uid127 ++ ++dn: cn=user128,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user128 ++sn: user128 ++uid: uid128 ++givenname: givenname128 ++description: description128 ++userPassword: password128 ++mail: uid128 ++uidnumber: 128 ++gidnumber: 128 ++homeDirectory: /home/uid128 ++ ++dn: cn=user129,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user129 ++sn: user129 ++uid: uid129 ++givenname: givenname129 ++description: description129 ++userPassword: password129 ++mail: uid129 ++uidnumber: 129 ++gidnumber: 129 ++homeDirectory: /home/uid129 ++ ++dn: cn=user130,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user130 ++sn: user130 ++uid: uid130 ++givenname: givenname130 ++description: description130 ++userPassword: password130 ++mail: uid130 ++uidnumber: 130 ++gidnumber: 130 ++homeDirectory: /home/uid130 ++ ++dn: cn=user131,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user131 ++sn: user131 ++uid: uid131 ++givenname: givenname131 ++description: description131 ++userPassword: password131 ++mail: uid131 ++uidnumber: 131 ++gidnumber: 131 ++homeDirectory: /home/uid131 ++ ++dn: cn=user132,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user132 ++sn: user132 ++uid: uid132 ++givenname: givenname132 ++description: description132 ++userPassword: password132 ++mail: uid132 ++uidnumber: 132 ++gidnumber: 132 ++homeDirectory: /home/uid132 ++ ++dn: cn=user133,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user133 ++sn: user133 ++uid: uid133 ++givenname: givenname133 ++description: description133 ++userPassword: password133 ++mail: uid133 ++uidnumber: 133 ++gidnumber: 133 ++homeDirectory: /home/uid133 ++ ++dn: cn=user134,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user134 ++sn: user134 ++uid: uid134 ++givenname: givenname134 ++description: description134 ++userPassword: password134 ++mail: uid134 ++uidnumber: 134 ++gidnumber: 134 ++homeDirectory: /home/uid134 ++ ++dn: cn=user135,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user135 ++sn: user135 ++uid: uid135 ++givenname: givenname135 ++description: description135 ++userPassword: password135 ++mail: uid135 ++uidnumber: 135 ++gidnumber: 135 ++homeDirectory: /home/uid135 ++ ++dn: cn=user136,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user136 ++sn: user136 ++uid: uid136 ++givenname: givenname136 ++description: description136 ++userPassword: password136 ++mail: uid136 ++uidnumber: 136 ++gidnumber: 136 ++homeDirectory: /home/uid136 ++ ++dn: cn=user137,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user137 ++sn: user137 ++uid: uid137 ++givenname: givenname137 ++description: description137 ++userPassword: password137 ++mail: uid137 ++uidnumber: 137 ++gidnumber: 137 ++homeDirectory: /home/uid137 ++ ++dn: cn=user138,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user138 ++sn: user138 ++uid: uid138 ++givenname: givenname138 ++description: description138 ++userPassword: password138 ++mail: uid138 ++uidnumber: 138 ++gidnumber: 138 ++homeDirectory: /home/uid138 ++ ++dn: cn=user139,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user139 ++sn: user139 ++uid: uid139 ++givenname: givenname139 ++description: description139 ++userPassword: password139 ++mail: uid139 ++uidnumber: 139 ++gidnumber: 139 ++homeDirectory: /home/uid139 ++ ++dn: cn=user140,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user140 ++sn: user140 ++uid: uid140 ++givenname: givenname140 ++description: description140 ++userPassword: password140 ++mail: uid140 ++uidnumber: 140 ++gidnumber: 140 ++homeDirectory: /home/uid140 ++ ++dn: cn=user141,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user141 ++sn: user141 ++uid: uid141 ++givenname: givenname141 ++description: description141 ++userPassword: password141 ++mail: uid141 ++uidnumber: 141 ++gidnumber: 141 ++homeDirectory: /home/uid141 ++ ++dn: cn=user142,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user142 ++sn: user142 ++uid: uid142 ++givenname: givenname142 ++description: description142 ++userPassword: password142 ++mail: uid142 ++uidnumber: 142 ++gidnumber: 142 ++homeDirectory: /home/uid142 ++ ++dn: cn=user143,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user143 ++sn: user143 ++uid: uid143 ++givenname: givenname143 ++description: description143 ++userPassword: password143 ++mail: uid143 ++uidnumber: 143 ++gidnumber: 143 ++homeDirectory: /home/uid143 ++ ++dn: cn=user144,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user144 ++sn: user144 ++uid: uid144 ++givenname: givenname144 ++description: description144 ++userPassword: password144 ++mail: uid144 ++uidnumber: 144 ++gidnumber: 144 ++homeDirectory: /home/uid144 ++ ++dn: cn=user145,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user145 ++sn: user145 ++uid: uid145 ++givenname: givenname145 ++description: description145 ++userPassword: password145 ++mail: uid145 ++uidnumber: 145 ++gidnumber: 145 ++homeDirectory: /home/uid145 ++ ++dn: cn=user146,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user146 ++sn: user146 ++uid: uid146 ++givenname: givenname146 ++description: description146 ++userPassword: password146 ++mail: uid146 ++uidnumber: 146 ++gidnumber: 146 ++homeDirectory: /home/uid146 ++ ++dn: cn=user147,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user147 ++sn: user147 ++uid: uid147 ++givenname: givenname147 ++description: description147 ++userPassword: password147 ++mail: uid147 ++uidnumber: 147 ++gidnumber: 147 ++homeDirectory: /home/uid147 ++ ++dn: cn=user148,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user148 ++sn: user148 ++uid: uid148 ++givenname: givenname148 ++description: description148 ++userPassword: password148 ++mail: uid148 ++uidnumber: 148 ++gidnumber: 148 ++homeDirectory: /home/uid148 ++ ++dn: cn=user149,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user149 ++sn: user149 ++uid: uid149 ++givenname: givenname149 ++description: description149 ++userPassword: password149 ++mail: uid149 ++uidnumber: 149 ++gidnumber: 149 ++homeDirectory: /home/uid149 ++ ++dn: cn=user150,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user150 ++sn: user150 ++uid: uid150 ++givenname: givenname150 ++description: description150 ++userPassword: password150 ++mail: uid150 ++uidnumber: 150 ++gidnumber: 150 ++homeDirectory: /home/uid150 ++ ++dn: cn=user151,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user151 ++sn: user151 ++uid: uid151 ++givenname: givenname151 ++description: description151 ++userPassword: password151 ++mail: uid151 ++uidnumber: 151 ++gidnumber: 151 ++homeDirectory: /home/uid151 ++ ++dn: cn=user152,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user152 ++sn: user152 ++uid: uid152 ++givenname: givenname152 ++description: description152 ++userPassword: password152 ++mail: uid152 ++uidnumber: 152 ++gidnumber: 152 ++homeDirectory: /home/uid152 ++ ++dn: cn=user153,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user153 ++sn: user153 ++uid: uid153 ++givenname: givenname153 ++description: description153 ++userPassword: password153 ++mail: uid153 ++uidnumber: 153 ++gidnumber: 153 ++homeDirectory: /home/uid153 ++ ++dn: cn=user154,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user154 ++sn: user154 ++uid: uid154 ++givenname: givenname154 ++description: description154 ++userPassword: password154 ++mail: uid154 ++uidnumber: 154 ++gidnumber: 154 ++homeDirectory: /home/uid154 ++ ++dn: cn=user155,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user155 ++sn: user155 ++uid: uid155 ++givenname: givenname155 ++description: description155 ++userPassword: password155 ++mail: uid155 ++uidnumber: 155 ++gidnumber: 155 ++homeDirectory: /home/uid155 ++ ++dn: cn=user156,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user156 ++sn: user156 ++uid: uid156 ++givenname: givenname156 ++description: description156 ++userPassword: password156 ++mail: uid156 ++uidnumber: 156 ++gidnumber: 156 ++homeDirectory: /home/uid156 ++ ++dn: cn=user157,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user157 ++sn: user157 ++uid: uid157 ++givenname: givenname157 ++description: description157 ++userPassword: password157 ++mail: uid157 ++uidnumber: 157 ++gidnumber: 157 ++homeDirectory: /home/uid157 ++ ++dn: cn=user158,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user158 ++sn: user158 ++uid: uid158 ++givenname: givenname158 ++description: description158 ++userPassword: password158 ++mail: uid158 ++uidnumber: 158 ++gidnumber: 158 ++homeDirectory: /home/uid158 ++ ++dn: cn=user159,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user159 ++sn: user159 ++uid: uid159 ++givenname: givenname159 ++description: description159 ++userPassword: password159 ++mail: uid159 ++uidnumber: 159 ++gidnumber: 159 ++homeDirectory: /home/uid159 ++ ++dn: cn=user160,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user160 ++sn: user160 ++uid: uid160 ++givenname: givenname160 ++description: description160 ++userPassword: password160 ++mail: uid160 ++uidnumber: 160 ++gidnumber: 160 ++homeDirectory: /home/uid160 ++ ++dn: cn=user161,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user161 ++sn: user161 ++uid: uid161 ++givenname: givenname161 ++description: description161 ++userPassword: password161 ++mail: uid161 ++uidnumber: 161 ++gidnumber: 161 ++homeDirectory: /home/uid161 ++ ++dn: cn=user162,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user162 ++sn: user162 ++uid: uid162 ++givenname: givenname162 ++description: description162 ++userPassword: password162 ++mail: uid162 ++uidnumber: 162 ++gidnumber: 162 ++homeDirectory: /home/uid162 ++ ++dn: cn=user163,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user163 ++sn: user163 ++uid: uid163 ++givenname: givenname163 ++description: description163 ++userPassword: password163 ++mail: uid163 ++uidnumber: 163 ++gidnumber: 163 ++homeDirectory: /home/uid163 ++ ++dn: cn=user164,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user164 ++sn: user164 ++uid: uid164 ++givenname: givenname164 ++description: description164 ++userPassword: password164 ++mail: uid164 ++uidnumber: 164 ++gidnumber: 164 ++homeDirectory: /home/uid164 ++ ++dn: cn=user165,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user165 ++sn: user165 ++uid: uid165 ++givenname: givenname165 ++description: description165 ++userPassword: password165 ++mail: uid165 ++uidnumber: 165 ++gidnumber: 165 ++homeDirectory: /home/uid165 ++ ++dn: cn=user166,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user166 ++sn: user166 ++uid: uid166 ++givenname: givenname166 ++description: description166 ++userPassword: password166 ++mail: uid166 ++uidnumber: 166 ++gidnumber: 166 ++homeDirectory: /home/uid166 ++ ++dn: cn=user167,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user167 ++sn: user167 ++uid: uid167 ++givenname: givenname167 ++description: description167 ++userPassword: password167 ++mail: uid167 ++uidnumber: 167 ++gidnumber: 167 ++homeDirectory: /home/uid167 ++ ++dn: cn=user168,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user168 ++sn: user168 ++uid: uid168 ++givenname: givenname168 ++description: description168 ++userPassword: password168 ++mail: uid168 ++uidnumber: 168 ++gidnumber: 168 ++homeDirectory: /home/uid168 ++ ++dn: cn=user169,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user169 ++sn: user169 ++uid: uid169 ++givenname: givenname169 ++description: description169 ++userPassword: password169 ++mail: uid169 ++uidnumber: 169 ++gidnumber: 169 ++homeDirectory: /home/uid169 ++ ++dn: cn=user170,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user170 ++sn: user170 ++uid: uid170 ++givenname: givenname170 ++description: description170 ++userPassword: password170 ++mail: uid170 ++uidnumber: 170 ++gidnumber: 170 ++homeDirectory: /home/uid170 ++ ++dn: cn=user171,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user171 ++sn: user171 ++uid: uid171 ++givenname: givenname171 ++description: description171 ++userPassword: password171 ++mail: uid171 ++uidnumber: 171 ++gidnumber: 171 ++homeDirectory: /home/uid171 ++ ++dn: cn=user172,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user172 ++sn: user172 ++uid: uid172 ++givenname: givenname172 ++description: description172 ++userPassword: password172 ++mail: uid172 ++uidnumber: 172 ++gidnumber: 172 ++homeDirectory: /home/uid172 ++ ++dn: cn=user173,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user173 ++sn: user173 ++uid: uid173 ++givenname: givenname173 ++description: description173 ++userPassword: password173 ++mail: uid173 ++uidnumber: 173 ++gidnumber: 173 ++homeDirectory: /home/uid173 ++ ++dn: cn=user174,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user174 ++sn: user174 ++uid: uid174 ++givenname: givenname174 ++description: description174 ++userPassword: password174 ++mail: uid174 ++uidnumber: 174 ++gidnumber: 174 ++homeDirectory: /home/uid174 ++ ++dn: cn=user175,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user175 ++sn: user175 ++uid: uid175 ++givenname: givenname175 ++description: description175 ++userPassword: password175 ++mail: uid175 ++uidnumber: 175 ++gidnumber: 175 ++homeDirectory: /home/uid175 ++ ++dn: cn=user176,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user176 ++sn: user176 ++uid: uid176 ++givenname: givenname176 ++description: description176 ++userPassword: password176 ++mail: uid176 ++uidnumber: 176 ++gidnumber: 176 ++homeDirectory: /home/uid176 ++ ++dn: cn=user177,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user177 ++sn: user177 ++uid: uid177 ++givenname: givenname177 ++description: description177 ++userPassword: password177 ++mail: uid177 ++uidnumber: 177 ++gidnumber: 177 ++homeDirectory: /home/uid177 ++ ++dn: cn=user178,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user178 ++sn: user178 ++uid: uid178 ++givenname: givenname178 ++description: description178 ++userPassword: password178 ++mail: uid178 ++uidnumber: 178 ++gidnumber: 178 ++homeDirectory: /home/uid178 ++ ++dn: cn=user179,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user179 ++sn: user179 ++uid: uid179 ++givenname: givenname179 ++description: description179 ++userPassword: password179 ++mail: uid179 ++uidnumber: 179 ++gidnumber: 179 ++homeDirectory: /home/uid179 ++ ++dn: cn=user180,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user180 ++sn: user180 ++uid: uid180 ++givenname: givenname180 ++description: description180 ++userPassword: password180 ++mail: uid180 ++uidnumber: 180 ++gidnumber: 180 ++homeDirectory: /home/uid180 ++ ++dn: cn=user181,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user181 ++sn: user181 ++uid: uid181 ++givenname: givenname181 ++description: description181 ++userPassword: password181 ++mail: uid181 ++uidnumber: 181 ++gidnumber: 181 ++homeDirectory: /home/uid181 ++ ++dn: cn=user182,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user182 ++sn: user182 ++uid: uid182 ++givenname: givenname182 ++description: description182 ++userPassword: password182 ++mail: uid182 ++uidnumber: 182 ++gidnumber: 182 ++homeDirectory: /home/uid182 ++ ++dn: cn=user183,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user183 ++sn: user183 ++uid: uid183 ++givenname: givenname183 ++description: description183 ++userPassword: password183 ++mail: uid183 ++uidnumber: 183 ++gidnumber: 183 ++homeDirectory: /home/uid183 ++ ++dn: cn=user184,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user184 ++sn: user184 ++uid: uid184 ++givenname: givenname184 ++description: description184 ++userPassword: password184 ++mail: uid184 ++uidnumber: 184 ++gidnumber: 184 ++homeDirectory: /home/uid184 ++ ++dn: cn=user185,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user185 ++sn: user185 ++uid: uid185 ++givenname: givenname185 ++description: description185 ++userPassword: password185 ++mail: uid185 ++uidnumber: 185 ++gidnumber: 185 ++homeDirectory: /home/uid185 ++ ++dn: cn=user186,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user186 ++sn: user186 ++uid: uid186 ++givenname: givenname186 ++description: description186 ++userPassword: password186 ++mail: uid186 ++uidnumber: 186 ++gidnumber: 186 ++homeDirectory: /home/uid186 ++ ++dn: cn=user187,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user187 ++sn: user187 ++uid: uid187 ++givenname: givenname187 ++description: description187 ++userPassword: password187 ++mail: uid187 ++uidnumber: 187 ++gidnumber: 187 ++homeDirectory: /home/uid187 ++ ++dn: cn=user188,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user188 ++sn: user188 ++uid: uid188 ++givenname: givenname188 ++description: description188 ++userPassword: password188 ++mail: uid188 ++uidnumber: 188 ++gidnumber: 188 ++homeDirectory: /home/uid188 ++ ++dn: cn=user189,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user189 ++sn: user189 ++uid: uid189 ++givenname: givenname189 ++description: description189 ++userPassword: password189 ++mail: uid189 ++uidnumber: 189 ++gidnumber: 189 ++homeDirectory: /home/uid189 ++ ++dn: cn=user190,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user190 ++sn: user190 ++uid: uid190 ++givenname: givenname190 ++description: description190 ++userPassword: password190 ++mail: uid190 ++uidnumber: 190 ++gidnumber: 190 ++homeDirectory: /home/uid190 ++ ++dn: cn=user191,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user191 ++sn: user191 ++uid: uid191 ++givenname: givenname191 ++description: description191 ++userPassword: password191 ++mail: uid191 ++uidnumber: 191 ++gidnumber: 191 ++homeDirectory: /home/uid191 ++ ++dn: cn=user192,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user192 ++sn: user192 ++uid: uid192 ++givenname: givenname192 ++description: description192 ++userPassword: password192 ++mail: uid192 ++uidnumber: 192 ++gidnumber: 192 ++homeDirectory: /home/uid192 ++ ++dn: cn=user193,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user193 ++sn: user193 ++uid: uid193 ++givenname: givenname193 ++description: description193 ++userPassword: password193 ++mail: uid193 ++uidnumber: 193 ++gidnumber: 193 ++homeDirectory: /home/uid193 ++ ++dn: cn=user194,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user194 ++sn: user194 ++uid: uid194 ++givenname: givenname194 ++description: description194 ++userPassword: password194 ++mail: uid194 ++uidnumber: 194 ++gidnumber: 194 ++homeDirectory: /home/uid194 ++ ++dn: cn=user195,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user195 ++sn: user195 ++uid: uid195 ++givenname: givenname195 ++description: description195 ++userPassword: password195 ++mail: uid195 ++uidnumber: 195 ++gidnumber: 195 ++homeDirectory: /home/uid195 ++ ++dn: cn=user196,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user196 ++sn: user196 ++uid: uid196 ++givenname: givenname196 ++description: description196 ++userPassword: password196 ++mail: uid196 ++uidnumber: 196 ++gidnumber: 196 ++homeDirectory: /home/uid196 ++ ++dn: cn=user197,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user197 ++sn: user197 ++uid: uid197 ++givenname: givenname197 ++description: description197 ++userPassword: password197 ++mail: uid197 ++uidnumber: 197 ++gidnumber: 197 ++homeDirectory: /home/uid197 ++ ++dn: cn=user198,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user198 ++sn: user198 ++uid: uid198 ++givenname: givenname198 ++description: description198 ++userPassword: password198 ++mail: uid198 ++uidnumber: 198 ++gidnumber: 198 ++homeDirectory: /home/uid198 ++ ++dn: cn=user199,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user199 ++sn: user199 ++uid: uid199 ++givenname: givenname199 ++description: description199 ++userPassword: password199 ++mail: uid199 ++uidnumber: 199 ++gidnumber: 199 ++homeDirectory: /home/uid199 ++ ++dn: cn=user200,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user200 ++sn: user200 ++uid: uid200 ++givenname: givenname200 ++description: description200 ++userPassword: password200 ++mail: uid200 ++uidnumber: 200 ++gidnumber: 200 ++homeDirectory: /home/uid200 ++ ++dn: cn=user201,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user201 ++sn: user201 ++uid: uid201 ++givenname: givenname201 ++description: description201 ++userPassword: password201 ++mail: uid201 ++uidnumber: 201 ++gidnumber: 201 ++homeDirectory: /home/uid201 ++ ++dn: cn=user202,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user202 ++sn: user202 ++uid: uid202 ++givenname: givenname202 ++description: description202 ++userPassword: password202 ++mail: uid202 ++uidnumber: 202 ++gidnumber: 202 ++homeDirectory: /home/uid202 ++ ++dn: cn=user203,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user203 ++sn: user203 ++uid: uid203 ++givenname: givenname203 ++description: description203 ++userPassword: password203 ++mail: uid203 ++uidnumber: 203 ++gidnumber: 203 ++homeDirectory: /home/uid203 ++ ++dn: cn=user204,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user204 ++sn: user204 ++uid: uid204 ++givenname: givenname204 ++description: description204 ++userPassword: password204 ++mail: uid204 ++uidnumber: 204 ++gidnumber: 204 ++homeDirectory: /home/uid204 ++ ++dn: cn=user205,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user205 ++sn: user205 ++uid: uid205 ++givenname: givenname205 ++description: description205 ++userPassword: password205 ++mail: uid205 ++uidnumber: 205 ++gidnumber: 205 ++homeDirectory: /home/uid205 ++ ++dn: cn=user206,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user206 ++sn: user206 ++uid: uid206 ++givenname: givenname206 ++description: description206 ++userPassword: password206 ++mail: uid206 ++uidnumber: 206 ++gidnumber: 206 ++homeDirectory: /home/uid206 ++ ++dn: cn=user207,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user207 ++sn: user207 ++uid: uid207 ++givenname: givenname207 ++description: description207 ++userPassword: password207 ++mail: uid207 ++uidnumber: 207 ++gidnumber: 207 ++homeDirectory: /home/uid207 ++ ++dn: cn=user208,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user208 ++sn: user208 ++uid: uid208 ++givenname: givenname208 ++description: description208 ++userPassword: password208 ++mail: uid208 ++uidnumber: 208 ++gidnumber: 208 ++homeDirectory: /home/uid208 ++ ++dn: cn=user209,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user209 ++sn: user209 ++uid: uid209 ++givenname: givenname209 ++description: description209 ++userPassword: password209 ++mail: uid209 ++uidnumber: 209 ++gidnumber: 209 ++homeDirectory: /home/uid209 ++ ++dn: cn=user210,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user210 ++sn: user210 ++uid: uid210 ++givenname: givenname210 ++description: description210 ++userPassword: password210 ++mail: uid210 ++uidnumber: 210 ++gidnumber: 210 ++homeDirectory: /home/uid210 ++ ++dn: cn=user211,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user211 ++sn: user211 ++uid: uid211 ++givenname: givenname211 ++description: description211 ++userPassword: password211 ++mail: uid211 ++uidnumber: 211 ++gidnumber: 211 ++homeDirectory: /home/uid211 ++ ++dn: cn=user212,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user212 ++sn: user212 ++uid: uid212 ++givenname: givenname212 ++description: description212 ++userPassword: password212 ++mail: uid212 ++uidnumber: 212 ++gidnumber: 212 ++homeDirectory: /home/uid212 ++ ++dn: cn=user213,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user213 ++sn: user213 ++uid: uid213 ++givenname: givenname213 ++description: description213 ++userPassword: password213 ++mail: uid213 ++uidnumber: 213 ++gidnumber: 213 ++homeDirectory: /home/uid213 ++ ++dn: cn=user214,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user214 ++sn: user214 ++uid: uid214 ++givenname: givenname214 ++description: description214 ++userPassword: password214 ++mail: uid214 ++uidnumber: 214 ++gidnumber: 214 ++homeDirectory: /home/uid214 ++ ++dn: cn=user215,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user215 ++sn: user215 ++uid: uid215 ++givenname: givenname215 ++description: description215 ++userPassword: password215 ++mail: uid215 ++uidnumber: 215 ++gidnumber: 215 ++homeDirectory: /home/uid215 ++ ++dn: cn=user216,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user216 ++sn: user216 ++uid: uid216 ++givenname: givenname216 ++description: description216 ++userPassword: password216 ++mail: uid216 ++uidnumber: 216 ++gidnumber: 216 ++homeDirectory: /home/uid216 ++ ++dn: cn=user217,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user217 ++sn: user217 ++uid: uid217 ++givenname: givenname217 ++description: description217 ++userPassword: password217 ++mail: uid217 ++uidnumber: 217 ++gidnumber: 217 ++homeDirectory: /home/uid217 ++ ++dn: cn=user218,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user218 ++sn: user218 ++uid: uid218 ++givenname: givenname218 ++description: description218 ++userPassword: password218 ++mail: uid218 ++uidnumber: 218 ++gidnumber: 218 ++homeDirectory: /home/uid218 ++ ++dn: cn=user219,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user219 ++sn: user219 ++uid: uid219 ++givenname: givenname219 ++description: description219 ++userPassword: password219 ++mail: uid219 ++uidnumber: 219 ++gidnumber: 219 ++homeDirectory: /home/uid219 ++ ++dn: cn=user220,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user220 ++sn: user220 ++uid: uid220 ++givenname: givenname220 ++description: description220 ++userPassword: password220 ++mail: uid220 ++uidnumber: 220 ++gidnumber: 220 ++homeDirectory: /home/uid220 ++ ++dn: cn=user221,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user221 ++sn: user221 ++uid: uid221 ++givenname: givenname221 ++description: description221 ++userPassword: password221 ++mail: uid221 ++uidnumber: 221 ++gidnumber: 221 ++homeDirectory: /home/uid221 ++ ++dn: cn=user222,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user222 ++sn: user222 ++uid: uid222 ++givenname: givenname222 ++description: description222 ++userPassword: password222 ++mail: uid222 ++uidnumber: 222 ++gidnumber: 222 ++homeDirectory: /home/uid222 ++ ++dn: cn=user223,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user223 ++sn: user223 ++uid: uid223 ++givenname: givenname223 ++description: description223 ++userPassword: password223 ++mail: uid223 ++uidnumber: 223 ++gidnumber: 223 ++homeDirectory: /home/uid223 ++ ++dn: cn=user224,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user224 ++sn: user224 ++uid: uid224 ++givenname: givenname224 ++description: description224 ++userPassword: password224 ++mail: uid224 ++uidnumber: 224 ++gidnumber: 224 ++homeDirectory: /home/uid224 ++ ++dn: cn=user225,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user225 ++sn: user225 ++uid: uid225 ++givenname: givenname225 ++description: description225 ++userPassword: password225 ++mail: uid225 ++uidnumber: 225 ++gidnumber: 225 ++homeDirectory: /home/uid225 ++ ++dn: cn=user226,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user226 ++sn: user226 ++uid: uid226 ++givenname: givenname226 ++description: description226 ++userPassword: password226 ++mail: uid226 ++uidnumber: 226 ++gidnumber: 226 ++homeDirectory: /home/uid226 ++ ++dn: cn=user227,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user227 ++sn: user227 ++uid: uid227 ++givenname: givenname227 ++description: description227 ++userPassword: password227 ++mail: uid227 ++uidnumber: 227 ++gidnumber: 227 ++homeDirectory: /home/uid227 ++ ++dn: cn=user228,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user228 ++sn: user228 ++uid: uid228 ++givenname: givenname228 ++description: description228 ++userPassword: password228 ++mail: uid228 ++uidnumber: 228 ++gidnumber: 228 ++homeDirectory: /home/uid228 ++ ++dn: cn=user229,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user229 ++sn: user229 ++uid: uid229 ++givenname: givenname229 ++description: description229 ++userPassword: password229 ++mail: uid229 ++uidnumber: 229 ++gidnumber: 229 ++homeDirectory: /home/uid229 ++ ++dn: cn=user230,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user230 ++sn: user230 ++uid: uid230 ++givenname: givenname230 ++description: description230 ++userPassword: password230 ++mail: uid230 ++uidnumber: 230 ++gidnumber: 230 ++homeDirectory: /home/uid230 ++ ++dn: cn=user231,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user231 ++sn: user231 ++uid: uid231 ++givenname: givenname231 ++description: description231 ++userPassword: password231 ++mail: uid231 ++uidnumber: 231 ++gidnumber: 231 ++homeDirectory: /home/uid231 ++ ++dn: cn=user232,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user232 ++sn: user232 ++uid: uid232 ++givenname: givenname232 ++description: description232 ++userPassword: password232 ++mail: uid232 ++uidnumber: 232 ++gidnumber: 232 ++homeDirectory: /home/uid232 ++ ++dn: cn=user233,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user233 ++sn: user233 ++uid: uid233 ++givenname: givenname233 ++description: description233 ++userPassword: password233 ++mail: uid233 ++uidnumber: 233 ++gidnumber: 233 ++homeDirectory: /home/uid233 ++ ++dn: cn=user234,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user234 ++sn: user234 ++uid: uid234 ++givenname: givenname234 ++description: description234 ++userPassword: password234 ++mail: uid234 ++uidnumber: 234 ++gidnumber: 234 ++homeDirectory: /home/uid234 ++ ++dn: cn=user235,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user235 ++sn: user235 ++uid: uid235 ++givenname: givenname235 ++description: description235 ++userPassword: password235 ++mail: uid235 ++uidnumber: 235 ++gidnumber: 235 ++homeDirectory: /home/uid235 ++ ++dn: cn=user236,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user236 ++sn: user236 ++uid: uid236 ++givenname: givenname236 ++description: description236 ++userPassword: password236 ++mail: uid236 ++uidnumber: 236 ++gidnumber: 236 ++homeDirectory: /home/uid236 ++ ++dn: cn=user237,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user237 ++sn: user237 ++uid: uid237 ++givenname: givenname237 ++description: description237 ++userPassword: password237 ++mail: uid237 ++uidnumber: 237 ++gidnumber: 237 ++homeDirectory: /home/uid237 ++ ++dn: cn=user238,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user238 ++sn: user238 ++uid: uid238 ++givenname: givenname238 ++description: description238 ++userPassword: password238 ++mail: uid238 ++uidnumber: 238 ++gidnumber: 238 ++homeDirectory: /home/uid238 ++ ++dn: cn=user239,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user239 ++sn: user239 ++uid: uid239 ++givenname: givenname239 ++description: description239 ++userPassword: password239 ++mail: uid239 ++uidnumber: 239 ++gidnumber: 239 ++homeDirectory: /home/uid239 ++ ++dn: cn=user240,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user240 ++sn: user240 ++uid: uid240 ++givenname: givenname240 ++description: description240 ++userPassword: password240 ++mail: uid240 ++uidnumber: 240 ++gidnumber: 240 ++homeDirectory: /home/uid240 ++ ++dn: cn=user241,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user241 ++sn: user241 ++uid: uid241 ++givenname: givenname241 ++description: description241 ++userPassword: password241 ++mail: uid241 ++uidnumber: 241 ++gidnumber: 241 ++homeDirectory: /home/uid241 ++ ++dn: cn=user242,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user242 ++sn: user242 ++uid: uid242 ++givenname: givenname242 ++description: description242 ++userPassword: password242 ++mail: uid242 ++uidnumber: 242 ++gidnumber: 242 ++homeDirectory: /home/uid242 ++ ++dn: cn=user243,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user243 ++sn: user243 ++uid: uid243 ++givenname: givenname243 ++description: description243 ++userPassword: password243 ++mail: uid243 ++uidnumber: 243 ++gidnumber: 243 ++homeDirectory: /home/uid243 ++ ++dn: cn=user244,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user244 ++sn: user244 ++uid: uid244 ++givenname: givenname244 ++description: description244 ++userPassword: password244 ++mail: uid244 ++uidnumber: 244 ++gidnumber: 244 ++homeDirectory: /home/uid244 ++ ++dn: cn=user245,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user245 ++sn: user245 ++uid: uid245 ++givenname: givenname245 ++description: description245 ++userPassword: password245 ++mail: uid245 ++uidnumber: 245 ++gidnumber: 245 ++homeDirectory: /home/uid245 ++ ++dn: cn=user246,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user246 ++sn: user246 ++uid: uid246 ++givenname: givenname246 ++description: description246 ++userPassword: password246 ++mail: uid246 ++uidnumber: 246 ++gidnumber: 246 ++homeDirectory: /home/uid246 ++ ++dn: cn=user247,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user247 ++sn: user247 ++uid: uid247 ++givenname: givenname247 ++description: description247 ++userPassword: password247 ++mail: uid247 ++uidnumber: 247 ++gidnumber: 247 ++homeDirectory: /home/uid247 ++ ++dn: cn=user248,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user248 ++sn: user248 ++uid: uid248 ++givenname: givenname248 ++description: description248 ++userPassword: password248 ++mail: uid248 ++uidnumber: 248 ++gidnumber: 248 ++homeDirectory: /home/uid248 ++ ++dn: cn=user249,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user249 ++sn: user249 ++uid: uid249 ++givenname: givenname249 ++description: description249 ++userPassword: password249 ++mail: uid249 ++uidnumber: 249 ++gidnumber: 249 ++homeDirectory: /home/uid249 ++ ++dn: cn=user250,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user250 ++sn: user250 ++uid: uid250 ++givenname: givenname250 ++description: description250 ++userPassword: password250 ++mail: uid250 ++uidnumber: 250 ++gidnumber: 250 ++homeDirectory: /home/uid250 ++ ++dn: cn=user251,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user251 ++sn: user251 ++uid: uid251 ++givenname: givenname251 ++description: description251 ++userPassword: password251 ++mail: uid251 ++uidnumber: 251 ++gidnumber: 251 ++homeDirectory: /home/uid251 ++ ++dn: cn=user252,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user252 ++sn: user252 ++uid: uid252 ++givenname: givenname252 ++description: description252 ++userPassword: password252 ++mail: uid252 ++uidnumber: 252 ++gidnumber: 252 ++homeDirectory: /home/uid252 ++ ++dn: cn=user253,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user253 ++sn: user253 ++uid: uid253 ++givenname: givenname253 ++description: description253 ++userPassword: password253 ++mail: uid253 ++uidnumber: 253 ++gidnumber: 253 ++homeDirectory: /home/uid253 ++ ++dn: cn=user254,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user254 ++sn: user254 ++uid: uid254 ++givenname: givenname254 ++description: description254 ++userPassword: password254 ++mail: uid254 ++uidnumber: 254 ++gidnumber: 254 ++homeDirectory: /home/uid254 ++ ++dn: cn=user255,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user255 ++sn: user255 ++uid: uid255 ++givenname: givenname255 ++description: description255 ++userPassword: password255 ++mail: uid255 ++uidnumber: 255 ++gidnumber: 255 ++homeDirectory: /home/uid255 ++ ++dn: cn=user256,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user256 ++sn: user256 ++uid: uid256 ++givenname: givenname256 ++description: description256 ++userPassword: password256 ++mail: uid256 ++uidnumber: 256 ++gidnumber: 256 ++homeDirectory: /home/uid256 ++ ++dn: cn=user257,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user257 ++sn: user257 ++uid: uid257 ++givenname: givenname257 ++description: description257 ++userPassword: password257 ++mail: uid257 ++uidnumber: 257 ++gidnumber: 257 ++homeDirectory: /home/uid257 ++ ++dn: cn=user258,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user258 ++sn: user258 ++uid: uid258 ++givenname: givenname258 ++description: description258 ++userPassword: password258 ++mail: uid258 ++uidnumber: 258 ++gidnumber: 258 ++homeDirectory: /home/uid258 ++ ++dn: cn=user259,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user259 ++sn: user259 ++uid: uid259 ++givenname: givenname259 ++description: description259 ++userPassword: password259 ++mail: uid259 ++uidnumber: 259 ++gidnumber: 259 ++homeDirectory: /home/uid259 ++ ++dn: cn=user260,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user260 ++sn: user260 ++uid: uid260 ++givenname: givenname260 ++description: description260 ++userPassword: password260 ++mail: uid260 ++uidnumber: 260 ++gidnumber: 260 ++homeDirectory: /home/uid260 ++ ++dn: cn=user261,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user261 ++sn: user261 ++uid: uid261 ++givenname: givenname261 ++description: description261 ++userPassword: password261 ++mail: uid261 ++uidnumber: 261 ++gidnumber: 261 ++homeDirectory: /home/uid261 ++ ++dn: cn=user262,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user262 ++sn: user262 ++uid: uid262 ++givenname: givenname262 ++description: description262 ++userPassword: password262 ++mail: uid262 ++uidnumber: 262 ++gidnumber: 262 ++homeDirectory: /home/uid262 ++ ++dn: cn=user263,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user263 ++sn: user263 ++uid: uid263 ++givenname: givenname263 ++description: description263 ++userPassword: password263 ++mail: uid263 ++uidnumber: 263 ++gidnumber: 263 ++homeDirectory: /home/uid263 ++ ++dn: cn=user264,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user264 ++sn: user264 ++uid: uid264 ++givenname: givenname264 ++description: description264 ++userPassword: password264 ++mail: uid264 ++uidnumber: 264 ++gidnumber: 264 ++homeDirectory: /home/uid264 ++ ++dn: cn=user265,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user265 ++sn: user265 ++uid: uid265 ++givenname: givenname265 ++description: description265 ++userPassword: password265 ++mail: uid265 ++uidnumber: 265 ++gidnumber: 265 ++homeDirectory: /home/uid265 ++ ++dn: cn=user266,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user266 ++sn: user266 ++uid: uid266 ++givenname: givenname266 ++description: description266 ++userPassword: password266 ++mail: uid266 ++uidnumber: 266 ++gidnumber: 266 ++homeDirectory: /home/uid266 ++ ++dn: cn=user267,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user267 ++sn: user267 ++uid: uid267 ++givenname: givenname267 ++description: description267 ++userPassword: password267 ++mail: uid267 ++uidnumber: 267 ++gidnumber: 267 ++homeDirectory: /home/uid267 ++ ++dn: cn=user268,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user268 ++sn: user268 ++uid: uid268 ++givenname: givenname268 ++description: description268 ++userPassword: password268 ++mail: uid268 ++uidnumber: 268 ++gidnumber: 268 ++homeDirectory: /home/uid268 ++ ++dn: cn=user269,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user269 ++sn: user269 ++uid: uid269 ++givenname: givenname269 ++description: description269 ++userPassword: password269 ++mail: uid269 ++uidnumber: 269 ++gidnumber: 269 ++homeDirectory: /home/uid269 ++ ++dn: cn=user270,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user270 ++sn: user270 ++uid: uid270 ++givenname: givenname270 ++description: description270 ++userPassword: password270 ++mail: uid270 ++uidnumber: 270 ++gidnumber: 270 ++homeDirectory: /home/uid270 ++ ++dn: cn=user271,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user271 ++sn: user271 ++uid: uid271 ++givenname: givenname271 ++description: description271 ++userPassword: password271 ++mail: uid271 ++uidnumber: 271 ++gidnumber: 271 ++homeDirectory: /home/uid271 ++ ++dn: cn=user272,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user272 ++sn: user272 ++uid: uid272 ++givenname: givenname272 ++description: description272 ++userPassword: password272 ++mail: uid272 ++uidnumber: 272 ++gidnumber: 272 ++homeDirectory: /home/uid272 ++ ++dn: cn=user273,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user273 ++sn: user273 ++uid: uid273 ++givenname: givenname273 ++description: description273 ++userPassword: password273 ++mail: uid273 ++uidnumber: 273 ++gidnumber: 273 ++homeDirectory: /home/uid273 ++ ++dn: cn=user274,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user274 ++sn: user274 ++uid: uid274 ++givenname: givenname274 ++description: description274 ++userPassword: password274 ++mail: uid274 ++uidnumber: 274 ++gidnumber: 274 ++homeDirectory: /home/uid274 ++ ++dn: cn=user275,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user275 ++sn: user275 ++uid: uid275 ++givenname: givenname275 ++description: description275 ++userPassword: password275 ++mail: uid275 ++uidnumber: 275 ++gidnumber: 275 ++homeDirectory: /home/uid275 ++ ++dn: cn=user276,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user276 ++sn: user276 ++uid: uid276 ++givenname: givenname276 ++description: description276 ++userPassword: password276 ++mail: uid276 ++uidnumber: 276 ++gidnumber: 276 ++homeDirectory: /home/uid276 ++ ++dn: cn=user277,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user277 ++sn: user277 ++uid: uid277 ++givenname: givenname277 ++description: description277 ++userPassword: password277 ++mail: uid277 ++uidnumber: 277 ++gidnumber: 277 ++homeDirectory: /home/uid277 ++ ++dn: cn=user278,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user278 ++sn: user278 ++uid: uid278 ++givenname: givenname278 ++description: description278 ++userPassword: password278 ++mail: uid278 ++uidnumber: 278 ++gidnumber: 278 ++homeDirectory: /home/uid278 ++ ++dn: cn=user279,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user279 ++sn: user279 ++uid: uid279 ++givenname: givenname279 ++description: description279 ++userPassword: password279 ++mail: uid279 ++uidnumber: 279 ++gidnumber: 279 ++homeDirectory: /home/uid279 ++ ++dn: cn=user280,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user280 ++sn: user280 ++uid: uid280 ++givenname: givenname280 ++description: description280 ++userPassword: password280 ++mail: uid280 ++uidnumber: 280 ++gidnumber: 280 ++homeDirectory: /home/uid280 ++ ++dn: cn=user281,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user281 ++sn: user281 ++uid: uid281 ++givenname: givenname281 ++description: description281 ++userPassword: password281 ++mail: uid281 ++uidnumber: 281 ++gidnumber: 281 ++homeDirectory: /home/uid281 ++ ++dn: cn=user282,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user282 ++sn: user282 ++uid: uid282 ++givenname: givenname282 ++description: description282 ++userPassword: password282 ++mail: uid282 ++uidnumber: 282 ++gidnumber: 282 ++homeDirectory: /home/uid282 ++ ++dn: cn=user283,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user283 ++sn: user283 ++uid: uid283 ++givenname: givenname283 ++description: description283 ++userPassword: password283 ++mail: uid283 ++uidnumber: 283 ++gidnumber: 283 ++homeDirectory: /home/uid283 ++ ++dn: cn=user284,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user284 ++sn: user284 ++uid: uid284 ++givenname: givenname284 ++description: description284 ++userPassword: password284 ++mail: uid284 ++uidnumber: 284 ++gidnumber: 284 ++homeDirectory: /home/uid284 ++ ++dn: cn=user285,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user285 ++sn: user285 ++uid: uid285 ++givenname: givenname285 ++description: description285 ++userPassword: password285 ++mail: uid285 ++uidnumber: 285 ++gidnumber: 285 ++homeDirectory: /home/uid285 ++ ++dn: cn=user286,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user286 ++sn: user286 ++uid: uid286 ++givenname: givenname286 ++description: description286 ++userPassword: password286 ++mail: uid286 ++uidnumber: 286 ++gidnumber: 286 ++homeDirectory: /home/uid286 ++ ++dn: cn=user287,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user287 ++sn: user287 ++uid: uid287 ++givenname: givenname287 ++description: description287 ++userPassword: password287 ++mail: uid287 ++uidnumber: 287 ++gidnumber: 287 ++homeDirectory: /home/uid287 ++ ++dn: cn=user288,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user288 ++sn: user288 ++uid: uid288 ++givenname: givenname288 ++description: description288 ++userPassword: password288 ++mail: uid288 ++uidnumber: 288 ++gidnumber: 288 ++homeDirectory: /home/uid288 ++ ++dn: cn=user289,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user289 ++sn: user289 ++uid: uid289 ++givenname: givenname289 ++description: description289 ++userPassword: password289 ++mail: uid289 ++uidnumber: 289 ++gidnumber: 289 ++homeDirectory: /home/uid289 ++ ++dn: cn=user290,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user290 ++sn: user290 ++uid: uid290 ++givenname: givenname290 ++description: description290 ++userPassword: password290 ++mail: uid290 ++uidnumber: 290 ++gidnumber: 290 ++homeDirectory: /home/uid290 ++ ++dn: cn=user291,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user291 ++sn: user291 ++uid: uid291 ++givenname: givenname291 ++description: description291 ++userPassword: password291 ++mail: uid291 ++uidnumber: 291 ++gidnumber: 291 ++homeDirectory: /home/uid291 ++ ++dn: cn=user292,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user292 ++sn: user292 ++uid: uid292 ++givenname: givenname292 ++description: description292 ++userPassword: password292 ++mail: uid292 ++uidnumber: 292 ++gidnumber: 292 ++homeDirectory: /home/uid292 ++ ++dn: cn=user293,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user293 ++sn: user293 ++uid: uid293 ++givenname: givenname293 ++description: description293 ++userPassword: password293 ++mail: uid293 ++uidnumber: 293 ++gidnumber: 293 ++homeDirectory: /home/uid293 ++ ++dn: cn=user294,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user294 ++sn: user294 ++uid: uid294 ++givenname: givenname294 ++description: description294 ++userPassword: password294 ++mail: uid294 ++uidnumber: 294 ++gidnumber: 294 ++homeDirectory: /home/uid294 ++ ++dn: cn=user295,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user295 ++sn: user295 ++uid: uid295 ++givenname: givenname295 ++description: description295 ++userPassword: password295 ++mail: uid295 ++uidnumber: 295 ++gidnumber: 295 ++homeDirectory: /home/uid295 ++ ++dn: cn=user296,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user296 ++sn: user296 ++uid: uid296 ++givenname: givenname296 ++description: description296 ++userPassword: password296 ++mail: uid296 ++uidnumber: 296 ++gidnumber: 296 ++homeDirectory: /home/uid296 ++ ++dn: cn=user297,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user297 ++sn: user297 ++uid: uid297 ++givenname: givenname297 ++description: description297 ++userPassword: password297 ++mail: uid297 ++uidnumber: 297 ++gidnumber: 297 ++homeDirectory: /home/uid297 ++ ++dn: cn=user298,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user298 ++sn: user298 ++uid: uid298 ++givenname: givenname298 ++description: description298 ++userPassword: password298 ++mail: uid298 ++uidnumber: 298 ++gidnumber: 298 ++homeDirectory: /home/uid298 ++ ++dn: cn=user299,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user299 ++sn: user299 ++uid: uid299 ++givenname: givenname299 ++description: description299 ++userPassword: password299 ++mail: uid299 ++uidnumber: 299 ++gidnumber: 299 ++homeDirectory: /home/uid299 ++ ++dn: cn=user300,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user300 ++sn: user300 ++uid: uid300 ++givenname: givenname300 ++description: description300 ++userPassword: password300 ++mail: uid300 ++uidnumber: 300 ++gidnumber: 300 ++homeDirectory: /home/uid300 ++ ++dn: cn=user301,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user301 ++sn: user301 ++uid: uid301 ++givenname: givenname301 ++description: description301 ++userPassword: password301 ++mail: uid301 ++uidnumber: 301 ++gidnumber: 301 ++homeDirectory: /home/uid301 ++ ++dn: cn=user302,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user302 ++sn: user302 ++uid: uid302 ++givenname: givenname302 ++description: description302 ++userPassword: password302 ++mail: uid302 ++uidnumber: 302 ++gidnumber: 302 ++homeDirectory: /home/uid302 ++ ++dn: cn=user303,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user303 ++sn: user303 ++uid: uid303 ++givenname: givenname303 ++description: description303 ++userPassword: password303 ++mail: uid303 ++uidnumber: 303 ++gidnumber: 303 ++homeDirectory: /home/uid303 ++ ++dn: cn=user304,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user304 ++sn: user304 ++uid: uid304 ++givenname: givenname304 ++description: description304 ++userPassword: password304 ++mail: uid304 ++uidnumber: 304 ++gidnumber: 304 ++homeDirectory: /home/uid304 ++ ++dn: cn=user305,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user305 ++sn: user305 ++uid: uid305 ++givenname: givenname305 ++description: description305 ++userPassword: password305 ++mail: uid305 ++uidnumber: 305 ++gidnumber: 305 ++homeDirectory: /home/uid305 ++ ++dn: cn=user306,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user306 ++sn: user306 ++uid: uid306 ++givenname: givenname306 ++description: description306 ++userPassword: password306 ++mail: uid306 ++uidnumber: 306 ++gidnumber: 306 ++homeDirectory: /home/uid306 ++ ++dn: cn=user307,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user307 ++sn: user307 ++uid: uid307 ++givenname: givenname307 ++description: description307 ++userPassword: password307 ++mail: uid307 ++uidnumber: 307 ++gidnumber: 307 ++homeDirectory: /home/uid307 ++ ++dn: cn=user308,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user308 ++sn: user308 ++uid: uid308 ++givenname: givenname308 ++description: description308 ++userPassword: password308 ++mail: uid308 ++uidnumber: 308 ++gidnumber: 308 ++homeDirectory: /home/uid308 ++ ++dn: cn=user309,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user309 ++sn: user309 ++uid: uid309 ++givenname: givenname309 ++description: description309 ++userPassword: password309 ++mail: uid309 ++uidnumber: 309 ++gidnumber: 309 ++homeDirectory: /home/uid309 ++ ++dn: cn=user310,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user310 ++sn: user310 ++uid: uid310 ++givenname: givenname310 ++description: description310 ++userPassword: password310 ++mail: uid310 ++uidnumber: 310 ++gidnumber: 310 ++homeDirectory: /home/uid310 ++ ++dn: cn=user311,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user311 ++sn: user311 ++uid: uid311 ++givenname: givenname311 ++description: description311 ++userPassword: password311 ++mail: uid311 ++uidnumber: 311 ++gidnumber: 311 ++homeDirectory: /home/uid311 ++ ++dn: cn=user312,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user312 ++sn: user312 ++uid: uid312 ++givenname: givenname312 ++description: description312 ++userPassword: password312 ++mail: uid312 ++uidnumber: 312 ++gidnumber: 312 ++homeDirectory: /home/uid312 ++ ++dn: cn=user313,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user313 ++sn: user313 ++uid: uid313 ++givenname: givenname313 ++description: description313 ++userPassword: password313 ++mail: uid313 ++uidnumber: 313 ++gidnumber: 313 ++homeDirectory: /home/uid313 ++ ++dn: cn=user314,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user314 ++sn: user314 ++uid: uid314 ++givenname: givenname314 ++description: description314 ++userPassword: password314 ++mail: uid314 ++uidnumber: 314 ++gidnumber: 314 ++homeDirectory: /home/uid314 ++ ++dn: cn=user315,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user315 ++sn: user315 ++uid: uid315 ++givenname: givenname315 ++description: description315 ++userPassword: password315 ++mail: uid315 ++uidnumber: 315 ++gidnumber: 315 ++homeDirectory: /home/uid315 ++ ++dn: cn=user316,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user316 ++sn: user316 ++uid: uid316 ++givenname: givenname316 ++description: description316 ++userPassword: password316 ++mail: uid316 ++uidnumber: 316 ++gidnumber: 316 ++homeDirectory: /home/uid316 ++ ++dn: cn=user317,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user317 ++sn: user317 ++uid: uid317 ++givenname: givenname317 ++description: description317 ++userPassword: password317 ++mail: uid317 ++uidnumber: 317 ++gidnumber: 317 ++homeDirectory: /home/uid317 ++ ++dn: cn=user318,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user318 ++sn: user318 ++uid: uid318 ++givenname: givenname318 ++description: description318 ++userPassword: password318 ++mail: uid318 ++uidnumber: 318 ++gidnumber: 318 ++homeDirectory: /home/uid318 ++ ++dn: cn=user319,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user319 ++sn: user319 ++uid: uid319 ++givenname: givenname319 ++description: description319 ++userPassword: password319 ++mail: uid319 ++uidnumber: 319 ++gidnumber: 319 ++homeDirectory: /home/uid319 ++ ++dn: cn=user320,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user320 ++sn: user320 ++uid: uid320 ++givenname: givenname320 ++description: description320 ++userPassword: password320 ++mail: uid320 ++uidnumber: 320 ++gidnumber: 320 ++homeDirectory: /home/uid320 ++ ++dn: cn=user321,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user321 ++sn: user321 ++uid: uid321 ++givenname: givenname321 ++description: description321 ++userPassword: password321 ++mail: uid321 ++uidnumber: 321 ++gidnumber: 321 ++homeDirectory: /home/uid321 ++ ++dn: cn=user322,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user322 ++sn: user322 ++uid: uid322 ++givenname: givenname322 ++description: description322 ++userPassword: password322 ++mail: uid322 ++uidnumber: 322 ++gidnumber: 322 ++homeDirectory: /home/uid322 ++ ++dn: cn=user323,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user323 ++sn: user323 ++uid: uid323 ++givenname: givenname323 ++description: description323 ++userPassword: password323 ++mail: uid323 ++uidnumber: 323 ++gidnumber: 323 ++homeDirectory: /home/uid323 ++ ++dn: cn=user324,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user324 ++sn: user324 ++uid: uid324 ++givenname: givenname324 ++description: description324 ++userPassword: password324 ++mail: uid324 ++uidnumber: 324 ++gidnumber: 324 ++homeDirectory: /home/uid324 ++ ++dn: cn=user325,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user325 ++sn: user325 ++uid: uid325 ++givenname: givenname325 ++description: description325 ++userPassword: password325 ++mail: uid325 ++uidnumber: 325 ++gidnumber: 325 ++homeDirectory: /home/uid325 ++ ++dn: cn=user326,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user326 ++sn: user326 ++uid: uid326 ++givenname: givenname326 ++description: description326 ++userPassword: password326 ++mail: uid326 ++uidnumber: 326 ++gidnumber: 326 ++homeDirectory: /home/uid326 ++ ++dn: cn=user327,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user327 ++sn: user327 ++uid: uid327 ++givenname: givenname327 ++description: description327 ++userPassword: password327 ++mail: uid327 ++uidnumber: 327 ++gidnumber: 327 ++homeDirectory: /home/uid327 ++ ++dn: cn=user328,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user328 ++sn: user328 ++uid: uid328 ++givenname: givenname328 ++description: description328 ++userPassword: password328 ++mail: uid328 ++uidnumber: 328 ++gidnumber: 328 ++homeDirectory: /home/uid328 ++ ++dn: cn=user329,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user329 ++sn: user329 ++uid: uid329 ++givenname: givenname329 ++description: description329 ++userPassword: password329 ++mail: uid329 ++uidnumber: 329 ++gidnumber: 329 ++homeDirectory: /home/uid329 ++ ++dn: cn=user330,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user330 ++sn: user330 ++uid: uid330 ++givenname: givenname330 ++description: description330 ++userPassword: password330 ++mail: uid330 ++uidnumber: 330 ++gidnumber: 330 ++homeDirectory: /home/uid330 ++ ++dn: cn=user331,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user331 ++sn: user331 ++uid: uid331 ++givenname: givenname331 ++description: description331 ++userPassword: password331 ++mail: uid331 ++uidnumber: 331 ++gidnumber: 331 ++homeDirectory: /home/uid331 ++ ++dn: cn=user332,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user332 ++sn: user332 ++uid: uid332 ++givenname: givenname332 ++description: description332 ++userPassword: password332 ++mail: uid332 ++uidnumber: 332 ++gidnumber: 332 ++homeDirectory: /home/uid332 ++ ++dn: cn=user333,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user333 ++sn: user333 ++uid: uid333 ++givenname: givenname333 ++description: description333 ++userPassword: password333 ++mail: uid333 ++uidnumber: 333 ++gidnumber: 333 ++homeDirectory: /home/uid333 ++ ++dn: cn=user334,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user334 ++sn: user334 ++uid: uid334 ++givenname: givenname334 ++description: description334 ++userPassword: password334 ++mail: uid334 ++uidnumber: 334 ++gidnumber: 334 ++homeDirectory: /home/uid334 ++ ++dn: cn=user335,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user335 ++sn: user335 ++uid: uid335 ++givenname: givenname335 ++description: description335 ++userPassword: password335 ++mail: uid335 ++uidnumber: 335 ++gidnumber: 335 ++homeDirectory: /home/uid335 ++ ++dn: cn=user336,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user336 ++sn: user336 ++uid: uid336 ++givenname: givenname336 ++description: description336 ++userPassword: password336 ++mail: uid336 ++uidnumber: 336 ++gidnumber: 336 ++homeDirectory: /home/uid336 ++ ++dn: cn=user337,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user337 ++sn: user337 ++uid: uid337 ++givenname: givenname337 ++description: description337 ++userPassword: password337 ++mail: uid337 ++uidnumber: 337 ++gidnumber: 337 ++homeDirectory: /home/uid337 ++ ++dn: cn=user338,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user338 ++sn: user338 ++uid: uid338 ++givenname: givenname338 ++description: description338 ++userPassword: password338 ++mail: uid338 ++uidnumber: 338 ++gidnumber: 338 ++homeDirectory: /home/uid338 ++ ++dn: cn=user339,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user339 ++sn: user339 ++uid: uid339 ++givenname: givenname339 ++description: description339 ++userPassword: password339 ++mail: uid339 ++uidnumber: 339 ++gidnumber: 339 ++homeDirectory: /home/uid339 ++ ++dn: cn=user340,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user340 ++sn: user340 ++uid: uid340 ++givenname: givenname340 ++description: description340 ++userPassword: password340 ++mail: uid340 ++uidnumber: 340 ++gidnumber: 340 ++homeDirectory: /home/uid340 ++ ++dn: cn=user341,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user341 ++sn: user341 ++uid: uid341 ++givenname: givenname341 ++description: description341 ++userPassword: password341 ++mail: uid341 ++uidnumber: 341 ++gidnumber: 341 ++homeDirectory: /home/uid341 ++ ++dn: cn=user342,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user342 ++sn: user342 ++uid: uid342 ++givenname: givenname342 ++description: description342 ++userPassword: password342 ++mail: uid342 ++uidnumber: 342 ++gidnumber: 342 ++homeDirectory: /home/uid342 ++ ++dn: cn=user343,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user343 ++sn: user343 ++uid: uid343 ++givenname: givenname343 ++description: description343 ++userPassword: password343 ++mail: uid343 ++uidnumber: 343 ++gidnumber: 343 ++homeDirectory: /home/uid343 ++ ++dn: cn=user344,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user344 ++sn: user344 ++uid: uid344 ++givenname: givenname344 ++description: description344 ++userPassword: password344 ++mail: uid344 ++uidnumber: 344 ++gidnumber: 344 ++homeDirectory: /home/uid344 ++ ++dn: cn=user345,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user345 ++sn: user345 ++uid: uid345 ++givenname: givenname345 ++description: description345 ++userPassword: password345 ++mail: uid345 ++uidnumber: 345 ++gidnumber: 345 ++homeDirectory: /home/uid345 ++ ++dn: cn=user346,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user346 ++sn: user346 ++uid: uid346 ++givenname: givenname346 ++description: description346 ++userPassword: password346 ++mail: uid346 ++uidnumber: 346 ++gidnumber: 346 ++homeDirectory: /home/uid346 ++ ++dn: cn=user347,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user347 ++sn: user347 ++uid: uid347 ++givenname: givenname347 ++description: description347 ++userPassword: password347 ++mail: uid347 ++uidnumber: 347 ++gidnumber: 347 ++homeDirectory: /home/uid347 ++ ++dn: cn=user348,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user348 ++sn: user348 ++uid: uid348 ++givenname: givenname348 ++description: description348 ++userPassword: password348 ++mail: uid348 ++uidnumber: 348 ++gidnumber: 348 ++homeDirectory: /home/uid348 ++ ++dn: cn=user349,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user349 ++sn: user349 ++uid: uid349 ++givenname: givenname349 ++description: description349 ++userPassword: password349 ++mail: uid349 ++uidnumber: 349 ++gidnumber: 349 ++homeDirectory: /home/uid349 ++ ++dn: cn=user350,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user350 ++sn: user350 ++uid: uid350 ++givenname: givenname350 ++description: description350 ++userPassword: password350 ++mail: uid350 ++uidnumber: 350 ++gidnumber: 350 ++homeDirectory: /home/uid350 ++ ++dn: cn=user351,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user351 ++sn: user351 ++uid: uid351 ++givenname: givenname351 ++description: description351 ++userPassword: password351 ++mail: uid351 ++uidnumber: 351 ++gidnumber: 351 ++homeDirectory: /home/uid351 ++ ++dn: cn=user352,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user352 ++sn: user352 ++uid: uid352 ++givenname: givenname352 ++description: description352 ++userPassword: password352 ++mail: uid352 ++uidnumber: 352 ++gidnumber: 352 ++homeDirectory: /home/uid352 ++ ++dn: cn=user353,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user353 ++sn: user353 ++uid: uid353 ++givenname: givenname353 ++description: description353 ++userPassword: password353 ++mail: uid353 ++uidnumber: 353 ++gidnumber: 353 ++homeDirectory: /home/uid353 ++ ++dn: cn=user354,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user354 ++sn: user354 ++uid: uid354 ++givenname: givenname354 ++description: description354 ++userPassword: password354 ++mail: uid354 ++uidnumber: 354 ++gidnumber: 354 ++homeDirectory: /home/uid354 ++ ++dn: cn=user355,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user355 ++sn: user355 ++uid: uid355 ++givenname: givenname355 ++description: description355 ++userPassword: password355 ++mail: uid355 ++uidnumber: 355 ++gidnumber: 355 ++homeDirectory: /home/uid355 ++ ++dn: cn=user356,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user356 ++sn: user356 ++uid: uid356 ++givenname: givenname356 ++description: description356 ++userPassword: password356 ++mail: uid356 ++uidnumber: 356 ++gidnumber: 356 ++homeDirectory: /home/uid356 ++ ++dn: cn=user357,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user357 ++sn: user357 ++uid: uid357 ++givenname: givenname357 ++description: description357 ++userPassword: password357 ++mail: uid357 ++uidnumber: 357 ++gidnumber: 357 ++homeDirectory: /home/uid357 ++ ++dn: cn=user358,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user358 ++sn: user358 ++uid: uid358 ++givenname: givenname358 ++description: description358 ++userPassword: password358 ++mail: uid358 ++uidnumber: 358 ++gidnumber: 358 ++homeDirectory: /home/uid358 ++ ++dn: cn=user359,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user359 ++sn: user359 ++uid: uid359 ++givenname: givenname359 ++description: description359 ++userPassword: password359 ++mail: uid359 ++uidnumber: 359 ++gidnumber: 359 ++homeDirectory: /home/uid359 ++ ++dn: cn=user360,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user360 ++sn: user360 ++uid: uid360 ++givenname: givenname360 ++description: description360 ++userPassword: password360 ++mail: uid360 ++uidnumber: 360 ++gidnumber: 360 ++homeDirectory: /home/uid360 ++ ++dn: cn=user361,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user361 ++sn: user361 ++uid: uid361 ++givenname: givenname361 ++description: description361 ++userPassword: password361 ++mail: uid361 ++uidnumber: 361 ++gidnumber: 361 ++homeDirectory: /home/uid361 ++ ++dn: cn=user362,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user362 ++sn: user362 ++uid: uid362 ++givenname: givenname362 ++description: description362 ++userPassword: password362 ++mail: uid362 ++uidnumber: 362 ++gidnumber: 362 ++homeDirectory: /home/uid362 ++ ++dn: cn=user363,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user363 ++sn: user363 ++uid: uid363 ++givenname: givenname363 ++description: description363 ++userPassword: password363 ++mail: uid363 ++uidnumber: 363 ++gidnumber: 363 ++homeDirectory: /home/uid363 ++ ++dn: cn=user364,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user364 ++sn: user364 ++uid: uid364 ++givenname: givenname364 ++description: description364 ++userPassword: password364 ++mail: uid364 ++uidnumber: 364 ++gidnumber: 364 ++homeDirectory: /home/uid364 ++ ++dn: cn=user365,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user365 ++sn: user365 ++uid: uid365 ++givenname: givenname365 ++description: description365 ++userPassword: password365 ++mail: uid365 ++uidnumber: 365 ++gidnumber: 365 ++homeDirectory: /home/uid365 ++ ++dn: cn=user366,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user366 ++sn: user366 ++uid: uid366 ++givenname: givenname366 ++description: description366 ++userPassword: password366 ++mail: uid366 ++uidnumber: 366 ++gidnumber: 366 ++homeDirectory: /home/uid366 ++ ++dn: cn=user367,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user367 ++sn: user367 ++uid: uid367 ++givenname: givenname367 ++description: description367 ++userPassword: password367 ++mail: uid367 ++uidnumber: 367 ++gidnumber: 367 ++homeDirectory: /home/uid367 ++ ++dn: cn=user368,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user368 ++sn: user368 ++uid: uid368 ++givenname: givenname368 ++description: description368 ++userPassword: password368 ++mail: uid368 ++uidnumber: 368 ++gidnumber: 368 ++homeDirectory: /home/uid368 ++ ++dn: cn=user369,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user369 ++sn: user369 ++uid: uid369 ++givenname: givenname369 ++description: description369 ++userPassword: password369 ++mail: uid369 ++uidnumber: 369 ++gidnumber: 369 ++homeDirectory: /home/uid369 ++ ++dn: cn=user370,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user370 ++sn: user370 ++uid: uid370 ++givenname: givenname370 ++description: description370 ++userPassword: password370 ++mail: uid370 ++uidnumber: 370 ++gidnumber: 370 ++homeDirectory: /home/uid370 ++ ++dn: cn=user371,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user371 ++sn: user371 ++uid: uid371 ++givenname: givenname371 ++description: description371 ++userPassword: password371 ++mail: uid371 ++uidnumber: 371 ++gidnumber: 371 ++homeDirectory: /home/uid371 ++ ++dn: cn=user372,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user372 ++sn: user372 ++uid: uid372 ++givenname: givenname372 ++description: description372 ++userPassword: password372 ++mail: uid372 ++uidnumber: 372 ++gidnumber: 372 ++homeDirectory: /home/uid372 ++ ++dn: cn=user373,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user373 ++sn: user373 ++uid: uid373 ++givenname: givenname373 ++description: description373 ++userPassword: password373 ++mail: uid373 ++uidnumber: 373 ++gidnumber: 373 ++homeDirectory: /home/uid373 ++ ++dn: cn=user374,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user374 ++sn: user374 ++uid: uid374 ++givenname: givenname374 ++description: description374 ++userPassword: password374 ++mail: uid374 ++uidnumber: 374 ++gidnumber: 374 ++homeDirectory: /home/uid374 ++ ++dn: cn=user375,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user375 ++sn: user375 ++uid: uid375 ++givenname: givenname375 ++description: description375 ++userPassword: password375 ++mail: uid375 ++uidnumber: 375 ++gidnumber: 375 ++homeDirectory: /home/uid375 ++ ++dn: cn=user376,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user376 ++sn: user376 ++uid: uid376 ++givenname: givenname376 ++description: description376 ++userPassword: password376 ++mail: uid376 ++uidnumber: 376 ++gidnumber: 376 ++homeDirectory: /home/uid376 ++ ++dn: cn=user377,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user377 ++sn: user377 ++uid: uid377 ++givenname: givenname377 ++description: description377 ++userPassword: password377 ++mail: uid377 ++uidnumber: 377 ++gidnumber: 377 ++homeDirectory: /home/uid377 ++ ++dn: cn=user378,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user378 ++sn: user378 ++uid: uid378 ++givenname: givenname378 ++description: description378 ++userPassword: password378 ++mail: uid378 ++uidnumber: 378 ++gidnumber: 378 ++homeDirectory: /home/uid378 ++ ++dn: cn=user379,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user379 ++sn: user379 ++uid: uid379 ++givenname: givenname379 ++description: description379 ++userPassword: password379 ++mail: uid379 ++uidnumber: 379 ++gidnumber: 379 ++homeDirectory: /home/uid379 ++ ++dn: cn=user380,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user380 ++sn: user380 ++uid: uid380 ++givenname: givenname380 ++description: description380 ++userPassword: password380 ++mail: uid380 ++uidnumber: 380 ++gidnumber: 380 ++homeDirectory: /home/uid380 ++ ++dn: cn=user381,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user381 ++sn: user381 ++uid: uid381 ++givenname: givenname381 ++description: description381 ++userPassword: password381 ++mail: uid381 ++uidnumber: 381 ++gidnumber: 381 ++homeDirectory: /home/uid381 ++ ++dn: cn=user382,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user382 ++sn: user382 ++uid: uid382 ++givenname: givenname382 ++description: description382 ++userPassword: password382 ++mail: uid382 ++uidnumber: 382 ++gidnumber: 382 ++homeDirectory: /home/uid382 ++ ++dn: cn=user383,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user383 ++sn: user383 ++uid: uid383 ++givenname: givenname383 ++description: description383 ++userPassword: password383 ++mail: uid383 ++uidnumber: 383 ++gidnumber: 383 ++homeDirectory: /home/uid383 ++ ++dn: cn=user384,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user384 ++sn: user384 ++uid: uid384 ++givenname: givenname384 ++description: description384 ++userPassword: password384 ++mail: uid384 ++uidnumber: 384 ++gidnumber: 384 ++homeDirectory: /home/uid384 ++ ++dn: cn=user385,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user385 ++sn: user385 ++uid: uid385 ++givenname: givenname385 ++description: description385 ++userPassword: password385 ++mail: uid385 ++uidnumber: 385 ++gidnumber: 385 ++homeDirectory: /home/uid385 ++ ++dn: cn=user386,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user386 ++sn: user386 ++uid: uid386 ++givenname: givenname386 ++description: description386 ++userPassword: password386 ++mail: uid386 ++uidnumber: 386 ++gidnumber: 386 ++homeDirectory: /home/uid386 ++ ++dn: cn=user387,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user387 ++sn: user387 ++uid: uid387 ++givenname: givenname387 ++description: description387 ++userPassword: password387 ++mail: uid387 ++uidnumber: 387 ++gidnumber: 387 ++homeDirectory: /home/uid387 ++ ++dn: cn=user388,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user388 ++sn: user388 ++uid: uid388 ++givenname: givenname388 ++description: description388 ++userPassword: password388 ++mail: uid388 ++uidnumber: 388 ++gidnumber: 388 ++homeDirectory: /home/uid388 ++ ++dn: cn=user389,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user389 ++sn: user389 ++uid: uid389 ++givenname: givenname389 ++description: description389 ++userPassword: password389 ++mail: uid389 ++uidnumber: 389 ++gidnumber: 389 ++homeDirectory: /home/uid389 ++ ++dn: cn=user390,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user390 ++sn: user390 ++uid: uid390 ++givenname: givenname390 ++description: description390 ++userPassword: password390 ++mail: uid390 ++uidnumber: 390 ++gidnumber: 390 ++homeDirectory: /home/uid390 ++ ++dn: cn=user391,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user391 ++sn: user391 ++uid: uid391 ++givenname: givenname391 ++description: description391 ++userPassword: password391 ++mail: uid391 ++uidnumber: 391 ++gidnumber: 391 ++homeDirectory: /home/uid391 ++ ++dn: cn=user392,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user392 ++sn: user392 ++uid: uid392 ++givenname: givenname392 ++description: description392 ++userPassword: password392 ++mail: uid392 ++uidnumber: 392 ++gidnumber: 392 ++homeDirectory: /home/uid392 ++ ++dn: cn=user393,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user393 ++sn: user393 ++uid: uid393 ++givenname: givenname393 ++description: description393 ++userPassword: password393 ++mail: uid393 ++uidnumber: 393 ++gidnumber: 393 ++homeDirectory: /home/uid393 ++ ++dn: cn=user394,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user394 ++sn: user394 ++uid: uid394 ++givenname: givenname394 ++description: description394 ++userPassword: password394 ++mail: uid394 ++uidnumber: 394 ++gidnumber: 394 ++homeDirectory: /home/uid394 ++ ++dn: cn=user395,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user395 ++sn: user395 ++uid: uid395 ++givenname: givenname395 ++description: description395 ++userPassword: password395 ++mail: uid395 ++uidnumber: 395 ++gidnumber: 395 ++homeDirectory: /home/uid395 ++ ++dn: cn=user396,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user396 ++sn: user396 ++uid: uid396 ++givenname: givenname396 ++description: description396 ++userPassword: password396 ++mail: uid396 ++uidnumber: 396 ++gidnumber: 396 ++homeDirectory: /home/uid396 ++ ++dn: cn=user397,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user397 ++sn: user397 ++uid: uid397 ++givenname: givenname397 ++description: description397 ++userPassword: password397 ++mail: uid397 ++uidnumber: 397 ++gidnumber: 397 ++homeDirectory: /home/uid397 ++ ++dn: cn=user398,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user398 ++sn: user398 ++uid: uid398 ++givenname: givenname398 ++description: description398 ++userPassword: password398 ++mail: uid398 ++uidnumber: 398 ++gidnumber: 398 ++homeDirectory: /home/uid398 ++ ++dn: cn=user399,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user399 ++sn: user399 ++uid: uid399 ++givenname: givenname399 ++description: description399 ++userPassword: password399 ++mail: uid399 ++uidnumber: 399 ++gidnumber: 399 ++homeDirectory: /home/uid399 ++ ++dn: cn=user400,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user400 ++sn: user400 ++uid: uid400 ++givenname: givenname400 ++description: description400 ++userPassword: password400 ++mail: uid400 ++uidnumber: 400 ++gidnumber: 400 ++homeDirectory: /home/uid400 ++ ++dn: cn=user401,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user401 ++sn: user401 ++uid: uid401 ++givenname: givenname401 ++description: description401 ++userPassword: password401 ++mail: uid401 ++uidnumber: 401 ++gidnumber: 401 ++homeDirectory: /home/uid401 ++ ++dn: cn=user402,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user402 ++sn: user402 ++uid: uid402 ++givenname: givenname402 ++description: description402 ++userPassword: password402 ++mail: uid402 ++uidnumber: 402 ++gidnumber: 402 ++homeDirectory: /home/uid402 ++ ++dn: cn=user403,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user403 ++sn: user403 ++uid: uid403 ++givenname: givenname403 ++description: description403 ++userPassword: password403 ++mail: uid403 ++uidnumber: 403 ++gidnumber: 403 ++homeDirectory: /home/uid403 ++ ++dn: cn=user404,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user404 ++sn: user404 ++uid: uid404 ++givenname: givenname404 ++description: description404 ++userPassword: password404 ++mail: uid404 ++uidnumber: 404 ++gidnumber: 404 ++homeDirectory: /home/uid404 ++ ++dn: cn=user405,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user405 ++sn: user405 ++uid: uid405 ++givenname: givenname405 ++description: description405 ++userPassword: password405 ++mail: uid405 ++uidnumber: 405 ++gidnumber: 405 ++homeDirectory: /home/uid405 ++ ++dn: cn=user406,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user406 ++sn: user406 ++uid: uid406 ++givenname: givenname406 ++description: description406 ++userPassword: password406 ++mail: uid406 ++uidnumber: 406 ++gidnumber: 406 ++homeDirectory: /home/uid406 ++ ++dn: cn=user407,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user407 ++sn: user407 ++uid: uid407 ++givenname: givenname407 ++description: description407 ++userPassword: password407 ++mail: uid407 ++uidnumber: 407 ++gidnumber: 407 ++homeDirectory: /home/uid407 ++ ++dn: cn=user408,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user408 ++sn: user408 ++uid: uid408 ++givenname: givenname408 ++description: description408 ++userPassword: password408 ++mail: uid408 ++uidnumber: 408 ++gidnumber: 408 ++homeDirectory: /home/uid408 ++ ++dn: cn=user409,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user409 ++sn: user409 ++uid: uid409 ++givenname: givenname409 ++description: description409 ++userPassword: password409 ++mail: uid409 ++uidnumber: 409 ++gidnumber: 409 ++homeDirectory: /home/uid409 ++ ++dn: cn=user410,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user410 ++sn: user410 ++uid: uid410 ++givenname: givenname410 ++description: description410 ++userPassword: password410 ++mail: uid410 ++uidnumber: 410 ++gidnumber: 410 ++homeDirectory: /home/uid410 ++ ++dn: cn=user411,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user411 ++sn: user411 ++uid: uid411 ++givenname: givenname411 ++description: description411 ++userPassword: password411 ++mail: uid411 ++uidnumber: 411 ++gidnumber: 411 ++homeDirectory: /home/uid411 ++ ++dn: cn=user412,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user412 ++sn: user412 ++uid: uid412 ++givenname: givenname412 ++description: description412 ++userPassword: password412 ++mail: uid412 ++uidnumber: 412 ++gidnumber: 412 ++homeDirectory: /home/uid412 ++ ++dn: cn=user413,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user413 ++sn: user413 ++uid: uid413 ++givenname: givenname413 ++description: description413 ++userPassword: password413 ++mail: uid413 ++uidnumber: 413 ++gidnumber: 413 ++homeDirectory: /home/uid413 ++ ++dn: cn=user414,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user414 ++sn: user414 ++uid: uid414 ++givenname: givenname414 ++description: description414 ++userPassword: password414 ++mail: uid414 ++uidnumber: 414 ++gidnumber: 414 ++homeDirectory: /home/uid414 ++ ++dn: cn=user415,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user415 ++sn: user415 ++uid: uid415 ++givenname: givenname415 ++description: description415 ++userPassword: password415 ++mail: uid415 ++uidnumber: 415 ++gidnumber: 415 ++homeDirectory: /home/uid415 ++ ++dn: cn=user416,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user416 ++sn: user416 ++uid: uid416 ++givenname: givenname416 ++description: description416 ++userPassword: password416 ++mail: uid416 ++uidnumber: 416 ++gidnumber: 416 ++homeDirectory: /home/uid416 ++ ++dn: cn=user417,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user417 ++sn: user417 ++uid: uid417 ++givenname: givenname417 ++description: description417 ++userPassword: password417 ++mail: uid417 ++uidnumber: 417 ++gidnumber: 417 ++homeDirectory: /home/uid417 ++ ++dn: cn=user418,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user418 ++sn: user418 ++uid: uid418 ++givenname: givenname418 ++description: description418 ++userPassword: password418 ++mail: uid418 ++uidnumber: 418 ++gidnumber: 418 ++homeDirectory: /home/uid418 ++ ++dn: cn=user419,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user419 ++sn: user419 ++uid: uid419 ++givenname: givenname419 ++description: description419 ++userPassword: password419 ++mail: uid419 ++uidnumber: 419 ++gidnumber: 419 ++homeDirectory: /home/uid419 ++ ++dn: cn=user420,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user420 ++sn: user420 ++uid: uid420 ++givenname: givenname420 ++description: description420 ++userPassword: password420 ++mail: uid420 ++uidnumber: 420 ++gidnumber: 420 ++homeDirectory: /home/uid420 ++ ++dn: cn=user421,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user421 ++sn: user421 ++uid: uid421 ++givenname: givenname421 ++description: description421 ++userPassword: password421 ++mail: uid421 ++uidnumber: 421 ++gidnumber: 421 ++homeDirectory: /home/uid421 ++ ++dn: cn=user422,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user422 ++sn: user422 ++uid: uid422 ++givenname: givenname422 ++description: description422 ++userPassword: password422 ++mail: uid422 ++uidnumber: 422 ++gidnumber: 422 ++homeDirectory: /home/uid422 ++ ++dn: cn=user423,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user423 ++sn: user423 ++uid: uid423 ++givenname: givenname423 ++description: description423 ++userPassword: password423 ++mail: uid423 ++uidnumber: 423 ++gidnumber: 423 ++homeDirectory: /home/uid423 ++ ++dn: cn=user424,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user424 ++sn: user424 ++uid: uid424 ++givenname: givenname424 ++description: description424 ++userPassword: password424 ++mail: uid424 ++uidnumber: 424 ++gidnumber: 424 ++homeDirectory: /home/uid424 ++ ++dn: cn=user425,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user425 ++sn: user425 ++uid: uid425 ++givenname: givenname425 ++description: description425 ++userPassword: password425 ++mail: uid425 ++uidnumber: 425 ++gidnumber: 425 ++homeDirectory: /home/uid425 ++ ++dn: cn=user426,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user426 ++sn: user426 ++uid: uid426 ++givenname: givenname426 ++description: description426 ++userPassword: password426 ++mail: uid426 ++uidnumber: 426 ++gidnumber: 426 ++homeDirectory: /home/uid426 ++ ++dn: cn=user427,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user427 ++sn: user427 ++uid: uid427 ++givenname: givenname427 ++description: description427 ++userPassword: password427 ++mail: uid427 ++uidnumber: 427 ++gidnumber: 427 ++homeDirectory: /home/uid427 ++ ++dn: cn=user428,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user428 ++sn: user428 ++uid: uid428 ++givenname: givenname428 ++description: description428 ++userPassword: password428 ++mail: uid428 ++uidnumber: 428 ++gidnumber: 428 ++homeDirectory: /home/uid428 ++ ++dn: cn=user429,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user429 ++sn: user429 ++uid: uid429 ++givenname: givenname429 ++description: description429 ++userPassword: password429 ++mail: uid429 ++uidnumber: 429 ++gidnumber: 429 ++homeDirectory: /home/uid429 ++ ++dn: cn=user430,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user430 ++sn: user430 ++uid: uid430 ++givenname: givenname430 ++description: description430 ++userPassword: password430 ++mail: uid430 ++uidnumber: 430 ++gidnumber: 430 ++homeDirectory: /home/uid430 ++ ++dn: cn=user431,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user431 ++sn: user431 ++uid: uid431 ++givenname: givenname431 ++description: description431 ++userPassword: password431 ++mail: uid431 ++uidnumber: 431 ++gidnumber: 431 ++homeDirectory: /home/uid431 ++ ++dn: cn=user432,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user432 ++sn: user432 ++uid: uid432 ++givenname: givenname432 ++description: description432 ++userPassword: password432 ++mail: uid432 ++uidnumber: 432 ++gidnumber: 432 ++homeDirectory: /home/uid432 ++ ++dn: cn=user433,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user433 ++sn: user433 ++uid: uid433 ++givenname: givenname433 ++description: description433 ++userPassword: password433 ++mail: uid433 ++uidnumber: 433 ++gidnumber: 433 ++homeDirectory: /home/uid433 ++ ++dn: cn=user434,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user434 ++sn: user434 ++uid: uid434 ++givenname: givenname434 ++description: description434 ++userPassword: password434 ++mail: uid434 ++uidnumber: 434 ++gidnumber: 434 ++homeDirectory: /home/uid434 ++ ++dn: cn=user435,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user435 ++sn: user435 ++uid: uid435 ++givenname: givenname435 ++description: description435 ++userPassword: password435 ++mail: uid435 ++uidnumber: 435 ++gidnumber: 435 ++homeDirectory: /home/uid435 ++ ++dn: cn=user436,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user436 ++sn: user436 ++uid: uid436 ++givenname: givenname436 ++description: description436 ++userPassword: password436 ++mail: uid436 ++uidnumber: 436 ++gidnumber: 436 ++homeDirectory: /home/uid436 ++ ++dn: cn=user437,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user437 ++sn: user437 ++uid: uid437 ++givenname: givenname437 ++description: description437 ++userPassword: password437 ++mail: uid437 ++uidnumber: 437 ++gidnumber: 437 ++homeDirectory: /home/uid437 ++ ++dn: cn=user438,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user438 ++sn: user438 ++uid: uid438 ++givenname: givenname438 ++description: description438 ++userPassword: password438 ++mail: uid438 ++uidnumber: 438 ++gidnumber: 438 ++homeDirectory: /home/uid438 ++ ++dn: cn=user439,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user439 ++sn: user439 ++uid: uid439 ++givenname: givenname439 ++description: description439 ++userPassword: password439 ++mail: uid439 ++uidnumber: 439 ++gidnumber: 439 ++homeDirectory: /home/uid439 ++ ++dn: cn=user440,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user440 ++sn: user440 ++uid: uid440 ++givenname: givenname440 ++description: description440 ++userPassword: password440 ++mail: uid440 ++uidnumber: 440 ++gidnumber: 440 ++homeDirectory: /home/uid440 ++ ++dn: cn=user441,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user441 ++sn: user441 ++uid: uid441 ++givenname: givenname441 ++description: description441 ++userPassword: password441 ++mail: uid441 ++uidnumber: 441 ++gidnumber: 441 ++homeDirectory: /home/uid441 ++ ++dn: cn=user442,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user442 ++sn: user442 ++uid: uid442 ++givenname: givenname442 ++description: description442 ++userPassword: password442 ++mail: uid442 ++uidnumber: 442 ++gidnumber: 442 ++homeDirectory: /home/uid442 ++ ++dn: cn=user443,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user443 ++sn: user443 ++uid: uid443 ++givenname: givenname443 ++description: description443 ++userPassword: password443 ++mail: uid443 ++uidnumber: 443 ++gidnumber: 443 ++homeDirectory: /home/uid443 ++ ++dn: cn=user444,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user444 ++sn: user444 ++uid: uid444 ++givenname: givenname444 ++description: description444 ++userPassword: password444 ++mail: uid444 ++uidnumber: 444 ++gidnumber: 444 ++homeDirectory: /home/uid444 ++ ++dn: cn=user445,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user445 ++sn: user445 ++uid: uid445 ++givenname: givenname445 ++description: description445 ++userPassword: password445 ++mail: uid445 ++uidnumber: 445 ++gidnumber: 445 ++homeDirectory: /home/uid445 ++ ++dn: cn=user446,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user446 ++sn: user446 ++uid: uid446 ++givenname: givenname446 ++description: description446 ++userPassword: password446 ++mail: uid446 ++uidnumber: 446 ++gidnumber: 446 ++homeDirectory: /home/uid446 ++ ++dn: cn=user447,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user447 ++sn: user447 ++uid: uid447 ++givenname: givenname447 ++description: description447 ++userPassword: password447 ++mail: uid447 ++uidnumber: 447 ++gidnumber: 447 ++homeDirectory: /home/uid447 ++ ++dn: cn=user448,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user448 ++sn: user448 ++uid: uid448 ++givenname: givenname448 ++description: description448 ++userPassword: password448 ++mail: uid448 ++uidnumber: 448 ++gidnumber: 448 ++homeDirectory: /home/uid448 ++ ++dn: cn=user449,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user449 ++sn: user449 ++uid: uid449 ++givenname: givenname449 ++description: description449 ++userPassword: password449 ++mail: uid449 ++uidnumber: 449 ++gidnumber: 449 ++homeDirectory: /home/uid449 ++ ++dn: cn=user450,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user450 ++sn: user450 ++uid: uid450 ++givenname: givenname450 ++description: description450 ++userPassword: password450 ++mail: uid450 ++uidnumber: 450 ++gidnumber: 450 ++homeDirectory: /home/uid450 ++ ++dn: cn=user451,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user451 ++sn: user451 ++uid: uid451 ++givenname: givenname451 ++description: description451 ++userPassword: password451 ++mail: uid451 ++uidnumber: 451 ++gidnumber: 451 ++homeDirectory: /home/uid451 ++ ++dn: cn=user452,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user452 ++sn: user452 ++uid: uid452 ++givenname: givenname452 ++description: description452 ++userPassword: password452 ++mail: uid452 ++uidnumber: 452 ++gidnumber: 452 ++homeDirectory: /home/uid452 ++ ++dn: cn=user453,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user453 ++sn: user453 ++uid: uid453 ++givenname: givenname453 ++description: description453 ++userPassword: password453 ++mail: uid453 ++uidnumber: 453 ++gidnumber: 453 ++homeDirectory: /home/uid453 ++ ++dn: cn=user454,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user454 ++sn: user454 ++uid: uid454 ++givenname: givenname454 ++description: description454 ++userPassword: password454 ++mail: uid454 ++uidnumber: 454 ++gidnumber: 454 ++homeDirectory: /home/uid454 ++ ++dn: cn=user455,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user455 ++sn: user455 ++uid: uid455 ++givenname: givenname455 ++description: description455 ++userPassword: password455 ++mail: uid455 ++uidnumber: 455 ++gidnumber: 455 ++homeDirectory: /home/uid455 ++ ++dn: cn=user456,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user456 ++sn: user456 ++uid: uid456 ++givenname: givenname456 ++description: description456 ++userPassword: password456 ++mail: uid456 ++uidnumber: 456 ++gidnumber: 456 ++homeDirectory: /home/uid456 ++ ++dn: cn=user457,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user457 ++sn: user457 ++uid: uid457 ++givenname: givenname457 ++description: description457 ++userPassword: password457 ++mail: uid457 ++uidnumber: 457 ++gidnumber: 457 ++homeDirectory: /home/uid457 ++ ++dn: cn=user458,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user458 ++sn: user458 ++uid: uid458 ++givenname: givenname458 ++description: description458 ++userPassword: password458 ++mail: uid458 ++uidnumber: 458 ++gidnumber: 458 ++homeDirectory: /home/uid458 ++ ++dn: cn=user459,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user459 ++sn: user459 ++uid: uid459 ++givenname: givenname459 ++description: description459 ++userPassword: password459 ++mail: uid459 ++uidnumber: 459 ++gidnumber: 459 ++homeDirectory: /home/uid459 ++ ++dn: cn=user460,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user460 ++sn: user460 ++uid: uid460 ++givenname: givenname460 ++description: description460 ++userPassword: password460 ++mail: uid460 ++uidnumber: 460 ++gidnumber: 460 ++homeDirectory: /home/uid460 ++ ++dn: cn=user461,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user461 ++sn: user461 ++uid: uid461 ++givenname: givenname461 ++description: description461 ++userPassword: password461 ++mail: uid461 ++uidnumber: 461 ++gidnumber: 461 ++homeDirectory: /home/uid461 ++ ++dn: cn=user462,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user462 ++sn: user462 ++uid: uid462 ++givenname: givenname462 ++description: description462 ++userPassword: password462 ++mail: uid462 ++uidnumber: 462 ++gidnumber: 462 ++homeDirectory: /home/uid462 ++ ++dn: cn=user463,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user463 ++sn: user463 ++uid: uid463 ++givenname: givenname463 ++description: description463 ++userPassword: password463 ++mail: uid463 ++uidnumber: 463 ++gidnumber: 463 ++homeDirectory: /home/uid463 ++ ++dn: cn=user464,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user464 ++sn: user464 ++uid: uid464 ++givenname: givenname464 ++description: description464 ++userPassword: password464 ++mail: uid464 ++uidnumber: 464 ++gidnumber: 464 ++homeDirectory: /home/uid464 ++ ++dn: cn=user465,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user465 ++sn: user465 ++uid: uid465 ++givenname: givenname465 ++description: description465 ++userPassword: password465 ++mail: uid465 ++uidnumber: 465 ++gidnumber: 465 ++homeDirectory: /home/uid465 ++ ++dn: cn=user466,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user466 ++sn: user466 ++uid: uid466 ++givenname: givenname466 ++description: description466 ++userPassword: password466 ++mail: uid466 ++uidnumber: 466 ++gidnumber: 466 ++homeDirectory: /home/uid466 ++ ++dn: cn=user467,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user467 ++sn: user467 ++uid: uid467 ++givenname: givenname467 ++description: description467 ++userPassword: password467 ++mail: uid467 ++uidnumber: 467 ++gidnumber: 467 ++homeDirectory: /home/uid467 ++ ++dn: cn=user468,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user468 ++sn: user468 ++uid: uid468 ++givenname: givenname468 ++description: description468 ++userPassword: password468 ++mail: uid468 ++uidnumber: 468 ++gidnumber: 468 ++homeDirectory: /home/uid468 ++ ++dn: cn=user469,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user469 ++sn: user469 ++uid: uid469 ++givenname: givenname469 ++description: description469 ++userPassword: password469 ++mail: uid469 ++uidnumber: 469 ++gidnumber: 469 ++homeDirectory: /home/uid469 ++ ++dn: cn=user470,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user470 ++sn: user470 ++uid: uid470 ++givenname: givenname470 ++description: description470 ++userPassword: password470 ++mail: uid470 ++uidnumber: 470 ++gidnumber: 470 ++homeDirectory: /home/uid470 ++ ++dn: cn=user471,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user471 ++sn: user471 ++uid: uid471 ++givenname: givenname471 ++description: description471 ++userPassword: password471 ++mail: uid471 ++uidnumber: 471 ++gidnumber: 471 ++homeDirectory: /home/uid471 ++ ++dn: cn=user472,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user472 ++sn: user472 ++uid: uid472 ++givenname: givenname472 ++description: description472 ++userPassword: password472 ++mail: uid472 ++uidnumber: 472 ++gidnumber: 472 ++homeDirectory: /home/uid472 ++ ++dn: cn=user473,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user473 ++sn: user473 ++uid: uid473 ++givenname: givenname473 ++description: description473 ++userPassword: password473 ++mail: uid473 ++uidnumber: 473 ++gidnumber: 473 ++homeDirectory: /home/uid473 ++ ++dn: cn=user474,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user474 ++sn: user474 ++uid: uid474 ++givenname: givenname474 ++description: description474 ++userPassword: password474 ++mail: uid474 ++uidnumber: 474 ++gidnumber: 474 ++homeDirectory: /home/uid474 ++ ++dn: cn=user475,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user475 ++sn: user475 ++uid: uid475 ++givenname: givenname475 ++description: description475 ++userPassword: password475 ++mail: uid475 ++uidnumber: 475 ++gidnumber: 475 ++homeDirectory: /home/uid475 ++ ++dn: cn=user476,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user476 ++sn: user476 ++uid: uid476 ++givenname: givenname476 ++description: description476 ++userPassword: password476 ++mail: uid476 ++uidnumber: 476 ++gidnumber: 476 ++homeDirectory: /home/uid476 ++ ++dn: cn=user477,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user477 ++sn: user477 ++uid: uid477 ++givenname: givenname477 ++description: description477 ++userPassword: password477 ++mail: uid477 ++uidnumber: 477 ++gidnumber: 477 ++homeDirectory: /home/uid477 ++ ++dn: cn=user478,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user478 ++sn: user478 ++uid: uid478 ++givenname: givenname478 ++description: description478 ++userPassword: password478 ++mail: uid478 ++uidnumber: 478 ++gidnumber: 478 ++homeDirectory: /home/uid478 ++ ++dn: cn=user479,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user479 ++sn: user479 ++uid: uid479 ++givenname: givenname479 ++description: description479 ++userPassword: password479 ++mail: uid479 ++uidnumber: 479 ++gidnumber: 479 ++homeDirectory: /home/uid479 ++ ++dn: cn=user480,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user480 ++sn: user480 ++uid: uid480 ++givenname: givenname480 ++description: description480 ++userPassword: password480 ++mail: uid480 ++uidnumber: 480 ++gidnumber: 480 ++homeDirectory: /home/uid480 ++ ++dn: cn=user481,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user481 ++sn: user481 ++uid: uid481 ++givenname: givenname481 ++description: description481 ++userPassword: password481 ++mail: uid481 ++uidnumber: 481 ++gidnumber: 481 ++homeDirectory: /home/uid481 ++ ++dn: cn=user482,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user482 ++sn: user482 ++uid: uid482 ++givenname: givenname482 ++description: description482 ++userPassword: password482 ++mail: uid482 ++uidnumber: 482 ++gidnumber: 482 ++homeDirectory: /home/uid482 ++ ++dn: cn=user483,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user483 ++sn: user483 ++uid: uid483 ++givenname: givenname483 ++description: description483 ++userPassword: password483 ++mail: uid483 ++uidnumber: 483 ++gidnumber: 483 ++homeDirectory: /home/uid483 ++ ++dn: cn=user484,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user484 ++sn: user484 ++uid: uid484 ++givenname: givenname484 ++description: description484 ++userPassword: password484 ++mail: uid484 ++uidnumber: 484 ++gidnumber: 484 ++homeDirectory: /home/uid484 ++ ++dn: cn=user485,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user485 ++sn: user485 ++uid: uid485 ++givenname: givenname485 ++description: description485 ++userPassword: password485 ++mail: uid485 ++uidnumber: 485 ++gidnumber: 485 ++homeDirectory: /home/uid485 ++ ++dn: cn=user486,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user486 ++sn: user486 ++uid: uid486 ++givenname: givenname486 ++description: description486 ++userPassword: password486 ++mail: uid486 ++uidnumber: 486 ++gidnumber: 486 ++homeDirectory: /home/uid486 ++ ++dn: cn=user487,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user487 ++sn: user487 ++uid: uid487 ++givenname: givenname487 ++description: description487 ++userPassword: password487 ++mail: uid487 ++uidnumber: 487 ++gidnumber: 487 ++homeDirectory: /home/uid487 ++ ++dn: cn=user488,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user488 ++sn: user488 ++uid: uid488 ++givenname: givenname488 ++description: description488 ++userPassword: password488 ++mail: uid488 ++uidnumber: 488 ++gidnumber: 488 ++homeDirectory: /home/uid488 ++ ++dn: cn=user489,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user489 ++sn: user489 ++uid: uid489 ++givenname: givenname489 ++description: description489 ++userPassword: password489 ++mail: uid489 ++uidnumber: 489 ++gidnumber: 489 ++homeDirectory: /home/uid489 ++ ++dn: cn=user490,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user490 ++sn: user490 ++uid: uid490 ++givenname: givenname490 ++description: description490 ++userPassword: password490 ++mail: uid490 ++uidnumber: 490 ++gidnumber: 490 ++homeDirectory: /home/uid490 ++ ++dn: cn=user491,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user491 ++sn: user491 ++uid: uid491 ++givenname: givenname491 ++description: description491 ++userPassword: password491 ++mail: uid491 ++uidnumber: 491 ++gidnumber: 491 ++homeDirectory: /home/uid491 ++ ++dn: cn=user492,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user492 ++sn: user492 ++uid: uid492 ++givenname: givenname492 ++description: description492 ++userPassword: password492 ++mail: uid492 ++uidnumber: 492 ++gidnumber: 492 ++homeDirectory: /home/uid492 ++ ++dn: cn=user493,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user493 ++sn: user493 ++uid: uid493 ++givenname: givenname493 ++description: description493 ++userPassword: password493 ++mail: uid493 ++uidnumber: 493 ++gidnumber: 493 ++homeDirectory: /home/uid493 ++ ++dn: cn=user494,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user494 ++sn: user494 ++uid: uid494 ++givenname: givenname494 ++description: description494 ++userPassword: password494 ++mail: uid494 ++uidnumber: 494 ++gidnumber: 494 ++homeDirectory: /home/uid494 ++ ++dn: cn=user495,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user495 ++sn: user495 ++uid: uid495 ++givenname: givenname495 ++description: description495 ++userPassword: password495 ++mail: uid495 ++uidnumber: 495 ++gidnumber: 495 ++homeDirectory: /home/uid495 ++ ++dn: cn=user496,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user496 ++sn: user496 ++uid: uid496 ++givenname: givenname496 ++description: description496 ++userPassword: password496 ++mail: uid496 ++uidnumber: 496 ++gidnumber: 496 ++homeDirectory: /home/uid496 ++ ++dn: cn=user497,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user497 ++sn: user497 ++uid: uid497 ++givenname: givenname497 ++description: description497 ++userPassword: password497 ++mail: uid497 ++uidnumber: 497 ++gidnumber: 497 ++homeDirectory: /home/uid497 ++ ++dn: cn=user498,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user498 ++sn: user498 ++uid: uid498 ++givenname: givenname498 ++description: description498 ++userPassword: password498 ++mail: uid498 ++uidnumber: 498 ++gidnumber: 498 ++homeDirectory: /home/uid498 ++ ++dn: cn=user499,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user499 ++sn: user499 ++uid: uid499 ++givenname: givenname499 ++description: description499 ++userPassword: password499 ++mail: uid499 ++uidnumber: 499 ++gidnumber: 499 ++homeDirectory: /home/uid499 ++ ++dn: cn=user500,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user500 ++sn: user500 ++uid: uid500 ++givenname: givenname500 ++description: description500 ++userPassword: password500 ++mail: uid500 ++uidnumber: 500 ++gidnumber: 500 ++homeDirectory: /home/uid500 ++ ++dn: cn=user501,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user501 ++sn: user501 ++uid: uid501 ++givenname: givenname501 ++description: description501 ++userPassword: password501 ++mail: uid501 ++uidnumber: 501 ++gidnumber: 501 ++homeDirectory: /home/uid501 ++ ++dn: cn=user502,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user502 ++sn: user502 ++uid: uid502 ++givenname: givenname502 ++description: description502 ++userPassword: password502 ++mail: uid502 ++uidnumber: 502 ++gidnumber: 502 ++homeDirectory: /home/uid502 ++ ++dn: cn=user503,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user503 ++sn: user503 ++uid: uid503 ++givenname: givenname503 ++description: description503 ++userPassword: password503 ++mail: uid503 ++uidnumber: 503 ++gidnumber: 503 ++homeDirectory: /home/uid503 ++ ++dn: cn=user504,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user504 ++sn: user504 ++uid: uid504 ++givenname: givenname504 ++description: description504 ++userPassword: password504 ++mail: uid504 ++uidnumber: 504 ++gidnumber: 504 ++homeDirectory: /home/uid504 ++ ++dn: cn=user505,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user505 ++sn: user505 ++uid: uid505 ++givenname: givenname505 ++description: description505 ++userPassword: password505 ++mail: uid505 ++uidnumber: 505 ++gidnumber: 505 ++homeDirectory: /home/uid505 ++ ++dn: cn=user506,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user506 ++sn: user506 ++uid: uid506 ++givenname: givenname506 ++description: description506 ++userPassword: password506 ++mail: uid506 ++uidnumber: 506 ++gidnumber: 506 ++homeDirectory: /home/uid506 ++ ++dn: cn=user507,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user507 ++sn: user507 ++uid: uid507 ++givenname: givenname507 ++description: description507 ++userPassword: password507 ++mail: uid507 ++uidnumber: 507 ++gidnumber: 507 ++homeDirectory: /home/uid507 ++ ++dn: cn=user508,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user508 ++sn: user508 ++uid: uid508 ++givenname: givenname508 ++description: description508 ++userPassword: password508 ++mail: uid508 ++uidnumber: 508 ++gidnumber: 508 ++homeDirectory: /home/uid508 ++ ++dn: cn=user509,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user509 ++sn: user509 ++uid: uid509 ++givenname: givenname509 ++description: description509 ++userPassword: password509 ++mail: uid509 ++uidnumber: 509 ++gidnumber: 509 ++homeDirectory: /home/uid509 ++ ++dn: cn=user510,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user510 ++sn: user510 ++uid: uid510 ++givenname: givenname510 ++description: description510 ++userPassword: password510 ++mail: uid510 ++uidnumber: 510 ++gidnumber: 510 ++homeDirectory: /home/uid510 ++ ++dn: cn=user511,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user511 ++sn: user511 ++uid: uid511 ++givenname: givenname511 ++description: description511 ++userPassword: password511 ++mail: uid511 ++uidnumber: 511 ++gidnumber: 511 ++homeDirectory: /home/uid511 ++ ++dn: cn=user512,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user512 ++sn: user512 ++uid: uid512 ++givenname: givenname512 ++description: description512 ++userPassword: password512 ++mail: uid512 ++uidnumber: 512 ++gidnumber: 512 ++homeDirectory: /home/uid512 ++ ++dn: cn=user513,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user513 ++sn: user513 ++uid: uid513 ++givenname: givenname513 ++description: description513 ++userPassword: password513 ++mail: uid513 ++uidnumber: 513 ++gidnumber: 513 ++homeDirectory: /home/uid513 ++ ++dn: cn=user514,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user514 ++sn: user514 ++uid: uid514 ++givenname: givenname514 ++description: description514 ++userPassword: password514 ++mail: uid514 ++uidnumber: 514 ++gidnumber: 514 ++homeDirectory: /home/uid514 ++ ++dn: cn=user515,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user515 ++sn: user515 ++uid: uid515 ++givenname: givenname515 ++description: description515 ++userPassword: password515 ++mail: uid515 ++uidnumber: 515 ++gidnumber: 515 ++homeDirectory: /home/uid515 ++ ++dn: cn=user516,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user516 ++sn: user516 ++uid: uid516 ++givenname: givenname516 ++description: description516 ++userPassword: password516 ++mail: uid516 ++uidnumber: 516 ++gidnumber: 516 ++homeDirectory: /home/uid516 ++ ++dn: cn=user517,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user517 ++sn: user517 ++uid: uid517 ++givenname: givenname517 ++description: description517 ++userPassword: password517 ++mail: uid517 ++uidnumber: 517 ++gidnumber: 517 ++homeDirectory: /home/uid517 ++ ++dn: cn=user518,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user518 ++sn: user518 ++uid: uid518 ++givenname: givenname518 ++description: description518 ++userPassword: password518 ++mail: uid518 ++uidnumber: 518 ++gidnumber: 518 ++homeDirectory: /home/uid518 ++ ++dn: cn=user519,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user519 ++sn: user519 ++uid: uid519 ++givenname: givenname519 ++description: description519 ++userPassword: password519 ++mail: uid519 ++uidnumber: 519 ++gidnumber: 519 ++homeDirectory: /home/uid519 ++ ++dn: cn=user520,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user520 ++sn: user520 ++uid: uid520 ++givenname: givenname520 ++description: description520 ++userPassword: password520 ++mail: uid520 ++uidnumber: 520 ++gidnumber: 520 ++homeDirectory: /home/uid520 ++ ++dn: cn=user521,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user521 ++sn: user521 ++uid: uid521 ++givenname: givenname521 ++description: description521 ++userPassword: password521 ++mail: uid521 ++uidnumber: 521 ++gidnumber: 521 ++homeDirectory: /home/uid521 ++ ++dn: cn=user522,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user522 ++sn: user522 ++uid: uid522 ++givenname: givenname522 ++description: description522 ++userPassword: password522 ++mail: uid522 ++uidnumber: 522 ++gidnumber: 522 ++homeDirectory: /home/uid522 ++ ++dn: cn=user523,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user523 ++sn: user523 ++uid: uid523 ++givenname: givenname523 ++description: description523 ++userPassword: password523 ++mail: uid523 ++uidnumber: 523 ++gidnumber: 523 ++homeDirectory: /home/uid523 ++ ++dn: cn=user524,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user524 ++sn: user524 ++uid: uid524 ++givenname: givenname524 ++description: description524 ++userPassword: password524 ++mail: uid524 ++uidnumber: 524 ++gidnumber: 524 ++homeDirectory: /home/uid524 ++ ++dn: cn=user525,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user525 ++sn: user525 ++uid: uid525 ++givenname: givenname525 ++description: description525 ++userPassword: password525 ++mail: uid525 ++uidnumber: 525 ++gidnumber: 525 ++homeDirectory: /home/uid525 ++ ++dn: cn=user526,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user526 ++sn: user526 ++uid: uid526 ++givenname: givenname526 ++description: description526 ++userPassword: password526 ++mail: uid526 ++uidnumber: 526 ++gidnumber: 526 ++homeDirectory: /home/uid526 ++ ++dn: cn=user527,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user527 ++sn: user527 ++uid: uid527 ++givenname: givenname527 ++description: description527 ++userPassword: password527 ++mail: uid527 ++uidnumber: 527 ++gidnumber: 527 ++homeDirectory: /home/uid527 ++ ++dn: cn=user528,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user528 ++sn: user528 ++uid: uid528 ++givenname: givenname528 ++description: description528 ++userPassword: password528 ++mail: uid528 ++uidnumber: 528 ++gidnumber: 528 ++homeDirectory: /home/uid528 ++ ++dn: cn=user529,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user529 ++sn: user529 ++uid: uid529 ++givenname: givenname529 ++description: description529 ++userPassword: password529 ++mail: uid529 ++uidnumber: 529 ++gidnumber: 529 ++homeDirectory: /home/uid529 ++ ++dn: cn=user530,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user530 ++sn: user530 ++uid: uid530 ++givenname: givenname530 ++description: description530 ++userPassword: password530 ++mail: uid530 ++uidnumber: 530 ++gidnumber: 530 ++homeDirectory: /home/uid530 ++ ++dn: cn=user531,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user531 ++sn: user531 ++uid: uid531 ++givenname: givenname531 ++description: description531 ++userPassword: password531 ++mail: uid531 ++uidnumber: 531 ++gidnumber: 531 ++homeDirectory: /home/uid531 ++ ++dn: cn=user532,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user532 ++sn: user532 ++uid: uid532 ++givenname: givenname532 ++description: description532 ++userPassword: password532 ++mail: uid532 ++uidnumber: 532 ++gidnumber: 532 ++homeDirectory: /home/uid532 ++ ++dn: cn=user533,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user533 ++sn: user533 ++uid: uid533 ++givenname: givenname533 ++description: description533 ++userPassword: password533 ++mail: uid533 ++uidnumber: 533 ++gidnumber: 533 ++homeDirectory: /home/uid533 ++ ++dn: cn=user534,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user534 ++sn: user534 ++uid: uid534 ++givenname: givenname534 ++description: description534 ++userPassword: password534 ++mail: uid534 ++uidnumber: 534 ++gidnumber: 534 ++homeDirectory: /home/uid534 ++ ++dn: cn=user535,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user535 ++sn: user535 ++uid: uid535 ++givenname: givenname535 ++description: description535 ++userPassword: password535 ++mail: uid535 ++uidnumber: 535 ++gidnumber: 535 ++homeDirectory: /home/uid535 ++ ++dn: cn=user536,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user536 ++sn: user536 ++uid: uid536 ++givenname: givenname536 ++description: description536 ++userPassword: password536 ++mail: uid536 ++uidnumber: 536 ++gidnumber: 536 ++homeDirectory: /home/uid536 ++ ++dn: cn=user537,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user537 ++sn: user537 ++uid: uid537 ++givenname: givenname537 ++description: description537 ++userPassword: password537 ++mail: uid537 ++uidnumber: 537 ++gidnumber: 537 ++homeDirectory: /home/uid537 ++ ++dn: cn=user538,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user538 ++sn: user538 ++uid: uid538 ++givenname: givenname538 ++description: description538 ++userPassword: password538 ++mail: uid538 ++uidnumber: 538 ++gidnumber: 538 ++homeDirectory: /home/uid538 ++ ++dn: cn=user539,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user539 ++sn: user539 ++uid: uid539 ++givenname: givenname539 ++description: description539 ++userPassword: password539 ++mail: uid539 ++uidnumber: 539 ++gidnumber: 539 ++homeDirectory: /home/uid539 ++ ++dn: cn=user540,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user540 ++sn: user540 ++uid: uid540 ++givenname: givenname540 ++description: description540 ++userPassword: password540 ++mail: uid540 ++uidnumber: 540 ++gidnumber: 540 ++homeDirectory: /home/uid540 ++ ++dn: cn=user541,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user541 ++sn: user541 ++uid: uid541 ++givenname: givenname541 ++description: description541 ++userPassword: password541 ++mail: uid541 ++uidnumber: 541 ++gidnumber: 541 ++homeDirectory: /home/uid541 ++ ++dn: cn=user542,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user542 ++sn: user542 ++uid: uid542 ++givenname: givenname542 ++description: description542 ++userPassword: password542 ++mail: uid542 ++uidnumber: 542 ++gidnumber: 542 ++homeDirectory: /home/uid542 ++ ++dn: cn=user543,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user543 ++sn: user543 ++uid: uid543 ++givenname: givenname543 ++description: description543 ++userPassword: password543 ++mail: uid543 ++uidnumber: 543 ++gidnumber: 543 ++homeDirectory: /home/uid543 ++ ++dn: cn=user544,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user544 ++sn: user544 ++uid: uid544 ++givenname: givenname544 ++description: description544 ++userPassword: password544 ++mail: uid544 ++uidnumber: 544 ++gidnumber: 544 ++homeDirectory: /home/uid544 ++ ++dn: cn=user545,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user545 ++sn: user545 ++uid: uid545 ++givenname: givenname545 ++description: description545 ++userPassword: password545 ++mail: uid545 ++uidnumber: 545 ++gidnumber: 545 ++homeDirectory: /home/uid545 ++ ++dn: cn=user546,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user546 ++sn: user546 ++uid: uid546 ++givenname: givenname546 ++description: description546 ++userPassword: password546 ++mail: uid546 ++uidnumber: 546 ++gidnumber: 546 ++homeDirectory: /home/uid546 ++ ++dn: cn=user547,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user547 ++sn: user547 ++uid: uid547 ++givenname: givenname547 ++description: description547 ++userPassword: password547 ++mail: uid547 ++uidnumber: 547 ++gidnumber: 547 ++homeDirectory: /home/uid547 ++ ++dn: cn=user548,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user548 ++sn: user548 ++uid: uid548 ++givenname: givenname548 ++description: description548 ++userPassword: password548 ++mail: uid548 ++uidnumber: 548 ++gidnumber: 548 ++homeDirectory: /home/uid548 ++ ++dn: cn=user549,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user549 ++sn: user549 ++uid: uid549 ++givenname: givenname549 ++description: description549 ++userPassword: password549 ++mail: uid549 ++uidnumber: 549 ++gidnumber: 549 ++homeDirectory: /home/uid549 ++ ++dn: cn=user550,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user550 ++sn: user550 ++uid: uid550 ++givenname: givenname550 ++description: description550 ++userPassword: password550 ++mail: uid550 ++uidnumber: 550 ++gidnumber: 550 ++homeDirectory: /home/uid550 ++ ++dn: cn=user551,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user551 ++sn: user551 ++uid: uid551 ++givenname: givenname551 ++description: description551 ++userPassword: password551 ++mail: uid551 ++uidnumber: 551 ++gidnumber: 551 ++homeDirectory: /home/uid551 ++ ++dn: cn=user552,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user552 ++sn: user552 ++uid: uid552 ++givenname: givenname552 ++description: description552 ++userPassword: password552 ++mail: uid552 ++uidnumber: 552 ++gidnumber: 552 ++homeDirectory: /home/uid552 ++ ++dn: cn=user553,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user553 ++sn: user553 ++uid: uid553 ++givenname: givenname553 ++description: description553 ++userPassword: password553 ++mail: uid553 ++uidnumber: 553 ++gidnumber: 553 ++homeDirectory: /home/uid553 ++ ++dn: cn=user554,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user554 ++sn: user554 ++uid: uid554 ++givenname: givenname554 ++description: description554 ++userPassword: password554 ++mail: uid554 ++uidnumber: 554 ++gidnumber: 554 ++homeDirectory: /home/uid554 ++ ++dn: cn=user555,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user555 ++sn: user555 ++uid: uid555 ++givenname: givenname555 ++description: description555 ++userPassword: password555 ++mail: uid555 ++uidnumber: 555 ++gidnumber: 555 ++homeDirectory: /home/uid555 ++ ++dn: cn=user556,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user556 ++sn: user556 ++uid: uid556 ++givenname: givenname556 ++description: description556 ++userPassword: password556 ++mail: uid556 ++uidnumber: 556 ++gidnumber: 556 ++homeDirectory: /home/uid556 ++ ++dn: cn=user557,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user557 ++sn: user557 ++uid: uid557 ++givenname: givenname557 ++description: description557 ++userPassword: password557 ++mail: uid557 ++uidnumber: 557 ++gidnumber: 557 ++homeDirectory: /home/uid557 ++ ++dn: cn=user558,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user558 ++sn: user558 ++uid: uid558 ++givenname: givenname558 ++description: description558 ++userPassword: password558 ++mail: uid558 ++uidnumber: 558 ++gidnumber: 558 ++homeDirectory: /home/uid558 ++ ++dn: cn=user559,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user559 ++sn: user559 ++uid: uid559 ++givenname: givenname559 ++description: description559 ++userPassword: password559 ++mail: uid559 ++uidnumber: 559 ++gidnumber: 559 ++homeDirectory: /home/uid559 ++ ++dn: cn=user560,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user560 ++sn: user560 ++uid: uid560 ++givenname: givenname560 ++description: description560 ++userPassword: password560 ++mail: uid560 ++uidnumber: 560 ++gidnumber: 560 ++homeDirectory: /home/uid560 ++ ++dn: cn=user561,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user561 ++sn: user561 ++uid: uid561 ++givenname: givenname561 ++description: description561 ++userPassword: password561 ++mail: uid561 ++uidnumber: 561 ++gidnumber: 561 ++homeDirectory: /home/uid561 ++ ++dn: cn=user562,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user562 ++sn: user562 ++uid: uid562 ++givenname: givenname562 ++description: description562 ++userPassword: password562 ++mail: uid562 ++uidnumber: 562 ++gidnumber: 562 ++homeDirectory: /home/uid562 ++ ++dn: cn=user563,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user563 ++sn: user563 ++uid: uid563 ++givenname: givenname563 ++description: description563 ++userPassword: password563 ++mail: uid563 ++uidnumber: 563 ++gidnumber: 563 ++homeDirectory: /home/uid563 ++ ++dn: cn=user564,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user564 ++sn: user564 ++uid: uid564 ++givenname: givenname564 ++description: description564 ++userPassword: password564 ++mail: uid564 ++uidnumber: 564 ++gidnumber: 564 ++homeDirectory: /home/uid564 ++ ++dn: cn=user565,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user565 ++sn: user565 ++uid: uid565 ++givenname: givenname565 ++description: description565 ++userPassword: password565 ++mail: uid565 ++uidnumber: 565 ++gidnumber: 565 ++homeDirectory: /home/uid565 ++ ++dn: cn=user566,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user566 ++sn: user566 ++uid: uid566 ++givenname: givenname566 ++description: description566 ++userPassword: password566 ++mail: uid566 ++uidnumber: 566 ++gidnumber: 566 ++homeDirectory: /home/uid566 ++ ++dn: cn=user567,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user567 ++sn: user567 ++uid: uid567 ++givenname: givenname567 ++description: description567 ++userPassword: password567 ++mail: uid567 ++uidnumber: 567 ++gidnumber: 567 ++homeDirectory: /home/uid567 ++ ++dn: cn=user568,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user568 ++sn: user568 ++uid: uid568 ++givenname: givenname568 ++description: description568 ++userPassword: password568 ++mail: uid568 ++uidnumber: 568 ++gidnumber: 568 ++homeDirectory: /home/uid568 ++ ++dn: cn=user569,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user569 ++sn: user569 ++uid: uid569 ++givenname: givenname569 ++description: description569 ++userPassword: password569 ++mail: uid569 ++uidnumber: 569 ++gidnumber: 569 ++homeDirectory: /home/uid569 ++ ++dn: cn=user570,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user570 ++sn: user570 ++uid: uid570 ++givenname: givenname570 ++description: description570 ++userPassword: password570 ++mail: uid570 ++uidnumber: 570 ++gidnumber: 570 ++homeDirectory: /home/uid570 ++ ++dn: cn=user571,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user571 ++sn: user571 ++uid: uid571 ++givenname: givenname571 ++description: description571 ++userPassword: password571 ++mail: uid571 ++uidnumber: 571 ++gidnumber: 571 ++homeDirectory: /home/uid571 ++ ++dn: cn=user572,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user572 ++sn: user572 ++uid: uid572 ++givenname: givenname572 ++description: description572 ++userPassword: password572 ++mail: uid572 ++uidnumber: 572 ++gidnumber: 572 ++homeDirectory: /home/uid572 ++ ++dn: cn=user573,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user573 ++sn: user573 ++uid: uid573 ++givenname: givenname573 ++description: description573 ++userPassword: password573 ++mail: uid573 ++uidnumber: 573 ++gidnumber: 573 ++homeDirectory: /home/uid573 ++ ++dn: cn=user574,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user574 ++sn: user574 ++uid: uid574 ++givenname: givenname574 ++description: description574 ++userPassword: password574 ++mail: uid574 ++uidnumber: 574 ++gidnumber: 574 ++homeDirectory: /home/uid574 ++ ++dn: cn=user575,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user575 ++sn: user575 ++uid: uid575 ++givenname: givenname575 ++description: description575 ++userPassword: password575 ++mail: uid575 ++uidnumber: 575 ++gidnumber: 575 ++homeDirectory: /home/uid575 ++ ++dn: cn=user576,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user576 ++sn: user576 ++uid: uid576 ++givenname: givenname576 ++description: description576 ++userPassword: password576 ++mail: uid576 ++uidnumber: 576 ++gidnumber: 576 ++homeDirectory: /home/uid576 ++ ++dn: cn=user577,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user577 ++sn: user577 ++uid: uid577 ++givenname: givenname577 ++description: description577 ++userPassword: password577 ++mail: uid577 ++uidnumber: 577 ++gidnumber: 577 ++homeDirectory: /home/uid577 ++ ++dn: cn=user578,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user578 ++sn: user578 ++uid: uid578 ++givenname: givenname578 ++description: description578 ++userPassword: password578 ++mail: uid578 ++uidnumber: 578 ++gidnumber: 578 ++homeDirectory: /home/uid578 ++ ++dn: cn=user579,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user579 ++sn: user579 ++uid: uid579 ++givenname: givenname579 ++description: description579 ++userPassword: password579 ++mail: uid579 ++uidnumber: 579 ++gidnumber: 579 ++homeDirectory: /home/uid579 ++ ++dn: cn=user580,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user580 ++sn: user580 ++uid: uid580 ++givenname: givenname580 ++description: description580 ++userPassword: password580 ++mail: uid580 ++uidnumber: 580 ++gidnumber: 580 ++homeDirectory: /home/uid580 ++ ++dn: cn=user581,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user581 ++sn: user581 ++uid: uid581 ++givenname: givenname581 ++description: description581 ++userPassword: password581 ++mail: uid581 ++uidnumber: 581 ++gidnumber: 581 ++homeDirectory: /home/uid581 ++ ++dn: cn=user582,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user582 ++sn: user582 ++uid: uid582 ++givenname: givenname582 ++description: description582 ++userPassword: password582 ++mail: uid582 ++uidnumber: 582 ++gidnumber: 582 ++homeDirectory: /home/uid582 ++ ++dn: cn=user583,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user583 ++sn: user583 ++uid: uid583 ++givenname: givenname583 ++description: description583 ++userPassword: password583 ++mail: uid583 ++uidnumber: 583 ++gidnumber: 583 ++homeDirectory: /home/uid583 ++ ++dn: cn=user584,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user584 ++sn: user584 ++uid: uid584 ++givenname: givenname584 ++description: description584 ++userPassword: password584 ++mail: uid584 ++uidnumber: 584 ++gidnumber: 584 ++homeDirectory: /home/uid584 ++ ++dn: cn=user585,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user585 ++sn: user585 ++uid: uid585 ++givenname: givenname585 ++description: description585 ++userPassword: password585 ++mail: uid585 ++uidnumber: 585 ++gidnumber: 585 ++homeDirectory: /home/uid585 ++ ++dn: cn=user586,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user586 ++sn: user586 ++uid: uid586 ++givenname: givenname586 ++description: description586 ++userPassword: password586 ++mail: uid586 ++uidnumber: 586 ++gidnumber: 586 ++homeDirectory: /home/uid586 ++ ++dn: cn=user587,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user587 ++sn: user587 ++uid: uid587 ++givenname: givenname587 ++description: description587 ++userPassword: password587 ++mail: uid587 ++uidnumber: 587 ++gidnumber: 587 ++homeDirectory: /home/uid587 ++ ++dn: cn=user588,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user588 ++sn: user588 ++uid: uid588 ++givenname: givenname588 ++description: description588 ++userPassword: password588 ++mail: uid588 ++uidnumber: 588 ++gidnumber: 588 ++homeDirectory: /home/uid588 ++ ++dn: cn=user589,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user589 ++sn: user589 ++uid: uid589 ++givenname: givenname589 ++description: description589 ++userPassword: password589 ++mail: uid589 ++uidnumber: 589 ++gidnumber: 589 ++homeDirectory: /home/uid589 ++ ++dn: cn=user590,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user590 ++sn: user590 ++uid: uid590 ++givenname: givenname590 ++description: description590 ++userPassword: password590 ++mail: uid590 ++uidnumber: 590 ++gidnumber: 590 ++homeDirectory: /home/uid590 ++ ++dn: cn=user591,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user591 ++sn: user591 ++uid: uid591 ++givenname: givenname591 ++description: description591 ++userPassword: password591 ++mail: uid591 ++uidnumber: 591 ++gidnumber: 591 ++homeDirectory: /home/uid591 ++ ++dn: cn=user592,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user592 ++sn: user592 ++uid: uid592 ++givenname: givenname592 ++description: description592 ++userPassword: password592 ++mail: uid592 ++uidnumber: 592 ++gidnumber: 592 ++homeDirectory: /home/uid592 ++ ++dn: cn=user593,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user593 ++sn: user593 ++uid: uid593 ++givenname: givenname593 ++description: description593 ++userPassword: password593 ++mail: uid593 ++uidnumber: 593 ++gidnumber: 593 ++homeDirectory: /home/uid593 ++ ++dn: cn=user594,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user594 ++sn: user594 ++uid: uid594 ++givenname: givenname594 ++description: description594 ++userPassword: password594 ++mail: uid594 ++uidnumber: 594 ++gidnumber: 594 ++homeDirectory: /home/uid594 ++ ++dn: cn=user595,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user595 ++sn: user595 ++uid: uid595 ++givenname: givenname595 ++description: description595 ++userPassword: password595 ++mail: uid595 ++uidnumber: 595 ++gidnumber: 595 ++homeDirectory: /home/uid595 ++ ++dn: cn=user596,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user596 ++sn: user596 ++uid: uid596 ++givenname: givenname596 ++description: description596 ++userPassword: password596 ++mail: uid596 ++uidnumber: 596 ++gidnumber: 596 ++homeDirectory: /home/uid596 ++ ++dn: cn=user597,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user597 ++sn: user597 ++uid: uid597 ++givenname: givenname597 ++description: description597 ++userPassword: password597 ++mail: uid597 ++uidnumber: 597 ++gidnumber: 597 ++homeDirectory: /home/uid597 ++ ++dn: cn=user598,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user598 ++sn: user598 ++uid: uid598 ++givenname: givenname598 ++description: description598 ++userPassword: password598 ++mail: uid598 ++uidnumber: 598 ++gidnumber: 598 ++homeDirectory: /home/uid598 ++ ++dn: cn=user599,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user599 ++sn: user599 ++uid: uid599 ++givenname: givenname599 ++description: description599 ++userPassword: password599 ++mail: uid599 ++uidnumber: 599 ++gidnumber: 599 ++homeDirectory: /home/uid599 ++ ++dn: cn=user600,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user600 ++sn: user600 ++uid: uid600 ++givenname: givenname600 ++description: description600 ++userPassword: password600 ++mail: uid600 ++uidnumber: 600 ++gidnumber: 600 ++homeDirectory: /home/uid600 ++ ++dn: cn=user601,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user601 ++sn: user601 ++uid: uid601 ++givenname: givenname601 ++description: description601 ++userPassword: password601 ++mail: uid601 ++uidnumber: 601 ++gidnumber: 601 ++homeDirectory: /home/uid601 ++ ++dn: cn=user602,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user602 ++sn: user602 ++uid: uid602 ++givenname: givenname602 ++description: description602 ++userPassword: password602 ++mail: uid602 ++uidnumber: 602 ++gidnumber: 602 ++homeDirectory: /home/uid602 ++ ++dn: cn=user603,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user603 ++sn: user603 ++uid: uid603 ++givenname: givenname603 ++description: description603 ++userPassword: password603 ++mail: uid603 ++uidnumber: 603 ++gidnumber: 603 ++homeDirectory: /home/uid603 ++ ++dn: cn=user604,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user604 ++sn: user604 ++uid: uid604 ++givenname: givenname604 ++description: description604 ++userPassword: password604 ++mail: uid604 ++uidnumber: 604 ++gidnumber: 604 ++homeDirectory: /home/uid604 ++ ++dn: cn=user605,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user605 ++sn: user605 ++uid: uid605 ++givenname: givenname605 ++description: description605 ++userPassword: password605 ++mail: uid605 ++uidnumber: 605 ++gidnumber: 605 ++homeDirectory: /home/uid605 ++ ++dn: cn=user606,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user606 ++sn: user606 ++uid: uid606 ++givenname: givenname606 ++description: description606 ++userPassword: password606 ++mail: uid606 ++uidnumber: 606 ++gidnumber: 606 ++homeDirectory: /home/uid606 ++ ++dn: cn=user607,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user607 ++sn: user607 ++uid: uid607 ++givenname: givenname607 ++description: description607 ++userPassword: password607 ++mail: uid607 ++uidnumber: 607 ++gidnumber: 607 ++homeDirectory: /home/uid607 ++ ++dn: cn=user608,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user608 ++sn: user608 ++uid: uid608 ++givenname: givenname608 ++description: description608 ++userPassword: password608 ++mail: uid608 ++uidnumber: 608 ++gidnumber: 608 ++homeDirectory: /home/uid608 ++ ++dn: cn=user609,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user609 ++sn: user609 ++uid: uid609 ++givenname: givenname609 ++description: description609 ++userPassword: password609 ++mail: uid609 ++uidnumber: 609 ++gidnumber: 609 ++homeDirectory: /home/uid609 ++ ++dn: cn=user610,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user610 ++sn: user610 ++uid: uid610 ++givenname: givenname610 ++description: description610 ++userPassword: password610 ++mail: uid610 ++uidnumber: 610 ++gidnumber: 610 ++homeDirectory: /home/uid610 ++ ++dn: cn=user611,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user611 ++sn: user611 ++uid: uid611 ++givenname: givenname611 ++description: description611 ++userPassword: password611 ++mail: uid611 ++uidnumber: 611 ++gidnumber: 611 ++homeDirectory: /home/uid611 ++ ++dn: cn=user612,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user612 ++sn: user612 ++uid: uid612 ++givenname: givenname612 ++description: description612 ++userPassword: password612 ++mail: uid612 ++uidnumber: 612 ++gidnumber: 612 ++homeDirectory: /home/uid612 ++ ++dn: cn=user613,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user613 ++sn: user613 ++uid: uid613 ++givenname: givenname613 ++description: description613 ++userPassword: password613 ++mail: uid613 ++uidnumber: 613 ++gidnumber: 613 ++homeDirectory: /home/uid613 ++ ++dn: cn=user614,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user614 ++sn: user614 ++uid: uid614 ++givenname: givenname614 ++description: description614 ++userPassword: password614 ++mail: uid614 ++uidnumber: 614 ++gidnumber: 614 ++homeDirectory: /home/uid614 ++ ++dn: cn=user615,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user615 ++sn: user615 ++uid: uid615 ++givenname: givenname615 ++description: description615 ++userPassword: password615 ++mail: uid615 ++uidnumber: 615 ++gidnumber: 615 ++homeDirectory: /home/uid615 ++ ++dn: cn=user616,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user616 ++sn: user616 ++uid: uid616 ++givenname: givenname616 ++description: description616 ++userPassword: password616 ++mail: uid616 ++uidnumber: 616 ++gidnumber: 616 ++homeDirectory: /home/uid616 ++ ++dn: cn=user617,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user617 ++sn: user617 ++uid: uid617 ++givenname: givenname617 ++description: description617 ++userPassword: password617 ++mail: uid617 ++uidnumber: 617 ++gidnumber: 617 ++homeDirectory: /home/uid617 ++ ++dn: cn=user618,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user618 ++sn: user618 ++uid: uid618 ++givenname: givenname618 ++description: description618 ++userPassword: password618 ++mail: uid618 ++uidnumber: 618 ++gidnumber: 618 ++homeDirectory: /home/uid618 ++ ++dn: cn=user619,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user619 ++sn: user619 ++uid: uid619 ++givenname: givenname619 ++description: description619 ++userPassword: password619 ++mail: uid619 ++uidnumber: 619 ++gidnumber: 619 ++homeDirectory: /home/uid619 ++ ++dn: cn=user620,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user620 ++sn: user620 ++uid: uid620 ++givenname: givenname620 ++description: description620 ++userPassword: password620 ++mail: uid620 ++uidnumber: 620 ++gidnumber: 620 ++homeDirectory: /home/uid620 ++ ++dn: cn=user621,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user621 ++sn: user621 ++uid: uid621 ++givenname: givenname621 ++description: description621 ++userPassword: password621 ++mail: uid621 ++uidnumber: 621 ++gidnumber: 621 ++homeDirectory: /home/uid621 ++ ++dn: cn=user622,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user622 ++sn: user622 ++uid: uid622 ++givenname: givenname622 ++description: description622 ++userPassword: password622 ++mail: uid622 ++uidnumber: 622 ++gidnumber: 622 ++homeDirectory: /home/uid622 ++ ++dn: cn=user623,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user623 ++sn: user623 ++uid: uid623 ++givenname: givenname623 ++description: description623 ++userPassword: password623 ++mail: uid623 ++uidnumber: 623 ++gidnumber: 623 ++homeDirectory: /home/uid623 ++ ++dn: cn=user624,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user624 ++sn: user624 ++uid: uid624 ++givenname: givenname624 ++description: description624 ++userPassword: password624 ++mail: uid624 ++uidnumber: 624 ++gidnumber: 624 ++homeDirectory: /home/uid624 ++ ++dn: cn=user625,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user625 ++sn: user625 ++uid: uid625 ++givenname: givenname625 ++description: description625 ++userPassword: password625 ++mail: uid625 ++uidnumber: 625 ++gidnumber: 625 ++homeDirectory: /home/uid625 ++ ++dn: cn=user626,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user626 ++sn: user626 ++uid: uid626 ++givenname: givenname626 ++description: description626 ++userPassword: password626 ++mail: uid626 ++uidnumber: 626 ++gidnumber: 626 ++homeDirectory: /home/uid626 ++ ++dn: cn=user627,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user627 ++sn: user627 ++uid: uid627 ++givenname: givenname627 ++description: description627 ++userPassword: password627 ++mail: uid627 ++uidnumber: 627 ++gidnumber: 627 ++homeDirectory: /home/uid627 ++ ++dn: cn=user628,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user628 ++sn: user628 ++uid: uid628 ++givenname: givenname628 ++description: description628 ++userPassword: password628 ++mail: uid628 ++uidnumber: 628 ++gidnumber: 628 ++homeDirectory: /home/uid628 ++ ++dn: cn=user629,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user629 ++sn: user629 ++uid: uid629 ++givenname: givenname629 ++description: description629 ++userPassword: password629 ++mail: uid629 ++uidnumber: 629 ++gidnumber: 629 ++homeDirectory: /home/uid629 ++ ++dn: cn=user630,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user630 ++sn: user630 ++uid: uid630 ++givenname: givenname630 ++description: description630 ++userPassword: password630 ++mail: uid630 ++uidnumber: 630 ++gidnumber: 630 ++homeDirectory: /home/uid630 ++ ++dn: cn=user631,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user631 ++sn: user631 ++uid: uid631 ++givenname: givenname631 ++description: description631 ++userPassword: password631 ++mail: uid631 ++uidnumber: 631 ++gidnumber: 631 ++homeDirectory: /home/uid631 ++ ++dn: cn=user632,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user632 ++sn: user632 ++uid: uid632 ++givenname: givenname632 ++description: description632 ++userPassword: password632 ++mail: uid632 ++uidnumber: 632 ++gidnumber: 632 ++homeDirectory: /home/uid632 ++ ++dn: cn=user633,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user633 ++sn: user633 ++uid: uid633 ++givenname: givenname633 ++description: description633 ++userPassword: password633 ++mail: uid633 ++uidnumber: 633 ++gidnumber: 633 ++homeDirectory: /home/uid633 ++ ++dn: cn=user634,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user634 ++sn: user634 ++uid: uid634 ++givenname: givenname634 ++description: description634 ++userPassword: password634 ++mail: uid634 ++uidnumber: 634 ++gidnumber: 634 ++homeDirectory: /home/uid634 ++ ++dn: cn=user635,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user635 ++sn: user635 ++uid: uid635 ++givenname: givenname635 ++description: description635 ++userPassword: password635 ++mail: uid635 ++uidnumber: 635 ++gidnumber: 635 ++homeDirectory: /home/uid635 ++ ++dn: cn=user636,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user636 ++sn: user636 ++uid: uid636 ++givenname: givenname636 ++description: description636 ++userPassword: password636 ++mail: uid636 ++uidnumber: 636 ++gidnumber: 636 ++homeDirectory: /home/uid636 ++ ++dn: cn=user637,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user637 ++sn: user637 ++uid: uid637 ++givenname: givenname637 ++description: description637 ++userPassword: password637 ++mail: uid637 ++uidnumber: 637 ++gidnumber: 637 ++homeDirectory: /home/uid637 ++ ++dn: cn=user638,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user638 ++sn: user638 ++uid: uid638 ++givenname: givenname638 ++description: description638 ++userPassword: password638 ++mail: uid638 ++uidnumber: 638 ++gidnumber: 638 ++homeDirectory: /home/uid638 ++ ++dn: cn=user639,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user639 ++sn: user639 ++uid: uid639 ++givenname: givenname639 ++description: description639 ++userPassword: password639 ++mail: uid639 ++uidnumber: 639 ++gidnumber: 639 ++homeDirectory: /home/uid639 ++ ++dn: cn=user640,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user640 ++sn: user640 ++uid: uid640 ++givenname: givenname640 ++description: description640 ++userPassword: password640 ++mail: uid640 ++uidnumber: 640 ++gidnumber: 640 ++homeDirectory: /home/uid640 ++ ++dn: cn=user641,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user641 ++sn: user641 ++uid: uid641 ++givenname: givenname641 ++description: description641 ++userPassword: password641 ++mail: uid641 ++uidnumber: 641 ++gidnumber: 641 ++homeDirectory: /home/uid641 ++ ++dn: cn=user642,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user642 ++sn: user642 ++uid: uid642 ++givenname: givenname642 ++description: description642 ++userPassword: password642 ++mail: uid642 ++uidnumber: 642 ++gidnumber: 642 ++homeDirectory: /home/uid642 ++ ++dn: cn=user643,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user643 ++sn: user643 ++uid: uid643 ++givenname: givenname643 ++description: description643 ++userPassword: password643 ++mail: uid643 ++uidnumber: 643 ++gidnumber: 643 ++homeDirectory: /home/uid643 ++ ++dn: cn=user644,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user644 ++sn: user644 ++uid: uid644 ++givenname: givenname644 ++description: description644 ++userPassword: password644 ++mail: uid644 ++uidnumber: 644 ++gidnumber: 644 ++homeDirectory: /home/uid644 ++ ++dn: cn=user645,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user645 ++sn: user645 ++uid: uid645 ++givenname: givenname645 ++description: description645 ++userPassword: password645 ++mail: uid645 ++uidnumber: 645 ++gidnumber: 645 ++homeDirectory: /home/uid645 ++ ++dn: cn=user646,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user646 ++sn: user646 ++uid: uid646 ++givenname: givenname646 ++description: description646 ++userPassword: password646 ++mail: uid646 ++uidnumber: 646 ++gidnumber: 646 ++homeDirectory: /home/uid646 ++ ++dn: cn=user647,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user647 ++sn: user647 ++uid: uid647 ++givenname: givenname647 ++description: description647 ++userPassword: password647 ++mail: uid647 ++uidnumber: 647 ++gidnumber: 647 ++homeDirectory: /home/uid647 ++ ++dn: cn=user648,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user648 ++sn: user648 ++uid: uid648 ++givenname: givenname648 ++description: description648 ++userPassword: password648 ++mail: uid648 ++uidnumber: 648 ++gidnumber: 648 ++homeDirectory: /home/uid648 ++ ++dn: cn=user649,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user649 ++sn: user649 ++uid: uid649 ++givenname: givenname649 ++description: description649 ++userPassword: password649 ++mail: uid649 ++uidnumber: 649 ++gidnumber: 649 ++homeDirectory: /home/uid649 ++ ++dn: cn=user650,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user650 ++sn: user650 ++uid: uid650 ++givenname: givenname650 ++description: description650 ++userPassword: password650 ++mail: uid650 ++uidnumber: 650 ++gidnumber: 650 ++homeDirectory: /home/uid650 ++ ++dn: cn=user651,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user651 ++sn: user651 ++uid: uid651 ++givenname: givenname651 ++description: description651 ++userPassword: password651 ++mail: uid651 ++uidnumber: 651 ++gidnumber: 651 ++homeDirectory: /home/uid651 ++ ++dn: cn=user652,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user652 ++sn: user652 ++uid: uid652 ++givenname: givenname652 ++description: description652 ++userPassword: password652 ++mail: uid652 ++uidnumber: 652 ++gidnumber: 652 ++homeDirectory: /home/uid652 ++ ++dn: cn=user653,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user653 ++sn: user653 ++uid: uid653 ++givenname: givenname653 ++description: description653 ++userPassword: password653 ++mail: uid653 ++uidnumber: 653 ++gidnumber: 653 ++homeDirectory: /home/uid653 ++ ++dn: cn=user654,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user654 ++sn: user654 ++uid: uid654 ++givenname: givenname654 ++description: description654 ++userPassword: password654 ++mail: uid654 ++uidnumber: 654 ++gidnumber: 654 ++homeDirectory: /home/uid654 ++ ++dn: cn=user655,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user655 ++sn: user655 ++uid: uid655 ++givenname: givenname655 ++description: description655 ++userPassword: password655 ++mail: uid655 ++uidnumber: 655 ++gidnumber: 655 ++homeDirectory: /home/uid655 ++ ++dn: cn=user656,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user656 ++sn: user656 ++uid: uid656 ++givenname: givenname656 ++description: description656 ++userPassword: password656 ++mail: uid656 ++uidnumber: 656 ++gidnumber: 656 ++homeDirectory: /home/uid656 ++ ++dn: cn=user657,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user657 ++sn: user657 ++uid: uid657 ++givenname: givenname657 ++description: description657 ++userPassword: password657 ++mail: uid657 ++uidnumber: 657 ++gidnumber: 657 ++homeDirectory: /home/uid657 ++ ++dn: cn=user658,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user658 ++sn: user658 ++uid: uid658 ++givenname: givenname658 ++description: description658 ++userPassword: password658 ++mail: uid658 ++uidnumber: 658 ++gidnumber: 658 ++homeDirectory: /home/uid658 ++ ++dn: cn=user659,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user659 ++sn: user659 ++uid: uid659 ++givenname: givenname659 ++description: description659 ++userPassword: password659 ++mail: uid659 ++uidnumber: 659 ++gidnumber: 659 ++homeDirectory: /home/uid659 ++ ++dn: cn=user660,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user660 ++sn: user660 ++uid: uid660 ++givenname: givenname660 ++description: description660 ++userPassword: password660 ++mail: uid660 ++uidnumber: 660 ++gidnumber: 660 ++homeDirectory: /home/uid660 ++ ++dn: cn=user661,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user661 ++sn: user661 ++uid: uid661 ++givenname: givenname661 ++description: description661 ++userPassword: password661 ++mail: uid661 ++uidnumber: 661 ++gidnumber: 661 ++homeDirectory: /home/uid661 ++ ++dn: cn=user662,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user662 ++sn: user662 ++uid: uid662 ++givenname: givenname662 ++description: description662 ++userPassword: password662 ++mail: uid662 ++uidnumber: 662 ++gidnumber: 662 ++homeDirectory: /home/uid662 ++ ++dn: cn=user663,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user663 ++sn: user663 ++uid: uid663 ++givenname: givenname663 ++description: description663 ++userPassword: password663 ++mail: uid663 ++uidnumber: 663 ++gidnumber: 663 ++homeDirectory: /home/uid663 ++ ++dn: cn=user664,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user664 ++sn: user664 ++uid: uid664 ++givenname: givenname664 ++description: description664 ++userPassword: password664 ++mail: uid664 ++uidnumber: 664 ++gidnumber: 664 ++homeDirectory: /home/uid664 ++ ++dn: cn=user665,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user665 ++sn: user665 ++uid: uid665 ++givenname: givenname665 ++description: description665 ++userPassword: password665 ++mail: uid665 ++uidnumber: 665 ++gidnumber: 665 ++homeDirectory: /home/uid665 ++ ++dn: cn=user666,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user666 ++sn: user666 ++uid: uid666 ++givenname: givenname666 ++description: description666 ++userPassword: password666 ++mail: uid666 ++uidnumber: 666 ++gidnumber: 666 ++homeDirectory: /home/uid666 ++ ++dn: cn=user667,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user667 ++sn: user667 ++uid: uid667 ++givenname: givenname667 ++description: description667 ++userPassword: password667 ++mail: uid667 ++uidnumber: 667 ++gidnumber: 667 ++homeDirectory: /home/uid667 ++ ++dn: cn=user668,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user668 ++sn: user668 ++uid: uid668 ++givenname: givenname668 ++description: description668 ++userPassword: password668 ++mail: uid668 ++uidnumber: 668 ++gidnumber: 668 ++homeDirectory: /home/uid668 ++ ++dn: cn=user669,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user669 ++sn: user669 ++uid: uid669 ++givenname: givenname669 ++description: description669 ++userPassword: password669 ++mail: uid669 ++uidnumber: 669 ++gidnumber: 669 ++homeDirectory: /home/uid669 ++ ++dn: cn=user670,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user670 ++sn: user670 ++uid: uid670 ++givenname: givenname670 ++description: description670 ++userPassword: password670 ++mail: uid670 ++uidnumber: 670 ++gidnumber: 670 ++homeDirectory: /home/uid670 ++ ++dn: cn=user671,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user671 ++sn: user671 ++uid: uid671 ++givenname: givenname671 ++description: description671 ++userPassword: password671 ++mail: uid671 ++uidnumber: 671 ++gidnumber: 671 ++homeDirectory: /home/uid671 ++ ++dn: cn=user672,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user672 ++sn: user672 ++uid: uid672 ++givenname: givenname672 ++description: description672 ++userPassword: password672 ++mail: uid672 ++uidnumber: 672 ++gidnumber: 672 ++homeDirectory: /home/uid672 ++ ++dn: cn=user673,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user673 ++sn: user673 ++uid: uid673 ++givenname: givenname673 ++description: description673 ++userPassword: password673 ++mail: uid673 ++uidnumber: 673 ++gidnumber: 673 ++homeDirectory: /home/uid673 ++ ++dn: cn=user674,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user674 ++sn: user674 ++uid: uid674 ++givenname: givenname674 ++description: description674 ++userPassword: password674 ++mail: uid674 ++uidnumber: 674 ++gidnumber: 674 ++homeDirectory: /home/uid674 ++ ++dn: cn=user675,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user675 ++sn: user675 ++uid: uid675 ++givenname: givenname675 ++description: description675 ++userPassword: password675 ++mail: uid675 ++uidnumber: 675 ++gidnumber: 675 ++homeDirectory: /home/uid675 ++ ++dn: cn=user676,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user676 ++sn: user676 ++uid: uid676 ++givenname: givenname676 ++description: description676 ++userPassword: password676 ++mail: uid676 ++uidnumber: 676 ++gidnumber: 676 ++homeDirectory: /home/uid676 ++ ++dn: cn=user677,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user677 ++sn: user677 ++uid: uid677 ++givenname: givenname677 ++description: description677 ++userPassword: password677 ++mail: uid677 ++uidnumber: 677 ++gidnumber: 677 ++homeDirectory: /home/uid677 ++ ++dn: cn=user678,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user678 ++sn: user678 ++uid: uid678 ++givenname: givenname678 ++description: description678 ++userPassword: password678 ++mail: uid678 ++uidnumber: 678 ++gidnumber: 678 ++homeDirectory: /home/uid678 ++ ++dn: cn=user679,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user679 ++sn: user679 ++uid: uid679 ++givenname: givenname679 ++description: description679 ++userPassword: password679 ++mail: uid679 ++uidnumber: 679 ++gidnumber: 679 ++homeDirectory: /home/uid679 ++ ++dn: cn=user680,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user680 ++sn: user680 ++uid: uid680 ++givenname: givenname680 ++description: description680 ++userPassword: password680 ++mail: uid680 ++uidnumber: 680 ++gidnumber: 680 ++homeDirectory: /home/uid680 ++ ++dn: cn=user681,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user681 ++sn: user681 ++uid: uid681 ++givenname: givenname681 ++description: description681 ++userPassword: password681 ++mail: uid681 ++uidnumber: 681 ++gidnumber: 681 ++homeDirectory: /home/uid681 ++ ++dn: cn=user682,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user682 ++sn: user682 ++uid: uid682 ++givenname: givenname682 ++description: description682 ++userPassword: password682 ++mail: uid682 ++uidnumber: 682 ++gidnumber: 682 ++homeDirectory: /home/uid682 ++ ++dn: cn=user683,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user683 ++sn: user683 ++uid: uid683 ++givenname: givenname683 ++description: description683 ++userPassword: password683 ++mail: uid683 ++uidnumber: 683 ++gidnumber: 683 ++homeDirectory: /home/uid683 ++ ++dn: cn=user684,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user684 ++sn: user684 ++uid: uid684 ++givenname: givenname684 ++description: description684 ++userPassword: password684 ++mail: uid684 ++uidnumber: 684 ++gidnumber: 684 ++homeDirectory: /home/uid684 ++ ++dn: cn=user685,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user685 ++sn: user685 ++uid: uid685 ++givenname: givenname685 ++description: description685 ++userPassword: password685 ++mail: uid685 ++uidnumber: 685 ++gidnumber: 685 ++homeDirectory: /home/uid685 ++ ++dn: cn=user686,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user686 ++sn: user686 ++uid: uid686 ++givenname: givenname686 ++description: description686 ++userPassword: password686 ++mail: uid686 ++uidnumber: 686 ++gidnumber: 686 ++homeDirectory: /home/uid686 ++ ++dn: cn=user687,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user687 ++sn: user687 ++uid: uid687 ++givenname: givenname687 ++description: description687 ++userPassword: password687 ++mail: uid687 ++uidnumber: 687 ++gidnumber: 687 ++homeDirectory: /home/uid687 ++ ++dn: cn=user688,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user688 ++sn: user688 ++uid: uid688 ++givenname: givenname688 ++description: description688 ++userPassword: password688 ++mail: uid688 ++uidnumber: 688 ++gidnumber: 688 ++homeDirectory: /home/uid688 ++ ++dn: cn=user689,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user689 ++sn: user689 ++uid: uid689 ++givenname: givenname689 ++description: description689 ++userPassword: password689 ++mail: uid689 ++uidnumber: 689 ++gidnumber: 689 ++homeDirectory: /home/uid689 ++ ++dn: cn=user690,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user690 ++sn: user690 ++uid: uid690 ++givenname: givenname690 ++description: description690 ++userPassword: password690 ++mail: uid690 ++uidnumber: 690 ++gidnumber: 690 ++homeDirectory: /home/uid690 ++ ++dn: cn=user691,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user691 ++sn: user691 ++uid: uid691 ++givenname: givenname691 ++description: description691 ++userPassword: password691 ++mail: uid691 ++uidnumber: 691 ++gidnumber: 691 ++homeDirectory: /home/uid691 ++ ++dn: cn=user692,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user692 ++sn: user692 ++uid: uid692 ++givenname: givenname692 ++description: description692 ++userPassword: password692 ++mail: uid692 ++uidnumber: 692 ++gidnumber: 692 ++homeDirectory: /home/uid692 ++ ++dn: cn=user693,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user693 ++sn: user693 ++uid: uid693 ++givenname: givenname693 ++description: description693 ++userPassword: password693 ++mail: uid693 ++uidnumber: 693 ++gidnumber: 693 ++homeDirectory: /home/uid693 ++ ++dn: cn=user694,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user694 ++sn: user694 ++uid: uid694 ++givenname: givenname694 ++description: description694 ++userPassword: password694 ++mail: uid694 ++uidnumber: 694 ++gidnumber: 694 ++homeDirectory: /home/uid694 ++ ++dn: cn=user695,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user695 ++sn: user695 ++uid: uid695 ++givenname: givenname695 ++description: description695 ++userPassword: password695 ++mail: uid695 ++uidnumber: 695 ++gidnumber: 695 ++homeDirectory: /home/uid695 ++ ++dn: cn=user696,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user696 ++sn: user696 ++uid: uid696 ++givenname: givenname696 ++description: description696 ++userPassword: password696 ++mail: uid696 ++uidnumber: 696 ++gidnumber: 696 ++homeDirectory: /home/uid696 ++ ++dn: cn=user697,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user697 ++sn: user697 ++uid: uid697 ++givenname: givenname697 ++description: description697 ++userPassword: password697 ++mail: uid697 ++uidnumber: 697 ++gidnumber: 697 ++homeDirectory: /home/uid697 ++ ++dn: cn=user698,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user698 ++sn: user698 ++uid: uid698 ++givenname: givenname698 ++description: description698 ++userPassword: password698 ++mail: uid698 ++uidnumber: 698 ++gidnumber: 698 ++homeDirectory: /home/uid698 ++ ++dn: cn=user699,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user699 ++sn: user699 ++uid: uid699 ++givenname: givenname699 ++description: description699 ++userPassword: password699 ++mail: uid699 ++uidnumber: 699 ++gidnumber: 699 ++homeDirectory: /home/uid699 ++ ++dn: cn=user700,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user700 ++sn: user700 ++uid: uid700 ++givenname: givenname700 ++description: description700 ++userPassword: password700 ++mail: uid700 ++uidnumber: 700 ++gidnumber: 700 ++homeDirectory: /home/uid700 ++ ++dn: cn=user701,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user701 ++sn: user701 ++uid: uid701 ++givenname: givenname701 ++description: description701 ++userPassword: password701 ++mail: uid701 ++uidnumber: 701 ++gidnumber: 701 ++homeDirectory: /home/uid701 ++ ++dn: cn=user702,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user702 ++sn: user702 ++uid: uid702 ++givenname: givenname702 ++description: description702 ++userPassword: password702 ++mail: uid702 ++uidnumber: 702 ++gidnumber: 702 ++homeDirectory: /home/uid702 ++ ++dn: cn=user703,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user703 ++sn: user703 ++uid: uid703 ++givenname: givenname703 ++description: description703 ++userPassword: password703 ++mail: uid703 ++uidnumber: 703 ++gidnumber: 703 ++homeDirectory: /home/uid703 ++ ++dn: cn=user704,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user704 ++sn: user704 ++uid: uid704 ++givenname: givenname704 ++description: description704 ++userPassword: password704 ++mail: uid704 ++uidnumber: 704 ++gidnumber: 704 ++homeDirectory: /home/uid704 ++ ++dn: cn=user705,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user705 ++sn: user705 ++uid: uid705 ++givenname: givenname705 ++description: description705 ++userPassword: password705 ++mail: uid705 ++uidnumber: 705 ++gidnumber: 705 ++homeDirectory: /home/uid705 ++ ++dn: cn=user706,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user706 ++sn: user706 ++uid: uid706 ++givenname: givenname706 ++description: description706 ++userPassword: password706 ++mail: uid706 ++uidnumber: 706 ++gidnumber: 706 ++homeDirectory: /home/uid706 ++ ++dn: cn=user707,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user707 ++sn: user707 ++uid: uid707 ++givenname: givenname707 ++description: description707 ++userPassword: password707 ++mail: uid707 ++uidnumber: 707 ++gidnumber: 707 ++homeDirectory: /home/uid707 ++ ++dn: cn=user708,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user708 ++sn: user708 ++uid: uid708 ++givenname: givenname708 ++description: description708 ++userPassword: password708 ++mail: uid708 ++uidnumber: 708 ++gidnumber: 708 ++homeDirectory: /home/uid708 ++ ++dn: cn=user709,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user709 ++sn: user709 ++uid: uid709 ++givenname: givenname709 ++description: description709 ++userPassword: password709 ++mail: uid709 ++uidnumber: 709 ++gidnumber: 709 ++homeDirectory: /home/uid709 ++ ++dn: cn=user710,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user710 ++sn: user710 ++uid: uid710 ++givenname: givenname710 ++description: description710 ++userPassword: password710 ++mail: uid710 ++uidnumber: 710 ++gidnumber: 710 ++homeDirectory: /home/uid710 ++ ++dn: cn=user711,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user711 ++sn: user711 ++uid: uid711 ++givenname: givenname711 ++description: description711 ++userPassword: password711 ++mail: uid711 ++uidnumber: 711 ++gidnumber: 711 ++homeDirectory: /home/uid711 ++ ++dn: cn=user712,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user712 ++sn: user712 ++uid: uid712 ++givenname: givenname712 ++description: description712 ++userPassword: password712 ++mail: uid712 ++uidnumber: 712 ++gidnumber: 712 ++homeDirectory: /home/uid712 ++ ++dn: cn=user713,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user713 ++sn: user713 ++uid: uid713 ++givenname: givenname713 ++description: description713 ++userPassword: password713 ++mail: uid713 ++uidnumber: 713 ++gidnumber: 713 ++homeDirectory: /home/uid713 ++ ++dn: cn=user714,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user714 ++sn: user714 ++uid: uid714 ++givenname: givenname714 ++description: description714 ++userPassword: password714 ++mail: uid714 ++uidnumber: 714 ++gidnumber: 714 ++homeDirectory: /home/uid714 ++ ++dn: cn=user715,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user715 ++sn: user715 ++uid: uid715 ++givenname: givenname715 ++description: description715 ++userPassword: password715 ++mail: uid715 ++uidnumber: 715 ++gidnumber: 715 ++homeDirectory: /home/uid715 ++ ++dn: cn=user716,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user716 ++sn: user716 ++uid: uid716 ++givenname: givenname716 ++description: description716 ++userPassword: password716 ++mail: uid716 ++uidnumber: 716 ++gidnumber: 716 ++homeDirectory: /home/uid716 ++ ++dn: cn=user717,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user717 ++sn: user717 ++uid: uid717 ++givenname: givenname717 ++description: description717 ++userPassword: password717 ++mail: uid717 ++uidnumber: 717 ++gidnumber: 717 ++homeDirectory: /home/uid717 ++ ++dn: cn=user718,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user718 ++sn: user718 ++uid: uid718 ++givenname: givenname718 ++description: description718 ++userPassword: password718 ++mail: uid718 ++uidnumber: 718 ++gidnumber: 718 ++homeDirectory: /home/uid718 ++ ++dn: cn=user719,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user719 ++sn: user719 ++uid: uid719 ++givenname: givenname719 ++description: description719 ++userPassword: password719 ++mail: uid719 ++uidnumber: 719 ++gidnumber: 719 ++homeDirectory: /home/uid719 ++ ++dn: cn=user720,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user720 ++sn: user720 ++uid: uid720 ++givenname: givenname720 ++description: description720 ++userPassword: password720 ++mail: uid720 ++uidnumber: 720 ++gidnumber: 720 ++homeDirectory: /home/uid720 ++ ++dn: cn=user721,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user721 ++sn: user721 ++uid: uid721 ++givenname: givenname721 ++description: description721 ++userPassword: password721 ++mail: uid721 ++uidnumber: 721 ++gidnumber: 721 ++homeDirectory: /home/uid721 ++ ++dn: cn=user722,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user722 ++sn: user722 ++uid: uid722 ++givenname: givenname722 ++description: description722 ++userPassword: password722 ++mail: uid722 ++uidnumber: 722 ++gidnumber: 722 ++homeDirectory: /home/uid722 ++ ++dn: cn=user723,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user723 ++sn: user723 ++uid: uid723 ++givenname: givenname723 ++description: description723 ++userPassword: password723 ++mail: uid723 ++uidnumber: 723 ++gidnumber: 723 ++homeDirectory: /home/uid723 ++ ++dn: cn=user724,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user724 ++sn: user724 ++uid: uid724 ++givenname: givenname724 ++description: description724 ++userPassword: password724 ++mail: uid724 ++uidnumber: 724 ++gidnumber: 724 ++homeDirectory: /home/uid724 ++ ++dn: cn=user725,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user725 ++sn: user725 ++uid: uid725 ++givenname: givenname725 ++description: description725 ++userPassword: password725 ++mail: uid725 ++uidnumber: 725 ++gidnumber: 725 ++homeDirectory: /home/uid725 ++ ++dn: cn=user726,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user726 ++sn: user726 ++uid: uid726 ++givenname: givenname726 ++description: description726 ++userPassword: password726 ++mail: uid726 ++uidnumber: 726 ++gidnumber: 726 ++homeDirectory: /home/uid726 ++ ++dn: cn=user727,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user727 ++sn: user727 ++uid: uid727 ++givenname: givenname727 ++description: description727 ++userPassword: password727 ++mail: uid727 ++uidnumber: 727 ++gidnumber: 727 ++homeDirectory: /home/uid727 ++ ++dn: cn=user728,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user728 ++sn: user728 ++uid: uid728 ++givenname: givenname728 ++description: description728 ++userPassword: password728 ++mail: uid728 ++uidnumber: 728 ++gidnumber: 728 ++homeDirectory: /home/uid728 ++ ++dn: cn=user729,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user729 ++sn: user729 ++uid: uid729 ++givenname: givenname729 ++description: description729 ++userPassword: password729 ++mail: uid729 ++uidnumber: 729 ++gidnumber: 729 ++homeDirectory: /home/uid729 ++ ++dn: cn=user730,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user730 ++sn: user730 ++uid: uid730 ++givenname: givenname730 ++description: description730 ++userPassword: password730 ++mail: uid730 ++uidnumber: 730 ++gidnumber: 730 ++homeDirectory: /home/uid730 ++ ++dn: cn=user731,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user731 ++sn: user731 ++uid: uid731 ++givenname: givenname731 ++description: description731 ++userPassword: password731 ++mail: uid731 ++uidnumber: 731 ++gidnumber: 731 ++homeDirectory: /home/uid731 ++ ++dn: cn=user732,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user732 ++sn: user732 ++uid: uid732 ++givenname: givenname732 ++description: description732 ++userPassword: password732 ++mail: uid732 ++uidnumber: 732 ++gidnumber: 732 ++homeDirectory: /home/uid732 ++ ++dn: cn=user733,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user733 ++sn: user733 ++uid: uid733 ++givenname: givenname733 ++description: description733 ++userPassword: password733 ++mail: uid733 ++uidnumber: 733 ++gidnumber: 733 ++homeDirectory: /home/uid733 ++ ++dn: cn=user734,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user734 ++sn: user734 ++uid: uid734 ++givenname: givenname734 ++description: description734 ++userPassword: password734 ++mail: uid734 ++uidnumber: 734 ++gidnumber: 734 ++homeDirectory: /home/uid734 ++ ++dn: cn=user735,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user735 ++sn: user735 ++uid: uid735 ++givenname: givenname735 ++description: description735 ++userPassword: password735 ++mail: uid735 ++uidnumber: 735 ++gidnumber: 735 ++homeDirectory: /home/uid735 ++ ++dn: cn=user736,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user736 ++sn: user736 ++uid: uid736 ++givenname: givenname736 ++description: description736 ++userPassword: password736 ++mail: uid736 ++uidnumber: 736 ++gidnumber: 736 ++homeDirectory: /home/uid736 ++ ++dn: cn=user737,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user737 ++sn: user737 ++uid: uid737 ++givenname: givenname737 ++description: description737 ++userPassword: password737 ++mail: uid737 ++uidnumber: 737 ++gidnumber: 737 ++homeDirectory: /home/uid737 ++ ++dn: cn=user738,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user738 ++sn: user738 ++uid: uid738 ++givenname: givenname738 ++description: description738 ++userPassword: password738 ++mail: uid738 ++uidnumber: 738 ++gidnumber: 738 ++homeDirectory: /home/uid738 ++ ++dn: cn=user739,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user739 ++sn: user739 ++uid: uid739 ++givenname: givenname739 ++description: description739 ++userPassword: password739 ++mail: uid739 ++uidnumber: 739 ++gidnumber: 739 ++homeDirectory: /home/uid739 ++ ++dn: cn=user740,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user740 ++sn: user740 ++uid: uid740 ++givenname: givenname740 ++description: description740 ++userPassword: password740 ++mail: uid740 ++uidnumber: 740 ++gidnumber: 740 ++homeDirectory: /home/uid740 ++ ++dn: cn=user741,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user741 ++sn: user741 ++uid: uid741 ++givenname: givenname741 ++description: description741 ++userPassword: password741 ++mail: uid741 ++uidnumber: 741 ++gidnumber: 741 ++homeDirectory: /home/uid741 ++ ++dn: cn=user742,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user742 ++sn: user742 ++uid: uid742 ++givenname: givenname742 ++description: description742 ++userPassword: password742 ++mail: uid742 ++uidnumber: 742 ++gidnumber: 742 ++homeDirectory: /home/uid742 ++ ++dn: cn=user743,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user743 ++sn: user743 ++uid: uid743 ++givenname: givenname743 ++description: description743 ++userPassword: password743 ++mail: uid743 ++uidnumber: 743 ++gidnumber: 743 ++homeDirectory: /home/uid743 ++ ++dn: cn=user744,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user744 ++sn: user744 ++uid: uid744 ++givenname: givenname744 ++description: description744 ++userPassword: password744 ++mail: uid744 ++uidnumber: 744 ++gidnumber: 744 ++homeDirectory: /home/uid744 ++ ++dn: cn=user745,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user745 ++sn: user745 ++uid: uid745 ++givenname: givenname745 ++description: description745 ++userPassword: password745 ++mail: uid745 ++uidnumber: 745 ++gidnumber: 745 ++homeDirectory: /home/uid745 ++ ++dn: cn=user746,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user746 ++sn: user746 ++uid: uid746 ++givenname: givenname746 ++description: description746 ++userPassword: password746 ++mail: uid746 ++uidnumber: 746 ++gidnumber: 746 ++homeDirectory: /home/uid746 ++ ++dn: cn=user747,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user747 ++sn: user747 ++uid: uid747 ++givenname: givenname747 ++description: description747 ++userPassword: password747 ++mail: uid747 ++uidnumber: 747 ++gidnumber: 747 ++homeDirectory: /home/uid747 ++ ++dn: cn=user748,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user748 ++sn: user748 ++uid: uid748 ++givenname: givenname748 ++description: description748 ++userPassword: password748 ++mail: uid748 ++uidnumber: 748 ++gidnumber: 748 ++homeDirectory: /home/uid748 ++ ++dn: cn=user749,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user749 ++sn: user749 ++uid: uid749 ++givenname: givenname749 ++description: description749 ++userPassword: password749 ++mail: uid749 ++uidnumber: 749 ++gidnumber: 749 ++homeDirectory: /home/uid749 ++ ++dn: cn=user750,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user750 ++sn: user750 ++uid: uid750 ++givenname: givenname750 ++description: description750 ++userPassword: password750 ++mail: uid750 ++uidnumber: 750 ++gidnumber: 750 ++homeDirectory: /home/uid750 ++ ++dn: cn=user751,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user751 ++sn: user751 ++uid: uid751 ++givenname: givenname751 ++description: description751 ++userPassword: password751 ++mail: uid751 ++uidnumber: 751 ++gidnumber: 751 ++homeDirectory: /home/uid751 ++ ++dn: cn=user752,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user752 ++sn: user752 ++uid: uid752 ++givenname: givenname752 ++description: description752 ++userPassword: password752 ++mail: uid752 ++uidnumber: 752 ++gidnumber: 752 ++homeDirectory: /home/uid752 ++ ++dn: cn=user753,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user753 ++sn: user753 ++uid: uid753 ++givenname: givenname753 ++description: description753 ++userPassword: password753 ++mail: uid753 ++uidnumber: 753 ++gidnumber: 753 ++homeDirectory: /home/uid753 ++ ++dn: cn=user754,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user754 ++sn: user754 ++uid: uid754 ++givenname: givenname754 ++description: description754 ++userPassword: password754 ++mail: uid754 ++uidnumber: 754 ++gidnumber: 754 ++homeDirectory: /home/uid754 ++ ++dn: cn=user755,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user755 ++sn: user755 ++uid: uid755 ++givenname: givenname755 ++description: description755 ++userPassword: password755 ++mail: uid755 ++uidnumber: 755 ++gidnumber: 755 ++homeDirectory: /home/uid755 ++ ++dn: cn=user756,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user756 ++sn: user756 ++uid: uid756 ++givenname: givenname756 ++description: description756 ++userPassword: password756 ++mail: uid756 ++uidnumber: 756 ++gidnumber: 756 ++homeDirectory: /home/uid756 ++ ++dn: cn=user757,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user757 ++sn: user757 ++uid: uid757 ++givenname: givenname757 ++description: description757 ++userPassword: password757 ++mail: uid757 ++uidnumber: 757 ++gidnumber: 757 ++homeDirectory: /home/uid757 ++ ++dn: cn=user758,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user758 ++sn: user758 ++uid: uid758 ++givenname: givenname758 ++description: description758 ++userPassword: password758 ++mail: uid758 ++uidnumber: 758 ++gidnumber: 758 ++homeDirectory: /home/uid758 ++ ++dn: cn=user759,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user759 ++sn: user759 ++uid: uid759 ++givenname: givenname759 ++description: description759 ++userPassword: password759 ++mail: uid759 ++uidnumber: 759 ++gidnumber: 759 ++homeDirectory: /home/uid759 ++ ++dn: cn=user760,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user760 ++sn: user760 ++uid: uid760 ++givenname: givenname760 ++description: description760 ++userPassword: password760 ++mail: uid760 ++uidnumber: 760 ++gidnumber: 760 ++homeDirectory: /home/uid760 ++ ++dn: cn=user761,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user761 ++sn: user761 ++uid: uid761 ++givenname: givenname761 ++description: description761 ++userPassword: password761 ++mail: uid761 ++uidnumber: 761 ++gidnumber: 761 ++homeDirectory: /home/uid761 ++ ++dn: cn=user762,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user762 ++sn: user762 ++uid: uid762 ++givenname: givenname762 ++description: description762 ++userPassword: password762 ++mail: uid762 ++uidnumber: 762 ++gidnumber: 762 ++homeDirectory: /home/uid762 ++ ++dn: cn=user763,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user763 ++sn: user763 ++uid: uid763 ++givenname: givenname763 ++description: description763 ++userPassword: password763 ++mail: uid763 ++uidnumber: 763 ++gidnumber: 763 ++homeDirectory: /home/uid763 ++ ++dn: cn=user764,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user764 ++sn: user764 ++uid: uid764 ++givenname: givenname764 ++description: description764 ++userPassword: password764 ++mail: uid764 ++uidnumber: 764 ++gidnumber: 764 ++homeDirectory: /home/uid764 ++ ++dn: cn=user765,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user765 ++sn: user765 ++uid: uid765 ++givenname: givenname765 ++description: description765 ++userPassword: password765 ++mail: uid765 ++uidnumber: 765 ++gidnumber: 765 ++homeDirectory: /home/uid765 ++ ++dn: cn=user766,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user766 ++sn: user766 ++uid: uid766 ++givenname: givenname766 ++description: description766 ++userPassword: password766 ++mail: uid766 ++uidnumber: 766 ++gidnumber: 766 ++homeDirectory: /home/uid766 ++ ++dn: cn=user767,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user767 ++sn: user767 ++uid: uid767 ++givenname: givenname767 ++description: description767 ++userPassword: password767 ++mail: uid767 ++uidnumber: 767 ++gidnumber: 767 ++homeDirectory: /home/uid767 ++ ++dn: cn=user768,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user768 ++sn: user768 ++uid: uid768 ++givenname: givenname768 ++description: description768 ++userPassword: password768 ++mail: uid768 ++uidnumber: 768 ++gidnumber: 768 ++homeDirectory: /home/uid768 ++ ++dn: cn=user769,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user769 ++sn: user769 ++uid: uid769 ++givenname: givenname769 ++description: description769 ++userPassword: password769 ++mail: uid769 ++uidnumber: 769 ++gidnumber: 769 ++homeDirectory: /home/uid769 ++ ++dn: cn=user770,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user770 ++sn: user770 ++uid: uid770 ++givenname: givenname770 ++description: description770 ++userPassword: password770 ++mail: uid770 ++uidnumber: 770 ++gidnumber: 770 ++homeDirectory: /home/uid770 ++ ++dn: cn=user771,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user771 ++sn: user771 ++uid: uid771 ++givenname: givenname771 ++description: description771 ++userPassword: password771 ++mail: uid771 ++uidnumber: 771 ++gidnumber: 771 ++homeDirectory: /home/uid771 ++ ++dn: cn=user772,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user772 ++sn: user772 ++uid: uid772 ++givenname: givenname772 ++description: description772 ++userPassword: password772 ++mail: uid772 ++uidnumber: 772 ++gidnumber: 772 ++homeDirectory: /home/uid772 ++ ++dn: cn=user773,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user773 ++sn: user773 ++uid: uid773 ++givenname: givenname773 ++description: description773 ++userPassword: password773 ++mail: uid773 ++uidnumber: 773 ++gidnumber: 773 ++homeDirectory: /home/uid773 ++ ++dn: cn=user774,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user774 ++sn: user774 ++uid: uid774 ++givenname: givenname774 ++description: description774 ++userPassword: password774 ++mail: uid774 ++uidnumber: 774 ++gidnumber: 774 ++homeDirectory: /home/uid774 ++ ++dn: cn=user775,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user775 ++sn: user775 ++uid: uid775 ++givenname: givenname775 ++description: description775 ++userPassword: password775 ++mail: uid775 ++uidnumber: 775 ++gidnumber: 775 ++homeDirectory: /home/uid775 ++ ++dn: cn=user776,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user776 ++sn: user776 ++uid: uid776 ++givenname: givenname776 ++description: description776 ++userPassword: password776 ++mail: uid776 ++uidnumber: 776 ++gidnumber: 776 ++homeDirectory: /home/uid776 ++ ++dn: cn=user777,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user777 ++sn: user777 ++uid: uid777 ++givenname: givenname777 ++description: description777 ++userPassword: password777 ++mail: uid777 ++uidnumber: 777 ++gidnumber: 777 ++homeDirectory: /home/uid777 ++ ++dn: cn=user778,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user778 ++sn: user778 ++uid: uid778 ++givenname: givenname778 ++description: description778 ++userPassword: password778 ++mail: uid778 ++uidnumber: 778 ++gidnumber: 778 ++homeDirectory: /home/uid778 ++ ++dn: cn=user779,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user779 ++sn: user779 ++uid: uid779 ++givenname: givenname779 ++description: description779 ++userPassword: password779 ++mail: uid779 ++uidnumber: 779 ++gidnumber: 779 ++homeDirectory: /home/uid779 ++ ++dn: cn=user780,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user780 ++sn: user780 ++uid: uid780 ++givenname: givenname780 ++description: description780 ++userPassword: password780 ++mail: uid780 ++uidnumber: 780 ++gidnumber: 780 ++homeDirectory: /home/uid780 ++ ++dn: cn=user781,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user781 ++sn: user781 ++uid: uid781 ++givenname: givenname781 ++description: description781 ++userPassword: password781 ++mail: uid781 ++uidnumber: 781 ++gidnumber: 781 ++homeDirectory: /home/uid781 ++ ++dn: cn=user782,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user782 ++sn: user782 ++uid: uid782 ++givenname: givenname782 ++description: description782 ++userPassword: password782 ++mail: uid782 ++uidnumber: 782 ++gidnumber: 782 ++homeDirectory: /home/uid782 ++ ++dn: cn=user783,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user783 ++sn: user783 ++uid: uid783 ++givenname: givenname783 ++description: description783 ++userPassword: password783 ++mail: uid783 ++uidnumber: 783 ++gidnumber: 783 ++homeDirectory: /home/uid783 ++ ++dn: cn=user784,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user784 ++sn: user784 ++uid: uid784 ++givenname: givenname784 ++description: description784 ++userPassword: password784 ++mail: uid784 ++uidnumber: 784 ++gidnumber: 784 ++homeDirectory: /home/uid784 ++ ++dn: cn=user785,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user785 ++sn: user785 ++uid: uid785 ++givenname: givenname785 ++description: description785 ++userPassword: password785 ++mail: uid785 ++uidnumber: 785 ++gidnumber: 785 ++homeDirectory: /home/uid785 ++ ++dn: cn=user786,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user786 ++sn: user786 ++uid: uid786 ++givenname: givenname786 ++description: description786 ++userPassword: password786 ++mail: uid786 ++uidnumber: 786 ++gidnumber: 786 ++homeDirectory: /home/uid786 ++ ++dn: cn=user787,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user787 ++sn: user787 ++uid: uid787 ++givenname: givenname787 ++description: description787 ++userPassword: password787 ++mail: uid787 ++uidnumber: 787 ++gidnumber: 787 ++homeDirectory: /home/uid787 ++ ++dn: cn=user788,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user788 ++sn: user788 ++uid: uid788 ++givenname: givenname788 ++description: description788 ++userPassword: password788 ++mail: uid788 ++uidnumber: 788 ++gidnumber: 788 ++homeDirectory: /home/uid788 ++ ++dn: cn=user789,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user789 ++sn: user789 ++uid: uid789 ++givenname: givenname789 ++description: description789 ++userPassword: password789 ++mail: uid789 ++uidnumber: 789 ++gidnumber: 789 ++homeDirectory: /home/uid789 ++ ++dn: cn=user790,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user790 ++sn: user790 ++uid: uid790 ++givenname: givenname790 ++description: description790 ++userPassword: password790 ++mail: uid790 ++uidnumber: 790 ++gidnumber: 790 ++homeDirectory: /home/uid790 ++ ++dn: cn=user791,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user791 ++sn: user791 ++uid: uid791 ++givenname: givenname791 ++description: description791 ++userPassword: password791 ++mail: uid791 ++uidnumber: 791 ++gidnumber: 791 ++homeDirectory: /home/uid791 ++ ++dn: cn=user792,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user792 ++sn: user792 ++uid: uid792 ++givenname: givenname792 ++description: description792 ++userPassword: password792 ++mail: uid792 ++uidnumber: 792 ++gidnumber: 792 ++homeDirectory: /home/uid792 ++ ++dn: cn=user793,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user793 ++sn: user793 ++uid: uid793 ++givenname: givenname793 ++description: description793 ++userPassword: password793 ++mail: uid793 ++uidnumber: 793 ++gidnumber: 793 ++homeDirectory: /home/uid793 ++ ++dn: cn=user794,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user794 ++sn: user794 ++uid: uid794 ++givenname: givenname794 ++description: description794 ++userPassword: password794 ++mail: uid794 ++uidnumber: 794 ++gidnumber: 794 ++homeDirectory: /home/uid794 ++ ++dn: cn=user795,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user795 ++sn: user795 ++uid: uid795 ++givenname: givenname795 ++description: description795 ++userPassword: password795 ++mail: uid795 ++uidnumber: 795 ++gidnumber: 795 ++homeDirectory: /home/uid795 ++ ++dn: cn=user796,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user796 ++sn: user796 ++uid: uid796 ++givenname: givenname796 ++description: description796 ++userPassword: password796 ++mail: uid796 ++uidnumber: 796 ++gidnumber: 796 ++homeDirectory: /home/uid796 ++ ++dn: cn=user797,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user797 ++sn: user797 ++uid: uid797 ++givenname: givenname797 ++description: description797 ++userPassword: password797 ++mail: uid797 ++uidnumber: 797 ++gidnumber: 797 ++homeDirectory: /home/uid797 ++ ++dn: cn=user798,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user798 ++sn: user798 ++uid: uid798 ++givenname: givenname798 ++description: description798 ++userPassword: password798 ++mail: uid798 ++uidnumber: 798 ++gidnumber: 798 ++homeDirectory: /home/uid798 ++ ++dn: cn=user799,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user799 ++sn: user799 ++uid: uid799 ++givenname: givenname799 ++description: description799 ++userPassword: password799 ++mail: uid799 ++uidnumber: 799 ++gidnumber: 799 ++homeDirectory: /home/uid799 ++ ++dn: cn=user800,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user800 ++sn: user800 ++uid: uid800 ++givenname: givenname800 ++description: description800 ++userPassword: password800 ++mail: uid800 ++uidnumber: 800 ++gidnumber: 800 ++homeDirectory: /home/uid800 ++ ++dn: cn=user801,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user801 ++sn: user801 ++uid: uid801 ++givenname: givenname801 ++description: description801 ++userPassword: password801 ++mail: uid801 ++uidnumber: 801 ++gidnumber: 801 ++homeDirectory: /home/uid801 ++ ++dn: cn=user802,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user802 ++sn: user802 ++uid: uid802 ++givenname: givenname802 ++description: description802 ++userPassword: password802 ++mail: uid802 ++uidnumber: 802 ++gidnumber: 802 ++homeDirectory: /home/uid802 ++ ++dn: cn=user803,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user803 ++sn: user803 ++uid: uid803 ++givenname: givenname803 ++description: description803 ++userPassword: password803 ++mail: uid803 ++uidnumber: 803 ++gidnumber: 803 ++homeDirectory: /home/uid803 ++ ++dn: cn=user804,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user804 ++sn: user804 ++uid: uid804 ++givenname: givenname804 ++description: description804 ++userPassword: password804 ++mail: uid804 ++uidnumber: 804 ++gidnumber: 804 ++homeDirectory: /home/uid804 ++ ++dn: cn=user805,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user805 ++sn: user805 ++uid: uid805 ++givenname: givenname805 ++description: description805 ++userPassword: password805 ++mail: uid805 ++uidnumber: 805 ++gidnumber: 805 ++homeDirectory: /home/uid805 ++ ++dn: cn=user806,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user806 ++sn: user806 ++uid: uid806 ++givenname: givenname806 ++description: description806 ++userPassword: password806 ++mail: uid806 ++uidnumber: 806 ++gidnumber: 806 ++homeDirectory: /home/uid806 ++ ++dn: cn=user807,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user807 ++sn: user807 ++uid: uid807 ++givenname: givenname807 ++description: description807 ++userPassword: password807 ++mail: uid807 ++uidnumber: 807 ++gidnumber: 807 ++homeDirectory: /home/uid807 ++ ++dn: cn=user808,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user808 ++sn: user808 ++uid: uid808 ++givenname: givenname808 ++description: description808 ++userPassword: password808 ++mail: uid808 ++uidnumber: 808 ++gidnumber: 808 ++homeDirectory: /home/uid808 ++ ++dn: cn=user809,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user809 ++sn: user809 ++uid: uid809 ++givenname: givenname809 ++description: description809 ++userPassword: password809 ++mail: uid809 ++uidnumber: 809 ++gidnumber: 809 ++homeDirectory: /home/uid809 ++ ++dn: cn=user810,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user810 ++sn: user810 ++uid: uid810 ++givenname: givenname810 ++description: description810 ++userPassword: password810 ++mail: uid810 ++uidnumber: 810 ++gidnumber: 810 ++homeDirectory: /home/uid810 ++ ++dn: cn=user811,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user811 ++sn: user811 ++uid: uid811 ++givenname: givenname811 ++description: description811 ++userPassword: password811 ++mail: uid811 ++uidnumber: 811 ++gidnumber: 811 ++homeDirectory: /home/uid811 ++ ++dn: cn=user812,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user812 ++sn: user812 ++uid: uid812 ++givenname: givenname812 ++description: description812 ++userPassword: password812 ++mail: uid812 ++uidnumber: 812 ++gidnumber: 812 ++homeDirectory: /home/uid812 ++ ++dn: cn=user813,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user813 ++sn: user813 ++uid: uid813 ++givenname: givenname813 ++description: description813 ++userPassword: password813 ++mail: uid813 ++uidnumber: 813 ++gidnumber: 813 ++homeDirectory: /home/uid813 ++ ++dn: cn=user814,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user814 ++sn: user814 ++uid: uid814 ++givenname: givenname814 ++description: description814 ++userPassword: password814 ++mail: uid814 ++uidnumber: 814 ++gidnumber: 814 ++homeDirectory: /home/uid814 ++ ++dn: cn=user815,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user815 ++sn: user815 ++uid: uid815 ++givenname: givenname815 ++description: description815 ++userPassword: password815 ++mail: uid815 ++uidnumber: 815 ++gidnumber: 815 ++homeDirectory: /home/uid815 ++ ++dn: cn=user816,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user816 ++sn: user816 ++uid: uid816 ++givenname: givenname816 ++description: description816 ++userPassword: password816 ++mail: uid816 ++uidnumber: 816 ++gidnumber: 816 ++homeDirectory: /home/uid816 ++ ++dn: cn=user817,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user817 ++sn: user817 ++uid: uid817 ++givenname: givenname817 ++description: description817 ++userPassword: password817 ++mail: uid817 ++uidnumber: 817 ++gidnumber: 817 ++homeDirectory: /home/uid817 ++ ++dn: cn=user818,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user818 ++sn: user818 ++uid: uid818 ++givenname: givenname818 ++description: description818 ++userPassword: password818 ++mail: uid818 ++uidnumber: 818 ++gidnumber: 818 ++homeDirectory: /home/uid818 ++ ++dn: cn=user819,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user819 ++sn: user819 ++uid: uid819 ++givenname: givenname819 ++description: description819 ++userPassword: password819 ++mail: uid819 ++uidnumber: 819 ++gidnumber: 819 ++homeDirectory: /home/uid819 ++ ++dn: cn=user820,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user820 ++sn: user820 ++uid: uid820 ++givenname: givenname820 ++description: description820 ++userPassword: password820 ++mail: uid820 ++uidnumber: 820 ++gidnumber: 820 ++homeDirectory: /home/uid820 ++ ++dn: cn=user821,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user821 ++sn: user821 ++uid: uid821 ++givenname: givenname821 ++description: description821 ++userPassword: password821 ++mail: uid821 ++uidnumber: 821 ++gidnumber: 821 ++homeDirectory: /home/uid821 ++ ++dn: cn=user822,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user822 ++sn: user822 ++uid: uid822 ++givenname: givenname822 ++description: description822 ++userPassword: password822 ++mail: uid822 ++uidnumber: 822 ++gidnumber: 822 ++homeDirectory: /home/uid822 ++ ++dn: cn=user823,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user823 ++sn: user823 ++uid: uid823 ++givenname: givenname823 ++description: description823 ++userPassword: password823 ++mail: uid823 ++uidnumber: 823 ++gidnumber: 823 ++homeDirectory: /home/uid823 ++ ++dn: cn=user824,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user824 ++sn: user824 ++uid: uid824 ++givenname: givenname824 ++description: description824 ++userPassword: password824 ++mail: uid824 ++uidnumber: 824 ++gidnumber: 824 ++homeDirectory: /home/uid824 ++ ++dn: cn=user825,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user825 ++sn: user825 ++uid: uid825 ++givenname: givenname825 ++description: description825 ++userPassword: password825 ++mail: uid825 ++uidnumber: 825 ++gidnumber: 825 ++homeDirectory: /home/uid825 ++ ++dn: cn=user826,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user826 ++sn: user826 ++uid: uid826 ++givenname: givenname826 ++description: description826 ++userPassword: password826 ++mail: uid826 ++uidnumber: 826 ++gidnumber: 826 ++homeDirectory: /home/uid826 ++ ++dn: cn=user827,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user827 ++sn: user827 ++uid: uid827 ++givenname: givenname827 ++description: description827 ++userPassword: password827 ++mail: uid827 ++uidnumber: 827 ++gidnumber: 827 ++homeDirectory: /home/uid827 ++ ++dn: cn=user828,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user828 ++sn: user828 ++uid: uid828 ++givenname: givenname828 ++description: description828 ++userPassword: password828 ++mail: uid828 ++uidnumber: 828 ++gidnumber: 828 ++homeDirectory: /home/uid828 ++ ++dn: cn=user829,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user829 ++sn: user829 ++uid: uid829 ++givenname: givenname829 ++description: description829 ++userPassword: password829 ++mail: uid829 ++uidnumber: 829 ++gidnumber: 829 ++homeDirectory: /home/uid829 ++ ++dn: cn=user830,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user830 ++sn: user830 ++uid: uid830 ++givenname: givenname830 ++description: description830 ++userPassword: password830 ++mail: uid830 ++uidnumber: 830 ++gidnumber: 830 ++homeDirectory: /home/uid830 ++ ++dn: cn=user831,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user831 ++sn: user831 ++uid: uid831 ++givenname: givenname831 ++description: description831 ++userPassword: password831 ++mail: uid831 ++uidnumber: 831 ++gidnumber: 831 ++homeDirectory: /home/uid831 ++ ++dn: cn=user832,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user832 ++sn: user832 ++uid: uid832 ++givenname: givenname832 ++description: description832 ++userPassword: password832 ++mail: uid832 ++uidnumber: 832 ++gidnumber: 832 ++homeDirectory: /home/uid832 ++ ++dn: cn=user833,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user833 ++sn: user833 ++uid: uid833 ++givenname: givenname833 ++description: description833 ++userPassword: password833 ++mail: uid833 ++uidnumber: 833 ++gidnumber: 833 ++homeDirectory: /home/uid833 ++ ++dn: cn=user834,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user834 ++sn: user834 ++uid: uid834 ++givenname: givenname834 ++description: description834 ++userPassword: password834 ++mail: uid834 ++uidnumber: 834 ++gidnumber: 834 ++homeDirectory: /home/uid834 ++ ++dn: cn=user835,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user835 ++sn: user835 ++uid: uid835 ++givenname: givenname835 ++description: description835 ++userPassword: password835 ++mail: uid835 ++uidnumber: 835 ++gidnumber: 835 ++homeDirectory: /home/uid835 ++ ++dn: cn=user836,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user836 ++sn: user836 ++uid: uid836 ++givenname: givenname836 ++description: description836 ++userPassword: password836 ++mail: uid836 ++uidnumber: 836 ++gidnumber: 836 ++homeDirectory: /home/uid836 ++ ++dn: cn=user837,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user837 ++sn: user837 ++uid: uid837 ++givenname: givenname837 ++description: description837 ++userPassword: password837 ++mail: uid837 ++uidnumber: 837 ++gidnumber: 837 ++homeDirectory: /home/uid837 ++ ++dn: cn=user838,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user838 ++sn: user838 ++uid: uid838 ++givenname: givenname838 ++description: description838 ++userPassword: password838 ++mail: uid838 ++uidnumber: 838 ++gidnumber: 838 ++homeDirectory: /home/uid838 ++ ++dn: cn=user839,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user839 ++sn: user839 ++uid: uid839 ++givenname: givenname839 ++description: description839 ++userPassword: password839 ++mail: uid839 ++uidnumber: 839 ++gidnumber: 839 ++homeDirectory: /home/uid839 ++ ++dn: cn=user840,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user840 ++sn: user840 ++uid: uid840 ++givenname: givenname840 ++description: description840 ++userPassword: password840 ++mail: uid840 ++uidnumber: 840 ++gidnumber: 840 ++homeDirectory: /home/uid840 ++ ++dn: cn=user841,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user841 ++sn: user841 ++uid: uid841 ++givenname: givenname841 ++description: description841 ++userPassword: password841 ++mail: uid841 ++uidnumber: 841 ++gidnumber: 841 ++homeDirectory: /home/uid841 ++ ++dn: cn=user842,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user842 ++sn: user842 ++uid: uid842 ++givenname: givenname842 ++description: description842 ++userPassword: password842 ++mail: uid842 ++uidnumber: 842 ++gidnumber: 842 ++homeDirectory: /home/uid842 ++ ++dn: cn=user843,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user843 ++sn: user843 ++uid: uid843 ++givenname: givenname843 ++description: description843 ++userPassword: password843 ++mail: uid843 ++uidnumber: 843 ++gidnumber: 843 ++homeDirectory: /home/uid843 ++ ++dn: cn=user844,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user844 ++sn: user844 ++uid: uid844 ++givenname: givenname844 ++description: description844 ++userPassword: password844 ++mail: uid844 ++uidnumber: 844 ++gidnumber: 844 ++homeDirectory: /home/uid844 ++ ++dn: cn=user845,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user845 ++sn: user845 ++uid: uid845 ++givenname: givenname845 ++description: description845 ++userPassword: password845 ++mail: uid845 ++uidnumber: 845 ++gidnumber: 845 ++homeDirectory: /home/uid845 ++ ++dn: cn=user846,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user846 ++sn: user846 ++uid: uid846 ++givenname: givenname846 ++description: description846 ++userPassword: password846 ++mail: uid846 ++uidnumber: 846 ++gidnumber: 846 ++homeDirectory: /home/uid846 ++ ++dn: cn=user847,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user847 ++sn: user847 ++uid: uid847 ++givenname: givenname847 ++description: description847 ++userPassword: password847 ++mail: uid847 ++uidnumber: 847 ++gidnumber: 847 ++homeDirectory: /home/uid847 ++ ++dn: cn=user848,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user848 ++sn: user848 ++uid: uid848 ++givenname: givenname848 ++description: description848 ++userPassword: password848 ++mail: uid848 ++uidnumber: 848 ++gidnumber: 848 ++homeDirectory: /home/uid848 ++ ++dn: cn=user849,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user849 ++sn: user849 ++uid: uid849 ++givenname: givenname849 ++description: description849 ++userPassword: password849 ++mail: uid849 ++uidnumber: 849 ++gidnumber: 849 ++homeDirectory: /home/uid849 ++ ++dn: cn=user850,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user850 ++sn: user850 ++uid: uid850 ++givenname: givenname850 ++description: description850 ++userPassword: password850 ++mail: uid850 ++uidnumber: 850 ++gidnumber: 850 ++homeDirectory: /home/uid850 ++ ++dn: cn=user851,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user851 ++sn: user851 ++uid: uid851 ++givenname: givenname851 ++description: description851 ++userPassword: password851 ++mail: uid851 ++uidnumber: 851 ++gidnumber: 851 ++homeDirectory: /home/uid851 ++ ++dn: cn=user852,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user852 ++sn: user852 ++uid: uid852 ++givenname: givenname852 ++description: description852 ++userPassword: password852 ++mail: uid852 ++uidnumber: 852 ++gidnumber: 852 ++homeDirectory: /home/uid852 ++ ++dn: cn=user853,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user853 ++sn: user853 ++uid: uid853 ++givenname: givenname853 ++description: description853 ++userPassword: password853 ++mail: uid853 ++uidnumber: 853 ++gidnumber: 853 ++homeDirectory: /home/uid853 ++ ++dn: cn=user854,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user854 ++sn: user854 ++uid: uid854 ++givenname: givenname854 ++description: description854 ++userPassword: password854 ++mail: uid854 ++uidnumber: 854 ++gidnumber: 854 ++homeDirectory: /home/uid854 ++ ++dn: cn=user855,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user855 ++sn: user855 ++uid: uid855 ++givenname: givenname855 ++description: description855 ++userPassword: password855 ++mail: uid855 ++uidnumber: 855 ++gidnumber: 855 ++homeDirectory: /home/uid855 ++ ++dn: cn=user856,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user856 ++sn: user856 ++uid: uid856 ++givenname: givenname856 ++description: description856 ++userPassword: password856 ++mail: uid856 ++uidnumber: 856 ++gidnumber: 856 ++homeDirectory: /home/uid856 ++ ++dn: cn=user857,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user857 ++sn: user857 ++uid: uid857 ++givenname: givenname857 ++description: description857 ++userPassword: password857 ++mail: uid857 ++uidnumber: 857 ++gidnumber: 857 ++homeDirectory: /home/uid857 ++ ++dn: cn=user858,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user858 ++sn: user858 ++uid: uid858 ++givenname: givenname858 ++description: description858 ++userPassword: password858 ++mail: uid858 ++uidnumber: 858 ++gidnumber: 858 ++homeDirectory: /home/uid858 ++ ++dn: cn=user859,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user859 ++sn: user859 ++uid: uid859 ++givenname: givenname859 ++description: description859 ++userPassword: password859 ++mail: uid859 ++uidnumber: 859 ++gidnumber: 859 ++homeDirectory: /home/uid859 ++ ++dn: cn=user860,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user860 ++sn: user860 ++uid: uid860 ++givenname: givenname860 ++description: description860 ++userPassword: password860 ++mail: uid860 ++uidnumber: 860 ++gidnumber: 860 ++homeDirectory: /home/uid860 ++ ++dn: cn=user861,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user861 ++sn: user861 ++uid: uid861 ++givenname: givenname861 ++description: description861 ++userPassword: password861 ++mail: uid861 ++uidnumber: 861 ++gidnumber: 861 ++homeDirectory: /home/uid861 ++ ++dn: cn=user862,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user862 ++sn: user862 ++uid: uid862 ++givenname: givenname862 ++description: description862 ++userPassword: password862 ++mail: uid862 ++uidnumber: 862 ++gidnumber: 862 ++homeDirectory: /home/uid862 ++ ++dn: cn=user863,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user863 ++sn: user863 ++uid: uid863 ++givenname: givenname863 ++description: description863 ++userPassword: password863 ++mail: uid863 ++uidnumber: 863 ++gidnumber: 863 ++homeDirectory: /home/uid863 ++ ++dn: cn=user864,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user864 ++sn: user864 ++uid: uid864 ++givenname: givenname864 ++description: description864 ++userPassword: password864 ++mail: uid864 ++uidnumber: 864 ++gidnumber: 864 ++homeDirectory: /home/uid864 ++ ++dn: cn=user865,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user865 ++sn: user865 ++uid: uid865 ++givenname: givenname865 ++description: description865 ++userPassword: password865 ++mail: uid865 ++uidnumber: 865 ++gidnumber: 865 ++homeDirectory: /home/uid865 ++ ++dn: cn=user866,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user866 ++sn: user866 ++uid: uid866 ++givenname: givenname866 ++description: description866 ++userPassword: password866 ++mail: uid866 ++uidnumber: 866 ++gidnumber: 866 ++homeDirectory: /home/uid866 ++ ++dn: cn=user867,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user867 ++sn: user867 ++uid: uid867 ++givenname: givenname867 ++description: description867 ++userPassword: password867 ++mail: uid867 ++uidnumber: 867 ++gidnumber: 867 ++homeDirectory: /home/uid867 ++ ++dn: cn=user868,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user868 ++sn: user868 ++uid: uid868 ++givenname: givenname868 ++description: description868 ++userPassword: password868 ++mail: uid868 ++uidnumber: 868 ++gidnumber: 868 ++homeDirectory: /home/uid868 ++ ++dn: cn=user869,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user869 ++sn: user869 ++uid: uid869 ++givenname: givenname869 ++description: description869 ++userPassword: password869 ++mail: uid869 ++uidnumber: 869 ++gidnumber: 869 ++homeDirectory: /home/uid869 ++ ++dn: cn=user870,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user870 ++sn: user870 ++uid: uid870 ++givenname: givenname870 ++description: description870 ++userPassword: password870 ++mail: uid870 ++uidnumber: 870 ++gidnumber: 870 ++homeDirectory: /home/uid870 ++ ++dn: cn=user871,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user871 ++sn: user871 ++uid: uid871 ++givenname: givenname871 ++description: description871 ++userPassword: password871 ++mail: uid871 ++uidnumber: 871 ++gidnumber: 871 ++homeDirectory: /home/uid871 ++ ++dn: cn=user872,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user872 ++sn: user872 ++uid: uid872 ++givenname: givenname872 ++description: description872 ++userPassword: password872 ++mail: uid872 ++uidnumber: 872 ++gidnumber: 872 ++homeDirectory: /home/uid872 ++ ++dn: cn=user873,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user873 ++sn: user873 ++uid: uid873 ++givenname: givenname873 ++description: description873 ++userPassword: password873 ++mail: uid873 ++uidnumber: 873 ++gidnumber: 873 ++homeDirectory: /home/uid873 ++ ++dn: cn=user874,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user874 ++sn: user874 ++uid: uid874 ++givenname: givenname874 ++description: description874 ++userPassword: password874 ++mail: uid874 ++uidnumber: 874 ++gidnumber: 874 ++homeDirectory: /home/uid874 ++ ++dn: cn=user875,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user875 ++sn: user875 ++uid: uid875 ++givenname: givenname875 ++description: description875 ++userPassword: password875 ++mail: uid875 ++uidnumber: 875 ++gidnumber: 875 ++homeDirectory: /home/uid875 ++ ++dn: cn=user876,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user876 ++sn: user876 ++uid: uid876 ++givenname: givenname876 ++description: description876 ++userPassword: password876 ++mail: uid876 ++uidnumber: 876 ++gidnumber: 876 ++homeDirectory: /home/uid876 ++ ++dn: cn=user877,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user877 ++sn: user877 ++uid: uid877 ++givenname: givenname877 ++description: description877 ++userPassword: password877 ++mail: uid877 ++uidnumber: 877 ++gidnumber: 877 ++homeDirectory: /home/uid877 ++ ++dn: cn=user878,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user878 ++sn: user878 ++uid: uid878 ++givenname: givenname878 ++description: description878 ++userPassword: password878 ++mail: uid878 ++uidnumber: 878 ++gidnumber: 878 ++homeDirectory: /home/uid878 ++ ++dn: cn=user879,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user879 ++sn: user879 ++uid: uid879 ++givenname: givenname879 ++description: description879 ++userPassword: password879 ++mail: uid879 ++uidnumber: 879 ++gidnumber: 879 ++homeDirectory: /home/uid879 ++ ++dn: cn=user880,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user880 ++sn: user880 ++uid: uid880 ++givenname: givenname880 ++description: description880 ++userPassword: password880 ++mail: uid880 ++uidnumber: 880 ++gidnumber: 880 ++homeDirectory: /home/uid880 ++ ++dn: cn=user881,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user881 ++sn: user881 ++uid: uid881 ++givenname: givenname881 ++description: description881 ++userPassword: password881 ++mail: uid881 ++uidnumber: 881 ++gidnumber: 881 ++homeDirectory: /home/uid881 ++ ++dn: cn=user882,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user882 ++sn: user882 ++uid: uid882 ++givenname: givenname882 ++description: description882 ++userPassword: password882 ++mail: uid882 ++uidnumber: 882 ++gidnumber: 882 ++homeDirectory: /home/uid882 ++ ++dn: cn=user883,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user883 ++sn: user883 ++uid: uid883 ++givenname: givenname883 ++description: description883 ++userPassword: password883 ++mail: uid883 ++uidnumber: 883 ++gidnumber: 883 ++homeDirectory: /home/uid883 ++ ++dn: cn=user884,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user884 ++sn: user884 ++uid: uid884 ++givenname: givenname884 ++description: description884 ++userPassword: password884 ++mail: uid884 ++uidnumber: 884 ++gidnumber: 884 ++homeDirectory: /home/uid884 ++ ++dn: cn=user885,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user885 ++sn: user885 ++uid: uid885 ++givenname: givenname885 ++description: description885 ++userPassword: password885 ++mail: uid885 ++uidnumber: 885 ++gidnumber: 885 ++homeDirectory: /home/uid885 ++ ++dn: cn=user886,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user886 ++sn: user886 ++uid: uid886 ++givenname: givenname886 ++description: description886 ++userPassword: password886 ++mail: uid886 ++uidnumber: 886 ++gidnumber: 886 ++homeDirectory: /home/uid886 ++ ++dn: cn=user887,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user887 ++sn: user887 ++uid: uid887 ++givenname: givenname887 ++description: description887 ++userPassword: password887 ++mail: uid887 ++uidnumber: 887 ++gidnumber: 887 ++homeDirectory: /home/uid887 ++ ++dn: cn=user888,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user888 ++sn: user888 ++uid: uid888 ++givenname: givenname888 ++description: description888 ++userPassword: password888 ++mail: uid888 ++uidnumber: 888 ++gidnumber: 888 ++homeDirectory: /home/uid888 ++ ++dn: cn=user889,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user889 ++sn: user889 ++uid: uid889 ++givenname: givenname889 ++description: description889 ++userPassword: password889 ++mail: uid889 ++uidnumber: 889 ++gidnumber: 889 ++homeDirectory: /home/uid889 ++ ++dn: cn=user890,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user890 ++sn: user890 ++uid: uid890 ++givenname: givenname890 ++description: description890 ++userPassword: password890 ++mail: uid890 ++uidnumber: 890 ++gidnumber: 890 ++homeDirectory: /home/uid890 ++ ++dn: cn=user891,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user891 ++sn: user891 ++uid: uid891 ++givenname: givenname891 ++description: description891 ++userPassword: password891 ++mail: uid891 ++uidnumber: 891 ++gidnumber: 891 ++homeDirectory: /home/uid891 ++ ++dn: cn=user892,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user892 ++sn: user892 ++uid: uid892 ++givenname: givenname892 ++description: description892 ++userPassword: password892 ++mail: uid892 ++uidnumber: 892 ++gidnumber: 892 ++homeDirectory: /home/uid892 ++ ++dn: cn=user893,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user893 ++sn: user893 ++uid: uid893 ++givenname: givenname893 ++description: description893 ++userPassword: password893 ++mail: uid893 ++uidnumber: 893 ++gidnumber: 893 ++homeDirectory: /home/uid893 ++ ++dn: cn=user894,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user894 ++sn: user894 ++uid: uid894 ++givenname: givenname894 ++description: description894 ++userPassword: password894 ++mail: uid894 ++uidnumber: 894 ++gidnumber: 894 ++homeDirectory: /home/uid894 ++ ++dn: cn=user895,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user895 ++sn: user895 ++uid: uid895 ++givenname: givenname895 ++description: description895 ++userPassword: password895 ++mail: uid895 ++uidnumber: 895 ++gidnumber: 895 ++homeDirectory: /home/uid895 ++ ++dn: cn=user896,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user896 ++sn: user896 ++uid: uid896 ++givenname: givenname896 ++description: description896 ++userPassword: password896 ++mail: uid896 ++uidnumber: 896 ++gidnumber: 896 ++homeDirectory: /home/uid896 ++ ++dn: cn=user897,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user897 ++sn: user897 ++uid: uid897 ++givenname: givenname897 ++description: description897 ++userPassword: password897 ++mail: uid897 ++uidnumber: 897 ++gidnumber: 897 ++homeDirectory: /home/uid897 ++ ++dn: cn=user898,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user898 ++sn: user898 ++uid: uid898 ++givenname: givenname898 ++description: description898 ++userPassword: password898 ++mail: uid898 ++uidnumber: 898 ++gidnumber: 898 ++homeDirectory: /home/uid898 ++ ++dn: cn=user899,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user899 ++sn: user899 ++uid: uid899 ++givenname: givenname899 ++description: description899 ++userPassword: password899 ++mail: uid899 ++uidnumber: 899 ++gidnumber: 899 ++homeDirectory: /home/uid899 ++ ++dn: cn=user900,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user900 ++sn: user900 ++uid: uid900 ++givenname: givenname900 ++description: description900 ++userPassword: password900 ++mail: uid900 ++uidnumber: 900 ++gidnumber: 900 ++homeDirectory: /home/uid900 ++ ++dn: cn=user901,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user901 ++sn: user901 ++uid: uid901 ++givenname: givenname901 ++description: description901 ++userPassword: password901 ++mail: uid901 ++uidnumber: 901 ++gidnumber: 901 ++homeDirectory: /home/uid901 ++ ++dn: cn=user902,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user902 ++sn: user902 ++uid: uid902 ++givenname: givenname902 ++description: description902 ++userPassword: password902 ++mail: uid902 ++uidnumber: 902 ++gidnumber: 902 ++homeDirectory: /home/uid902 ++ ++dn: cn=user903,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user903 ++sn: user903 ++uid: uid903 ++givenname: givenname903 ++description: description903 ++userPassword: password903 ++mail: uid903 ++uidnumber: 903 ++gidnumber: 903 ++homeDirectory: /home/uid903 ++ ++dn: cn=user904,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user904 ++sn: user904 ++uid: uid904 ++givenname: givenname904 ++description: description904 ++userPassword: password904 ++mail: uid904 ++uidnumber: 904 ++gidnumber: 904 ++homeDirectory: /home/uid904 ++ ++dn: cn=user905,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user905 ++sn: user905 ++uid: uid905 ++givenname: givenname905 ++description: description905 ++userPassword: password905 ++mail: uid905 ++uidnumber: 905 ++gidnumber: 905 ++homeDirectory: /home/uid905 ++ ++dn: cn=user906,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user906 ++sn: user906 ++uid: uid906 ++givenname: givenname906 ++description: description906 ++userPassword: password906 ++mail: uid906 ++uidnumber: 906 ++gidnumber: 906 ++homeDirectory: /home/uid906 ++ ++dn: cn=user907,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user907 ++sn: user907 ++uid: uid907 ++givenname: givenname907 ++description: description907 ++userPassword: password907 ++mail: uid907 ++uidnumber: 907 ++gidnumber: 907 ++homeDirectory: /home/uid907 ++ ++dn: cn=user908,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user908 ++sn: user908 ++uid: uid908 ++givenname: givenname908 ++description: description908 ++userPassword: password908 ++mail: uid908 ++uidnumber: 908 ++gidnumber: 908 ++homeDirectory: /home/uid908 ++ ++dn: cn=user909,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user909 ++sn: user909 ++uid: uid909 ++givenname: givenname909 ++description: description909 ++userPassword: password909 ++mail: uid909 ++uidnumber: 909 ++gidnumber: 909 ++homeDirectory: /home/uid909 ++ ++dn: cn=user910,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user910 ++sn: user910 ++uid: uid910 ++givenname: givenname910 ++description: description910 ++userPassword: password910 ++mail: uid910 ++uidnumber: 910 ++gidnumber: 910 ++homeDirectory: /home/uid910 ++ ++dn: cn=user911,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user911 ++sn: user911 ++uid: uid911 ++givenname: givenname911 ++description: description911 ++userPassword: password911 ++mail: uid911 ++uidnumber: 911 ++gidnumber: 911 ++homeDirectory: /home/uid911 ++ ++dn: cn=user912,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user912 ++sn: user912 ++uid: uid912 ++givenname: givenname912 ++description: description912 ++userPassword: password912 ++mail: uid912 ++uidnumber: 912 ++gidnumber: 912 ++homeDirectory: /home/uid912 ++ ++dn: cn=user913,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user913 ++sn: user913 ++uid: uid913 ++givenname: givenname913 ++description: description913 ++userPassword: password913 ++mail: uid913 ++uidnumber: 913 ++gidnumber: 913 ++homeDirectory: /home/uid913 ++ ++dn: cn=user914,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user914 ++sn: user914 ++uid: uid914 ++givenname: givenname914 ++description: description914 ++userPassword: password914 ++mail: uid914 ++uidnumber: 914 ++gidnumber: 914 ++homeDirectory: /home/uid914 ++ ++dn: cn=user915,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user915 ++sn: user915 ++uid: uid915 ++givenname: givenname915 ++description: description915 ++userPassword: password915 ++mail: uid915 ++uidnumber: 915 ++gidnumber: 915 ++homeDirectory: /home/uid915 ++ ++dn: cn=user916,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user916 ++sn: user916 ++uid: uid916 ++givenname: givenname916 ++description: description916 ++userPassword: password916 ++mail: uid916 ++uidnumber: 916 ++gidnumber: 916 ++homeDirectory: /home/uid916 ++ ++dn: cn=user917,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user917 ++sn: user917 ++uid: uid917 ++givenname: givenname917 ++description: description917 ++userPassword: password917 ++mail: uid917 ++uidnumber: 917 ++gidnumber: 917 ++homeDirectory: /home/uid917 ++ ++dn: cn=user918,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user918 ++sn: user918 ++uid: uid918 ++givenname: givenname918 ++description: description918 ++userPassword: password918 ++mail: uid918 ++uidnumber: 918 ++gidnumber: 918 ++homeDirectory: /home/uid918 ++ ++dn: cn=user919,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user919 ++sn: user919 ++uid: uid919 ++givenname: givenname919 ++description: description919 ++userPassword: password919 ++mail: uid919 ++uidnumber: 919 ++gidnumber: 919 ++homeDirectory: /home/uid919 ++ ++dn: cn=user920,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user920 ++sn: user920 ++uid: uid920 ++givenname: givenname920 ++description: description920 ++userPassword: password920 ++mail: uid920 ++uidnumber: 920 ++gidnumber: 920 ++homeDirectory: /home/uid920 ++ ++dn: cn=user921,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user921 ++sn: user921 ++uid: uid921 ++givenname: givenname921 ++description: description921 ++userPassword: password921 ++mail: uid921 ++uidnumber: 921 ++gidnumber: 921 ++homeDirectory: /home/uid921 ++ ++dn: cn=user922,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user922 ++sn: user922 ++uid: uid922 ++givenname: givenname922 ++description: description922 ++userPassword: password922 ++mail: uid922 ++uidnumber: 922 ++gidnumber: 922 ++homeDirectory: /home/uid922 ++ ++dn: cn=user923,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user923 ++sn: user923 ++uid: uid923 ++givenname: givenname923 ++description: description923 ++userPassword: password923 ++mail: uid923 ++uidnumber: 923 ++gidnumber: 923 ++homeDirectory: /home/uid923 ++ ++dn: cn=user924,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user924 ++sn: user924 ++uid: uid924 ++givenname: givenname924 ++description: description924 ++userPassword: password924 ++mail: uid924 ++uidnumber: 924 ++gidnumber: 924 ++homeDirectory: /home/uid924 ++ ++dn: cn=user925,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user925 ++sn: user925 ++uid: uid925 ++givenname: givenname925 ++description: description925 ++userPassword: password925 ++mail: uid925 ++uidnumber: 925 ++gidnumber: 925 ++homeDirectory: /home/uid925 ++ ++dn: cn=user926,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user926 ++sn: user926 ++uid: uid926 ++givenname: givenname926 ++description: description926 ++userPassword: password926 ++mail: uid926 ++uidnumber: 926 ++gidnumber: 926 ++homeDirectory: /home/uid926 ++ ++dn: cn=user927,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user927 ++sn: user927 ++uid: uid927 ++givenname: givenname927 ++description: description927 ++userPassword: password927 ++mail: uid927 ++uidnumber: 927 ++gidnumber: 927 ++homeDirectory: /home/uid927 ++ ++dn: cn=user928,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user928 ++sn: user928 ++uid: uid928 ++givenname: givenname928 ++description: description928 ++userPassword: password928 ++mail: uid928 ++uidnumber: 928 ++gidnumber: 928 ++homeDirectory: /home/uid928 ++ ++dn: cn=user929,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user929 ++sn: user929 ++uid: uid929 ++givenname: givenname929 ++description: description929 ++userPassword: password929 ++mail: uid929 ++uidnumber: 929 ++gidnumber: 929 ++homeDirectory: /home/uid929 ++ ++dn: cn=user930,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user930 ++sn: user930 ++uid: uid930 ++givenname: givenname930 ++description: description930 ++userPassword: password930 ++mail: uid930 ++uidnumber: 930 ++gidnumber: 930 ++homeDirectory: /home/uid930 ++ ++dn: cn=user931,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user931 ++sn: user931 ++uid: uid931 ++givenname: givenname931 ++description: description931 ++userPassword: password931 ++mail: uid931 ++uidnumber: 931 ++gidnumber: 931 ++homeDirectory: /home/uid931 ++ ++dn: cn=user932,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user932 ++sn: user932 ++uid: uid932 ++givenname: givenname932 ++description: description932 ++userPassword: password932 ++mail: uid932 ++uidnumber: 932 ++gidnumber: 932 ++homeDirectory: /home/uid932 ++ ++dn: cn=user933,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user933 ++sn: user933 ++uid: uid933 ++givenname: givenname933 ++description: description933 ++userPassword: password933 ++mail: uid933 ++uidnumber: 933 ++gidnumber: 933 ++homeDirectory: /home/uid933 ++ ++dn: cn=user934,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user934 ++sn: user934 ++uid: uid934 ++givenname: givenname934 ++description: description934 ++userPassword: password934 ++mail: uid934 ++uidnumber: 934 ++gidnumber: 934 ++homeDirectory: /home/uid934 ++ ++dn: cn=user935,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user935 ++sn: user935 ++uid: uid935 ++givenname: givenname935 ++description: description935 ++userPassword: password935 ++mail: uid935 ++uidnumber: 935 ++gidnumber: 935 ++homeDirectory: /home/uid935 ++ ++dn: cn=user936,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user936 ++sn: user936 ++uid: uid936 ++givenname: givenname936 ++description: description936 ++userPassword: password936 ++mail: uid936 ++uidnumber: 936 ++gidnumber: 936 ++homeDirectory: /home/uid936 ++ ++dn: cn=user937,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user937 ++sn: user937 ++uid: uid937 ++givenname: givenname937 ++description: description937 ++userPassword: password937 ++mail: uid937 ++uidnumber: 937 ++gidnumber: 937 ++homeDirectory: /home/uid937 ++ ++dn: cn=user938,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user938 ++sn: user938 ++uid: uid938 ++givenname: givenname938 ++description: description938 ++userPassword: password938 ++mail: uid938 ++uidnumber: 938 ++gidnumber: 938 ++homeDirectory: /home/uid938 ++ ++dn: cn=user939,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user939 ++sn: user939 ++uid: uid939 ++givenname: givenname939 ++description: description939 ++userPassword: password939 ++mail: uid939 ++uidnumber: 939 ++gidnumber: 939 ++homeDirectory: /home/uid939 ++ ++dn: cn=user940,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user940 ++sn: user940 ++uid: uid940 ++givenname: givenname940 ++description: description940 ++userPassword: password940 ++mail: uid940 ++uidnumber: 940 ++gidnumber: 940 ++homeDirectory: /home/uid940 ++ ++dn: cn=user941,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user941 ++sn: user941 ++uid: uid941 ++givenname: givenname941 ++description: description941 ++userPassword: password941 ++mail: uid941 ++uidnumber: 941 ++gidnumber: 941 ++homeDirectory: /home/uid941 ++ ++dn: cn=user942,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user942 ++sn: user942 ++uid: uid942 ++givenname: givenname942 ++description: description942 ++userPassword: password942 ++mail: uid942 ++uidnumber: 942 ++gidnumber: 942 ++homeDirectory: /home/uid942 ++ ++dn: cn=user943,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user943 ++sn: user943 ++uid: uid943 ++givenname: givenname943 ++description: description943 ++userPassword: password943 ++mail: uid943 ++uidnumber: 943 ++gidnumber: 943 ++homeDirectory: /home/uid943 ++ ++dn: cn=user944,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user944 ++sn: user944 ++uid: uid944 ++givenname: givenname944 ++description: description944 ++userPassword: password944 ++mail: uid944 ++uidnumber: 944 ++gidnumber: 944 ++homeDirectory: /home/uid944 ++ ++dn: cn=user945,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user945 ++sn: user945 ++uid: uid945 ++givenname: givenname945 ++description: description945 ++userPassword: password945 ++mail: uid945 ++uidnumber: 945 ++gidnumber: 945 ++homeDirectory: /home/uid945 ++ ++dn: cn=user946,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user946 ++sn: user946 ++uid: uid946 ++givenname: givenname946 ++description: description946 ++userPassword: password946 ++mail: uid946 ++uidnumber: 946 ++gidnumber: 946 ++homeDirectory: /home/uid946 ++ ++dn: cn=user947,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user947 ++sn: user947 ++uid: uid947 ++givenname: givenname947 ++description: description947 ++userPassword: password947 ++mail: uid947 ++uidnumber: 947 ++gidnumber: 947 ++homeDirectory: /home/uid947 ++ ++dn: cn=user948,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user948 ++sn: user948 ++uid: uid948 ++givenname: givenname948 ++description: description948 ++userPassword: password948 ++mail: uid948 ++uidnumber: 948 ++gidnumber: 948 ++homeDirectory: /home/uid948 ++ ++dn: cn=user949,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user949 ++sn: user949 ++uid: uid949 ++givenname: givenname949 ++description: description949 ++userPassword: password949 ++mail: uid949 ++uidnumber: 949 ++gidnumber: 949 ++homeDirectory: /home/uid949 ++ ++dn: cn=user950,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user950 ++sn: user950 ++uid: uid950 ++givenname: givenname950 ++description: description950 ++userPassword: password950 ++mail: uid950 ++uidnumber: 950 ++gidnumber: 950 ++homeDirectory: /home/uid950 ++ ++dn: cn=user951,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user951 ++sn: user951 ++uid: uid951 ++givenname: givenname951 ++description: description951 ++userPassword: password951 ++mail: uid951 ++uidnumber: 951 ++gidnumber: 951 ++homeDirectory: /home/uid951 ++ ++dn: cn=user952,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user952 ++sn: user952 ++uid: uid952 ++givenname: givenname952 ++description: description952 ++userPassword: password952 ++mail: uid952 ++uidnumber: 952 ++gidnumber: 952 ++homeDirectory: /home/uid952 ++ ++dn: cn=user953,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user953 ++sn: user953 ++uid: uid953 ++givenname: givenname953 ++description: description953 ++userPassword: password953 ++mail: uid953 ++uidnumber: 953 ++gidnumber: 953 ++homeDirectory: /home/uid953 ++ ++dn: cn=user954,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user954 ++sn: user954 ++uid: uid954 ++givenname: givenname954 ++description: description954 ++userPassword: password954 ++mail: uid954 ++uidnumber: 954 ++gidnumber: 954 ++homeDirectory: /home/uid954 ++ ++dn: cn=user955,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user955 ++sn: user955 ++uid: uid955 ++givenname: givenname955 ++description: description955 ++userPassword: password955 ++mail: uid955 ++uidnumber: 955 ++gidnumber: 955 ++homeDirectory: /home/uid955 ++ ++dn: cn=user956,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user956 ++sn: user956 ++uid: uid956 ++givenname: givenname956 ++description: description956 ++userPassword: password956 ++mail: uid956 ++uidnumber: 956 ++gidnumber: 956 ++homeDirectory: /home/uid956 ++ ++dn: cn=user957,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user957 ++sn: user957 ++uid: uid957 ++givenname: givenname957 ++description: description957 ++userPassword: password957 ++mail: uid957 ++uidnumber: 957 ++gidnumber: 957 ++homeDirectory: /home/uid957 ++ ++dn: cn=user958,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user958 ++sn: user958 ++uid: uid958 ++givenname: givenname958 ++description: description958 ++userPassword: password958 ++mail: uid958 ++uidnumber: 958 ++gidnumber: 958 ++homeDirectory: /home/uid958 ++ ++dn: cn=user959,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user959 ++sn: user959 ++uid: uid959 ++givenname: givenname959 ++description: description959 ++userPassword: password959 ++mail: uid959 ++uidnumber: 959 ++gidnumber: 959 ++homeDirectory: /home/uid959 ++ ++dn: cn=user960,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user960 ++sn: user960 ++uid: uid960 ++givenname: givenname960 ++description: description960 ++userPassword: password960 ++mail: uid960 ++uidnumber: 960 ++gidnumber: 960 ++homeDirectory: /home/uid960 ++ ++dn: cn=user961,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user961 ++sn: user961 ++uid: uid961 ++givenname: givenname961 ++description: description961 ++userPassword: password961 ++mail: uid961 ++uidnumber: 961 ++gidnumber: 961 ++homeDirectory: /home/uid961 ++ ++dn: cn=user962,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user962 ++sn: user962 ++uid: uid962 ++givenname: givenname962 ++description: description962 ++userPassword: password962 ++mail: uid962 ++uidnumber: 962 ++gidnumber: 962 ++homeDirectory: /home/uid962 ++ ++dn: cn=user963,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user963 ++sn: user963 ++uid: uid963 ++givenname: givenname963 ++description: description963 ++userPassword: password963 ++mail: uid963 ++uidnumber: 963 ++gidnumber: 963 ++homeDirectory: /home/uid963 ++ ++dn: cn=user964,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user964 ++sn: user964 ++uid: uid964 ++givenname: givenname964 ++description: description964 ++userPassword: password964 ++mail: uid964 ++uidnumber: 964 ++gidnumber: 964 ++homeDirectory: /home/uid964 ++ ++dn: cn=user965,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user965 ++sn: user965 ++uid: uid965 ++givenname: givenname965 ++description: description965 ++userPassword: password965 ++mail: uid965 ++uidnumber: 965 ++gidnumber: 965 ++homeDirectory: /home/uid965 ++ ++dn: cn=user966,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user966 ++sn: user966 ++uid: uid966 ++givenname: givenname966 ++description: description966 ++userPassword: password966 ++mail: uid966 ++uidnumber: 966 ++gidnumber: 966 ++homeDirectory: /home/uid966 ++ ++dn: cn=user967,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user967 ++sn: user967 ++uid: uid967 ++givenname: givenname967 ++description: description967 ++userPassword: password967 ++mail: uid967 ++uidnumber: 967 ++gidnumber: 967 ++homeDirectory: /home/uid967 ++ ++dn: cn=user968,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user968 ++sn: user968 ++uid: uid968 ++givenname: givenname968 ++description: description968 ++userPassword: password968 ++mail: uid968 ++uidnumber: 968 ++gidnumber: 968 ++homeDirectory: /home/uid968 ++ ++dn: cn=user969,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user969 ++sn: user969 ++uid: uid969 ++givenname: givenname969 ++description: description969 ++userPassword: password969 ++mail: uid969 ++uidnumber: 969 ++gidnumber: 969 ++homeDirectory: /home/uid969 ++ ++dn: cn=user970,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user970 ++sn: user970 ++uid: uid970 ++givenname: givenname970 ++description: description970 ++userPassword: password970 ++mail: uid970 ++uidnumber: 970 ++gidnumber: 970 ++homeDirectory: /home/uid970 ++ ++dn: cn=user971,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user971 ++sn: user971 ++uid: uid971 ++givenname: givenname971 ++description: description971 ++userPassword: password971 ++mail: uid971 ++uidnumber: 971 ++gidnumber: 971 ++homeDirectory: /home/uid971 ++ ++dn: cn=user972,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user972 ++sn: user972 ++uid: uid972 ++givenname: givenname972 ++description: description972 ++userPassword: password972 ++mail: uid972 ++uidnumber: 972 ++gidnumber: 972 ++homeDirectory: /home/uid972 ++ ++dn: cn=user973,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user973 ++sn: user973 ++uid: uid973 ++givenname: givenname973 ++description: description973 ++userPassword: password973 ++mail: uid973 ++uidnumber: 973 ++gidnumber: 973 ++homeDirectory: /home/uid973 ++ ++dn: cn=user974,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user974 ++sn: user974 ++uid: uid974 ++givenname: givenname974 ++description: description974 ++userPassword: password974 ++mail: uid974 ++uidnumber: 974 ++gidnumber: 974 ++homeDirectory: /home/uid974 ++ ++dn: cn=user975,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user975 ++sn: user975 ++uid: uid975 ++givenname: givenname975 ++description: description975 ++userPassword: password975 ++mail: uid975 ++uidnumber: 975 ++gidnumber: 975 ++homeDirectory: /home/uid975 ++ ++dn: cn=user976,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user976 ++sn: user976 ++uid: uid976 ++givenname: givenname976 ++description: description976 ++userPassword: password976 ++mail: uid976 ++uidnumber: 976 ++gidnumber: 976 ++homeDirectory: /home/uid976 ++ ++dn: cn=user977,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user977 ++sn: user977 ++uid: uid977 ++givenname: givenname977 ++description: description977 ++userPassword: password977 ++mail: uid977 ++uidnumber: 977 ++gidnumber: 977 ++homeDirectory: /home/uid977 ++ ++dn: cn=user978,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user978 ++sn: user978 ++uid: uid978 ++givenname: givenname978 ++description: description978 ++userPassword: password978 ++mail: uid978 ++uidnumber: 978 ++gidnumber: 978 ++homeDirectory: /home/uid978 ++ ++dn: cn=user979,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user979 ++sn: user979 ++uid: uid979 ++givenname: givenname979 ++description: description979 ++userPassword: password979 ++mail: uid979 ++uidnumber: 979 ++gidnumber: 979 ++homeDirectory: /home/uid979 ++ ++dn: cn=user980,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user980 ++sn: user980 ++uid: uid980 ++givenname: givenname980 ++description: description980 ++userPassword: password980 ++mail: uid980 ++uidnumber: 980 ++gidnumber: 980 ++homeDirectory: /home/uid980 ++ ++dn: cn=user981,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user981 ++sn: user981 ++uid: uid981 ++givenname: givenname981 ++description: description981 ++userPassword: password981 ++mail: uid981 ++uidnumber: 981 ++gidnumber: 981 ++homeDirectory: /home/uid981 ++ ++dn: cn=user982,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user982 ++sn: user982 ++uid: uid982 ++givenname: givenname982 ++description: description982 ++userPassword: password982 ++mail: uid982 ++uidnumber: 982 ++gidnumber: 982 ++homeDirectory: /home/uid982 ++ ++dn: cn=user983,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user983 ++sn: user983 ++uid: uid983 ++givenname: givenname983 ++description: description983 ++userPassword: password983 ++mail: uid983 ++uidnumber: 983 ++gidnumber: 983 ++homeDirectory: /home/uid983 ++ ++dn: cn=user984,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user984 ++sn: user984 ++uid: uid984 ++givenname: givenname984 ++description: description984 ++userPassword: password984 ++mail: uid984 ++uidnumber: 984 ++gidnumber: 984 ++homeDirectory: /home/uid984 ++ ++dn: cn=user985,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user985 ++sn: user985 ++uid: uid985 ++givenname: givenname985 ++description: description985 ++userPassword: password985 ++mail: uid985 ++uidnumber: 985 ++gidnumber: 985 ++homeDirectory: /home/uid985 ++ ++dn: cn=user986,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user986 ++sn: user986 ++uid: uid986 ++givenname: givenname986 ++description: description986 ++userPassword: password986 ++mail: uid986 ++uidnumber: 986 ++gidnumber: 986 ++homeDirectory: /home/uid986 ++ ++dn: cn=user987,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user987 ++sn: user987 ++uid: uid987 ++givenname: givenname987 ++description: description987 ++userPassword: password987 ++mail: uid987 ++uidnumber: 987 ++gidnumber: 987 ++homeDirectory: /home/uid987 ++ ++dn: cn=user988,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user988 ++sn: user988 ++uid: uid988 ++givenname: givenname988 ++description: description988 ++userPassword: password988 ++mail: uid988 ++uidnumber: 988 ++gidnumber: 988 ++homeDirectory: /home/uid988 ++ ++dn: cn=user989,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user989 ++sn: user989 ++uid: uid989 ++givenname: givenname989 ++description: description989 ++userPassword: password989 ++mail: uid989 ++uidnumber: 989 ++gidnumber: 989 ++homeDirectory: /home/uid989 ++ ++dn: cn=user990,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user990 ++sn: user990 ++uid: uid990 ++givenname: givenname990 ++description: description990 ++userPassword: password990 ++mail: uid990 ++uidnumber: 990 ++gidnumber: 990 ++homeDirectory: /home/uid990 ++ ++dn: cn=user991,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user991 ++sn: user991 ++uid: uid991 ++givenname: givenname991 ++description: description991 ++userPassword: password991 ++mail: uid991 ++uidnumber: 991 ++gidnumber: 991 ++homeDirectory: /home/uid991 ++ ++dn: cn=user992,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user992 ++sn: user992 ++uid: uid992 ++givenname: givenname992 ++description: description992 ++userPassword: password992 ++mail: uid992 ++uidnumber: 992 ++gidnumber: 992 ++homeDirectory: /home/uid992 ++ ++dn: cn=user993,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user993 ++sn: user993 ++uid: uid993 ++givenname: givenname993 ++description: description993 ++userPassword: password993 ++mail: uid993 ++uidnumber: 993 ++gidnumber: 993 ++homeDirectory: /home/uid993 ++ ++dn: cn=user994,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user994 ++sn: user994 ++uid: uid994 ++givenname: givenname994 ++description: description994 ++userPassword: password994 ++mail: uid994 ++uidnumber: 994 ++gidnumber: 994 ++homeDirectory: /home/uid994 ++ ++dn: cn=user995,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user995 ++sn: user995 ++uid: uid995 ++givenname: givenname995 ++description: description995 ++userPassword: password995 ++mail: uid995 ++uidnumber: 995 ++gidnumber: 995 ++homeDirectory: /home/uid995 ++ ++dn: cn=user996,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user996 ++sn: user996 ++uid: uid996 ++givenname: givenname996 ++description: description996 ++userPassword: password996 ++mail: uid996 ++uidnumber: 996 ++gidnumber: 996 ++homeDirectory: /home/uid996 ++ ++dn: cn=user997,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user997 ++sn: user997 ++uid: uid997 ++givenname: givenname997 ++description: description997 ++userPassword: password997 ++mail: uid997 ++uidnumber: 997 ++gidnumber: 997 ++homeDirectory: /home/uid997 ++ ++dn: cn=user998,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user998 ++sn: user998 ++uid: uid998 ++givenname: givenname998 ++description: description998 ++userPassword: password998 ++mail: uid998 ++uidnumber: 998 ++gidnumber: 998 ++homeDirectory: /home/uid998 ++ ++dn: cn=user999,ou=People,dc=example,dc=com ++objectClass: top ++objectClass: person ++objectClass: organizationalPerson ++objectClass: inetOrgPerson ++objectClass: posixAccount ++cn: user999 ++sn: user999 ++uid: uid999 ++givenname: givenname999 ++description: description999 ++userPassword: password999 ++mail: uid999 ++uidnumber: 999 ++gidnumber: 999 ++homeDirectory: /home/uid999 ++ +diff --git a/dirsrvtests/tickets/ticket48212_test.py b/dirsrvtests/tickets/ticket48212_test.py +new file mode 100644 +index 0000000..c3c8c8f +--- /dev/null ++++ b/dirsrvtests/tickets/ticket48212_test.py +@@ -0,0 +1,210 @@ ++import os ++import sys ++import time ++import ldap ++import logging ++import pytest ++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 ldap.controls import SimplePagedResultsControl ++ ++log = logging.getLogger(__name__) ++ ++installation_prefix = None ++ ++MYSUFFIX = 'dc=example,dc=com' ++MYSUFFIXBE = 'userRoot' ++_MYLDIF = 'example1k_posix.ldif' ++UIDNUMBERDN = "cn=uidnumber,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config" ++ ++class TopologyStandalone(object): ++ def __init__(self, standalone): ++ standalone.open() ++ self.standalone = standalone ++ ++ ++@pytest.fixture(scope="module") ++def topology(request): ++ ''' ++ This fixture is used to standalone topology for the 'module'. ++ ''' ++ global installation_prefix ++ ++ if installation_prefix: ++ args_instance[SER_DEPLOYED_DIR] = installation_prefix ++ ++ standalone = DirSrv(verbose=False) ++ ++ # Args for the standalone instance ++ args_instance[SER_HOST] = HOST_STANDALONE ++ args_instance[SER_PORT] = PORT_STANDALONE ++ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE ++ args_standalone = args_instance.copy() ++ standalone.allocate(args_standalone) ++ ++ # Get the status of the instance and restart it if it exists ++ instance_standalone = standalone.exists() ++ ++ # Remove the instance ++ if instance_standalone: ++ standalone.delete() ++ ++ # Create the instance ++ standalone.create() ++ ++ # Used to retrieve configuration information (dbdir, confdir...) ++ standalone.open() ++ ++ # clear the tmp directory ++ standalone.clearTmpDir(__file__) ++ ++ # Here we have standalone instance up and running ++ return TopologyStandalone(standalone) ++ ++def runDbVerify(topology): ++ topology.standalone.log.info("\n\n +++++ dbverify +++++\n") ++ dbverifyCMD = topology.standalone.sroot + "/slapd-" + topology.standalone.inst + "/dbverify -V" ++ dbverifyOUT = os.popen(dbverifyCMD, "r") ++ topology.standalone.log.info("Running %s" % dbverifyCMD) ++ running = True ++ error = False ++ while running: ++ l = dbverifyOUT.readline() ++ if l == "": ++ running = False ++ elif "libdb:" in l: ++ running = False ++ error = True ++ topology.standalone.log.info("%s" % l) ++ elif "verify failed" in l: ++ error = True ++ running = False ++ topology.standalone.log.info("%s" % l) ++ ++ if error: ++ topology.standalone.log.fatal("dbverify failed") ++ assert False ++ else: ++ topology.standalone.log.info("dbverify passed") ++ ++def reindexUidNumber(topology): ++ topology.standalone.log.info("\n\n +++++ reindex uidnumber +++++\n") ++ indexCMD = topology.standalone.sroot + "/slapd-" + topology.standalone.inst + "/db2index.pl -D \"" + DN_DM + "\" -w \"" + PASSWORD + "\" -n " + MYSUFFIXBE + " -t uidnumber" ++ ++ indexOUT = os.popen(indexCMD, "r") ++ topology.standalone.log.info("Running %s" % indexCMD) ++ ++ time.sleep(10) ++ ++ tailCMD = "tail -n 3 " + topology.standalone.errlog ++ tailOUT = os.popen(tailCMD, "r") ++ running = True ++ done = False ++ while running: ++ l = tailOUT.readline() ++ if l == "": ++ running = False ++ elif "Finished indexing" in l: ++ running = False ++ done = True ++ topology.standalone.log.info("%s" % l) ++ ++ if done: ++ topology.standalone.log.info("%s done" % indexCMD) ++ else: ++ topology.standalone.log.fatal("%s did not finish" % indexCMD) ++ assert False ++ ++def test_ticket48212_run(topology): ++ """ ++ Import posixAccount entries. ++ Index uidNumber ++ add nsMatchingRule: integerOrderingMatch ++ run dbverify to see if it reports the db corruption or not ++ delete nsMatchingRule: integerOrderingMatch ++ run dbverify to see if it reports the db corruption or not ++ if no corruption is reported, the bug fix was verified. ++ """ ++ log.info('Testing Ticket 48212 - Dynamic nsMatchingRule changes had no effect on the attrinfo thus following reindexing, as well.') ++ ++ # bind as directory manager ++ topology.standalone.log.info("Bind as %s" % DN_DM) ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ ++ ++ data_dir_path = topology.standalone.getDir(__file__, DATA_DIR) ++ ldif_file = data_dir_path + "ticket48212/" + _MYLDIF ++ topology.standalone.log.info("\n\n######################### Import Test data (%s) ######################\n" % ldif_file) ++ args = {TASK_WAIT: True} ++ importTask = Tasks(topology.standalone) ++ importTask.importLDIF(MYSUFFIX, MYSUFFIXBE, ldif_file, args) ++ args = {TASK_WAIT: True} ++ ++ runDbVerify(topology) ++ ++ topology.standalone.log.info("\n\n######################### Add index by uidnumber ######################\n") ++ try: ++ topology.standalone.add_s(Entry((UIDNUMBERDN, {'objectclass': "top nsIndex".split(), ++ 'cn': 'uidnumber', ++ 'nsSystemIndex': 'false', ++ 'nsIndexType': "pres eq".split()}))) ++ except ValueError: ++ topology.standalone.log.fatal("add_s failed: %s", ValueError) ++ ++ topology.standalone.log.info("\n\n######################### reindexing... ######################\n") ++ reindexUidNumber(topology) ++ ++ runDbVerify(topology) ++ ++ topology.standalone.log.info("\n\n######################### Add nsMatchingRule ######################\n") ++ try: ++ topology.standalone.modify_s(UIDNUMBERDN, [(ldap.MOD_ADD, 'nsMatchingRule', 'integerOrderingMatch')]) ++ except ValueError: ++ topology.standalone.log.fatal("modify_s failed: %s", ValueError) ++ ++ topology.standalone.log.info("\n\n######################### reindexing... ######################\n") ++ reindexUidNumber(topology) ++ ++ runDbVerify(topology) ++ ++ topology.standalone.log.info("\n\n######################### Delete nsMatchingRule ######################\n") ++ try: ++ topology.standalone.modify_s(UIDNUMBERDN, [(ldap.MOD_DELETE, 'nsMatchingRule', 'integerOrderingMatch')]) ++ except ValueError: ++ topology.standalone.log.fatal("modify_s failed: %s", ValueError) ++ ++ reindexUidNumber(topology) ++ ++ runDbVerify(topology) ++ ++ topology.standalone.log.info("ticket48212 was successfully verified.") ++ ++ ++def test_ticket48212_final(topology): ++ topology.standalone.delete() ++ log.info('Testcase PASSED') ++ ++ ++def run_isolated(): ++ ''' ++ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) ++ To run isolated without py.test, you need to ++ - edit this file and comment '@pytest.fixture' line before 'topology' function. ++ - set the installation prefix ++ - run this program ++ ''' ++ global installation_prefix ++ installation_prefix = None ++ ++ topo = topology(True) ++ test_ticket48212_run(topo) ++ ++ test_ticket48212_final(topo) ++ ++ ++if __name__ == '__main__': ++ run_isolated() ++ +-- +1.9.3 + diff --git a/SOURCES/0005-Ticket-47838-47895-CI-test-add-test-cases-for-ticket.patch b/SOURCES/0005-Ticket-47838-47895-CI-test-add-test-cases-for-ticket.patch deleted file mode 100644 index ad744c2..0000000 --- a/SOURCES/0005-Ticket-47838-47895-CI-test-add-test-cases-for-ticket.patch +++ /dev/null @@ -1,494 +0,0 @@ -From d15c48e4041d3d7ccde3e791c9ee517af42b7447 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 10 Sep 2014 18:48:07 -0700 -Subject: [PATCH 5/7] Ticket 47838,47895 - CI test: add test cases for ticket - 47838 and 47895 - -Description: -Ticket #47838: harden the list of ciphers available by default -Adding test cases for default behaviour change of allowWeakCipher. - -Ticket #47895 - If no effective ciphers are available, disable security setting. -Test case for "Even if no cipher is available, the server starts -without SSL" is added. - -https://fedorahosted.org/389/ticket/47838 -(cherry picked from commit 4fb1a04ceb9631680a9bcff844250afb4b6e5b7d) -(cherry picked from commit 3877981d63fb82716b60cd1294008b2d272197c9) ---- - dirsrvtests/tickets/ticket47838_test.py | 221 +++++++++++++++++++++++--------- - 1 file changed, 163 insertions(+), 58 deletions(-) - -diff --git a/dirsrvtests/tickets/ticket47838_test.py b/dirsrvtests/tickets/ticket47838_test.py -index dedd61d..0e406f3 100644 ---- a/dirsrvtests/tickets/ticket47838_test.py -+++ b/dirsrvtests/tickets/ticket47838_test.py -@@ -201,6 +201,7 @@ def test_ticket47838_init(topology): - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3', 'on'), - (ldap.MOD_REPLACE, 'nsSSLClientAuth', 'allowed'), -+ (ldap.MOD_REPLACE, 'allowWeakCipher', 'on'), - (ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all')]) - - topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-security', 'on'), -@@ -217,6 +218,7 @@ def test_ticket47838_run_0(topology): - """ - Check nsSSL3Ciphers: +all - All ciphers are enabled except null. -+ Note: allowWeakCipher: on - """ - _header(topology, 'Test Case 1 - Check the ciphers availability for "+all"') - -@@ -226,42 +228,78 @@ def test_ticket47838_run_0(topology): - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.restart(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - - log.info("Enabled ciphers: %d" % ecount) - log.info("Disabled ciphers: %d" % dcount) -- assert ecount >= 60 -- assert dcount <= 7 -+ assert ecount >= 31 -+ assert dcount <= 36 - global plus_all_ecount - global plus_all_dcount - plus_all_ecount = ecount - plus_all_dcount = dcount -- weak = os.popen('egrep "SSL alert:" %s | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ weak = os.popen('egrep "SSL alert:" %s | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) - wcount = int(weak.readline().rstrip()) - log.info("Weak ciphers: %d" % wcount) - assert wcount <= 29 - - def test_ticket47838_run_1(topology): - """ -+ Check nsSSL3Ciphers: +all -+ All ciphers are enabled except null. -+ Note: allowWeakCipher: off for +all -+ """ -+ _header(topology, 'Test Case 2 - Check the ciphers availability for "+all" with not allowing WeakCiphers') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '64')]) -+ # Make sure allowWeakCipher is not set. -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_DELETE, 'allowWeakCipher', None)]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_0' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) -+ ecount = int(enabled.readline().rstrip()) -+ dcount = int(disabled.readline().rstrip()) -+ -+ log.info("Enabled ciphers: %d" % ecount) -+ log.info("Disabled ciphers: %d" % dcount) -+ assert ecount >= 31 -+ assert dcount <= 36 -+ weak = os.popen('egrep "SSL alert:" %s | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ wcount = int(weak.readline().rstrip()) -+ log.info("Weak ciphers: %d" % wcount) -+ assert wcount <= 29 -+ -+def test_ticket47838_run_2(topology): -+ """ - Check nsSSL3Ciphers: +rsa_aes_128_sha,+rsa_aes_256_sha - rsa_aes_128_sha, tls_rsa_aes_128_sha, rsa_aes_256_sha, tls_rsa_aes_256_sha are enabled. - """ -- _header(topology, 'Test Case 2 - Check the ciphers availability for "+rsa_aes_128_sha,+rsa_aes_256_sha"') -+ _header(topology, 'Test Case 3 - Check the ciphers availability for "+rsa_aes_128_sha,+rsa_aes_256_sha"') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ #topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+rsa_aes_128_sha,+rsa_aes_256_sha'), -+ # (ldap.MOD_REPLACE, 'allowWeakCipher', 'on')]) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+rsa_aes_128_sha,+rsa_aes_256_sha')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_0' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_1' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -272,24 +310,24 @@ def test_ticket47838_run_1(topology): - assert ecount == 2 - assert dcount == (plus_all_ecount + plus_all_dcount - ecount) - --def test_ticket47838_run_2(topology): -+def test_ticket47838_run_3(topology): - """ - Check nsSSL3Ciphers: -all - All ciphers are disabled. - """ -- _header(topology, 'Test Case 3 - Check the ciphers availability for "-all"') -+ _header(topology, 'Test Case 4 - Check the ciphers availability for "-all"') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '-all')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_1' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_2' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -300,24 +338,24 @@ def test_ticket47838_run_2(topology): - assert ecount == 0 - assert dcount == (plus_all_ecount + plus_all_dcount) - --def test_ticket47838_run_3(topology): -+def test_ticket47838_run_4(topology): - """ - Check no nsSSL3Ciphers - Default ciphers are enabled. - """ -- _header(topology, 'Test Case 4 - Check no nssSSL3Chiphers (default setting)') -+ _header(topology, 'Test Case 5 - Check no nssSSL3Chiphers (default setting)') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_DELETE, 'nsSSL3Ciphers', '-all')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_2' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_3' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -327,29 +365,29 @@ def test_ticket47838_run_3(topology): - global plus_all_dcount - assert ecount == 12 - assert dcount == (plus_all_ecount + plus_all_dcount - ecount) -- weak = os.popen('egrep "SSL alert:" %s | egrep enabled | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ weak = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) - wcount = int(weak.readline().rstrip()) - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 0 - --def test_ticket47838_run_4(topology): -+def test_ticket47838_run_5(topology): - """ - Check nsSSL3Ciphers: default - Default ciphers are enabled. - """ -- _header(topology, 'Test Case 5 - Check default nssSSL3Chiphers (default setting)') -+ _header(topology, 'Test Case 6 - Check default nssSSL3Chiphers (default setting)') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', 'default')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_3' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_4' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -359,29 +397,29 @@ def test_ticket47838_run_4(topology): - global plus_all_dcount - assert ecount == 12 - assert dcount == (plus_all_ecount + plus_all_dcount - ecount) -- weak = os.popen('egrep "SSL alert:" %s | egrep enabled | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ weak = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) - wcount = int(weak.readline().rstrip()) - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 0 - --def test_ticket47838_run_5(topology): -+def test_ticket47838_run_6(topology): - """ - Check nssSSL3Chiphers: +all,-rsa_rc4_128_md5 - All ciphers are disabled. - """ -- _header(topology, 'Test Case 6 - Check nssSSL3Chiphers: +all,-rsa_rc4_128_md5') -+ _header(topology, 'Test Case 7 - Check nssSSL3Chiphers: +all,-tls_dhe_rsa_aes_128_gcm_sha') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -- topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all,-rsa_rc4_128_md5')]) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all,-tls_dhe_rsa_aes_128_gcm_sha')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_4' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_5' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -389,27 +427,29 @@ def test_ticket47838_run_5(topology): - log.info("Disabled ciphers: %d" % dcount) - global plus_all_ecount - global plus_all_dcount -+ log.info("ALL Ecount: %d" % plus_all_ecount) -+ log.info("ALL Dcount: %d" % plus_all_dcount) - assert ecount == (plus_all_ecount - 1) - assert dcount == (plus_all_dcount + 1) - --def test_ticket47838_run_6(topology): -+def test_ticket47838_run_7(topology): - """ - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5 - All ciphers are disabled. - """ -- _header(topology, 'Test Case 7 - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5') -+ _header(topology, 'Test Case 8 - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '-all,+rsa_rc4_128_md5')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_5' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_6' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -420,25 +460,59 @@ def test_ticket47838_run_6(topology): - assert ecount == 1 - assert dcount == (plus_all_ecount + plus_all_dcount - ecount) - --def test_ticket47838_run_7(topology): -+def test_ticket47838_run_8(topology): -+ """ -+ Check nsSSL3Ciphers: default + allowWeakCipher: off -+ Strong Default ciphers are enabled. -+ """ -+ _header(topology, 'Test Case 9 - Check default nssSSL3Chiphers (default setting + allowWeakCipher: off)') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', 'default'), -+ (ldap.MOD_REPLACE, 'allowWeakCipher', 'off')]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_7' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) -+ ecount = int(enabled.readline().rstrip()) -+ dcount = int(disabled.readline().rstrip()) -+ -+ log.info("Enabled ciphers: %d" % ecount) -+ log.info("Disabled ciphers: %d" % dcount) -+ global plus_all_ecount -+ global plus_all_dcount -+ assert ecount == 12 -+ assert dcount == (plus_all_ecount + plus_all_dcount - ecount) -+ weak = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ wcount = int(weak.readline().rstrip()) -+ log.info("Weak ciphers in the default setting: %d" % wcount) -+ assert wcount == 0 -+ -+def test_ticket47838_run_9(topology): - """ - Check no nsSSL3Ciphers - Default ciphers are enabled. - """ -- _header(topology, 'Test Case 8 - Check no nssSSL3Chiphers (default setting) with no errorlog-level') -+ _header(topology, 'Test Case 10 - Check no nssSSL3Chiphers (default setting) with no errorlog-level') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -- topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', None)]) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', None), -+ (ldap.MOD_REPLACE, 'allowWeakCipher', 'on')]) - topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', None)]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_6' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_8' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -446,12 +520,12 @@ def test_ticket47838_run_7(topology): - log.info("Disabled ciphers: %d" % dcount) - assert ecount == 12 - assert dcount == 0 -- weak = os.popen('egrep "SSL alert:" %s | egrep enabled | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ weak = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) - wcount = int(weak.readline().rstrip()) - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 0 - --def test_ticket47838_run_8(topology): -+def test_ticket47838_run_10(topology): - """ - Check nssSSL3Chiphers: -TLS_RSA_WITH_NULL_MD5,+TLS_RSA_WITH_RC4_128_MD5, - +TLS_RSA_EXPORT_WITH_RC4_40_MD5,+TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, -@@ -462,7 +536,7 @@ def test_ticket47838_run_8(topology): - -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 - """ -- _header(topology, 'Test Case 9 - Check nssSSL3Chiphers: long list using the NSS Cipher Suite name') -+ _header(topology, 'Test Case 11 - Check nssSSL3Chiphers: long list using the NSS Cipher Suite name') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', -@@ -470,12 +544,12 @@ def test_ticket47838_run_8(topology): - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_7' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_9' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- enabled = os.popen('egrep "SSL alert:" %s | egrep enabled | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep disabled | wc -l' % topology.standalone.errlog) -+ enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -+ disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -@@ -485,32 +559,56 @@ def test_ticket47838_run_8(topology): - global plus_all_dcount - assert ecount == 9 - assert dcount == 0 -- weak = os.popen('egrep "SSL alert:" %s | egrep enabled | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) -+ weak = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) - wcount = int(weak.readline().rstrip()) - log.info("Weak ciphers in the default setting: %d" % wcount) - --def test_ticket47838_run_9(topology): -+ topology.standalone.log.info("ticket47838 was successfully verified."); -+ -+def test_ticket47838_run_11(topology): -+ """ -+ Check nssSSL3Chiphers: +fortezza -+ SSL_GetImplementedCiphers does not return this as a secuire cipher suite -+ """ -+ _header(topology, 'Test Case 12 - Check nssSSL3Chiphers: +fortezza, which is not supported') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+fortezza')]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_10' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "is not available in NSS"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected error message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected error message was not found") -+ assert False -+ -+def test_ticket47838_run_last(topology): - """ -- NOTE: Currently, this test case is commented out since if the server fails to start, -- it repeatedly restarted. - Check nssSSL3Chiphers: all <== invalid value - All ciphers are disabled. - """ -- _header(topology, 'Test Case 10 - Check nssSSL3Chiphers: all, which is invalid') -+ _header(topology, 'Test Case 13 - Check nssSSL3Chiphers: all, which is invalid') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', 'all')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_7' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_10' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -- errmsg = os.popen('egrep "SSL alert:" %s | egrep "invalid ciphers"' % topology.standalone.errlog) -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "invalid ciphers"' % topology.standalone.errlog) - if errmsg != "": - log.info("Expected error message:") -- log.info("%s" % errmsg) -+ log.info("%s" % errmsg.readline()) - else: - log.info("Expected error message was not found") - assert False -@@ -519,6 +617,9 @@ def test_ticket47838_run_9(topology): - - def test_ticket47838_final(topology): - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', None)]) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', 'default'), -+ (ldap.MOD_REPLACE, 'allowWeakCipher', 'on')]) - topology.standalone.stop(timeout=10) - - def run_isolated(): -@@ -544,7 +645,11 @@ def run_isolated(): - test_ticket47838_run_6(topo) - test_ticket47838_run_7(topo) - test_ticket47838_run_8(topo) -- # test_ticket47838_run_9(topo) -+ test_ticket47838_run_9(topo) -+ test_ticket47838_run_10(topo) -+ test_ticket47838_run_11(topo) -+ -+ test_ticket47838_run_last(topo) - - test_ticket47838_final(topo) - --- -1.9.3 - diff --git a/SOURCES/0005-Ticket-48214-ldapsearch-on-nsslapd-maxbersize-return.patch b/SOURCES/0005-Ticket-48214-ldapsearch-on-nsslapd-maxbersize-return.patch new file mode 100644 index 0000000..b40bdc3 --- /dev/null +++ b/SOURCES/0005-Ticket-48214-ldapsearch-on-nsslapd-maxbersize-return.patch @@ -0,0 +1,65 @@ +From e37431f50e8d4bfc7015d9a00b58a9b9e77f1c79 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 2 Jul 2015 16:44:09 -0700 +Subject: [PATCH 5/7] Ticket #48214 - ldapsearch on nsslapd-maxbersize returns + 0 instead of current value + +Description: If nsslapd-maxbersize is not explicitely set in cn=config +or the value is 0, the default value is assigned. Internally, it was. +But ldapsearch did not return the default value. + +https://fedorahosted.org/389/ticket/48214 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!) + +(cherry picked from commit 7d0689aaadfa66a8f8a481b0c1bb70b2465c4986) +(cherry picked from commit b83c2554fad0bb2a08055c5105bcfa4c9d44af8f) +--- + ldap/servers/slapd/libglobs.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c +index 24de4f3..a3c4243 100644 +--- a/ldap/servers/slapd/libglobs.c ++++ b/ldap/servers/slapd/libglobs.c +@@ -821,7 +821,7 @@ static struct config_get_and_set { + {CONFIG_MAXBERSIZE_ATTRIBUTE, config_set_maxbersize, + NULL, 0, + (void**)&global_slapdFrontendConfig.maxbersize, +- CONFIG_INT, NULL, DEFAULT_MAX_BERSIZE}, ++ CONFIG_INT, NULL, STRINGIFYDEFINE(DEFAULT_MAXBERSIZE)}, + {CONFIG_MAXSASLIOSIZE_ATTRIBUTE, config_set_maxsasliosize, + NULL, 0, + (void**)&global_slapdFrontendConfig.maxsasliosize, +@@ -1540,6 +1540,7 @@ FrontendConfig_init () { + init_cn_uses_dn_syntax_in_dns = cfg->cn_uses_dn_syntax_in_dns = LDAP_OFF; + init_global_backend_local = LDAP_OFF; + cfg->maxsimplepaged_per_conn = DEFAULT_MAXSIMPLEPAGED_PER_CONN; ++ cfg->maxbersize = DEFAULT_MAXBERSIZE; + #ifdef ENABLE_NUNC_STANS + init_enable_nunc_stans = cfg->enable_nunc_stans = LDAP_OFF; + #endif +@@ -5713,6 +5714,9 @@ config_set_maxbersize( const char *attrname, char *value, char *errorbuf, int ap + return retVal; + } + ++ if (size == 0) { ++ size = DEFAULT_MAXBERSIZE; ++ } + CFG_LOCK_WRITE(slapdFrontendConfig); + + slapdFrontendConfig->maxbersize = size; +@@ -5728,8 +5732,9 @@ config_get_maxbersize() + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + maxbersize = slapdFrontendConfig->maxbersize; +- if(maxbersize==0) ++ if (maxbersize == 0) { + maxbersize = DEFAULT_MAXBERSIZE; ++ } + + return maxbersize; + } +-- +1.9.3 + diff --git a/SOURCES/0006-Ticket-47895-If-no-effective-ciphers-are-available-d.patch b/SOURCES/0006-Ticket-47895-If-no-effective-ciphers-are-available-d.patch deleted file mode 100644 index 06cfdd1..0000000 --- a/SOURCES/0006-Ticket-47895-If-no-effective-ciphers-are-available-d.patch +++ /dev/null @@ -1,96 +0,0 @@ -From dd2dc9218ec91589f03c89f4f38fe2927bf5e3ab Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 10 Sep 2014 18:56:43 -0700 -Subject: [PATCH 6/7] Ticket #47895 - If no effective ciphers are available, - disable security setting. - -Description: If nsslapd-security is "on" and nsSSL3Ciphers is given -AND none of the ciphers are available or some syntax error is detected, -the server sets nsslapd-security "off" and starts up. - -https://fedorahosted.org/389/ticket/47895 - -Reviewed by nkinder@redhat.com (Thank you, Nathan!!) - -(cherry picked from commit 0f1a203a0fe85f3cf0440006685f63409502f093) -(cherry picked from commit cad5b96507caf9e08a12285c52d0353f8e6dcc3b) ---- - ldap/servers/slapd/main.c | 42 ++++++++++++++++++++++++++++++------------ - 1 file changed, 30 insertions(+), 12 deletions(-) - -diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c -index d577514..6bad2a0 100644 ---- a/ldap/servers/slapd/main.c -+++ b/ldap/servers/slapd/main.c -@@ -3077,6 +3077,24 @@ slapd_debug_level_usage( void ) - } - #endif /* LDAP_DEBUG */ - -+static int -+force_to_disable_security(const char *what, int *init_ssl, daemon_ports_t *ports_info) -+{ -+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; -+ errorbuf[0] = '\0'; -+ -+ LDAPDebug2Args(LDAP_DEBUG_ANY, "ERROR: %s Initialization Failed. Disabling %s.\n", what, what); -+ ports_info->s_socket = SLAPD_INVALID_SOCKET; -+ ports_info->s_port = 0; -+ *init_ssl = 0; -+ if (config_set_security(CONFIG_SECURITY_ATTRIBUTE, "off", errorbuf, 1)) { -+ LDAPDebug2Args(LDAP_DEBUG_ANY, "ERROR: Failed to disable %s: \"%s\".\n", -+ CONFIG_SECURITY_ATTRIBUTE, errorbuf[0]?errorbuf:"no error message"); -+ return 1; -+ } -+ return 0; -+} -+ - /* - This function does all NSS and SSL related initialization - required during startup. We use this function rather -@@ -3113,20 +3131,20 @@ slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt, - * modules can assume NSS is available - */ - if ( slapd_nss_init((slapd_exemode == SLAPD_EXEMODE_SLAPD), -- (slapd_exemode != SLAPD_EXEMODE_REFERRAL) /* have config? */ )) { -- LDAPDebug(LDAP_DEBUG_ANY, -- "ERROR: NSS Initialization Failed.\n", 0, 0, 0); -- return 1; -+ (slapd_exemode != SLAPD_EXEMODE_REFERRAL) /* have config? */ )) { -+ if (force_to_disable_security("NSS", &init_ssl, ports_info)) { -+ return 1; -+ } - } - - if (slapd_exemode == SLAPD_EXEMODE_SLAPD) { - client_auth_init(); - } - -- if ( init_ssl && ( 0 != slapd_ssl_init())) { -- LDAPDebug(LDAP_DEBUG_ANY, -- "ERROR: SSL Initialization Failed.\n", 0, 0, 0 ); -- return 1; -+ if (init_ssl && slapd_ssl_init()) { -+ if (force_to_disable_security("SSL", &init_ssl, ports_info)) { -+ return 1; -+ } - } - - if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) || -@@ -3134,10 +3152,10 @@ slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt, - if ( init_ssl ) { - PRFileDesc **sock; - for (sock = ports_info->s_socket; sock && *sock; sock++) { -- if ( 0 != slapd_ssl_init2(sock, 0) ) { -- LDAPDebug(LDAP_DEBUG_ANY, -- "ERROR: SSL Initialization phase 2 Failed.\n", 0, 0, 0 ); -- return 1; -+ if ( slapd_ssl_init2(sock, 0) ) { -+ if (force_to_disable_security("SSL2", &init_ssl, ports_info)) { -+ return 1; -+ } - } - } - } --- -1.9.3 - diff --git a/SOURCES/0006-Ticket-48214-CI-test-added-test-cases-for-ticket-482.patch b/SOURCES/0006-Ticket-48214-CI-test-added-test-cases-for-ticket-482.patch new file mode 100644 index 0000000..a90e65d --- /dev/null +++ b/SOURCES/0006-Ticket-48214-CI-test-added-test-cases-for-ticket-482.patch @@ -0,0 +1,197 @@ +From b36cdf27f313bba70f03b687ceef5bb5b3edd78b Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 2 Jul 2015 16:07:14 -0700 +Subject: [PATCH 6/7] Ticket #48214 - CI test: added test cases for ticket + 48213 + +Description: ldapsearch on nsslapd-maxbersize returns 0 instead of + current value + +https://fedorahosted.org/389/ticket/48214 +(cherry picked from commit b7b663c0e20c2f9bf8885bd7633570dc8d34f394) +(cherry picked from commit 7c73adc28c8877eb3b0d30a91f7fa8a964fb3fd2) +--- + dirsrvtests/tickets/ticket48214_test.py | 171 ++++++++++++++++++++++++++++++++ + 1 file changed, 171 insertions(+) + create mode 100644 dirsrvtests/tickets/ticket48214_test.py + +diff --git a/dirsrvtests/tickets/ticket48214_test.py b/dirsrvtests/tickets/ticket48214_test.py +new file mode 100644 +index 0000000..afbef22 +--- /dev/null ++++ b/dirsrvtests/tickets/ticket48214_test.py +@@ -0,0 +1,171 @@ ++import os ++import sys ++import time ++import ldap ++import logging ++import pytest ++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 ldap.controls import SimplePagedResultsControl ++ ++log = logging.getLogger(__name__) ++ ++installation_prefix = None ++ ++MYSUFFIX = 'dc=example,dc=com' ++MYSUFFIXBE = 'userRoot' ++ ++class TopologyStandalone(object): ++ def __init__(self, standalone): ++ standalone.open() ++ self.standalone = standalone ++ ++ ++@pytest.fixture(scope="module") ++def topology(request): ++ ''' ++ This fixture is used to standalone topology for the 'module'. ++ ''' ++ global installation_prefix ++ ++ if installation_prefix: ++ args_instance[SER_DEPLOYED_DIR] = installation_prefix ++ ++ standalone = DirSrv(verbose=False) ++ ++ # Args for the standalone instance ++ args_instance[SER_HOST] = HOST_STANDALONE ++ args_instance[SER_PORT] = PORT_STANDALONE ++ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE ++ args_standalone = args_instance.copy() ++ standalone.allocate(args_standalone) ++ ++ # Get the status of the instance and restart it if it exists ++ instance_standalone = standalone.exists() ++ ++ # Remove the instance ++ if instance_standalone: ++ standalone.delete() ++ ++ # Create the instance ++ standalone.create() ++ ++ # Used to retrieve configuration information (dbdir, confdir...) ++ standalone.open() ++ ++ # clear the tmp directory ++ standalone.clearTmpDir(__file__) ++ ++ # Here we have standalone instance up and running ++ return TopologyStandalone(standalone) ++ ++def getMaxBerSizeFromDseLdif(topology): ++ topology.standalone.log.info(" +++++ Get maxbersize from dse.ldif +++++\n") ++ dse_ldif = topology.standalone.confdir + '/dse.ldif' ++ grepMaxBerCMD = "egrep nsslapd-maxbersize " + dse_ldif ++ topology.standalone.log.info(" Run CMD: %s\n" % grepMaxBerCMD) ++ grepMaxBerOUT = os.popen(grepMaxBerCMD, "r") ++ running = True ++ maxbersize = -1 ++ while running: ++ l = grepMaxBerOUT.readline() ++ if l == "": ++ topology.standalone.log.info(" Empty: %s\n" % l) ++ running = False ++ elif "nsslapd-maxbersize:" in l.lower(): ++ running = False ++ fields = l.split() ++ if len(fields) >= 2: ++ maxbersize = fields[1] ++ topology.standalone.log.info(" Right format - %s %s\n" % (fields[0], fields[1])) ++ else: ++ topology.standalone.log.info(" Wrong format - %s\n" % l) ++ else: ++ topology.standalone.log.info(" Else?: %s\n" % l) ++ return maxbersize ++ ++def checkMaxBerSize(topology): ++ topology.standalone.log.info(" +++++ Check Max Ber Size +++++\n") ++ maxbersizestr = getMaxBerSizeFromDseLdif(topology) ++ maxbersize = int(maxbersizestr) ++ isdefault = True ++ defaultvalue = 2097152 ++ if maxbersize < 0: ++ topology.standalone.log.info(" No nsslapd-maxbersize found in dse.ldif\n") ++ elif maxbersize == 0: ++ topology.standalone.log.info(" nsslapd-maxbersize: %d\n" % maxbersize) ++ else: ++ isdefault = False ++ topology.standalone.log.info(" nsslapd-maxbersize: %d\n" % maxbersize) ++ ++ try: ++ entry = topology.standalone.search_s('cn=config', ldap.SCOPE_BASE, ++ "(cn=*)", ++ ['nsslapd-maxbersize']) ++ if entry: ++ searchedsize = entry[0].getValue('nsslapd-maxbersize') ++ topology.standalone.log.info(" ldapsearch returned nsslapd-maxbersize: %s\n" % searchedsize) ++ else: ++ topology.standalone.log.fatal('ERROR: cn=config is not found?') ++ assert False ++ except ldap.LDAPError, e: ++ topology.standalone.log.error('ERROR: Failed to search for user entry: ' + e.message['desc']) ++ assert False ++ ++ if isdefault: ++ topology.standalone.log.info(" Checking %d vs %d\n" % (int(searchedsize), defaultvalue)) ++ assert int(searchedsize) == defaultvalue ++ ++ ++def test_ticket48214_run(topology): ++ """ ++ Check ldapsearch returns the correct maxbersize when it is not explicitly set. ++ """ ++ log.info('Testing Ticket 48214 - ldapsearch on nsslapd-maxbersize returns 0 instead of current value') ++ ++ # bind as directory manager ++ topology.standalone.log.info("Bind as %s" % DN_DM) ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ ++ topology.standalone.log.info("\n\n######################### Out of Box ######################\n") ++ checkMaxBerSize(topology) ++ ++ topology.standalone.log.info("\n\n######################### Add nsslapd-maxbersize: 0 ######################\n") ++ topology.standalone.modify_s('cn=config', [(ldap.MOD_REPLACE, 'nsslapd-maxbersize', '0')]) ++ checkMaxBerSize(topology) ++ ++ topology.standalone.log.info("\n\n######################### Add nsslapd-maxbersize: 10000 ######################\n") ++ topology.standalone.modify_s('cn=config', [(ldap.MOD_REPLACE, 'nsslapd-maxbersize', '10000')]) ++ checkMaxBerSize(topology) ++ ++ topology.standalone.log.info("ticket48214 was successfully verified.") ++ ++ ++def test_ticket48214_final(topology): ++ topology.standalone.delete() ++ log.info('Testcase PASSED') ++ ++ ++def run_isolated(): ++ ''' ++ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) ++ To run isolated without py.test, you need to ++ - edit this file and comment '@pytest.fixture' line before 'topology' function. ++ - set the installation prefix ++ - run this program ++ ''' ++ global installation_prefix ++ installation_prefix = None ++ ++ topo = topology(True) ++ test_ticket48214_run(topo) ++ ++ test_ticket48214_final(topo) ++ ++ ++if __name__ == '__main__': ++ run_isolated() ++ +-- +1.9.3 + diff --git a/SOURCES/0007-Ticket-47889-DS-crashed-during-ipa-server-install-on.patch b/SOURCES/0007-Ticket-47889-DS-crashed-during-ipa-server-install-on.patch deleted file mode 100644 index a5c5bb4..0000000 --- a/SOURCES/0007-Ticket-47889-DS-crashed-during-ipa-server-install-on.patch +++ /dev/null @@ -1,48 +0,0 @@ -From ea4b10991ea02274cd4861a123494917c3f2e8d5 Mon Sep 17 00:00:00 2001 -From: "Thierry bordaz (tbordaz)" -Date: Thu, 11 Sep 2014 09:47:29 +0200 -Subject: [PATCH 7/7] Ticket 47889 - DS crashed during ipa-server-install on - test_ava_filter - -Bug Description: - During a MOD the target entry is duplicated and mods are applied - on the duplicated entry that is set in the pblock (SLAPI_MODIFY_EXISTING_ENTRY). - In case of transient DB error, ldbm_back_modify retries. - But when retrying the duplicated entry will be freed and needs to be duplicated again. - The new duplicated entry needs to be set in the pblock. - https://fedorahosted.org/389/ticket/47834 erronously skip the setting of SLAPI_MODIFY_EXISTING_ENTRY - -Fix Description: - Set SLAPI_MODIFY_EXISTING_ENTRY during mod/retry - -https://fedorahosted.org/389/ticket/47889 - -Reviewed by: ? - -Platforms tested: F20 - -Flag Day: no - -Doc impact: no - -(cherry picked from commit 3b5f3fa1b82cde2bda1104cf758acb64f6484009) -(cherry picked from commit 0363fa49265c0c27d510064cea361eb400802548) ---- - ldap/servers/slapd/back-ldbm/ldbm_modify.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -index 254ef29..529bd32 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -@@ -529,6 +529,7 @@ ldbm_back_modify( Slapi_PBlock *pb ) - CACHE_REMOVE(&inst->inst_cache, ec); - } - CACHE_RETURN(&inst->inst_cache, &ec); -+ slapi_pblock_set( pb, SLAPI_MODIFY_EXISTING_ENTRY, original_entry->ep_entry ); - ec = original_entry; - original_entry = tmpentry; - tmpentry = NULL; --- -1.9.3 - diff --git a/SOURCES/0007-Ticket-48192-Individual-abandoned-simple-paged-resul.patch b/SOURCES/0007-Ticket-48192-Individual-abandoned-simple-paged-resul.patch new file mode 100644 index 0000000..22f39e0 --- /dev/null +++ b/SOURCES/0007-Ticket-48192-Individual-abandoned-simple-paged-resul.patch @@ -0,0 +1,146 @@ +From 7b17c488de280f29264920b4e53dce862ed5b7e4 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Mon, 6 Jul 2015 14:06:11 -0700 +Subject: [PATCH 7/7] Ticket #48192 - Individual abandoned simple paged results + request has no chance to be cleaned up + +Description: There was a small window that the search on the next page +after the previous page abandoned referred the cleaned up simple paged +object. + +This patch introduces a pagedresults_is_abandoned helper function to +check the simple paged results was abandoned or not with some improvements +based upon the comments by rmeggins@redhat.com (Thank you!!): +1) adding locking when getting a simplepaged object in pagedresults_is_ + abandoned_or_notavailable as well as in pagedresults_{un}lock. +2) sending "Simple Paged Results Search abandoned" if the previous page + with the same cookie in the same connection was abandoned. + +https://fedorahosted.org/389/ticket/48192 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit e4d83c91fc88fcf9e6c823c608c629ac10e362f8) +(cherry picked from commit b513a502250f93cfb43df000c2140b27c4ef0d39) +--- + ldap/servers/slapd/opshared.c | 22 ++++++++++++++++------ + ldap/servers/slapd/pagedresults.c | 24 +++++++++++++++++++++++- + ldap/servers/slapd/proto-slap.h | 1 + + 3 files changed, 40 insertions(+), 7 deletions(-) + +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index 177daa6..dcdbb04 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -677,12 +677,20 @@ op_shared_search (Slapi_PBlock *pb, int send_result) + */ + pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx); + if (pr_search_result) { +- slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result ); +- rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat); ++ if (pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) { ++ pagedresults_unlock(pb->pb_conn, pr_idx); ++ /* Previous operation was abandoned and the simplepaged object is not in use. */ ++ send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); ++ rc = LDAP_SUCCESS; ++ goto free_and_return; ++ } else { ++ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result ); ++ rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat); + +- /* search result could be reset in the backend/dse */ +- slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); +- pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx); ++ /* search result could be reset in the backend/dse */ ++ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); ++ pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx); ++ } + } else { + pr_stat = PAGEDRESULTS_SEARCH_END; + } +@@ -712,7 +720,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result) + if (PAGEDRESULTS_SEARCH_END == pr_stat) { + pagedresults_lock(pb->pb_conn, pr_idx); + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); +- pagedresults_free_one(pb->pb_conn, operation, pr_idx); ++ if (!pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) { ++ pagedresults_free_one(pb->pb_conn, operation, pr_idx); ++ } + pagedresults_unlock(pb->pb_conn, pr_idx); + if (next_be) { + /* no more entries, but at least another backend */ +diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c +index fdbfa41..d0c93cd 100644 +--- a/ldap/servers/slapd/pagedresults.c ++++ b/ldap/servers/slapd/pagedresults.c +@@ -877,6 +877,8 @@ pagedresults_reset_processing(Connection *conn, int index) + * If there are multiple slots, the connection may be a permanent one. + * Do not return timed out here. But let the next request take care the + * timedout slot(s). ++ * ++ * must be called within conn->c_mutex + */ + int + pagedresults_is_timedout_nolock(Connection *conn) +@@ -905,7 +907,10 @@ pagedresults_is_timedout_nolock(Connection *conn) + return 0; + } + +-/* reset all timeout */ ++/* ++ * reset all timeout ++ * must be called within conn->c_mutex ++ */ + int + pagedresults_reset_timedout_nolock(Connection *conn) + { +@@ -968,7 +973,9 @@ pagedresults_lock( Connection *conn, int index ) + if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { + return; + } ++ PR_Lock(conn->c_mutex); + prp = conn->c_pagedresults.prl_list + index; ++ PR_Unlock(conn->c_mutex); + if (prp->pr_mutex) { + PR_Lock(prp->pr_mutex); + } +@@ -982,9 +989,24 @@ pagedresults_unlock( Connection *conn, int index ) + if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { + return; + } ++ PR_Lock(conn->c_mutex); + prp = conn->c_pagedresults.prl_list + index; ++ PR_Unlock(conn->c_mutex); + if (prp->pr_mutex) { + PR_Unlock(prp->pr_mutex); + } + return; + } ++ ++int ++pagedresults_is_abandoned_or_notavailable( Connection *conn, int index ) ++{ ++ PagedResults *prp; ++ if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { ++ return 1; /* not abandoned, but do not want to proceed paged results op. */ ++ } ++ PR_Lock(conn->c_mutex); ++ prp = conn->c_pagedresults.prl_list + index; ++ PR_Unlock(conn->c_mutex); ++ return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; ++} +diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h +index 57a2ce7..e8673e1 100644 +--- a/ldap/servers/slapd/proto-slap.h ++++ b/ldap/servers/slapd/proto-slap.h +@@ -1487,6 +1487,7 @@ int pagedresults_cleanup_all(Connection *conn, int needlock); + void op_set_pagedresults(Operation *op); + void pagedresults_lock(Connection *conn, int index); + void pagedresults_unlock(Connection *conn, int index); ++int pagedresults_is_abandoned_or_notavailable(Connection *conn, int index); + + /* + * sort.c +-- +1.9.3 + diff --git a/SOURCES/0008-Ticket-47892-coverity-defects-found-in-1.3.3.1.patch b/SOURCES/0008-Ticket-47892-coverity-defects-found-in-1.3.3.1.patch deleted file mode 100644 index 9527614..0000000 --- a/SOURCES/0008-Ticket-47892-coverity-defects-found-in-1.3.3.1.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 80ee43bf0f6ad4a8702f0695b9294a3797483ebe Mon Sep 17 00:00:00 2001 -From: Rich Megginson -Date: Fri, 12 Sep 2014 13:11:26 -0600 -Subject: [PATCH] Ticket #47892 coverity defects found in 1.3.3.1 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -https://fedorahosted.org/389/ticket/47892 -Reviewed by: mreynolds, nkinder (Thanks!) -Branch: rhel-7.1 -Fix Description: -9. 389-ds-base-1.3.3.1/ldap/servers/plugins/memberof/memberof.c:2079:var_compare_op – Comparing "group_norm_vals" to null implies that "group_norm_vals" might be null. -11. 389-ds-base-1.3.3.1/ldap/servers/plugins/memberof/memberof.c:2099:var_deref_model – Passing null pointer "group_norm_vals" to function "slapi_valueset_add_value_ext(Slapi_ValueSet *, Slapi_Value const *, unsigned long)", which dereferences it. -12. 389-ds-base-1.3.3.1/ldap/servers/slapd/valueset.c:896:2:deref_parm_in_call – Function "slapi_valueset_add_attr_valuearray_ext(Slapi_Attr const *, Slapi_ValueSet *, Slapi_Value **, int, unsigned long, int *)" dereferences "vs". -15. 389-ds-base-1.3.3.1/ldap/servers/slapd/valueset.c:1075:2:deref_parm – Directly dereferencing parameter "vs". - -Added a check for group_norm_vals == NULL at beginning of function. I think this had a chain effect causing 11, 12, and 15 as well. - -various - deprecated conversion from string constant - added const_cast as recommended by C++ guides. - -2. 389-ds-base-1.3.3.1/ldap/servers/slapd/back-ldbm/ldif2ldbm.c:2198:78:warning – 'j' may be used uninitialized in this function [-Wmaybe-uninitialized] - -Should have been using SLAPI_ATTR_TOMBSTONE_CSN - -2. 389-ds-base-1.3.3.1/ldap/servers/plugins/acl/aclparse.c:538:28:warning – 'is_target_to' may be used uninitialized in this function [-Wmaybe-uninitialized] - -2. 389-ds-base-1.3.3.1/ldap/servers/plugins/acl/acl.c:2493:26:warning – 'attrFilterArray' may be used uninitialized in this function [-Wmaybe-uninitialized] - -These are false positives. - -The minor memleaks were also fixed. - -Platforms tested: Fedora 20 -Flag Day: no -Doc impact: no - -(cherry picked from commit 66e43aee7151acf6939b1a646eb869c7ccf0f7a4) -(cherry picked from commit 6dc23ec794cd5644a40c223e7b66066f195d8d7d) ---- - ldap/servers/plugins/memberof/memberof.c | 6 +++--- - ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 2 +- - ldap/servers/slapd/tools/ldif.c | 5 ++++- - ldap/servers/slapd/tools/rsearch/nametable.c | 1 + - lib/base/pool.cpp | 10 +++++----- - lib/libaccess/aclcache.cpp | 2 +- - 6 files changed, 15 insertions(+), 11 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index 6549718..bd87ee9 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -2044,10 +2044,10 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) - goto bail; - } - -- if (!groupvals) -+ if (!groupvals || !group_norm_vals) - { - slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, -- "memberof_get_groups_callback: NULL groupvals\n"); -+ "memberof_get_groups_callback: NULL groupvals or group_norm_vals\n"); - rc = -1; - goto bail; - -@@ -2076,7 +2076,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) - * in config. We only need this attribute for it's syntax so the comparison can be - * performed. Since all of the grouping attributes are validated to use the Dinstinguished - * Name syntax, we can safely just use the first group_slapiattr. */ -- if (group_norm_vals && slapi_valueset_find( -+ if (slapi_valueset_find( - ((memberof_get_groups_data*)callback_data)->config->group_slapiattrs[0], group_norm_vals, group_ndn_val)) - { - /* we either hit a recursive grouping, or an entry is -diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c -index ab3a4a5..523da09 100644 ---- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c -+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c -@@ -2195,7 +2195,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) - if (task) { - slapi_task_log_notice(task, "%s: ERROR: failed to begin txn for " - "update index '%s' (err %d: %s)", -- inst->inst_name, indexAttrs[j], rc, -+ inst->inst_name, SLAPI_ATTR_TOMBSTONE_CSN, rc, - dblayer_strerror(rc)); - } - return_value = -2; -diff --git a/ldap/servers/slapd/tools/ldif.c b/ldap/servers/slapd/tools/ldif.c -index e8e6f9b..e4527ba 100644 ---- a/ldap/servers/slapd/tools/ldif.c -+++ b/ldap/servers/slapd/tools/ldif.c -@@ -142,7 +142,8 @@ int main( int argc, char **argv ) - } - - if (( out = ldif_type_and_value( type, val, cur )) == NULL ) { -- perror( "ldif_type_and_value" ); -+ perror( "ldif_type_and_value" ); -+ free( val ); - return( 1 ); - } - -@@ -166,6 +167,7 @@ int main( int argc, char **argv ) - maxlen *= 2; - if( (buf = (char *)realloc(buf, maxlen)) == NULL ) { - perror( "realloc" ); -+ free( buf ); - return( 1 ); - } - (void)fgets(buf+curlen, maxlen/2 + 1, stdin); -@@ -176,6 +178,7 @@ int main( int argc, char **argv ) - if (( out = ldif_type_and_value( type, buf, strlen( buf ) )) - == NULL ) { - perror( "ldif_type_and_value" ); -+ free( buf ); - return( 1 ); - } - fputs( out, stdout ); -diff --git a/ldap/servers/slapd/tools/rsearch/nametable.c b/ldap/servers/slapd/tools/rsearch/nametable.c -index 03a6ae1..9d56a34 100644 ---- a/ldap/servers/slapd/tools/rsearch/nametable.c -+++ b/ldap/servers/slapd/tools/rsearch/nametable.c -@@ -160,6 +160,7 @@ int nt_load(NameTable *nt, const char *filename) - free(s); - break; - } -+ free(s); - } - PR_Close(fd); - return nt->size; -diff --git a/lib/base/pool.cpp b/lib/base/pool.cpp -index 9ee1b8c..ab952d1 100644 ---- a/lib/base/pool.cpp -+++ b/lib/base/pool.cpp -@@ -178,7 +178,7 @@ _create_block(int size) - crit_exit(freelist_lock); - if (((newblock = (block_t *)PERM_MALLOC(sizeof(block_t))) == NULL) || - ((newblock->data = (char *)PERM_MALLOC(bytes)) == NULL)) { -- ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_)); -+ ereport(LOG_CATASTROPHE, const_cast("%s"), XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_)); - if (newblock) - PERM_FREE(newblock); - return NULL; -@@ -259,7 +259,7 @@ pool_create() - } - - if ( (newpool->curr_block =_create_block(BLOCK_SIZE)) == NULL) { -- ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolCreateOutOfMemory_)); -+ ereport(LOG_CATASTROPHE, const_cast("%s"), XP_GetAdminStr(DBT_poolCreateOutOfMemory_)); - PERM_FREE(newpool); - return NULL; - } -@@ -280,7 +280,7 @@ pool_create() - crit_exit(known_pools_lock); - } - else -- ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolCreateOutOfMemory_1)); -+ ereport(LOG_CATASTROPHE, const_cast("%s"), XP_GetAdminStr(DBT_poolCreateOutOfMemory_1)); - - return (pool_handle_t *)newpool; - } -@@ -386,7 +386,7 @@ pool_malloc(pool_handle_t *pool_handle, size_t size) - */ - blocksize = ( (size + BLOCK_SIZE-1) / BLOCK_SIZE ) * BLOCK_SIZE; - if ( (pool->curr_block = _create_block(blocksize)) == NULL) { -- ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolMallocOutOfMemory_)); -+ ereport(LOG_CATASTROPHE, const_cast("%s"), XP_GetAdminStr(DBT_poolMallocOutOfMemory_)); - #ifdef POOL_LOCKING - crit_exit(pool->lock); - #endif -@@ -408,7 +408,7 @@ pool_malloc(pool_handle_t *pool_handle, size_t size) - - void _pool_free_error() - { -- ereport(LOG_WARN, "%s", XP_GetAdminStr(DBT_freeUsedWherePermFreeShouldHaveB_)); -+ ereport(LOG_WARN, const_cast("%s"), XP_GetAdminStr(DBT_freeUsedWherePermFreeShouldHaveB_)); - - return; - } -diff --git a/lib/libaccess/aclcache.cpp b/lib/libaccess/aclcache.cpp -index 52e019b..a96b0c9 100644 ---- a/lib/libaccess/aclcache.cpp -+++ b/lib/libaccess/aclcache.cpp -@@ -133,7 +133,7 @@ ACL_ListHashInit() - &ACLPermAllocOps, - NULL); - if (ACLListHash == NULL) { -- ereport(LOG_SECURITY, "Unable to allocate ACL List Hash\n"); -+ ereport(LOG_SECURITY, const_cast("Unable to allocate ACL List Hash\n")); - return; - } - --- -1.9.3 - diff --git a/SOURCES/0008-Ticket-48119-setup-ds.pl-does-not-log-invalid-file-p.patch b/SOURCES/0008-Ticket-48119-setup-ds.pl-does-not-log-invalid-file-p.patch new file mode 100644 index 0000000..f0463b8 --- /dev/null +++ b/SOURCES/0008-Ticket-48119-setup-ds.pl-does-not-log-invalid-file-p.patch @@ -0,0 +1,71 @@ +From 7f10ea89c30944fc60a95d53e544caa005c03e0e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 6 Jul 2015 15:55:43 -0400 +Subject: [PATCH] Ticket 48119 - setup-ds.pl does not log invalid --file path + errors the same way as other errors. + +Bug Description: Errors occuring from Inf.pm are only written to STDERR + +Fix Description: Write errors from Inf.pm using the debug function + +https://fedorahosted.org/389/ticket/48119 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 6306fc4e8eb2fb5973360f550c83e3c9b220df5c) +(cherry picked from commit 5bd7119d8529e1c0b763c45e3ec7d1fb497da6c8) +--- + ldap/admin/src/scripts/Inf.pm | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/ldap/admin/src/scripts/Inf.pm b/ldap/admin/src/scripts/Inf.pm +index 98649ac..ec433e2 100644 +--- a/ldap/admin/src/scripts/Inf.pm ++++ b/ldap/admin/src/scripts/Inf.pm +@@ -12,6 +12,7 @@ + + package Inf; + ++use DSUtil; + use File::Temp qw(tempfile tempdir); + + #require Exporter; +@@ -59,7 +60,7 @@ sub read { + $inffh = \*STDIN; + } else { + if (!open(INF, $filename)) { +- print STDERR "Error: could not open inf file $filename: $!\n"; ++ debug(0, "Error: could not open inf file $filename: $!\n"); + return; + } + $inffh = \*INF; +@@ -124,7 +125,7 @@ sub section { + my $key = shift; + + if (!exists($self->{$key})) { +- print "Error: unknown inf section $key\n"; ++ debug(0, "Error: unknown inf section $key\n"); + return undef; + } + +@@ -187,7 +188,7 @@ sub write { + my $savemask = umask(0077); + if (!$fh) { + if (!open(INF, ">$filename")) { +- print STDERR "Error: could not write inf file $filename: $!\n"; ++ debug(0, "Error: could not write inf file $filename: $!\n"); + umask($savemask); + return; + } +@@ -232,7 +233,7 @@ sub updateFromArgs { + $argsinf->{$sec}->{$parm} = $val; + } + } else { # error +- print STDERR "Error: unknown command line option $arg\n"; ++ debug(0, "Error: unknown command line option $arg\n"); + return; + } + } +-- +1.9.3 + diff --git a/SOURCES/0009-Ticket-47750-Creating-a-glue-fails-if-one-above-leve.patch b/SOURCES/0009-Ticket-47750-Creating-a-glue-fails-if-one-above-leve.patch deleted file mode 100644 index a0d1616..0000000 --- a/SOURCES/0009-Ticket-47750-Creating-a-glue-fails-if-one-above-leve.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 1ccde69d778878e331311839d1c5d6be0bbfad26 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 22 Sep 2014 14:34:58 -0700 -Subject: [PATCH 09/14] Ticket #47750 - Creating a glue fails if one above - level is a conflict or missing - -Description: Poring changes made to 1.2.11 branch to newer versions. -1) Enabiling cache lock in cache_is_in_cache and cache_has_otherref. -2) Removing unused field new_entry_in_cache from "struct _modify_context". - -(cherry picked from commit 5ae13072330e9a769a5949b2e8a91085b38ac4e1) -(cherry picked from commit ef766784ed7d09aa81e82316b621e8490a368dc6) ---- - ldap/servers/slapd/back-ldbm/back-ldbm.h | 1 - - ldap/servers/slapd/back-ldbm/cache.c | 10 ++++++---- - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h -index 938d261..fd17453 100644 ---- a/ldap/servers/slapd/back-ldbm/back-ldbm.h -+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h -@@ -705,7 +705,6 @@ typedef struct _import_subcount_stuff import_subcount_stuff; - /* Handy structures for modify operations */ - - struct _modify_context { -- int new_entry_in_cache; - struct backentry *old_entry; - struct backentry *new_entry; - Slapi_Mods *smods; -diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c -index a98cf0c..4746204 100644 ---- a/ldap/servers/slapd/back-ldbm/cache.c -+++ b/ldap/servers/slapd/back-ldbm/cache.c -@@ -1506,10 +1506,12 @@ int cache_add_tentative(struct cache *cache, struct backentry *e, - { - return entrycache_add_int(cache, e, ENTRY_STATE_CREATING, alt); - } -+ - void cache_lock(struct cache *cache) - { - PR_EnterMonitor(cache->c_mutex); - } -+ - void cache_unlock(struct cache *cache) - { - PR_ExitMonitor(cache->c_mutex); -@@ -2095,9 +2097,9 @@ cache_has_otherref(struct cache *cache, void *ptr) - return hasref; - } - bep = (struct backcommon *)ptr; -- /* slows down too much? PR_Lock(cache->c_mutex); */ -+ cache_lock(cache); - hasref = bep->ep_refcnt; -- /* PR_Unlock(cache->c_mutex); */ -+ cache_unlock(cache); - return (hasref>1)?1:0; - } - -@@ -2111,8 +2113,8 @@ cache_is_in_cache(struct cache *cache, void *ptr) - return in_cache; - } - bep = (struct backcommon *)ptr; -- /* slows down too much? PR_Lock(cache->c_mutex); */ -+ cache_lock(cache); - in_cache = (bep->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE))?0:1; -- /* PR_Unlock(cache->c_mutex); */ -+ cache_unlock(cache); - return in_cache; - } --- -1.9.3 - diff --git a/SOURCES/0009-Ticket-48203-Fix-coverity-issues-07-07-2015.patch b/SOURCES/0009-Ticket-48203-Fix-coverity-issues-07-07-2015.patch new file mode 100644 index 0000000..18a0ca7 --- /dev/null +++ b/SOURCES/0009-Ticket-48203-Fix-coverity-issues-07-07-2015.patch @@ -0,0 +1,38 @@ +From 4b532c2fde59790981142e3245535a0176bb7e4f Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 7 Jul 2015 12:54:38 -0700 +Subject: [PATCH] Ticket #48203 - Fix coverity issues - 07/07/2015 + +Description: +1. Defect type: CLANG_WARNING + 389-ds-base-1.3.4.0/ldap/servers/slapd/conntable.c:161:11: warning: + Access to field 'c_ct' results in a dereference of a null pointer + (loaded from variable 'c') + +Thanks to rmeggins@redhat.com for the advice: +> PR_NewLock() returns NULL then the server is severely out of some +> resource (like RAM, stack space, etc.) and probably should just exit. + +https://fedorahosted.org/389/ticket/48203#comment:8 +(cherry picked from commit bca0908b1e10ada69cdc051d4aaceda73a940597) +(cherry picked from commit a741911c9a5090d78f7a81c475bea3f6593d72ad) +--- + ldap/servers/slapd/conntable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c +index 0364d94..d5b9058 100644 +--- a/ldap/servers/slapd/conntable.c ++++ b/ldap/servers/slapd/conntable.c +@@ -147,7 +147,7 @@ connection_table_get_connection(Connection_Table *ct, int sd) + c->c_mutex = NULL; + c->c_pdumutex = NULL; + LDAPDebug( LDAP_DEBUG_ANY,"PR_NewLock failed\n",0, 0, 0 ); +- c= NULL; ++ exit(1); + } + } + /* Let's make sure there's no cruft left on there from the last time this connection was used. */ +-- +1.9.3 + diff --git a/SOURCES/0010-Ticket-47908-389-ds-1.3.3.0-does-not-adjust-cipher-s.patch b/SOURCES/0010-Ticket-47908-389-ds-1.3.3.0-does-not-adjust-cipher-s.patch deleted file mode 100644 index 066ac23..0000000 --- a/SOURCES/0010-Ticket-47908-389-ds-1.3.3.0-does-not-adjust-cipher-s.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 0e32f3731887dbdf9c594a94fee693826f1a96de Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 23 Sep 2014 14:38:00 -0700 -Subject: [PATCH 10/14] Ticket #47908 - 389-ds 1.3.3.0 does not adjust cipher - suite configuration on upgrade, breaks itself and pki-server - -Description: -In the given cipher list: - nsSSL3Ciphers: +rsa_fips_3des_sha,+rsa_fips_des_sha,+rsa_3des_sha, - +rsa_rc4_128_md5,+rsa_des_sha,+rsa_rc2_40_md5,+rsa_rc4_40_md5, - +fortezza -there were 2 issues. -1) An old cipher suite name rsa_des_sha was not correctly mapped - to the name supported by NSS (TLS_RSA_WITH_DES_CBC_SHA) in the - mapping table. And the unsupported cipher name was not gracefully - skipped but returned an error. This patch fixes the mapped name - and the behaviour so that it skips the unknown/unsupported cipher. -2) A cipher "fortezza" is deprecated. It's now skipped with the - proper warning message. - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -https://fedorahosted.org/389/ticket/47908 -(cherry picked from commit 83a6ceb556e769f0d0a201f4a3d783ae3915c6bc) -(cherry picked from commit 4e347407887589635fe077fb6174d20d3d34c7c8) ---- - ldap/servers/slapd/ssl.c | 25 ++++++++++++++++--------- - 1 file changed, 16 insertions(+), 9 deletions(-) - -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 03b5904..4e38308 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -172,7 +172,7 @@ static lookup_cipher _lookup_cipher[] = { - {"tls_rsa_3des_sha", "TLS_RSA_WITH_3DES_EDE_CBC_SHA"}, - {"rsa_fips_3des_sha", "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, - {"fips_3des_sha", "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, -- {"rsa_des_sha", "SSL_RSA_WITH_DES_CBC_SHA"}, -+ {"rsa_des_sha", "TLS_RSA_WITH_DES_CBC_SHA"}, - {"rsa_fips_des_sha", "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, - {"fips_des_sha", "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, /* ditto */ - {"rsa_rc4_40_md5", "TLS_RSA_EXPORT_WITH_RC4_40_MD5"}, -@@ -455,7 +455,7 @@ _conf_setciphers(char *ciphers, int flags) - char *raw = ciphers; - char **suplist = NULL; - char **unsuplist = NULL; -- int lookup; -+ PRBool enabledOne = PR_FALSE; - - /* #47838: harden the list of ciphers available by default */ - /* Default is to activate all of them ==> none of them*/ -@@ -474,6 +474,7 @@ _conf_setciphers(char *ciphers, int flags) - * from the console - */ - _conf_setallciphers(CIPHER_SET_ALL|CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flags), &suplist, NULL); -+ enabledOne = PR_TRUE; - } else { - /* If "+all" is not in nsSSL3Ciphers value, disable all first, - * then enable specified ciphers. */ -@@ -499,7 +500,7 @@ _conf_setciphers(char *ciphers, int flags) - - if (strcasecmp(ciphers, "all")) { /* if not all */ - PRBool enabled = active ? PR_TRUE : PR_FALSE; -- lookup = 1; -+ int lookup = 1; - for (x = 0; _conf_ciphers[x].name; x++) { - if (!PL_strcasecmp(ciphers, _conf_ciphers[x].name)) { - if (_conf_ciphers[x].flags & CIPHER_IS_WEAK) { -@@ -558,6 +559,9 @@ _conf_setciphers(char *ciphers, int flags) - enabled = cipher_check_fips(x, NULL, &unsuplist); - } - } -+ if (enabled) { -+ enabledOne = PR_TRUE; /* At least one active cipher is set. */ -+ } - SSL_CipherPrefSetDefault(_conf_ciphers[x].num, enabled); - break; - } -@@ -566,15 +570,14 @@ _conf_setciphers(char *ciphers, int flags) - } - } - } -- if(!_conf_ciphers[x].name) { -- PR_snprintf(err, sizeof(err), "unknown cipher %s", ciphers); -- slapi_ch_free((void **)&suplist); /* strings inside are static */ -- slapi_ch_free((void **)&unsuplist); /* strings inside are static */ -- return slapi_ch_strdup(err); -+ if (!lookup && !_conf_ciphers[x].name) { /* If lookup, it's already reported. */ -+ slapd_SSL_warn("Cipher suite %s is not available in NSS %d.%d. Ignoring %s", -+ ciphers, NSS_VMAJOR, NSS_VMINOR, ciphers); - } - } -- if(t) -+ if(t) { - ciphers = t; -+ } - } - if (unsuplist && *unsuplist) { - char *strsup = charray2str(suplist, ","); -@@ -592,6 +595,10 @@ _conf_setciphers(char *ciphers, int flags) - slapi_ch_free((void **)&suplist); /* strings inside are static */ - slapi_ch_free((void **)&unsuplist); /* strings inside are static */ - -+ if (!enabledOne) { -+ char *nocipher = PR_smprintf("No active cipher suite is available."); -+ return nocipher; -+ } - _conf_dumpciphers(); - - return NULL; --- -1.9.3 - diff --git a/SOURCES/0010-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch b/SOURCES/0010-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch new file mode 100644 index 0000000..c025f60 --- /dev/null +++ b/SOURCES/0010-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch @@ -0,0 +1,808 @@ +From 46cd28db8402517febf0c5db4f2f869c491c41c0 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 8 Jul 2015 11:48:27 -0400 +Subject: [PATCH 10/20] Ticket 48208 - CleanAllRUV should completely purge + changelog + +Bug Description: After cleanAllRUV finishes, the changelog still + contains entries from the cleaned rid. Under certain + conditions this can allow the RUV to get polluted + again, and the ruv element will be missing the replica + url. + +Fix Description: At the end of the cleaning task, fire of a thread to + to completely purge the changelog of all entries + containing the cleaned rid. + + Also, improved the cleanAllRUV task when dealing + with a server shutdown - previously if the timing is + right the task can "delay/hang" the shutdown process. + +https://fedorahosted.org/389/ticket/48208 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit ff1c34538b0600259dba4801da2b2f0993fa5404) +(cherry picked from commit 9e4cf12cfbfde0761325b75c3fd5a8b39223760a) +--- + ldap/servers/plugins/replication/cl5_api.c | 447 ++++++++++++++++++--- + ldap/servers/plugins/replication/cl5_api.h | 5 +- + .../plugins/replication/repl5_replica_config.c | 44 +- + 3 files changed, 430 insertions(+), 66 deletions(-) + +diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c +index a10c3ac..ae23353 100644 +--- a/ldap/servers/plugins/replication/cl5_api.c ++++ b/ldap/servers/plugins/replication/cl5_api.c +@@ -319,14 +319,17 @@ static void _cl5TrimCleanup (); + static int _cl5TrimMain (void *param); + static void _cl5DoTrimming (ReplicaId rid); + static void _cl5CompactDBs(); +-static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid); ++static void _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid); ++static int _cl5PurgeGetFirstEntry (Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key); ++static int _cl5PurgeGetNextEntry (CL5Entry *entry, void *iterator, DBT *key); ++static void _cl5TrimFile (Object *obj, long *numToTrim); + static PRBool _cl5CanTrim (time_t time, long *numToTrim); + static int _cl5ReadRUV (const char *replGen, Object *obj, PRBool purge); + static int _cl5WriteRUV (CL5DBFile *file, PRBool purge); + static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge); + static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge); + static int _cl5GetRUV2Purge2 (Object *fileObj, RUV **ruv); +-void trigger_cl_trimming_thread(void *rid); ++void trigger_cl_purging_thread(void *rid); + + /* bakup/recovery, import/export */ + static int _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, +@@ -3470,9 +3473,17 @@ static void _cl5DoTrimming (ReplicaId rid) + trimmed more often than other. We might have to fix that by, for + example, randomizing starting point */ + obj = objset_first_obj (s_cl5Desc.dbFiles); +- while (obj && _cl5CanTrim ((time_t)0, &numToTrim)) ++ while (obj && (_cl5CanTrim ((time_t)0, &numToTrim) || rid)) + { +- _cl5TrimFile (obj, &numToTrim, rid); ++ if (rid){ ++ /* ++ * We are cleaning an invalid rid, and need to strip it ++ * from the changelog. ++ */ ++ _cl5PurgeRID (obj, rid); ++ } else { ++ _cl5TrimFile (obj, &numToTrim); ++ } + obj = objset_next_obj (s_cl5Desc.dbFiles, obj); + } + +@@ -3549,12 +3560,351 @@ bail: + return; + } + ++/* ++ * If the rid is not set it is the very first iteration of the changelog. ++ * If the rid is set, we are doing another pass, and we have a key as our ++ * starting point. ++ */ ++static int ++_cl5PurgeGetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key) ++{ ++ DBC *cursor = NULL; ++ DBT data = {0}; ++ CL5Iterator *it; ++ CL5DBFile *file; ++ int rc; ++ ++ file = (CL5DBFile*)object_get_data (obj); ++ ++ /* create cursor */ ++ rc = file->db->cursor(file->db, txnid, &cursor, 0); ++ if (rc != 0) ++ { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeGetFirstEntry: failed to create cursor; db error - %d %s\n", rc, db_strerror(rc)); ++ rc = CL5_DB_ERROR; ++ goto done; ++ } ++ ++ key->flags = DB_DBT_MALLOC; ++ data.flags = DB_DBT_MALLOC; ++ while ((rc = cursor->c_get(cursor, key, &data, rid?DB_SET:DB_NEXT)) == 0) ++ { ++ /* skip service entries on the first pass (rid == 0)*/ ++ if (!rid && cl5HelperEntry ((char*)key->data, NULL)) ++ { ++ slapi_ch_free(&key->data); ++ slapi_ch_free(&(data.data)); ++ continue; ++ } ++ ++ /* format entry */ ++ rc = cl5DBData2Entry(data.data, data.size, entry); ++ slapi_ch_free(&(data.data)); ++ if (rc != 0) ++ { ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, ++ "_cl5PurgeGetFirstEntry: failed to format entry: %d\n", rc); ++ goto done; ++ } ++ ++ it = (CL5Iterator*)slapi_ch_malloc(sizeof (CL5Iterator)); ++ it->cursor = cursor; ++ object_acquire (obj); ++ it->file = obj; ++ *(CL5Iterator**)iterator = it; ++ ++ return CL5_SUCCESS; ++ } ++ ++ slapi_ch_free(&key->data); ++ slapi_ch_free(&(data.data)); ++ ++ /* walked of the end of the file */ ++ if (rc == DB_NOTFOUND) ++ { ++ rc = CL5_NOTFOUND; ++ goto done; ++ } ++ ++ /* db error occured while iterating */ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeGetFirstEntry: failed to get entry; db error - %d %s\n", ++ rc, db_strerror(rc)); ++ rc = CL5_DB_ERROR; ++ ++done: ++ /* ++ * We didn't success in assigning this cursor to the iterator, ++ * so we need to free the cursor here. ++ */ ++ if (cursor) ++ cursor->c_close(cursor); ++ ++ return rc; ++} ++ ++/* ++ * Get the next entry. If we get a lock error we will restart the process ++ * starting at the current key. ++ */ ++static int ++_cl5PurgeGetNextEntry (CL5Entry *entry, void *iterator, DBT *key) ++{ ++ CL5Iterator *it; ++ DBT data={0}; ++ int rc; ++ ++ it = (CL5Iterator*) iterator; ++ ++ key->flags = DB_DBT_MALLOC; ++ data.flags = DB_DBT_MALLOC; ++ while ((rc = it->cursor->c_get(it->cursor, key, &data, DB_NEXT)) == 0) ++ { ++ if (cl5HelperEntry ((char*)key->data, NULL)) ++ { ++ slapi_ch_free(&key->data); ++ slapi_ch_free(&(data.data)); ++ continue; ++ } ++ ++ /* format entry */ ++ rc = cl5DBData2Entry (data.data, data.size, entry); ++ slapi_ch_free (&(data.data)); ++ if (rc != 0) ++ { ++ if (rc != CL5_DB_LOCK_ERROR){ ++ /* Not a lock error, free the key */ ++ slapi_ch_free(&key->data); ++ } ++ slapi_log_error(rc == CL5_DB_LOCK_ERROR?SLAPI_LOG_REPL:SLAPI_LOG_FATAL, ++ repl_plugin_name_cl, ++ "_cl5PurgeGetNextEntry: failed to format entry: %d\n", ++ rc); ++ ++ } ++ ++ return rc; ++ } ++ slapi_ch_free(&(data.data)); ++ ++ /* walked of the end of the file or entry is out of range */ ++ if (rc == 0 || rc == DB_NOTFOUND){ ++ slapi_ch_free(&key->data); ++ return CL5_NOTFOUND; ++ } ++ if (rc != CL5_DB_LOCK_ERROR){ ++ /* Not a lock error, free the key */ ++ slapi_ch_free(&key->data); ++ } ++ ++ /* cursor operation failed */ ++ slapi_log_error(rc == CL5_DB_LOCK_ERROR?SLAPI_LOG_REPL:SLAPI_LOG_FATAL, ++ repl_plugin_name_cl, ++ "_cl5PurgeGetNextEntry: failed to get entry; db error - %d %s\n", ++ rc, db_strerror(rc)); ++ ++ return rc; ++} ++ ++#define MAX_RETRIES 10 ++/* ++ * _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) ++ * ++ * Clean the entire changelog of updates from the "cleaned rid" via CLEANALLRUV ++ * Delete entries in batches so we don't consume too many db locks, and we don't ++ * lockup the changelog during the entire purging process using one transaction. ++ * We save the key from the last iteration so we don't have to start from the ++ * beginning for each new iteration. ++ */ ++static void ++_cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) ++{ ++ slapi_operation_parameters op = {0}; ++ ReplicaId csn_rid; ++ CL5Entry entry; ++ DB_TXN *txnid = NULL; ++ DBT key = {0}; ++ void *iterator = NULL; ++ long totalTrimmed = 0; ++ long trimmed = 0; ++ char *starting_key = NULL; ++ int batch_count = 0; ++ int db_lock_retry_count = 0; ++ int first_pass = 1; ++ int finished = 0; ++ int rc = 0; ++ ++ PR_ASSERT (obj); ++ entry.op = &op; ++ ++ /* ++ * Keep processing the changelog until we are done, shutting down, or we ++ * maxed out on the db lock retries. ++ */ ++ while (!finished && db_lock_retry_count < MAX_RETRIES && !slapi_is_shutting_down()){ ++ trimmed = 0; ++ ++ /* ++ * Sleep a bit to allow others to use the changelog - we can't hog the ++ * changelog for the entire purge. ++ */ ++ DS_Sleep(PR_MillisecondsToInterval(100)); ++ ++ rc = TXN_BEGIN(s_cl5Desc.dbEnv, NULL, &txnid, 0); ++ if (rc != 0){ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeRID: failed to begin transaction; db error - %d %s. " ++ "Changelog was not purged of rid(%d)\n", ++ rc, db_strerror(rc), cleaned_rid); ++ return; ++ } ++ ++ /* ++ * Check every changelog entry for the cleaned rid ++ */ ++ rc = _cl5PurgeGetFirstEntry(obj, &entry, &iterator, txnid, first_pass?0:cleaned_rid, &key); ++ first_pass = 0; ++ while (rc == CL5_SUCCESS && !slapi_is_shutting_down()) { ++ /* ++ * Store the new starting key - we need this starting key in case ++ * we run out of locks and have to start the transaction over. ++ */ ++ slapi_ch_free_string(&starting_key); ++ starting_key = slapi_ch_strdup((char*)key.data); ++ ++ if(trimmed == 10000 || (batch_count && trimmed == batch_count)){ ++ /* ++ * Break out, and commit these deletes. Do not free the key, ++ * we need it for the next pass. ++ */ ++ cl5_operation_parameters_done (&op); ++ db_lock_retry_count = 0; /* reset the retry count */ ++ break; ++ } ++ if(op.csn){ ++ csn_rid = csn_get_replicaid (op.csn); ++ if (csn_rid == cleaned_rid){ ++ rc = _cl5CurrentDeleteEntry (iterator); ++ if (rc != CL5_SUCCESS){ ++ /* log error */ ++ cl5_operation_parameters_done (&op); ++ if (rc == CL5_DB_LOCK_ERROR){ ++ /* ++ * Ran out of locks, need to restart the transaction. ++ * Reduce the the batch count and reset the key to ++ * the starting point ++ */ ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, ++ "_cl5PurgeRID: Ran out of db locks deleting entry. " ++ "Reduce the batch value and restart.\n"); ++ batch_count = trimmed - 10; ++ if (batch_count < 10){ ++ batch_count = 10; ++ } ++ trimmed = 0; ++ slapi_ch_free(&(key.data)); ++ key.data = starting_key; ++ starting_key = NULL; ++ db_lock_retry_count++; ++ break; ++ } else { ++ /* fatal error */ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeRID: fatal error (%d)\n", rc); ++ slapi_ch_free(&(key.data)); ++ finished = 1; ++ break; ++ } ++ } ++ trimmed++; ++ } ++ } ++ slapi_ch_free(&(key.data)); ++ cl5_operation_parameters_done (&op); ++ ++ rc = _cl5PurgeGetNextEntry (&entry, iterator, &key); ++ if (rc == CL5_DB_LOCK_ERROR){ ++ /* ++ * Ran out of locks, need to restart the transaction. ++ * Reduce the the batch count and reset the key to the starting ++ * point. ++ */ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeRID: Ran out of db locks getting the next entry. " ++ "Reduce the batch value and restart.\n"); ++ batch_count = trimmed - 10; ++ if (batch_count < 10){ ++ batch_count = 10; ++ } ++ trimmed = 0; ++ cl5_operation_parameters_done (&op); ++ slapi_ch_free(&(key.data)); ++ key.data = starting_key; ++ starting_key = NULL; ++ db_lock_retry_count++; ++ break; ++ } ++ } ++ ++ if (rc == CL5_NOTFOUND){ ++ /* Scanned the entire changelog, we're done */ ++ finished = 1; ++ } ++ ++ /* Destroy the iterator before we finish with the txn */ ++ cl5DestroyIterator (iterator); ++ ++ /* ++ * Commit or abort the txn ++ */ ++ if (rc == CL5_SUCCESS || rc == CL5_NOTFOUND){ ++ rc = TXN_COMMIT (txnid, 0); ++ if (rc != 0){ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeRID: failed to commit transaction; db error - %d %s. " ++ "Changelog was not completely purged of rid (%d)\n", ++ rc, db_strerror(rc), cleaned_rid); ++ break; ++ } else if (finished){ ++ /* We're done */ ++ totalTrimmed += trimmed; ++ break; ++ } else { ++ /* Not done yet */ ++ totalTrimmed += trimmed; ++ trimmed = 0; ++ } ++ } else { ++ rc = TXN_ABORT (txnid); ++ if (rc != 0){ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeRID: failed to abort transaction; db error - %d %s. " ++ "Changelog was not completely purged of rid (%d)\n", ++ rc, db_strerror(rc), cleaned_rid); ++ } ++ if (batch_count == 0){ ++ /* This was not a retry. Fatal error, break out */ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5PurgeRID: Changelog was not purged of rid (%d)\n", ++ cleaned_rid); ++ break; ++ } ++ } ++ } ++ slapi_ch_free_string(&starting_key); ++ ++ slapi_log_error (SLAPI_LOG_REPL, repl_plugin_name_cl, ++ "_cl5PurgeRID: Removed (%ld entries) that originated from rid (%d)\n", ++ totalTrimmed, cleaned_rid); ++} ++ + /* Note that each file contains changes for a single replicated area. + trimming algorithm: + */ + #define CL5_TRIM_MAX_PER_TRANSACTION 10 + +-static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) ++static void _cl5TrimFile (Object *obj, long *numToTrim) + { + DB_TXN *txnid; + RUV *ruv = NULL; +@@ -3577,7 +3927,6 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) + } + + entry.op = &op; +- + while ( !finished && !slapi_is_shutting_down() ) + { + it = NULL; +@@ -3598,7 +3947,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) + } + + finished = _cl5GetFirstEntry (obj, &entry, &it, txnid); +- while ( !finished ) ++ while ( !finished && !slapi_is_shutting_down()) + { + /* + * This change can be trimmed if it exceeds purge +@@ -3612,11 +3961,12 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) + continue; + } + csn_rid = csn_get_replicaid (op.csn); ++ + if ( (*numToTrim > 0 || _cl5CanTrim (entry.time, numToTrim)) && + ruv_covers_csn_strict (ruv, op.csn) ) + { + rc = _cl5CurrentDeleteEntry (it); +- if ( rc == CL5_SUCCESS && cleaned_rid != csn_rid) ++ if ( rc == CL5_SUCCESS) + { + rc = _cl5UpdateRUV (obj, op.csn, PR_FALSE, PR_TRUE); + } +@@ -3630,7 +3980,6 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) + /* The above two functions have logged the error */ + abort = PR_TRUE; + } +- + } + else + { +@@ -3687,7 +4036,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) + rc = TXN_ABORT (txnid); + if (rc != 0) + { +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "_cl5TrimFile: failed to abort transaction; db error - %d %s\n", + rc, db_strerror(rc)); + } +@@ -3698,7 +4047,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) + if (rc != 0) + { + finished = 1; +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "_cl5TrimFile: failed to commit transaction; db error - %d %s\n", + rc, db_strerror(rc)); + } +@@ -4722,9 +5071,9 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, + goto done; + } + #endif +- /* back off */ ++ /* back off */ + interval = PR_MillisecondsToInterval(slapi_rand() % 100); +- DS_Sleep(interval); ++ DS_Sleep(interval); + } + #if USE_DB_TXN + /* begin transaction */ +@@ -4770,19 +5119,19 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, + } + cnt ++; + } +- ++ + if (rc == 0) /* we successfully added entry */ + { + #if USE_DB_TXN + rc = TXN_COMMIT (txnid, 0); + #endif + } +- else ++ else + { +- char s[CSN_STRSIZE]; +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ char s[CSN_STRSIZE]; ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "_cl5WriteOperationTxn: failed to write entry with csn (%s); " +- "db error - %d %s\n", csn_as_string(op->csn,PR_FALSE,s), ++ "db error - %d %s\n", csn_as_string(op->csn,PR_FALSE,s), + rc, db_strerror(rc)); + #if USE_DB_TXN + rc = TXN_ABORT (txnid); +@@ -4803,7 +5152,7 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, + /* update purge vector if we have not seen any changes from this replica before */ + _cl5UpdateRUV (file_obj, op->csn, PR_TRUE, PR_TRUE); + +- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl, ++ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl, + "cl5WriteOperationTxn: successfully written entry with csn (%s)\n", csnStr); + rc = CL5_SUCCESS; + done: +@@ -4817,7 +5166,7 @@ done: + return rc; + } + +-static int _cl5WriteOperation(const char *replName, const char *replGen, ++static int _cl5WriteOperation(const char *replName, const char *replGen, + const slapi_operation_parameters *op, PRBool local) + { + return _cl5WriteOperationTxn(replName, replGen, op, local, NULL); +@@ -4868,7 +5217,7 @@ static int _cl5GetFirstEntry (Object *obj, CL5Entry *entry, void **iterator, DB_ + goto done; + } + +- it = (CL5Iterator*)slapi_ch_malloc (sizeof (CL5Iterator)); ++ it = (CL5Iterator*)slapi_ch_malloc(sizeof (CL5Iterator)); + it->cursor = cursor; + object_acquire (obj); + it->file = obj; +@@ -4943,7 +5292,7 @@ static int _cl5GetNextEntry (CL5Entry *entry, void *iterator) + slapi_ch_free (&(data.data)); + if (rc != 0) + { +- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "_cl5GetNextEntry: failed to format entry: %d\n", rc); + } + +@@ -4972,38 +5321,42 @@ static int _cl5GetNextEntry (CL5Entry *entry, void *iterator) + } + + /* cursor operation failed */ +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, +- "_cl5GetNextEntry: failed to get entry; db error - %d %s\n", +- rc, db_strerror(rc)); ++ slapi_log_error(rc == CL5_DB_LOCK_ERROR?SLAPI_LOG_REPL:SLAPI_LOG_FATAL, ++ repl_plugin_name_cl, ++ "_cl5GetNextEntry: failed to get entry; db error - %d %s\n", ++ rc, db_strerror(rc)); + +- return CL5_DB_ERROR; ++ return rc; + } + + static int _cl5CurrentDeleteEntry (void *iterator) + { + int rc; + CL5Iterator *it; +- CL5DBFile *file; ++ CL5DBFile *file; + +- PR_ASSERT (iterator); ++ PR_ASSERT (iterator); + + it = (CL5Iterator*)iterator; + + rc = it->cursor->c_del (it->cursor, 0); + + if (rc == 0) { +- /* decrement entry count */ +- file = (CL5DBFile*)object_get_data (it->file); +- PR_AtomicDecrement (&file->entryCount); +- return CL5_SUCCESS; +- } else { +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, +- "_cl5CurrentDeleteEntry failed, err=%d %s\n", +- rc, db_strerror(rc)); +- /* We don't free(close) the cursor here, as the caller will free it by a call to cl5DestroyIterator */ +- /* Freeing it here is a potential bug, as the cursor can't be referenced later once freed */ +- return CL5_DB_ERROR; +- } ++ /* decrement entry count */ ++ file = (CL5DBFile*)object_get_data (it->file); ++ PR_AtomicDecrement (&file->entryCount); ++ return CL5_SUCCESS; ++ } else { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, ++ "_cl5CurrentDeleteEntry failed, err=%d %s\n", ++ rc, db_strerror(rc)); ++ /* ++ * We don't free(close) the cursor here, as the caller will free it by ++ * a call to cl5DestroyIterator. Freeing it here is a potential bug, ++ * as the cursor can't be referenced later once freed. ++ */ ++ return rc; ++ } + } + + static PRBool _cl5IsValidIterator (const CL5Iterator *iterator) +@@ -6275,7 +6628,7 @@ static int _cl5ExportFile (PRFileDesc *prFile, Object *obj) + slapi_write_buffer (prFile, "\n", strlen("\n")); + + entry.op = &op; +- rc = _cl5GetFirstEntry (obj, &entry, &iterator, NULL); ++ rc = _cl5GetFirstEntry (obj, &entry, &iterator, NULL); + while (rc == CL5_SUCCESS) + { + rc = _cl5Operation2LDIF (&op, file->replGen, &buff, &len); +@@ -6696,16 +7049,16 @@ cl5CleanRUV(ReplicaId rid){ + slapi_rwlock_unlock (s_cl5Desc.stLock); + } + +-void trigger_cl_trimming(ReplicaId rid){ ++void trigger_cl_purging(ReplicaId rid){ + PRThread *trim_tid = NULL; + +- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "trigger_cl_trimming: rid (%d)\n",(int)rid); +- trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_trimming_thread, ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "trigger_cl_purging: rid (%d)\n",(int)rid); ++ trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_purging_thread, + (void *)&rid, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE); + if (NULL == trim_tid){ + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, +- "trigger_cl_trimming: failed to create trimming " ++ "trigger_cl_purging: failed to create trimming " + "thread; NSPR error - %d\n", PR_GetError ()); + } else { + /* need a little time for the thread to get started */ +@@ -6714,7 +7067,7 @@ void trigger_cl_trimming(ReplicaId rid){ + } + + void +-trigger_cl_trimming_thread(void *arg){ ++trigger_cl_purging_thread(void *arg){ + ReplicaId rid = *(ReplicaId *)arg; + + /* make sure we have a change log, and we aren't closing it */ +@@ -6723,7 +7076,7 @@ trigger_cl_trimming_thread(void *arg){ + } + if (CL5_SUCCESS != _cl5AddThread()) { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, +- "trigger_cl_trimming: failed to increment thread count " ++ "trigger_cl_purging: failed to increment thread count " + "NSPR error - %d\n", PR_GetError ()); + } + _cl5DoTrimming(rid); +diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h +index 5809570..4c3b8e8 100644 +--- a/ldap/servers/plugins/replication/cl5_api.h ++++ b/ldap/servers/plugins/replication/cl5_api.h +@@ -117,6 +117,9 @@ enum + CL5_CSN_ERROR, /* CSN API failed */ + CL5_RUV_ERROR, /* RUV API failed */ + CL5_OBJSET_ERROR, /* namedobjset api failed */ ++ CL5_DB_LOCK_ERROR, /* bdb returns error 12 when the db runs out of locks, ++ this var needs to be in slot 12 of the list. ++ Do not re-order enum above! */ + CL5_PURGED_DATA, /* requested data has been purged */ + CL5_MISSING_DATA, /* data should be in the changelog, but is missing */ + CL5_UNKNOWN_ERROR, /* unclassified error */ +@@ -464,6 +467,6 @@ int cl5WriteRUV(); + int cl5DeleteRUV(); + void cl5CleanRUV(ReplicaId rid); + void cl5NotifyCleanup(int rid); +-void trigger_cl_trimming(ReplicaId rid); ++void trigger_cl_purging(ReplicaId rid); + + #endif +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 660b134..faa86b8 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -1439,6 +1439,11 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not + */ + cl5CleanRUV(rid); + ++ /* ++ * Now purge the changelog ++ */ ++ trigger_cl_purging(rid); ++ + if (rc != RUV_SUCCESS){ + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_task: task failed(%d)\n",rc); + return LDAP_OPERATIONS_ERROR; +@@ -1837,7 +1842,7 @@ replica_cleanallruv_thread(void *arg) + /* no agmts, just clean this replica */ + break; + } +- while (agmt_obj){ ++ while (agmt_obj && !slapi_is_shutting_down()){ + agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ + agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj); +@@ -1919,13 +1924,15 @@ replica_cleanallruv_thread(void *arg) + break; + } + /* +- * need to sleep between passes ++ * Need to sleep between passes unless we are shutting down + */ +- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, "Replicas have not been cleaned yet, " +- "retrying in %d seconds", interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); ++ if (!slapi_is_shutting_down()){ ++ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, "Replicas have not been cleaned yet, " ++ "retrying in %d seconds", interval); ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; +@@ -1936,10 +1943,9 @@ replica_cleanallruv_thread(void *arg) + + done: + /* +- * If the replicas are cleaned, release the rid, and trim the changelog ++ * If the replicas are cleaned, release the rid + */ + if(!aborted){ +- trigger_cl_trimming(data->rid); + delete_cleaned_rid_config(data); + /* make sure all the replicas have been "pre_cleaned" before finishing */ + check_replicas_are_done_cleaning(data); +@@ -1949,7 +1955,7 @@ done: + /* + * Shutdown or abort + */ +- if(!is_task_aborted(data->rid)){ ++ if(!is_task_aborted(data->rid) || slapi_is_shutting_down()){ + cleanruv_log(data->task, data->rid, CLEANALLRUV_ID,"Server shutting down. Process will resume at server startup"); + } else { + cleanruv_log(data->task, data->rid, CLEANALLRUV_ID,"Task aborted for rid(%d).",data->rid); +@@ -2184,7 +2190,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn) + not_all_caughtup = 0; + break; + } +- while (agmt_obj){ ++ while (agmt_obj && !slapi_is_shutting_down()){ + agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ + agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj); +@@ -2242,7 +2248,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task) + not_all_alive = 0; + break; + } +- while (agmt_obj){ ++ while (agmt_obj && !slapi_is_shutting_down()){ + agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ + agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj); +@@ -3022,12 +3028,14 @@ replica_abort_task_thread(void *arg) + break; + } + /* +- * need to sleep between passes ++ * Need to sleep between passes. unless we are shutting down + */ +- cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID,"Retrying in %d seconds",interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); ++ if (!slapi_is_shutting_down()){ ++ cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID,"Retrying in %d seconds",interval); ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; +@@ -3045,7 +3053,7 @@ done: + * Wait for this server to stop its cleanallruv task(which removes the rid from the cleaned list) + */ + cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, "Waiting for CleanAllRUV task to abort..."); +- while(is_cleaned_rid(data->rid)){ ++ while(is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){ + DS_Sleep(PR_SecondsToInterval(1)); + count++; + if(count == 60){ /* it should not take this long */ +-- +1.9.3 + diff --git a/SOURCES/0011-Ticket-47799-Any-negative-LDAP-error-code-number-rep.patch b/SOURCES/0011-Ticket-47799-Any-negative-LDAP-error-code-number-rep.patch new file mode 100644 index 0000000..19dc5da --- /dev/null +++ b/SOURCES/0011-Ticket-47799-Any-negative-LDAP-error-code-number-rep.patch @@ -0,0 +1,224 @@ +From 3c2165deb45571a0ff0547e5c8c2c970095cca04 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 8 Jul 2015 10:19:15 -0700 +Subject: [PATCH 11/20] Ticket #47799 - Any negative LDAP error code number + reported as Illegal error by ldclt. + +Description: ldclt was implemented with mozldap, which did not expect +negative erorr codes, but openldap does. E.g., LDAP_FILTER_ERROR (-7) +This patch prepares a negativeError array for the negative error codes. +Example: + $ ldclt [...] -e esearch -e random -b "" -f "" -v + Filter = "" + ... + ldclt[16030]: T000: Cannot ldap_search(), error=-7 (Bad search filter) -- NULL result + ... + ldclt[16030]: Global error -7 (Bad search filter) occurs 1001 times + ldclt[16030]: Exit status 3 - Max errors reached. + +https://fedorahosted.org/389/ticket/47799 + +Reviewed by mreynolds@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 71be5faaa478593bb056887410ca8e48e05b2fe4) +(cherry picked from commit 0680a45773ab4b0e92ec26caa3acbb6bab379103) +--- + ldap/servers/slapd/tools/ldclt/ldapfct.c | 4 +++ + ldap/servers/slapd/tools/ldclt/ldclt.c | 35 ++++++++++++++++----- + ldap/servers/slapd/tools/ldclt/ldclt.h | 11 ++++++- + ldap/servers/slapd/tools/ldclt/threadMain.c | 48 +++++++++++++++++++---------- + 4 files changed, 73 insertions(+), 25 deletions(-) + +diff --git a/ldap/servers/slapd/tools/ldclt/ldapfct.c b/ldap/servers/slapd/tools/ldclt/ldapfct.c +index f906c5a..13e66b8 100644 +--- a/ldap/servers/slapd/tools/ldclt/ldapfct.c ++++ b/ldap/servers/slapd/tools/ldclt/ldapfct.c +@@ -1382,6 +1382,10 @@ printErrorFromLdap ( + printf ("ldclt[%d]: T%03d: %s, error=%d (%s", + mctx.pid, tttctx->thrdNum, errmsg, + errcode, my_ldap_err2string (errcode)); ++ if (!res) { ++ printf (") -- NULL result\n"); ++ return -1; ++ } + + /* + * See if there is an additional error message... +diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.c b/ldap/servers/slapd/tools/ldclt/ldclt.c +index edb687f..9e573a5 100644 +--- a/ldap/servers/slapd/tools/ldclt/ldclt.c ++++ b/ldap/servers/slapd/tools/ldclt/ldclt.c +@@ -716,19 +716,35 @@ printGlobalStatistics (void) + * Note: Maybe implement a way to stop the running threads ? + */ + found = 0; +- for (i=0 ; i 0) +- { ++ for (i = 0; i < MAX_ERROR_NB; i++) { ++ if (mctx.errors[i] > 0) { + found = 1; + sprintf (buf, "(%s)", my_ldap_err2string (i)); + printf ("ldclt[%d]: Global error %2d %s occurs %5d times\n", + mctx.pid, i, buf, mctx.errors[i]); + } ++ } ++#if defined(USE_OPENLDAP) ++ for (i = 0; i < ABS(NEGATIVE_MAX_ERROR_NB); i++) { ++ if (mctx.negativeErrors[i] > 0) { ++ found = 1; ++ sprintf (buf, "(%s)", my_ldap_err2string (-i)); ++ printf ("ldclt[%d]: Global error %2d %s occurs %5d times\n", ++ mctx.pid, -i, buf, mctx.negativeErrors[i]); ++ } ++ } ++#endif + if (mctx.errorsBad > 0) + { + found = 1; +- printf ("ldclt[%d]: Global illegal errors (codes not in [0, %d]) occurs %5d times\n", +- mctx.pid, MAX_ERROR_NB-1, mctx.errorsBad); ++ printf("ldclt[%d]: Global illegal errors (codes not in [%d, %d]) occurs %5d times\n", ++ mctx.pid, ++#if defined(USE_OPENLDAP) ++ NEGATIVE_MAX_ERROR_NB, ++#else ++ 0, ++#endif ++ MAX_ERROR_NB-1, mctx.errorsBad); + } + if (!found) + printf ("ldclt[%d]: Global no error occurs during this session.\n", mctx.pid); +@@ -1293,9 +1309,14 @@ basicInit (void) + mctx.totNbOpers = 0; + mctx.totNbSamples = 0; + mctx.errorsBad = 0; +- for (i=0 ; i 0) ? (x) : (-x)) ++#endif + /* + * Misc constant definitions + */ +@@ -183,7 +186,10 @@ dd/mm/yy | Author | Comments + #define DEF_PORT_CHECK 16000 /* Port used for check processing */ + #define MAX_ATTRIBS 40 /* Max number of attributes */ /*JLS 28-03-01*/ + #define MAX_DN_LENGTH 1024 /* Max length for a DN */ +-#define MAX_ERROR_NB 0x62 /* Max ldap err number + 1 */ ++#define MAX_ERROR_NB 0x7b /* Max ldap err number + 1 */ ++#if defined(USE_OPENLDAP) ++#define NEGATIVE_MAX_ERROR_NB (LDAP_X_CONNECTING - 1) /* Mininum ldap err number */ ++#endif + #define MAX_IGN_ERRORS 20 /* Max errors ignored */ + #define MAX_FILTER 512 /* Max filters length */ + #define MAX_THREADS 1000 /* Max number of threads */ /*JLS 21-11-00*/ +@@ -504,6 +510,9 @@ typedef struct main_context { + char *certfile; /* certificate file */ /* BK 11-10-00 */ + char *cltcertname; /* client cert name */ /* BK 23 11-00 */ + data_list_file *dlf; /* Data list files */ /*JLS 23-03-01*/ ++#if defined(USE_OPENLDAP) ++ int negativeErrors[ABS(NEGATIVE_MAX_ERROR_NB)]; /* Err stats */ ++#endif + int errors[MAX_ERROR_NB]; /* Err stats */ + int errorsBad; /* Bad errors */ + ldclt_mutex_t errors_mutex; /* Protect errors */ /*JLS 28-11-00*/ +diff --git a/ldap/servers/slapd/tools/ldclt/threadMain.c b/ldap/servers/slapd/tools/ldclt/threadMain.c +index be41186..5d915fd 100644 +--- a/ldap/servers/slapd/tools/ldclt/threadMain.c ++++ b/ldap/servers/slapd/tools/ldclt/threadMain.c +@@ -430,14 +430,26 @@ addErrorStat ( + /* + * Update the counters + */ ++#if defined(USE_OPENLDAP) ++ if ((err <= NEGATIVE_MAX_ERROR_NB) || (err >= MAX_ERROR_NB)) ++#else + if ((err <= 0) || (err >= MAX_ERROR_NB)) ++#endif + { + fprintf (stderr, "ldclt[%d]: Illegal error number %d\n", mctx.pid, err); + fflush (stderr); + mctx.errorsBad++; + } ++#if defined(USE_OPENLDAP) ++ else if (err < 0) ++ { ++ mctx.negativeErrors[abs(err)]++; ++ } ++#endif + else ++ { + mctx.errors[err]++; ++ } + + /* + * Release the mutex +@@ -460,26 +472,28 @@ addErrorStat ( + * Ok, we should not ignore this error... + * Maybe the limit is reached ? + */ ++#if defined(USE_OPENLDAP) ++ if ((err <= NEGATIVE_MAX_ERROR_NB) || (err >= MAX_ERROR_NB)) ++#else + if ((err <= 0) || (err >= MAX_ERROR_NB)) +- { +- if (mctx.errorsBad > mctx.maxErrors) +- { +- printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); +- (void) printGlobalStatistics(); /*JLS 25-08-00*/ +- fflush (stdout); +- ldclt_sleep (5); +- ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/ ++#endif ++ { ++ if (mctx.errorsBad > mctx.maxErrors) { ++ printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); ++ (void) printGlobalStatistics(); /*JLS 25-08-00*/ ++ fflush (stdout); ++ ldclt_sleep (5); ++ ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/ + } +- } +- else +- if (mctx.errors[err] > mctx.maxErrors) +- { +- printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); +- (void) printGlobalStatistics(); /*JLS 25-08-00*/ +- fflush (stdout); +- ldclt_sleep (5); +- ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/ ++ } else { ++ if (mctx.errors[err] + mctx.negativeErrors[abs(err)] > mctx.maxErrors) { ++ printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); ++ (void) printGlobalStatistics(); /*JLS 25-08-00*/ ++ fflush (stdout); ++ ldclt_sleep (5); ++ ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/ + } ++ } + } + + /* +-- +1.9.3 + diff --git a/SOURCES/0011-Ticket-47838-harden-the-list-of-ciphers-available-by.patch b/SOURCES/0011-Ticket-47838-harden-the-list-of-ciphers-available-by.patch deleted file mode 100644 index 865d197..0000000 --- a/SOURCES/0011-Ticket-47838-harden-the-list-of-ciphers-available-by.patch +++ /dev/null @@ -1,154 +0,0 @@ -From afffe2dde82708b7c4837d5823cbb624a143dd7d Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 25 Sep 2014 13:38:03 -0700 -Subject: [PATCH 11/14] Ticket #47838 - harden the list of ciphers available by - default (phase 2) - -Description: -1) By default (i.e., no explicit allowWeakCipher set in cn=encryption,cn=config), - allowWeakCipher is on for user specified cipher list - allowWeakCipher is off for "+all" and "default" -2) Fixed enabled allowWeakCipher (explicitly set "on" to it) is - applied to "+all" and "default". -3) If an invalid value is set to allowWeakCipher, this message is - logged in the error log and set it to the default value. - SSL alert: The value of allowWeakCipher "poor" in cn=encryption, - cn=config is invalid. Ignoring it and set it to default. - -https://fedorahosted.org/389/ticket/47838 - -Reviewed by tbordaz@redhat.com (Thank you, Thierry!) - -(cherry picked from commit c6febe325a1b5a0e4f7e7e59bcc076c9e4a3b825) -(cherry picked from commit 411ca8f1cc5aade2fbe7d9f91aff8c658f5e8248) ---- - ldap/servers/slapd/ssl.c | 60 +++++++++++++++++++++++++++++++++++------------- - 1 file changed, 44 insertions(+), 16 deletions(-) - -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 4e38308..28ff475 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -120,18 +120,34 @@ static char * configDN = "cn=encryption,cn=config"; - - /* ----------------------- Multiple cipher support ------------------------ */ - /* cipher set flags */ --#define CIPHER_SET_ALL 0x1 --#define CIPHER_SET_NONE 0x0 --#define CIPHER_SET_DEFAULT 0x2 --#define CIPHER_SET_CORE (CIPHER_SET_ALL|CIPHER_SET_DEFAULT|CIPHER_SET_NONE) --#define CIPHER_SET_ALLOWWEAKCIPHER 0x10 /* can be or'ed with other CIPHER_SET flags */ -+#define CIPHER_SET_NONE 0x0 -+#define CIPHER_SET_ALL 0x1 -+#define CIPHER_SET_DEFAULT 0x2 -+#define CIPHER_SET_DEFAULTWEAKCIPHER 0x10 /* allowWeakCipher is not set in cn=encryption */ -+#define CIPHER_SET_ALLOWWEAKCIPHER 0x20 /* allowWeakCipher is on */ -+#define CIPHER_SET_DISALLOWWEAKCIPHER 0x40 /* allowWeakCipher is off */ - - #define CIPHER_SET_ISDEFAULT(flag) \ -- ((((flag)&CIPHER_SET_CORE) == CIPHER_SET_DEFAULT) ? PR_TRUE : PR_FALSE) -+ (((flag)&CIPHER_SET_DEFAULT) ? PR_TRUE : PR_FALSE) - #define CIPHER_SET_ISALL(flag) \ -- ((((flag)&CIPHER_SET_CORE) == CIPHER_SET_ALL) ? PR_TRUE : PR_FALSE) --#define CIPHER_SET_ALLOWSWEAKCIPHER(flag) \ -+ (((flag)&CIPHER_SET_ALL) ? PR_TRUE : PR_FALSE) -+ -+#define ALLOWWEAK_ISDEFAULT(flag) \ -+ (((flag)&CIPHER_SET_DEFAULTWEAKCIPHER) ? PR_TRUE : PR_FALSE) -+#define ALLOWWEAK_ISON(flag) \ - (((flag)&CIPHER_SET_ALLOWWEAKCIPHER) ? PR_TRUE : PR_FALSE) -+#define ALLOWWEAK_ISOFF(flag) \ -+ (((flag)&CIPHER_SET_DISALLOWWEAKCIPHER) ? PR_TRUE : PR_FALSE) -+/* -+ * If ISALL or ISDEFAULT, allowWeakCipher is true only if CIPHER_SET_ALLOWWEAKCIPHER. -+ * Otherwise (user specified cipher list), allowWeakCipher is true -+ * if CIPHER_SET_ALLOWWEAKCIPHER or CIPHER_SET_DEFAULTWEAKCIPHER. -+ */ -+#define CIPHER_SET_ALLOWSWEAKCIPHER(flag) \ -+ ((CIPHER_SET_ISDEFAULT(flag)|CIPHER_SET_ISALL(flag)) ? \ -+ (ALLOWWEAK_ISON(flag) ? PR_TRUE : PR_FALSE) : \ -+ (!ALLOWWEAK_ISOFF(flag) ? PR_TRUE : PR_FALSE)) -+ - #define CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flag) \ - ((flag)&~CIPHER_SET_ALLOWWEAKCIPHER) - -@@ -460,7 +476,7 @@ _conf_setciphers(char *ciphers, int flags) - /* #47838: harden the list of ciphers available by default */ - /* Default is to activate all of them ==> none of them*/ - if (!ciphers || (ciphers[0] == '\0') || !PL_strcasecmp(ciphers, "default")) { -- _conf_setallciphers((CIPHER_SET_DEFAULT|CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flags)), NULL, NULL); -+ _conf_setallciphers((CIPHER_SET_DEFAULT|flags), NULL, NULL); - slapd_SSL_warn("Security Initialization: Enabling default cipher set."); - _conf_dumpciphers(); - return NULL; -@@ -473,7 +489,7 @@ _conf_setciphers(char *ciphers, int flags) - * set of ciphers in the table. Right now there is no support for this - * from the console - */ -- _conf_setallciphers(CIPHER_SET_ALL|CIPHER_SET_DISABLE_ALLOWSWEAKCIPHER(flags), &suplist, NULL); -+ _conf_setallciphers((CIPHER_SET_ALL|flags), &suplist, NULL); - enabledOne = PR_TRUE; - } else { - /* If "+all" is not in nsSSL3Ciphers value, disable all first, -@@ -504,7 +520,7 @@ _conf_setciphers(char *ciphers, int flags) - for (x = 0; _conf_ciphers[x].name; x++) { - if (!PL_strcasecmp(ciphers, _conf_ciphers[x].name)) { - if (_conf_ciphers[x].flags & CIPHER_IS_WEAK) { -- if (CIPHER_SET_ALLOWSWEAKCIPHER(flags)) { -+ if (active && CIPHER_SET_ALLOWSWEAKCIPHER(flags)) { - slapd_SSL_warn("Cipher %s is weak. It is enabled since allowWeakCipher is \"on\" " - "(default setting for the backward compatibility). " - "We strongly recommend to set it to \"off\". " -@@ -522,6 +538,9 @@ _conf_setciphers(char *ciphers, int flags) - check fips. */ - enabled = cipher_check_fips(x, NULL, &unsuplist); - } -+ if (enabled) { -+ enabledOne = PR_TRUE; /* At least one active cipher is set. */ -+ } - SSL_CipherPrefSetDefault(_conf_ciphers[x].num, enabled); - lookup = 0; - break; -@@ -539,7 +558,7 @@ _conf_setciphers(char *ciphers, int flags) - if (!PL_strcasecmp(_lookup_cipher[i].name, _conf_ciphers[x].name)) { - if (enabled) { - if (_conf_ciphers[x].flags & CIPHER_IS_WEAK) { -- if (CIPHER_SET_ALLOWSWEAKCIPHER(flags)) { -+ if (active && CIPHER_SET_ALLOWSWEAKCIPHER(flags)) { - slapd_SSL_warn("Cipher %s is weak. " - "It is enabled since allowWeakCipher is \"on\" " - "(default setting for the backward compatibility). " -@@ -1065,7 +1084,7 @@ slapd_ssl_init() - int rv = 0; - PK11SlotInfo *slot; - Slapi_Entry *entry = NULL; -- int allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; -+ int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER; - - /* Get general information */ - -@@ -1105,9 +1124,18 @@ slapd_ssl_init() - } - - val = slapi_entry_attr_get_charptr(entry, "allowWeakCipher"); -- if (val && (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -- !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no"))) { -- allowweakcipher = 0; -+ if (val) { -+ if (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -+ !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no")) { -+ allowweakcipher = CIPHER_SET_DISALLOWWEAKCIPHER; -+ } else if (!PL_strcasecmp(val, "on") || !PL_strcasecmp(val, "true") || -+ !PL_strcmp(val, "1") || !PL_strcasecmp(val, "yes")) { -+ allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; -+ } else { -+ slapd_SSL_warn("The value of allowWeakCipher \"%s\" in " -+ "cn=encryption,cn=config is invalid. " -+ "Ignoring it and set it to default.", val); -+ } - } - slapi_ch_free((void **) &val); - --- -1.9.3 - diff --git a/SOURCES/0012-Ticket-47838-CI-test-adjusted-test-cases-based-on-th.patch b/SOURCES/0012-Ticket-47838-CI-test-adjusted-test-cases-based-on-th.patch deleted file mode 100644 index 63d9653..0000000 --- a/SOURCES/0012-Ticket-47838-CI-test-adjusted-test-cases-based-on-th.patch +++ /dev/null @@ -1,215 +0,0 @@ -From d5d6836c9935fe4393e1d2b991271bf7ee53c609 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 24 Sep 2014 15:47:02 -0700 -Subject: [PATCH 12/14] Ticket 47838 - CI test: adjusted test cases based on - the phase 2 fixes for ticket 47838 - -https://fedorahosted.org/389/ticket/47838 -(cherry picked from commit c6c73e674ecf79fc7404758f90f4837f04bdbed0) -(cherry picked from commit b5ce880cc7e6df5f2a1d4bd24de2ce107cf1a5fe) ---- - dirsrvtests/tickets/ticket47838_test.py | 68 ++++++++++++++++++++------------- - 1 file changed, 41 insertions(+), 27 deletions(-) - -diff --git a/dirsrvtests/tickets/ticket47838_test.py b/dirsrvtests/tickets/ticket47838_test.py -index 0e406f3..1575376 100644 ---- a/dirsrvtests/tickets/ticket47838_test.py -+++ b/dirsrvtests/tickets/ticket47838_test.py -@@ -25,6 +25,8 @@ LDAPSPORT = '10636' - SERVERCERT = 'Server-Cert' - plus_all_ecount = 0 - plus_all_dcount = 0 -+plus_all_ecount_noweak = 0 -+plus_all_dcount_noweak = 0 - - class TopologyStandalone(object): - def __init__(self, standalone): -@@ -220,7 +222,7 @@ def test_ticket47838_run_0(topology): - All ciphers are enabled except null. - Note: allowWeakCipher: on - """ -- _header(topology, 'Test Case 1 - Check the ciphers availability for "+all"') -+ _header(topology, 'Test Case 1 - Check the ciphers availability for "+all"; allowWeakCipher: on') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '64')]) -@@ -235,8 +237,8 @@ def test_ticket47838_run_0(topology): - - log.info("Enabled ciphers: %d" % ecount) - log.info("Disabled ciphers: %d" % dcount) -- assert ecount >= 31 -- assert dcount <= 36 -+ assert ecount >= 60 -+ assert dcount <= 7 - global plus_all_ecount - global plus_all_dcount - plus_all_ecount = ecount -@@ -250,9 +252,9 @@ def test_ticket47838_run_1(topology): - """ - Check nsSSL3Ciphers: +all - All ciphers are enabled except null. -- Note: allowWeakCipher: off for +all -+ Note: default allowWeakCipher (i.e., off) for +all - """ -- _header(topology, 'Test Case 2 - Check the ciphers availability for "+all" with not allowing WeakCiphers') -+ _header(topology, 'Test Case 2 - Check the ciphers availability for "+all" with default allowWeakCiphers') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '64')]) -@@ -271,6 +273,11 @@ def test_ticket47838_run_1(topology): - ecount = int(enabled.readline().rstrip()) - dcount = int(disabled.readline().rstrip()) - -+ global plus_all_ecount_noweak -+ global plus_all_dcount_noweak -+ plus_all_ecount_noweak = ecount -+ plus_all_dcount_noweak = dcount -+ - log.info("Enabled ciphers: %d" % ecount) - log.info("Disabled ciphers: %d" % dcount) - assert ecount >= 31 -@@ -284,12 +291,11 @@ def test_ticket47838_run_2(topology): - """ - Check nsSSL3Ciphers: +rsa_aes_128_sha,+rsa_aes_256_sha - rsa_aes_128_sha, tls_rsa_aes_128_sha, rsa_aes_256_sha, tls_rsa_aes_256_sha are enabled. -+ default allowWeakCipher - """ -- _header(topology, 'Test Case 3 - Check the ciphers availability for "+rsa_aes_128_sha,+rsa_aes_256_sha"') -+ _header(topology, 'Test Case 3 - Check the ciphers availability for "+rsa_aes_128_sha,+rsa_aes_256_sha" with default allowWeakCipher') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -- #topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+rsa_aes_128_sha,+rsa_aes_256_sha'), -- # (ldap.MOD_REPLACE, 'allowWeakCipher', 'on')]) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+rsa_aes_128_sha,+rsa_aes_256_sha')]) - - log.info("\n######################### Restarting the server ######################\n") -@@ -314,6 +320,7 @@ def test_ticket47838_run_3(topology): - """ - Check nsSSL3Ciphers: -all - All ciphers are disabled. -+ default allowWeakCipher - """ - _header(topology, 'Test Case 4 - Check the ciphers availability for "-all"') - -@@ -327,23 +334,23 @@ def test_ticket47838_run_3(topology): - topology.standalone.start(timeout=120) - - enabled = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | wc -l' % topology.standalone.errlog) -- disabled = os.popen('egrep "SSL alert:" %s | egrep \": disabled\" | wc -l' % topology.standalone.errlog) - ecount = int(enabled.readline().rstrip()) -- dcount = int(disabled.readline().rstrip()) - - log.info("Enabled ciphers: %d" % ecount) -- log.info("Disabled ciphers: %d" % dcount) - global plus_all_ecount -- global plus_all_dcount - assert ecount == 0 -- assert dcount == (plus_all_ecount + plus_all_dcount) -+ -+ disabledmsg = os.popen('egrep "Disabling SSL" %s' % topology.standalone.errlog) -+ log.info("Disabling SSL message?: %s" % disabledmsg.readline()) -+ assert disabledmsg != '' - - def test_ticket47838_run_4(topology): - """ - Check no nsSSL3Ciphers - Default ciphers are enabled. -+ default allowWeakCipher - """ -- _header(topology, 'Test Case 5 - Check no nssSSL3Chiphers (default setting)') -+ _header(topology, 'Test Case 5 - Check no nssSSL3Chiphers (default setting) with default allowWeakCipher') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_DELETE, 'nsSSL3Ciphers', '-all')]) -@@ -374,8 +381,9 @@ def test_ticket47838_run_5(topology): - """ - Check nsSSL3Ciphers: default - Default ciphers are enabled. -+ default allowWeakCipher - """ -- _header(topology, 'Test Case 6 - Check default nssSSL3Chiphers (default setting)') -+ _header(topology, 'Test Case 6 - Check default nssSSL3Chiphers (default setting) with default allowWeakCipher') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', 'default')]) -@@ -406,8 +414,9 @@ def test_ticket47838_run_6(topology): - """ - Check nssSSL3Chiphers: +all,-rsa_rc4_128_md5 - All ciphers are disabled. -+ default allowWeakCipher - """ -- _header(topology, 'Test Case 7 - Check nssSSL3Chiphers: +all,-tls_dhe_rsa_aes_128_gcm_sha') -+ _header(topology, 'Test Case 7 - Check nssSSL3Chiphers: +all,-tls_dhe_rsa_aes_128_gcm_sha with default allowWeakCipher') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all,-tls_dhe_rsa_aes_128_gcm_sha')]) -@@ -425,19 +434,20 @@ def test_ticket47838_run_6(topology): - - log.info("Enabled ciphers: %d" % ecount) - log.info("Disabled ciphers: %d" % dcount) -- global plus_all_ecount -- global plus_all_dcount -- log.info("ALL Ecount: %d" % plus_all_ecount) -- log.info("ALL Dcount: %d" % plus_all_dcount) -- assert ecount == (plus_all_ecount - 1) -- assert dcount == (plus_all_dcount + 1) -+ global plus_all_ecount_noweak -+ global plus_all_dcount_noweak -+ log.info("ALL Ecount: %d" % plus_all_ecount_noweak) -+ log.info("ALL Dcount: %d" % plus_all_dcount_noweak) -+ assert ecount == (plus_all_ecount_noweak - 1) -+ assert dcount == (plus_all_dcount_noweak + 1) - - def test_ticket47838_run_7(topology): - """ - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5 - All ciphers are disabled. -+ default allowWeakCipher - """ -- _header(topology, 'Test Case 8 - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5') -+ _header(topology, 'Test Case 8 - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5 with default allowWeakCipher') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '-all,+rsa_rc4_128_md5')]) -@@ -497,8 +507,10 @@ def test_ticket47838_run_9(topology): - """ - Check no nsSSL3Ciphers - Default ciphers are enabled. -+ allowWeakCipher: on -+ nsslapd-errorlog-level: 0 - """ -- _header(topology, 'Test Case 10 - Check no nssSSL3Chiphers (default setting) with no errorlog-level') -+ _header(topology, 'Test Case 10 - Check no nssSSL3Chiphers (default setting) with no errorlog-level & allowWeakCipher on') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', None), -@@ -518,12 +530,12 @@ def test_ticket47838_run_9(topology): - - log.info("Enabled ciphers: %d" % ecount) - log.info("Disabled ciphers: %d" % dcount) -- assert ecount == 12 -+ assert ecount == 23 - assert dcount == 0 - weak = os.popen('egrep "SSL alert:" %s | egrep \": enabled\" | egrep "WEAK CIPHER" | wc -l' % topology.standalone.errlog) - wcount = int(weak.readline().rstrip()) - log.info("Weak ciphers in the default setting: %d" % wcount) -- assert wcount == 0 -+ assert wcount == 11 - - def test_ticket47838_run_10(topology): - """ -@@ -535,8 +547,10 @@ def test_ticket47838_run_10(topology): - -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 -+ allowWeakCipher: on -+ nsslapd-errorlog-level: 0 - """ -- _header(topology, 'Test Case 11 - Check nssSSL3Chiphers: long list using the NSS Cipher Suite name') -+ _header(topology, 'Test Case 11 - Check nssSSL3Chiphers: long list using the NSS Cipher Suite name with allowWeakCipher on') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', --- -1.9.3 - diff --git a/SOURCES/0012-Ticket-48013-Inconsistent-behaviour-of-DS-when-LDAP-.patch b/SOURCES/0012-Ticket-48013-Inconsistent-behaviour-of-DS-when-LDAP-.patch new file mode 100644 index 0000000..f850942 --- /dev/null +++ b/SOURCES/0012-Ticket-48013-Inconsistent-behaviour-of-DS-when-LDAP-.patch @@ -0,0 +1,184 @@ +From a8e885d2d69381adc483d1a506b9f1e739a507f5 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 8 Jul 2015 17:21:57 -0400 +Subject: [PATCH 12/20] Ticket 48013 - Inconsistent behaviour of DS when LDAP + Sync is used with an invalid cookie + +Bug Description: Some invalid cookies are treated as errors, while others are not. + +Fix Description: Perform the cookie parsing and validation in the same step. This + gives consistent results. + +https://fedorahosted.org/389/ticket/48013 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit fdf46817fcc3b334bd477316d253bc18f243c0f6) +(cherry picked from commit 41dff5ba7a6368bfb2d8a2057dd5ba5b6a91d175) +--- + dirsrvtests/tickets/ticket48013_test.py | 134 +++++++++++++++++++++++++++++++ + ldap/servers/plugins/sync/sync_refresh.c | 7 +- + 2 files changed, 138 insertions(+), 3 deletions(-) + create mode 100644 dirsrvtests/tickets/ticket48013_test.py + +diff --git a/dirsrvtests/tickets/ticket48013_test.py b/dirsrvtests/tickets/ticket48013_test.py +new file mode 100644 +index 0000000..0ccdeba +--- /dev/null ++++ b/dirsrvtests/tickets/ticket48013_test.py +@@ -0,0 +1,134 @@ ++import os ++import sys ++import time ++import ldap ++import logging ++import pytest ++import pyasn1 ++import pyasn1_modules ++import ldap,ldapurl ++from ldap.ldapobject import SimpleLDAPObject ++from ldap.syncrepl import SyncreplConsumer ++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 ++ ++ ++class TopologyStandalone(object): ++ def __init__(self, standalone): ++ standalone.open() ++ self.standalone = standalone ++ ++ ++class SyncObject(SimpleLDAPObject, SyncreplConsumer): ++ def __init__(self, uri): ++ # Init the ldap connection ++ SimpleLDAPObject.__init__(self, uri) ++ ++ def sync_search(self, test_cookie): ++ self.syncrepl_search('dc=example,dc=com', ldap.SCOPE_SUBTREE, ++ filterstr='(objectclass=*)', mode='refreshOnly', ++ cookie=test_cookie) ++ ++ def poll(self): ++ self.syncrepl_poll(all=1) ++ ++ ++@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() ++ ++ # Clear out the tmp dir ++ standalone.clearTmpDir(__file__) ++ ++ return TopologyStandalone(standalone) ++ ++ ++def test_ticket48013(topology): ++ ''' ++ Content Synchonization: Test that invalid cookies are caught ++ ''' ++ ++ cookies = ('#', '##', 'a#a#a', 'a#a#1') ++ ++ # Enable dynamic plugins ++ 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 plugin!' + e.message['desc']) ++ assert False ++ ++ # Enable retro changelog ++ topology.standalone.plugins.enable(name=PLUGIN_RETRO_CHANGELOG) ++ ++ # Enbale content sync plugin ++ topology.standalone.plugins.enable(name=PLUGIN_REPL_SYNC) ++ ++ # Set everything up ++ ldap_url = ldapurl.LDAPUrl('ldap://localhost:31389') ++ ldap_connection = SyncObject(ldap_url.initializeUrl()) ++ ++ # Authenticate ++ try: ++ ldap_connection.simple_bind_s(DN_DM, PASSWORD) ++ except ldap.LDAPError as e: ++ print('Login to LDAP server failed: %s' % e.message['desc']) ++ assert False ++ ++ # Test invalid cookies ++ for invalid_cookie in cookies: ++ log.info('Testing cookie: %s' % invalid_cookie) ++ try: ++ ldap_connection.sync_search(invalid_cookie) ++ ldap_connection.poll() ++ log.fatal('Invalid cookie accepted!') ++ assert False ++ except Exception as e: ++ log.info('Invalid cookie correctly rejected: %s' % e.message['info']) ++ pass ++ ++ # Success ++ log.info('Test complete') ++ ++ ++def test_ticket48013_final(topology): ++ topology.standalone.delete() ++ log.info('Testcase PASSED') ++ ++ ++def run_isolated(): ++ global installation1_prefix ++ installation1_prefix = None ++ ++ topo = topology(True) ++ test_ticket48013(topo) ++ test_ticket48013_final(topo) ++ ++ ++if __name__ == '__main__': ++ run_isolated() ++ +diff --git a/ldap/servers/plugins/sync/sync_refresh.c b/ldap/servers/plugins/sync/sync_refresh.c +index 1ae2604..beb87ab 100644 +--- a/ldap/servers/plugins/sync/sync_refresh.c ++++ b/ldap/servers/plugins/sync/sync_refresh.c +@@ -113,9 +113,10 @@ int sync_srch_refresh_pre_search(Slapi_PBlock *pb) + * -- return e-syncRefreshRequired if the data referenced in the cookie are no + * longer in the history + */ +- if (cookie && +- ( client_cookie = sync_cookie_parse (cookie))) { +- if (sync_cookie_isvalid(client_cookie, session_cookie)) { ++ if (cookie) { ++ if ((client_cookie = sync_cookie_parse (cookie)) && ++ sync_cookie_isvalid(client_cookie, session_cookie)) ++ { + rc = sync_refresh_update_content(pb, client_cookie, session_cookie); + if (rc == 0) + entries_sent = 1; +-- +1.9.3 + diff --git a/SOURCES/0013-Ticket-47880-provide-enabled-ciphers-as-search-resul.patch b/SOURCES/0013-Ticket-47880-provide-enabled-ciphers-as-search-resul.patch deleted file mode 100644 index 4254032..0000000 --- a/SOURCES/0013-Ticket-47880-provide-enabled-ciphers-as-search-resul.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 82cf90789bd34622e2ae7b4584ff75214d1dea47 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 25 Sep 2014 13:34:00 -0700 -Subject: [PATCH 13/14] Ticket #47880 - provide enabled ciphers as search - result - -Description: Implemented getEnabledCiphers, with which - ldapsearch -b "cn=encryption,cn=config" nsSSLEnabledCiphers -returns enabled cipher list. Example of returned enabled cipher - dn: cn=encryption,cn=config - nsSSLEnabledCiphers: TLS_RSA_WITH_RC4_128_MD5::RC4::MD5::128 - nsSSLEnabledCiphers: SSL_CK_DES_192_EDE3_CBC_WITH_MD5::3DES::MD5::192 - -https://fedorahosted.org/389/ticket/47880 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!) - -(cherry picked from commit c675243e018a89291760161998944c04ea04b12f) -(cherry picked from commit 8de80533cbfdb22166f5595839307a6a6db5a636) ---- - ldap/servers/slapd/fedse.c | 14 +++++++++++++- - ldap/servers/slapd/ssl.c | 42 +++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 54 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c -index 1ffa08d..1f455e5 100644 ---- a/ldap/servers/slapd/fedse.c -+++ b/ldap/servers/slapd/fedse.c -@@ -76,6 +76,7 @@ - #endif /* _WIN32 */ - - extern char ** getSupportedCiphers(); -+extern char ** getEnabledCiphers(); - - /* Note: These DNs are no need to be normalized */ - static const char *internal_entries[] = -@@ -1695,11 +1696,12 @@ search_encryption( Slapi_PBlock *pb, Slapi_Entry *entry, Slapi_Entry *entryAfter - struct berval *vals[2]; - struct berval val; - char ** cipherList = getSupportedCiphers(); /*Get the string array of supported ciphers here */ -+ char ** enabledCipherList = getEnabledCiphers(); /*Get the string array of enabled ciphers here */ - vals[0] = &val; - vals[1] = NULL; - - attrlist_delete ( &entry->e_attrs, "nsSSLSupportedCiphers"); -- while (*cipherList) /* iterarate thru each of them and add to the attr value */ -+ while (cipherList && *cipherList) /* iterarate thru each of them and add to the attr value */ - { - char *cipher = *cipherList; - val.bv_val = (char* ) cipher; -@@ -1708,6 +1710,16 @@ search_encryption( Slapi_PBlock *pb, Slapi_Entry *entry, Slapi_Entry *entryAfter - cipherList++; - } - -+ attrlist_delete ( &entry->e_attrs, "nsSSLEnabledCiphers"); -+ while (enabledCipherList && *enabledCipherList) /* iterarate thru each of them and add to the attr value */ -+ { -+ char *cipher = *enabledCipherList; -+ val.bv_val = (char* ) cipher; -+ val.bv_len = strlen ( val.bv_val ); -+ attrlist_merge ( &entry->e_attrs, "nsSSLEnabledCiphers", vals); -+ enabledCipherList++; -+ } -+ - return SLAPI_DSE_CALLBACK_OK; - } - -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 28ff475..5f9916b 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -157,6 +157,7 @@ static char * configDN = "cn=encryption,cn=config"; - #define CIPHER_IS_WEAK 0x4 - #define CIPHER_IS_DEPRECATED 0x8 - static char **cipher_names = NULL; -+static char **enabled_cipher_names = NULL; - typedef struct { - char *name; - int num; -@@ -265,7 +266,8 @@ slapd_SSL_warn(char *fmt, ...) - va_end(args); - } - --char ** getSupportedCiphers() -+char ** -+getSupportedCiphers() - { - SSLCipherSuiteInfo info; - char *sep = "::"; -@@ -294,6 +296,44 @@ char ** getSupportedCiphers() - return cipher_names; - } - -+char ** -+getEnabledCiphers() -+{ -+ SSLCipherSuiteInfo info; -+ char *sep = "::"; -+ int number_of_ciphers = 0; -+ int x; -+ int idx = 0; -+ PRBool enabled; -+ -+ /* We have to wait until the SSL initialization is done. */ -+ if (!slapd_ssl_listener_is_initialized()) { -+ return NULL; -+ } -+ if ((enabled_cipher_names == NULL) && _conf_ciphers) { -+ for (x = 0; _conf_ciphers[x].name; x++) { -+ SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled); -+ if (enabled) { -+ number_of_ciphers++; -+ } -+ } -+ enabled_cipher_names = (char **)slapi_ch_calloc((number_of_ciphers + 1), sizeof(char *)); -+ for (x = 0; _conf_ciphers[x].name; x++) { -+ SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled); -+ if (enabled) { -+ SSL_GetCipherSuiteInfo((PRUint16)_conf_ciphers[x].num,&info,sizeof(info)); -+ enabled_cipher_names[idx++] = PR_smprintf("%s%s%s%s%s%s%d", -+ _conf_ciphers[x].name,sep, -+ info.symCipherName,sep, -+ info.macAlgorithmName,sep, -+ info.symKeyBits); -+ } -+ } -+ } -+ -+ return enabled_cipher_names; -+} -+ - static PRBool - cipher_check_fips(int idx, char ***suplist, char ***unsuplist) - { --- -1.9.3 - diff --git a/SOURCES/0013-Ticket-48217-cleanAllRUV-hangs-shutdown-if-not-all-o.patch b/SOURCES/0013-Ticket-48217-cleanAllRUV-hangs-shutdown-if-not-all-o.patch new file mode 100644 index 0000000..3fe4c40 --- /dev/null +++ b/SOURCES/0013-Ticket-48217-cleanAllRUV-hangs-shutdown-if-not-all-o.patch @@ -0,0 +1,146 @@ +From cb54fa78fdd5e94f890c3fa1c03481358e3c82ce Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 9 Jul 2015 09:59:46 -0400 +Subject: [PATCH 13/20] Ticket 48217 - cleanAllRUV hangs shutdown if not all of + the replicas are online + +Bug Description: There are race conditions where we might not notify the + clean task when a shutdown is occuring. This casues the + task refcount to be not decremented, which hangs the + destructor function. + +Fix Description: Check that the server is not shutting down before going + to sleep, and notify the clean/abort tasks to stop in + the destructor functions(instead of in the mmr plugin stop + function). + +https://fedorahosted.org/389/ticket/48217 + +Reviewed by: lkrispen(Thanks!) + +(cherry picked from commit d6269f2e6898a187d43e3368860b13cdbd39ec55) +(cherry picked from commit 0bb881aea92d64e509cf7604e86559779e4f9b77) +--- + .../plugins/replication/repl5_replica_config.c | 49 ++++++++++++++-------- + 1 file changed, 31 insertions(+), 18 deletions(-) + +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index faa86b8..446da3f 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -1738,7 +1738,9 @@ replica_cleanallruv_thread(void *arg) + } + if (data->task) { + slapi_task_inc_refcount(data->task); +- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, "replica_cleanallruv_thread --> refcount incremented.\n"); ++ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, ++ "replica_cleanallruv_thread --> refcount incremented (%d).\n", ++ data->task->task_refcount); + } + /* + * Initialize our settings +@@ -1871,10 +1873,11 @@ replica_cleanallruv_thread(void *arg) + */ + cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, "Not all replicas have received the " + "cleanallruv extended op, retrying in %d seconds",interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); +- ++ if(!slapi_is_shutting_down()){ ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; + } else { +@@ -1974,6 +1977,7 @@ done: + if(data->repl_obj && free_obj){ + object_release(data->repl_obj); + } ++ + csn_free(&data->maxcsn); + slapi_sdn_free(&data->sdn); + slapi_ch_free_string(&data->repl_root); +@@ -1987,6 +1991,7 @@ replica_cleanall_ruv_destructor(Slapi_Task *task) + { + slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, + "replica_cleanall_ruv_destructor -->\n" ); ++ stop_ruv_cleaning(); + if (task) { + while (slapi_task_get_refcount(task) > 0) { + /* Yield to wait for the fixup task finishes. */ +@@ -2002,6 +2007,7 @@ replica_cleanall_ruv_abort_destructor(Slapi_Task *task) + { + slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, + "replica_cleanall_ruv_abort_destructor -->\n" ); ++ stop_ruv_cleaning(); + if (task) { + while (slapi_task_get_refcount(task) > 0) { + /* Yield to wait for the fixup task finishes. */ +@@ -2055,9 +2061,11 @@ check_replicas_are_done_cleaning(cleanruv_data *data ) + break; + } + cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, "Not all replicas finished cleaning, retrying in %d seconds",interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); ++ if(!slapi_is_shutting_down()){ ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; + } else { +@@ -2158,9 +2166,11 @@ check_replicas_are_done_aborting(cleanruv_data *data ) + break; + } + cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, "Not all replicas finished aborting, retrying in %d seconds",interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); ++ if(!slapi_is_shutting_down()){ ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; + } else { +@@ -2212,10 +2222,11 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn) + } + cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, + "Not all replicas caught up, retrying in %d seconds",interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); +- ++ if(!slapi_is_shutting_down()){ ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; + } else { +@@ -2271,10 +2282,12 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task) + } + cleanruv_log(task, rid, CLEANALLRUV_ID, "Not all replicas online, retrying in %d seconds...", + interval); +- PR_Lock( notify_lock ); +- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); +- PR_Unlock( notify_lock ); + ++ if(!slapi_is_shutting_down()){ ++ PR_Lock( notify_lock ); ++ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); ++ PR_Unlock( notify_lock ); ++ } + if(interval < 14400){ /* 4 hour max */ + interval = interval * 2; + } else { +-- +1.9.3 + diff --git a/SOURCES/0014-Ticket-47880-CI-test-added-test-cases-for-ticket-478.patch b/SOURCES/0014-Ticket-47880-CI-test-added-test-cases-for-ticket-478.patch deleted file mode 100644 index fbdd6b2..0000000 --- a/SOURCES/0014-Ticket-47880-CI-test-added-test-cases-for-ticket-478.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 85e5ebbddf2a9b39376b7bc3b1529d6f170b907e Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 25 Sep 2014 14:43:16 -0700 -Subject: [PATCH 14/14] Ticket 47880 - CI test: added test cases for ticket - 47880 - -Description: Ticket #47880 - provide enabled ciphers as search result - -https://fedorahosted.org/389/ticket/47880 -(cherry picked from commit ce7378990855abe1a5b52cd4fbe78ffc33365dcb) -(cherry picked from commit b922e5d8387535a8bd71bbcea821ba08608d27c2) ---- - dirsrvtests/tickets/ticket47838_test.py | 46 ++++++++++++++++++++++++++++++++- - 1 file changed, 45 insertions(+), 1 deletion(-) - -diff --git a/dirsrvtests/tickets/ticket47838_test.py b/dirsrvtests/tickets/ticket47838_test.py -index 1575376..c98c36e 100644 ---- a/dirsrvtests/tickets/ticket47838_test.py -+++ b/dirsrvtests/tickets/ticket47838_test.py -@@ -216,6 +216,24 @@ def test_ticket47838_init(topology): - 'nsSSLToken': 'internal (software)', - 'nsSSLActivation': 'on'}))) - -+def comp_nsSSLEnableCipherCount(topology, ecount): -+ """ -+ Check nsSSLEnabledCipher count with ecount -+ """ -+ log.info("Checking nsSSLEnabledCiphers...") -+ msgid = topology.standalone.search_ext(ENCRYPTION_DN, ldap.SCOPE_BASE, 'cn=*', ['nsSSLEnabledCiphers']) -+ enabledciphercnt = 0 -+ rtype, rdata, rmsgid = topology.standalone.result2(msgid) -+ topology.standalone.log.info("%d results" % len(rdata)) -+ -+ topology.standalone.log.info("Results:") -+ for dn, attrs in rdata: -+ topology.standalone.log.info("dn: %s" % dn) -+ if attrs.has_key('nsSSLEnabledCiphers'): -+ enabledciphercnt = len(attrs['nsSSLEnabledCiphers']) -+ topology.standalone.log.info("enabledCipherCount: %d" % enabledciphercnt) -+ assert ecount == enabledciphercnt -+ - def test_ticket47838_run_0(topology): - """ - Check nsSSL3Ciphers: +all -@@ -248,6 +266,8 @@ def test_ticket47838_run_0(topology): - log.info("Weak ciphers: %d" % wcount) - assert wcount <= 29 - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_1(topology): - """ - Check nsSSL3Ciphers: +all -@@ -287,6 +307,8 @@ def test_ticket47838_run_1(topology): - log.info("Weak ciphers: %d" % wcount) - assert wcount <= 29 - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_2(topology): - """ - Check nsSSL3Ciphers: +rsa_aes_128_sha,+rsa_aes_256_sha -@@ -316,6 +338,8 @@ def test_ticket47838_run_2(topology): - assert ecount == 2 - assert dcount == (plus_all_ecount + plus_all_dcount - ecount) - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_3(topology): - """ - Check nsSSL3Ciphers: -all -@@ -344,6 +368,8 @@ def test_ticket47838_run_3(topology): - log.info("Disabling SSL message?: %s" % disabledmsg.readline()) - assert disabledmsg != '' - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_4(topology): - """ - Check no nsSSL3Ciphers -@@ -377,6 +403,8 @@ def test_ticket47838_run_4(topology): - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 0 - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_5(topology): - """ - Check nsSSL3Ciphers: default -@@ -410,6 +438,8 @@ def test_ticket47838_run_5(topology): - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 0 - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_6(topology): - """ - Check nssSSL3Chiphers: +all,-rsa_rc4_128_md5 -@@ -441,6 +471,8 @@ def test_ticket47838_run_6(topology): - assert ecount == (plus_all_ecount_noweak - 1) - assert dcount == (plus_all_dcount_noweak + 1) - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_7(topology): - """ - Check nssSSL3Chiphers: -all,+rsa_rc4_128_md5 -@@ -470,6 +502,8 @@ def test_ticket47838_run_7(topology): - assert ecount == 1 - assert dcount == (plus_all_ecount + plus_all_dcount - ecount) - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_8(topology): - """ - Check nsSSL3Ciphers: default + allowWeakCipher: off -@@ -503,6 +537,8 @@ def test_ticket47838_run_8(topology): - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 0 - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_9(topology): - """ - Check no nsSSL3Ciphers -@@ -537,6 +573,8 @@ def test_ticket47838_run_9(topology): - log.info("Weak ciphers in the default setting: %d" % wcount) - assert wcount == 11 - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_10(topology): - """ - Check nssSSL3Chiphers: -TLS_RSA_WITH_NULL_MD5,+TLS_RSA_WITH_RC4_128_MD5, -@@ -579,6 +617,8 @@ def test_ticket47838_run_10(topology): - - topology.standalone.log.info("ticket47838 was successfully verified."); - -+ comp_nsSSLEnableCipherCount(topology, ecount) -+ - def test_ticket47838_run_11(topology): - """ - Check nssSSL3Chiphers: +fortezza -@@ -603,6 +643,8 @@ def test_ticket47838_run_11(topology): - log.info("Expected error message was not found") - assert False - -+ comp_nsSSLEnableCipherCount(topology, 0) -+ - def test_ticket47838_run_last(topology): - """ - Check nssSSL3Chiphers: all <== invalid value -@@ -627,7 +669,9 @@ def test_ticket47838_run_last(topology): - log.info("Expected error message was not found") - assert False - -- topology.standalone.log.info("ticket47838 was successfully verified."); -+ comp_nsSSLEnableCipherCount(topology, 0) -+ -+ topology.standalone.log.info("ticket47838, 47880, 47908 were successfully verified."); - - def test_ticket47838_final(topology): - topology.standalone.simple_bind_s(DN_DM, PASSWORD) --- -1.9.3 - diff --git a/SOURCES/0014-Ticket-48216-crash-in-ns-slapd-when-deleting-winSync.patch b/SOURCES/0014-Ticket-48216-crash-in-ns-slapd-when-deleting-winSync.patch new file mode 100644 index 0000000..f1e78fb --- /dev/null +++ b/SOURCES/0014-Ticket-48216-crash-in-ns-slapd-when-deleting-winSync.patch @@ -0,0 +1,70 @@ +From 4fe9f07d50f383e3765ba97294f8b641f7feefa3 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 9 Jul 2015 17:23:57 -0700 +Subject: [PATCH 14/20] Ticket #48216 - crash in ns-slapd when deleting + winSyncSubtreePair from sync agreement + +Description: In free_subtree_pairs, the condition for stopping the +loop to clean up the AD and DS subtree dn was incomplete. + +This patch checks the AD and DS subtree dn and if any of the pair +is NULL, it stops the clean up. Related to the issue, more checks +for the validation of the winSyncSubtreePair is added so that any +single valued cases are ignored with an error log. +[single valued case examples] + winSyncSubtreePair: ou=People,dc=anytree + winSyncSubtreePair: ou=People,dc=anytree: + winSyncSubtreePair: :ou=People,dc=anytree + +https://fedorahosted.org/389/ticket/48216 + +Reviewed by rmeggins@redht.com (Thank you, Rich!!) + +(cherry picked from commit 6dce81e77a47dc23e0b825952c97112039f45201) +(cherry picked from commit 6d177bf359c022f1e46d575c6fe3ad3d97f1cfeb) +--- + ldap/servers/plugins/replication/windows_private.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c +index 36015c2..f5cb44e 100644 +--- a/ldap/servers/plugins/replication/windows_private.c ++++ b/ldap/servers/plugins/replication/windows_private.c +@@ -885,7 +885,7 @@ windows_private_get_subtreepairs(const Repl_Agmt *ra) + return dp->subtree_pairs; + } + +-/* parray is NOT passed in */ ++/* parray is NOT passed in; caller frees it. */ + void + windows_private_set_subtreepairs(const Repl_Agmt *ra, char **parray) + { +@@ -930,6 +930,12 @@ create_subtree_pairs(char **pairs) + for (ptr = pairs; ptr && *ptr; ptr++) { + p0 = ldap_utf8strtok_r(*ptr, ":", &saveptr); + p1 = ldap_utf8strtok_r(NULL, ":", &saveptr); ++ if ((NULL == p0) || (NULL == p1)) { ++ LDAPDebug1Arg(LDAP_DEBUG_ANY, ++ "create_subtree_pairs: " ++ "Ignoring invalid subtree pairs \"%s\".\n", *ptr); ++ continue; ++ } + spp->DSsubtree = slapi_sdn_new_dn_byval(p0); + if (NULL == spp->DSsubtree) { + LDAPDebug1Arg(LDAP_DEBUG_ANY, +@@ -960,7 +966,11 @@ free_subtree_pairs(subtreePair **pairs) + if (NULL == pairs) { + return; + } +- for (p = *pairs; p; p++) { ++ /* ++ * If exists, the subtree pair is both non-NULL or NULL. ++ * Both NULL is the condition to stop the loop. ++ */ ++ for (p = *pairs; p && p->ADsubtree && p->DSsubtree; p++) { + slapi_sdn_free(&(p->ADsubtree)); + slapi_sdn_free(&(p->DSsubtree)); + } +-- +1.9.3 + diff --git a/SOURCES/0015-Ticket-47892-coverity-defects-found-in-1.3.3.x.patch b/SOURCES/0015-Ticket-47892-coverity-defects-found-in-1.3.3.x.patch deleted file mode 100644 index 0542296..0000000 --- a/SOURCES/0015-Ticket-47892-coverity-defects-found-in-1.3.3.x.patch +++ /dev/null @@ -1,64 +0,0 @@ -From dd3b06c0c6581bf0c2c3c3f347ab7a84c860a15b Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 1 Oct 2014 14:06:06 -0700 -Subject: [PATCH] Ticket #47892 - coverity defects found in 1.3.3.x - -Description: fixing compiler warnings reported by covscan on 1.3.3.4. -https://fedorahosted.org/389/ticket/47892#comment:8 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit afc8b06f9e9cc045906d6d6fb64fe5d5f9d7c3d5) -(cherry picked from commit 5353f9fd97518074b77698bf13d95325aeb667d9) ---- - ldap/servers/plugins/acl/acl.c | 10 +++++----- - ldap/servers/plugins/acl/aclparse.c | 2 +- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c -index f8b854c..fe863c8 100644 ---- a/ldap/servers/plugins/acl/acl.c -+++ b/ldap/servers/plugins/acl/acl.c -@@ -2475,13 +2475,13 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int * - int done; - - -- if (aclpb->aclpb_access & SLAPI_ACL_ADD && -- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) { -+ if ((aclpb->aclpb_access & SLAPI_ACL_ADD) && -+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) { - - attrFilterArray = aci->targetAttrAddFilters; - -- } else if (aclpb->aclpb_access & SLAPI_ACL_DELETE && -- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) { -+ } else if ((aclpb->aclpb_access & SLAPI_ACL_DELETE) && -+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) { - - attrFilterArray = aci->targetAttrDelFilters; - -@@ -2490,7 +2490,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int * - attr_matched = ACL_TRUE; - num_attrs = 0; - -- while (attrFilterArray[num_attrs] && attr_matched) { -+ while (attrFilterArray && attrFilterArray[num_attrs] && attr_matched) { - attrFilter = attrFilterArray[num_attrs]; - - /* -diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c -index ae4f2d5..ea64fa7 100644 ---- a/ldap/servers/plugins/acl/aclparse.c -+++ b/ldap/servers/plugins/acl/aclparse.c -@@ -256,7 +256,7 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf) - int targetattrfilterslen = strlen(aci_targetattrfilters); - int target_to_len = strlen(aci_target_to); - int target_from_len = strlen(aci_target_from); -- PRBool is_target_to; -+ PRBool is_target_to = PR_FALSE; - - __acl_strip_leading_space( &str ); - --- -1.9.3 - diff --git a/SOURCES/0015-Ticket-48119-Silent-install-needs-to-properly-exit-w.patch b/SOURCES/0015-Ticket-48119-Silent-install-needs-to-properly-exit-w.patch new file mode 100644 index 0000000..a2c2fe1 --- /dev/null +++ b/SOURCES/0015-Ticket-48119-Silent-install-needs-to-properly-exit-w.patch @@ -0,0 +1,103 @@ +From 8f298b2241bb1dc1342b3f7435806af0c22c9f69 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 13 Jul 2015 12:24:19 -0400 +Subject: [PATCH 15/20] Ticket 48119 - Silent install needs to properly exit + when INF file is missing + +Bug Description: If the INF file is not present, we don't log the error to the + setup log file. We also don't properly check for the suitespot + user, which also does not properly exit if the calling user is root. + +Fix Description: Properly exit if the INF file is missing, or the suitespot user + is not set(and we are running the script as root). + +https://fedorahosted.org/389/ticket/48119 + +Reviewed by: rmeggins(Thanks!) + +(cherry picked from commit 5363898b122b1a7e7ad07fdc0ad074e91cd1510f) +(cherry picked from commit eeddc9f03b6131f5c8ba715a0a05bb1280a4f9ef) +--- + ldap/admin/src/scripts/DSCreate.pm.in | 3 ++- + ldap/admin/src/scripts/Inf.pm | 8 ++++++-- + ldap/admin/src/scripts/Setup.pm.in | 3 +++ + ldap/admin/src/scripts/setup-ds.res.in | 1 + + 4 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in +index f44afbb..e4a4ed0 100644 +--- a/ldap/admin/src/scripts/DSCreate.pm.in ++++ b/ldap/admin/src/scripts/DSCreate.pm.in +@@ -797,8 +797,9 @@ sub setDefaults { + if (!$inf->{General}->{SuiteSpotUserID}) { + if ($> != 0) { # if not root, use the user's uid + $inf->{General}->{SuiteSpotUserID} = getLogin; ++ } else { ++ return('error_missing_userid'); + } +- # otherwise, the uid must be specified + } + + if (!$inf->{General}->{SuiteSpotGroup}) { +diff --git a/ldap/admin/src/scripts/Inf.pm b/ldap/admin/src/scripts/Inf.pm +index ec433e2..d4c55f1 100644 +--- a/ldap/admin/src/scripts/Inf.pm ++++ b/ldap/admin/src/scripts/Inf.pm +@@ -31,7 +31,9 @@ sub new { + $self = bless $self, $type; + + if ($self->{filename}) { +- $self->read(); ++ if($self->read() != 0){ ++ undef $self; ++ } + } + + return $self; +@@ -61,7 +63,7 @@ sub read { + } else { + if (!open(INF, $filename)) { + debug(0, "Error: could not open inf file $filename: $!\n"); +- return; ++ return -1; + } + $inffh = \*INF; + } +@@ -118,6 +120,8 @@ sub read { + if ($inffh ne \*STDIN) { + close $inffh; + } ++ ++ return 0; + } + + sub section { +diff --git a/ldap/admin/src/scripts/Setup.pm.in b/ldap/admin/src/scripts/Setup.pm.in +index cd49d95..99025ab 100644 +--- a/ldap/admin/src/scripts/Setup.pm.in ++++ b/ldap/admin/src/scripts/Setup.pm.in +@@ -117,6 +117,9 @@ sub init { + # if user supplied inf file, use that to initialize + if (defined($inffile)) { + $self->{inf} = new Inf($inffile); ++ if(!$self->{inf}){ ++ $self->doExit(1); ++ } + } else { + $self->{inf} = new Inf; + } +diff --git a/ldap/admin/src/scripts/setup-ds.res.in b/ldap/admin/src/scripts/setup-ds.res.in +index 011bf36..7134e25 100644 +--- a/ldap/admin/src/scripts/setup-ds.res.in ++++ b/ldap/admin/src/scripts/setup-ds.res.in +@@ -118,6 +118,7 @@ error_enabling_feature = Could not enable the directory server feature '%s'. Er + error_importing_ldif = Could not import LDIF file '%s'. Error: %s. Output: %s\n + error_starting_server = Could not start the directory server using command '%s'. The last line from the error log was '%s'. Error: %s\n + error_stopping_server = Could not stop the directory server '%s'. Error: %s\n ++error_missing_userid = The SuiteSpotUserID is missing. This must be set to valid user\n + error_missing_port_and_ldapi = Either ServerPort or ldapifilepath must be specified. The server must listen to something.\n + error_missing_port = No ServerPort specified. The server must have a port number to listen to (default 389).\n + error_server_already_exists = Error: the server already exists at '%s'\ +-- +1.9.3 + diff --git a/SOURCES/0016-Ticket-47878-Remove-warning-suppression-in-1.3.4.patch b/SOURCES/0016-Ticket-47878-Remove-warning-suppression-in-1.3.4.patch new file mode 100644 index 0000000..3d68e2b --- /dev/null +++ b/SOURCES/0016-Ticket-47878-Remove-warning-suppression-in-1.3.4.patch @@ -0,0 +1,34 @@ +From e0ceac7c48a4cc616f1602d4cc3430a306740021 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 13 Jul 2015 13:12:12 -0400 +Subject: [PATCH 16/20] Ticket 47878 - Remove warning suppression in 1.3.4 + +Description: Perl 5.16 does not support the warning suppression of + "smartmatch", but 5.18 does. RHEL 7 is currently only + using 5.16, so it needs to be removed from 1.3.4 for now. + +https://fedorahosted.org/389/ticket/47878 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit d8b7a3c93692eae229c74ef67f6f608f95eb2eef) +--- + ldap/admin/src/scripts/52updateAESplugin.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/admin/src/scripts/52updateAESplugin.pl b/ldap/admin/src/scripts/52updateAESplugin.pl +index ae258b6..4225770 100644 +--- a/ldap/admin/src/scripts/52updateAESplugin.pl ++++ b/ldap/admin/src/scripts/52updateAESplugin.pl +@@ -6,7 +6,7 @@ use File::Basename; + use File::Copy; + use DSUtil qw(debug serverIsRunning); + +-no warnings 'experimental::smartmatch'; ++# no warnings 'experimental::smartmatch'; warning supression available in perl 5.18 + + # + # Check if there is a DES plugin and make sure the AES plugin contains the same attributes +-- +1.9.3 + diff --git a/SOURCES/0016-Ticket-47918-result-of-dna_dn_is_shared_config-is-in.patch b/SOURCES/0016-Ticket-47918-result-of-dna_dn_is_shared_config-is-in.patch deleted file mode 100644 index 9e59d63..0000000 --- a/SOURCES/0016-Ticket-47918-result-of-dna_dn_is_shared_config-is-in.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 832fb9a26af053e989e59e5bae0aabbc7d2943a7 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Mon, 6 Oct 2014 17:12:42 +0200 -Subject: [PATCH 16/21] Ticket 47918 - result of dna_dn_is_shared_config is - incorrectly used - -Bug Description: dna_load_shared_servers() is called for all entries, - except the config entries - -Fix Description: revert the logic of the result of dna_dn_is_shared_config() - -https://fedorahosted.org/389/ticket/47918 - -Reviewed by: Mark, Thanks - -(cherry picked from commit 8d9679194c945a6e0b06f6527fba6b4548d4844d) ---- - ldap/servers/plugins/dna/dna.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c -index b42150a..bc280a4 100644 ---- a/ldap/servers/plugins/dna/dna.c -+++ b/ldap/servers/plugins/dna/dna.c -@@ -4163,7 +4163,7 @@ static int dna_config_check_post_op(Slapi_PBlock * pb) - if (dna_dn_is_config(dn)) { - dna_load_plugin_config(pb, 0); - } -- if(dna_dn_is_shared_config(pb, dn) == 0){ -+ if(dna_dn_is_shared_config(pb, dn)){ - dna_load_shared_servers(); - } - } --- -1.9.3 - diff --git a/SOURCES/0017-Ticket-47892-Fix-remaining-compiler-warnings.patch b/SOURCES/0017-Ticket-47892-Fix-remaining-compiler-warnings.patch deleted file mode 100644 index 2e95b09..0000000 --- a/SOURCES/0017-Ticket-47892-Fix-remaining-compiler-warnings.patch +++ /dev/null @@ -1,57 +0,0 @@ -From f8bdd437a0ab09315bfcb980ea590d4463f15189 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 7 Oct 2014 15:38:34 -0400 -Subject: [PATCH 17/21] Ticket 47892 - Fix remaining compiler warnings - -Description: Fix the remaining compiler warnings from ds/lib/base/system.cpp - -https://fedorahosted.org/389/ticket/47892 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 5f3aaa2872d69c5900eaf52d7e9fc2f1bcea475e) -(cherry picked from commit 0f29b5e920088ab4d32f5afdc7dcb076a88c5eae) ---- - lib/base/system.cpp | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/lib/base/system.cpp b/lib/base/system.cpp -index 287d5a8..c4cbfd0 100644 ---- a/lib/base/system.cpp -+++ b/lib/base/system.cpp -@@ -201,7 +201,7 @@ NSAPI_PUBLIC void *system_realloc_perm(void *ptr, int size) - return ptr; - } - } else { -- ereport(LOG_WARN, "realloc: attempt to realloc to smaller size"); -+ ereport(LOG_WARN, const_cast("realloc: attempt to realloc to smaller size")); - return realloc(ptr, size); - } - -@@ -228,20 +228,20 @@ NSAPI_PUBLIC void system_free_perm(void *ptr) - cptr += sizeof(int); - for (index=0; index("free: corrupt memory (prebounds overwrite)")); - break; - } - - cptr += DEBUG_MARGIN + *length; - for (index=0; index("free: corrupt memory (prebounds overwrite)")); - break; - } - - memset(baseptr, DEBUG_FREE_CHAR, *length + 2*DEBUG_MARGIN+sizeof(int)); - } else { -- ereport(LOG_CATASTROPHE, "free: freeing unallocated memory"); -+ ereport(LOG_CATASTROPHE, const_cast("free: freeing unallocated memory")); - } - free(baseptr); - #else --- -1.9.3 - diff --git a/SOURCES/0017-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch b/SOURCES/0017-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch new file mode 100644 index 0000000..9a1049b --- /dev/null +++ b/SOURCES/0017-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch @@ -0,0 +1,77 @@ +From 8622b69a733a6126414876f11ab627211cb3bd06 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Mon, 13 Jul 2015 17:51:01 -0700 +Subject: [PATCH 17/20] Ticket #48223 - Winsync fails when AD users have + multiple spaces (two)inside the value of the rdn attribute + +Description: When the dirsync search returns a remote entry, winsync +search the entry with DN to retrieve the whole attribute value pairs. +The DN used for the search was normalized which replaced multiple white- +spaces with one in the DN. This patch does not used the normalized DN, +but the same DN given by AD. + +The DN normalization behaviour was introduced to fix a ticket #529 - +dn normalization must handle multiple space characters in attributes. + +Added additional debugging to get the info which entry failed to sync. + +https://fedorahosted.org/389/ticket/48223 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit 2c484cc6e89e473bced0e9b25dd6e68d53024bb3) +(cherry picked from commit 69fd1f188105b2c3ca1bee04b05909e53c980b34) +--- + ldap/servers/plugins/posix-winsync/posix-group-func.c | 2 +- + ldap/servers/plugins/replication/windows_protocol_util.c | 11 +++++++---- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.c b/ldap/servers/plugins/posix-winsync/posix-group-func.c +index 5f841e5..a497f3f 100644 +--- a/ldap/servers/plugins/posix-winsync/posix-group-func.c ++++ b/ldap/servers/plugins/posix-winsync/posix-group-func.c +@@ -95,7 +95,7 @@ getEntry(const char *udn, char **attrs) + } + else { + slapi_log_error(SLAPI_LOG_FATAL, POSIX_WINSYNC_PLUGIN_NAME, +- "getEntry: error searching for uid: %d\n", rc); ++ "getEntry: error searching for uid %s: %d\n", udn, rc); + } + + return NULL; +diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c +index 4607251..6bf20b7 100644 +--- a/ldap/servers/plugins/replication/windows_protocol_util.c ++++ b/ldap/servers/plugins/replication/windows_protocol_util.c +@@ -3226,7 +3226,7 @@ windows_get_remote_entry (Private_Repl_Protocol *prp, const Slapi_DN* remote_dn, + const char *searchbase = NULL; + Slapi_Entry *found_entry = NULL; + +- searchbase = slapi_sdn_get_dn(remote_dn); ++ searchbase = slapi_sdn_get_udn(remote_dn); + cres = windows_search_entry_ext(prp->conn, (char*)searchbase, filter, &found_entry, NULL, LDAP_SCOPE_BASE); + if (cres) + { +@@ -5886,13 +5886,16 @@ retry: + remote_entry = NULL; + } else + { +- slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name,"%s: windows_process_dirsync_entry: failed to fetch inbound entry.\n",agmt_get_long_name(prp->agmt)); ++ slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name, ++ "%s: windows_process_dirsync_entry: failed to fetch inbound entry %s.\n", ++ agmt_get_long_name(prp->agmt), slapi_sdn_get_dn(slapi_entry_get_sdn_const(e))); + } + slapi_entry_free(local_entry); + if (rc) { + /* Something bad happened */ +- slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"%s: windows_process_dirsync_entry: failed to update inbound entry for %s.\n",agmt_get_long_name(prp->agmt), +- slapi_sdn_get_dn(slapi_entry_get_sdn_const(e))); ++ slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name, ++ "%s: windows_process_dirsync_entry: failed to update inbound entry for %s.\n", ++ agmt_get_long_name(prp->agmt), slapi_sdn_get_dn(slapi_entry_get_sdn_const(e))); + } + } else + { +-- +1.9.3 + diff --git a/SOURCES/0018-Ticket-47910-logconv.pl-validate-start-and-end-time-.patch b/SOURCES/0018-Ticket-47910-logconv.pl-validate-start-and-end-time-.patch new file mode 100644 index 0000000..a147d49 --- /dev/null +++ b/SOURCES/0018-Ticket-47910-logconv.pl-validate-start-and-end-time-.patch @@ -0,0 +1,132 @@ +From 5f0aab1fccab4c191b2083aea88e28856caf1a4c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 14 Jul 2015 10:09:00 -0400 +Subject: [PATCH 18/20] Ticket 47910 - logconv.pl - validate start and end time + args + +Description: Add validatation checks for the startTime/endTime configuration + arguments(-S, -E) + +https://fedorahosted.org/389/ticket/47910 + +Reviewed by: rmeggins(Thanks!) + +(cherry picked from commit 8495afa57ad837e3a51871a4f6da2a9978c8e711) +(cherry picked from commit 3bf1daaadd7e7c7b0f99d1f7a93d78598730269d) +--- + ldap/admin/src/logconv.pl | 65 +++++++++++++++++++++++++++++++++++------------ + 1 file changed, 49 insertions(+), 16 deletions(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index ce4114e..7ca9084 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -24,6 +24,7 @@ use DB_File; + use sigtrap qw(die normal-signals); + use Archive::Tar; + use IO::Uncompress::AnyUncompress qw($AnyUncompressError); ++use Scalar::Util qw(looks_like_number); + + Getopt::Long::Configure ("bundling"); + Getopt::Long::Configure ("permute"); +@@ -341,18 +342,18 @@ $connmsg{"P2"} = "Poll"; + $connmsg{"U1"} = "Cleanly Closed Connections"; + + my %monthname = ( +- "Jan" => 0, +- "Feb" => 1, +- "Mar" => 2, +- "Apr" => 3, +- "May" => 4, +- "Jun" => 5, +- "Jul" => 6, +- "Aug" => 7, +- "Sep" => 8, +- "Oct" => 9, +- "Nov" => 10, +- "Dec" => 11, ++ "jan" => 0, ++ "feb" => 1, ++ "mar" => 2, ++ "apr" => 3, ++ "may" => 4, ++ "jun" => 5, ++ "jul" => 6, ++ "aug" => 7, ++ "sep" => 8, ++ "oct" => 9, ++ "nov" => 10, ++ "dec" => 11, + + ); + +@@ -411,11 +412,27 @@ sub convertTimeToSeconds { + my $logDate; + my @dateComps; + my ($timeMonth, $timeDay, $timeYear, $dateTotal); ++ $dateTotal = 0; + if ($log_line =~ / *([0-9A-Z\/]+)/i ){ + $logDate = $1; + @dateComps = split /\//, $logDate; +- +- $timeMonth = 1 + $monthname{$dateComps[1]}; ++ if ($#dateComps < 2) { ++ print "The date string ($log_line) is invalid, exiting...\n"; ++ exit(1); ++ } ++ if (!looks_like_number($dateComps[0]) || length $dateComps[0] != 2) { ++ print "The date string ($log_line) has invalid day ($dateComps[0]), exiting...\n"; ++ exit(1); ++ } ++ if ($monthname{lc $dateComps[1]} eq "") { ++ print "The date string ($log_line) has invalid month ($dateComps[1]), exiting...\n"; ++ exit(1); ++ } ++ if (!looks_like_number($dateComps[2]) || length $dateComps[2] != 4 ) { ++ print "The date string ($log_line) has invalid year ($dateComps[2]), exiting...\n"; ++ exit(1); ++ } ++ $timeMonth = 1 + $monthname{lc $dateComps[1]}; + $timeMonth = $timeMonth * 3600 * 24 * 30; + $timeDay= $dateComps[0] * 3600 * 24; + $timeYear = $dateComps[2] * 365 * 3600 * 24; +@@ -425,10 +442,26 @@ sub convertTimeToSeconds { + my $logTime; + my @timeComps; + my ($timeHour, $timeMinute, $timeSecond, $timeTotal); ++ $timeTotal = 0; + if ($log_line =~ / *(:[0-9:]+)/i ){ + $logTime = $1; + @timeComps = split /:/, $logTime; +- ++ if ($#timeComps < 3) { ++ print "The time string ($log_line) is invalid, exiting...\n"; ++ exit(1); ++ } ++ if (!looks_like_number($timeComps[1]) || length $timeComps[1] != 2){ ++ print "The time string ($log_line) has invalid hour ($timeComps[1]), exiting...\n"; ++ exit(1); ++ } ++ if (!looks_like_number($timeComps[2]) || length $timeComps[2] != 2){ ++ print "The time string ($log_line) has invalid minute ($timeComps[2]), exiting...\n"; ++ exit(1); ++ } ++ if (!looks_like_number($timeComps[3]) || length $timeComps[3] != 2){ ++ print "The time string ($log_line) has invalid second ($timeComps[3]), exiting...\n"; ++ exit(1); ++ } + $timeHour = $timeComps[1] * 3600; + $timeMinute = $timeComps[2] * 60; + $timeSecond = $timeComps[3]; +@@ -1796,7 +1829,7 @@ sub parseLineNormal + } + my ($date, $hr, $min, $sec) = split (':', $time); + my ($day, $mon, $yr) = split ('/', $date); +- my $newmin = timegm(0, $min, $hr, $day, $monthname{$mon}, $yr) - $tzoff; ++ my $newmin = timegm(0, $min, $hr, $day, $monthname{lc $mon}, $yr) - $tzoff; + $gmtime = $newmin + $sec; + print_stats_block( $s_stats ); + reset_stats_block( $s_stats, $gmtime, $time.' '.$tzone ); +-- +1.9.3 + diff --git a/SOURCES/0018-Ticket-47919-ldbm_back_modify-SLAPI_PLUGIN_BE_PRE_MO.patch b/SOURCES/0018-Ticket-47919-ldbm_back_modify-SLAPI_PLUGIN_BE_PRE_MO.patch deleted file mode 100644 index a56c01d..0000000 --- a/SOURCES/0018-Ticket-47919-ldbm_back_modify-SLAPI_PLUGIN_BE_PRE_MO.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 6e09835b2b5b221f285f1bd6d61978d0a77843bd Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 7 Oct 2014 12:12:28 -0700 -Subject: [PATCH 18/21] Ticket #47919 - ldbm_back_modify - SLAPI_PLUGIN_BE_PRE_MODIFY_FN does not return even if one of the preop - plugins fails. - -Bug Description: In ldbm_back_modify, if one of the be_preop plugins -called at SLAPI_PLUGIN_BE_PRE_MODIFY_FN fail, ldbm_back_modify does -not return there but go to the real modify operation. - -Fix Description: If an error is returned from be_preop plugins in -ldbm_back_modify, it returns the error there and does not proceed -the modify operation. - -https://fedorahosted.org/389/ticket/47919 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit cb173814ec579fafbfef515738c16a986a9749cd) -(cherry picked from commit 17294432e95bdb30c6816cefa7be5035df818a43) ---- - ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -index 529bd32..d15b050 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -@@ -641,11 +641,11 @@ ldbm_back_modify( Slapi_PBlock *pb ) - if (SLAPI_PLUGIN_NOOP == opreturn) { - not_an_error = 1; - rc = opreturn = LDAP_SUCCESS; -- goto error_return; - } else if (!opreturn) { -- opreturn = -1; -+ opreturn = SLAPI_PLUGIN_FAILURE; - slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &opreturn); - } -+ goto error_return; - } - /* The Plugin may have messed about with some of the PBlock parameters... ie. mods */ - slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ); --- -1.9.3 - diff --git a/SOURCES/0019-Ticket-47920-Encoding-of-SearchResultEntry-is-missin.patch b/SOURCES/0019-Ticket-47920-Encoding-of-SearchResultEntry-is-missin.patch deleted file mode 100644 index 94eb5ff..0000000 --- a/SOURCES/0019-Ticket-47920-Encoding-of-SearchResultEntry-is-missin.patch +++ /dev/null @@ -1,308 +0,0 @@ -From 5d034162124f8d92c4ad3ea205b0e60be81c5c4f Mon Sep 17 00:00:00 2001 -From: "Thierry bordaz (tbordaz)" -Date: Thu, 9 Oct 2014 14:31:11 +0200 -Subject: [PATCH 19/21] Ticket 47920: Encoding of SearchResultEntry is missing - tag - -Bug Description: - The encoding of the PreReadControl,PostReadControl does not - contain the tag (LDAP_RES_SEARCH_ENTRY = constructed+application). - - The server should return SearchResultEntry (http://tools.ietf.org/html/rfc4527 3.1 & 3.2) - That is - SearchResultEntry ::= [APPLICATION 4] SEQUENCE { - objectName LDAPDN, - attributes PartialAttributeList } -Fix Description: - Add the tag to the ber encoding - -https://fedorahosted.org/389/ticket/47920 - -Reviewed by: Noriko (thanks !) - -Platforms tested: F17 - -Flag Day: no - -Doc impact: no - -(cherry picked from commit 90939dc9c965ea1cb88b88eec0cb735ab97ae551) ---- - dirsrvtests/tickets/ticket47920_test.py | 251 ++++++++++++++++++++++++++++++++ - ldap/servers/slapd/result.c | 2 +- - 2 files changed, 252 insertions(+), 1 deletion(-) - create mode 100644 dirsrvtests/tickets/ticket47920_test.py - -diff --git a/dirsrvtests/tickets/ticket47920_test.py b/dirsrvtests/tickets/ticket47920_test.py -new file mode 100644 -index 0000000..1e04626 ---- /dev/null -+++ b/dirsrvtests/tickets/ticket47920_test.py -@@ -0,0 +1,251 @@ -+import os -+import sys -+import time -+import ldap -+import logging -+import socket -+import time -+import logging -+import pytest -+import re -+from lib389 import DirSrv, Entry, tools -+from lib389.tools import DirSrvTools -+from lib389._constants import * -+from lib389.properties import * -+from constants import * -+from ldap.controls.readentry import PreReadControl,PostReadControl -+ -+ -+SCOPE_IN_CN = 'in' -+SCOPE_OUT_CN = 'out' -+SCOPE_IN_DN = 'cn=%s,%s' % (SCOPE_IN_CN, SUFFIX) -+SCOPE_OUT_DN = 'cn=%s,%s' % (SCOPE_OUT_CN, SUFFIX) -+ -+PROVISIONING_CN = "provisioning" -+PROVISIONING_DN = "cn=%s,%s" % (PROVISIONING_CN, SCOPE_IN_DN) -+ -+ -+ -+ -+ACTIVE_CN = "accounts" -+STAGE_CN = "staged users" -+DELETE_CN = "deleted users" -+ACTIVE_DN = "cn=%s,%s" % (ACTIVE_CN, SCOPE_IN_DN) -+STAGE_DN = "cn=%s,%s" % (STAGE_CN, PROVISIONING_DN) -+DELETE_DN = "cn=%s,%s" % (DELETE_CN, PROVISIONING_DN) -+ -+STAGE_USER_CN = "stage guy" -+STAGE_USER_DN = "cn=%s,%s" % (STAGE_USER_CN, STAGE_DN) -+ -+ACTIVE_USER_CN = "active guy" -+ACTIVE_USER_DN = "cn=%s,%s" % (ACTIVE_USER_CN, ACTIVE_DN) -+ -+OUT_USER_CN = "out guy" -+OUT_USER_DN = "cn=%s,%s" % (OUT_USER_CN, SCOPE_OUT_DN) -+ -+STAGE_GROUP_CN = "stage group" -+STAGE_GROUP_DN = "cn=%s,%s" % (STAGE_GROUP_CN, STAGE_DN) -+ -+ACTIVE_GROUP_CN = "active group" -+ACTIVE_GROUP_DN = "cn=%s,%s" % (ACTIVE_GROUP_CN, ACTIVE_DN) -+ -+OUT_GROUP_CN = "out group" -+OUT_GROUP_DN = "cn=%s,%s" % (OUT_GROUP_CN, SCOPE_OUT_DN) -+ -+INDIRECT_ACTIVE_GROUP_CN = "indirect active group" -+INDIRECT_ACTIVE_GROUP_DN = "cn=%s,%s" % (INDIRECT_ACTIVE_GROUP_CN, ACTIVE_DN) -+ -+INITIAL_DESC="inital description" -+FINAL_DESC ="final description" -+ -+ -+ -+log = logging.getLogger(__name__) -+ -+installation_prefix = None -+ -+ -+class TopologyStandalone(object): -+ def __init__(self, standalone): -+ standalone.open() -+ self.standalone = standalone -+ -+ -+ -+@pytest.fixture(scope="module") -+def topology(request): -+ ''' -+ This fixture is used to standalone topology for the 'module'. -+ At the beginning, It may exists a standalone instance. -+ It may also exists a backup for the standalone instance. -+ -+ Principle: -+ If standalone instance exists: -+ restart it -+ If backup of standalone exists: -+ create/rebind to standalone -+ -+ restore standalone instance from backup -+ else: -+ Cleanup everything -+ remove instance -+ remove backup -+ Create instance -+ Create backup -+ ''' -+ global installation_prefix -+ -+ if installation_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation_prefix -+ -+ standalone = DirSrv(verbose=False) -+ -+ # Args for the standalone instance -+ args_instance[SER_HOST] = HOST_STANDALONE -+ args_instance[SER_PORT] = PORT_STANDALONE -+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE -+ args_standalone = args_instance.copy() -+ standalone.allocate(args_standalone) -+ -+ # Get the status of the backups -+ backup_standalone = standalone.checkBackupFS() -+ -+ # Get the status of the instance and restart it if it exists -+ instance_standalone = standalone.exists() -+ if instance_standalone: -+ # assuming the instance is already stopped, just wait 5 sec max -+ standalone.stop(timeout=5) -+ standalone.start(timeout=10) -+ -+ if backup_standalone: -+ # The backup exist, assuming it is correct -+ # we just re-init the instance with it -+ if not instance_standalone: -+ standalone.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # restore standalone instance from backup -+ standalone.stop(timeout=10) -+ standalone.restoreFS(backup_standalone) -+ standalone.start(timeout=10) -+ -+ else: -+ # We should be here only in two conditions -+ # - This is the first time a test involve standalone instance -+ # - Something weird happened (instance/backup destroyed) -+ # so we discard everything and recreate all -+ -+ # Remove the backup. So even if we have a specific backup file -+ # (e.g backup_standalone) we clear backup that an instance may have created -+ if backup_standalone: -+ standalone.clearBackupFS() -+ -+ # Remove the instance -+ if instance_standalone: -+ standalone.delete() -+ -+ # Create the instance -+ standalone.create() -+ -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # Time to create the backups -+ standalone.stop(timeout=10) -+ standalone.backupfile = standalone.backupFS() -+ standalone.start(timeout=10) -+ -+ # clear the tmp directory -+ standalone.clearTmpDir(__file__) -+ -+ # -+ # Here we have standalone instance up and running -+ # Either coming from a backup recovery -+ # or from a fresh (re)init -+ # Time to return the topology -+ return TopologyStandalone(standalone) -+ -+def _header(topology, label): -+ topology.standalone.log.info("\n\n###############################################") -+ topology.standalone.log.info("#######") -+ topology.standalone.log.info("####### %s" % label) -+ topology.standalone.log.info("#######") -+ topology.standalone.log.info("###############################################") -+ -+def _add_user(topology, type='active'): -+ if type == 'active': -+ topology.standalone.add_s(Entry((ACTIVE_USER_DN, { -+ 'objectclass': "top person inetuser".split(), -+ 'sn': ACTIVE_USER_CN, -+ 'cn': ACTIVE_USER_CN, -+ 'description': INITIAL_DESC}))) -+ elif type == 'stage': -+ topology.standalone.add_s(Entry((STAGE_USER_DN, { -+ 'objectclass': "top person inetuser".split(), -+ 'sn': STAGE_USER_CN, -+ 'cn': STAGE_USER_CN}))) -+ else: -+ topology.standalone.add_s(Entry((OUT_USER_DN, { -+ 'objectclass': "top person inetuser".split(), -+ 'sn': OUT_USER_CN, -+ 'cn': OUT_USER_CN}))) -+ -+def test_ticket47920_init(topology): -+ topology.standalone.add_s(Entry((SCOPE_IN_DN, { -+ 'objectclass': "top nscontainer".split(), -+ 'cn': SCOPE_IN_DN}))) -+ topology.standalone.add_s(Entry((ACTIVE_DN, { -+ 'objectclass': "top nscontainer".split(), -+ 'cn': ACTIVE_CN}))) -+ -+ # add users -+ _add_user(topology, 'active') -+ -+ -+def test_ticket47920_mod_readentry_ctrl(topology): -+ _header(topology, 'MOD: with a readentry control') -+ -+ topology.standalone.log.info("Check the initial value of the entry") -+ ent = topology.standalone.getEntry(ACTIVE_USER_DN, ldap.SCOPE_BASE, "(objectclass=*)", ['description']) -+ assert ent.hasAttr('description') -+ assert ent.getValue('description') == INITIAL_DESC -+ -+ pr = PostReadControl(criticality=True,attrList=['cn', 'description']) -+ _,_,_,resp_ctrls = topology.standalone.modify_ext_s(ACTIVE_USER_DN, [(ldap.MOD_REPLACE, 'description', [FINAL_DESC])], serverctrls= [pr]) -+ -+ assert resp_ctrls[0].dn == ACTIVE_USER_DN -+ assert resp_ctrls[0].entry.has_key('description') -+ assert resp_ctrls[0].entry.has_key('cn') -+ print resp_ctrls[0].entry['description'] -+ -+ ent = topology.standalone.getEntry(ACTIVE_USER_DN, ldap.SCOPE_BASE, "(objectclass=*)", ['description']) -+ assert ent.hasAttr('description') -+ assert ent.getValue('description') == FINAL_DESC -+ -+def test_ticket47920_final(topology): -+ topology.standalone.stop(timeout=10) -+ -+ -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - edit this file and comment '@pytest.fixture' line before 'topology' function. -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation_prefix -+ installation_prefix = None -+ -+ topo = topology(True) -+ test_ticket47920_init(topo) -+ -+ test_ticket47920_mod_readentry_ctrl(topo) -+ -+ test_ticket47920_final(topo) -+ -+if __name__ == '__main__': -+ run_isolated() -+ -diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c -index fa1788c..92573d5 100644 ---- a/ldap/servers/slapd/result.c -+++ b/ldap/servers/slapd/result.c -@@ -2176,7 +2176,7 @@ encode_read_entry (Slapi_PBlock *pb, Slapi_Entry *e, char **attrs, int alluserat - } - - /* Start the ber encoding with the DN */ -- rc = ber_printf( ber, "{s{", slapi_entry_get_dn_const(e) ); -+ rc = ber_printf( ber, "t{s{", LDAP_RES_SEARCH_ENTRY, slapi_entry_get_dn_const(e) ); - if ( rc == -1 ) { - rc = -1; - goto cleanup; --- -1.9.3 - diff --git a/SOURCES/0019-Ticket-48224-logconv.pl-should-handle-.tar.xz-.txz-..patch b/SOURCES/0019-Ticket-48224-logconv.pl-should-handle-.tar.xz-.txz-..patch new file mode 100644 index 0000000..7771109 --- /dev/null +++ b/SOURCES/0019-Ticket-48224-logconv.pl-should-handle-.tar.xz-.txz-..patch @@ -0,0 +1,89 @@ +From 5d2f818d33801b1ae6c7d3c19ab67e52a4944251 Mon Sep 17 00:00:00 2001 +From: Rich Megginson +Date: Mon, 13 Jul 2015 18:27:50 -0600 +Subject: [PATCH 19/20] Ticket #48224 - logconv.pl should handle *.tar.xz, + *.txz, *.xz log files + +https://fedorahosted.org/389/ticket/48224 +Reviewed by: ??? +Branch: 389-ds-base-1.3.4 +Fix Description: There is no xz support by default, the perl module +IO::Uncompress::UnXz is required for that. Also, Tar::Archive can't +handle xz files by default, so they have to be uncompressed first. +This will also need a spec file change: +Requires: perl-IO-Compress +Requires: perl-IO-Compress-Lzma +Platforms tested: Fedora 21 +Flag Day: no +Doc impact: no + +(cherry picked from commit d1b0acd12faa620774c66044f91e509ae175e4a1) +(cherry picked from commit 4f3b802fac46adfa8fd5cf49443b875f136fb19c) +--- + ldap/admin/src/logconv.pl | 20 +++++++++++++++++++- + rpm/389-ds-base.spec.in | 3 +++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index 7ca9084..a6bd6c2 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -398,14 +398,26 @@ my $totalLineCount = 0; + + sub isTarArchive { + local $_ = shift; ++ if (/\.txz$/ || /\.tar.xz$/) { ++ use IO::Uncompress::UnXz; ++ } + return /\.tar$/ || /\.tar\.bz2$/ || /\.tar.gz$/ || /\.tar.xz$/ || /\.tgz$/ || /\.tbz$/ || /\.txz$/; + } + + sub isCompressed { + local $_ = shift; ++ if (/\.xz$/) { ++ use IO::Uncompress::UnXz; ++ } + return /\.gz$/ || /\.bz2$/ || /\.xz$/; + } + ++# Tar::Archive can't grok xz, so have to uncompress first ++sub tarNeedsUncompress { ++ local $_ = shift; ++ return /\.tar.xz$/ || /\.txz$/; ++} ++ + sub convertTimeToSeconds { + my $log_line = shift; + +@@ -503,7 +515,13 @@ for (my $count=0; $count < $file_count; $count++){ + my $comp = 0; + if (isTarArchive($logname)) { + $tar = Archive::Tar->new(); +- $tariter = Archive::Tar->iter($logname); ++ if (tarNeedsUncompress($logname)) { ++ my $TARFH = new IO::Uncompress::AnyUncompress $logname or ++ do { openFailed($AnyUncompressError, $logname); next }; ++ $tariter = Archive::Tar->iter($TARFH); ++ } else { ++ $tariter = Archive::Tar->iter($logname); ++ } + if (!$tariter) { + print "$logname is not a valid tar archive, or compression is unrecognized: $!\n"; + next; +diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in +index d0bbb7a..3405ccd 100644 +--- a/rpm/389-ds-base.spec.in ++++ b/rpm/389-ds-base.spec.in +@@ -116,6 +116,9 @@ Requires: perl-Socket6 + Requires: perl-Socket + %endif + Requires: perl-NetAddr-IP ++# for logconv compressed file support ++Requires: perl-IO-Compress ++Requires: perl-IO-Compress-Lzma + + Source0: http://port389.org/sources/%{name}-%{version}%{?prerel}.tar.bz2 + # 389-ds-git.sh should be used to generate the source tarball from git +-- +1.9.3 + diff --git a/SOURCES/0020-Ticket-47897-Need-to-move-slapi_pblock_set-pb-SLAPI_.patch b/SOURCES/0020-Ticket-47897-Need-to-move-slapi_pblock_set-pb-SLAPI_.patch deleted file mode 100644 index e090b64..0000000 --- a/SOURCES/0020-Ticket-47897-Need-to-move-slapi_pblock_set-pb-SLAPI_.patch +++ /dev/null @@ -1,88 +0,0 @@ -From afe5e1ac7306fd5024dcb6550dce3b0c722cbe31 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 8 Oct 2014 10:38:02 -0700 -Subject: [PATCH 20/21] Ticket #47897 - Need to move slapi_pblock_set(pb, - SLAPI_MODRDN_EXISTING_ENTRY, original_entry->ep_entry) prior to - original_entry overwritten - -Bug Description: In the DEADLOCK retry code in ldbm_back_modrdn, -SLAPI_MODRDN_EXISTING_ENTRY in pblock is reset with the new entry -to be renamed. The location of the setting entry was inappropriate, -thus instead of the entry, but its backup is set in pblock. - -Fix Description: Moving the slapi_pblock_set(SLAPI_MODRDN_EXISTING_ -ENTRY) to the correct position. - -Plus, in the DEADLOCK retry code, original_entry is duplicated and -used for the next loop. The source of the duplication has to be -the clean entry before updated in the backend code, but in ldbm_add, -ldbm_modify, and ldbm_modrdn, the current entry was duplicated and -set to the original entry, which could have been updated in the -previous loop. This patch fixes it, as well. - -https://fedorahosted.org/389/ticket/47897 - -Reviewed by tbordaz@redhat.com (Thank you, Theirry!!) - -(cherry picked from commit 2aabb017bd4eec6d30bf00486eb027f59129cf74) -(cherry picked from commit 2393a48021944230f5ebcf5363c0095b1c4679ab) ---- - ldap/servers/slapd/back-ldbm/ldbm_add.c | 2 +- - ldap/servers/slapd/back-ldbm/ldbm_modify.c | 2 +- - ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c -index b74154a..75cb0dc 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_add.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c -@@ -225,7 +225,7 @@ ldbm_back_add( Slapi_PBlock *pb ) - slapi_pblock_set(pb, SLAPI_TXN, parent_txn); - /* must duplicate addingentry before returning it to cache, - * which could free the entry. */ -- if ( (tmpentry = backentry_dup( addingentry )) == NULL ) { -+ if ((tmpentry = backentry_dup(originalentry?originalentry:addingentry)) == NULL) { - ldap_result_code= LDAP_OPERATIONS_ERROR; - goto error_return; - } -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -index d15b050..b9f754d 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -@@ -521,7 +521,7 @@ ldbm_back_modify( Slapi_PBlock *pb ) - if (ec) { - /* must duplicate ec before returning it to cache, - * which could free the entry. */ -- if ( (tmpentry = backentry_dup( ec )) == NULL ) { -+ if ((tmpentry = backentry_dup(original_entry?original_entry:ec)) == NULL) { - ldap_result_code= LDAP_OPERATIONS_ERROR; - goto error_return; - } -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -index 7bcbcee..6a4982c 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -@@ -275,7 +275,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) - orig_dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn); - /* must duplicate ec before returning it to cache, - * which could free the entry. */ -- if ( (tmpentry = backentry_dup( ec )) == NULL ) { -+ if ((tmpentry = backentry_dup(original_entry?original_entry:ec)) == NULL) { - ldap_result_code= LDAP_OPERATIONS_ERROR; - goto error_return; - } -@@ -295,10 +295,10 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) - slapi_entry_free(ent); - slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, NULL ); - } -+ slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, original_entry->ep_entry ); - ec = original_entry; - original_entry = tmpentry; - tmpentry = NULL; -- slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, original_entry->ep_entry ); - free_modrdn_existing_entry = 0; /* owned by original_entry now */ - if (!cache_is_in_cache(&inst->inst_cache, ec)) { - /* Put the resetted entry 'ec' into the cache again. */ --- -1.9.3 - diff --git a/SOURCES/0020-Ticket-48194-CI-test-fixing-test-cases-for-ticket-48.patch b/SOURCES/0020-Ticket-48194-CI-test-fixing-test-cases-for-ticket-48.patch new file mode 100644 index 0000000..df10002 --- /dev/null +++ b/SOURCES/0020-Ticket-48194-CI-test-fixing-test-cases-for-ticket-48.patch @@ -0,0 +1,50 @@ +From 5dda81412db1609f67035957ab65a6c726228e00 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 14 Jul 2015 11:12:56 -0700 +Subject: [PATCH 20/20] Ticket #48194 - CI test: fixing test cases for ticket + 48194 + +Description: nsSSL3Ciphers preference not enforced server side +. Test Case 6 - wrong expectation for RC4-SHA +. Test Case 7 - removing a extra space in nsSSL3Ciphers + +(cherry picked from commit f69ce333052f7f33350fd4038b8f598f650a743f) +(cherry picked from commit ca9e6f9292289a7b6b7f57602555bf9aeb9ba9de) +--- + dirsrvtests/tickets/ticket48194_test.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dirsrvtests/tickets/ticket48194_test.py b/dirsrvtests/tickets/ticket48194_test.py +index 18739ca..17e179a 100644 +--- a/dirsrvtests/tickets/ticket48194_test.py ++++ b/dirsrvtests/tickets/ticket48194_test.py +@@ -295,7 +295,7 @@ def test_ticket48194_run_4(topology): + Default ciphers are enabled. + default allowWeakCipher + """ +- _header(topology, 'Test Case 5 - Check no nsSSL3Ciphers (default setting) with default allowWeakCipher') ++ _header(topology, 'Test Case 5 - Check no nsSSL3Ciphers (-all) with default allowWeakCipher') + + topology.standalone.simple_bind_s(DN_DM, PASSWORD) + topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_DELETE, 'nsSSL3Ciphers', '-all')]) +@@ -326,7 +326,7 @@ def test_ticket48194_run_5(topology): + os.system('touch %s' % (topology.standalone.errlog)) + topology.standalone.start(timeout=120) + +- connectWithOpenssl(topology, 'RC4-SHA', True) ++ connectWithOpenssl(topology, 'RC4-SHA', False) + connectWithOpenssl(topology, 'AES256-SHA256', True) + + def test_ticket48194_run_6(topology): +@@ -338,7 +338,7 @@ def test_ticket48194_run_6(topology): + _header(topology, 'Test Case 7 - Check nsSSL3Ciphers: +all,-TLS_RSA_WITH_AES_256_CBC_SHA256 with default allowWeakCipher') + + topology.standalone.simple_bind_s(DN_DM, PASSWORD) +- topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all,-TLS_RSA_WITH_AES_256_CBC_SHA256 ')]) ++ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all,-TLS_RSA_WITH_AES_256_CBC_SHA256')]) + + log.info("\n######################### Restarting the server ######################\n") + topology.standalone.stop(timeout=10) +-- +1.9.3 + diff --git a/SOURCES/0021-Ticket-47922-dynamically-added-macro-aci-is-not-eval.patch b/SOURCES/0021-Ticket-47922-dynamically-added-macro-aci-is-not-eval.patch deleted file mode 100644 index 6cbf850..0000000 --- a/SOURCES/0021-Ticket-47922-dynamically-added-macro-aci-is-not-eval.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0a1e9e51568d5caea0b97d79773dbc9f5a900ab3 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Fri, 10 Oct 2014 11:50:13 -0700 -Subject: [PATCH 21/21] Ticket #47922 - dynamically added macro aci is not - evaluated on the fly - -Bug Description: When macro aci is dynamically added and if the aci's -macro target dn is not normalized, the following operation that requires -the aci could fail with Insufficient access since matching the target dn -and the macro target dn fails since the code expects normalized macro -target dn. - -Fix Description: Before setting the macro target dn, process the dn by -slapi_create_dn_string_case. - -https://fedorahosted.org/389/ticket/47922 - -Reviewed by lkrispen@redhat.com and rmeggins@redhat.com (Thank you, Ludwig and Rich!!) - -(cherry picked from commit 07c1bc25508a9c1e71dd8e717fd4ce455ddfeff0) -(cherry picked from commit c6b397c8466fd0859c5404c946a82f240564076e) ---- - ldap/servers/plugins/acl/aclparse.c | 19 +++++++++++++------ - ldap/servers/plugins/acl/aclutil.c | 2 +- - 2 files changed, 14 insertions(+), 7 deletions(-) - -diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c -index ea64fa7..be86c8b 100644 ---- a/ldap/servers/plugins/acl/aclparse.c -+++ b/ldap/servers/plugins/acl/aclparse.c -@@ -1849,9 +1849,9 @@ static int - acl_check_for_target_macro( aci_t *aci_item, char *value) - { - -- char *str = NULL; -+ char *str = NULL; - -- str = strstr(value, ACL_TARGET_MACRO_DN_KEY /* ($dn) */); -+ str = PL_strcasestr(value, ACL_TARGET_MACRO_DN_KEY /* ($dn) */); - - if (str != NULL) { - char *p0 = NULL, *p1 = NULL; -@@ -1871,10 +1871,17 @@ acl_check_for_target_macro( aci_t *aci_item, char *value) - aci_item->aci_type &= ~ACI_TARGET_DN; - aci_item->aci_type |= ACI_TARGET_MACRO_DN; - aci_item->aci_macro = (aciMacro *)slapi_ch_malloc(sizeof(aciMacro)); -- aci_item->aci_macro->match_this = slapi_ch_strdup(value); -- aci_item->aci_macro->macro_ptr = strstr( aci_item->aci_macro->match_this, -- ACL_TARGET_MACRO_DN_KEY); -- return(1); -+ /* Macro dn needs to normalize. E.g., "ou=Groups, ($dN), dn=example,dn=com" */ -+ aci_item->aci_macro->match_this = slapi_create_dn_string_case("%s", value); -+ if (NULL == aci_item->aci_macro->match_this) { -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_name, -+ "acl_check_for_target_macro: Error: Invalid macro target dn: \"%s\"\n", value); -+ aci_item->aci_type &= ~ACI_TARGET_MACRO_DN; -+ slapi_ch_free((void **)&aci_item->aci_macro); -+ return -1; -+ } -+ aci_item->aci_macro->macro_ptr = PL_strcasestr(aci_item->aci_macro->match_this, ACL_TARGET_MACRO_DN_KEY); -+ return(1); - } - - return(0); -diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c -index e865a95..0720dae 100644 ---- a/ldap/servers/plugins/acl/aclutil.c -+++ b/ldap/servers/plugins/acl/aclutil.c -@@ -785,7 +785,7 @@ acl_match_macro_in_target( const char *ndn, char * match_this, - macro_prefix = slapi_ch_strdup(match_this); - - /* we know it's got a $(dn) */ -- tmp_ptr = strstr(macro_prefix, ACL_TARGET_MACRO_DN_KEY); -+ tmp_ptr = PL_strcasestr(macro_prefix, ACL_TARGET_MACRO_DN_KEY); - if (!tmp_ptr) { - LDAPDebug(LDAP_DEBUG_ACL,"acl_match_macro_in_target: " - "Target macro DN key \"%s\" not found in \"%s\".\n", --- -1.9.3 - diff --git a/SOURCES/0021-Ticket-48203-Fix-coverity-issues-07-14-2015.patch b/SOURCES/0021-Ticket-48203-Fix-coverity-issues-07-14-2015.patch new file mode 100644 index 0000000..d721123 --- /dev/null +++ b/SOURCES/0021-Ticket-48203-Fix-coverity-issues-07-14-2015.patch @@ -0,0 +1,64 @@ +From e88ffac24b49acb01fb7d460ff4282abe85d3799 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 14 Jul 2015 16:00:03 -0700 +Subject: [PATCH 21/22] Ticket #48203 - Fix coverity issues - 07/14/2015 + +Description: Overrunning array "mctx.negativeErrors" of 19 4-byte +elements at element index 122 (byte offset 488) using index "abs(err)" +(which evaluates to 122). + +Commit 71be5faaa478593bb056887410ca8e48e05b2fe4 to fix Ticket #47799 +introduced this problem. The error count checking has to be done per +error. + +https://fedorahosted.org/389/ticket/48203 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!) + +(cherry picked from commit cc435b8c382f7da662b5c27339d23fd33a8f4117) +(cherry picked from commit 6ec1001e507908ba60f8c52568d24b5c7c727855) +--- + ldap/servers/slapd/tools/ldclt/threadMain.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/ldap/servers/slapd/tools/ldclt/threadMain.c b/ldap/servers/slapd/tools/ldclt/threadMain.c +index 5d915fd..88353c6 100644 +--- a/ldap/servers/slapd/tools/ldclt/threadMain.c ++++ b/ldap/servers/slapd/tools/ldclt/threadMain.c +@@ -477,7 +477,7 @@ addErrorStat ( + #else + if ((err <= 0) || (err >= MAX_ERROR_NB)) + #endif +- { ++ { + if (mctx.errorsBad > mctx.maxErrors) { + printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); + (void) printGlobalStatistics(); /*JLS 25-08-00*/ +@@ -485,8 +485,22 @@ addErrorStat ( + ldclt_sleep (5); + ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/ + } +- } else { +- if (mctx.errors[err] + mctx.negativeErrors[abs(err)] > mctx.maxErrors) { ++ } ++#if defined(USE_OPENLDAP) ++ else if (err < 0) ++ { ++ if (mctx.negativeErrors[abs(err)] > mctx.maxErrors) { ++ printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); ++ (void) printGlobalStatistics(); /*JLS 25-08-00*/ ++ fflush (stdout); ++ ldclt_sleep (5); ++ ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/ ++ } ++ } ++#endif ++ else ++ { ++ if (mctx.errors[err] > mctx.maxErrors) { + printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid); + (void) printGlobalStatistics(); /*JLS 25-08-00*/ + fflush (stdout); +-- +1.9.3 + diff --git a/SOURCES/0022-Ticket-47928-Disable-SSL-v3-by-default.patch b/SOURCES/0022-Ticket-47928-Disable-SSL-v3-by-default.patch deleted file mode 100644 index 6a13d5a..0000000 --- a/SOURCES/0022-Ticket-47928-Disable-SSL-v3-by-default.patch +++ /dev/null @@ -1,741 +0,0 @@ -From 09f4f3932881ce97722480ef4f2196ed35a49ab3 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 22 Oct 2014 14:43:26 -0700 -Subject: [PATCH] Ticket #47928 - Disable SSL v3, by default. - -Description: -There are 2 ways to specify the SSL version in in cn=encryption,cn=config. - . existing method (SSL version info) - nsSSL3: on|off - nsTLS1: on|off - . new method (SSL version range) - sslVersionMin: - sslVersionMax: - where takes "SSL3", "TLS1.0" through "TLS1.2". - -If no SSL version info nor range are set in cn=encryption,cn=config, - nsSSL3: off - nsTLS1: on - sslVersionMin is TLS1.1 - sslVersionMax is TLS1.2 - -If SSL version info and range have conflicts, a tighter setting is -chosen. For instance, the case of sslVersionMin: TLS1.1; nsTLS1: off; -nsSSL3: on, the range setting is respected. - nsSSL3: off - nsTLS1: on - sslVersionMin is TLS1.1 - sslVersionMax is TLS1.2 -"SSL alert: Configured range: min: TLS1.1, max: TLS1.2; but nsSSL3 is on -and nsTLS1 is off. Respect the configured range." is logged in the error -log. - -When cn=encryption,cn=config is searched, the SSL version info as well -as the range are retrieved from the settings in ssl.c and returned. -E.g., -dn: cn=encryption,cn=config -nsSSl2: off -nsSSL3: off -nsTLS1: on -sslVersionMin: TLS1.1 -sslVersionMax: TLS1.2 - -https://fedorahosted.org/389/ticket/47928 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit c1ecd8b659a0b8f7d84f8157cb69810c85ee26e4) -(cherry picked from commit 524d127f14d3bb666d8ac11a277c4ef60693045f) ---- - ldap/servers/slapd/fedse.c | 43 +++++- - ldap/servers/slapd/ssl.c | 360 ++++++++++++++++++++++++++++----------------- - 2 files changed, 266 insertions(+), 137 deletions(-) - -diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c -index 1f455e5..87f45a1 100644 ---- a/ldap/servers/slapd/fedse.c -+++ b/ldap/servers/slapd/fedse.c -@@ -77,6 +77,8 @@ - - extern char ** getSupportedCiphers(); - extern char ** getEnabledCiphers(); -+extern int getSSLVersionInfo(int *ssl2, int *ssl3, int *tls1); -+extern int getSSLVersionRange(char **min, char **max); - - /* Note: These DNs are no need to be normalized */ - static const char *internal_entries[] = -@@ -108,8 +110,7 @@ static const char *internal_entries[] = - "cn:encryption\n" - "nsSSLSessionTimeout:0\n" - "nsSSLClientAuth:allowed\n" -- "nsSSL2:off\n" -- "nsSSL3:off\n", -+ "sslVersionMin:tls1.1\n", - - "dn:cn=monitor\n" - "objectclass:top\n" -@@ -1688,15 +1689,38 @@ dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int - return SLAPI_DSE_CALLBACK_ERROR; - } - -+static void -+setEntrySSLVersion(Slapi_Entry *entry, char *sslversion, char *newval) -+{ -+ char *v = slapi_entry_attr_get_charptr(entry, sslversion); -+ -+ if (v) { -+ if (PL_strcasecmp(v, newval)) { /* did not match */ -+ struct berval bv; -+ struct berval *bvals[2]; -+ bvals[0] = &bv; -+ bvals[1] = NULL; -+ bv.bv_val = newval; -+ bv.bv_len = strlen(bv.bv_val); -+ slapi_entry_attr_replace(entry, sslversion, bvals ); -+ } -+ slapi_ch_free_string(&v); -+ } else { -+ slapi_entry_attr_set_charptr(entry, sslversion, newval); -+ } -+} -+ - /*This function takes care of the search on the attribute nssslsupportedciphers in cn=encryption,cn=config" entry. This would get the list of supported ciphers from the table in ssl.c and always return that value */ - int - search_encryption( Slapi_PBlock *pb, Slapi_Entry *entry, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg) - { -- - struct berval *vals[2]; - struct berval val; - char ** cipherList = getSupportedCiphers(); /*Get the string array of supported ciphers here */ - char ** enabledCipherList = getEnabledCiphers(); /*Get the string array of enabled ciphers here */ -+ int ssl2, ssl3, tls1; -+ char *sslVersionMin = NULL; -+ char *sslVersionMax = NULL; - vals[0] = &val; - vals[1] = NULL; - -@@ -1720,6 +1744,19 @@ search_encryption( Slapi_PBlock *pb, Slapi_Entry *entry, Slapi_Entry *entryAfter - enabledCipherList++; - } - -+ if (!getSSLVersionInfo(&ssl2, &ssl3, &tls1)) { /* 0 if the version info is initialized */ -+ setEntrySSLVersion(entry, "nsSSL2", ssl2?"on":"off"); -+ setEntrySSLVersion(entry, "nsSSL3", ssl3?"on":"off"); -+ setEntrySSLVersion(entry, "nsTLS1", tls1?"on":"off"); -+ } -+ -+ if (!getSSLVersionRange(&sslVersionMin, &sslVersionMax)) { /* 0 if the range is initialized or supported */ -+ setEntrySSLVersion(entry, "sslVersionMin", sslVersionMin); -+ setEntrySSLVersion(entry, "sslVersionMax", sslVersionMax); -+ } -+ slapi_ch_free_string(&sslVersionMin); -+ slapi_ch_free_string(&sslVersionMax); -+ - return SLAPI_DSE_CALLBACK_OK; - } - -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 5f9916b..26ef251 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -81,17 +81,25 @@ - #endif - - #if NSS_VMAJOR * 100 + NSS_VMINOR >= 315 -+/* TLS1.2 is defined in RFC5246. */ - #define NSS_TLS12 1 - #elif NSS_VMAJOR * 100 + NSS_VMINOR >= 314 -+/* TLS1.1 is defined in RFC4346. */ - #define NSS_TLS11 1 - #else -+/* -+ * TLS1.0 is defined in RFC2246. -+ * Close to SSL 3.0. -+ */ - #define NSS_TLS10 1 - #endif - - extern char* slapd_SSL3ciphers; - extern symbol_t supported_ciphers[]; - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ --static SSLVersionRange enabledNSSVersions; -+static SSLVersionRange enabledNSSVersions; -+static SSLVersionRange slapdNSSVersions; -+static char *getNSSVersion_str(PRUint16 vnum); - #endif - - /* dongle_file_name is set in slapd_nss_init when we set the path for the -@@ -238,6 +246,20 @@ static lookup_cipher _lookup_cipher[] = { - {NULL, NULL} - }; - -+/* Supported SSL versions */ -+/* nsSSL2: on -- we don't allow this any more. */ -+PRBool enableSSL2 = PR_FALSE; -+/* -+ * nsSSL3: on -- disable SSLv3 by default. -+ * Corresonding to SSL_LIBRARY_VERSION_3_0 and SSL_LIBRARY_VERSION_TLS_1_0 -+ */ -+PRBool enableSSL3 = PR_FALSE; -+/* -+ * nsTLS1: on -- enable TLS1 by default. -+ * Corresonding to SSL_LIBRARY_VERSION_TLS_1_1 and greater. -+ */ -+PRBool enableTLS1 = PR_TRUE; -+ - static void - slapd_SSL_report(int degree, char *fmt, va_list args) - { -@@ -372,6 +394,36 @@ cipher_check_fips(int idx, char ***suplist, char ***unsuplist) - return rc; - } - -+int -+getSSLVersionInfo(int *ssl2, int *ssl3, int *tls1) -+{ -+ if (!slapd_ssl_listener_is_initialized()) { -+ return -1; -+ } -+ *ssl2 = enableSSL2; -+ *ssl3 = enableSSL3; -+ *tls1 = enableTLS1; -+ return 0; -+} -+ -+int -+getSSLVersionRange(char **min, char **max) -+{ -+ if (!slapd_ssl_listener_is_initialized()) { -+ return -1; -+ } -+ if ((NULL == min) || (NULL == max)) { -+ return -1; -+ } -+#if defined(NSS_TLS10) -+ return -1; /* not supported */ -+#else /* NSS_TLS11 or newer */ -+ *min = slapi_ch_strdup(getNSSVersion_str(slapdNSSVersions.min)); -+ *max = slapi_ch_strdup(getNSSVersion_str(slapdNSSVersions.max)); -+ return 0; -+#endif -+} -+ - static void - _conf_init_ciphers() - { -@@ -834,89 +886,132 @@ getNSSVersion_str(PRUint16 vnum) - return vstr; - } - --/* restrict SSLVersionRange with the existing SSL config params (nsSSL3, nsTLS1) */ -+#define SSLVGreater(x, y) (((x) > (y)) ? (x) : (y)) -+ -+/* -+ * Check the SSLVersionRange and the old style config params (nsSSL3, nsTLS1) . -+ * If there are conflicts, choose the secure setting. -+ */ - static void --restrict_SSLVersionRange(SSLVersionRange *sslversion, PRBool enableSSL3, PRBool enableTLS1) -+restrict_SSLVersionRange(void) - { -- int rc = 0; -+ if (slapdNSSVersions.min > slapdNSSVersions.max) { -+ slapd_SSL_warn("Invalid configured SSL range: min: %s, max: %s; " -+ "Resetting the max to the supported max SSL version: %s.", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max), -+ getNSSVersion_str(enabledNSSVersions.max)); -+ slapdNSSVersions.max = enabledNSSVersions.max; -+ } - if (enableSSL3) { -+ slapd_SSL_warn("Found unsecure configuration: nsSSL3: on; " -+ "We strongly recommend to disable nsSSL3 in %s.", configDN); - if (enableTLS1) { -- /* no restriction */ -- ; -+ if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ slapd_SSL_warn("Configured range: min: %s, max: %s; " -+ "but both nsSSL3 and nsTLS1 are on. " -+ "Respect the supported range.", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max)); -+ enableSSL3 = PR_FALSE; -+ } -+ if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ slapd_SSL_warn("Configured range: min: %s, max: %s; " -+ "but both nsSSL3 and nsTLS1 are on. " -+ "Resetting the max to the supported max SSL version: %s.", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max), -+ getNSSVersion_str(enabledNSSVersions.max)); -+ slapdNSSVersions.max = enabledNSSVersions.max; -+ } - } else { -- if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_3_0) { -- slapd_SSL_warn("Security Initialization: " -- "Supported range: min: %s, max: %s; " -- "but the SSL configuration of the server disables nsTLS1. " -- "Ignoring nsTLS1: off\n", -+ /* nsTLS1 is explicitly set to off. */ -+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ slapd_SSL_warn("Supported range: min: %s, max: %s; " -+ "but nsSSL3 is on and nsTLS1 is off. " -+ "Respect the supported range.", - getNSSVersion_str(enabledNSSVersions.min), - getNSSVersion_str(enabledNSSVersions.max)); -- rc = 1; -- } else if (sslversion->min > SSL_LIBRARY_VERSION_3_0) { -- slapd_SSL_warn("Security Initialization: " -- "Configured range: min: %s, max: %s; " -- "but the SSL configuration of the server disables nsTLS1. " -- "Ignoring nsTLS1: off\n", -- getNSSVersion_str(sslversion->min), -- getNSSVersion_str(sslversion->max)); -- rc = 1; -- } else if (sslversion->max < SSL_LIBRARY_VERSION_3_0) { -- slapd_SSL_warn("Security Initialization: " -- "Configured range: min: %s, max: %s; " -- "but the SSL configuration of the server enabled nsSSL3. " -- "Ignoring max: %s\n", -- getNSSVersion_str(sslversion->min), -- getNSSVersion_str(sslversion->max), -- getNSSVersion_str(sslversion->max)); -- sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */ -- sslversion->max = SSL_LIBRARY_VERSION_3_0; -- rc = 1; -+ slapdNSSVersions.min = SSLVGreater(slapdNSSVersions.min, enabledNSSVersions.min); -+ enableSSL3 = PR_FALSE; -+ enableTLS1 = PR_TRUE; -+ } else if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ slapd_SSL_warn("Configured range: min: %s, max: %s; " -+ "but nsSSL3 is on and nsTLS1 is off. " -+ "Respect the configured range.", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max)); -+ enableSSL3 = PR_FALSE; -+ enableTLS1 = PR_TRUE; -+ } else if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ slapd_SSL_warn("Too low configured range: min: %s, max: %s; " -+ "Resetting the range to: min: %s, max: %s.", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max), -+ getNSSVersion_str(SSL_LIBRARY_VERSION_TLS_1_0), -+ getNSSVersion_str(SSL_LIBRARY_VERSION_TLS_1_0)); -+ slapdNSSVersions.min = SSL_LIBRARY_VERSION_TLS_1_0; -+ slapdNSSVersions.max = SSL_LIBRARY_VERSION_TLS_1_0; - } else { -- sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */ -- sslversion->max = SSL_LIBRARY_VERSION_3_0; -+ /* -+ * slapdNSSVersions.min <= SSL_LIBRARY_VERSION_TLS_1_0 && -+ * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_1 -+ */ -+ slapd_SSL_warn("Configured range: min: %s, max: %s; " -+ "but nsSSL3 is on and nsTLS1 is off. " -+ "Respect the configured range.", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max)); -+ enableTLS1 = PR_TRUE; - } - } - } else { - if (enableTLS1) { -- if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) { -- slapd_SSL_warn("Security Initialization: " -- "Supported range: min: %s, max: %s; " -- "but the SSL configuration of the server disables nsSSL3. ", -- "Ignoring nsSSL3: off\n", -+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ /* TLS1 is on, but TLS1 is not supported by NSS. */ -+ slapd_SSL_warn("Supported range: min: %s, max: %s; " -+ "Setting the version range based upon the supported range.", - getNSSVersion_str(enabledNSSVersions.min), - getNSSVersion_str(enabledNSSVersions.max)); -- sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */ -- sslversion->max = SSL_LIBRARY_VERSION_3_0; -- rc = 1; -- } else if (sslversion->max < SSL_LIBRARY_VERSION_TLS_1_0) { -- slapd_SSL_warn("Security Initialization: " -- "Configured range: min: %s, max: %s; " -- "but the SSL configuration of the server disables nsSSL3. " -- "Ignoring nsSSL3: off\n", -- getNSSVersion_str(sslversion->min), -- getNSSVersion_str(sslversion->max)); -- sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */ -- sslversion->max = SSL_LIBRARY_VERSION_3_0; -- rc = 1; -- } else if (sslversion->min < SSL_LIBRARY_VERSION_TLS_1_0) { -- sslversion->min = SSL_LIBRARY_VERSION_TLS_1_0; -+ slapdNSSVersions.max = enabledNSSVersions.max; -+ slapdNSSVersions.min = enabledNSSVersions.min; -+ enableSSL3 = PR_TRUE; -+ enableTLS1 = PR_FALSE; -+ } else if ((slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) || -+ (slapdNSSVersions.min < SSL_LIBRARY_VERSION_TLS_1_1)) { -+ slapdNSSVersions.max = enabledNSSVersions.max; -+ slapdNSSVersions.min = SSLVGreater(SSL_LIBRARY_VERSION_TLS_1_1, enabledNSSVersions.min); -+ slapd_SSL_warn("Default SSL Version settings; " -+ "Configuring the version range as min: %s, max: %s; ", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max)); -+ } else { -+ /* -+ * slapdNSSVersions.min >= SSL_LIBRARY_VERSION_TLS_1_1 && -+ * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_1 -+ */ -+ ; - } - } else { -- slapd_SSL_warn("Security Initialization: " -- "Supported range: min: %s, max: %s; " -- "but the SSL configuration of the server disables nsSSL3 and nsTLS1. " -- "Ignoring nsSSL3: off and nsTLS1: off\n", -- getNSSVersion_str(enabledNSSVersions.min), -- getNSSVersion_str(enabledNSSVersions.max)); -- rc = 1; -+ slapd_SSL_warn("Supported range: min: %s, max: %s; " -+ "Respect the configured range.", -+ getNSSVersion_str(enabledNSSVersions.min), -+ getNSSVersion_str(enabledNSSVersions.max)); -+ /* nsTLS1 is explicitly set to off. */ -+ if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ enableTLS1 = PR_TRUE; -+ } else if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ enableSSL3 = PR_TRUE; -+ } else { -+ /* -+ * slapdNSSVersions.min <= SSL_LIBRARY_VERSION_TLS_1_0 && -+ * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_1 -+ */ -+ enableSSL3 = PR_TRUE; -+ enableTLS1 = PR_TRUE; -+ } - } - } -- if (0 == rc) { -- slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization", -- "SSL version range: min: %s, max: %s\n", -- getNSSVersion_str(sslversion->min), -- getNSSVersion_str(sslversion->max)); -- } - } - #endif - -@@ -949,7 +1044,7 @@ slapd_nss_init(int init_ssl, int config_available) - SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions); - - slapi_log_error(SLAPI_LOG_CONFIG, "SSL Initialization", -- "supported range: min: %s, max: %s\n", -+ "supported range by NSS: min: %s, max: %s\n", - getNSSVersion_str(enabledNSSVersions.min), - getNSSVersion_str(enabledNSSVersions.max)); - #endif -@@ -1120,11 +1215,9 @@ slapd_ssl_init() - PRErrorCode errorCode; - char ** family_list; - char *val = NULL; -- char cipher_string[1024]; - int rv = 0; - PK11SlotInfo *slot; - Slapi_Entry *entry = NULL; -- int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER; - - /* Get general information */ - -@@ -1162,23 +1255,6 @@ slapd_ssl_init() - freeConfigEntry( &entry ); - return -1; - } -- -- val = slapi_entry_attr_get_charptr(entry, "allowWeakCipher"); -- if (val) { -- if (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -- !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no")) { -- allowweakcipher = CIPHER_SET_DISALLOWWEAKCIPHER; -- } else if (!PL_strcasecmp(val, "on") || !PL_strcasecmp(val, "true") || -- !PL_strcmp(val, "1") || !PL_strcasecmp(val, "yes")) { -- allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; -- } else { -- slapd_SSL_warn("The value of allowWeakCipher \"%s\" in " -- "cn=encryption,cn=config is invalid. " -- "Ignoring it and set it to default.", val); -- } -- } -- slapi_ch_free((void **) &val); -- - if ((family_list = getChildren(configDN))) { - char **family; - char *token; -@@ -1252,22 +1328,6 @@ slapd_ssl_init() - /* ugaston- Cipher preferences must be set before any sslSocket is created - * for such sockets to take preferences into account. - */ -- -- /* Step Three.5: 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)) ) { -- errorCode = PR_GetError(); -- slapd_SSL_warn("Security Initialization: Failed to set SSL cipher " -- "preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -- val, errorCode, slapd_pr_strerror(errorCode)); -- rv = 3; -- slapi_ch_free((void **) &val); -- } -- - freeConfigEntry( &entry ); - - /* Introduce a way of knowing whether slapd_ssl_init has -@@ -1308,7 +1368,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_2) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { -@@ -1319,7 +1379,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.max)); - (*rval) = enabledNSSVersions.max; - } else { -@@ -1331,7 +1391,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_3_0) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { -@@ -1342,7 +1402,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.max)); - (*rval) = enabledNSSVersions.max; - } else { -@@ -1352,12 +1412,12 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - } else { - if (ismin) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " -- "\"%s\" is invalid; the default value \"%s\" is used.\n", -+ "\"%s\" is invalid; the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " -- "\"%s\" is invalid; the default value \"%s\" is used.\n", -+ "\"%s\" is invalid; the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.max)); - (*rval) = enabledNSSVersions.max; - } -@@ -1371,7 +1431,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { -@@ -1382,7 +1442,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.max)); - (*rval) = enabledNSSVersions.max; - } else { -@@ -1394,7 +1454,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { -@@ -1405,7 +1465,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.max)); - (*rval) = enabledNSSVersions.max; - } else { -@@ -1418,7 +1478,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { -@@ -1429,7 +1489,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.max)); - (*rval) = enabledNSSVersions.max; - } else { -@@ -1441,13 +1501,13 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (ismin) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is out of the range of the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is out of the range of the supported version; " -- "the default value \"%s\" is used.\n", -+ "the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.max; - } -@@ -1455,12 +1515,12 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - } else { - if (ismin) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " -- "\"%s\" is invalid; the default value \"%s\" is used.\n", -+ "\"%s\" is invalid; the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.min; - } else { - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " -- "\"%s\" is invalid; the default value \"%s\" is used.\n", -+ "\"%s\" is invalid; the default value \"%s\" is used.", - val, getNSSVersion_str(enabledNSSVersions.min)); - (*rval) = enabledNSSVersions.max; - } -@@ -1490,14 +1550,13 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - int slapd_SSLclientAuth; - char* tmpDir; - Slapi_Entry *e = NULL; -- PRBool enableSSL2 = PR_FALSE; -- PRBool enableSSL3 = PR_TRUE; -- PRBool enableTLS1 = PR_TRUE; - PRBool fipsMode = PR_FALSE; - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ - PRUint16 NSSVersionMin = enabledNSSVersions.min; - PRUint16 NSSVersionMax = enabledNSSVersions.max; - #endif -+ char cipher_string[1024]; -+ int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER; - - /* turn off the PKCS11 pin interactive mode */ - #ifndef _WIN32 -@@ -1839,6 +1898,8 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - } else { - enableTLS1 = slapi_entry_attr_get_bool( e, "nsTLS1" ); - } -+ } else if (enabledNSSVersions.max > SSL_LIBRARY_VERSION_TLS_1_0) { -+ enableTLS1 = PR_TRUE; /* If available, enable TLS1 */ - } - slapi_ch_free_string( &val ); - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ -@@ -1853,14 +1914,12 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - } - slapi_ch_free_string( &val ); - if (NSSVersionMin > NSSVersionMax) { -- slapd_SSL_warn("Security Initialization: The min value of NSS version range " -- "\"%s\" is greater than the max value \"%s\"; " -- "the default range \"%s\" - \"%s\" is used.\n", -+ slapd_SSL_warn("The min value of NSS version range \"%s\" is greater than the max value \"%s\".", - getNSSVersion_str(NSSVersionMin), -- getNSSVersion_str(NSSVersionMax), -- getNSSVersion_str(enabledNSSVersions.min), -+ getNSSVersion_str(NSSVersionMax)); -+ slapd_SSL_warn("Reset the max \"%s\" to supported max \"%s\".", -+ getNSSVersion_str(NSSVersionMax), - getNSSVersion_str(enabledNSSVersions.max)); -- NSSVersionMin = enabledNSSVersions.min; - NSSVersionMax = enabledNSSVersions.max; - } - #endif -@@ -1868,18 +1927,21 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ - if (NSSVersionMin > 0) { - /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */ -- SSLVersionRange myNSSVersions; -- myNSSVersions.min = NSSVersionMin; -- myNSSVersions.max = NSSVersionMax; -- restrict_SSLVersionRange(&myNSSVersions, enableSSL3, enableTLS1); -- sslStatus = SSL_VersionRangeSet(pr_sock, &myNSSVersions); -+ slapdNSSVersions.min = NSSVersionMin; -+ slapdNSSVersions.max = NSSVersionMax; -+ restrict_SSLVersionRange(); -+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization", -+ "Configured SSL version range: min: %s, max: %s\n", -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max)); -+ sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions); - if (sslStatus == SECSuccess) { - /* Set the restricted value to the cn=encryption entry */ - } else { - slapd_SSL_error("SSL Initialization 2: " - "Failed to set SSL range: min: %s, max: %s\n", -- getNSSVersion_str(myNSSVersions.min), -- getNSSVersion_str(myNSSVersions.max)); -+ getNSSVersion_str(slapdNSSVersions.min), -+ getNSSVersion_str(slapdNSSVersions.max)); - } - } else { - #endif -@@ -1904,6 +1966,36 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ - } - #endif -+ val = slapi_entry_attr_get_charptr(e, "allowWeakCipher"); -+ if (val) { -+ if (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -+ !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no")) { -+ allowweakcipher = CIPHER_SET_DISALLOWWEAKCIPHER; -+ } else if (!PL_strcasecmp(val, "on") || !PL_strcasecmp(val, "true") || -+ !PL_strcmp(val, "1") || !PL_strcasecmp(val, "yes")) { -+ allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; -+ } else { -+ slapd_SSL_warn("The value of allowWeakCipher \"%s\" in %s is invalid.", -+ "Ignoring it and set it to default.", val, configDN); -+ } -+ } -+ slapi_ch_free((void **) &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)) ) { -+ errorCode = PR_GetError(); -+ slapd_SSL_warn("Security Initialization: Failed to set SSL cipher " -+ "preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -+ val, errorCode, slapd_pr_strerror(errorCode)); -+ rv = 3; -+ slapi_ch_free((void **) &val); -+ } -+ - freeConfigEntry( &e ); - - if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) { --- -1.9.3 - diff --git a/SOURCES/0022-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch b/SOURCES/0022-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch new file mode 100644 index 0000000..657c214 --- /dev/null +++ b/SOURCES/0022-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch @@ -0,0 +1,174 @@ +From abfd367015c9d0dfa0b97b8473923c97eab0dab5 Mon Sep 17 00:00:00 2001 +From: Rich Megginson +Date: Wed, 15 Jul 2015 14:09:24 -0600 +Subject: [PATCH 22/22] Ticket #48224 - redux - logconv.pl should handle + *.tar.xz, *.txz, *.xz log files + +https://fedorahosted.org/389/ticket/48224 +Reviewed by: nhosoi, mreynolds (Thanks!) +Branch: 389-ds-base-1.3.4 +Fix Description: Some platforms have no IO::Uncompress::UnXz, so have +to pipe out to the 'xz' command for uncompression. +Doing the 'xz' pipe will not work with compressed xz files in tar +archives, so issue an appropriate error. +The tar archive file handling was wrong - have to wrap the data in a +filehandle before passing to uncompress. +Added a lot of error checking - trying to uncompress plain text files, +trying to untar non-tar archives, trying to untar and uncompress a +tar file that is not compressed, other weird stuff like specifying a +.bz2 extension on a file compressed with .xz. +This will also need a spec file change: +Requires: perl-IO-Compress +Requires: perl-DB_File +Requires: perl-Archive-Tar +Requires: xz +Platforms tested: Fedora 21, RHEL 7.2 candidate +Flag Day: no +Doc impact: no + +(cherry picked from commit ae5b62f53557c8ce2d174999c4b561ebc4ccde55) +(cherry picked from commit 8473ae0c49492dd7931dbdd3a8377119f53ce49b) +--- + ldap/admin/src/logconv.pl | 73 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 57 insertions(+), 16 deletions(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index a6bd6c2..d26e91e 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -398,17 +398,11 @@ my $totalLineCount = 0; + + sub isTarArchive { + local $_ = shift; +- if (/\.txz$/ || /\.tar.xz$/) { +- use IO::Uncompress::UnXz; +- } + return /\.tar$/ || /\.tar\.bz2$/ || /\.tar.gz$/ || /\.tar.xz$/ || /\.tgz$/ || /\.tbz$/ || /\.txz$/; + } + + sub isCompressed { + local $_ = shift; +- if (/\.xz$/) { +- use IO::Uncompress::UnXz; +- } + return /\.gz$/ || /\.bz2$/ || /\.xz$/; + } + +@@ -418,6 +412,43 @@ sub tarNeedsUncompress { + return /\.tar.xz$/ || /\.txz$/; + } + ++# rhel7 can't grok xz ++sub doUncompress { ++ local $_ = shift; ++ my $data = shift; ++ my $TARFH; ++ # some platforms don't have xz support in IO::Uncompress::AnyUncompress ++ if (/\.tar.xz$/ || /\.txz$/ || /\.xz$/) { ++ if ($data) { ++ openFailed("Cannot read from compressed xz file in tar archive.\nPlease un-tar the tar file first, then pass individual .xz files to this program.\n", $_); ++ } ++ # so use the xz command directly ++ # NOTE: This doesn't work if the argument is a file handle e.g. from ++ # Archive::Tar ++ $! = 0; # clear ++ if (!open($TARFH, "xz -dc $_ |") or $!) { ++ openFailed($!, $_); ++ return; ++ } ++ } else { ++ my $uncompressthing; ++ if ($data) { ++ # make a filehandle object from data ++ open($uncompressthing, "<", \$data) or openFailed($!, $_); ++ } else { ++ # just read from the file ++ $uncompressthing = $_; ++ } ++ $TARFH = new IO::Uncompress::AnyUncompress $uncompressthing or ++ do { openFailed($AnyUncompressError, $_); return; }; ++ if (*$TARFH->{Plain}) { ++ openFailed("Unknown compression", $_); ++ return; ++ } ++ } ++ return $TARFH; ++} ++ + sub convertTimeToSeconds { + my $log_line = shift; + +@@ -497,6 +528,10 @@ for (my $count=0; $count < $file_count; $count++){ + if($logCount > 1 && $count == 0 && $skipFirstFile == 1){ + next; + } ++ if (! -r $logname) { ++ print "File not found: $logname\n"; ++ next; ++ } + $linesProcessed = 0; $lineBlockCount = 0; + my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$atime,$mtime,$ctime,$blksize,$blocks); + ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$cursize, +@@ -513,11 +548,12 @@ for (my $count=0; $count < $file_count; $count++){ + my $tariter = 0; + my $tarfile = 0; + my $comp = 0; ++ $LOGFH = undef; + if (isTarArchive($logname)) { + $tar = Archive::Tar->new(); + if (tarNeedsUncompress($logname)) { +- my $TARFH = new IO::Uncompress::AnyUncompress $logname or +- do { openFailed($AnyUncompressError, $logname); next }; ++ my $TARFH = doUncompress($logname); ++ next if (!$TARFH); + $tariter = Archive::Tar->iter($TARFH); + } else { + $tariter = Archive::Tar->iter($logname); +@@ -540,24 +576,21 @@ for (my $count=0; $count < $file_count; $count++){ + next; + } + if (isCompressed($tarfile->name)) { +- $LOGFH = new IO::Uncompress::AnyUncompress \$tarfile->name or +- do { openFailed($AnyUncompressError, $logname); next }; ++ $LOGFH = doUncompress($tarfile->name, $tarfile->get_content); ++ next if (!$LOGFH); + # no way in general to know how big the uncompressed file is - so + # assume a factor of 10 inflation - only used for progress reporting + $cursize *= 10; + } else { +- open(LOG,"<",\$tarfile->data) or do { openFailed($!, $tarfile->name) ; next }; +- $LOGFH = \*LOG; ++ open($LOGFH,"<",\$tarfile->data) or do { openFailed($!, $tarfile->name) ; next }; + } + } elsif ($comp) { +- $LOGFH = new IO::Uncompress::AnyUncompress $logname or +- do { openFailed($AnyUncompressError, $logname); next }; ++ $LOGFH = doUncompress($logname); + # no way in general to know how big the uncompressed file is - so + # assume a factor of 10 inflation - only used for progress reporting + $cursize *= 10; + } else { +- open(LOG,$logname) or do { openFailed($!, $logname); next }; +- $LOGFH = \*LOG; ++ open($LOGFH,$logname) or do { openFailed($!, $logname); next }; + } + my $firstline = "yes"; + while(<$LOGFH>){ +@@ -588,6 +621,14 @@ for (my $count=0; $count < $file_count; $count++){ + } + last if (!$tariter); + } ++ if ($tar) { ++ if ($tar->error()) { ++ openFailed($tar->error(), $logname); ++ } ++ if ($Archive::Tar::error) { ++ openFailed($Archive::Tar::error, $logname); ++ } ++ } + } + + if ($totalLineCount eq "0"){ +-- +1.9.3 + diff --git a/SOURCES/0023-Ticket-47928-CI-test-added-test-cases-for-ticket-479.patch b/SOURCES/0023-Ticket-47928-CI-test-added-test-cases-for-ticket-479.patch deleted file mode 100644 index 1d3b1e0..0000000 --- a/SOURCES/0023-Ticket-47928-CI-test-added-test-cases-for-ticket-479.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 8a412f7c540ac2925ad33ee633e60bf7e55e929c Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 22 Oct 2014 17:11:17 -0700 -Subject: [PATCH 23/28] Ticket 47928 - CI test: added test cases for ticket - 47928 - -Description: -test_ticket47928_run_0 - Test Case 13 - No SSL version config parameters -test_ticket47928_run_1 - Test Case 14 - No nsSSL3, nsTLS1; sslVersionMin > sslVersionMax -test_ticket47928_run_2 - Test Case 15 - nsSSL3: on; sslVersionMin: TLS1.1; sslVersionMax: TLS1.2 -test_ticket47928_run_3 - Test Case 16 - nsSSL3: on; nsTLS1: off; sslVersionMin: TLS1.1; sslVersionMax: TLS1.2 - -(cherry picked from commit 958be1271ab440a15649046e7927b44b57a4e19a) -Signed-off-by: Noriko Hosoi ---- - dirsrvtests/tickets/ticket47838_test.py | 165 +++++++++++++++++++++++++++++++- - 1 file changed, 161 insertions(+), 4 deletions(-) - -diff --git a/dirsrvtests/tickets/ticket47838_test.py b/dirsrvtests/tickets/ticket47838_test.py -index c98c36e..50a4b50 100644 ---- a/dirsrvtests/tickets/ticket47838_test.py -+++ b/dirsrvtests/tickets/ticket47838_test.py -@@ -201,7 +201,8 @@ def test_ticket47838_init(topology): - - log.info("\n######################### enable SSL in the directory server with all ciphers ######################\n") - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -- topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3', 'on'), -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3', 'off'), -+ (ldap.MOD_REPLACE, 'nsTLS1', 'on'), - (ldap.MOD_REPLACE, 'nsSSLClientAuth', 'allowed'), - (ldap.MOD_REPLACE, 'allowWeakCipher', 'on'), - (ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all')]) -@@ -645,19 +646,171 @@ def test_ticket47838_run_11(topology): - - comp_nsSSLEnableCipherCount(topology, 0) - -+def test_ticket47928_run_0(topology): -+ """ -+ No SSL version config parameters. -+ Check SSL3 (TLS1.0) is off. -+ """ -+ _header(topology, 'Test Case 13 - No SSL version config parameters') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ # add them once and remove them -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3', 'off'), -+ (ldap.MOD_REPLACE, 'nsTLS1', 'on'), -+ (ldap.MOD_REPLACE, 'sslVersionMin', 'TLS1.1'), -+ (ldap.MOD_REPLACE, 'sslVersionMax', 'TLS1.2')]) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_DELETE, 'nsSSL3', None), -+ (ldap.MOD_DELETE, 'nsTLS1', None), -+ (ldap.MOD_DELETE, 'sslVersionMin', None), -+ (ldap.MOD_DELETE, 'sslVersionMax', None)]) -+ topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '64')]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_11' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "Default SSL Version settings; Configuring the version range as min: TLS1.1"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+def test_ticket47928_run_1(topology): -+ """ -+ No nsSSL3, nsTLS1; sslVersionMin > sslVersionMax -+ Check sslVersionMax is ignored. -+ """ -+ _header(topology, 'Test Case 14 - No nsSSL3, nsTLS1; sslVersionMin > sslVersionMax') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'sslVersionMin', 'TLS1.2'), -+ (ldap.MOD_REPLACE, 'sslVersionMax', 'TLS1.1')]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_12' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "The min value of NSS version range"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+ errmsg = os.popen('egrep "SSL Initialization" %s | egrep "Configured SSL version range: min: TLS1.2, max: TLS1"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+def test_ticket47928_run_2(topology): -+ """ -+ nsSSL3: on; sslVersionMin: TLS1.1; sslVersionMax: TLS1.2 -+ Conflict between nsSSL3 and range; nsSSL3 is disabled -+ """ -+ _header(topology, 'Test Case 15 - nsSSL3: on; sslVersionMin: TLS1.1; sslVersionMax: TLS1.2') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'sslVersionMin', 'TLS1.1'), -+ (ldap.MOD_REPLACE, 'sslVersionMax', 'TLS1.2'), -+ (ldap.MOD_REPLACE, 'nsSSL3', 'on')]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_13' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "Found unsecure configuration: nsSSL3: on"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "Respect the supported range."' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+ errmsg = os.popen('egrep "SSL Initialization" %s | egrep "Configured SSL version range: min: TLS1.1, max: TLS1"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+def test_ticket47928_run_3(topology): -+ """ -+ nsSSL3: on; nsTLS1: off; sslVersionMin: TLS1.1; sslVersionMax: TLS1.2 -+ Conflict between nsSSL3/nsTLS1 and range; nsSSL3 is disabled; nsTLS1 is enabled. -+ """ -+ _header(topology, 'Test Case 16 - nsSSL3: on; nsTLS1: off; sslVersionMin: TLS1.1; sslVersionMax: TLS1.2') -+ -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'sslVersionMin', 'TLS1.1'), -+ (ldap.MOD_REPLACE, 'sslVersionMax', 'TLS1.2'), -+ (ldap.MOD_REPLACE, 'nsSSL3', 'on'), -+ (ldap.MOD_REPLACE, 'nsTLS1', 'off')]) -+ -+ log.info("\n######################### Restarting the server ######################\n") -+ topology.standalone.stop(timeout=10) -+ os.system('mv %s %s.47838_14' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('touch %s' % (topology.standalone.errlog)) -+ topology.standalone.start(timeout=120) -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "Found unsecure configuration: nsSSL3: on"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+ errmsg = os.popen('egrep "SSL alert:" %s | egrep "Respect the configured range."' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ -+ errmsg = os.popen('egrep "SSL Initialization" %s | egrep "Configured SSL version range: min: TLS1.1, max: TLS1"' % topology.standalone.errlog) -+ if errmsg != "": -+ log.info("Expected message:") -+ log.info("%s" % errmsg.readline()) -+ else: -+ log.info("Expected message was not found") -+ assert False -+ - def test_ticket47838_run_last(topology): - """ - Check nssSSL3Chiphers: all <== invalid value - All ciphers are disabled. - """ -- _header(topology, 'Test Case 13 - Check nssSSL3Chiphers: all, which is invalid') -+ _header(topology, 'Test Case 17 - Check nssSSL3Chiphers: all, which is invalid') - - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', None)]) - topology.standalone.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3Ciphers', 'all')]) - - log.info("\n######################### Restarting the server ######################\n") - topology.standalone.stop(timeout=10) -- os.system('mv %s %s.47838_10' % (topology.standalone.errlog, topology.standalone.errlog)) -+ os.system('mv %s %s.47838_15' % (topology.standalone.errlog, topology.standalone.errlog)) - os.system('touch %s' % (topology.standalone.errlog)) - topology.standalone.start(timeout=120) - -@@ -671,7 +824,7 @@ def test_ticket47838_run_last(topology): - - comp_nsSSLEnableCipherCount(topology, 0) - -- topology.standalone.log.info("ticket47838, 47880, 47908 were successfully verified."); -+ topology.standalone.log.info("ticket47838, 47880, 47908, 47928 were successfully verified."); - - def test_ticket47838_final(topology): - topology.standalone.simple_bind_s(DN_DM, PASSWORD) -@@ -706,6 +859,10 @@ def run_isolated(): - test_ticket47838_run_9(topo) - test_ticket47838_run_10(topo) - test_ticket47838_run_11(topo) -+ test_ticket47928_run_0(topo) -+ test_ticket47928_run_1(topo) -+ test_ticket47928_run_2(topo) -+ test_ticket47928_run_3(topo) - - test_ticket47838_run_last(topo) - --- -1.9.3 - diff --git a/SOURCES/0023-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch b/SOURCES/0023-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch new file mode 100644 index 0000000..cf76685 --- /dev/null +++ b/SOURCES/0023-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch @@ -0,0 +1,37 @@ +From 23c9a297b240d1538125721fb0f93abb876ce9c1 Mon Sep 17 00:00:00 2001 +From: Rich Megginson +Date: Thu, 16 Jul 2015 09:06:45 -0600 +Subject: [PATCH 23/30] Ticket #48224 - redux - logconv.pl should handle + *.tar.xz, *.txz, *.xz log files + +https://fedorahosted.org/389/ticket/48224 +Reviewed by: +Branch: master +Fix Description: Fix Requires: in spec file +Platforms tested: Fedora 21, RHEL 7.2 candidate +Flag Day: no +Doc impact: no + +(cherry picked from commit 193d79d4a459b709c5a55cea88794105fa60c453) +(cherry picked from commit 9109a570edd3ddb58434b19a9fca2f7c021b18ca) +--- + rpm/389-ds-base.spec.in | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in +index 3405ccd..d0bbb7a 100644 +--- a/rpm/389-ds-base.spec.in ++++ b/rpm/389-ds-base.spec.in +@@ -116,9 +116,6 @@ Requires: perl-Socket6 + Requires: perl-Socket + %endif + Requires: perl-NetAddr-IP +-# for logconv compressed file support +-Requires: perl-IO-Compress +-Requires: perl-IO-Compress-Lzma + + Source0: http://port389.org/sources/%{name}-%{version}%{?prerel}.tar.bz2 + # 389-ds-git.sh should be used to generate the source tarball from git +-- +1.9.3 + diff --git a/SOURCES/0024-Ticket-47937-Crash-in-entry_add_present_values_wsi_m.patch b/SOURCES/0024-Ticket-47937-Crash-in-entry_add_present_values_wsi_m.patch deleted file mode 100644 index c31da71..0000000 --- a/SOURCES/0024-Ticket-47937-Crash-in-entry_add_present_values_wsi_m.patch +++ /dev/null @@ -1,319 +0,0 @@ -From 0fb6ca5fe49774a646e36fd7acd59638cc57041c Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 24 Oct 2014 14:14:25 -0400 -Subject: [PATCH 24/28] Ticket 47937 - Crash in - entry_add_present_values_wsi_multi_valued - -Bug Description: If the DNA plugin uses an invlid attribute for "dnaType" - this can lead to crash when DNA attempts to update this - attribute. - -Fix Description: In the DNA plugin, verify that the attribute exists. - Also in entrywsi.c, pass in the type from the attribute - struct(which does do some basic normalization). - -https://fedorahosted.org/389/ticket/47937 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 3cdf0eb571d120573f2cda2c140fd2b4215c94fa) -(cherry picked from commit 738d985dc6f52660e13d94a118271ce288a75ea6) ---- - dirsrvtests/tickets/ticket47937_test.py | 237 ++++++++++++++++++++++++++++++++ - ldap/servers/plugins/dna/dna.c | 8 ++ - ldap/servers/slapd/entrywsi.c | 5 +- - 3 files changed, 248 insertions(+), 2 deletions(-) - create mode 100644 dirsrvtests/tickets/ticket47937_test.py - -diff --git a/dirsrvtests/tickets/ticket47937_test.py b/dirsrvtests/tickets/ticket47937_test.py -new file mode 100644 -index 0000000..09ee714 ---- /dev/null -+++ b/dirsrvtests/tickets/ticket47937_test.py -@@ -0,0 +1,237 @@ -+import os -+import sys -+import time -+import ldap -+import logging -+import socket -+import pytest -+from lib389 import DirSrv, Entry, tools -+from lib389.tools import DirSrvTools -+from lib389._constants import * -+from lib389.properties import * -+from constants import * -+ -+log = logging.getLogger(__name__) -+ -+installation_prefix = None -+ -+ -+class TopologyStandalone(object): -+ def __init__(self, standalone): -+ standalone.open() -+ self.standalone = standalone -+ -+ -+@pytest.fixture(scope="module") -+def topology(request): -+ ''' -+ This fixture is used to standalone topology for the 'module'. -+ At the beginning, It may exists a standalone instance. -+ It may also exists a backup for the standalone instance. -+ -+ Principle: -+ If standalone instance exists: -+ restart it -+ If backup of standalone exists: -+ create/rebind to standalone -+ -+ restore standalone instance from backup -+ else: -+ Cleanup everything -+ remove instance -+ remove backup -+ Create instance -+ Create backup -+ ''' -+ global installation_prefix -+ -+ if installation_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation_prefix -+ -+ standalone = DirSrv(verbose=False) -+ -+ # Args for the standalone instance -+ args_instance[SER_HOST] = HOST_STANDALONE -+ args_instance[SER_PORT] = PORT_STANDALONE -+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE -+ args_standalone = args_instance.copy() -+ standalone.allocate(args_standalone) -+ -+ # Get the status of the backups -+ backup_standalone = standalone.checkBackupFS() -+ -+ # Get the status of the instance and restart it if it exists -+ instance_standalone = standalone.exists() -+ if instance_standalone: -+ # assuming the instance is already stopped, just wait 5 sec max -+ standalone.stop(timeout=5) -+ standalone.start(timeout=10) -+ -+ if backup_standalone: -+ # The backup exist, assuming it is correct -+ # we just re-init the instance with it -+ if not instance_standalone: -+ standalone.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # restore standalone instance from backup -+ standalone.stop(timeout=10) -+ standalone.restoreFS(backup_standalone) -+ standalone.start(timeout=10) -+ -+ else: -+ # We should be here only in two conditions -+ # - This is the first time a test involve standalone instance -+ # - Something weird happened (instance/backup destroyed) -+ # so we discard everything and recreate all -+ -+ # Remove the backup. So even if we have a specific backup file -+ # (e.g backup_standalone) we clear backup that an instance may have created -+ if backup_standalone: -+ standalone.clearBackupFS() -+ -+ # Remove the instance -+ if instance_standalone: -+ standalone.delete() -+ -+ # Create the instance -+ standalone.create() -+ -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # Time to create the backups -+ standalone.stop(timeout=10) -+ standalone.backupfile = standalone.backupFS() -+ standalone.start(timeout=10) -+ -+ # clear the tmp directory -+ standalone.clearTmpDir(__file__) -+ -+ # -+ # Here we have standalone instance up and running -+ # Either coming from a backup recovery -+ # or from a fresh (re)init -+ # Time to return the topology -+ return TopologyStandalone(standalone) -+ -+ -+def test_ticket47937(topology): -+ """ -+ Test that DNA plugin only accepts valid attributes for "dnaType" -+ """ -+ -+ log.info("Creating \"ou=people\"...") -+ try: -+ topology.standalone.add_s(Entry(('ou=people,' + SUFFIX, { -+ 'objectclass': 'top organizationalunit'.split(), -+ 'ou': 'people' -+ }))) -+ -+ except ldap.ALREADY_EXISTS: -+ pass -+ except ldap.LDAPError, e: -+ log.error('Failed to add ou=people org unit: error ' + e.message['desc']) -+ assert False -+ -+ log.info("Creating \"ou=ranges\"...") -+ try: -+ topology.standalone.add_s(Entry(('ou=ranges,' + SUFFIX, { -+ 'objectclass': 'top organizationalunit'.split(), -+ 'ou': 'ranges' -+ }))) -+ -+ except ldap.LDAPError, e: -+ log.error('Failed to add ou=ranges org unit: error ' + e.message['desc']) -+ assert False -+ -+ log.info("Creating \"cn=entry\"...") -+ try: -+ topology.standalone.add_s(Entry(('cn=entry,ou=people,' + SUFFIX, { -+ 'objectclass': 'top groupofuniquenames'.split(), -+ 'cn': 'entry' -+ }))) -+ -+ except ldap.LDAPError, e: -+ log.error('Failed to add test entry: error ' + e.message['desc']) -+ assert False -+ -+ log.info("Creating DNA shared config entry...") -+ try: -+ topology.standalone.add_s(Entry(('dnaHostname=localhost.localdomain+dnaPortNum=389,ou=ranges,%s' % SUFFIX, { -+ 'objectclass': 'top dnaSharedConfig'.split(), -+ 'dnaHostname': 'localhost.localdomain', -+ 'dnaPortNum': '389', -+ 'dnaSecurePortNum': '636', -+ 'dnaRemainingValues': '9501' -+ }))) -+ -+ except ldap.LDAPError, e: -+ log.error('Failed to add shared config entry: error ' + e.message['desc']) -+ assert False -+ -+ log.info("Add dna plugin config entry...") -+ try: -+ topology.standalone.add_s(Entry(('cn=dna config,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config', { -+ 'objectclass': 'top dnaPluginConfig'.split(), -+ 'dnaType': 'description', -+ 'dnaMaxValue': '10000', -+ 'dnaMagicRegen': '0', -+ 'dnaFilter': '(objectclass=top)', -+ 'dnaScope': 'ou=people,%s' % SUFFIX, -+ 'dnaNextValue': '500', -+ 'dnaSharedCfgDN': 'ou=ranges,%s' % SUFFIX -+ }))) -+ -+ except ldap.LDAPError, e: -+ log.error('Failed to add DNA config entry: error ' + e.message['desc']) -+ assert False -+ -+ log.info("Enable the DNA plugin...") -+ try: -+ topology.standalone.plugins.enable(name=PLUGIN_DNA) -+ except e: -+ log.error("Failed to enable DNA Plugin: error " + e.message['desc']) -+ assert False -+ -+ log.info("Restarting the server...") -+ topology.standalone.stop(timeout=120) -+ time.sleep(1) -+ topology.standalone.start(timeout=120) -+ time.sleep(3) -+ -+ log.info("Apply an invalid attribute to the DNA config(dnaType: foo)...") -+ -+ try: -+ topology.standalone.modify_s('cn=dna config,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config', -+ [(ldap.MOD_REPLACE, 'dnaType', 'foo')]) -+ except ldap.LDAPError, e: -+ log.info('Operation failed as expected (error: %s)' % e.message['desc']) -+ else: -+ log.error('Operation incorectly succeeded! Test Failed!') -+ assert False -+ -+ topology.standalone.log.info('Test 47937 Passed.') -+ -+ -+def test_ticket47937_final(topology): -+ topology.standalone.stop(timeout=10) -+ -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - edit this file and comment '@pytest.fixture' line before 'topology' function. -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation_prefix -+ installation_prefix = None -+ -+ topo = topology(True) -+ test_ticket47937(topo) -+ -+if __name__ == '__main__': -+ run_isolated() -\ No newline at end of file -diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c -index bc280a4..75edca8 100644 ---- a/ldap/servers/plugins/dna/dna.c -+++ b/ldap/servers/plugins/dna/dna.c -@@ -936,6 +936,14 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply) - } - - for (i = 0; entry->types && entry->types[i]; i++) { -+ if (!slapi_attr_syntax_exists(entry->types[i])){ -+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -+ "dna_parse_config_entry: dnaType (%s) does " -+ "not exist.\n", -+ entry->types[i]); -+ ret = DNA_FAILURE; -+ goto bail; -+ } - slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, - "----------> %s [%s]\n", DNA_TYPE, entry->types[i]); - } -diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c -index 7039bfc..41afe1a 100644 ---- a/ldap/servers/slapd/entrywsi.c -+++ b/ldap/servers/slapd/entrywsi.c -@@ -423,6 +423,7 @@ static void resolve_attribute_state_present_to_deleted(Slapi_Entry *e, Slapi_Att - static void resolve_attribute_state_to_present_or_deleted(Slapi_Entry *e, Slapi_Attr *a, Slapi_Value **valuestoupdate, int attribute_state); - static int entry_add_present_values_wsi_single_valued(Slapi_Entry *e, const char *type, struct berval **bervals, const CSN *csn, int urp, long flags); - static int entry_add_present_values_wsi_multi_valued(Slapi_Entry *e, const char *type, struct berval **bervals, const CSN *csn, int urp, long flags); -+ - static int - entry_add_present_values_wsi(Slapi_Entry *e, const char *type, struct berval **bervals, const CSN *csn, int urp, long flags) - { -@@ -439,11 +440,11 @@ entry_add_present_values_wsi(Slapi_Entry *e, const char *type, struct berval **b - - if(slapi_attr_flag_is_set(a,SLAPI_ATTR_FLAG_SINGLE)) - { -- retVal = entry_add_present_values_wsi_single_valued( e, type, bervals, csn, urp, 0 ); -+ retVal = entry_add_present_values_wsi_single_valued( e, a->a_type, bervals, csn, urp, 0 ); - } - else - { -- retVal = entry_add_present_values_wsi_multi_valued( e, type, bervals, csn, urp, 0 ); -+ retVal = entry_add_present_values_wsi_multi_valued( e, a->a_type, bervals, csn, urp, 0 ); - } - return retVal; - } --- -1.9.3 - diff --git a/SOURCES/0024-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch b/SOURCES/0024-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch new file mode 100644 index 0000000..21a99ea --- /dev/null +++ b/SOURCES/0024-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch @@ -0,0 +1,43 @@ +From 413414c98313a076111d8e40a7a10fa369433e6e Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 16 Jul 2015 10:34:47 -0700 +Subject: [PATCH 24/30] Ticket #48226 - In MMR, double free coould occur under + some special condition + +Bug description: + In a replicated topology, a authenticated user that have write access + on an entry can send a series of operations that crash the server. + The crash is due to an access to a already freed buffer. +Fix description: + To avoid the double free, duplicate a CSNSet and assign it to the + Slapi_Value. + +https://fedorahosted.org/389/ticket/48226 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit a0f8e0f981a046882db299a7a6d6d1c01bc19571) +(cherry picked from commit bdbc81e62eb8d7b8dfb298c7ba983cf86353fe66) +--- + ldap/servers/slapd/valueset.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c +index 0cf3ded..7eabb82 100644 +--- a/ldap/servers/slapd/valueset.c ++++ b/ldap/servers/slapd/valueset.c +@@ -1415,8 +1415,9 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a, + if(v) + { + value_update_csn(v,t,csn); +- if (csnref_updated) +- valuestoupdate[i]->v_csnset = (CSNSet *)value_get_csnset(v); ++ if (csnref_updated) { ++ valuestoupdate[i]->v_csnset = csnset_dup(value_get_csnset(v)); ++ } + valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]); + valuestoupdate[i]= NULL; + del_count++; +-- +1.9.3 + diff --git a/SOURCES/0025-Ticket-47928-Disable-SSL-v3-by-default.patch b/SOURCES/0025-Ticket-47928-Disable-SSL-v3-by-default.patch deleted file mode 100644 index ea6855f..0000000 --- a/SOURCES/0025-Ticket-47928-Disable-SSL-v3-by-default.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 02e9d25e7836bc5f350bc81d78ed2b8dd457f9b2 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 27 Oct 2014 09:24:46 -0700 -Subject: [PATCH 25/28] Ticket #47928 - Disable SSL v3, by default. - -Description: commit c1ecd8b659a0b8f7d84f8157cb69810c85ee26e4 -introdueced a coverity defect: 12783 - Logically dead code - -This patch removes the dead code. - -https://fedorahosted.org/389/ticket/47928 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit 77989d3bb5471542db50d66de77cc40fe4500cbd) -(cherry picked from commit 29a41604ce48855bd6d96bbd83cbae870deaa8d7) ---- - ldap/servers/slapd/ssl.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 26ef251..f81d1fb 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -1215,7 +1215,6 @@ slapd_ssl_init() - PRErrorCode errorCode; - char ** family_list; - char *val = NULL; -- int rv = 0; - PK11SlotInfo *slot; - Slapi_Entry *entry = NULL; - -@@ -1334,10 +1333,6 @@ slapd_ssl_init() - * already been executed. */ - _security_library_initialized = 1; - -- if ( rv != 0 ) { -- return rv; -- } -- - return 0; - } - --- -1.9.3 - diff --git a/SOURCES/0025-Ticket-48226-CI-test-added-test-cases-for-ticket-482.patch b/SOURCES/0025-Ticket-48226-CI-test-added-test-cases-for-ticket-482.patch new file mode 100644 index 0000000..3db39ae --- /dev/null +++ b/SOURCES/0025-Ticket-48226-CI-test-added-test-cases-for-ticket-482.patch @@ -0,0 +1,266 @@ +From e6b20ffcc995b2ac190b96850073c0569bc6d294 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 16 Jul 2015 10:41:53 -0700 +Subject: [PATCH 25/30] Ticket #48226 - CI test: added test cases for ticket + 48226 + +Description: In MMR, double free coould occur under some special condition + +This test script was written by thierry bordaz . +A small modification to check the memory leak was added. + +(cherry picked from commit f5d24450477f8341261c3e5cb5c54ec1ab83328f) +(cherry picked from commit 8600a5eabc78848ad1bf0a9c2014823d0cd6cedc) +--- + dirsrvtests/tickets/ticket48226_test.py | 239 ++++++++++++++++++++++++++++++++ + 1 file changed, 239 insertions(+) + create mode 100644 dirsrvtests/tickets/ticket48226_test.py + +diff --git a/dirsrvtests/tickets/ticket48226_test.py b/dirsrvtests/tickets/ticket48226_test.py +new file mode 100644 +index 0000000..87814e7 +--- /dev/null ++++ b/dirsrvtests/tickets/ticket48226_test.py +@@ -0,0 +1,239 @@ ++# --- 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 --- ++# ++import os ++import sys ++import time ++import ldap ++import logging ++import pytest ++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 ++ ++ ++class TopologyReplication(object): ++ def __init__(self, master1, master2): ++ master1.open() ++ self.master1 = master1 ++ master2.open() ++ self.master2 = master2 ++ ++ ++@pytest.fixture(scope="module") ++def topology(request): ++ global installation1_prefix ++ os.environ['USE_VALGRIND'] = '1' ++ if installation1_prefix: ++ args_instance[SER_DEPLOYED_DIR] = installation1_prefix ++ ++ # Creating master 1... ++ master1 = DirSrv(verbose=False) ++ if installation1_prefix: ++ args_instance[SER_DEPLOYED_DIR] = installation1_prefix ++ args_instance[SER_HOST] = HOST_MASTER_1 ++ args_instance[SER_PORT] = PORT_MASTER_1 ++ args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1 ++ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX ++ args_master = args_instance.copy() ++ master1.allocate(args_master) ++ instance_master1 = master1.exists() ++ if instance_master1: ++ master1.delete() ++ master1.create() ++ master1.open() ++ master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1) ++ ++ # Creating master 2... ++ master2 = DirSrv(verbose=False) ++ if installation1_prefix: ++ args_instance[SER_DEPLOYED_DIR] = installation1_prefix ++ args_instance[SER_HOST] = HOST_MASTER_2 ++ args_instance[SER_PORT] = PORT_MASTER_2 ++ args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2 ++ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX ++ args_master = args_instance.copy() ++ master2.allocate(args_master) ++ instance_master2 = master2.exists() ++ if instance_master2: ++ master2.delete() ++ master2.create() ++ master2.open() ++ master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2) ++ ++ # ++ # Create all the agreements ++ # ++ # Creating agreement from master 1 to master 2 ++ properties = {RA_NAME: r'meTo_$host:$port', ++ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], ++ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], ++ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], ++ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} ++ m1_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties) ++ if not m1_m2_agmt: ++ log.fatal("Fail to create a master -> master replica agreement") ++ sys.exit(1) ++ log.debug("%s created" % m1_m2_agmt) ++ ++ # Creating agreement from master 2 to master 1 ++ properties = {RA_NAME: r'meTo_$host:$port', ++ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], ++ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], ++ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], ++ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} ++ m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties) ++ if not m2_m1_agmt: ++ log.fatal("Fail to create a master -> master replica agreement") ++ sys.exit(1) ++ log.debug("%s created" % m2_m1_agmt) ++ ++ # Allow the replicas to get situated with the new agreements... ++ time.sleep(5) ++ ++ # ++ # Initialize all the agreements ++ # ++ master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2) ++ master1.waitForReplInit(m1_m2_agmt) ++ ++ # Check replication is working... ++ if master1.testReplication(DEFAULT_SUFFIX, master2): ++ log.info('Replication is working.') ++ else: ++ log.fatal('Replication is not working.') ++ assert False ++ ++ # Clear out the tmp dir ++ master1.clearTmpDir(__file__) ++ ++ return TopologyReplication(master1, master2) ++ ++def test_ticket11111_set_purgedelay(topology): ++ args = {REPLICA_PURGE_DELAY: '5', ++ REPLICA_PURGE_INTERVAL: '5'} ++ try: ++ topology.master1.replica.setProperties(DEFAULT_SUFFIX, None, None, args) ++ except: ++ log.fatal('Failed to configure replica') ++ assert False ++ try: ++ topology.master2.replica.setProperties(DEFAULT_SUFFIX, None, None, args) ++ except: ++ log.fatal('Failed to configure replica') ++ assert False ++ topology.master1.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-auditlog-logging-enabled', 'on')]) ++ topology.master2.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-auditlog-logging-enabled', 'on')]) ++ topology.master1.restart(10) ++ topology.master2.restart(10) ++ ++ ++def test_ticket11111_1(topology): ++ name = 'test_entry' ++ dn = "cn=%s,%s" % (name, SUFFIX) ++ ++ topology.master1.add_s(Entry((dn , { ++ 'objectclass': "top person".split(), ++ 'sn': name, ++ 'cn': name}))) ++ ++ # First do an update that is replicated ++ mods = [(ldap.MOD_ADD, 'description', '5')] ++ topology.master1.modify_s(dn, mods) ++ ++ nbtry = 0 ++ while (nbtry <= 10): ++ try: ++ ent = topology.master2.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)", ['description']) ++ if ent.hasAttr('description') and ent.getValue('description') == '5': ++ break ++ except ldap.NO_SUCH_OBJECT: ++ pass ++ nbtry = nbtry + 1 ++ time.sleep(1) ++ assert nbtry <= 10 ++ ++ # Stop M2 so that it will not receive the next update ++ topology.master2.stop(10) ++ ++ # ADD a new value that is not replicated ++ mods = [(ldap.MOD_DELETE, 'description', '5')] ++ topology.master1.modify_s(dn, mods) ++ ++ # Stop M1 so that it will keep del '5' that is unknown from master2 ++ topology.master1.stop(10) ++ ++ # Get the sbin directory so we know where to replace 'ns-slapd' ++ sbin_dir = get_sbin_dir(prefix=topology.master2.prefix) ++ ++ # Enable valgrind ++ valgrind_enable(sbin_dir) ++ ++ # start M2 to do the next updates ++ topology.master2.start(10) ++ ++ # ADD 'description' by '5' ++ mods = [(ldap.MOD_DELETE, 'description', '5')] ++ topology.master2.modify_s(dn, mods) ++ ++ # DEL 'description' by '5' ++ mods = [(ldap.MOD_ADD, 'description', '5')] ++ topology.master2.modify_s(dn, mods) ++ ++ # sleep of purgedelay so that the next update will purge the CSN_7 ++ time.sleep(6) ++ ++ # ADD 'description' by '8' that purge the state info ++ mods = [(ldap.MOD_ADD, 'description', '6')] ++ topology.master2.modify_s(dn, mods) ++ ++ if valgrind_check_leak(topology.master2, 'csnset_dup'): ++ log.error('test_csnset_dup: Memory leak is present!') ++ else: ++ log.info('test_csnset_dup: No leak is present!') ++ ++ if valgrind_check_leak(topology.master2, 'Invalid'): ++ log.info('Valgrind reported invalid!') ++ else: ++ log.info('Valgrind is happy!') ++ ++ #log.info("You can attach yourself") ++ #time.sleep(60) ++ ++ # Enable valgrind ++ valgrind_disable(sbin_dir) ++ ++ topology.master1.start(10) ++ ++ ++def test_ticket11111_final(topology): ++ topology.master1.delete() ++ topology.master2.delete() ++ log.info('Testcase PASSED') ++ ++ ++def run_isolated(): ++ global installation1_prefix ++ installation1_prefix = None ++ ++ topo = topology(True) ++ test_ticket11111_set_purgedelay(topo) ++ test_ticket11111_1(topo) ++ ++ ++if __name__ == '__main__': ++ run_isolated() ++ +-- +1.9.3 + diff --git a/SOURCES/0026-Ticket-47939-Malformed-cookie-for-LDAP-Sync-makes-DS.patch b/SOURCES/0026-Ticket-47939-Malformed-cookie-for-LDAP-Sync-makes-DS.patch deleted file mode 100644 index b217b4e..0000000 --- a/SOURCES/0026-Ticket-47939-Malformed-cookie-for-LDAP-Sync-makes-DS.patch +++ /dev/null @@ -1,97 +0,0 @@ -From fe0ac5946b04d9ff2455692ddb8c0a8b0c91a7c7 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 3 Nov 2014 16:58:21 -0800 -Subject: [PATCH 26/28] Ticket #47939 - Malformed cookie for LDAP Sync makes DS - crash - -Bug Description: If a cookie sent from clients did not have the -expected form: server_signature#client_signature#change_info_number, -a NULL reference triggered a server crash in sync_cookie_isvalid. - -Fix Description: If a cookie does not have the expected form, -sync_cookie_parse returns NULL, which prevents the NULL reference -in the server_signature and client_signature. - -https://fedorahosted.org/389/ticket/47939 - -Reviewed by lkrispen@redhat.com (Thank you, Ludwig!!) - -(cherry picked from commit 8f540a6cee09be13430ebe0b983d2affe2863365) -(cherry picked from commit d87202acad6426bee7af8753a0ffe5ad5b3082df) ---- - ldap/servers/plugins/sync/sync_util.c | 33 ++++++++++++++++++++++----------- - 1 file changed, 22 insertions(+), 11 deletions(-) - -diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c -index ef4a3f7..de65b99 100644 ---- a/ldap/servers/plugins/sync/sync_util.c -+++ b/ldap/servers/plugins/sync/sync_util.c -@@ -552,21 +552,21 @@ Sync_Cookie * - sync_cookie_parse (char *cookie) - { - char *p, *q; -- Sync_Cookie *sc; -+ Sync_Cookie *sc = NULL; - - if (cookie == NULL || *cookie == '\0' ) { - return NULL; - } - -+ /* -+ * Format of cookie: server_signature#client_signature#change_info_number -+ * If the cookie is malformed, NULL is returned. -+ */ - p = q = cookie; -- sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie)); -- -- sc->cookie_client_signature = NULL; -- sc->cookie_server_signature = NULL; -- sc->cookie_change_info = -1; - p = strchr(q, '#'); - if (p) { - *p = '\0'; -+ sc = (Sync_Cookie *)slapi_ch_calloc(1, sizeof(Sync_Cookie)); - sc->cookie_server_signature = slapi_ch_strdup(q); - q = p + 1; - p = strchr(q, '#'); -@@ -574,21 +574,32 @@ sync_cookie_parse (char *cookie) - *p = '\0'; - sc->cookie_client_signature = slapi_ch_strdup(q); - sc->cookie_change_info = sync_number2int(p+1); -+ if (sc->cookie_change_info < 0) { -+ goto error_return; -+ } -+ } else { -+ goto error_return; - } - } -- - return (sc); -+error_return: -+ slapi_ch_free_string(&(sc->cookie_client_signature)); -+ slapi_ch_free_string(&(sc->cookie_server_signature)); -+ slapi_ch_free((void **)&sc); -+ return NULL; - } - - int - sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie) - { - /* client and server info must match */ -- if (strcmp(testcookie->cookie_client_signature,refcookie->cookie_client_signature) || -- strcmp(testcookie->cookie_server_signature,refcookie->cookie_server_signature) || -- testcookie->cookie_change_info == -1 || -- testcookie->cookie_change_info > refcookie->cookie_change_info ) -+ if ((testcookie && refcookie) && -+ (strcmp(testcookie->cookie_client_signature,refcookie->cookie_client_signature) || -+ strcmp(testcookie->cookie_server_signature,refcookie->cookie_server_signature) || -+ testcookie->cookie_change_info == -1 || -+ testcookie->cookie_change_info > refcookie->cookie_change_info)) { - return (0); -+ } - /* could add an additional check if the requested state in client cookie is still - * available. Accept any state request for now. - */ --- -1.9.3 - diff --git a/SOURCES/0026-Ticket-48179-Starting-a-replica-agreement-can-lead-t.patch b/SOURCES/0026-Ticket-48179-Starting-a-replica-agreement-can-lead-t.patch new file mode 100644 index 0000000..275a95c --- /dev/null +++ b/SOURCES/0026-Ticket-48179-Starting-a-replica-agreement-can-lead-t.patch @@ -0,0 +1,293 @@ +From 1acfdbb4428c70f7f6058da4374ecb29f9bb3149 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 17 Jul 2015 15:08:00 -0400 +Subject: [PATCH 26/30] Ticket 48179 - Starting a replica agreement can lead to + deadlock + +Bug Description: When starting a replica agreement and setting the agmt maxcsn + a deadlock can occur with another op updating nsuniqueid index. + When setting the agmt maxcsn the server searches for the tombstone + ruv which uses the nsuniqueid index, and it does this while holding + the repl agmt lock. If another thread is doing a delete and + writing to the change log, it can also grab a write lock on the + nsuniqueid index, before it attempts to grab the agmt lock. This + can lead to a deadlock if the timing is right. + +Fix Description: When starting the agmt and setting the agmt maxcsn, search/get + the tombstone ruv before we take the repl agmt lock. + +https://fedorahosted.org/389/ticket/48179 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit eb3086dcb0c56a23d6cee00a12f38b2584fe59a2) +(cherry picked from commit 23a3ff6082cba3eb749401eff44942b16dc30538) +--- + ldap/servers/plugins/replication/repl5.h | 1 - + ldap/servers/plugins/replication/repl5_agmt.c | 211 ++++++++++++-------------- + 2 files changed, 101 insertions(+), 111 deletions(-) + +diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 4a5d859..0b0f26b 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -380,7 +380,6 @@ PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt); + void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout); + void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn); + void add_agmt_maxcsns(Slapi_Entry *e, Replica *r); +-void agmt_set_maxcsn(Repl_Agmt *ra); + void agmt_remove_maxcsn(Repl_Agmt *ra); + int agmt_maxcsn_to_smod (Replica *r, Slapi_Mod *smod); + int agmt_set_WaitForAsyncResults(Repl_Agmt *ra, const Slapi_Entry *e); +diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c +index 9d1a8f2..f84eacb 100644 +--- a/ldap/servers/plugins/replication/repl5_agmt.c ++++ b/ldap/servers/plugins/replication/repl5_agmt.c +@@ -668,43 +668,127 @@ int + agmt_start(Repl_Agmt *ra) + { + Repl_Protocol *prot = NULL; ++ Slapi_PBlock *pb = NULL; ++ Slapi_Entry **entries = NULL; ++ Slapi_DN *repl_sdn = NULL; ++ char *attrs[2]; ++ int protocol_state; ++ int found_ruv = 0; ++ int rc = 0; + +- int protocol_state; +- +- /* To Allow Consumer Initialisation when adding an agreement: */ +- if (ra->auto_initialize == STATE_PERFORMING_TOTAL_UPDATE) +- { +- protocol_state = STATE_PERFORMING_TOTAL_UPDATE; +- } +- else +- { +- protocol_state = STATE_PERFORMING_INCREMENTAL_UPDATE; +- } ++ /* To Allow Consumer Initialisation when adding an agreement: */ ++ if (ra->auto_initialize == STATE_PERFORMING_TOTAL_UPDATE){ ++ protocol_state = STATE_PERFORMING_TOTAL_UPDATE; ++ } else { ++ protocol_state = STATE_PERFORMING_INCREMENTAL_UPDATE; ++ } + + /* First, create a new protocol object */ + if ((prot = prot_new(ra, protocol_state)) == NULL) { + return -1; + } + +- /* Now it is safe to own the agreement lock */ ++ /* ++ * Set the agmt maxcsn ++ * ++ * We need to get the replica ruv before we take the ++ * agmt lock to avoid potential deadlocks on the nsuniqueid ++ * index. ++ */ ++ repl_sdn = agmt_get_replarea(ra); ++ ++ pb = slapi_pblock_new(); ++ attrs[0] = (char*)type_agmtMaxCSN; ++ attrs[1] = NULL; ++ slapi_search_internal_set_pb_ext( ++ pb, ++ repl_sdn, ++ LDAP_SCOPE_BASE, ++ "objectclass=*", ++ attrs, ++ 0, ++ NULL, ++ RUV_STORAGE_ENTRY_UNIQUEID, ++ repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), ++ OP_FLAG_REPLICATED); ++ slapi_search_internal_pb (pb); ++ ++ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); ++ if (rc == LDAP_SUCCESS){ ++ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); ++ if (NULL == entries || NULL == entries[0]){ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, ++ "agmt_start: replica ruv tombstone entry for " ++ "replica %s not found\n", ++ slapi_sdn_get_dn(ra->replarea)); ++ } else { ++ found_ruv = 1; ++ } ++ } ++ ++ /* ++ * Now it is safe to own the agreement lock ++ */ + PR_Lock(ra->lock); + + /* Check that replication is not already started */ + if (ra->protocol != NULL) { + slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "replication already started for agreement \"%s\"\n", agmt_get_long_name(ra)); +- PR_Unlock(ra->lock); + prot_free(&prot); +- return 0; ++ goto done; + } + ++ /* Set and start the protocol */ + ra->protocol = prot; +- +- /* Start the protocol thread */ + prot_start(ra->protocol); + +- agmt_set_maxcsn(ra); ++ /* ++ * If we found the repl ruv, set the agmt maxcsn... ++ */ ++ if (found_ruv){ ++ Replica *r; ++ Object *repl_obj; ++ char **maxcsns = NULL; ++ int i; + ++ maxcsns = slapi_entry_attr_get_charray(entries[0], type_agmtMaxCSN); ++ repl_obj = prot_get_replica_object(ra->protocol); ++ if(repl_obj && maxcsns){ ++ r = (Replica *)object_get_data(repl_obj); ++ if(r){ ++ /* ++ * Loop over all the agmt maxcsns and find ours... ++ */ ++ for(i = 0; maxcsns[i]; i++){ ++ char buf[BUFSIZ]; ++ char unavail_buf[BUFSIZ]; ++ ++ PR_snprintf(buf,BUFSIZ,"%s;%s;%s;%d;",slapi_sdn_get_dn(repl_sdn), ++ slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), ++ ra->hostname, ra->port); ++ PR_snprintf(unavail_buf, BUFSIZ,"%s;%s;%s;%d;unavailable", slapi_sdn_get_dn(repl_sdn), ++ slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), ++ ra->hostname, ra->port); ++ if(strstr(maxcsns[i], buf) || strstr(maxcsns[i], unavail_buf)){ ++ /* Set the maxcsn */ ++ slapi_ch_free_string(&ra->maxcsn); ++ ra->maxcsn = slapi_ch_strdup(maxcsns[i]); ++ ra->consumerRID = agmt_maxcsn_get_rid(maxcsns[i]); ++ ra->tmpConsumerRID = 1; ++ break; ++ } ++ } ++ } ++ } ++ slapi_ch_array_free(maxcsns); ++ } ++ ++done: + PR_Unlock(ra->lock); ++ slapi_free_search_results_internal(pb); ++ slapi_pblock_destroy (pb); ++ slapi_sdn_free(&repl_sdn); ++ + return 0; + } + +@@ -3052,99 +3136,6 @@ agmt_maxcsn_to_smod (Replica *r, Slapi_Mod *smod) + } + + /* +- * Called when we start a repl agmt +- */ +-void +-agmt_set_maxcsn(Repl_Agmt *ra) +-{ +- Slapi_PBlock *pb = NULL; +- Slapi_Entry **entries = NULL; +- Replica *r = NULL; +- Object *repl_obj; +- const Slapi_DN *tombstone_sdn = NULL; +- char *attrs[2]; +- int rc; +- +- /* read ruv state from the ruv tombstone entry */ +- pb = slapi_pblock_new(); +- if (!pb) { +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "agmt_set_maxcsn: Out of memory\n"); +- goto done; +- } +- repl_obj = prot_get_replica_object(ra->protocol); +- if(repl_obj){ +- r = (Replica *)object_get_data(repl_obj); +- tombstone_sdn = replica_get_root(r); +- } +- ra->maxcsn = NULL; +- attrs[0] = (char*)type_agmtMaxCSN; +- attrs[1] = NULL; +- slapi_search_internal_set_pb_ext( +- pb, +- (Slapi_DN *)tombstone_sdn, +- LDAP_SCOPE_BASE, +- "objectclass=*", +- attrs, +- 0, /* attrsonly */ +- NULL, /* controls */ +- RUV_STORAGE_ENTRY_UNIQUEID, +- repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), +- OP_FLAG_REPLICATED); /* flags */ +- slapi_search_internal_pb (pb); +- +- slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); +- if (rc == LDAP_SUCCESS){ +- Replica *r; +- Object *repl_obj; +- char **maxcsns; +- int i; +- +- slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); +- if (NULL == entries || NULL == entries[0]){ +- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, +- "agmt_set_maxcsn: replica ruv tombstone entry for " +- "replica %s not found\n", +- slapi_sdn_get_dn(ra->replarea)); +- goto done; +- } +- maxcsns = slapi_entry_attr_get_charray(entries[0], type_agmtMaxCSN); +- repl_obj = prot_get_replica_object(ra->protocol); +- if(repl_obj && maxcsns){ +- r = (Replica *)object_get_data(repl_obj); +- if(r){ +- /* +- * Loop over all the agmt maxcsns and find ours +- */ +- for(i = 0; maxcsns[i]; i++){ +- char buf[BUFSIZ]; +- char unavail_buf[BUFSIZ]; +- +- PR_snprintf(buf,BUFSIZ,"%s;%s;%s;%d;",slapi_sdn_get_dn(ra->replarea), +- slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), +- ra->hostname, ra->port); +- PR_snprintf(unavail_buf, BUFSIZ,"%s;%s;%s;%d;unavailable", slapi_sdn_get_dn(ra->replarea), +- slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), +- ra->hostname, ra->port); +- if(strstr(maxcsns[i], buf) || strstr(maxcsns[i], unavail_buf)){ +- slapi_ch_free_string(&ra->maxcsn); +- ra->maxcsn = slapi_ch_strdup(maxcsns[i]); +- ra->consumerRID = agmt_maxcsn_get_rid(maxcsns[i]); +- ra->tmpConsumerRID = 1; +- break; +- } +- } +- } +- } +- slapi_ch_array_free(maxcsns); +- } +-done: +- if (NULL != pb){ +- slapi_free_search_results_internal(pb); +- slapi_pblock_destroy (pb); +- } +-} +- +-/* + * Parse out the consumer replicaID from the agmt maxcsn + * + * "repl area;agmt_rdn;hostname;port;consumer_rid;maxcsn" +-- +1.9.3 + diff --git a/SOURCES/0027-Ticket-47910-logconv.pl-check-that-the-end-time-is-g.patch b/SOURCES/0027-Ticket-47910-logconv.pl-check-that-the-end-time-is-g.patch new file mode 100644 index 0000000..5ad4f0c --- /dev/null +++ b/SOURCES/0027-Ticket-47910-logconv.pl-check-that-the-end-time-is-g.patch @@ -0,0 +1,72 @@ +From 422028f6589250523c8a8669827bd0cccc347090 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 20 Jul 2015 11:18:12 -0400 +Subject: [PATCH 27/30] Ticket 47910 - logconv.pl - check that the end time is + greater than the start time + +Bug Description: There is no check if the end time is greater than the start time. + This leads to an empty report being generated, when an error + should be returned instead. + +Fix Description: If start and end time are used, validate that the end time is + greater than the start time. + + Also, improved an error message when the tool options are not + correctly used. + +https://fedorahosted.org/389/ticket/47910 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 34ffa6c44734b99c252e7585bb499089ac8e6a67) +(cherry picked from commit 16b95b12d26fb293d68be154c602398798353bb8) +--- + ldap/admin/src/logconv.pl | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index d26e91e..0038a03 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -148,14 +148,13 @@ while($arg_count <= $#ARGV){ + } + + if($file_count == 0){ +- if($reportStatsSecFile or $reportStatsMinFile){ +- print "Usage error for option -m or -M, either the output file or access log is missing!\n\n"; +- } else { +- print "There are no access logs specified!\n\n"; +- } ++ print "There are no access logs specified, or the tool options have not been used correctly!\n"; + exit 1; + } + ++# ++# Initialize the statistic blocks ++# + if ($reportStatsSecFile) { + $s_stats = new_stats_block($reportStatsSecFile); + $reportStats = "-m"; +@@ -357,6 +356,19 @@ my %monthname = ( + + ); + ++# ++# Validate start/end times (if specified) ++# ++if ($startTime and $endTime){ ++ # Make sure the end time is not earlier than the start time ++ my $testStart = convertTimeToSeconds($startTime); ++ my $testEnd = convertTimeToSeconds($endTime); ++ if ($testStart > $testEnd){ ++ print "Start time ($startTime) is greater than end time ($endTime)!\n"; ++ exit 1; ++ } ++} ++ + my $linesProcessed; + my $lineBlockCount; + my $cursize = 0; +-- +1.9.3 + diff --git a/SOURCES/0027-Ticket-47945-Add-SSL-TLS-version-info-to-the-access-.patch b/SOURCES/0027-Ticket-47945-Add-SSL-TLS-version-info-to-the-access-.patch deleted file mode 100644 index 675fa31..0000000 --- a/SOURCES/0027-Ticket-47945-Add-SSL-TLS-version-info-to-the-access-.patch +++ /dev/null @@ -1,641 +0,0 @@ -From e7c71a8c3a361fa7cbf96a0c57723c74d044922a Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 10 Nov 2014 13:51:34 -0800 -Subject: [PATCH 27/28] Ticket #47945 - Add SSL/TLS version info to the access - log - -Description: Added the currently used SSL library version info per -connection to the access log. -Sample output: - SSL - [..] conn=3 fd=64 slot=64 SSL connection from ::1 to ::1 - [..] conn=3 TLS1.2 128-bit AES-GCM - - startTLS - [..] conn=4 op=0 EXT oid="1.3.6.1.4.1.1466.20037" name="startTLS" - [..] conn=4 op=0 RESULT err=0 tag=120 nentries=0 etime=0 - [..] conn=4 TLS1.2 128-bit AES-GCM - -To convert the SSL version number to string (e.g., SSL_LIBRARY_VERSION_ -TLS_1_2 --> "TLS1.2"), instead of maintaining a mapping table, this -patch calculates the number and generates the version string. - -https://fedorahosted.org/389/ticket/47945 - -Reviewed and adviced by rmeggins@redhat.com (Thanks a lot, Rich!!) - -(cherry picked from commit a2e0de3aa90f04593427628afeb7fe090dac93fb) -(cherry picked from commit 0d1087d0c4dc9b6af3a01776ae11e0977c447fb7) ---- - ldap/servers/slapd/auth.c | 85 +++++++++------- - ldap/servers/slapd/slapi-private.h | 19 ++++ - ldap/servers/slapd/ssl.c | 194 ++++++++++++++++++++----------------- - 3 files changed, 174 insertions(+), 124 deletions(-) - -diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c -index 5b7dc31..0219576 100644 ---- a/ldap/servers/slapd/auth.c -+++ b/ldap/servers/slapd/auth.c -@@ -430,9 +430,10 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) - int keySize = 0; - char* cipher = NULL; - char* extraErrorMsg = ""; -- SSLChannelInfo channelInfo; -- SSLCipherSuiteInfo cipherInfo; -- char* subject = NULL; -+ SSLChannelInfo channelInfo; -+ SSLCipherSuiteInfo cipherInfo; -+ char* subject = NULL; -+ char sslversion[64]; - - if ( (slapd_ssl_getChannelInfo (prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess ) { - PRErrorCode errorCode = PR_GetError(); -@@ -460,38 +461,48 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) - * to be enough, close the SSL connection. */ - if ( conn->c_flags & CONN_FLAG_START_TLS ) { - if ( cipherInfo.symKeyBits == 0 ) { -- start_tls_graceful_closure( conn, NULL, 1 ); -- goto done; -- } -+ start_tls_graceful_closure( conn, NULL, 1 ); -+ goto done; -+ } - } - - if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF ) { -- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n", -- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL" ); -- goto done; -- } -+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); -+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n", -+ (long long unsigned int)conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL" ); -+ goto done; -+ } - if (clientCert == NULL) { -- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n", -- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL" ); -+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); -+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n", -+ (long long unsigned int)conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL" ); - } else { -- subject = subject_of (clientCert); -- if (!subject) { -- slapi_log_access( LDAP_DEBUG_STATS, -- "conn=%" NSPRIu64 " SSL %i-bit %s; missing subject\n", -- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL"); -- goto done; -- } -- { -- char* issuer = issuer_of (clientCert); -- char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ]; -- slapi_log_access( LDAP_DEBUG_STATS, -- "conn=%" NSPRIu64 " SSL %i-bit %s; client %s; issuer %s\n", -- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL", -- subject ? escape_string( subject, sbuf ) : "NULL", -- issuer ? escape_string( issuer, ibuf ) : "NULL"); -- if (issuer) free (issuer); -- } -- slapi_dn_normalize (subject); -+ subject = subject_of (clientCert); -+ if (!subject) { -+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, -+ sslversion, sizeof(sslversion)); -+ slapi_log_access( LDAP_DEBUG_STATS, -+ "conn=%" NSPRIu64 " %s %i-bit %s; missing subject\n", -+ (long long unsigned int)conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL"); -+ goto done; -+ } -+ { -+ char* issuer = issuer_of (clientCert); -+ char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ]; -+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, -+ sslversion, sizeof(sslversion)); -+ slapi_log_access( LDAP_DEBUG_STATS, -+ "conn=%" NSPRIu64 " %s %i-bit %s; client %s; issuer %s\n", -+ (long long unsigned int)conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL", -+ subject ? escape_string( subject, sbuf ) : "NULL", -+ issuer ? escape_string( issuer, ibuf ) : "NULL"); -+ if (issuer) free (issuer); -+ } -+ slapi_dn_normalize (subject); - { - LDAPMessage* chain = NULL; - char *basedn = config_get_basedn(); -@@ -525,14 +536,20 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) - sdn = slapi_sdn_new_dn_passin(clientDN); - clientDN = slapi_ch_strdup(slapi_sdn_get_dn(sdn)); - slapi_sdn_free(&sdn); -+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, -+ sslversion, sizeof(sslversion)); - slapi_log_access (LDAP_DEBUG_STATS, -- "conn=%" NSPRIu64 " SSL client bound as %s\n", -- (long long unsigned int)conn->c_connid, clientDN); -+ "conn=%" NSPRIu64 " %s client bound as %s\n", -+ (long long unsigned int)conn->c_connid, -+ sslversion, clientDN); - } else if (clientCert != NULL) { -+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, -+ sslversion, sizeof(sslversion)); - slapi_log_access (LDAP_DEBUG_STATS, -- "conn=%" NSPRIu64 " SSL failed to map client " -+ "conn=%" NSPRIu64 " %s failed to map client " - "certificate to LDAP DN (%s)\n", -- (long long unsigned int)conn->c_connid, extraErrorMsg ); -+ (long long unsigned int)conn->c_connid, -+ sslversion, extraErrorMsg); - } - - /* -diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h -index a8d7738..921c397 100644 ---- a/ldap/servers/slapd/slapi-private.h -+++ b/ldap/servers/slapd/slapi-private.h -@@ -1336,6 +1336,25 @@ void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e); - /* ldaputil.c */ - char *ldaputil_get_saslpath(); - -+/* ssl.c */ -+/* -+ * If non NULL buf and positive bufsize is given, -+ * the memory is used to store the version string. -+ * Otherwise, the memory for the string is allocated. -+ * The latter case, caller is responsible to free it. -+ */ -+/* vnum is supposed to be in one of the following: -+ * nss3/sslproto.h -+ * #define SSL_LIBRARY_VERSION_2 0x0002 -+ * #define SSL_LIBRARY_VERSION_3_0 0x0300 -+ * #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301 -+ * #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302 -+ * #define SSL_LIBRARY_VERSION_TLS_1_2 0x0303 -+ * #define SSL_LIBRARY_VERSION_TLS_1_3 0x0304 -+ * ... -+ */ -+char *slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize); -+ - #ifdef __cplusplus - } - #endif -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index f81d1fb..5d6919a 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -99,7 +99,6 @@ extern symbol_t supported_ciphers[]; - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ - static SSLVersionRange enabledNSSVersions; - static SSLVersionRange slapdNSSVersions; --static char *getNSSVersion_str(PRUint16 vnum); - #endif - - /* dongle_file_name is set in slapd_nss_init when we set the path for the -@@ -246,6 +245,9 @@ static lookup_cipher _lookup_cipher[] = { - {NULL, NULL} - }; - -+/* E.g., "SSL3", "TLS1.2", "Unknown SSL version: 0x0" */ -+#define VERSION_STR_LENGTH 64 -+ - /* Supported SSL versions */ - /* nsSSL2: on -- we don't allow this any more. */ - PRBool enableSSL2 = PR_FALSE; -@@ -418,8 +420,8 @@ getSSLVersionRange(char **min, char **max) - #if defined(NSS_TLS10) - return -1; /* not supported */ - #else /* NSS_TLS11 or newer */ -- *min = slapi_ch_strdup(getNSSVersion_str(slapdNSSVersions.min)); -- *max = slapi_ch_strdup(getNSSVersion_str(slapdNSSVersions.max)); -+ *min = slapi_getSSLVersion_str(slapdNSSVersions.min, NULL, 0); -+ *max = slapi_getSSLVersion_str(slapdNSSVersions.max, NULL, 0); - return 0; - #endif - } -@@ -854,34 +856,48 @@ warn_if_no_key_file(const char *dir, int no_log) - } - - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ --typedef struct _nss_version_list { -- PRUint16 vnum; -- char* vname; --} NSSVersion_list; --NSSVersion_list _NSSVersion_list[] = --{ -- {SSL_LIBRARY_VERSION_2, "SSL2"}, -- {SSL_LIBRARY_VERSION_3_0, "SSL3"}, -- {SSL_LIBRARY_VERSION_TLS_1_0, "TLS1.0"}, -- {SSL_LIBRARY_VERSION_TLS_1_1, "TLS1.1"}, --#if defined(NSS_TLS12) -- {SSL_LIBRARY_VERSION_TLS_1_2, "TLS1.2"}, --#endif -- {0, "unknown"} --}; -- --static char * --getNSSVersion_str(PRUint16 vnum) -+/* -+ * If non NULL buf and positive bufsize is given, -+ * the memory is used to store the version string. -+ * Otherwise, the memory for the string is allocated. -+ * The latter case, caller is responsible to free it. -+ */ -+char * -+slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize) - { -- NSSVersion_list *nvlp = NULL; -- char *vstr = "none"; -- if (vnum) { -- for (nvlp = _NSSVersion_list; nvlp && nvlp->vnum; nvlp++) { -- if (nvlp->vnum == vnum) { -- vstr = nvlp->vname; -- break; -+ char *vstr = buf; -+ if (vnum >= SSL_LIBRARY_VERSION_3_0) { -+ if (vnum == SSL_LIBRARY_VERSION_3_0) { /* SSL3 */ -+ if (buf && bufsize) { -+ PR_snprintf(buf, bufsize, "SSL3"); -+ } else { -+ vstr = slapi_ch_smprintf("SSL3"); -+ } -+ } else { /* TLS v X.Y */ -+ const char *TLSFMT = "TLS%d.%d"; -+ int minor_offset = 0; /* e.g. 0x0401 -> TLS v 2.1, not 2.0 */ -+ -+ if ((vnum & SSL_LIBRARY_VERSION_3_0) == SSL_LIBRARY_VERSION_3_0) { -+ minor_offset = 1; /* e.g. 0x0301 -> TLS v 1.0, not 1.1 */ -+ } -+ if (buf && bufsize) { -+ PR_snprintf(buf, bufsize, TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset); -+ } else { -+ vstr = slapi_ch_smprintf(TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset); - } - } -+ } else if (vnum == SSL_LIBRARY_VERSION_2) { /* SSL2 */ -+ if (buf && bufsize) { -+ PR_snprintf(buf, bufsize, "SSL2"); -+ } else { -+ vstr = slapi_ch_smprintf("SSL2"); -+ } -+ } else { -+ if (buf && bufsize) { -+ PR_snprintf(buf, bufsize, "Unknown SSL version: 0x%x", vnum); -+ } else { -+ vstr = slapi_ch_smprintf("Unknown SSL version: 0x%x", vnum); -+ } - } - return vstr; - } -@@ -895,12 +911,16 @@ getNSSVersion_str(PRUint16 vnum) - static void - restrict_SSLVersionRange(void) - { -+ char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH]; -+ char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH]; -+ (void) slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin)); -+ (void) slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax)); -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax)); -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin)); - if (slapdNSSVersions.min > slapdNSSVersions.max) { - slapd_SSL_warn("Invalid configured SSL range: min: %s, max: %s; " - "Resetting the max to the supported max SSL version: %s.", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max), -- getNSSVersion_str(enabledNSSVersions.max)); -+ mymin, mymax, emax); - slapdNSSVersions.max = enabledNSSVersions.max; - } - if (enableSSL3) { -@@ -911,17 +931,14 @@ restrict_SSLVersionRange(void) - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but both nsSSL3 and nsTLS1 are on. " - "Respect the supported range.", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max)); -+ mymin, mymax); - enableSSL3 = PR_FALSE; - } - if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but both nsSSL3 and nsTLS1 are on. " - "Resetting the max to the supported max SSL version: %s.", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max), -- getNSSVersion_str(enabledNSSVersions.max)); -+ mymin, mymax, emax); - slapdNSSVersions.max = enabledNSSVersions.max; - } - } else { -@@ -930,8 +947,7 @@ restrict_SSLVersionRange(void) - slapd_SSL_warn("Supported range: min: %s, max: %s; " - "but nsSSL3 is on and nsTLS1 is off. " - "Respect the supported range.", -- getNSSVersion_str(enabledNSSVersions.min), -- getNSSVersion_str(enabledNSSVersions.max)); -+ emin, emax); - slapdNSSVersions.min = SSLVGreater(slapdNSSVersions.min, enabledNSSVersions.min); - enableSSL3 = PR_FALSE; - enableTLS1 = PR_TRUE; -@@ -939,19 +955,13 @@ restrict_SSLVersionRange(void) - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but nsSSL3 is on and nsTLS1 is off. " - "Respect the configured range.", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max)); -+ mymin, mymax); - enableSSL3 = PR_FALSE; - enableTLS1 = PR_TRUE; - } else if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { - slapd_SSL_warn("Too low configured range: min: %s, max: %s; " -- "Resetting the range to: min: %s, max: %s.", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max), -- getNSSVersion_str(SSL_LIBRARY_VERSION_TLS_1_0), -- getNSSVersion_str(SSL_LIBRARY_VERSION_TLS_1_0)); -- slapdNSSVersions.min = SSL_LIBRARY_VERSION_TLS_1_0; -- slapdNSSVersions.max = SSL_LIBRARY_VERSION_TLS_1_0; -+ "We strongly recommend to set sslVersionMax higher than %s.", -+ mymin, mymax, emax); - } else { - /* - * slapdNSSVersions.min <= SSL_LIBRARY_VERSION_TLS_1_0 && -@@ -960,8 +970,7 @@ restrict_SSLVersionRange(void) - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but nsSSL3 is on and nsTLS1 is off. " - "Respect the configured range.", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max)); -+ mymin, mymax); - enableTLS1 = PR_TRUE; - } - } -@@ -971,8 +980,7 @@ restrict_SSLVersionRange(void) - /* TLS1 is on, but TLS1 is not supported by NSS. */ - slapd_SSL_warn("Supported range: min: %s, max: %s; " - "Setting the version range based upon the supported range.", -- getNSSVersion_str(enabledNSSVersions.min), -- getNSSVersion_str(enabledNSSVersions.max)); -+ emin, emax); - slapdNSSVersions.max = enabledNSSVersions.max; - slapdNSSVersions.min = enabledNSSVersions.min; - enableSSL3 = PR_TRUE; -@@ -983,8 +991,7 @@ restrict_SSLVersionRange(void) - slapdNSSVersions.min = SSLVGreater(SSL_LIBRARY_VERSION_TLS_1_1, enabledNSSVersions.min); - slapd_SSL_warn("Default SSL Version settings; " - "Configuring the version range as min: %s, max: %s; ", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max)); -+ mymin, mymax); - } else { - /* - * slapdNSSVersions.min >= SSL_LIBRARY_VERSION_TLS_1_1 && -@@ -995,8 +1002,7 @@ restrict_SSLVersionRange(void) - } else { - slapd_SSL_warn("Supported range: min: %s, max: %s; " - "Respect the configured range.", -- getNSSVersion_str(enabledNSSVersions.min), -- getNSSVersion_str(enabledNSSVersions.max)); -+ emin, emax); - /* nsTLS1 is explicitly set to off. */ - if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { - enableTLS1 = PR_TRUE; -@@ -1040,13 +1046,15 @@ slapd_nss_init(int init_ssl, int config_available) - char *keydb_file_name = NULL; - char *secmoddb_file_name = NULL; - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ -+ char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH]; - /* Get the range of the supported SSL version */ - SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions); - -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin)); -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax)); - slapi_log_error(SLAPI_LOG_CONFIG, "SSL Initialization", - "supported range by NSS: min: %s, max: %s\n", -- getNSSVersion_str(enabledNSSVersions.min), -- getNSSVersion_str(enabledNSSVersions.max)); -+ emin, emax); - #endif - - /* set in slapd_bootstrap_config, -@@ -1351,34 +1359,37 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - { - char *vp, *endp; - int vnum; -+ char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH]; - - if (NULL == rval) { - return 1; - } -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin)); -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax)); - if (!strncasecmp(val, SSLSTR, SSLLEN)) { /* ssl# */ - vp = val + SSLLEN; - vnum = strtol(vp, &endp, 10); - if (2 == vnum) { - if (ismin) { - if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_2) { -- slapd_SSL_warn("Security Initialization: The value of sslVersionMin " -- "\"%s\" is lower than the supported version; " -- "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -- (*rval) = enabledNSSVersions.min; -+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin " -+ "\"%s\" is lower than the supported version; " -+ "the default value \"%s\" is used.", -+ val, emin); -+ (*rval) = enabledNSSVersions.min; - } else { -- (*rval) = SSL_LIBRARY_VERSION_2; -+ (*rval) = SSL_LIBRARY_VERSION_2; - } - } else { - if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_2) { - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " -- "\"%s\" is higher than the supported version; " -- "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.max)); -- (*rval) = enabledNSSVersions.max; -+ "\"%s\" is higher than the supported version; " -+ "the default value \"%s\" is used.", -+ val, emax); -+ (*rval) = enabledNSSVersions.max; - } else { -- (*rval) = SSL_LIBRARY_VERSION_2; -+ (*rval) = SSL_LIBRARY_VERSION_2; - } - } - } else if (3 == vnum) { -@@ -1387,7 +1398,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - (*rval) = SSL_LIBRARY_VERSION_3_0; -@@ -1398,7 +1409,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.max)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } else { - (*rval) = SSL_LIBRARY_VERSION_3_0; -@@ -1408,12 +1419,12 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (ismin) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is invalid; the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is invalid; the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.max)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } - } -@@ -1427,7 +1438,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - (*rval) = SSL_LIBRARY_VERSION_TLS_1_0; -@@ -1438,7 +1449,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.max)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } else { - (*rval) = SSL_LIBRARY_VERSION_TLS_1_0; -@@ -1450,7 +1461,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - (*rval) = SSL_LIBRARY_VERSION_TLS_1_1; -@@ -1461,7 +1472,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.max)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } else { - (*rval) = SSL_LIBRARY_VERSION_TLS_1_1; -@@ -1474,7 +1485,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - (*rval) = SSL_LIBRARY_VERSION_TLS_1_2; -@@ -1485,7 +1496,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.max)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } else { - (*rval) = SSL_LIBRARY_VERSION_TLS_1_2; -@@ -1497,13 +1508,13 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is out of the range of the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is out of the range of the supported version; " - "the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } - } -@@ -1511,12 +1522,12 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - if (ismin) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is invalid; the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emin); - (*rval) = enabledNSSVersions.min; - } else { - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is invalid; the default value \"%s\" is used.", -- val, getNSSVersion_str(enabledNSSVersions.min)); -+ val, emax); - (*rval) = enabledNSSVersions.max; - } - } -@@ -1549,6 +1560,8 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ - PRUint16 NSSVersionMin = enabledNSSVersions.min; - PRUint16 NSSVersionMax = enabledNSSVersions.max; -+ char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH]; -+ char newmax[VERSION_STR_LENGTH]; - #endif - char cipher_string[1024]; - int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER; -@@ -1909,12 +1922,13 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - } - slapi_ch_free_string( &val ); - if (NSSVersionMin > NSSVersionMax) { -+ (void) slapi_getSSLVersion_str(NSSVersionMin, mymin, sizeof(mymin)); -+ (void) slapi_getSSLVersion_str(NSSVersionMax, mymax, sizeof(mymax)); - slapd_SSL_warn("The min value of NSS version range \"%s\" is greater than the max value \"%s\".", -- getNSSVersion_str(NSSVersionMin), -- getNSSVersion_str(NSSVersionMax)); -+ mymin, mymax); -+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, newmax, sizeof(newmax)); - slapd_SSL_warn("Reset the max \"%s\" to supported max \"%s\".", -- getNSSVersion_str(NSSVersionMax), -- getNSSVersion_str(enabledNSSVersions.max)); -+ mymax, newmax); - NSSVersionMax = enabledNSSVersions.max; - } - #endif -@@ -1925,18 +1939,18 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - slapdNSSVersions.min = NSSVersionMin; - slapdNSSVersions.max = NSSVersionMax; - restrict_SSLVersionRange(); -+ (void) slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin)); -+ (void) slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax)); - slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization", - "Configured SSL version range: min: %s, max: %s\n", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max)); -+ mymin, mymax); - sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions); - if (sslStatus == SECSuccess) { - /* Set the restricted value to the cn=encryption entry */ - } else { - slapd_SSL_error("SSL Initialization 2: " - "Failed to set SSL range: min: %s, max: %s\n", -- getNSSVersion_str(slapdNSSVersions.min), -- getNSSVersion_str(slapdNSSVersions.max)); -+ mymin, mymax); - } - } else { - #endif --- -1.9.3 - diff --git a/SOURCES/0028-Ticket-47948-ldap_sasl_bind-fails-assertion-ld-NULL-.patch b/SOURCES/0028-Ticket-47948-ldap_sasl_bind-fails-assertion-ld-NULL-.patch deleted file mode 100644 index 71b1487..0000000 --- a/SOURCES/0028-Ticket-47948-ldap_sasl_bind-fails-assertion-ld-NULL-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From fa5ccbb5f5b730122b624b31c0225762492797d7 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 10 Nov 2014 13:12:48 -0800 -Subject: [PATCH 28/28] Ticket #47948 - ldap_sasl_bind fails assertion (ld != - NULL) if it is called from chainingdb_bind over SSL/startTLS - -Bug Description: In case startTLS, if ldap_start_tls_s called from -cb_get_connection failed and it returned non LDAP_SUCCESS return -code, the code was stored in the local variable just in the error -case, used only for error logging and abandoned in the scope; the -caller cb_get_connection returned LDAP_SUCCESS even if the connection -was not established. That confuses the caller of cb_get_connection -and let it call ldap_sasl_bind with NULL ld and it causes the assertion -failure. - -Fix Description: remove the local variable declaration in the scope. - -https://fedorahosted.org/389/ticket/47948 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit 47868d3e5278d425abe5e8325f2965de66c10cff) -(cherry picked from commit cb4f0cb2d120bc899bfb68dfe134ec3a26f3f334) ---- - ldap/servers/plugins/chainingdb/cb_conn_stateless.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/ldap/servers/plugins/chainingdb/cb_conn_stateless.c b/ldap/servers/plugins/chainingdb/cb_conn_stateless.c -index a85b392..4b323b1 100644 ---- a/ldap/servers/plugins/chainingdb/cb_conn_stateless.c -+++ b/ldap/servers/plugins/chainingdb/cb_conn_stateless.c -@@ -463,7 +463,6 @@ cb_get_connection(cb_conn_pool * pool, - ldap_controls_free(serverctrls); - } - } else if (secure == 2) { -- int rc; - /* the start_tls operation is usually performed in slapi_ldap_bind, but - since we are not binding we still need to start_tls */ - if (cb_debug_on()) { --- -1.9.3 - diff --git a/SOURCES/0028-Ticket-48224-redux-2-logconv.pl-should-handle-.tar.x.patch b/SOURCES/0028-Ticket-48224-redux-2-logconv.pl-should-handle-.tar.x.patch new file mode 100644 index 0000000..4ad70ad --- /dev/null +++ b/SOURCES/0028-Ticket-48224-redux-2-logconv.pl-should-handle-.tar.x.patch @@ -0,0 +1,40 @@ +From 53e51059c4e95fab6c3601952069191343fe92b3 Mon Sep 17 00:00:00 2001 +From: Rich Megginson +Date: Mon, 20 Jul 2015 10:31:46 -0600 +Subject: [PATCH 28/30] Ticket #48224 - redux 2 - logconv.pl should handle + *.tar.xz, *.txz, *.xz log files + +https://fedorahosted.org/389/ticket/48224 +Reviewed by: nhosoi (Thanks!) +Branch: 389-ds-base-1.3.4 +Fix Description: Use $? instead of $! to get pipe errors. +Platforms tested: Fedora 21, RHEL 7.2 candidate +Flag Day: no +Doc impact: no + +(cherry picked from commit 29043c5716a1bc8364689d518cb4e35722eaaf77) +(cherry picked from commit 0e31d818366e846f45c60b2c24bdb8026a82c048) +--- + ldap/admin/src/logconv.pl | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index 0038a03..3113f8a 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -437,9 +437,9 @@ sub doUncompress { + # so use the xz command directly + # NOTE: This doesn't work if the argument is a file handle e.g. from + # Archive::Tar +- $! = 0; # clear +- if (!open($TARFH, "xz -dc $_ |") or $!) { +- openFailed($!, $_); ++ $? = 0; # clear ++ if (!open($TARFH, "xz -dc $_ |") or $?) { ++ openFailed($?, $_); + return; + } + } else { +-- +1.9.3 + diff --git a/SOURCES/0029-Ticket-47953-Should-not-check-aci-syntax-when-deleti.patch b/SOURCES/0029-Ticket-47953-Should-not-check-aci-syntax-when-deleti.patch deleted file mode 100644 index d4c5521..0000000 --- a/SOURCES/0029-Ticket-47953-Should-not-check-aci-syntax-when-deleti.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d14caafc91ea6f417b1c602a91153764cc70f1d9 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 12 Nov 2014 10:15:46 -0500 -Subject: [PATCH 29/30] Ticket 47953 - Should not check aci syntax when - deleting an aci - -Bug Description: Trying to delete an aci that has an invalid sytenx, generates a - syntax error when trying to remove it. - -Fix Description: Do not check the syntax of an aci if it's being deleted. - -https://fedorahosted.org/389/ticket/47953 - -Reviewed by: ? - -(cherry picked from commit 3ce60db0a404b4663df6005b78027332d0e56f95) -(cherry picked from commit 6a435f1cce137990c9c55f3f571f97c09ad6d9f4) ---- - ldap/servers/plugins/acl/acl.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c -index fe863c8..5416330 100644 ---- a/ldap/servers/plugins/acl/acl.c -+++ b/ldap/servers/plugins/acl/acl.c -@@ -1553,11 +1553,12 @@ acl_check_mods( - - /* Are we adding/replacing a aci attribute - ** value. In that case, we need to make -- ** sure that the new value has thr right -+ ** sure that the new value has the right - ** syntax - */ -- if (strcmp(mod->mod_type, -- aci_attr_type) == 0) { -+ if (!SLAPI_IS_MOD_DELETE(mod->mod_op) && -+ strcmp(mod->mod_type, aci_attr_type) == 0) -+ { - if ( 0 != (rv = acl_verify_syntax(pb, e_sdn, - mod->mod_bvalues[i], errbuf))) { - aclutil_print_err(rv, e_sdn, --- -1.9.3 - diff --git a/SOURCES/0029-Ticket-48206-Crash-during-retro-changelog-trimming.patch b/SOURCES/0029-Ticket-48206-Crash-during-retro-changelog-trimming.patch new file mode 100644 index 0000000..a162506 --- /dev/null +++ b/SOURCES/0029-Ticket-48206-Crash-during-retro-changelog-trimming.patch @@ -0,0 +1,66 @@ +From 4c275349c72a01803b772717ee29e7ac6f9a903f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 20 Jul 2015 14:22:05 -0400 +Subject: [PATCH 29/30] Ticket 48206 - Crash during retro changelog trimming + +Bug Description: If the retro changelog entry is small, its possible that + during the trimming the reto changelog entry is not in the + cache after the trim, but its tries to blindly unlock it + from the cache, which leads to a crash. + +FIx Description: After we call the post op plugins and retrieve the entry + from the cache, double check that it was found. If it + is not found, do not unlock it. + +https://fedorahosted.org/389/ticket/48206 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 2a8a8c8ced5849dada34ab28d79e87dd3636e413) +(cherry picked from commit 6d439887b99da557e8d7bc0c611d9afa909fdce7) +--- + ldap/servers/slapd/back-ldbm/ldbm_delete.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c +index 59c1f76..f31d545 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c +@@ -1257,17 +1257,24 @@ ldbm_back_delete( Slapi_PBlock *pb ) + CACHE_RETURN(&inst->inst_cache, &e); + } + } +- if (cache_is_in_cache(&inst->inst_cache, e)) { +- ep_id = e->ep_id; /* Otherwise, e might have been freed. */ +- CACHE_REMOVE(&inst->inst_cache, e); +- } +- cache_unlock_entry(&inst->inst_cache, e); +- CACHE_RETURN(&inst->inst_cache, &e); +- /* +- * e is unlocked and no longer in cache. +- * It could be freed at any moment. ++ ++ /* ++ * e could have been replaced by cache_find_id(), recheck if it's NULL ++ * before trying to unlock it, etc. + */ +- e = NULL; ++ if (e) { ++ if (cache_is_in_cache(&inst->inst_cache, e)) { ++ ep_id = e->ep_id; /* Otherwise, e might have been freed. */ ++ CACHE_REMOVE(&inst->inst_cache, e); ++ } ++ cache_unlock_entry(&inst->inst_cache, e); ++ CACHE_RETURN(&inst->inst_cache, &e); ++ /* ++ * e is unlocked and no longer in cache. ++ * It could be freed at any moment. ++ */ ++ e = NULL; ++ } + + if (entryrdn_get_switch() && ep_id) { /* subtree-rename: on */ + /* since the op was successful, delete the tombstone dn from the dn cache */ +-- +1.9.3 + diff --git a/SOURCES/0030-Ticket-47928-Disable-SSL-v3-by-default.patch b/SOURCES/0030-Ticket-47928-Disable-SSL-v3-by-default.patch deleted file mode 100644 index f6c0215..0000000 --- a/SOURCES/0030-Ticket-47928-Disable-SSL-v3-by-default.patch +++ /dev/null @@ -1,275 +0,0 @@ -From c2bb6286434ea3bb87d454a8c9451dcc8f278297 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 13 Nov 2014 12:14:48 -0800 -Subject: [PATCH 30/30] Ticket #47928 - Disable SSL v3, by default. - -Description: -Changing the default SSL Version Min value from TLS 1.1 to TLS 1.0. -In dn: cn=encryption,cn=config, -0) Setting no SSL version attrs (using defaults); supported max is TLS1.2 - ==> - SSL Initialization - Configured SSL version range: min: TLS1.0, max: TLS1.2 - -1) Setting old/new SSL version attrs; no conflict; supported max is TLS1.2 - sslVersionMin: TLS1.0 - sslVersionMax: TLS1.3 - nsSSL3: off - nsTLS1: on - ==> - SSL Initialization - Configured SSL version range: min: TLS1.0, max: TLS1.2 -2) Setting new SSL version attrs; supported max is TLS1.2 - sslVersionMin: TLS1.0 - sslVersionMax: TLS1.3 - ==> - SSL Initialization - Configured SSL version range: min: TLS1.0, max: TLS1.2 - -3) Setting old/new SSL version attrs; conflict (new min is stricter); supported max is TLS1.2 - nsSSL3: on - sslVersionMin: TLS1.0 - ==> - SSL alert: Found unsecure configuration: nsSSL3: on; We strongly recommend to dis - able nsSSL3 in cn=encryption,cn=config. - SSL alert: Configured range: min: TLS1.0, max: TLS1.2; but both nsSSL3 and nsTLS1 - are on. Respect the supported range. - SSL Initialization - Configured SSL version range: min: TLS1.0, max: TLS1.2 - -4) Setting old/new SSL version attrs; conflict (old min is stricter); supported max is TLS1.2 - nsSSL3: off - sslVersionMin: SSL3 - sslVersionMax: SSL3 - ==> - SSL alert: nsTLS1 is on, but the version range is lower than "TLS1.0"; Configuring - the version range as default min: TLS1.0, max: TLS1.2. - SSL Initialization - Configured SSL version range: min: TLS1.0, max: TLS1.2 - -5) Setting old/new SSL version attrs; no conflict; setting SSL3 - nsSSL3: on - nsTLS1: off - sslVersionMin: SSL3 - sslVersionMax: SSL3 - ==> - SSL alert: Found unsecure configuration: nsSSL3: on; We strongly recommend to disable - nsSSL3 in cn=encryption,cn=config. - SSL alert: Too low configured range: min: SSL3, max: SSL3; We strongly recommend - to set sslVersionMin higher than TLS1.0. - SSL Initialization - Configured SSL version range: min: SSL3, max: SSL3 - -https://fedorahosted.org/389/ticket/47928 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit ad7885eae64a2085a89d516c1106b578142be502) -(cherry picked from commit 3e7321ba1641234651fbf1e8fc01bf9fbecbc696) ---- - ldap/servers/slapd/fedse.c | 2 +- - ldap/servers/slapd/ssl.c | 74 ++++++++++++++++++++++++++-------------------- - 2 files changed, 43 insertions(+), 33 deletions(-) - -diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c -index 87f45a1..d10fb3e 100644 ---- a/ldap/servers/slapd/fedse.c -+++ b/ldap/servers/slapd/fedse.c -@@ -110,7 +110,7 @@ static const char *internal_entries[] = - "cn:encryption\n" - "nsSSLSessionTimeout:0\n" - "nsSSLClientAuth:allowed\n" -- "sslVersionMin:tls1.1\n", -+ "sslVersionMin:TLS1.0\n", - - "dn:cn=monitor\n" - "objectclass:top\n" -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 5d6919a..6b51e0c 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -87,13 +87,23 @@ - /* TLS1.1 is defined in RFC4346. */ - #define NSS_TLS11 1 - #else --/* -- * TLS1.0 is defined in RFC2246. -- * Close to SSL 3.0. -- */ - #define NSS_TLS10 1 - #endif - -+/****************************************************************************** -+ * Default SSL Version Rule -+ * Old SSL version attributes: -+ * nsSSL3: off -- nsSSL3 == SSL_LIBRARY_VERSION_3_0 -+ * nsTLS1: on -- nsTLS1 == SSL_LIBRARY_VERSION_TLS_1_0 and greater -+ * Note: TLS1.0 is defined in RFC2246, which is close to SSL 3.0. -+ * New SSL version attributes: -+ * sslVersionMin: TLS1.0 -+ * sslVersionMax: max ssl version supported by NSS -+ ******************************************************************************/ -+ -+#define DEFVERSION "TLS1.0" -+#define CURRENT_DEFAULT_SSL_VERSION SSL_LIBRARY_VERSION_TLS_1_0 -+ - extern char* slapd_SSL3ciphers; - extern symbol_t supported_ciphers[]; - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ -@@ -253,12 +263,12 @@ static lookup_cipher _lookup_cipher[] = { - PRBool enableSSL2 = PR_FALSE; - /* - * nsSSL3: on -- disable SSLv3 by default. -- * Corresonding to SSL_LIBRARY_VERSION_3_0 and SSL_LIBRARY_VERSION_TLS_1_0 -+ * Corresonding to SSL_LIBRARY_VERSION_3_0 - */ - PRBool enableSSL3 = PR_FALSE; - /* - * nsTLS1: on -- enable TLS1 by default. -- * Corresonding to SSL_LIBRARY_VERSION_TLS_1_1 and greater. -+ * Corresonding to SSL_LIBRARY_VERSION_TLS_1_0 and greater. - */ - PRBool enableTLS1 = PR_TRUE; - -@@ -927,14 +937,14 @@ restrict_SSLVersionRange(void) - slapd_SSL_warn("Found unsecure configuration: nsSSL3: on; " - "We strongly recommend to disable nsSSL3 in %s.", configDN); - if (enableTLS1) { -- if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ if (slapdNSSVersions.min >= CURRENT_DEFAULT_SSL_VERSION) { - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but both nsSSL3 and nsTLS1 are on. " - "Respect the supported range.", - mymin, mymax); - enableSSL3 = PR_FALSE; - } -- if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ if (slapdNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) { - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but both nsSSL3 and nsTLS1 are on. " - "Resetting the max to the supported max SSL version: %s.", -@@ -943,7 +953,7 @@ restrict_SSLVersionRange(void) - } - } else { - /* nsTLS1 is explicitly set to off. */ -- if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ if (enabledNSSVersions.min >= CURRENT_DEFAULT_SSL_VERSION) { - slapd_SSL_warn("Supported range: min: %s, max: %s; " - "but nsSSL3 is on and nsTLS1 is off. " - "Respect the supported range.", -@@ -951,20 +961,20 @@ restrict_SSLVersionRange(void) - slapdNSSVersions.min = SSLVGreater(slapdNSSVersions.min, enabledNSSVersions.min); - enableSSL3 = PR_FALSE; - enableTLS1 = PR_TRUE; -- } else if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ } else if (slapdNSSVersions.min >= CURRENT_DEFAULT_SSL_VERSION) { - slapd_SSL_warn("Configured range: min: %s, max: %s; " - "but nsSSL3 is on and nsTLS1 is off. " - "Respect the configured range.", - mymin, mymax); - enableSSL3 = PR_FALSE; - enableTLS1 = PR_TRUE; -- } else if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ } else if (slapdNSSVersions.min < CURRENT_DEFAULT_SSL_VERSION) { - slapd_SSL_warn("Too low configured range: min: %s, max: %s; " -- "We strongly recommend to set sslVersionMax higher than %s.", -- mymin, mymax, emax); -+ "We strongly recommend to set sslVersionMin higher than %s.", -+ mymin, mymax, DEFVERSION); - } else { - /* -- * slapdNSSVersions.min <= SSL_LIBRARY_VERSION_TLS_1_0 && -+ * slapdNSSVersions.min < SSL_LIBRARY_VERSION_TLS_1_0 && - * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_1 - */ - slapd_SSL_warn("Configured range: min: %s, max: %s; " -@@ -976,7 +986,7 @@ restrict_SSLVersionRange(void) - } - } else { - if (enableTLS1) { -- if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ if (enabledNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) { - /* TLS1 is on, but TLS1 is not supported by NSS. */ - slapd_SSL_warn("Supported range: min: %s, max: %s; " - "Setting the version range based upon the supported range.", -@@ -985,17 +995,17 @@ restrict_SSLVersionRange(void) - slapdNSSVersions.min = enabledNSSVersions.min; - enableSSL3 = PR_TRUE; - enableTLS1 = PR_FALSE; -- } else if ((slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) || -- (slapdNSSVersions.min < SSL_LIBRARY_VERSION_TLS_1_1)) { -+ } else if ((slapdNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) || -+ (slapdNSSVersions.min < CURRENT_DEFAULT_SSL_VERSION)) { - slapdNSSVersions.max = enabledNSSVersions.max; -- slapdNSSVersions.min = SSLVGreater(SSL_LIBRARY_VERSION_TLS_1_1, enabledNSSVersions.min); -- slapd_SSL_warn("Default SSL Version settings; " -- "Configuring the version range as min: %s, max: %s; ", -- mymin, mymax); -+ slapdNSSVersions.min = SSLVGreater(CURRENT_DEFAULT_SSL_VERSION, enabledNSSVersions.min); -+ slapd_SSL_warn("nsTLS1 is on, but the version range is lower than \"%s\"; " -+ "Configuring the version range as default min: %s, max: %s.", -+ DEFVERSION, DEFVERSION, emax); - } else { - /* -- * slapdNSSVersions.min >= SSL_LIBRARY_VERSION_TLS_1_1 && -- * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_1 -+ * slapdNSSVersions.min >= SSL_LIBRARY_VERSION_TLS_1_0 && -+ * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_0 - */ - ; - } -@@ -1004,14 +1014,14 @@ restrict_SSLVersionRange(void) - "Respect the configured range.", - emin, emax); - /* nsTLS1 is explicitly set to off. */ -- if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ if (slapdNSSVersions.min >= CURRENT_DEFAULT_SSL_VERSION) { - enableTLS1 = PR_TRUE; -- } else if (slapdNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) { -+ } else if (slapdNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) { - enableSSL3 = PR_TRUE; - } else { - /* -- * slapdNSSVersions.min <= SSL_LIBRARY_VERSION_TLS_1_0 && -- * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_1 -+ * slapdNSSVersions.min < SSL_LIBRARY_VERSION_TLS_1_0 && -+ * slapdNSSVersions.max >= SSL_LIBRARY_VERSION_TLS_1_0 - */ - enableSSL3 = PR_TRUE; - enableTLS1 = PR_TRUE; -@@ -1434,17 +1444,17 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - sscanf(vp, "%4f", &tlsv); - if (tlsv < 1.1) { /* TLS1.0 */ - if (ismin) { -- if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) { -+ if (enabledNSSVersions.min > CURRENT_DEFAULT_SSL_VERSION) { - slapd_SSL_warn("Security Initialization: The value of sslVersionMin " - "\"%s\" is lower than the supported version; " - "the default value \"%s\" is used.", - val, emin); - (*rval) = enabledNSSVersions.min; - } else { -- (*rval) = SSL_LIBRARY_VERSION_TLS_1_0; -+ (*rval) = CURRENT_DEFAULT_SSL_VERSION; - } - } else { -- if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) { -+ if (enabledNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) { - /* never happens */ - slapd_SSL_warn("Security Initialization: The value of sslVersionMax " - "\"%s\" is higher than the supported version; " -@@ -1452,7 +1462,7 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin) - val, emax); - (*rval) = enabledNSSVersions.max; - } else { -- (*rval) = SSL_LIBRARY_VERSION_TLS_1_0; -+ (*rval) = CURRENT_DEFAULT_SSL_VERSION; - } - } - } else if (tlsv < 1.2) { /* TLS1.1 */ -@@ -1906,7 +1916,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - } else { - enableTLS1 = slapi_entry_attr_get_bool( e, "nsTLS1" ); - } -- } else if (enabledNSSVersions.max > SSL_LIBRARY_VERSION_TLS_1_0) { -+ } else if (enabledNSSVersions.max >= CURRENT_DEFAULT_SSL_VERSION) { - enableTLS1 = PR_TRUE; /* If available, enable TLS1 */ - } - slapi_ch_free_string( &val ); --- -1.9.3 - diff --git a/SOURCES/0030-Ticket-48010-winsync-range-retrieval-gets-only-5000-.patch b/SOURCES/0030-Ticket-48010-winsync-range-retrieval-gets-only-5000-.patch new file mode 100644 index 0000000..b6a5197 --- /dev/null +++ b/SOURCES/0030-Ticket-48010-winsync-range-retrieval-gets-only-5000-.patch @@ -0,0 +1,222 @@ +From bc26583d161168ce664d160592a30abbd98b9a1f Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 22 Jul 2015 09:41:46 -0700 +Subject: [PATCH 30/30] Ticket #48010 - winsync range retrieval gets only 5000 + values upon initialization + +Description: Search with DirSync control does not support range subtype. +On WS2012, it returns all the multi-valued attribute values regardless +of MaxValRange, but on WS2008, it cuts at the physical limit 5000. +This patch does not rely on the entry returned by the DirySync search. + +Also, since DirSync search does not support the range subtype, removing +the range related code from the DirSync search. + +Researched and tested by vashirov@redhat.com (Thank you, Viktor!!) +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +https://fedorahosted.org/389/ticket/48010 +(cherry picked from commit c6b211f8ea4970623f8ac1b365d040756d46bf3c) +(cherry picked from commit d9af22eb940353c0692b6d73cc0a2d6998311498) +--- + .../plugins/replication/windows_connection.c | 21 ++----- + ldap/servers/plugins/replication/windows_private.c | 70 ---------------------- + .../plugins/replication/windows_protocol_util.c | 21 +++++-- + ldap/servers/plugins/replication/windowsrepl.h | 5 -- + 4 files changed, 21 insertions(+), 96 deletions(-) + +diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c +index 5db43a5..a06a07e 100644 +--- a/ldap/servers/plugins/replication/windows_connection.c ++++ b/ldap/servers/plugins/replication/windows_connection.c +@@ -821,7 +821,6 @@ send_dirsync_search(Repl_Connection *conn) + const char *old_dn = slapi_sdn_get_ndn( windows_private_get_windows_subtree(conn->agmt) ); + /* LDAP_SERVER_DIRSYNC_OID requires the search base Naming Context */ + char *dn = slapi_ch_strdup(strstr(old_dn, "dc=")); +- char **exattrs = NULL; + + if (conn->supports_dirsync == 0) + { +@@ -847,10 +846,6 @@ send_dirsync_search(Repl_Connection *conn) + + winsync_plugin_call_dirsync_search_params_cb(conn->agmt, old_dn, &dn, &scope, &filter, + &attrs, &server_controls); +- exattrs = windows_private_get_range_attrs(conn->agmt); +- charray_merge(&attrs, exattrs, 0 /* pass in */); +- slapi_ch_free((void **)&exattrs); /* strings are passed in */ +- + LDAPDebug( LDAP_DEBUG_REPL, "Sending dirsync search request\n", 0, 0, 0 ); + + rc = ldap_search_ext( conn->ld, dn, scope, filter, attrs, PR_FALSE, server_controls, +@@ -1010,20 +1005,14 @@ Slapi_Entry * windows_conn_get_search_result(Repl_Connection *conn) + { + if (( dn = ldap_get_dn( conn->ld, res )) != NULL ) + { +- char **exattrs = NULL; + slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"received entry from dirsync: %s\n", dn); + lm = ldap_first_entry( conn->ld, res ); +- e = windows_private_get_curr_entry(conn->agmt); /* if range search, e != NULL */ +- e = windows_LDAPMessage2Entry(e, conn, lm, 0, &exattrs); ++ /* ++ * we don't have to retrieve all the members here. ++ * here, we have to make sure to get the entry once. ++ */ ++ e = windows_LDAPMessage2Entry(e, conn, lm, 0, NULL); + ldap_memfree(dn); +- if (exattrs) { +- /* some attribute returned ";range=low-high" */ +- windows_private_set_curr_entry(conn->agmt, e); +- windows_private_set_range_attrs(conn->agmt, exattrs); +- } else { +- windows_private_set_curr_entry(conn->agmt, NULL); +- windows_private_set_range_attrs(conn->agmt, NULL); +- } + } + } + break; +diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c +index f5cb44e..c118236 100644 +--- a/ldap/servers/plugins/replication/windows_private.c ++++ b/ldap/servers/plugins/replication/windows_private.c +@@ -1570,76 +1570,6 @@ windows_private_set_move_action(const Repl_Agmt *ra, int value) + LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_move_action\n" ); + } + +-/* Get entry being retrieved; used for the range retrieval */ +-Slapi_Entry * +-windows_private_get_curr_entry(const Repl_Agmt *ra) +-{ +- Dirsync_Private *dp; +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_curr_entry\n" ); +- +- PR_ASSERT(ra); +- +- dp = (Dirsync_Private *) agmt_get_priv(ra); +- PR_ASSERT (dp); +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_curr_entry\n" ); +- +- return dp->curr_entry; +-} +- +-/* Set entry being retrieved; used for the range retrieval */ +-void +-windows_private_set_curr_entry(const Repl_Agmt *ra, Slapi_Entry *e) +-{ +- Dirsync_Private *dp; +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_curr_entry\n" ); +- +- PR_ASSERT(ra); +- +- dp = (Dirsync_Private *) agmt_get_priv(ra); +- PR_ASSERT (dp); +- dp->curr_entry = e; +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_curr_entry\n" ); +-} +- +-/* Get next range retrieval attributes */ +-char ** +-windows_private_get_range_attrs(const Repl_Agmt *ra) +-{ +- Dirsync_Private *dp; +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_range_attrs\n" ); +- +- PR_ASSERT(ra); +- +- dp = (Dirsync_Private *) agmt_get_priv(ra); +- PR_ASSERT (dp); +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_range_attrs\n" ); +- +- return dp->range_attrs; +-} +- +-/* Set next range retrieval attributes */ +-void +-windows_private_set_range_attrs(const Repl_Agmt *ra, char **attrs) +-{ +- Dirsync_Private *dp; +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_move_action\n" ); +- +- PR_ASSERT(ra); +- +- dp = (Dirsync_Private *) agmt_get_priv(ra); +- PR_ASSERT (dp); +- dp->range_attrs = attrs; +- +- LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_move_action\n" ); +-} +- + static PRCallOnceType winsync_callOnce = {0,0}; + + struct winsync_plugin { +diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c +index 6bf20b7..4cfa20d 100644 +--- a/ldap/servers/plugins/replication/windows_protocol_util.c ++++ b/ldap/servers/plugins/replication/windows_protocol_util.c +@@ -5847,6 +5847,9 @@ windows_process_dirsync_entry(Private_Repl_Protocol *prp,Slapi_Entry *e, int is_ + /* Is this entry one we should be interested in ? */ + if (is_subject_of_agreement_remote(e,prp->agmt)) + { ++ ConnResult cres = 0; ++ const char *searchbase = slapi_entry_get_dn_const(e); ++ char *filter = "(objectclass=*)"; + retry: + /* First make its local DN */ + rc = map_entry_dn_inbound(e, &local_sdn, prp->agmt); +@@ -5902,7 +5905,19 @@ retry: + /* If it doesn't exist, try to make it */ + if (add_local_entry_allowed(prp,e)) + { +- windows_create_local_entry(prp,e,local_sdn); ++ found_entry = NULL; ++ /* ++ * BZ 1172037: Search with DirSync Control does not return the range subtype. ++ * Re-search the entry to get all the attribute values over hard limit MaxValRange ++ * on 2008R2. Note: 2012R2 does not have the hard limit. ++ * If we stop supporting 2008R2, this windows_search_entry_ext call can be removed. ++ */ ++ cres = windows_search_entry_ext(prp->conn, (char*)searchbase, ++ filter, &found_entry, NULL, LDAP_SCOPE_BASE); ++ if (found_entry) { ++ e = found_entry; ++ } ++ windows_create_local_entry(prp, e, local_sdn); + } else + { + slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"%s: windows_process_dirsync_entry: not allowed to add entry %s.\n",agmt_get_long_name(prp->agmt) +@@ -5918,10 +5933,6 @@ retry: + * We search Windows with the dn and retry using the found + * entry. + */ +- ConnResult cres = 0; +- const char *searchbase = slapi_entry_get_dn_const(e); +- char *filter = "(objectclass=*)"; +- + retried = 1; + cres = windows_search_entry_ext(prp->conn, (char*)searchbase, + filter, &found_entry, NULL, LDAP_SCOPE_BASE); +diff --git a/ldap/servers/plugins/replication/windowsrepl.h b/ldap/servers/plugins/replication/windowsrepl.h +index fd80212..66f4804 100644 +--- a/ldap/servers/plugins/replication/windowsrepl.h ++++ b/ldap/servers/plugins/replication/windowsrepl.h +@@ -66,11 +66,6 @@ void windows_private_set_one_way(const Repl_Agmt *ra, PRBool value); + int windows_private_get_move_action(const Repl_Agmt *ra); + void windows_private_set_move_action(const Repl_Agmt *ra, int value); + +-Slapi_Entry *windows_private_get_curr_entry(const Repl_Agmt *ra); +-void windows_private_set_curr_entry(const Repl_Agmt *ra, Slapi_Entry *e); +-char **windows_private_get_range_attrs(const Repl_Agmt *ra); +-void windows_private_set_range_attrs(const Repl_Agmt *ra, char **attrs); +- + void windows_private_set_directory_userfilter(const Repl_Agmt *ra, char *filter); + void windows_private_set_windows_userfilter(const Repl_Agmt *ra, char *filter); + const char* windows_private_get_directory_userfilter(const Repl_Agmt *ra); +-- +1.9.3 + diff --git a/SOURCES/0031-Fix-for-CVE-2014-8112.patch b/SOURCES/0031-Fix-for-CVE-2014-8112.patch deleted file mode 100644 index ef94acf..0000000 --- a/SOURCES/0031-Fix-for-CVE-2014-8112.patch +++ /dev/null @@ -1,116 +0,0 @@ -From e5de803f4ab1b097c637c269fcc8b567e664c00d Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Fri, 28 Nov 2014 14:23:06 +0100 -Subject: [PATCH 31/53] Fix for CVE-2014-8112 - - If the unhashed pw switch is set to off this should only - prevent the generation of the unhashed#user#password - attribute. - But encoding of pw values and detiecetion which values have - to be deleted needs to stay intact. - So the check if the switch is set has to be placed close to - the generation of the attribute in different 'if' branches - -Reviewed by Noriko, thanks ---- - ldap/servers/plugins/retrocl/retrocl_po.c | 6 +++++ - ldap/servers/slapd/modify.c | 39 +++++++++++++++++-------------- - 2 files changed, 28 insertions(+), 17 deletions(-) - -diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c -index 4b2cdda..3f8af81 100644 ---- a/ldap/servers/plugins/retrocl/retrocl_po.c -+++ b/ldap/servers/plugins/retrocl/retrocl_po.c -@@ -101,6 +101,12 @@ static lenstr *make_changes_string(LDAPMod **ldm, const char **includeattrs) - continue; - } - } -+ if (SLAPD_UNHASHED_PW_NOLOG == slapi_config_get_unhashed_pw_switch()) { -+ if (0 == strcasecmp(ldm[ i ]->mod_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD)) { -+ /* If nsslapd-unhashed-pw-switch == nolog, skip writing it to cl. */ -+ continue; -+ } -+ } - switch ( ldm[ i ]->mod_op & ~LDAP_MOD_BVALUES ) { - case LDAP_MOD_ADD: - addlenstr( l, "add: " ); -diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c -index fb0fdde..de44fd3 100644 ---- a/ldap/servers/slapd/modify.c -+++ b/ldap/servers/slapd/modify.c -@@ -836,8 +836,7 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw) - * before calling the preop plugins - */ - -- if (pw_change && !repl_op && -- (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch())) { -+ if (pw_change && !repl_op ) { - Slapi_Value **va = NULL; - - unhashed_pw_attr = slapi_attr_syntax_normalize(PSEUDO_ATTR_UNHASHEDUSERPASSWORD); -@@ -907,13 +906,15 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw) - * Finally, delete the unhashed userpassword - * (this will update the password entry extension) - */ -- bval.bv_val = password; -- bval.bv_len = strlen(password); -- bv[0] = &bval; -- bv[1] = NULL; -- valuearray_init_bervalarray(bv, &va); -- slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va); -- valuearray_free(&va); -+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) { -+ bval.bv_val = password; -+ bval.bv_len = strlen(password); -+ bv[0] = &bval; -+ bv[1] = NULL; -+ valuearray_init_bervalarray(bv, &va); -+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va); -+ valuearray_free(&va); -+ } - } else { - /* - * Password is encoded, try and find a matching unhashed_password to delete -@@ -945,19 +946,23 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw) - if(strcmp(unhashed_pwsp->pws_name, "CLEAR") == 0){ - if((*(pwsp->pws_cmp))((char *)unhashed_pwd , valpwd) == 0 ){ - /* match, add the delete mod for this particular unhashed userpassword */ -- valuearray_init_bervalarray(bv, &va); -- slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va); -- valuearray_free(&va); -- free_pw_scheme( unhashed_pwsp ); -+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) { -+ valuearray_init_bervalarray(bv, &va); -+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va); -+ valuearray_free(&va); -+ free_pw_scheme( unhashed_pwsp ); -+ } - break; - } - } else { - /* - * We have a hashed unhashed_userpassword! We must delete it. - */ -- valuearray_init_bervalarray(bv, &va); -- slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va); -- valuearray_free(&va); -+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) { -+ valuearray_init_bervalarray(bv, &va); -+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va); -+ valuearray_free(&va); -+ } - } - free_pw_scheme( unhashed_pwsp ); - } -@@ -972,7 +977,7 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw) - if (remove_unhashed_pw && !slapi_entry_attr_find(e, unhashed_pw_attr, &a)){ - slapi_mods_add_mod_values(&smods, pw_mod->mod_op,unhashed_pw_attr, va); - } -- } else { -+ } else if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) { - /* add pseudo password attribute */ - valuearray_init_bervalarray_unhashed_only(pw_mod->mod_bvalues, &va); - if(va && va[0]){ --- -1.9.3 - diff --git a/SOURCES/0031-Ticket-48232-winsync-lastlogon-attribute-not-syncing.patch b/SOURCES/0031-Ticket-48232-winsync-lastlogon-attribute-not-syncing.patch new file mode 100644 index 0000000..1464ae9 --- /dev/null +++ b/SOURCES/0031-Ticket-48232-winsync-lastlogon-attribute-not-syncing.patch @@ -0,0 +1,47 @@ +From bf8da26adf08db15ae2cbaeadb40f62af6c52037 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 29 Jul 2015 11:26:22 -0700 +Subject: [PATCH 31/39] Ticket #48232 - winsync lastlogon attribute not syncing + between DS and AD. + +Bug Description: +From Microsoft forum: + The DirSync control taps into the replication stream to get the necessary + changes. Since lastLogon is not replicated, it isn't available via the + DirSync control. +Additional notes: + The lastLogon attribute is not replicated. + In contrast the lastLogontimeStamp attribute is replicated. + +Fix Description: + Instead of lastLogon|lastLogoff, sync lastLogonTimestamp|lastLogoffTimestamp + which are the target of DirSync, to ntUserLastLogon|ntUserLastLogoff. + +https://fedorahosted.org/389/ticket/48232 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit 0db29788e6c1b17f944fcafa368b66580e1e90d5) +(cherry picked from commit b81adb0bc8ad97fec50fba30454e94858476bad5) +--- + ldap/servers/plugins/replication/windows_protocol_util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c +index 4cfa20d..5c12af7 100644 +--- a/ldap/servers/plugins/replication/windows_protocol_util.c ++++ b/ldap/servers/plugins/replication/windows_protocol_util.c +@@ -194,8 +194,8 @@ static windows_attribute_map user_attribute_map[] = + { + { "homeDirectory", "ntUserHomeDir", bidirectional, always, normal}, + { "scriptPath", "ntUserScriptPath", bidirectional, always, normal}, +- { "lastLogon", "ntUserLastLogon", fromwindowsonly, always, normal}, +- { "lastLogoff", "ntUserLastLogoff", fromwindowsonly, always, normal}, ++ { "lastLogonTimestamp", "ntUserLastLogon", fromwindowsonly, always, normal}, ++ { "lastLogoffTimestamp", "ntUserLastLogoff", fromwindowsonly, always, normal}, + { "accountExpires", "ntUserAcctExpires", bidirectional, always, normal}, + { "codePage", "ntUserCodePage", bidirectional, always, normal}, + { "logonHours", "ntUserLogonHours", bidirectional, always, normal}, +-- +1.9.3 + diff --git a/SOURCES/0032-Ticket-47942-DS-hangs-during-online-total-update.patch b/SOURCES/0032-Ticket-47942-DS-hangs-during-online-total-update.patch deleted file mode 100644 index aa5cd5c..0000000 --- a/SOURCES/0032-Ticket-47942-DS-hangs-during-online-total-update.patch +++ /dev/null @@ -1,784 +0,0 @@ -From 5b0283a5a5b12c9b2ccee049ddc611decaa07a09 Mon Sep 17 00:00:00 2001 -From: "Thierry bordaz (tbordaz)" -Date: Mon, 15 Dec 2014 15:12:35 +0100 -Subject: [PATCH 32/53] Ticket 47942: DS hangs during online total update - -Bug Description: - During incremental or total update of a consumer the replica agreement thread may hang. - For total update: - The replica agreement thread that send the entries flowed the consumer that is not - able to process fast enough the entries. So the TCP connection get full and - the RA sender sleep on the connection to be able to write the next entries. - - Sleeping on the poll or write the RA.sender holds the connection lock. - - It prevents the replica agreement result thread to read the results from the - network. So the consumer is also halted because is can no longer send the results. - - For incrementatl update: - During incremental update, all updates are sent by the RA.sender. - If many updates need to be send, the supplier may overflow the consumer - that is very late. This flow of updates can fill the TCP connection - so that the RA.sender hang when writing the next update. - On the hang, it holds the connection lock preventing the RA.reader - to receive the acks. And so the consumer can also hang trying to send the - acks. - -Fix Description: - For total update there are two parts of the fix: - - To prevent the RA.sender to sleep too long on the poll, the fix (conn_is_available) - splits the RA.timeout into 1s period. - If unable to write for 1s, it releases the connection for a short period of time 100ms. - - To prevent the RA.sender to sleep on the write, the fix (check_flow_control_tot_init) - checks how late is the consumer and if it is too late, it pauses (releasing the connection - during that time). This second part of the fix is configurable and it may need to be - tune according to the observed failures. - - For incremental update: - The fix is to implement a flow control on the RA.sender. - After each sent update, if the window (update.sent - update.acked) cross the limit - The RA.sender pause during a configured delay. - When the RA.sender pause it does not hold the connection lock - - Tuning can be done with nsds5ReplicaFlowControlWindow (how late is the consumer in terms of - number of entries/updates acknowledged) and nsds5ReplicaFlowControlPause (how long the RA.sender will - pause if the consumer is too late) - - Logging: - For total update, the first time the flow control pauses, it logs a message (FATAL level). - If flow control happened, then at the end of the total update, it also logs the number - of flow control pauses (FATAL level). - - For incremental update, if flow control happened it logs the number of pause (REPL level). - -https://fedorahosted.org/389/ticket/47942 - -Reviewed by: Mark Reynolds, Rich Megginson, Andrey Ivanov, Noriko Hosoi (many many thanks to all of you !) - -Platforms tested: RHEL 7.0, Centos - -Flag Day: no - -Doc impact: no ---- - ldap/schema/01core389.ldif | 4 +- - ldap/servers/plugins/replication/repl5.h | 10 ++ - ldap/servers/plugins/replication/repl5_agmt.c | 160 ++++++++++++++++++++ - ldap/servers/plugins/replication/repl5_agmtlist.c | 26 ++++ - .../servers/plugins/replication/repl5_connection.c | 163 ++++++++++++++++++++- - .../plugins/replication/repl5_inc_protocol.c | 32 +++- - .../plugins/replication/repl5_prot_private.h | 2 + - .../plugins/replication/repl5_tot_protocol.c | 53 ++++++- - ldap/servers/plugins/replication/repl_globals.c | 2 + - 9 files changed, 446 insertions(+), 6 deletions(-) - -diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif -index c7aec70..c59d762 100644 ---- a/ldap/schema/01core389.ldif -+++ b/ldap/schema/01core389.ldif -@@ -302,6 +302,8 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2306 NAME 'nsslapd-return-default-opattr - attributeTypes: ( 2.16.840.1.113730.3.1.2307 NAME 'nsslapd-allow-hashed-passwords' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - attributeTypes: ( 2.16.840.1.113730.3.1.2308 NAME 'nstombstonecsn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - attributeTypes: ( 2.16.840.1.113730.3.1.2309 NAME 'nsds5ReplicaPreciseTombstonePurging' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) -+attributeTypes: ( 2.16.840.1.113730.3.1.2310 NAME 'nsds5ReplicaFlowControlWindow' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) -+attributeTypes: ( 2.16.840.1.113730.3.1.2311 NAME 'nsds5ReplicaFlowControlPause' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - # - # objectclasses - # -@@ -313,7 +315,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape d - objectClasses: ( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top MAY ( nstombstonecsn $ nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' ) --objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime $ nsds5ReplicaProtocolTimeout ) X-ORIGIN 'Netscape Directory Server' ) -+objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaFlowControlWindow $ nsds5ReplicaFlowControlPause ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) MAY ( nsSaslMapPriority ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' ) -diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h -index 86c77ce..e2b6209 100644 ---- a/ldap/servers/plugins/replication/repl5.h -+++ b/ldap/servers/plugins/replication/repl5.h -@@ -170,6 +170,8 @@ extern const char *type_nsds5ReplicaBusyWaitTime; - extern const char *type_nsds5ReplicaSessionPauseTime; - extern const char *type_nsds5ReplicaEnabled; - extern const char *type_nsds5ReplicaStripAttrs; -+extern const char *type_nsds5ReplicaFlowControlWindow; -+extern const char *type_nsds5ReplicaFlowControlPause; - extern const char *type_replicaProtocolTimeout; - extern const char *type_replicaBackoffMin; - extern const char *type_replicaBackoffMax; -@@ -332,6 +334,8 @@ int agmt_get_auto_initialize(const Repl_Agmt *ra); - long agmt_get_timeout(const Repl_Agmt *ra); - long agmt_get_busywaittime(const Repl_Agmt *ra); - long agmt_get_pausetime(const Repl_Agmt *ra); -+long agmt_get_flowcontrolwindow(const Repl_Agmt *ra); -+long agmt_get_flowcontrolpause(const Repl_Agmt *ra); - int agmt_start(Repl_Agmt *ra); - int windows_agmt_start(Repl_Agmt *ra); - int agmt_stop(Repl_Agmt *ra); -@@ -352,6 +356,8 @@ int agmt_replarea_matches(const Repl_Agmt *ra, const Slapi_DN *name); - int agmt_schedule_in_window_now(const Repl_Agmt *ra); - int agmt_set_schedule_from_entry( Repl_Agmt *ra, const Slapi_Entry *e ); - int agmt_set_timeout_from_entry( Repl_Agmt *ra, const Slapi_Entry *e ); -+int agmt_set_flowcontrolwindow_from_entry(Repl_Agmt *ra, const Slapi_Entry *e); -+int agmt_set_flowcontrolpause_from_entry(Repl_Agmt *ra, const Slapi_Entry *e); - int agmt_set_busywaittime_from_entry( Repl_Agmt *ra, const Slapi_Entry *e ); - int agmt_set_pausetime_from_entry( Repl_Agmt *ra, const Slapi_Entry *e ); - int agmt_set_credentials_from_entry( Repl_Agmt *ra, const Slapi_Entry *e ); -@@ -490,6 +496,10 @@ void conn_lock(Repl_Connection *conn); - void conn_unlock(Repl_Connection *conn); - void conn_delete_internal_ext(Repl_Connection *conn); - const char* conn_get_bindmethod(Repl_Connection *conn); -+void conn_set_tot_update_cb(Repl_Connection *conn, void *cb_data); -+void conn_set_tot_update_cb_nolock(Repl_Connection *conn, void *cb_data); -+void conn_get_tot_update_cb(Repl_Connection *conn, void **cb_data); -+void conn_get_tot_update_cb_nolock(Repl_Connection *conn, void **cb_data); - - /* In repl5_protocol.c */ - typedef struct repl_protocol Repl_Protocol; -diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c -index 7c5c37c..91be757 100644 ---- a/ldap/servers/plugins/replication/repl5_agmt.c -+++ b/ldap/servers/plugins/replication/repl5_agmt.c -@@ -87,6 +87,8 @@ - #include "slapi-plugin.h" - - #define DEFAULT_TIMEOUT 600 /* (seconds) default outbound LDAP connection */ -+#define DEFAULT_FLOWCONTROL_WINDOW 1000 /* #entries sent without acknowledgment */ -+#define DEFAULT_FLOWCONTROL_PAUSE 2000 /* msec of pause when #entries sent witout acknowledgment */ - #define STATUS_LEN 1024 - - struct changecounter { -@@ -145,6 +147,12 @@ typedef struct repl5agmt { - int agreement_type; - Slapi_Counter *protocol_timeout; - char *maxcsn; /* agmt max csn */ -+ long flowControlWindow; /* This is the maximum number of entries -+ * sent without acknowledgment -+ */ -+ long flowControlPause; /* When nb of not acknowledged entries overpass totalUpdateWindow -+ * This is the duration (in msec) that the RA will pause before sending the next entry -+ */ - Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */ - } repl5agmt; - -@@ -345,6 +353,28 @@ agmt_new_from_entry(Slapi_Entry *e) - } - } - -+ /* flow control update window. */ -+ ra->flowControlWindow = DEFAULT_FLOWCONTROL_WINDOW; -+ if (slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlWindow, &sattr) == 0) -+ { -+ Slapi_Value *sval; -+ if (slapi_attr_first_value(sattr, &sval) == 0) -+ { -+ ra->flowControlWindow = slapi_value_get_long(sval); -+ } -+ } -+ -+ /* flow control update pause. */ -+ ra->flowControlPause = DEFAULT_FLOWCONTROL_PAUSE; -+ if (slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlPause, &sattr) == 0) -+ { -+ Slapi_Value *sval; -+ if (slapi_attr_first_value(sattr, &sval) == 0) -+ { -+ ra->flowControlPause = slapi_value_get_long(sval); -+ } -+ } -+ - /* DN of entry at root of replicated area */ - tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaRoot); - if (NULL != tmpstr) -@@ -1014,6 +1044,26 @@ agmt_get_pausetime(const Repl_Agmt *ra) - return return_value; - } - -+long -+agmt_get_flowcontrolwindow(const Repl_Agmt *ra) -+{ -+ long return_value; -+ PR_ASSERT(NULL != ra); -+ PR_Lock(ra->lock); -+ return_value = ra->flowControlWindow; -+ PR_Unlock(ra->lock); -+ return return_value; -+} -+long -+agmt_get_flowcontrolpause(const Repl_Agmt *ra) -+{ -+ long return_value; -+ PR_ASSERT(NULL != ra); -+ PR_Lock(ra->lock); -+ return_value = ra->flowControlPause; -+ PR_Unlock(ra->lock); -+ return return_value; -+} - /* - * Warning - reference to the long name of the agreement is returned. - * The long name of an agreement is the DN of the agreement entry, -@@ -1775,6 +1825,90 @@ agmt_set_timeout_from_entry(Repl_Agmt *ra, const Slapi_Entry *e) - return return_value; - } - -+/* -+ * Set or reset the windows of entries sent without acknowledgment. -+ * The window is used during update to determine the number of -+ * entries will be send by the replica agreement without acknowledgment from the consumer -+ * -+ * Returns 0 if window set, or -1 if an error occurred. -+ */ -+int -+agmt_set_flowcontrolwindow_from_entry(Repl_Agmt *ra, const Slapi_Entry *e) -+{ -+ Slapi_Attr *sattr = NULL; -+ int return_value = -1; -+ -+ PR_ASSERT(NULL != ra); -+ PR_Lock(ra->lock); -+ if (ra->stop_in_progress) -+ { -+ PR_Unlock(ra->lock); -+ return return_value; -+ } -+ -+ slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlWindow, &sattr); -+ if (NULL != sattr) -+ { -+ Slapi_Value *sval = NULL; -+ slapi_attr_first_value(sattr, &sval); -+ if (NULL != sval) -+ { -+ long tmpval = slapi_value_get_long(sval); -+ if (tmpval >= 0) { -+ ra->flowControlWindow = tmpval; -+ return_value = 0; /* success! */ -+ } -+ } -+ } -+ PR_Unlock(ra->lock); -+ if (return_value == 0) -+ { -+ prot_notify_agmt_changed(ra->protocol, ra->long_name); -+ } -+ return return_value; -+} -+ -+/* -+ * Set or reset the pause duration when #entries sent without acknowledgment overpass flow control window -+ * -+ * Returns 0 if pause set, or -1 if an error occurred. -+ */ -+int -+agmt_set_flowcontrolpause_from_entry(Repl_Agmt *ra, const Slapi_Entry *e) -+{ -+ Slapi_Attr *sattr = NULL; -+ int return_value = -1; -+ -+ PR_ASSERT(NULL != ra); -+ PR_Lock(ra->lock); -+ if (ra->stop_in_progress) -+ { -+ PR_Unlock(ra->lock); -+ return return_value; -+ } -+ -+ slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlPause, &sattr); -+ if (NULL != sattr) -+ { -+ Slapi_Value *sval = NULL; -+ slapi_attr_first_value(sattr, &sval); -+ if (NULL != sval) -+ { -+ long tmpval = slapi_value_get_long(sval); -+ if (tmpval >= 0) { -+ ra->flowControlPause = tmpval; -+ return_value = 0; /* success! */ -+ } -+ } -+ } -+ PR_Unlock(ra->lock); -+ if (return_value == 0) -+ { -+ prot_notify_agmt_changed(ra->protocol, ra->long_name); -+ } -+ return return_value; -+} -+ - int - agmt_set_timeout(Repl_Agmt *ra, long timeout) - { -@@ -1788,6 +1922,32 @@ agmt_set_timeout(Repl_Agmt *ra, long timeout) - - return 0; - } -+int -+agmt_set_flowcontrolwindow(Repl_Agmt *ra, long window) -+{ -+ PR_Lock(ra->lock); -+ if (ra->stop_in_progress){ -+ PR_Unlock(ra->lock); -+ return -1; -+ } -+ ra->flowControlWindow = window; -+ PR_Unlock(ra->lock); -+ -+ return 0; -+} -+int -+agmt_set_flowcontrolpause(Repl_Agmt *ra, long pause) -+{ -+ PR_Lock(ra->lock); -+ if (ra->stop_in_progress){ -+ PR_Unlock(ra->lock); -+ return -1; -+ } -+ ra->flowControlPause = pause; -+ PR_Unlock(ra->lock); -+ -+ return 0; -+} - - /* - * Set or reset the busywaittime -diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c -index 8a70055..5eead07 100644 ---- a/ldap/servers/plugins/replication/repl5_agmtlist.c -+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c -@@ -330,6 +330,32 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry - } - } - else if (slapi_attr_types_equivalent(mods[i]->mod_type, -+ type_nsds5ReplicaFlowControlWindow)) -+ { -+ /* New replica timeout */ -+ if (agmt_set_flowcontrolwindow_from_entry(agmt, e) != 0) -+ { -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " -+ "failed to update the flow control window for agreement %s\n", -+ agmt_get_long_name(agmt)); -+ *returncode = LDAP_OPERATIONS_ERROR; -+ rc = SLAPI_DSE_CALLBACK_ERROR; -+ } -+ } -+ else if (slapi_attr_types_equivalent(mods[i]->mod_type, -+ type_nsds5ReplicaFlowControlPause)) -+ { -+ /* New replica timeout */ -+ if (agmt_set_flowcontrolpause_from_entry(agmt, e) != 0) -+ { -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " -+ "failed to update the flow control pause for agreement %s\n", -+ agmt_get_long_name(agmt)); -+ *returncode = LDAP_OPERATIONS_ERROR; -+ rc = SLAPI_DSE_CALLBACK_ERROR; -+ } -+ } -+ else if (slapi_attr_types_equivalent(mods[i]->mod_type, - type_nsds5ReplicaBusyWaitTime)) - { - /* New replica busywaittime */ -diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c -index c004bfb..2971025 100644 ---- a/ldap/servers/plugins/replication/repl5_connection.c -+++ b/ldap/servers/plugins/replication/repl5_connection.c -@@ -52,6 +52,7 @@ replica locked. Seems like right thing to do. - */ - - #include "repl5.h" -+#include "repl5_prot_private.h" - #include "slapi-private.h" - #if defined(USE_OPENLDAP) - #include "ldap.h" -@@ -91,6 +92,7 @@ typedef struct repl_connection - struct timeval timeout; - int flag_agmt_changed; - char *plain; -+ void *tot_init_callback; /* Used during total update to do flow control */ - } repl_connection; - - /* #define DEFAULT_LINGER_TIME (5 * 60) */ /* 5 minutes */ -@@ -274,6 +276,32 @@ conn_delete(Repl_Connection *conn) - PR_Unlock(conn->lock); - } - -+void -+conn_set_tot_update_cb_nolock(Repl_Connection *conn, void *cb_data) -+{ -+ conn->tot_init_callback = (void *) cb_data; -+} -+void -+conn_set_tot_update_cb(Repl_Connection *conn, void *cb_data) -+{ -+ PR_Lock(conn->lock); -+ conn_set_tot_update_cb_nolock(conn, cb_data); -+ PR_Unlock(conn->lock); -+} -+ -+void -+conn_get_tot_update_cb_nolock(Repl_Connection *conn, void **cb_data) -+{ -+ *cb_data = (void *) conn->tot_init_callback; -+} -+void -+conn_get_tot_update_cb(Repl_Connection *conn, void **cb_data) -+{ -+ PR_Lock(conn->lock); -+ conn_get_tot_update_cb_nolock(conn, cb_data); -+ PR_Unlock(conn->lock); -+} -+ - /* - * Return the last operation type processed by the connection - * object, and the LDAP error encountered. -@@ -640,6 +668,131 @@ see_if_write_available(Repl_Connection *conn, PRIntervalTime timeout) - } - #endif /* ! USE_OPENLDAP */ - -+/* -+ * During a total update, this function checks how much entries -+ * have been sent to the consumer without having received their acknowledgment. -+ * Basically it checks how late is the consumer. -+ * -+ * If the consumer is too late, it pause the RA.sender (releasing the lock) to -+ * let the consumer to catch up and RA.reader to receive the acknowledgments. -+ * -+ * Caller must hold conn->lock -+ */ -+static void -+check_flow_control_tot_init(Repl_Connection *conn, int optype, const char *extop_oid, int sent_msgid) -+{ -+ int rcv_msgid; -+ int once; -+ -+ if ((sent_msgid != 0) && (optype == CONN_EXTENDED_OPERATION) && (strcmp(extop_oid, REPL_NSDS50_REPLICATION_ENTRY_REQUEST_OID) == 0)) { -+ /* We are sending entries part of the total update of a consumer -+ * Wait a bit if the consumer needs to catchup from the current sent entries -+ */ -+ rcv_msgid = repl5_tot_last_rcv_msgid(conn); -+ if (rcv_msgid == -1) { -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, -+ "%s: check_flow_control_tot_init no callback data [ msgid sent: %d]\n", -+ agmt_get_long_name(conn->agmt), -+ sent_msgid); -+ } else if (sent_msgid < rcv_msgid) { -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, -+ "%s: check_flow_control_tot_init invalid message ids [ msgid sent: %d, rcv: %d]\n", -+ agmt_get_long_name(conn->agmt), -+ sent_msgid, -+ rcv_msgid); -+ } else if ((sent_msgid - rcv_msgid) > agmt_get_flowcontrolwindow(conn->agmt)) { -+ int totalUpdatePause; -+ -+ totalUpdatePause = agmt_get_flowcontrolpause(conn->agmt); -+ if (totalUpdatePause) { -+ /* The consumer is late. Last sent entry compare to last acknowledged entry -+ * overpass the allowed limit (flowcontrolwindow) -+ * Give some time to the consumer to catch up -+ */ -+ once = repl5_tot_flowcontrol_detection(conn, 1); -+ PR_Unlock(conn->lock); -+ if (once == 1) { -+ /* This is the first time we hit total update flow control. -+ * Log it at least once to inform administrator there is -+ * a potential configuration issue here -+ */ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, -+ "%s: Total update flow control gives time (%d msec) to the consumer before sending more entries [ msgid sent: %d, rcv: %d])\n" -+ "If total update fails you can try to increase %s and/or decrease %s in the replica agreement configuration\n", -+ agmt_get_long_name(conn->agmt), -+ totalUpdatePause, -+ sent_msgid, -+ rcv_msgid, -+ type_nsds5ReplicaFlowControlPause, -+ type_nsds5ReplicaFlowControlWindow); -+ } -+ DS_Sleep(PR_MillisecondsToInterval(totalUpdatePause)); -+ PR_Lock(conn->lock); -+ } -+ } -+ } -+ -+} -+/* -+ * Test if the connection is available to do a write. -+ * This function is doing a periodic polling of the connection. -+ * If the polling times out: -+ * - it releases the connection lock (to let other thread ,i.e. -+ * replication result thread, the opportunity to use the connection) -+ * - Sleeps for a short period (100ms) -+ * - acquires the connection lock -+ * -+ * It loops until -+ * - it is available -+ * - exceeds RA complete timeout -+ * - server is shutdown -+ * - connection is disconnected (Disable, stop, delete the RA -+ * 'terminate' the replication protocol and disconnect the connection) -+ * -+ * Return: -+ * - CONN_OPERATION_SUCCESS if the connection is available -+ * - CONN_TIMEOUT if the overall polling/sleeping delay exceeds RA timeout -+ * - CONN_NOT_CONNECTED if the replication connection state is disconnected -+ * - other ConnResult -+ * -+ * Caller must hold conn->Lock. At the exit, conn->lock is held -+ */ -+static ConnResult -+conn_is_available(Repl_Connection *conn) -+{ -+ time_t poll_timeout_sec = 1; /* Polling for 1sec */ -+ time_t yield_delay_msec = 100; /* Delay to wait */ -+ time_t start_time = time( NULL ); -+ time_t time_now; -+ ConnResult return_value = CONN_OPERATION_SUCCESS; -+ -+ while (!slapi_is_shutting_down() && (conn->state != STATE_DISCONNECTED)) { -+ return_value = see_if_write_available(conn, PR_SecondsToInterval(poll_timeout_sec)); -+ if (return_value == CONN_TIMEOUT) { -+ /* in case of timeout we return CONN_TIMEOUT only -+ * if the RA.timeout is exceeded -+ */ -+ time_now = time(NULL); -+ if (conn->timeout.tv_sec <= (time_now - start_time)) { -+ break; -+ } else { -+ /* Else give connection to others threads */ -+ PR_Unlock(conn->lock); -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, -+ "%s: perform_operation transient timeout. retry)\n", -+ agmt_get_long_name(conn->agmt)); -+ DS_Sleep(PR_MillisecondsToInterval(yield_delay_msec)); -+ PR_Lock(conn->lock); -+ } -+ } else { -+ break; -+ } -+ } -+ if (conn->state == STATE_DISCONNECTED) { -+ return_value = CONN_NOT_CONNECTED; -+ } -+ return return_value; -+} - /* - * Common code to send an LDAPv3 operation and collect the result. - * Return values: -@@ -683,10 +836,13 @@ perform_operation(Repl_Connection *conn, int optype, const char *dn, - - Slapi_Eq_Context eqctx = repl5_start_debug_timeout(&setlevel); - -- return_value = see_if_write_available( -- conn, PR_SecondsToInterval(conn->timeout.tv_sec)); -+ return_value = conn_is_available(conn); - if (return_value != CONN_OPERATION_SUCCESS) { - PR_Unlock(conn->lock); -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, -+ "%s: perform_operation connection is not available (%d)\n", -+ agmt_get_long_name(conn->agmt), -+ return_value); - return return_value; - } - conn->last_operation = optype; -@@ -758,6 +914,9 @@ perform_operation(Repl_Connection *conn, int optype, const char *dn, - */ - return_value = CONN_NOT_CONNECTED; - } -+ -+ check_flow_control_tot_init(conn, optype, extop_oid, msgid); -+ - PR_Unlock(conn->lock); /* release the lock */ - if (message_id) - { -diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c -index 3bb68e7..b867fc4 100644 ---- a/ldap/servers/plugins/replication/repl5_inc_protocol.c -+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c -@@ -108,6 +108,7 @@ typedef struct result_data - int stop_result_thread; /* Flag used to tell the result thread to exit */ - int last_message_id_sent; - int last_message_id_received; -+ int flowcontrol_detection; - int result; /* The UPDATE_TRANSIENT_ERROR etc */ - } result_data; - -@@ -460,6 +461,23 @@ repl5_inc_destroy_async_result_thread(result_data *rd) - return retval; - } - -+/* The interest of this routine is to give time to the consumer -+ * to apply the sent updates and return the acks. -+ * So the caller should not hold the replication connection lock -+ * to let the RA.reader receives the acks. -+ */ -+static void -+repl5_inc_flow_control_results(Repl_Agmt *agmt, result_data *rd) -+{ -+ PR_Lock(rd->lock); -+ if ((rd->last_message_id_received <= rd->last_message_id_sent) && -+ ((rd->last_message_id_sent - rd->last_message_id_received) >= agmt_get_flowcontrolwindow(agmt))) { -+ rd->flowcontrol_detection++; -+ DS_Sleep(PR_MillisecondsToInterval(agmt_get_flowcontrolpause(agmt))); -+ } -+ PR_Unlock(rd->lock); -+} -+ - static void - repl5_inc_waitfor_async_results(result_data *rd) - { -@@ -1683,7 +1701,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu - { - int finished = 0; - ConnResult replay_crc; -- char csn_str[CSN_STRSIZE]; -+ char csn_str[CSN_STRSIZE]; - - /* Start the results reading thread */ - rd = repl5_inc_rd_new(prp); -@@ -1818,6 +1836,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu - sop->replica_id = replica_id; - PL_strncpyz(sop->uniqueid, uniqueid, sizeof(sop->uniqueid)); - repl5_int_push_operation(rd,sop); -+ repl5_inc_flow_control_results(prp->agmt, rd); - } else { - slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, - "%s: Skipping update operation with no message_id (uniqueid %s, CSN %s):\n", -@@ -1906,6 +1925,17 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu - } - *num_changes_sent = rd->num_changes_sent; - } -+ PR_Lock(rd->lock); -+ if (rd->flowcontrol_detection) { -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, -+ "%s: Incremental update flow control triggered %d times\n" -+ "You may increase %s and/or decrease %s in the replica agreement configuration\n", -+ agmt_get_long_name(prp->agmt), -+ rd->flowcontrol_detection, -+ type_nsds5ReplicaFlowControlPause, -+ type_nsds5ReplicaFlowControlWindow); -+ } -+ PR_Unlock(rd->lock); - repl5_inc_rd_destroy(&rd); - - cl5_operation_parameters_done ( entry.op ); -diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h -index 586e1eb..1b1c00b 100644 ---- a/ldap/servers/plugins/replication/repl5_prot_private.h -+++ b/ldap/servers/plugins/replication/repl5_prot_private.h -@@ -79,6 +79,8 @@ typedef struct private_repl_protocol - - extern Private_Repl_Protocol *Repl_5_Inc_Protocol_new(); - extern Private_Repl_Protocol *Repl_5_Tot_Protocol_new(); -+extern int repl5_tot_last_rcv_msgid(Repl_Connection *conn); -+extern int repl5_tot_flowcontrol_detection(Repl_Connection *conn, int increment); - extern Private_Repl_Protocol *Windows_Inc_Protocol_new(); - extern Private_Repl_Protocol *Windows_Tot_Protocol_new(); - -diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c -index d4f0fcc..adadd44 100644 ---- a/ldap/servers/plugins/replication/repl5_tot_protocol.c -+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c -@@ -82,6 +82,7 @@ typedef struct callback_data - int stop_result_thread; /* Flag used to tell the result thread to exit */ - int last_message_id_sent; - int last_message_id_received; -+ int flowcontrol_detection; - } callback_data; - - /* -@@ -428,13 +429,19 @@ repl5_tot_run(Private_Repl_Protocol *prp) - LDAP_SCOPE_SUBTREE, "(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))", NULL, 0, ctrls, NULL, - repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0); - -- cb_data.prp = prp; -- cb_data.rc = 0; -+ cb_data.prp = prp; -+ cb_data.rc = 0; - cb_data.num_entries = 0UL; - cb_data.sleep_on_busy = 0UL; - cb_data.last_busy = current_time (); -+ cb_data.flowcontrol_detection = 0; - cb_data.lock = PR_NewLock(); - -+ /* This allows during perform_operation to check the callback data -+ * especially to do flow contol on delta send msgid / recv msgid -+ */ -+ conn_set_tot_update_cb(prp->conn, (void *) &cb_data); -+ - /* Before we get started on sending entries to the replica, we need to - * setup things for async propagation: - * 1. Create a thread that will read the LDAP results from the connection. -@@ -506,6 +513,17 @@ repl5_tot_run(Private_Repl_Protocol *prp) - done: - slapi_sdn_free(&area_sdn); - slapi_ch_free_string(&hostname); -+ if (cb_data.flowcontrol_detection > 1) -+ { -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, -+ "%s: Total update flow control triggered %d times\n" -+ "You may increase %s and/or decrease %s in the replica agreement configuration\n", -+ agmt_get_long_name(prp->agmt), -+ cb_data.flowcontrol_detection, -+ type_nsds5ReplicaFlowControlPause, -+ type_nsds5ReplicaFlowControlWindow); -+ } -+ conn_set_tot_update_cb(prp->conn, NULL); - if (cb_data.lock) - { - PR_DestroyLock(cb_data.lock); -@@ -645,6 +663,37 @@ void get_result (int rc, void *cb_data) - ((callback_data*)cb_data)->rc = rc; - } - -+/* Call must hold the connection lock */ -+int -+repl5_tot_last_rcv_msgid(Repl_Connection *conn) -+{ -+ struct callback_data *cb_data; -+ -+ conn_get_tot_update_cb_nolock(conn, (void **) &cb_data); -+ if (cb_data == NULL) { -+ return -1; -+ } else { -+ return cb_data->last_message_id_received; -+ } -+} -+ -+/* Increase the flowcontrol counter -+ * Call must hold the connection lock -+ */ -+int -+repl5_tot_flowcontrol_detection(Repl_Connection *conn, int increment) -+{ -+ struct callback_data *cb_data; -+ -+ conn_get_tot_update_cb_nolock(conn, (void **) &cb_data); -+ if (cb_data == NULL) { -+ return -1; -+ } else { -+ cb_data->flowcontrol_detection += increment; -+ return cb_data->flowcontrol_detection; -+ } -+} -+ - static - int send_entry (Slapi_Entry *e, void *cb_data) - { -diff --git a/ldap/servers/plugins/replication/repl_globals.c b/ldap/servers/plugins/replication/repl_globals.c -index 5609def..e2157fa 100644 ---- a/ldap/servers/plugins/replication/repl_globals.c -+++ b/ldap/servers/plugins/replication/repl_globals.c -@@ -139,6 +139,8 @@ const char *type_nsds5ReplicaBusyWaitTime = "nsds5ReplicaBusyWaitTime"; - const char *type_nsds5ReplicaSessionPauseTime = "nsds5ReplicaSessionPauseTime"; - const char *type_nsds5ReplicaEnabled = "nsds5ReplicaEnabled"; - const char *type_nsds5ReplicaStripAttrs = "nsds5ReplicaStripAttrs"; -+const char* type_nsds5ReplicaFlowControlWindow = "nsds5ReplicaFlowControlWindow"; -+const char* type_nsds5ReplicaFlowControlPause = "nsds5ReplicaFlowControlPause"; - - /* windows sync specific attributes */ - const char *type_nsds7WindowsReplicaArea = "nsds7WindowsReplicaSubtree"; --- -1.9.3 - diff --git a/SOURCES/0032-Ticket-48231-logconv-autobind-handling-regression-ca.patch b/SOURCES/0032-Ticket-48231-logconv-autobind-handling-regression-ca.patch new file mode 100644 index 0000000..f9682d7 --- /dev/null +++ b/SOURCES/0032-Ticket-48231-logconv-autobind-handling-regression-ca.patch @@ -0,0 +1,39 @@ +From ddf6d5dfd566d44a10af342d049f22b5dbe26381 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 30 Jul 2015 11:07:40 -0700 +Subject: [PATCH 32/39] Ticket #48231 - logconv autobind handling regression + caused by 47446 + +Description: When there are autobinds with ldapi, the tool fails with +an syntax error: + Use of uninitialized value in transliteration (tr///) at /Local/dirsrv/bin/logconv.pl line 2018, <$LOGFH> line 207. + Use of uninitialized value $tmpp in hash element at /Local/dirsrv/bin/logconv.pl line 2019, <$LOGFH> line 207. + +Thanks for providing the fix and testing it, pj101 and rmeggins@redhat.com. + +Reviewed by nhosoi@redhat.com. + +https://fedorahosted.org/389/ticket/48231 +(cherry picked from commit 44a223f73a537445976a77af1652515ea46f970b) +(cherry picked from commit e7fc14305e7e431034d5e076f31d2ee22742578f) +--- + ldap/admin/src/logconv.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index 3113f8a..9cd9aaa 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -2025,8 +2025,8 @@ sub parseLineNormal + if($1 eq $rootDN){ + $rootDNBindCount++; + } ++ $tmpp = $1; + if($usage =~ /f/ || $usage =~ /u/ || $usage =~ /U/ || $usage =~ /b/ || $verb eq "yes"){ +- $tmpp = $1; + $tmpp =~ tr/A-Z/a-z/; + $hashes->{bindlist}->{$tmpp}++; + } +-- +1.9.3 + diff --git a/SOURCES/0033-Fix-for-CVE-2014-8105.patch b/SOURCES/0033-Fix-for-CVE-2014-8105.patch deleted file mode 100644 index cc52f96..0000000 --- a/SOURCES/0033-Fix-for-CVE-2014-8105.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 4b812a1af367ed409e21abe73a77e57092e5a5f3 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 16 Dec 2014 16:53:07 -0500 -Subject: [PATCH 33/53] Fix for CVE-2014-8105 - -Description: At server startup check for the Retro Changelog default ACI - on cn=changelog, if present delete it. - -Reviewed by: lkrispenz(Thanks!) ---- - ldap/servers/plugins/retrocl/retrocl.c | 67 ++++++++++++++++++++++++++- - ldap/servers/plugins/retrocl/retrocl_create.c | 4 -- - 2 files changed, 66 insertions(+), 5 deletions(-) - -diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c -index 0d2a6dc..8a0f350 100644 ---- a/ldap/servers/plugins/retrocl/retrocl.c -+++ b/ldap/servers/plugins/retrocl/retrocl.c -@@ -308,6 +308,68 @@ char *retrocl_get_config_str(const char *attrt) - return ma; - } - -+static void -+retrocl_remove_legacy_default_aci(void) -+{ -+ Slapi_PBlock *pb = NULL; -+ Slapi_Entry **entries; -+ char **aci_vals = NULL; -+ char *attrs[] = {"aci", NULL}; -+ int rc; -+ -+ pb = slapi_pblock_new(); -+ slapi_search_internal_set_pb(pb, RETROCL_CHANGELOG_DN, LDAP_SCOPE_BASE, "objectclass=*", -+ attrs, 0, NULL, NULL, g_plg_identity[PLUGIN_RETROCL] , 0); -+ slapi_search_internal_pb(pb); -+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); -+ if (rc == LDAP_SUCCESS) { -+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); -+ if(entries && entries[0]){ -+ if((aci_vals = slapi_entry_attr_get_charray(entries[0], "aci"))){ -+ if(charray_inlist(aci_vals, RETROCL_ACL)){ -+ /* -+ * Okay, we need to remove the aci -+ */ -+ LDAPMod mod; -+ LDAPMod *mods[2]; -+ char *val[2]; -+ Slapi_PBlock *mod_pb = 0; -+ -+ mod_pb = slapi_pblock_new(); -+ mods[0] = &mod; -+ mods[1] = 0; -+ val[0] = RETROCL_ACL; -+ val[1] = 0; -+ mod.mod_op = LDAP_MOD_DELETE; -+ mod.mod_type = "aci"; -+ mod.mod_values = val; -+ -+ slapi_modify_internal_set_pb_ext(mod_pb, slapi_entry_get_sdn(entries[0]), -+ mods, 0, 0, g_plg_identity[PLUGIN_RETROCL], 0); -+ slapi_modify_internal_pb(mod_pb); -+ slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); -+ if(rc == LDAP_SUCCESS){ -+ slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, -+ "Successfully removed vulnerable legacy default aci \"%s\". " -+ "If the aci removal was not desired please use a different \"acl " -+ "name\" so it is not removed at the next plugin startup.\n", -+ RETROCL_ACL); -+ } else { -+ slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, -+ "Failed to removed vulnerable legacy default aci (%s) error %d\n", -+ RETROCL_ACL, rc); -+ } -+ slapi_pblock_destroy(mod_pb); -+ } -+ slapi_ch_array_free(aci_vals); -+ } -+ } -+ } -+ slapi_free_search_results_internal(pb); -+ slapi_pblock_destroy(pb); -+} -+ -+ - /* - * Function: retrocl_start - * -@@ -333,7 +395,10 @@ static int retrocl_start (Slapi_PBlock *pb) - LDAPDebug1Arg(LDAP_DEBUG_TRACE,"Couldnt find backend, not trimming retro changelog (%d).\n",rc); - return rc; - } -- -+ -+ /* Remove the old default aci as it exposes passwords changes to anonymous users */ -+ retrocl_remove_legacy_default_aci(); -+ - retrocl_init_trimming(); - - if (slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e) != 0) { -diff --git a/ldap/servers/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c -index 1ffdaae..870421c 100644 ---- a/ldap/servers/plugins/retrocl/retrocl_create.c -+++ b/ldap/servers/plugins/retrocl/retrocl_create.c -@@ -344,10 +344,6 @@ void retrocl_create_cle (void) - val.bv_len = strlen(val.bv_val); - slapi_entry_add_values( e, "cn", vals ); - -- val.bv_val = RETROCL_ACL; -- val.bv_len = strlen(val.bv_val); -- slapi_entry_add_values( e, "aci", vals ); -- - pb = slapi_pblock_new (); - slapi_add_entry_internal_set_pb( pb, e, NULL /* controls */, - g_plg_identity[PLUGIN_RETROCL], --- -1.9.3 - diff --git a/SOURCES/0033-Ticket-47810-memberOf-plugin-not-properly-rejecting-.patch b/SOURCES/0033-Ticket-47810-memberOf-plugin-not-properly-rejecting-.patch new file mode 100644 index 0000000..2803014 --- /dev/null +++ b/SOURCES/0033-Ticket-47810-memberOf-plugin-not-properly-rejecting-.patch @@ -0,0 +1,182 @@ +From 0536984f7b3e9d6e143936b0eda92b510f63d304 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 4 Aug 2015 12:15:31 -0400 +Subject: [PATCH 33/39] Ticket 47810 - memberOf plugin not properly rejecting + updates + +Bug Description: When the memberOf plugin tries to add memberOf attribute to + an entry during a mod-replace on a group, even though the + update to the user entry fails, but plugin still allows + the member to be added to the group. + +Fix Description: During a mod/replace check and return an error if the member + update fails. + +https://fedorahosted.org/389/ticket/47810 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit eb54f03e240402a4bd16f9cde1d66539805f56ea) +(cherry picked from commit b4b6adcec7d810c7893fd9cb888fa906b9ffa836) +--- + dirsrvtests/suites/betxns/betxn_test.py | 64 +++++++++++++++++++++++++++++++- + ldap/servers/plugins/memberof/memberof.c | 13 ++++--- + 2 files changed, 70 insertions(+), 7 deletions(-) + +diff --git a/dirsrvtests/suites/betxns/betxn_test.py b/dirsrvtests/suites/betxns/betxn_test.py +index 93c4c31..5da6e50 100644 +--- a/dirsrvtests/suites/betxns/betxn_test.py ++++ b/dirsrvtests/suites/betxns/betxn_test.py +@@ -3,7 +3,7 @@ + # All rights reserved. + # + # License: GPL (version 3 or any later version). +-# See LICENSE for details. ++# See LICENSE for details. + # --- END COPYRIGHT BLOCK --- + # + import os +@@ -174,6 +174,67 @@ def test_betxn_attr_uniqueness(topology): + log.info('test_betxn_attr_uniqueness: PASSED') + + ++def test_betxn_memberof(topology): ++ ENTRY1_DN = 'cn=group1,' + DEFAULT_SUFFIX ++ ENTRY2_DN = 'cn=group2,' + DEFAULT_SUFFIX ++ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config' ++ ++ # Enable and configure memberOf plugin ++ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF) ++ try: ++ topology.standalone.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')]) ++ except ldap.LDAPError, e: ++ log.fatal('test_betxn_memberof: Failed to update config(member): error ' + e.message['desc']) ++ assert False ++ ++ # Add our test entries ++ try: ++ topology.standalone.add_s(Entry((ENTRY1_DN, {'objectclass': "top groupofnames".split(), ++ 'cn': 'group1'}))) ++ except ldap.LDAPError, e: ++ log.error('test_betxn_memberof: Failed to add group1:' + ++ ENTRY1_DN + ', error ' + e.message['desc']) ++ assert False ++ ++ try: ++ topology.standalone.add_s(Entry((ENTRY2_DN, {'objectclass': "top groupofnames".split(), ++ 'cn': 'group1'}))) ++ except ldap.LDAPError, e: ++ log.error('test_betxn_memberof: Failed to add group2:' + ++ ENTRY2_DN + ', error ' + e.message['desc']) ++ assert False ++ ++ # ++ # Test mod replace ++ # ++ ++ # Add group2 to group1 - it should fail with objectclass violation ++ try: ++ topology.standalone.modify_s(ENTRY1_DN, [(ldap.MOD_REPLACE, 'member', ENTRY2_DN)]) ++ log.fatal('test_betxn_memberof: Group2 was incorrectly allowed to be added to group1') ++ assert False ++ except ldap.LDAPError, e: ++ log.info('test_betxn_memberof: Group2 was correctly rejected (mod replace): error ' + e.message['desc']) ++ ++ # ++ # Test mod add ++ # ++ ++ # Add group2 to group1 - it should fail with objectclass violation ++ try: ++ topology.standalone.modify_s(ENTRY1_DN, [(ldap.MOD_ADD, 'member', ENTRY2_DN)]) ++ log.fatal('test_betxn_memberof: Group2 was incorrectly allowed to be added to group1') ++ assert False ++ except ldap.LDAPError, e: ++ log.info('test_betxn_memberof: Group2 was correctly rejected (mod add): error ' + e.message['desc']) ++ ++ # ++ # Done ++ # ++ ++ log.info('test_betxn_memberof: PASSED') ++ ++ + def test_betxn_final(topology): + topology.standalone.delete() + log.info('betxn test suite PASSED') +@@ -187,6 +248,7 @@ def run_isolated(): + test_betxn_init(topo) + test_betxt_7bit(topo) + test_betxn_attr_uniqueness(topo) ++ test_betxn_memberof(topo) + test_betxn_final(topo) + + +diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c +index 144285b..da52bc8 100644 +--- a/ldap/servers/plugins/memberof/memberof.c ++++ b/ldap/servers/plugins/memberof/memberof.c +@@ -2373,6 +2373,7 @@ memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, + struct slapi_entry *post_e = NULL; + Slapi_Attr *pre_attr = 0; + Slapi_Attr *post_attr = 0; ++ int rc = 0; + int i = 0; + + slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e ); +@@ -2449,14 +2450,14 @@ memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, + in pre, not in post, delete from entry + not in pre, in post, add to entry + */ +- while(pre_index < pre_total || post_index < post_total) ++ while(rc == 0 && (pre_index < pre_total || post_index < post_total)) + { + if(pre_index == pre_total) + { + /* add the rest of post */ + slapi_sdn_set_normdn_byref(sdn, + slapi_value_get_string(post_array[post_index])); +- memberof_add_one(pb, config, group_sdn, sdn); ++ rc = memberof_add_one(pb, config, group_sdn, sdn); + + post_index++; + } +@@ -2465,7 +2466,7 @@ memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, + /* delete the rest of pre */ + slapi_sdn_set_normdn_byref(sdn, + slapi_value_get_string(pre_array[pre_index])); +- memberof_del_one(pb, config, group_sdn, sdn); ++ rc = memberof_del_one(pb, config, group_sdn, sdn); + + pre_index++; + } +@@ -2482,7 +2483,7 @@ memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, + /* delete pre array */ + slapi_sdn_set_normdn_byref(sdn, + slapi_value_get_string(pre_array[pre_index])); +- memberof_del_one(pb, config, group_sdn, sdn); ++ rc = memberof_del_one(pb, config, group_sdn, sdn); + + pre_index++; + } +@@ -2491,7 +2492,7 @@ memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, + /* add post array */ + slapi_sdn_set_normdn_byref(sdn, + slapi_value_get_string(post_array[post_index])); +- memberof_add_one(pb, config, group_sdn, sdn); ++ rc = memberof_add_one(pb, config, group_sdn, sdn); + + post_index++; + } +@@ -2509,7 +2510,7 @@ memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, + } + } + +- return 0; ++ return rc; + } + + /* memberof_load_array() +-- +1.9.3 + diff --git a/SOURCES/0034-Additional-fix-for-ticket-47526-v3.patch b/SOURCES/0034-Additional-fix-for-ticket-47526-v3.patch deleted file mode 100644 index 9c52246..0000000 --- a/SOURCES/0034-Additional-fix-for-ticket-47526-v3.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b046f03c6a7b828152246f44bcacfee6347e5337 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Wed, 17 Dec 2014 18:11:44 +0100 -Subject: [PATCH 34/53] Additional fix for ticket 47526 v3 - - In modrdn we need to distinguish if the entry is changed is a group or a - regular memebr of a group. for the group case do the same as when deleting a group - For the modrdn of an user entry, the case where no memberof attribute exists has - to succeed. - - Reviewed by: noriko, thanks - - https://fedorahosted.org/389/ticket/47526 - -(cherry picked from commit c8951669b3a74cb9fda013ffe914031b76e2e452) ---- - ldap/servers/plugins/memberof/memberof.c | 46 +++++++++++++++++++++++++------- - 1 file changed, 36 insertions(+), 10 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index bd87ee9..80b52ab 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -566,7 +566,7 @@ int memberof_postop_del(Slapi_PBlock *pb) - } - - /* is the entry of interest as a group? */ -- if(e && configCopy.group_filter && !slapi_filter_test_simple(e, configCopy.group_filter)) -+ if(e && configCopy.group_filter && 0 == slapi_filter_test_simple(e, configCopy.group_filter)) - { - int i = 0; - Slapi_Attr *attr = 0; -@@ -664,6 +664,12 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) - - slapi_pblock_destroy(mod_pb); - -+ if (rc == LDAP_NO_SUCH_ATTRIBUTE && val[0] == NULL) { -+ /* if no memberof attribut exists -+ * handle as success -+ */ -+ rc = LDAP_SUCCESS; -+ } - return rc; - } - -@@ -861,7 +867,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - - /* update any downstream members */ - if(pre_sdn && post_sdn && configCopy.group_filter && -- !slapi_filter_test_simple(post_e, configCopy.group_filter)) -+ 0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) - { - int i = 0; - Slapi_Attr *attr = 0; -@@ -890,17 +896,37 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - if (ret == LDAP_SUCCESS && pre_sdn && post_sdn) { - if ((entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) || - (entry_scope_exclude_subtree && slapi_sdn_issuffix(post_sdn, entry_scope_exclude_subtree))) { -- memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; - if((ret = memberof_del_dn_from_groups(pb, &configCopy, pre_sdn))){ - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, - "memberof_postop_modrdn - delete dn failed for (%s), error (%d)\n", - slapi_sdn_get_dn(pre_sdn), ret); - } -- if(ret == LDAP_SUCCESS && (ret = memberof_del_dn_type_callback(post_e, &del_data))){ -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", -- slapi_entry_get_dn(post_e), ret); -- } -+ if(ret == LDAP_SUCCESS && pre_e && configCopy.group_filter && -+ 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) { -+ /* is the entry of interest as a group? */ -+ int i = 0; -+ Slapi_Attr *attr = 0; -+ -+ /* Loop through to find each grouping attribute separately. */ -+ for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) { -+ if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) { -+ if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){ -+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n", -+ slapi_sdn_get_dn(pre_sdn),ret); -+ } -+ -+ } -+ } -+ } -+ if(ret == LDAP_SUCCESS) { -+ memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; -+ if(ret = memberof_del_dn_type_callback(post_e, &del_data)){ -+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", -+ slapi_entry_get_dn(post_e), ret); -+ } -+ } - } else { - if((ret = memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn))){ - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -@@ -1261,7 +1287,7 @@ int memberof_postop_add(Slapi_PBlock *pb) - memberof_rlock_config(); - mainConfig = memberof_get_config(); - if(e && mainConfig && mainConfig->group_filter && -- !slapi_filter_test_simple(e, mainConfig->group_filter)) -+ 0 == slapi_filter_test_simple(e, mainConfig->group_filter)) - { - interested = 1; - /* copy config so it doesn't change out from under us */ -@@ -1554,7 +1580,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, - "memberof_modop_one_replace_r: %s %s in %s\n" - ,op_str, op_this, op_to); - -- if(config->group_filter && !slapi_filter_test_simple(e, config->group_filter)) -+ if(config->group_filter && 0 == slapi_filter_test_simple(e, config->group_filter)) - { - /* group */ - Slapi_Value *ll_dn_val = 0; --- -1.9.3 - diff --git a/SOURCES/0034-Ticket-48215-verify_db.pl-doesn-t-verify-DB-specifie.patch b/SOURCES/0034-Ticket-48215-verify_db.pl-doesn-t-verify-DB-specifie.patch new file mode 100644 index 0000000..288ff91 --- /dev/null +++ b/SOURCES/0034-Ticket-48215-verify_db.pl-doesn-t-verify-DB-specifie.patch @@ -0,0 +1,288 @@ +From a117d87aac507e4002429e5f7aebe61a867da06d Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 5 Aug 2015 16:31:49 -0400 +Subject: [PATCH 34/39] Ticket 48215 - verify_db.pl doesn't verify DB specified + by -a option + +Bug Description: verify_db.pl -a only uses the db location for + checking the transaction logs, because it ends up + calling "nsslapd dbverify" which only checks the + db files in the server configuration. + +Fix Description: Allow a new argument to be passed to "nsslapd dbverify" + that specifies the db parent directory. + +https://fedorahosted.org/389/ticket/48215 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 27fadb75ec1f3b252028ce715cd7fa16da1f6525) +(cherry picked from commit 210071c682751897099e8eb138e5db1e47ac2bae) +--- + ldap/admin/src/scripts/dbverify.in | 3 ++- + ldap/admin/src/scripts/verify-db.pl.in | 17 +++++++++-------- + ldap/servers/slapd/back-ldbm/dbverify.c | 13 +++++++++++++ + ldap/servers/slapd/main.c | 18 +++++++++++++----- + ldap/servers/slapd/pblock.c | 12 +++++++++++- + ldap/servers/slapd/slap.h | 2 ++ + ldap/servers/slapd/slapi-plugin.h | 3 +++ + man/man8/dbverify.8 | 3 +++ + 8 files changed, 56 insertions(+), 15 deletions(-) + +diff --git a/ldap/admin/src/scripts/dbverify.in b/ldap/admin/src/scripts/dbverify.in +index 6306a07..778a9ba 100755 +--- a/ldap/admin/src/scripts/dbverify.in ++++ b/ldap/admin/src/scripts/dbverify.in +@@ -26,7 +26,7 @@ usage() + } + + display_version="no" +-while getopts "Z:n:hVvfd:n:D:" flag ++while getopts "Z:n:hVvfd:n:D:a:" flag + do + case $flag in + h) usage +@@ -39,6 +39,7 @@ do + display_version="yes";; + f) args=$args" -f";; + D) args=$args" -D $OPTARG";; ++ a) args=$args" -a $OPTARG";; + ?) usage + exit 1;; + esac +diff --git a/ldap/admin/src/scripts/verify-db.pl.in b/ldap/admin/src/scripts/verify-db.pl.in +index ae56a16..d481ecb 100644 +--- a/ldap/admin/src/scripts/verify-db.pl.in ++++ b/ldap/admin/src/scripts/verify-db.pl.in +@@ -16,7 +16,7 @@ DSUtil::libpath_add("@db_libdir@"); + DSUtil::libpath_add("@libdir@"); + $ENV{'PATH'} = "@libdir@/@package_name@/slapd-$servid:@db_bindir@:/usr/bin:/"; + $ENV{'SHLIB_PATH'} = "$ENV{'LD_LIBRARY_PATH'}"; +- ++my $custom_dbdir = 0; + my $i = 0; + + sub usage +@@ -118,12 +118,7 @@ sub getLastLogfile + return \$logfile; + } + +-$isWin = -d '\\'; +-if ($isWin) { +- $NULL = "nul"; +-} else { +- $NULL = "/dev/null"; +-} ++$NULL = "/dev/null"; + + while ($i <= $#ARGV) { + if ( "$ARGV[$i]" eq "-a" ) { # path to search the db files +@@ -149,6 +144,8 @@ print("*****************************************************************\n"); + + if ( "$startpoint" eq "" ) { + $startpoint = "@localstatedir@/lib/@PACKAGE_NAME@/slapd-$servid/db"; ++} else { ++ $custom_dbdir = 1; + } + # get dirs having DBVERSION + my $dbdirs = getDbDir($startpoint); +@@ -192,7 +189,11 @@ for (my $i = 0; "$$dbdirs[$i]" ne ""; $i++) + + # Check db files by db_verify + print "Verify db files ... "; +-open(DBVERIFY, "@sbindir@/dbverify -Z $servid 2>&1 1> $NULL |"); ++if ($custom_dbdir){ ++ open(DBVERIFY, "@sbindir@/dbverify -Z $servid -a $startpoint 2>&1 1> $NULL |"); ++} else { ++ open(DBVERIFY, "@sbindir@/dbverify -Z $servid 2>&1 1> $NULL |"); ++} + sleep 1; + my $bad_index = 0; + my $bad_id2entry = 0; +diff --git a/ldap/servers/slapd/back-ldbm/dbverify.c b/ldap/servers/slapd/back-ldbm/dbverify.c +index 85ee7a0..315ef93 100644 +--- a/ldap/servers/slapd/back-ldbm/dbverify.c ++++ b/ldap/servers/slapd/back-ldbm/dbverify.c +@@ -186,13 +186,16 @@ ldbm_back_dbverify( Slapi_PBlock *pb ) + int rval = 1; + int rval_main = 0; + char **instance_names = NULL; ++ char *dbdir = NULL; + + slapi_log_error(SLAPI_LOG_TRACE, "verify DB", "Verifying db files...\n"); + slapi_pblock_get(pb, SLAPI_BACKEND_INSTANCE_NAME, &instance_names); + slapi_pblock_get(pb, SLAPI_SEQ_TYPE, &verbose); + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li); ++ slapi_pblock_get(pb, SLAPI_DBVERIFY_DBDIR, &dbdir); + ldbm_config_load_dse_info(li); + ldbm_config_internal_set(li, CONFIG_DB_TRANSACTION_LOGGING, "off"); ++ + /* no write needed; choose EXPORT MODE */ + if (0 != dblayer_start(li, DBLAYER_EXPORT_MODE)) + { +@@ -211,6 +214,11 @@ ldbm_back_dbverify( Slapi_PBlock *pb ) + inst = ldbm_instance_find_by_name(li, *inp); + if (inst) + { ++ if (dbdir){ ++ /* verifying backup */ ++ slapi_ch_free_string(&inst->inst_parent_dir_name); ++ inst->inst_parent_dir_name = slapi_ch_strdup(dbdir); ++ } + rval_main |= dbverify_ext(inst, verbose); + } + else +@@ -235,6 +243,11 @@ ldbm_back_dbverify( Slapi_PBlock *pb ) + inst->inst_name); + continue; /* skip this instance and go to the next*/ + } ++ if (dbdir){ ++ /* verifying backup */ ++ slapi_ch_free_string(&inst->inst_parent_dir_name); ++ inst->inst_parent_dir_name = slapi_ch_strdup(dbdir); ++ } + rval_main |= dbverify_ext(inst, verbose); + } + } +diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c +index 9016144..922de97 100644 +--- a/ldap/servers/slapd/main.c ++++ b/ldap/servers/slapd/main.c +@@ -435,13 +435,15 @@ static int ldif_printkey = EXPORT_PRINTKEY|EXPORT_APPENDMODE; + static char *archive_name = NULL; + static int db2ldif_dump_replica = 0; + static int db2ldif_dump_uniqueid = 1; +-static int ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_TIME_BASED; +-static int dbverify_verbose = 0; ++static int ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_TIME_BASED; + static char *ldif2db_namespaceid = NULL; + int importexport_encrypt = 0; + static int upgradedb_flags = 0; + static int upgradednformat_dryrun = 0; + static int is_quiet = 0; ++/* dbverify options */ ++static int dbverify_verbose = 0; ++static char *dbverify_dbdir = NULL; + + /* taken from idsktune */ + #if defined(__sun) +@@ -1301,13 +1303,14 @@ process_command_line(int argc, char **argv, char *myname, + {"dryrun",ArgNone,'N'}, + {0,0,0}}; + +- char *opts_dbverify = "vVfd:n:D:"; ++ char *opts_dbverify = "vVfd:n:D:a:"; + struct opt_ext long_options_dbverify[] = { + {"version",ArgNone,'v'}, + {"debug",ArgRequired,'d'}, + {"backend",ArgRequired,'n'}, + {"configDir",ArgRequired,'D'}, + {"verbose",ArgNone,'V'}, ++ {"dbdir",ArgRequired,'a'}, + {0,0,0}}; + + char *opts_referral = "vd:p:r:SD:"; +@@ -1674,7 +1677,11 @@ process_command_line(int argc, char **argv, char *myname, + break; + + case 'a': /* archive pathname for db */ +- archive_name = optarg_ext; ++ if ( slapd_exemode == SLAPD_EXEMODE_DBVERIFY ) { ++ dbverify_dbdir = optarg_ext; ++ } else { ++ archive_name = optarg_ext; ++ } + break; + + case 'Z': +@@ -2688,7 +2695,8 @@ slapd_exemode_dbverify() + pb.pb_plugin = backend_plugin; + pb.pb_instance_name = (char *)cmd_line_instance_names; + pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; +- ++ pb.pb_dbverify_dbdir = dbverify_dbdir; ++ + if ( backend_plugin->plg_dbverify != NULL ) { + return_value = (*backend_plugin->plg_dbverify)( &pb ); + } else { +diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c +index c10f788..bf57a33 100644 +--- a/ldap/servers/slapd/pblock.c ++++ b/ldap/servers/slapd/pblock.c +@@ -5,7 +5,7 @@ + * All rights reserved. + * + * License: GPL (version 3 or any later version). +- * See LICENSE for details. ++ * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + + #ifdef HAVE_CONFIG_H +@@ -1677,6 +1677,11 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value ) + (*(IFP*)value) = pblock->pb_txn_ruv_mods_fn; + break; + ++ /* dbverify */ ++ case SLAPI_DBVERIFY_DBDIR: ++ (*(char **)value) = pblock->pb_dbverify_dbdir; ++ break; ++ + /* Search results set */ + case SLAPI_SEARCH_RESULT_SET: + if(pblock->pb_op!=NULL) +@@ -3520,6 +3525,11 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value ) + pblock->pb_aci_target_check = *((int *) value); + break; + ++ /* dbverify */ ++ case SLAPI_DBVERIFY_DBDIR: ++ pblock->pb_dbverify_dbdir = (char *) value; ++ break; ++ + default: + LDAPDebug( LDAP_DEBUG_ANY, + "Unknown parameter block argument %d\n", arg, 0, 0 ); +diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h +index 6d1ad7b..823568d 100644 +--- a/ldap/servers/slapd/slap.h ++++ b/ldap/servers/slapd/slap.h +@@ -1600,6 +1600,8 @@ typedef struct slapi_pblock { + int pb_seq_type; + char *pb_seq_attrname; + char *pb_seq_val; ++ /* dbverify argument */ ++ char *pb_dbverify_dbdir; + /* ldif2db arguments */ + char *pb_ldif_file; + int pb_removedupvals; +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index a8c7a4a..6b04610 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -7289,6 +7289,9 @@ typedef struct slapi_plugindesc { + /* ACI Target Check */ + #define SLAPI_ACI_TARGET_CHECK 1946 + ++/* dbverify */ ++#define SLAPI_DBVERIFY_DBDIR 1947 ++ + /* convenience macros for checking modify operation types */ + #define SLAPI_IS_MOD_ADD(x) (((x) & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD) + #define SLAPI_IS_MOD_DELETE(x) (((x) & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE) +diff --git a/man/man8/dbverify.8 b/man/man8/dbverify.8 +index 30d6933..c74747a 100644 +--- a/man/man8/dbverify.8 ++++ b/man/man8/dbverify.8 +@@ -31,6 +31,9 @@ one instance on the system, this option can be skipped. + .B \fB\-n\fR \fIBackend Name\fR + The name of the LDBM database to reindex. Example: userRoot + .TP ++.B \fB\-a\fR \fIDatabase Directory\fR ++Location of database if it is different than what is in the server configuration(e.g. backup directories) ++.TP + .B \fB\-d\fR \fIDebug Level\fR + Sets the debugging level. + .TP +-- +1.9.3 + diff --git a/SOURCES/0035-Ticket-48215-update-dbverify-usage.patch b/SOURCES/0035-Ticket-48215-update-dbverify-usage.patch new file mode 100644 index 0000000..b0931eb --- /dev/null +++ b/SOURCES/0035-Ticket-48215-update-dbverify-usage.patch @@ -0,0 +1,45 @@ +From 4fdac66777dd780bd1e46d91bf38513832934695 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 6 Aug 2015 10:13:40 -0400 +Subject: [PATCH 35/39] Ticket 48215 - update dbverify usage + +Description: Need to add the "-a" argument usage + +https://fedorahosted.org/389/ticket/48215 +(cherry picked from commit 20284e6539f557efc0679d974d5156cdcd55c407) +(cherry picked from commit 8e08c8b53641d807b63d87ee79564c596c5da4dd) +--- + ldap/admin/src/scripts/dbverify.in | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/ldap/admin/src/scripts/dbverify.in b/ldap/admin/src/scripts/dbverify.in +index 778a9ba..461cc16 100755 +--- a/ldap/admin/src/scripts/dbverify.in ++++ b/ldap/admin/src/scripts/dbverify.in +@@ -14,15 +14,16 @@ PATH=$PATH:/bin + + usage() + { +- echo "Usage: dbverify [-Z serverID] [-n backend_instance] [-V] [-v] [-d debuglevel] [-h]" ++ echo "Usage: dbverify [-Z serverID] [-n backend_instance] [-a db_directory ] [-V] [-v] [-d debuglevel] [-h]" + echo "Note if \"-n backend\" is not passed, verify all DBs." + echo "Options:" +- echo " -Z - Server instance identifier" +- echo " -n backend - Backend database name. Example: userRoot" +- echo " -V - Verbose output" +- echo " -d debuglevel - Debugging level" +- echo " -v - Display version" +- echo " -h - Display usage" ++ echo " -Z - Server instance identifier" ++ echo " -n backend - Backend database name. Example: userRoot" ++ echo " -a db_directory - Database directory" ++ echo " -V - Verbose output" ++ echo " -d debuglevel - Debugging level" ++ echo " -v - Display version" ++ echo " -h - Display usage" + } + + display_version="no" +-- +1.9.3 + diff --git a/SOURCES/0035-fix-jenkins-warning.patch b/SOURCES/0035-fix-jenkins-warning.patch deleted file mode 100644 index c65e3ff..0000000 --- a/SOURCES/0035-fix-jenkins-warning.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 841e1bb9dc9ae1e5ab0897a339f647baaf51524e Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Wed, 17 Dec 2014 19:54:33 +0100 -Subject: [PATCH 35/53] fix jenkins warning - -(cherry picked from commit 4760dc6c66249a793c8485a23c147954265f6fd3) ---- - ldap/servers/plugins/memberof/memberof.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index 80b52ab..ce48f01 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -921,7 +921,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - } - if(ret == LDAP_SUCCESS) { - memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; -- if(ret = memberof_del_dn_type_callback(post_e, &del_data)){ -+ if((ret = memberof_del_dn_type_callback(post_e, &del_data))){ - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, - "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", - slapi_entry_get_dn(post_e), ret); --- -1.9.3 - diff --git a/SOURCES/0036-Ticket-47950-Bind-DN-tracking-unable-to-write-to-int.patch b/SOURCES/0036-Ticket-47950-Bind-DN-tracking-unable-to-write-to-int.patch deleted file mode 100644 index 943ed9a..0000000 --- a/SOURCES/0036-Ticket-47950-Bind-DN-tracking-unable-to-write-to-int.patch +++ /dev/null @@ -1,534 +0,0 @@ -From 7ad3f7283e41f3d690626db5b38a9fb63fa8e005 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 18 Nov 2014 09:24:21 -0500 -Subject: [PATCH 36/53] Ticket 47950 - Bind DN tracking unable to write to - internalModifiersName without special permissions - -Bug Description: When a non-rootDN entry makes an update when plugin bind dn tracking - is enabled, it is incorrectly rejected with an error 50. - -Fix Description: Create a function to check if an attribute is one of last mod attributes, - including the internalModfieresname/internalModifytimestamp. Use this - new function wherever we are checking for last mod attributes. - -https://fedorahosted.org/389/ticket/47950 - -Reviewed by: rmeggins(Thanks!) - -(cherry picked from commit c973e7150cf1e7fb3f61a76cf1baf3c0fa91f756) -(cherry picked from commit fa8f7dc3d1ab508c762fc2e18de0cb860ed84657) ---- - dirsrvtests/tickets/ticket47950_test.py | 273 +++++++++++++++++++++ - ldap/servers/plugins/acl/acl.c | 4 +- - ldap/servers/plugins/replication/cl5_config.c | 9 +- - ldap/servers/plugins/replication/repl5_agmtlist.c | 3 +- - .../plugins/replication/repl5_replica_config.c | 3 +- - ldap/servers/slapd/add.c | 4 +- - ldap/servers/slapd/back-ldbm/ldbm_config.c | 3 +- - ldap/servers/slapd/configdse.c | 5 +- - ldap/servers/slapd/opshared.c | 17 ++ - ldap/servers/slapd/result.c | 2 + - ldap/servers/slapd/slapi-plugin.h | 2 + - ldap/servers/slapd/task.c | 4 +- - ldap/servers/slapd/tools/mmldif.c | 12 +- - 13 files changed, 309 insertions(+), 32 deletions(-) - create mode 100644 dirsrvtests/tickets/ticket47950_test.py - -diff --git a/dirsrvtests/tickets/ticket47950_test.py b/dirsrvtests/tickets/ticket47950_test.py -new file mode 100644 -index 0000000..976f964 ---- /dev/null -+++ b/dirsrvtests/tickets/ticket47950_test.py -@@ -0,0 +1,273 @@ -+import os -+import sys -+import time -+import ldap -+import logging -+import socket -+import pytest -+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 constants import * -+ -+log = logging.getLogger(__name__) -+ -+installation_prefix = None -+ -+USER1_DN = "uid=user1,%s" % DEFAULT_SUFFIX -+USER2_DN = "uid=user2,%s" % DEFAULT_SUFFIX -+ -+ -+class TopologyStandalone(object): -+ def __init__(self, standalone): -+ standalone.open() -+ self.standalone = standalone -+ -+ -+@pytest.fixture(scope="module") -+def topology(request): -+ ''' -+ This fixture is used to standalone topology for the 'module'. -+ At the beginning, It may exists a standalone instance. -+ It may also exists a backup for the standalone instance. -+ -+ Principle: -+ If standalone instance exists: -+ restart it -+ If backup of standalone exists: -+ create/rebind to standalone -+ -+ restore standalone instance from backup -+ else: -+ Cleanup everything -+ remove instance -+ remove backup -+ Create instance -+ Create backup -+ ''' -+ global installation_prefix -+ -+ if installation_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation_prefix -+ -+ standalone = DirSrv(verbose=False) -+ -+ # Args for the standalone instance -+ args_instance[SER_HOST] = HOST_STANDALONE -+ args_instance[SER_PORT] = PORT_STANDALONE -+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE -+ args_standalone = args_instance.copy() -+ standalone.allocate(args_standalone) -+ -+ # Get the status of the backups -+ backup_standalone = standalone.checkBackupFS() -+ -+ # Get the status of the instance and restart it if it exists -+ instance_standalone = standalone.exists() -+ if instance_standalone: -+ # assuming the instance is already stopped, just wait 5 sec max -+ standalone.stop(timeout=5) -+ standalone.start(timeout=10) -+ -+ if backup_standalone: -+ # The backup exist, assuming it is correct -+ # we just re-init the instance with it -+ if not instance_standalone: -+ standalone.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # restore standalone instance from backup -+ standalone.stop(timeout=10) -+ standalone.restoreFS(backup_standalone) -+ standalone.start(timeout=10) -+ -+ else: -+ # We should be here only in two conditions -+ # - This is the first time a test involve standalone instance -+ # - Something weird happened (instance/backup destroyed) -+ # so we discard everything and recreate all -+ -+ # Remove the backup. So even if we have a specific backup file -+ # (e.g backup_standalone) we clear backup that an instance may have created -+ if backup_standalone: -+ standalone.clearBackupFS() -+ -+ # Remove the instance -+ if instance_standalone: -+ standalone.delete() -+ -+ # Create the instance -+ standalone.create() -+ -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # Time to create the backups -+ standalone.stop(timeout=10) -+ standalone.backupfile = standalone.backupFS() -+ standalone.start(timeout=10) -+ -+ # clear the tmp directory -+ standalone.clearTmpDir(__file__) -+ -+ # -+ # Here we have standalone instance up and running -+ # Either coming from a backup recovery -+ # or from a fresh (re)init -+ # Time to return the topology -+ return TopologyStandalone(standalone) -+ -+ -+def test_ticket47950(topology): -+ """ -+ Testing nsslapd-plugin-binddn-tracking does not cause issues around -+ access control and reconfiguring replication/repl agmt. -+ """ -+ -+ log.info('Testing Ticket 47950 - Testing nsslapd-plugin-binddn-tracking') -+ -+ # -+ # Turn on bind dn tracking -+ # -+ try: -+ topology.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-plugin-binddn-tracking', 'on')]) -+ log.info('nsslapd-plugin-binddn-tracking enabled.') -+ except ldap.LDAPError, e: -+ log.error('Failed to enable bind dn tracking: ' + e.message['desc']) -+ assert False -+ -+ # -+ # Add two users -+ # -+ try: -+ topology.standalone.add_s(Entry((USER1_DN, { -+ 'objectclass': "top person inetuser".split(), -+ 'userpassword': "password", -+ 'sn': "1", -+ 'cn': "user 1"}))) -+ log.info('Added test user %s' % USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('Failed to add %s: %s' % (USER1_DN, e.message['desc'])) -+ assert False -+ -+ try: -+ topology.standalone.add_s(Entry((USER2_DN, { -+ 'objectclass': "top person inetuser".split(), -+ 'sn': "2", -+ 'cn': "user 2"}))) -+ log.info('Added test user %s' % USER2_DN) -+ except ldap.LDAPError, e: -+ log.error('Failed to add user1: ' + e.message['desc']) -+ assert False -+ -+ # -+ # Add an aci -+ # -+ try: -+ acival = '(targetattr ="cn")(version 3.0;acl "Test bind dn tracking"' + \ -+ ';allow (all) (userdn = "ldap:///%s");)' % USER1_DN -+ -+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', acival)]) -+ log.info('Added aci') -+ except ldap.LDAPError, e: -+ log.error('Failed to add aci: ' + e.message['desc']) -+ assert False -+ -+ # -+ # Make modification as user -+ # -+ try: -+ topology.standalone.simple_bind_s(USER1_DN, "password") -+ log.info('Bind as user %s successful' % USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('Failed to bind as user1: ' + e.message['desc']) -+ assert False -+ -+ try: -+ topology.standalone.modify_s(USER2_DN, [(ldap.MOD_REPLACE, 'cn', 'new value')]) -+ log.info('%s successfully modified user %s' % (USER1_DN, USER2_DN)) -+ except ldap.LDAPError, e: -+ log.error('Failed to update user2: ' + e.message['desc']) -+ assert False -+ -+ # -+ # Setup replica and create a repl agmt -+ # -+ try: -+ topology.standalone.simple_bind_s(DN_DM, PASSWORD) -+ log.info('Bind as %s successful' % DN_DM) -+ except ldap.LDAPError, e: -+ log.error('Failed to bind as rootDN: ' + e.message['desc']) -+ assert False -+ -+ try: -+ topology.standalone.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER, -+ replicaId=REPLICAID_MASTER) -+ log.info('Successfully enabled replication.') -+ except ValueError: -+ log.error('Failed to enable replication') -+ assert False -+ -+ properties = {RA_NAME: r'test plugin internal bind dn', -+ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], -+ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], -+ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], -+ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} -+ -+ try: -+ repl_agreement = topology.standalone.agreement.create(suffix=DEFAULT_SUFFIX, host="127.0.0.1", -+ port="7777", properties=properties) -+ log.info('Successfully created replication agreement') -+ except InvalidArgumentError, e: -+ log.error('Failed to create replication agreement: ' + e.message['desc']) -+ assert False -+ -+ # -+ # modify replica -+ # -+ try: -+ properties = {REPLICA_ID: "7"} -+ topology.standalone.replica.setProperties(DEFAULT_SUFFIX, None, None, properties) -+ log.info('Successfully modified replica') -+ except ldap.LDAPError, e: -+ log.error('Failed to update replica config: ' + e.message['desc']) -+ assert False -+ -+ # -+ # modify repl agmt -+ # -+ try: -+ properties = {RA_CONSUMER_PORT: "8888"} -+ topology.standalone.agreement.setProperties(None, repl_agreement, None, properties) -+ log.info('Successfully modified replication agreement') -+ except ValueError: -+ log.error('Failed to update replica agreement: ' + repl_agreement) -+ assert False -+ -+ # We passed -+ log.info("Test Passed.") -+ -+ -+def test_ticket47953_final(topology): -+ topology.standalone.stop(timeout=10) -+ -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - edit this file and comment '@pytest.fixture' line before 'topology' function. -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation_prefix -+ installation_prefix = None -+ -+ topo = topology(True) -+ test_ticket47950(topo) -+ -+if __name__ == '__main__': -+ run_isolated() -\ No newline at end of file -diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c -index 5416330..403c5b3 100644 ---- a/ldap/servers/plugins/acl/acl.c -+++ b/ldap/servers/plugins/acl/acl.c -@@ -1450,9 +1450,7 @@ acl_check_mods( - if (be != NULL) - slapi_pblock_get ( pb, SLAPI_BE_LASTMOD, &lastmod ); - } -- if (lastmod && -- (strcmp (mod->mod_type, "modifiersname")== 0 || -- strcmp (mod->mod_type, "modifytimestamp")== 0)) { -+ if (lastmod && slapi_attr_is_last_mod(mod->mod_type)) { - /* skip pseudo attr(s) */ - continue; - } -diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c -index 55727c2..a3a0fb3 100644 ---- a/ldap/servers/plugins/replication/cl5_config.c -+++ b/ldap/servers/plugins/replication/cl5_config.c -@@ -357,15 +357,10 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr - config_attr = (char *) mods[i]->mod_type; - config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val; - --#define ATTR_MODIFIERSNAME "modifiersname" --#define ATTR_MODIFYTIMESTAMP "modifytimestamp" -- -- if ( strcasecmp ( config_attr, ATTR_MODIFIERSNAME ) == 0 ) { -- continue; -- } -- if ( strcasecmp ( config_attr, ATTR_MODIFYTIMESTAMP ) == 0 ) { -+ if ( slapi_attr_is_last_mod(config_attr)){ - continue; - } -+ - /* replace existing value */ - if ( strcasecmp (config_attr, CONFIG_CHANGELOG_DIR_ATTRIBUTE ) == 0 ) - { -diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c -index 5eead07..4a1ff5d 100644 ---- a/ldap/servers/plugins/replication/repl5_agmtlist.c -+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c -@@ -524,8 +524,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry - repl5_set_debug_timeout(val); - slapi_ch_free_string(&val); - } -- else if (strcasecmp (mods[i]->mod_type, "modifytimestamp") == 0 || -- strcasecmp (mods[i]->mod_type, "modifiersname") == 0 || -+ else if (slapi_attr_is_last_mod(mods[i]->mod_type) || - strcasecmp (mods[i]->mod_type, "description") == 0) - { - /* ignore modifier's name and timestamp attributes and the description. */ -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 2810b11..3bc3916 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -534,8 +534,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - } - } - /* ignore modifiers attributes added by the server */ -- else if (strcasecmp (config_attr, "modifytimestamp") == 0 || -- strcasecmp (config_attr, "modifiersname") == 0) -+ else if (slapi_attr_is_last_mod(config_attr)) - { - *returncode = LDAP_SUCCESS; - } -diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c -index 875ad22..28fae32 100644 ---- a/ldap/servers/slapd/add.c -+++ b/ldap/servers/slapd/add.c -@@ -911,8 +911,8 @@ static int check_rdn_for_created_attrs(Slapi_Entry *e) - int i, rc = 0; - Slapi_RDN *rdn = NULL; - char *value = NULL; -- char *type[] = {SLAPI_ATTR_UNIQUEID, "modifytimestamp", "createtimestamp", -- "creatorsname", "modifiersname", 0}; -+ char *type[] = {SLAPI_ATTR_UNIQUEID, "modifytimestamp", "modifiersname", "internalmodifytimestamp", -+ "internalmodifiersname", "createtimestamp", "creatorsname", 0}; - - if ((rdn = slapi_rdn_new())) { - slapi_rdn_init_dn(rdn, slapi_entry_get_dn_const(e)); -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c -index 0f8cc76..294999c 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_config.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c -@@ -1849,10 +1849,9 @@ int ldbm_config_ignored_attr(char *attr_name) - if (!strcasecmp("objectclass", attr_name) || - !strcasecmp("cn", attr_name) || - !strcasecmp("creatorsname", attr_name) || -- !strcasecmp("modifiersname", attr_name) || - !strcasecmp("createtimestamp", attr_name) || - !strcasecmp(LDBM_NUMSUBORDINATES_STR, attr_name) || -- !strcasecmp("modifytimestamp", attr_name)) { -+ slapi_attr_is_last_mod(attr_name)){ - return 1; - } else { - return 0; -diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c -index 339be42..e70e340 100644 ---- a/ldap/servers/slapd/configdse.c -+++ b/ldap/servers/slapd/configdse.c -@@ -116,10 +116,9 @@ ignore_attr_type(const char *attr_type) - (strcasecmp (attr_type, "aci") == 0) || - (strcasecmp (attr_type, "objectclass") == 0) || - (strcasecmp (attr_type, "numsubordinates") == 0) || -- (strcasecmp (attr_type, "internalModifiersname") == 0) || - (strcasecmp (attr_type, "internalCreatorsname") == 0) || -- (strcasecmp (attr_type, "modifytimestamp") == 0) || -- (strcasecmp (attr_type, "modifiersname") == 0)) { -+ slapi_attr_is_last_mod((char *)attr_type)) -+ { - return 1; - } - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 4e06652..ebd4fdf 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -218,6 +218,23 @@ modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods) - } - - /* -+ * If the attribute is one of the last mod attributes return 1, -+ * otherwise return 0; -+ */ -+int -+slapi_attr_is_last_mod(char *attr) -+{ -+ if(strcasecmp (attr, "modifytimestamp") == 0 || -+ strcasecmp (attr, "modifiersname") == 0 || -+ strcasecmp (attr, "internalmodifytimestamp") == 0 || -+ strcasecmp (attr, "internalmodifiersname") == 0) -+ { -+ return 1; -+ } -+ return 0; -+} -+ -+/* - * Returns: 0 - if the operation is successful - * < 0 - if operation fails. - * Note that an operation is considered "failed" if a result is sent -diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c -index 92573d5..ca2fa43 100644 ---- a/ldap/servers/slapd/result.c -+++ b/ldap/servers/slapd/result.c -@@ -1059,6 +1059,8 @@ encode_attr( - - #define LASTMODATTR( x ) (strcasecmp( x, "modifytimestamp" ) == 0 \ - || strcasecmp( x, "modifiersname" ) == 0 \ -+ || strcasecmp( x, "internalmodifytimestamp" ) == 0 \ -+ || strcasecmp( x, "internalmodifiersname" ) == 0 \ - || strcasecmp( x, "createtimestamp" ) == 0 \ - || strcasecmp( x, "creatorsname" ) == 0) - -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index f1ecfe8..8ffc582 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -5278,6 +5278,8 @@ int slapi_filter_compare(struct slapi_filter *f1, struct slapi_filter *f2); - Slapi_Filter *slapi_filter_dup(Slapi_Filter *f); - int slapi_filter_changetype(Slapi_Filter *f, const char *newtype); - -+int slapi_attr_is_last_mod(char *attr); -+ - /** - * Normalize in-place the given filter. Normalizes the attribute types always. - * If norm_values is true, will also normalize the values. -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index a4d85a8..2a0cb82 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -802,8 +802,8 @@ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e, - * stuck in by the server */ - if ((strcasecmp(mods[i]->mod_type, "ttl") != 0) && - (strcasecmp(mods[i]->mod_type, "nsTaskCancel") != 0) && -- (strcasecmp(mods[i]->mod_type, "modifiersName") != 0) && -- (strcasecmp(mods[i]->mod_type, "modifyTimestamp") != 0)) { -+ !slapi_attr_is_last_mod(mods[i]->mod_type)) -+ { - /* you aren't allowed to change this! */ - *returncode = LDAP_UNWILLING_TO_PERFORM; - return SLAPI_DSE_CALLBACK_ERROR; -diff --git a/ldap/servers/slapd/tools/mmldif.c b/ldap/servers/slapd/tools/mmldif.c -index bf20945..156d892 100644 ---- a/ldap/servers/slapd/tools/mmldif.c -+++ b/ldap/servers/slapd/tools/mmldif.c -@@ -1009,9 +1009,7 @@ addnew(FILE * edf3, const char *changetype, record_t * first) - for (attnum = 1, att = &first->data; - attnum <= first->nattrs; - attnum++, att = attribnext(att)) { -- if (!stricmp(attribname(att), "modifytimestamp")) -- continue; -- if (!stricmp(attribname(att), "modifiersname")) -+ if (slapi_attr_is_last_mod(attribname(att))) - continue; - if (!putvalue(edf3, NULL, attribname(att), att->namelen, - attribvalue(att), att->valuelen)) { -@@ -1066,15 +1064,11 @@ addmodified(FILE * edf3, attrib1_t * attrib, record_t * first) - */ - while (a != NULL || num_b <= tot_b) { - /* ignore operational attrs */ -- if (num_b <= tot_b && -- (stricmp(attribname(b), "modifytimestamp") == 0 || -- stricmp(attribname(b), "modifiersname") == 0)) { -+ if ( num_b <= tot_b && slapi_attr_is_last_mod(attribname(b)) ){ - b = attribnext(b); num_b++; - continue; - } -- if (a != NULL && -- (stricmp(a->name, "modifytimestamp") == 0 || -- stricmp(a->name, "modifiersname") == 0)) { -+ if (a != NULL && slapi_attr_is_last_mod(a->name)) { - a = a->next; - continue; - } --- -1.9.3 - diff --git a/SOURCES/0036-Ticket-48215-update-dbverify-usage-in-main.c.patch b/SOURCES/0036-Ticket-48215-update-dbverify-usage-in-main.c.patch new file mode 100644 index 0000000..82f9189 --- /dev/null +++ b/SOURCES/0036-Ticket-48215-update-dbverify-usage-in-main.c.patch @@ -0,0 +1,30 @@ +From 5e348707ba4bece4ad4c75a8b640f1c40cbbaa0e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 6 Aug 2015 11:27:40 -0400 +Subject: [PATCH 36/39] Ticket 48215 - update dbverify usage in main.c + +Description: Need to update dbverify usage in main.c + +https://fedorahosted.org/389/ticket/48215 +(cherry picked from commit c1912cdcac8319e2fe0f98f765aa935e6a8ff297) +(cherry picked from commit c842dbe3d0ee2ac28c55e31b9b8e5e5a3c5dc200) +--- + ldap/servers/slapd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c +index 922de97..4f9fbfe 100644 +--- a/ldap/servers/slapd/main.c ++++ b/ldap/servers/slapd/main.c +@@ -398,7 +398,7 @@ usage( char *name, char *extraname ) + usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-N] -n backend-instance-name -a fullpath-backend-instance-dir-full\n"; + break; + case SLAPD_EXEMODE_DBVERIFY: +- usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-n backend-instance-name]\n"; ++ usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-n backend-instance-name] [-a db-directory]\n"; + break; + + default: /* SLAPD_EXEMODE_SLAPD */ +-- +1.9.3 + diff --git a/SOURCES/0037-Ticket-47949-logconv.pl-support-parsing-showing-repo.patch b/SOURCES/0037-Ticket-47949-logconv.pl-support-parsing-showing-repo.patch deleted file mode 100644 index 11ba18e..0000000 --- a/SOURCES/0037-Ticket-47949-logconv.pl-support-parsing-showing-repo.patch +++ /dev/null @@ -1,141 +0,0 @@ -From b4a38681279529caab2c221ed19ead5636c41071 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 5 Dec 2014 15:42:45 -0500 -Subject: [PATCH 37/53] Ticket 47949 - logconv.pl -- support - parsing/showing/reporting different protocol versions - -Description: Update script to report on the secure protocol versions that are now available - in the access log. - - Also, revised the connection section output, cleaned up the SASL bind report, - and handled issue with log(s) that only span 1 second(0 elapsed time) - -https://fedorahosted.org/389/ticket/47949 - -Reviewed by: nhosoi & rmeggins(Thanks!!) - -(cherry picked from commit 7aeeb7c968a03f4a75c8338ffbd7cbbaa73e102d) -(cherry picked from commit 8b7ae6d930927171c7976fe9093f2f765714c8ac) ---- - ldap/admin/src/logconv.pl | 69 ++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 53 insertions(+), 16 deletions(-) - -diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl -index 0611755..e4bbfbc 100755 ---- a/ldap/admin/src/logconv.pl -+++ b/ldap/admin/src/logconv.pl -@@ -69,7 +69,7 @@ if ($#ARGV < 0){; - - my $file_count = 0; - my $arg_count = 0; --my $logversion = "8.0"; -+my $logversion = "8.1"; - my $sizeCount = "20"; - my $startFlag = 0; - my $startTime = 0; -@@ -262,7 +262,14 @@ my $startTLSCount = 0; - my $ldapiCount = 0; - my $autobindCount = 0; - my $limit = 25000; # number of lines processed to trigger output -- -+my $searchStat; -+my $modStat; -+my $addStat; -+my $deleteStat; -+my $modrdnStat; -+my $compareStat; -+my $bindCountStat; -+my %cipher = (); - my @removefiles = (); - - my @conncodes = qw(A1 B1 B4 T1 T2 B2 B3 R1 P1 P2 U1); -@@ -680,27 +687,45 @@ if($reportStats ne ""){ - - print "Restarts: $serverRestartCount\n"; - print "Total Connections: $connectionCount\n"; --print " - StartTLS Connections: $startTLSCount\n"; --print " - LDAPS Connections: $sslCount\n"; -+print " - LDAP Connections: " . ($connectionCount - $sslCount - $ldapiCount) . "\n"; - print " - LDAPI Connections: $ldapiCount\n"; -+print " - LDAPS Connections: $sslCount\n"; -+print " - StartTLS Extended Ops: $startTLSCount\n"; -+if(%cipher){ -+ print " Secure Protocol Versions:\n"; -+ foreach my $key (sort { $b cmp $a } keys %cipher) { -+ print " - $key - $cipher{$key}\n"; -+ } -+ print "\n"; -+} -+ - print "Peak Concurrent Connections: $maxsimConnection\n"; - print "Total Operations: $allOps\n"; - print "Total Results: $allResults\n"; - my ($perf, $tmp); - if ($allOps ne "0"){ -- print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ; -- } --else { -- print "Overall Performance: No Operations to evaluate\n\n"; -+ print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ; -+} else { -+ print "Overall Performance: No Operations to evaluate\n\n"; - } - --my $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60); --my $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60); --my $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60); --my $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60); --my $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60); --my $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60); --my $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60); -+if ($totalTimeInSecs == 0){ -+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0"; -+} else { -+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60); -+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60); -+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60); -+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60); -+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60); -+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60); -+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60); -+} - - format STDOUT = - Searches: @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -@@ -973,7 +998,7 @@ print " - SASL Binds: $saslBindCount\n"; - if ($saslBindCount > 0){ - my $saslmech = $hashes->{saslmech}; - foreach my $saslb ( sort {$saslmech->{$b} <=> $saslmech->{$a} } (keys %{$saslmech}) ){ -- printf " %-4s %-12s\n",$saslmech->{$saslb}, $saslb; -+ printf " %-4s - %s\n",$saslb, $saslmech->{$saslb}; - } - } - -@@ -1908,6 +1933,18 @@ sub parseLineNormal - handleRestart(); - } - if (m/ SSL connection from/){$sslCount++; if($reportStats){ inc_stats('sslconns',$s_stats,$m_stats); }} -+ # Gather TLS and SSL version info -+ if ($_ =~ /conn= *([0-9A-Z]+) TLS *(.*)/){ -+ $cipher{"TLS" . $2}++; -+ } -+ if ($_ =~ /conn= *([0-9A-Z]+) SSL *(.*)/){ -+ my $sslversion = $2; -+ if(/SSL /){ -+ $cipher{"SSL " . $sslversion}++; -+ } else { -+ $cipher{"SSL" . $sslversion}++; -+ } -+ } - if (m/ connection from local to /){$ldapiCount++;} - if($_ =~ /AUTOBIND dn=\"(.*)\"/){ - $autobindCount++; --- -1.9.3 - diff --git a/SOURCES/0037-Ticket-48228-wrong-password-check-if-passwordInHisto.patch b/SOURCES/0037-Ticket-48228-wrong-password-check-if-passwordInHisto.patch new file mode 100644 index 0000000..7e4a3ba --- /dev/null +++ b/SOURCES/0037-Ticket-48228-wrong-password-check-if-passwordInHisto.patch @@ -0,0 +1,309 @@ +From a3d41922c0f211aa7602fb843f7cb4980f4bf285 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Mon, 3 Aug 2015 18:49:58 -0700 +Subject: [PATCH 37/39] Ticket #48228 - wrong password check if + passwordInHistory is decreased. + +Bug Description: When N passwords to be remembered (passwordInHistroy) +and N passwords are remembered, decreasing the passwordInHistory value +to M (< N) does not allow to use the oldest password which should have +been discarded from the history and should be allowed. + +Fix Description: Before checking if the password is in the history or +not, adding a check the passwordInHistory value (M) is less than the +count of passwords remembered (N). If M < N, discard the (N-M) oldest +passwords. + +https://fedorahosted.org/389/ticket/48228 + +Reviewed by mreynolds@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 1a119125856006543aae0520b5800a8b52c3b049) +(cherry picked from commit dd85ee9c9ac24f1b141dd806943de236d2e44c90) +--- + ldap/servers/slapd/pw.c | 193 ++++++++++++++++++++++++++++-------------------- + 1 file changed, 114 insertions(+), 79 deletions(-) + +diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c +index f883010..3abebbf 100644 +--- a/ldap/servers/slapd/pw.c ++++ b/ldap/servers/slapd/pw.c +@@ -613,7 +613,7 @@ update_pw_info ( Slapi_PBlock *pb , char *old_pw) + + /* update passwordHistory */ + if ( old_pw != NULL && pwpolicy->pw_history == 1 ) { +- update_pw_history(pb, sdn, old_pw); ++ (void)update_pw_history(pb, sdn, old_pw); + slapi_ch_free ( (void**)&old_pw ); + } + +@@ -654,8 +654,7 @@ update_pw_info ( Slapi_PBlock *pb , char *old_pw) + */ + if ((internal_op && pwpolicy->pw_must_change && (!pb->pb_conn || strcasecmp(target_dn, pb->pb_conn->c_dn))) || + (!internal_op && pwpolicy->pw_must_change && +- ((target_dn && bind_dn && strcasecmp(target_dn, bind_dn)) && pw_is_pwp_admin(pb, pwpolicy)))) +- { ++ ((target_dn && bind_dn && strcasecmp(target_dn, bind_dn)) && pw_is_pwp_admin(pb, pwpolicy)))) { + pw_exp_date = NO_TIME; + } else if ( pwpolicy->pw_exp == 1 ) { + Slapi_Entry *pse = NULL; +@@ -996,6 +995,7 @@ check_pw_syntax_ext ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, + + /* get the entry and check for the password history if this is called by a modify operation */ + if ( mod_op ) { ++retry: + /* retrieve the entry */ + e = get_entry ( pb, dn ); + if ( e == NULL ) { +@@ -1004,19 +1004,21 @@ check_pw_syntax_ext ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, + + /* check for password history */ + if ( pwpolicy->pw_history == 1 ) { ++ Slapi_Value **va = NULL; + attr = attrlist_find(e->e_attrs, "passwordHistory"); +- if (attr && +- !valueset_isempty(&attr->a_present_values)) +- { +- Slapi_Value **va= attr_get_present_values(attr); ++ if (attr && !valueset_isempty(&attr->a_present_values)) { ++ /* Resetting password history array if necessary. */ ++ if (0 == update_pw_history(pb, sdn, NULL)) { ++ /* There was an update in the password history. Retry... */ ++ slapi_entry_free(e); ++ goto retry; ++ } ++ va = attr_get_present_values(attr); + if ( pw_in_history( va, vals[0] ) == 0 ) { + if ( pwresponse_req == 1 ) { +- slapi_pwpolicy_make_response_control ( pb, -1, -1, +- LDAP_PWPOLICY_PWDINHISTORY ); ++ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDINHISTORY); + } +- pw_send_ldap_result ( pb, +- LDAP_CONSTRAINT_VIOLATION, NULL, +- "password in history", 0, NULL ); ++ pw_send_ldap_result(pb, LDAP_CONSTRAINT_VIOLATION, NULL, "password in history", 0, NULL); + slapi_entry_free( e ); + return ( 1 ); + } +@@ -1024,26 +1026,17 @@ check_pw_syntax_ext ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, + + /* get current password. check it and remember it */ + attr = attrlist_find(e->e_attrs, "userpassword"); +- if (attr && !valueset_isempty(&attr->a_present_values)) +- { +- Slapi_Value **va= valueset_get_valuearray(&attr->a_present_values); +- if (slapi_is_encoded((char*)slapi_value_get_string(vals[0]))) +- { +- if (slapi_attr_value_find(attr, (struct berval *)slapi_value_get_berval(vals[0])) == 0 ) +- { +- pw_send_ldap_result ( pb, +- LDAP_CONSTRAINT_VIOLATION ,NULL, +- "password in history", 0, NULL); ++ if (attr && !valueset_isempty(&attr->a_present_values)) { ++ va = valueset_get_valuearray(&attr->a_present_values); ++ if (slapi_is_encoded((char*)slapi_value_get_string(vals[0]))) { ++ if (slapi_attr_value_find(attr, (struct berval *)slapi_value_get_berval(vals[0])) == 0 ) { ++ pw_send_ldap_result(pb, LDAP_CONSTRAINT_VIOLATION, NULL, "password in history", 0, NULL); + slapi_entry_free( e ); + return ( 1 ); + } +- } else +- { +- if ( slapi_pw_find_sv ( va, vals[0] ) == 0 ) +- { +- pw_send_ldap_result ( pb, +- LDAP_CONSTRAINT_VIOLATION ,NULL, +- "password in history", 0, NULL); ++ } else { ++ if ( slapi_pw_find_sv ( va, vals[0] ) == 0 ) { ++ pw_send_ldap_result(pb, LDAP_CONSTRAINT_VIOLATION, NULL, "password in history", 0, NULL); + slapi_entry_free( e ); + return ( 1 ); + } +@@ -1086,68 +1079,112 @@ check_pw_syntax_ext ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, + + } + ++/* ++ * Basically, h0 and h1 must be longer than GENERALIZED_TIME_LENGTH. ++ */ ++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; ++ } else { ++ return -1; ++ } ++ } else { ++ 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) { ++ /* too short for the history str. */ ++ return 0; ++ } ++ } ++ } ++ return PL_strncmp(h0, h1, GENERALIZED_TIME_LENGTH); ++} ++ ++ + static int + update_pw_history( Slapi_PBlock *pb, const Slapi_DN *sdn, char *old_pw ) + { +- time_t t, old_t, cur_time; +- int i = 0, oldest = 0; +- int res; +- Slapi_Entry *e; +- Slapi_Attr *attr; ++ time_t cur_time; ++ int res = 1; /* no update, by default */ ++ Slapi_Entry *e = NULL; + LDAPMod attribute; +- char *values_replace[25]; /* 2-24 passwords in history */ + LDAPMod *list_of_mods[2]; + Slapi_PBlock mod_pb; +- char *history_str; +- char *str; ++ char *str = NULL; + passwdPolicy *pwpolicy = NULL; + const char *dn = slapi_sdn_get_dn(sdn); ++ char **values_replace = NULL; ++ int vacnt = 0; ++ int vacnt_todelete = 0; + + pwpolicy = new_passwdPolicy(pb, dn); + + /* retrieve the entry */ + e = get_entry ( pb, dn ); + if ( e == NULL ) { +- return ( 1 ); ++ return res; + } + +- history_str = (char *)slapi_ch_malloc(GENERALIZED_TIME_LENGTH + strlen(old_pw) + 1); +- /* get password history, and find the oldest password in history */ +- cur_time = current_time (); +- old_t = cur_time; +- str = format_genTime ( cur_time ); +- attr = attrlist_find(e->e_attrs, "passwordHistory"); +- if (attr && !valueset_isempty(&attr->a_present_values)) +- { +- Slapi_Value **va= valueset_get_valuearray(&attr->a_present_values); +- for ( i = oldest = 0 ; +- (va[i] != NULL) && (slapi_value_get_length(va[i]) > 0) ; +- i++ ) { +- +- values_replace[i] = (char*)slapi_value_get_string(va[i]); +- strncpy( history_str, values_replace[i], GENERALIZED_TIME_LENGTH); +- history_str[GENERALIZED_TIME_LENGTH] = '\0'; +- if (history_str[GENERALIZED_TIME_LENGTH - 1] != 'Z'){ +- /* The time is not a generalized Time. Probably a password history from 4.x */ +- history_str[GENERALIZED_TIME_LENGTH - 1] = '\0'; +- } +- t = parse_genTime ( history_str ); +- if ( difftime ( t, old_t ) < 0 ) { +- oldest = i; +- old_t = t; +- } ++ /* get password history */ ++ values_replace = slapi_entry_attr_get_charray_ext(e, "passwordHistory", &vacnt); ++ if (old_pw) { ++ /* we have a password to replace with the oldest one in the history. */ ++ if (!values_replace || !vacnt) { /* This is the first one to store */ ++ values_replace = (char **)slapi_ch_calloc(2, sizeof(char *)); + } ++ } else { ++ /* we are checking the history size if it stores more than the current inhistory count. */ ++ if (!values_replace || !vacnt) { /* nothing to revise */ ++ res = 1; ++ goto bail; ++ } ++ /* ++ * If revising the passwords in the passwordHistory values ++ * and the password count in the value array is less than the inhistory, ++ * we have nothing to do. ++ */ ++ if (vacnt <= pwpolicy->pw_inhistory) { ++ res = 1; ++ goto bail; ++ } ++ vacnt_todelete = vacnt - pwpolicy->pw_inhistory; + } +- strcpy ( history_str, str ); +- strcat ( history_str, old_pw ); +- if ( i >= pwpolicy->pw_inhistory ) { +- /* replace the oldest password in history */ +- values_replace[oldest] = history_str; +- values_replace[pwpolicy->pw_inhistory] = NULL; ++ ++ cur_time = current_time(); ++ str = format_genTime(cur_time); ++ /* values_replace is sorted. */ ++ if (old_pw) { ++ if ( vacnt >= pwpolicy->pw_inhistory ) { ++ slapi_ch_free_string(&values_replace[0]); ++ values_replace[0] = slapi_ch_smprintf("%s%s", str, old_pw); ++ } else { ++ /* add old_pw at the end of password history */ ++ values_replace = (char **)slapi_ch_realloc((char *)values_replace, sizeof(char *) * (vacnt + 2)); ++ values_replace[vacnt] = slapi_ch_smprintf("%s%s", str, old_pw); ++ values_replace[vacnt+1] = NULL; ++ } ++ qsort((void *)values_replace, vacnt, (size_t)sizeof(char *), pw_history_cmp); + } else { +- /* add old_pw at the end of password history */ +- values_replace[i] = history_str; +- values_replace[++i]=NULL; ++ int i; ++ /* vacnt > pwpolicy->pw_inhistory */ ++ for (i = 0; i < vacnt_todelete; i++) { ++ slapi_ch_free_string(&values_replace[i]); ++ } ++ memmove(values_replace, values_replace + vacnt_todelete, sizeof(char *) * pwpolicy->pw_inhistory); ++ values_replace[pwpolicy->pw_inhistory] = NULL; + } + + /* modify the attribute */ +@@ -1159,21 +1196,19 @@ update_pw_history( Slapi_PBlock *pb, const Slapi_DN *sdn, char *old_pw ) + list_of_mods[1] = NULL; + + pblock_init(&mod_pb); +- slapi_modify_internal_set_pb_ext(&mod_pb, sdn, list_of_mods, NULL, NULL, +- pw_get_componentID(), 0); ++ slapi_modify_internal_set_pb_ext(&mod_pb, sdn, list_of_mods, NULL, NULL, pw_get_componentID(), 0); + slapi_modify_internal_pb(&mod_pb); + slapi_pblock_get(&mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &res); + if (res != LDAP_SUCCESS){ + LDAPDebug2Args(LDAP_DEBUG_ANY, + "WARNING: passwordPolicy modify error %d on entry '%s'\n", res, dn); + } +- + pblock_done(&mod_pb); +- +- slapi_ch_free((void **) &str ); +- slapi_ch_free((void **) &history_str ); ++ slapi_ch_free_string(&str); ++bail: ++ slapi_ch_array_free(values_replace); + slapi_entry_free( e ); +- return 0; ++ return res; + } + + static +-- +1.9.3 + diff --git a/SOURCES/0038-Ticket-47947-start-dirsrv-after-chrony-on-RHEL7-and-.patch b/SOURCES/0038-Ticket-47947-start-dirsrv-after-chrony-on-RHEL7-and-.patch deleted file mode 100644 index a1134b9..0000000 --- a/SOURCES/0038-Ticket-47947-start-dirsrv-after-chrony-on-RHEL7-and-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 30877169647515a43ae9a1a7a1873e890c7798cc Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 16 Dec 2014 13:42:56 -0800 -Subject: [PATCH 38/53] Ticket #47947 - start dirsrv after chrony on RHEL7 and - Fedora - -Description: After=chronyd.service to systemd.template.service.in, -which is installed as this file: - /usr/lib/systemd/system/dirsrv@.service -and pointed by each server's service file: - /etc/systemd/system/dirsrv.target.wants/dirsrv@YOURID.service - -https://fedorahosted.org/389/ticket/47947 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit c3389a46c584fa39b2278a295f8b2b6dad726d31) -(cherry picked from commit 6e4e21ff010041eb636cc06b23bb3ed0de78ef1d) ---- - wrappers/systemd.template.service.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in -index 42c7c23..9432cb0 100644 ---- a/wrappers/systemd.template.service.in -+++ b/wrappers/systemd.template.service.in -@@ -15,6 +15,7 @@ - [Unit] - Description=@capbrand@ Directory Server %i. - PartOf=@systemdgroupname@ -+After=chronyd.service - - [Service] - Type=forking --- -1.9.3 - diff --git a/SOURCES/0038-Ticket-48228-CI-test-added-test-cases-for-ticket-482.patch b/SOURCES/0038-Ticket-48228-CI-test-added-test-cases-for-ticket-482.patch new file mode 100644 index 0000000..8d833cf --- /dev/null +++ b/SOURCES/0038-Ticket-48228-CI-test-added-test-cases-for-ticket-482.patch @@ -0,0 +1,350 @@ +From 970672905f7ca994f1d0f92e82f4c80484796181 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 5 Aug 2015 14:40:12 -0700 +Subject: [PATCH 38/39] Ticket #48228 - CI test: added test cases for ticket + 48228 + +Description: wrong password check if passwordInHistory is decreased. +(cherry picked from commit 6b138a2091bf7d78f3bc60a13f226a39296e0f4c) +(cherry picked from commit e62b4815f0682845992dc9a4375e1d7c5597bfba) +--- + dirsrvtests/tickets/ticket48228_test.py | 327 ++++++++++++++++++++++++++++++++ + 1 file changed, 327 insertions(+) + create mode 100644 dirsrvtests/tickets/ticket48228_test.py + +diff --git a/dirsrvtests/tickets/ticket48228_test.py b/dirsrvtests/tickets/ticket48228_test.py +new file mode 100644 +index 0000000..e0595bb +--- /dev/null ++++ b/dirsrvtests/tickets/ticket48228_test.py +@@ -0,0 +1,327 @@ ++# --- 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 --- ++# ++import os ++import sys ++import time ++import ldap ++import logging ++import pytest ++from lib389 import DirSrv, Entry, tools, tasks ++from lib389.tools import DirSrvTools ++from lib389._constants import * ++from lib389.properties import * ++from lib389.tasks import * ++ ++log = logging.getLogger(__name__) ++ ++installation_prefix = None ++ ++# Assuming DEFAULT_SUFFIX is "dc=example,dc=com", otherwise it does not work... :( ++SUBTREE_CONTAINER = 'cn=nsPwPolicyContainer,' + DEFAULT_SUFFIX ++SUBTREE_PWPDN = 'cn=nsPwPolicyEntry,' + DEFAULT_SUFFIX ++SUBTREE_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cdc\3Dexample\2Cdc\3Dcom,' + SUBTREE_CONTAINER ++SUBTREE_COS_TMPLDN = 'cn=nsPwTemplateEntry,' + DEFAULT_SUFFIX ++SUBTREE_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cdc\3Dexample\2Cdc\3Dcom,' + SUBTREE_CONTAINER ++SUBTREE_COS_DEF = 'cn=nsPwPolicy_CoS,' + DEFAULT_SUFFIX ++ ++USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX ++USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX ++ ++class TopologyStandalone(object): ++ def __init__(self, standalone): ++ standalone.open() ++ self.standalone = standalone ++ ++ ++@pytest.fixture(scope="module") ++def topology(request): ++ ''' ++ This fixture is used to standalone topology for the 'module'. ++ ''' ++ global installation_prefix ++ ++ if installation_prefix: ++ args_instance[SER_DEPLOYED_DIR] = installation_prefix ++ ++ standalone = DirSrv(verbose=False) ++ ++ # Args for the standalone instance ++ args_instance[SER_HOST] = HOST_STANDALONE ++ args_instance[SER_PORT] = PORT_STANDALONE ++ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE ++ args_standalone = args_instance.copy() ++ standalone.allocate(args_standalone) ++ ++ # Get the status of the instance and restart it if it exists ++ instance_standalone = standalone.exists() ++ ++ # Remove the instance ++ if instance_standalone: ++ standalone.delete() ++ ++ # Create the instance ++ standalone.create() ++ ++ # Used to retrieve configuration information (dbdir, confdir...) ++ standalone.open() ++ ++ # clear the tmp directory ++ standalone.clearTmpDir(__file__) ++ ++ # Here we have standalone instance up and running ++ return TopologyStandalone(standalone) ++ ++def set_global_pwpolicy(topology, inhistory): ++ log.info(" +++++ Enable global password policy +++++\n") ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ # Enable password policy ++ try: ++ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')]) ++ except ldap.LDAPError, e: ++ log.error('Failed to set pwpolicy-local: error ' + e.message['desc']) ++ assert False ++ ++ log.info(" Set global password history on\n") ++ try: ++ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordHistory', 'on')]) ++ except ldap.LDAPError, e: ++ log.error('Failed to set passwordHistory: error ' + e.message['desc']) ++ assert False ++ ++ log.info(" Set global passwords in history\n") ++ try: ++ count = "%d" % inhistory ++ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordInHistory', count)]) ++ except ldap.LDAPError, e: ++ log.error('Failed to set passwordInHistory: error ' + e.message['desc']) ++ assert False ++ ++def set_subtree_pwpolicy(topology): ++ log.info(" +++++ Enable subtree level password policy +++++\n") ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ log.info(" Add the container") ++ try: ++ topology.standalone.add_s(Entry((SUBTREE_CONTAINER, {'objectclass': 'top nsContainer'.split(), ++ 'cn': 'nsPwPolicyContainer'}))) ++ except ldap.LDAPError, e: ++ log.error('Failed to add subtree container: error ' + e.message['desc']) ++ assert False ++ ++ log.info(" Add the password policy subentry {passwordHistory: on, passwordInHistory: 6}") ++ try: ++ topology.standalone.add_s(Entry((SUBTREE_PWP, {'objectclass': 'top ldapsubentry passwordpolicy'.split(), ++ 'cn': SUBTREE_PWPDN, ++ 'passwordMustChange': 'off', ++ 'passwordExp': 'off', ++ 'passwordHistory': 'on', ++ 'passwordInHistory': '6', ++ 'passwordMinAge': '0', ++ 'passwordChange': 'on', ++ 'passwordStorageScheme': 'clear'}))) ++ except ldap.LDAPError, e: ++ log.error('Failed to add passwordpolicy: error ' + e.message['desc']) ++ assert False ++ ++ log.info(" Add the COS template") ++ try: ++ topology.standalone.add_s(Entry((SUBTREE_COS_TMPL, {'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(), ++ 'cn': SUBTREE_PWPDN, ++ 'cosPriority': '1', ++ 'cn': SUBTREE_COS_TMPLDN, ++ 'pwdpolicysubentry': SUBTREE_PWP}))) ++ except ldap.LDAPError, e: ++ log.error('Failed to add COS template: error ' + e.message['desc']) ++ assert False ++ ++ log.info(" Add the COS definition") ++ try: ++ topology.standalone.add_s(Entry((SUBTREE_COS_DEF, {'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(), ++ 'cn': SUBTREE_PWPDN, ++ 'costemplatedn': SUBTREE_COS_TMPL, ++ 'cosAttribute': 'pwdpolicysubentry default operational-default'}))) ++ except ldap.LDAPError, e: ++ log.error('Failed to add COS def: error ' + e.message['desc']) ++ assert False ++ ++def check_passwd_inhistory(topology, user, cpw, passwd): ++ inhistory = 0 ++ log.info(" Bind as {%s,%s}" % (user, cpw)) ++ topology.standalone.simple_bind_s(user, cpw) ++ try: ++ topology.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', passwd)]) ++ except ldap.LDAPError, e: ++ log.info(' The password ' + passwd + ' of user' + USER1_DN + ' in history: error ' + e.message['desc']) ++ inhistory = 1 ++ return inhistory ++ ++def update_passwd(topology, user, passwd, times): ++ cpw = passwd ++ loop = 0 ++ while loop < times: ++ log.info(" Bind as {%s,%s}" % (user, cpw)) ++ topology.standalone.simple_bind_s(user, cpw) ++ cpw = 'password%d' % loop ++ try: ++ topology.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', cpw)]) ++ except ldap.LDAPError, e: ++ log.fatal('test_ticket48228: Failed to update the password ' + cpw + ' of user ' + user + ': error ' + e.message['desc']) ++ assert False ++ loop += 1 ++ ++ # checking the first password, which is supposed to be in history ++ inhistory = check_passwd_inhistory(topology, user, cpw, passwd) ++ assert inhistory == 1 ++ ++def test_ticket48228_test_global_policy(topology): ++ """ ++ Check global password policy ++ """ ++ ++ log.info(' Set inhistory = 6') ++ set_global_pwpolicy(topology, 6) ++ ++ log.info(' Bind as directory manager') ++ log.info("Bind as %s" % DN_DM) ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ ++ log.info(' Add an entry' + USER1_DN) ++ try: ++ topology.standalone.add_s(Entry((USER1_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(), ++ 'sn': '1', ++ 'cn': 'user 1', ++ 'uid': 'user1', ++ 'givenname': 'user', ++ 'mail': 'user1@example.com', ++ 'userpassword': 'password'}))) ++ except ldap.LDAPError, e: ++ log.fatal('test_ticket48228: Failed to add user' + USER1_DN + ': error ' + e.message['desc']) ++ assert False ++ ++ log.info(' Update the password of ' + USER1_DN + ' 6 times') ++ update_passwd(topology, USER1_DN, 'password', 6) ++ ++ log.info(' Set inhistory = 4') ++ set_global_pwpolicy(topology, 4) ++ ++ log.info(' checking the first password, which is supposed NOT to be in history any more') ++ cpw = 'password%d' % 5 ++ tpw = 'password' ++ inhistory = check_passwd_inhistory(topology, USER1_DN, cpw, tpw) ++ assert inhistory == 0 ++ ++ log.info(' checking the second password, which is supposed NOT to be in history any more') ++ cpw = tpw ++ tpw = 'password%d' % 0 ++ inhistory = check_passwd_inhistory(topology, USER1_DN, cpw, tpw) ++ assert inhistory == 0 ++ ++ log.info(' checking the second password, which is supposed NOT to be in history any more') ++ cpw = tpw ++ tpw = 'password%d' % 1 ++ inhistory = check_passwd_inhistory(topology, USER1_DN, cpw, tpw) ++ assert inhistory == 0 ++ ++ log.info(' checking the third password, which is supposed to be in history') ++ cpw = tpw ++ tpw = 'password%d' % 2 ++ inhistory = check_passwd_inhistory(topology, USER1_DN, cpw, tpw) ++ assert inhistory == 1 ++ ++ log.info("Global policy was successfully verified.") ++ ++def test_ticket48228_test_subtree_policy(topology): ++ """ ++ Check subtree level password policy ++ """ ++ ++ log.info(' Set inhistory = 6') ++ set_subtree_pwpolicy(topology) ++ ++ log.info(' Bind as directory manager') ++ log.info("Bind as %s" % DN_DM) ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ ++ log.info(' Add an entry' + USER2_DN) ++ try: ++ topology.standalone.add_s(Entry((USER2_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(), ++ 'sn': '2', ++ 'cn': 'user 2', ++ 'uid': 'user2', ++ 'givenname': 'user', ++ 'mail': 'user2@example.com', ++ 'userpassword': 'password'}))) ++ except ldap.LDAPError, e: ++ log.fatal('test_ticket48228: Failed to add user' + USER2_DN + ': error ' + e.message['desc']) ++ assert False ++ ++ log.info(' Update the password of ' + USER2_DN + ' 6 times') ++ update_passwd(topology, USER2_DN, 'password', 6) ++ ++ log.info(' Set inhistory = 4') ++ topology.standalone.simple_bind_s(DN_DM, PASSWORD) ++ try: ++ topology.standalone.modify_s(SUBTREE_PWP, [(ldap.MOD_REPLACE, 'passwordInHistory', '4')]) ++ except ldap.LDAPError, e: ++ log.error('Failed to set pwpolicy-local: error ' + e.message['desc']) ++ assert False ++ ++ log.info(' checking the first password, which is supposed NOT to be in history any more') ++ cpw = 'password%d' % 5 ++ tpw = 'password' ++ inhistory = check_passwd_inhistory(topology, USER2_DN, cpw, tpw) ++ assert inhistory == 0 ++ ++ log.info(' checking the second password, which is supposed NOT to be in history any more') ++ cpw = tpw ++ tpw = 'password%d' % 0 ++ inhistory = check_passwd_inhistory(topology, USER2_DN, cpw, tpw) ++ assert inhistory == 0 ++ ++ log.info(' checking the second password, which is supposed NOT to be in history any more') ++ cpw = tpw ++ tpw = 'password%d' % 1 ++ inhistory = check_passwd_inhistory(topology, USER2_DN, cpw, tpw) ++ assert inhistory == 0 ++ ++ log.info(' checking the third password, which is supposed to be in history') ++ cpw = tpw ++ tpw = 'password%d' % 2 ++ inhistory = check_passwd_inhistory(topology, USER2_DN, cpw, tpw) ++ assert inhistory == 1 ++ ++ log.info("Subtree level policy was successfully verified.") ++ ++def test_ticket48228_final(topology): ++ topology.standalone.delete() ++ log.info('Testcase PASSED') ++ ++def run_isolated(): ++ ''' ++ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) ++ To run isolated without py.test, you need to ++ - edit this file and comment '@pytest.fixture' line before 'topology' function. ++ - set the installation prefix ++ - run this program ++ ''' ++ global installation_prefix ++ installation_prefix = None ++ ++ topo = topology(True) ++ log.info('Testing Ticket 48228 - wrong password check if passwordInHistory is decreased') ++ ++ test_ticket48228_test_global_policy(topo) ++ ++ test_ticket48228_test_subtree_policy(topo) ++ ++ test_ticket48228_final(topo) ++ ++ ++if __name__ == '__main__': ++ run_isolated() ++ +-- +1.9.3 + diff --git a/SOURCES/0039-Ticket-47931-memberOf-retrocl-deadlocks.patch b/SOURCES/0039-Ticket-47931-memberOf-retrocl-deadlocks.patch new file mode 100644 index 0000000..2cb87d6 --- /dev/null +++ b/SOURCES/0039-Ticket-47931-memberOf-retrocl-deadlocks.patch @@ -0,0 +1,1282 @@ +From 9ba3240a177c156e365f22c721432321bb0a679e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 4 Aug 2015 12:19:31 -0400 +Subject: [PATCH 39/39] Ticket 47931 - memberOf & retrocl deadlocks + +Bug Description: When concurrently updating multiple backends the + memberOf and retrocl plugins can deadlock on each + other. This is caused by the required retrocl lock, + and the db lock on the changenumber index in the + retrocl db. + +Fix Description: Added scoping to the retrocl that allows subtrees/suffixes + to be included or excluded. Also moved the existing + memberOf scoping outside of its global lock. + + Also improved the memberOf config copying to be consistent + and more efficient. Improved the memberOf scoping attributes + to be multivalued. And, properly valdiated new config + settings in the preop valdiation function, instead of the + "apply config" function. + +https://fedorahosted.org/389/ticket/47931 + +Valgrind: passed + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit fd959ac864d6d86d24928bc2c6f097d1a6031ecd) +(cherry picked from commit d8108476d3bedbcc03f6c61bfb3d50e921faaf42) +--- + ldap/servers/plugins/memberof/memberof.c | 217 +++++++++++++-------- + ldap/servers/plugins/memberof/memberof.h | 8 +- + ldap/servers/plugins/memberof/memberof_config.c | 249 +++++++++++++++++------- + ldap/servers/plugins/retrocl/retrocl.c | 183 +++++++++++++++-- + ldap/servers/plugins/retrocl/retrocl.h | 4 + + ldap/servers/plugins/retrocl/retrocl_po.c | 41 +++- + 6 files changed, 516 insertions(+), 186 deletions(-) + +diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c +index da52bc8..9b577b9 100644 +--- a/ldap/servers/plugins/memberof/memberof.c ++++ b/ldap/servers/plugins/memberof/memberof.c +@@ -116,7 +116,7 @@ static int memberof_compare(MemberOfConfig *config, const void *a, const void *b + static int memberof_qsort_compare(const void *a, const void *b); + static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr); + static int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN *sdn); +-static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, ++static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, MemberOfConfig *config, + char **types, plugin_search_entry_callback callback, void *callback_data); + static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, + Slapi_Value *memberdn); +@@ -144,7 +144,7 @@ static const char *fetch_attr(Slapi_Entry *e, const char *attrname, + static void memberof_fixup_task_thread(void *arg); + static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str); + static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data); +- ++static int memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn); + + /*** implementation ***/ + +@@ -489,7 +489,8 @@ memberof_get_plugin_area() + int memberof_postop_del(Slapi_PBlock *pb) + { + int ret = SLAPI_PLUGIN_SUCCESS; +- MemberOfConfig configCopy = {0, 0, 0, 0}; ++ MemberOfConfig *mainConfig = NULL; ++ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + Slapi_DN *sdn; + void *caller_id = NULL; + +@@ -509,12 +510,13 @@ int memberof_postop_del(Slapi_PBlock *pb) + struct slapi_entry *e = NULL; + + slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e ); +- +- /* We need to get the config lock first. Trying to get the +- * config lock after we already hold the op lock can cause +- * a deadlock. */ + memberof_rlock_config(); +- /* copy config so it doesn't change out from under us */ ++ mainConfig = memberof_get_config(); ++ if(!memberof_entry_in_scope(mainConfig, slapi_entry_get_sdn(e))){ ++ /* The entry is not in scope, bail...*/ ++ memberof_unlock_config(); ++ goto bail; ++ } + memberof_copy_config(&configCopy, memberof_get_config()); + memberof_unlock_config(); + +@@ -529,7 +531,6 @@ int memberof_postop_del(Slapi_PBlock *pb) + "memberof_postop_del: error deleting dn (%s) from group. Error (%d)\n", + slapi_sdn_get_dn(sdn),ret); + memberof_unlock(); +- memberof_free_config(&configCopy); + goto bail; + } + +@@ -554,10 +555,10 @@ int memberof_postop_del(Slapi_PBlock *pb) + } + } + memberof_unlock(); ++bail: + memberof_free_config(&configCopy); + } + +-bail: + if(ret){ + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); + ret = SLAPI_PLUGIN_FAILURE; +@@ -591,7 +592,7 @@ memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN * + + groupattrs[0] = config->groupattrs[i]; + +- rc = memberof_call_foreach_dn(pb, sdn, groupattrs, ++ rc = memberof_call_foreach_dn(pb, sdn, config, groupattrs, + memberof_del_dn_type_callback, &data); + } + +@@ -641,6 +642,20 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) + return rc; + } + ++/* Check if the the entry include scope is a child of the sdn */ ++static Slapi_DN* ++memberof_scope_is_child_of_dn(MemberOfConfig *config, Slapi_DN *sdn) ++{ ++ int i = 0; ++ ++ while(config->entryScopes && config->entryScopes[i]){ ++ if(slapi_sdn_issuffix(config->entryScopes[i], sdn)){ ++ return config->entryScopes[i]; ++ } ++ i++; ++ } ++ return NULL; ++} + /* + * Does a callback search of "type=dn" under the db suffix that "dn" is in, + * unless all_backends is set, then we look at all the backends. If "dn" +@@ -649,7 +664,7 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) + */ + int + memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, +- char **types, plugin_search_entry_callback callback, void *callback_data) ++ MemberOfConfig *config, char **types, plugin_search_entry_callback callback, void *callback_data) + { + Slapi_PBlock *search_pb = NULL; + Slapi_DN *base_sdn = NULL; +@@ -657,9 +672,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, + char *escaped_filter_val; + char *filter_str = NULL; + char *cookie = NULL; +- int all_backends = memberof_config_get_all_backends(); +- Slapi_DN *entry_scope = memberof_config_get_entry_scope(); +- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree(); ++ int all_backends = config->allBackends; + int types_name_len = 0; + int num_types = 0; + int dn_len = slapi_sdn_get_ndn_len(sdn); +@@ -667,11 +680,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, + int rc = 0; + int i = 0; + +- if (entry_scope && !slapi_sdn_issuffix(sdn, entry_scope)) { +- return (rc); +- } +- +- if (entry_scope_exclude_subtree && slapi_sdn_issuffix(sdn, entry_scope_exclude_subtree)) { ++ if (!memberof_entry_in_scope(config, sdn)) { + return (rc); + } + +@@ -728,6 +737,8 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, + search_pb = slapi_pblock_new(); + be = slapi_get_first_backend(&cookie); + while(be){ ++ Slapi_DN *scope_sdn = NULL; ++ + if(!all_backends){ + be = slapi_be_select(sdn); + if(be == NULL){ +@@ -743,13 +754,14 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, + continue; + } + } +- if (entry_scope) { +- if (slapi_sdn_issuffix(base_sdn, entry_scope)) { ++ ++ if (config->entryScopes || config->entryScopeExcludeSubtrees) { ++ if (memberof_entry_in_scope(config, base_sdn)) { + /* do nothing, entry scope is spanning + * multiple suffixes, start at suffix */ +- } else if (slapi_sdn_issuffix(entry_scope, base_sdn)) { ++ } else if ((scope_sdn = memberof_scope_is_child_of_dn(config, base_sdn))) { + /* scope is below suffix, set search base */ +- base_sdn = entry_scope; ++ base_sdn = scope_sdn; + } else if(!all_backends){ + break; + } else { +@@ -767,7 +779,6 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, + break; + } + +- + if(!all_backends){ + break; + } +@@ -792,10 +803,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) + { + int ret = SLAPI_PLUGIN_SUCCESS; + void *caller_id = NULL; +- Slapi_DN *entry_scope = NULL; +- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree(); + +- entry_scope = memberof_config_get_entry_scope(); + slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, + "--> memberof_postop_modrdn\n" ); + +@@ -810,7 +818,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) + if(memberof_oktodo(pb)) + { + MemberOfConfig *mainConfig = 0; +- MemberOfConfig configCopy = {0, 0, 0, 0}; ++ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + struct slapi_entry *pre_e = NULL; + struct slapi_entry *post_e = NULL; + Slapi_DN *pre_sdn = 0; +@@ -818,7 +826,6 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) + + slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e ); + slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e ); +- + if(pre_e && post_e) + { + pre_sdn = slapi_entry_get_sdn(pre_e); +@@ -831,11 +838,19 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) + memberof_copy_config(&configCopy, mainConfig); + memberof_unlock_config(); + ++ /* Need to check both the pre/post entries */ ++ if((pre_sdn && !memberof_entry_in_scope(&configCopy, pre_sdn)) && ++ (post_sdn && !memberof_entry_in_scope(&configCopy, post_sdn))) ++ { ++ /* The entry is not in scope */ ++ goto bail; ++ } ++ + memberof_lock(); + + /* update any downstream members */ + if(pre_sdn && post_sdn && configCopy.group_filter && +- 0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) ++ 0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) + { + int i = 0; + Slapi_Attr *attr = 0; +@@ -847,7 +862,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) + if(0 == slapi_entry_attr_find(post_e, configCopy.groupattrs[i], &attr)) + { + if((ret = memberof_moddn_attr_list(pb, &configCopy, pre_sdn, +- post_sdn, attr) != 0)) ++ post_sdn, attr) != 0)) + { + slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, + "memberof_postop_modrdn - update failed for (%s), error (%d)\n", +@@ -862,49 +877,49 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) + * of other group entries. We need to update any member + * attributes to refer to the new name. */ + if (ret == LDAP_SUCCESS && pre_sdn && post_sdn) { +- if ((entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) || +- (entry_scope_exclude_subtree && slapi_sdn_issuffix(post_sdn, entry_scope_exclude_subtree))) { ++ if (!memberof_entry_in_scope(&configCopy, post_sdn)){ + if((ret = memberof_del_dn_from_groups(pb, &configCopy, pre_sdn))){ + slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, + "memberof_postop_modrdn - delete dn failed for (%s), error (%d)\n", + slapi_sdn_get_dn(pre_sdn), ret); + } + if(ret == LDAP_SUCCESS && pre_e && configCopy.group_filter && +- 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) { ++ 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) ++ { + /* is the entry of interest as a group? */ +- int i = 0; +- Slapi_Attr *attr = 0; +- +- /* Loop through to find each grouping attribute separately. */ +- for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) { +- if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) { +- if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){ +- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n", +- slapi_sdn_get_dn(pre_sdn),ret); +- } ++ int i = 0; ++ Slapi_Attr *attr = 0; + ++ /* Loop through to find each grouping attribute separately. */ ++ for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) { ++ if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) { ++ if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){ ++ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, ++ "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n", ++ slapi_sdn_get_dn(pre_sdn),ret); + } ++ + } +- } ++ } ++ } + if(ret == LDAP_SUCCESS) { +- memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; +- if((ret = memberof_del_dn_type_callback(post_e, &del_data))){ +- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", +- slapi_entry_get_dn(post_e), ret); +- } ++ memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; ++ if((ret = memberof_del_dn_type_callback(post_e, &del_data))){ ++ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, ++ "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", ++ slapi_entry_get_dn(post_e), ret); + } ++ } + } else { + if((ret = memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn))){ + slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "memberof_postop_modrdn - replace dne failed for (%s), error (%d)\n", ++ "memberof_postop_modrdn - replace dn failed for (%s), error (%d)\n", + slapi_sdn_get_dn(pre_sdn), ret); + } + } + } +- + memberof_unlock(); ++bail: + memberof_free_config(&configCopy); + } + +@@ -946,7 +961,7 @@ memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, + + groupattrs[0] = config->groupattrs[i]; + +- if((ret = memberof_call_foreach_dn(pb, pre_sdn, groupattrs, ++ if((ret = memberof_call_foreach_dn(pb, pre_sdn, config, groupattrs, + memberof_replace_dn_type_callback, + &data))) + { +@@ -1064,12 +1079,11 @@ int memberof_postop_modify(Slapi_PBlock *pb) + goto done; + } + +- +- if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) ++ if(memberof_oktodo(pb)) + { + int config_copied = 0; + MemberOfConfig *mainConfig = 0; +- MemberOfConfig configCopy = {0, 0, 0, 0}; ++ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + /* get the mod set */ + slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); +@@ -1088,19 +1102,22 @@ int memberof_postop_modify(Slapi_PBlock *pb) + * only copy the config the first time it's needed so + * it remains the same for all mods in the operation, + * despite any config changes that may be made. */ +- if (!config_copied) +- { ++ if (!config_copied){ + memberof_rlock_config(); + mainConfig = memberof_get_config(); + + if (memberof_is_grouping_attr(type, mainConfig)) + { + interested = 1; ++ if (!memberof_entry_in_scope(mainConfig, sdn)){ ++ /* Entry is not in scope */ ++ memberof_unlock_config(); ++ goto bail; ++ } + /* copy config so it doesn't change out from under us */ + memberof_copy_config(&configCopy, mainConfig); + config_copied = 1; + } +- + memberof_unlock_config(); + } else { + if (memberof_is_grouping_attr(type, &configCopy)) +@@ -1197,8 +1214,7 @@ int memberof_postop_modify(Slapi_PBlock *pb) + } + + bail: +- if (config_copied) +- { ++ if (config_copied){ + memberof_free_config(&configCopy); + } + +@@ -1244,22 +1260,25 @@ int memberof_postop_add(Slapi_PBlock *pb) + + if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) + { +- MemberOfConfig *mainConfig = 0; +- MemberOfConfig configCopy = {0, 0, 0, 0}; + struct slapi_entry *e = NULL; +- ++ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ++ MemberOfConfig *mainConfig; + slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e ); +- + + /* is the entry of interest? */ + memberof_rlock_config(); + mainConfig = memberof_get_config(); + if(e && mainConfig && mainConfig->group_filter && + 0 == slapi_filter_test_simple(e, mainConfig->group_filter)) ++ + { + interested = 1; +- /* copy config so it doesn't change out from under us */ +- memberof_copy_config(&configCopy, mainConfig); ++ if(!memberof_entry_in_scope(mainConfig, slapi_entry_get_sdn(e))){ ++ /* Entry is not in scope */ ++ memberof_unlock_config(); ++ goto bail; ++ } ++ memberof_copy_config(&configCopy, memberof_get_config()); + } + memberof_unlock_config(); + +@@ -1284,11 +1303,11 @@ int memberof_postop_add(Slapi_PBlock *pb) + } + + memberof_unlock(); +- + memberof_free_config(&configCopy); + } + } + ++bail: + if(ret){ + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); + ret = SLAPI_PLUGIN_FAILURE; +@@ -1326,26 +1345,61 @@ int memberof_oktodo(Slapi_PBlock *pb) + } + + if(slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0) +- { ++ { + slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, + "memberof_postop_oktodo: could not get parameters\n" ); + ret = -1; + } + +- /* this plugin should only execute if the operation succeeded +- */ +- if(oprc != 0) ++ /* this plugin should only execute if the operation succeeded */ ++ if(oprc != 0) + { + ret = 0; + } +- ++ ++bail: + slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, + "<-- memberof_postop_oktodo\n" ); + +-bail: + return ret; + } + ++/* ++ * Return 1 if the entry is in the scope. ++ * For MODRDN the caller should check both the preop ++ * and postop entries. If we are moving out of, or ++ * into scope, we should process it. ++ */ ++static int ++memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn) ++{ ++ if (config->entryScopeExcludeSubtrees){ ++ int i = 0; ++ ++ /* check the excludes */ ++ while(config->entryScopeExcludeSubtrees[i]){ ++ if (slapi_sdn_issuffix(sdn, config->entryScopeExcludeSubtrees[i])){ ++ return 0; ++ } ++ i++; ++ } ++ } ++ if (config->entryScopes){ ++ int i = 0; ++ ++ /* check the excludes */ ++ while(config->entryScopes[i]){ ++ if (slapi_sdn_issuffix(sdn, config->entryScopes[i])){ ++ return 1; ++ } ++ i++; ++ } ++ return 0; ++ } ++ ++ return 1; ++} ++ + static Slapi_DN * + memberof_getsdn(Slapi_PBlock *pb) + { +@@ -2013,7 +2067,7 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn, + { + /* Search for any grouping attributes that point to memberdn. + * For each match, add it to the list, recurse and do same search */ +- return memberof_call_foreach_dn(NULL, member_sdn, config->groupattrs, ++ return memberof_call_foreach_dn(NULL, member_sdn, config, config->groupattrs, + memberof_get_groups_callback, data); + } + +@@ -2030,7 +2084,6 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) + Slapi_Value *group_dn_val = 0; + Slapi_ValueSet *groupvals = *((memberof_get_groups_data*)callback_data)->groupvals; + Slapi_ValueSet *group_norm_vals = *((memberof_get_groups_data*)callback_data)->group_norm_vals; +- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree(); + MemberOfConfig *config = ((memberof_get_groups_data*)callback_data)->config; + int rc = 0; + +@@ -2086,7 +2139,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) + } + + /* if the group does not belong to an excluded subtree, adds it to the valueset */ +- if (!(entry_scope_exclude_subtree && slapi_sdn_issuffix(group_sdn, entry_scope_exclude_subtree))) { ++ if (memberof_entry_in_scope(config, group_sdn)) { + /* Push group_dn_val into the valueset. This memory is now owned + * by the valueset. */ + group_dn_val = slapi_value_new_string(group_dn); +@@ -2188,8 +2241,8 @@ memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, + { + char *attrs[2] = {config->memberof_attr, 0}; + +- return memberof_call_foreach_dn(pb, group_sdn, attrs, +- memberof_test_membership_callback , config); ++ return memberof_call_foreach_dn(pb, group_sdn, config, attrs, ++ memberof_test_membership_callback, config); + } + + /* +diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h +index 5a70400..9d9d158 100644 +--- a/ldap/servers/plugins/memberof/memberof.h ++++ b/ldap/servers/plugins/memberof/memberof.h +@@ -52,8 +52,10 @@ typedef struct memberofconfig { + char **groupattrs; + char *memberof_attr; + int allBackends; +- Slapi_DN *entryScope; +- Slapi_DN *entryScopeExcludeSubtree; ++ Slapi_DN **entryScopes; ++ int entryScopeCount; ++ Slapi_DN **entryScopeExcludeSubtrees; ++ int entryExcludeScopeCount; + Slapi_Filter *group_filter; + Slapi_Attr **group_slapiattrs; + int skip_nested; +@@ -74,8 +76,6 @@ void memberof_rlock_config(); + void memberof_wlock_config(); + void memberof_unlock_config(); + int memberof_config_get_all_backends(); +-Slapi_DN * memberof_config_get_entry_scope(); +-Slapi_DN * memberof_config_get_entry_scope_exclude_subtree(); + void memberof_set_config_area(Slapi_DN *sdn); + Slapi_DN * memberof_get_config_area(); + void memberof_set_plugin_area(Slapi_DN *sdn); +diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c +index ac2d045..b4cc941 100644 +--- a/ldap/servers/plugins/memberof/memberof_config.c ++++ b/ldap/servers/plugins/memberof/memberof_config.c +@@ -48,7 +48,7 @@ static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_En + /* This is the main configuration which is updated from dse.ldif. The + * config will be copied when it is used by the plug-in to prevent it + * being changed out from under a running memberOf operation. */ +-static MemberOfConfig theConfig = {NULL, NULL,0, NULL, NULL, NULL, NULL}; ++static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + static Slapi_RWLock *memberof_config_lock = 0; + static int inited = 0; + +@@ -60,6 +60,19 @@ static int dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Ent + return SLAPI_DSE_CALLBACK_ERROR; + } + ++static void ++memberof_free_scope(Slapi_DN **scopes, int *count) ++{ ++ int i = 0; ++ ++ while(scopes && scopes[i]){ ++ slapi_sdn_free(&scopes[i]); ++ i++; ++ } ++ slapi_ch_free((void**)&scopes); ++ *count = 0; ++} ++ + /* + * memberof_config() + * +@@ -155,17 +168,22 @@ memberof_release_config() + * + * Validate the pending changes in the e entry. + */ +-static int ++int + memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, + int *returncode, char *returntext, void *arg) + { + Slapi_Attr *memberof_attr = NULL; + Slapi_Attr *group_attr = NULL; + Slapi_DN *config_sdn = NULL; ++ Slapi_DN **include_dn = NULL; ++ Slapi_DN **exclude_dn = NULL; + char *syntaxoid = NULL; + char *config_dn = NULL; + char *skip_nested = NULL; ++ char **entry_scopes = NULL; ++ char **entry_exclude_scopes = NULL; + int not_dn_syntax = 0; ++ int num_vals = 0; + + *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */ + +@@ -283,8 +301,112 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr + *returncode = LDAP_UNWILLING_TO_PERFORM; + } + } ++ /* ++ * Check the entry scopes ++ */ ++ entry_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals); ++ if(entry_scopes){ ++ int i = 0; ++ ++ /* Validate the syntax before we create our DN array */ ++ for (i = 0;i < num_vals; i++){ ++ if(slapi_dn_syntax_check(pb, entry_scopes[i], 1)){ ++ /* invalid dn syntax */ ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, ++ "%s: Invalid DN (%s) for include suffix.", ++ MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); ++ slapi_ch_array_free(entry_scopes); ++ theConfig.entryScopeCount = 0; ++ *returncode = LDAP_UNWILLING_TO_PERFORM; ++ goto done; ++ } ++ } ++ /* Now create our SDN array for conflict checking */ ++ include_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1); ++ for (i = 0;i < num_vals; i++){ ++ include_dn[i] = slapi_sdn_new_dn_passin(entry_scopes[i]); ++ } ++ } ++ /* ++ * Check and process the entry exclude scopes ++ */ ++ entry_exclude_scopes = ++ slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals); ++ if(entry_exclude_scopes){ ++ int i = 0; ++ ++ /* Validate the syntax before we create our DN array */ ++ for (i = 0;i < num_vals; i++){ ++ if(slapi_dn_syntax_check(pb, entry_exclude_scopes[i], 1)){ ++ /* invalid dn syntax */ ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, ++ "%s: Invalid DN (%s) for exclude suffix.", ++ MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); ++ slapi_ch_array_free(entry_exclude_scopes); ++ *returncode = LDAP_UNWILLING_TO_PERFORM; ++ goto done; ++ } ++ } ++ /* Now create our SDN array for conflict checking */ ++ exclude_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); ++ for (i = 0;i < num_vals; i++){ ++ exclude_dn[i] = slapi_sdn_new_dn_passin(entry_exclude_scopes[i]); ++ } ++ } ++ /* ++ * Need to do conflict checking ++ */ ++ if(include_dn && exclude_dn){ ++ /* ++ * Make sure we haven't mixed the same suffix, and there are no ++ * conflicts between the includes and excludes ++ */ ++ int i = 0; ++ ++ while(include_dn[i]){ ++ int x = 0; ++ while(exclude_dn[x]){ ++ if(slapi_sdn_compare(include_dn[i], exclude_dn[x] ) == 0) ++ { ++ /* we have a conflict */ ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, ++ "%s: include suffix (%s) is also listed as an exclude suffix list", ++ MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i])); ++ *returncode = LDAP_UNWILLING_TO_PERFORM; ++ goto done; ++ } ++ x++; ++ } ++ i++; ++ } ++ ++ /* Check for parent/child conflicts */ ++ i = 0; ++ while(include_dn[i]){ ++ int x = 0; ++ while(exclude_dn[x]){ ++ if(slapi_sdn_issuffix(include_dn[i], exclude_dn[x])) ++ { ++ /* we have a conflict */ ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, ++ "%s: include suffix (%s) is a child of the exclude suffix(%s)", ++ MEMBEROF_PLUGIN_SUBSYSTEM, ++ slapi_sdn_get_dn(include_dn[i]), ++ slapi_sdn_get_dn(exclude_dn[i])); ++ *returncode = LDAP_UNWILLING_TO_PERFORM; ++ goto done; ++ } ++ x++; ++ } ++ i++; ++ } ++ } + + done: ++ memberof_free_scope(exclude_dn, &num_vals); ++ memberof_free_scope(include_dn, &num_vals); ++ slapi_ch_free((void**)&entry_scopes); ++ slapi_ch_free((void**)&entry_exclude_scopes); + slapi_sdn_free(&config_sdn); + slapi_ch_free_string(&config_dn); + slapi_ch_free_string(&skip_nested); +@@ -299,7 +421,6 @@ done: + } + } + +- + /* + * memberof_apply_config() + * +@@ -318,10 +439,11 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* + int num_groupattrs = 0; + int groupattr_name_len = 0; + char *allBackends = NULL; +- char *entryScope = NULL; +- char *entryScopeExcludeSubtree = NULL; ++ char **entryScopes = NULL; ++ char **entryScopeExcludeSubtrees = NULL; + char *sharedcfg = NULL; + char *skip_nested = NULL; ++ int num_vals = 0; + + *returncode = LDAP_SUCCESS; + +@@ -353,8 +475,6 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* + groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR); + memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR); + allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR); +- entryScope = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_ATTR); +- entryScopeExcludeSubtree = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE); + skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR); + + /* +@@ -480,49 +600,39 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* + theConfig.allBackends = 0; + } + +- slapi_sdn_free(&theConfig.entryScope); +- if (entryScope) +- { +- if (slapi_dn_syntax_check(NULL, entryScope, 1) == 1) { +- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "Error: Ignoring invalid DN used as plugin entry scope: [%s]\n", +- entryScope); +- theConfig.entryScope = NULL; +- slapi_ch_free_string(&entryScope); +- } else { +- theConfig.entryScope = slapi_sdn_new_dn_passin(entryScope); ++ /* ++ * Check and process the entry scopes ++ */ ++ memberof_free_scope(theConfig.entryScopes, &theConfig.entryScopeCount); ++ entryScopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals); ++ if(entryScopes){ ++ int i = 0; ++ ++ /* Validation has already been performed in preop, just build the DN's */ ++ theConfig.entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1); ++ for (i = 0;i < num_vals; i++){ ++ theConfig.entryScopes[i] = slapi_sdn_new_dn_passin(entryScopes[i]); + } +- } else { +- theConfig.entryScope = NULL; ++ theConfig.entryScopeCount = num_vals; /* shortcut for config copy */ + } +- +- slapi_sdn_free(&theConfig.entryScopeExcludeSubtree); +- if (entryScopeExcludeSubtree) +- { +- if (theConfig.entryScope == NULL) { +- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "Error: Ignoring ExcludeSubtree (%s) because entryScope is not define\n", +- entryScopeExcludeSubtree); +- theConfig.entryScopeExcludeSubtree = NULL; +- slapi_ch_free_string(&entryScopeExcludeSubtree); +- } else if (slapi_dn_syntax_check(NULL, entryScopeExcludeSubtree, 1) == 1) { +- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "Error: Ignoring invalid DN used as plugin entry exclude subtree: [%s]\n", +- entryScopeExcludeSubtree); +- theConfig.entryScopeExcludeSubtree = NULL; +- slapi_ch_free_string(&entryScopeExcludeSubtree); +- } else { +- theConfig.entryScopeExcludeSubtree = slapi_sdn_new_dn_passin(entryScopeExcludeSubtree); ++ /* ++ * Check and process the entry exclude scopes ++ */ ++ memberof_free_scope(theConfig.entryScopeExcludeSubtrees, ++ &theConfig.entryExcludeScopeCount); ++ entryScopeExcludeSubtrees = ++ slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals); ++ if(entryScopeExcludeSubtrees){ ++ int i = 0; ++ ++ /* Validation has already been performed in preop, just build the DN's */ ++ theConfig.entryScopeExcludeSubtrees = ++ (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); ++ for (i = 0;i < num_vals; i++){ ++ theConfig.entryScopeExcludeSubtrees[i] = ++ slapi_sdn_new_dn_passin(entryScopeExcludeSubtrees[i]); + } +- } else { +- theConfig.entryScopeExcludeSubtree = NULL; +- } +- if (theConfig.entryScopeExcludeSubtree && theConfig.entryScope && !slapi_sdn_issuffix(theConfig.entryScopeExcludeSubtree, theConfig.entryScope)) { +- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, +- "Error: Ignoring ExcludeSubtree (%s) that is out of the scope (%s)\n", +- slapi_sdn_get_dn(theConfig.entryScopeExcludeSubtree), +- slapi_sdn_get_dn(theConfig.entryScope)); +- slapi_sdn_free(&theConfig.entryScopeExcludeSubtree); ++ theConfig.entryExcludeScopeCount = num_vals; /* shortcut for config copy */ + } + + /* release the lock */ +@@ -536,6 +646,8 @@ done: + slapi_ch_free_string(&memberof_attr); + slapi_ch_free_string(&allBackends); + slapi_ch_free_string(&skip_nested); ++ slapi_ch_free((void **)&entryScopes); ++ slapi_ch_free((void **)&entryScopeExcludeSubtrees); + + if (*returncode != LDAP_SUCCESS) + { +@@ -616,6 +728,23 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) + { + dest->allBackends = src->allBackends; + } ++ ++ if(src->entryScopes){ ++ int num_vals = 0; ++ ++ dest->entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryScopeCount+1); ++ for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){ ++ dest->entryScopes[num_vals] = slapi_sdn_dup(src->entryScopes[num_vals]); ++ } ++ } ++ if(src->entryScopeExcludeSubtrees){ ++ int num_vals = 0; ++ ++ dest->entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryExcludeScopeCount+1); ++ for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){ ++ dest->entryScopeExcludeSubtrees[num_vals] = slapi_sdn_dup(src->entryScopeExcludeSubtrees[num_vals]); ++ } ++ } + } + } + +@@ -641,6 +770,8 @@ memberof_free_config(MemberOfConfig *config) + slapi_ch_free((void **)&config->group_slapiattrs); + + slapi_ch_free_string(&config->memberof_attr); ++ memberof_free_scope(config->entryScopes, &config->entryScopeCount); ++ memberof_free_scope(config->entryScopeExcludeSubtrees, &config->entryExcludeScopeCount); + } + } + +@@ -706,30 +837,6 @@ memberof_config_get_all_backends() + return all_backends; + } + +-Slapi_DN * +-memberof_config_get_entry_scope() +-{ +- Slapi_DN *entry_scope; +- +- slapi_rwlock_rdlock(memberof_config_lock); +- entry_scope = theConfig.entryScope; +- slapi_rwlock_unlock(memberof_config_lock); +- +- return entry_scope; +-} +- +-Slapi_DN * +-memberof_config_get_entry_scope_exclude_subtree() +-{ +- Slapi_DN *entry_exclude_subtree; +- +- slapi_rwlock_rdlock(memberof_config_lock); +- entry_exclude_subtree = theConfig.entryScopeExcludeSubtree; +- slapi_rwlock_unlock(memberof_config_lock); +- +- return entry_exclude_subtree; +-} +- + /* + * Check if we are modifying the config, or changing the shared config entry + */ +diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c +index 78a0c6d..4bcbb38 100644 +--- a/ldap/servers/plugins/retrocl/retrocl.c ++++ b/ldap/servers/plugins/retrocl/retrocl.c +@@ -45,6 +45,9 @@ char **retrocl_attributes = NULL; + char **retrocl_aliases = NULL; + int retrocl_log_deleted = 0; + ++static Slapi_DN **retrocl_includes = NULL; ++static Slapi_DN **retrocl_excludes = NULL; ++ + /* ----------------------------- Retrocl Plugin */ + + static Slapi_PluginDesc retrocldesc = {"retrocl", VENDOR, DS_PACKAGE_VERSION, "Retrocl Plugin"}; +@@ -349,6 +352,8 @@ static int retrocl_start (Slapi_PBlock *pb) + int rc = 0; + Slapi_Entry *e = NULL; + char **values = NULL; ++ int num_vals = 0; ++ int i = 0; + + retrocl_rootdse_init(pb); + +@@ -369,6 +374,87 @@ static int retrocl_start (Slapi_PBlock *pb) + return -1; + } + ++ /* Get the exclude suffixes */ ++ values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_EXCLUDE_SUFFIX, &num_vals); ++ if(values){ ++ /* Validate the syntax before we create our DN array */ ++ for (i = 0;i < num_vals; i++){ ++ if(slapi_dn_syntax_check(pb, values[i], 1)){ ++ /* invalid dn syntax */ ++ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, ++ "Invalid DN (%s) for exclude suffix.\n", values[i] ); ++ slapi_ch_array_free(values); ++ return -1; ++ } ++ } ++ /* Now create our SDN array */ ++ retrocl_excludes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); ++ for (i = 0;i < num_vals; i++){ ++ retrocl_excludes[i] = slapi_sdn_new_dn_byval(values[i]); ++ } ++ slapi_ch_array_free(values); ++ } ++ /* Get the include suffixes */ ++ values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_INCLUDE_SUFFIX, &num_vals); ++ if(values){ ++ for (i = 0;i < num_vals; i++){ ++ /* Validate the syntax before we create our DN array */ ++ if(slapi_dn_syntax_check(pb, values[i], 1)){ ++ /* invalid dn syntax */ ++ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, ++ "Invalid DN (%s) for include suffix.\n", values[i] ); ++ slapi_ch_array_free(values); ++ return -1; ++ } ++ } ++ /* Now create our SDN array */ ++ retrocl_includes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); ++ for (i = 0;i < num_vals; i++){ ++ retrocl_includes[i] = slapi_sdn_new_dn_byval(values[i]); ++ } ++ slapi_ch_array_free(values); ++ } ++ if(retrocl_includes && retrocl_excludes){ ++ /* ++ * Make sure we haven't mixed the same suffix, and there are no ++ * conflicts between the includes and excludes ++ */ ++ int i = 0; ++ ++ while(retrocl_includes[i]){ ++ int x = 0; ++ while(retrocl_excludes[x]){ ++ if(slapi_sdn_compare(retrocl_includes[i], retrocl_excludes[x] ) == 0){ ++ /* we have a conflict */ ++ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, ++ "include suffix (%s) is also listed in exclude suffix list\n", ++ slapi_sdn_get_dn(retrocl_includes[i])); ++ return -1; ++ } ++ x++; ++ } ++ i++; ++ } ++ ++ /* Check for parent/child conflicts */ ++ i = 0; ++ while(retrocl_includes[i]){ ++ int x = 0; ++ while(retrocl_excludes[x]){ ++ if(slapi_sdn_issuffix(retrocl_includes[i], retrocl_excludes[x])){ ++ /* we have a conflict */ ++ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, ++ "include suffix (%s) is a child of the exclude suffix(%s)\n", ++ slapi_sdn_get_dn(retrocl_includes[i]), ++ slapi_sdn_get_dn(retrocl_excludes[i])); ++ return -1; ++ } ++ x++; ++ } ++ i++; ++ } ++ } ++ + values = slapi_entry_attr_get_charray(e, "nsslapd-attribute"); + if (values != NULL) { + int n = 0; +@@ -434,6 +520,49 @@ static int retrocl_start (Slapi_PBlock *pb) + } + + /* ++ * Check if an entry is in the configured scope. ++ * Return 1 if entry is in the scope, or 0 otherwise. ++ * For MODRDN the caller should check both the preop ++ * and postop entries. If we are moving out of, or ++ * into scope, we should record it. ++ */ ++int ++retrocl_entry_in_scope(Slapi_Entry *e) ++{ ++ Slapi_DN *sdn = slapi_entry_get_sdn(e); ++ ++ if (e == NULL){ ++ return 1; ++ } ++ ++ if (retrocl_excludes){ ++ int i = 0; ++ ++ /* check the excludes */ ++ while(retrocl_excludes[i]){ ++ if (slapi_sdn_issuffix(sdn, retrocl_excludes[i])){ ++ return 0; ++ } ++ i++; ++ } ++ } ++ if (retrocl_includes){ ++ int i = 0; ++ ++ /* check the excludes */ ++ while(retrocl_includes[i]){ ++ if (slapi_sdn_issuffix(sdn, retrocl_includes[i])){ ++ return 1; ++ } ++ i++; ++ } ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* + * Function: retrocl_stop + * + * Returns: 0 +@@ -446,26 +575,40 @@ static int retrocl_start (Slapi_PBlock *pb) + + static int retrocl_stop (Slapi_PBlock *pb) + { +- int rc = 0; +- +- slapi_ch_array_free(retrocl_attributes); +- retrocl_attributes = NULL; +- slapi_ch_array_free(retrocl_aliases); +- retrocl_aliases = NULL; +- +- retrocl_stop_trimming(); +- retrocl_be_changelog = NULL; +- retrocl_forget_changenumbers(); +- PR_DestroyLock(retrocl_internal_lock); +- retrocl_internal_lock = NULL; +- slapi_destroy_rwlock(retrocl_cn_lock); +- retrocl_cn_lock = NULL; +- legacy_initialised = 0; +- +- slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "", +- LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search); +- +- return rc; ++ int rc = 0; ++ int i = 0; ++ ++ slapi_ch_array_free(retrocl_attributes); ++ retrocl_attributes = NULL; ++ slapi_ch_array_free(retrocl_aliases); ++ retrocl_aliases = NULL; ++ ++ while(retrocl_excludes && retrocl_excludes[i]){ ++ slapi_sdn_free(&retrocl_excludes[i]); ++ i++; ++ } ++ slapi_ch_free((void**)&retrocl_excludes); ++ i = 0; ++ ++ while(retrocl_includes && retrocl_includes[i]){ ++ slapi_sdn_free(&retrocl_includes[i]); ++ i++; ++ } ++ slapi_ch_free((void**)&retrocl_includes); ++ ++ retrocl_stop_trimming(); ++ retrocl_be_changelog = NULL; ++ retrocl_forget_changenumbers(); ++ PR_DestroyLock(retrocl_internal_lock); ++ retrocl_internal_lock = NULL; ++ slapi_destroy_rwlock(retrocl_cn_lock); ++ retrocl_cn_lock = NULL; ++ legacy_initialised = 0; ++ ++ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "", ++ LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search); ++ ++ return rc; + } + + /* +diff --git a/ldap/servers/plugins/retrocl/retrocl.h b/ldap/servers/plugins/retrocl/retrocl.h +index ae0139c..7edd62f 100644 +--- a/ldap/servers/plugins/retrocl/retrocl.h ++++ b/ldap/servers/plugins/retrocl/retrocl.h +@@ -67,6 +67,8 @@ typedef struct _cnumRet { + /* was originally changelogmaximumage */ + #define CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE "nsslapd-changelogmaxage" + #define CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE "nsslapd-changelogdir" ++#define CONFIG_CHANGELOG_INCLUDE_SUFFIX "nsslapd-include-suffix" ++#define CONFIG_CHANGELOG_EXCLUDE_SUFFIX "nsslapd-exclude-suffix" + + #define RETROCL_CHANGELOG_DN "cn=changelog" + #define RETROCL_MAPPINGTREE_DN "cn=\"cn=changelog\",cn=mapping tree,cn=config" +@@ -140,4 +142,6 @@ extern void retrocl_init_trimming(void); + extern void retrocl_stop_trimming(void); + extern char *retrocl_get_config_str(const char *attrt); + ++int retrocl_entry_in_scope(Slapi_Entry *e); ++ + #endif /* _H_RETROCL */ +diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c +index 7083d0a..f689373 100644 +--- a/ldap/servers/plugins/retrocl/retrocl_po.c ++++ b/ldap/servers/plugins/retrocl/retrocl_po.c +@@ -140,6 +140,7 @@ write_replog_db( + int flag, + time_t curtime, + Slapi_Entry *log_e, ++ Slapi_Entry *post_entry, + const char *newrdn, + LDAPMod **modrdn_mods, + const char *newsuperior +@@ -156,11 +157,26 @@ 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)){ ++ /* modrdn: entry not in scope, just return... */ ++ return ret; ++ } ++ } else { ++ if(!retrocl_entry_in_scope(log_e)){ ++ /* entry not in scope, just return... */ ++ return ret; ++ } ++ } + + PR_Lock(retrocl_internal_lock); + changenum = retrocl_assign_changenumber(); +@@ -319,7 +335,7 @@ write_replog_db( + break; + + case OP_DELETE: +- if (log_e) { ++ if (retrocl_log_deleted) { + /* we have to log the full entry */ + if ( entry2reple( e, log_e, OP_DELETE ) != 0 ) { + err = SLAPI_PLUGIN_FAILURE; +@@ -559,7 +575,8 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) + char *dn; + LDAPMod **log_m = NULL; + int flag = 0; +- Slapi_Entry *te = NULL; ++ Slapi_Entry *entry = NULL; ++ Slapi_Entry *post_entry = NULL; + Slapi_Operation *op = NULL; + LDAPMod **modrdn_mods = NULL; + char *newrdn = NULL; +@@ -624,7 +641,12 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) + LDAPDebug0Args(LDAP_DEBUG_TRACE,"not applying change for nsTombstone entries\n"); + return SLAPI_PLUGIN_SUCCESS; + } +- ++ /* ++ * Start by grabbing the preop entry, ADD will replace it as needed. Getting the entry ++ * allows up to perform scoping in write_replog_db() for all op types. ++ */ ++ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry); ++ + switch ( optype ) { + case OP_MODIFY: + (void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &log_m ); +@@ -634,14 +656,14 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) + * For adds, we want the unnormalized dn, so we can preserve + * spacing, case, when replicating it. + */ +- (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &te ); +- if ( NULL != te ) { +- dn = slapi_entry_get_dn( te ); ++ (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &entry ); ++ if ( NULL != entry ) { ++ dn = slapi_entry_get_dn( entry ); + } + break; + case OP_DELETE: + if (retrocl_log_deleted) +- (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &te); ++ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry); + break; + case OP_MODRDN: + /* newrdn is used just for logging; no need to be normalized */ +@@ -649,13 +671,14 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) + (void)slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &flag ); + (void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &modrdn_mods ); + (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior ); ++ (void)slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &post_entry); + break; + } + + /* check if we should log change to retro changelog, and + * if so, do it here */ +- if((rc = write_replog_db( pb, optype, dn, log_m, flag, curtime, te, +- newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior) ))) ++ if((rc = write_replog_db( pb, optype, dn, log_m, flag, curtime, entry, ++ post_entry, newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior) ))) + { + slapi_log_error(SLAPI_LOG_FATAL, "retrocl-plugin", + "retrocl_postob: operation failure [%d]\n", rc); +-- +1.9.3 + diff --git a/SOURCES/0039-Ticket-47967-cos_cache_build_definition_list-does-no.patch b/SOURCES/0039-Ticket-47967-cos_cache_build_definition_list-does-no.patch deleted file mode 100644 index 070a463..0000000 --- a/SOURCES/0039-Ticket-47967-cos_cache_build_definition_list-does-no.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 28027d3f0d3f6df742c1a8360c75c7a922cb1819 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 4 Dec 2014 11:11:13 -0500 -Subject: [PATCH 39/53] Ticket 47967 - cos_cache_build_definition_list does not - stop during server shutdown - -Bug Description: If the COS cache is being rebuilt (where there are many COS - definitions/templates), attempting to stop the server can - take take a very long time. - -Fix Description: In the callback functions check for server shutdown to abort - out of the search callback loops. - -https://fedorahosted.org/389/ticket/47967 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 99f99743617c1d082e748e7d3e83adf953d2ad05) -(cherry picked from commit f2df95ea7a78e95535eaf798fdf3edff9cb33b72) ---- - ldap/servers/plugins/cos/cos_cache.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index 3f3841f..a7993c8 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -725,7 +725,7 @@ struct dn_defs_info { - /* - * Currently, always returns 0 to continue the search for definitions, even - * if a particular attempt to add a definition fails: info.ret gets set to -- * zero only if we succed to add a def. -+ * zero only if we succeed to add a def. - */ - static int - cos_dn_defs_cb (Slapi_Entry* e, void *callback_data) -@@ -1056,10 +1056,10 @@ bail: - /* This particular definition may not have yielded anything - * worth caching (eg. no template was found for it) but - * that should not cause us to abort the search for other more well behaved -- * definitions. -+ * definitions unless we are shutting down. - * return info->ret; -- */ -- return (0); -+ */ -+ return slapi_is_shutting_down(); - - } - -@@ -1116,7 +1116,7 @@ struct tmpl_info { - /* - * Currently, always returns 0 to continue the search for templates, even - * if a particular attempt to add a template fails: info.ret gets set to -- * zero only if we succed to add at least one tmpl. -+ * zero only if we succeed to add at least one tmpl. - */ - static int cos_dn_tmpl_entries_cb (Slapi_Entry* e, void *callback_data) { - cosAttrValue *pDn = 0; -@@ -1166,7 +1166,7 @@ static int cos_dn_tmpl_entries_cb (Slapi_Entry* e, void *callback_data) { - - if(pSneakyVal == NULL) - { -- /* look for the atrribute in the dynamic attributes */ -+ /* look for the attribute in the dynamic attributes */ - if(cos_cache_attrval_exists(info->pAttrs, attrType)) - { - pSneakyVal = &pCosAttribute; -@@ -1269,10 +1269,10 @@ static int cos_dn_tmpl_entries_cb (Slapi_Entry* e, void *callback_data) { - } - } - /* -- * Always contine the search even if a particular attempt -- * to add a template failed. -- */ -- return 0; -+ * Always continue the search even if a particular attempt -+ * to add a template failed unless we are shutting down -+ */ -+ return slapi_is_shutting_down(); - } - - /* --- -1.9.3 - diff --git a/SOURCES/0040-Ticket-47931-Fix-coverity-issues.patch b/SOURCES/0040-Ticket-47931-Fix-coverity-issues.patch new file mode 100644 index 0000000..d1ac778 --- /dev/null +++ b/SOURCES/0040-Ticket-47931-Fix-coverity-issues.patch @@ -0,0 +1,57 @@ +From a389bc3bafccb1f7bd9917a734230680e382af91 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 10 Aug 2015 10:42:40 -0400 +Subject: [PATCH] Ticket 47931 - Fix coverity issues + +Description: Fix coverity issues in memberof_config.c + + 13316 - double free + 13315 - Dereference after null check + 13314 - Dereference after null check + 13313 - copy/paste error + +https://fedorahosted.org/389/ticket/47931 + +Reviewed by: rmeggins(Thanks!) + +(cherry picked from commit 5daea973e4526584ee41d7b9f4b1b4993b4de6f1) +(cherry picked from commit 9a0047ef75f6dbeb1980ac77fab5d62865c77e6a) +--- + ldap/servers/plugins/memberof/memberof_config.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c +index b4cc941..10cbd7a 100644 +--- a/ldap/servers/plugins/memberof/memberof_config.c ++++ b/ldap/servers/plugins/memberof/memberof_config.c +@@ -316,6 +316,7 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr + "%s: Invalid DN (%s) for include suffix.", + MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); + slapi_ch_array_free(entry_scopes); ++ entry_scopes = NULL; + theConfig.entryScopeCount = 0; + *returncode = LDAP_UNWILLING_TO_PERFORM; + goto done; +@@ -341,8 +342,9 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr + /* invalid dn syntax */ + PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, + "%s: Invalid DN (%s) for exclude suffix.", +- MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); ++ MEMBEROF_PLUGIN_SUBSYSTEM, entry_exclude_scopes[i]); + slapi_ch_array_free(entry_exclude_scopes); ++ entry_exclude_scopes = NULL; + *returncode = LDAP_UNWILLING_TO_PERFORM; + goto done; + } +@@ -741,7 +743,7 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) + int num_vals = 0; + + dest->entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryExcludeScopeCount+1); +- for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){ ++ for(num_vals = 0; src->entryScopeExcludeSubtrees[num_vals]; num_vals++){ + dest->entryScopeExcludeSubtrees[num_vals] = slapi_sdn_dup(src->entryScopeExcludeSubtrees[num_vals]); + } + } +-- +1.9.3 + diff --git a/SOURCES/0040-Ticket-47969-COS-memory-leak-when-rebuilding-the-cac.patch b/SOURCES/0040-Ticket-47969-COS-memory-leak-when-rebuilding-the-cac.patch deleted file mode 100644 index 1fd571c..0000000 --- a/SOURCES/0040-Ticket-47969-COS-memory-leak-when-rebuilding-the-cac.patch +++ /dev/null @@ -1,41 +0,0 @@ -From cedd8dde2e4e16c883569fe900da317e9d0d69e9 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 2 Dec 2014 13:38:06 -0500 -Subject: [PATCH 40/53] Ticket 47969 - COS memory leak when rebuilding the - cache - -Bug Description: When the COS cache is released, not all of the schema - objectclasses are freed. So every time we rebuild the - COS cache we leak memory. - -Fix Description: After we free the schema attributes, the very first - attribute still needs to be freed. It is not freed - initially because of the duplicate checking logic, so - it is now done after the loop. - -https://fedorahosted.org/389/ticket/47969 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit d2dfda95c543f106443f898436151b00c68e4270) -(cherry picked from commit bc47239c5c7e6d19564fcd2839c6f2bd81a5b540) ---- - ldap/servers/plugins/cos/cos_cache.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index a7993c8..fd163f9 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -1864,6 +1864,8 @@ static void cos_cache_del_schema(cosCache *pCache) - } - } - } -+ /* Finally, remove the first attribute's objectclass list */ -+ cos_cache_del_attrval_list(&(pCache->ppAttrIndex[0]->pObjectclasses)); - - LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_del_schema\n",0,0,0); - } --- -1.9.3 - diff --git a/SOURCES/0041-Ticket-47686-removing-chaining-database-links-trigge.patch b/SOURCES/0041-Ticket-47686-removing-chaining-database-links-trigge.patch new file mode 100644 index 0000000..9a24344 --- /dev/null +++ b/SOURCES/0041-Ticket-47686-removing-chaining-database-links-trigge.patch @@ -0,0 +1,70 @@ +From a6532aa364e350224dcace082484a7cc58d678dc Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 10 Aug 2015 12:19:00 -0400 +Subject: [PATCH 41/45] Ticket 47686 - removing chaining database links trigger + valgrind read errors + +Bug Description: Plugins that remove their dse callback from the dse callback + function lead to invalid reads in dse_call_callback(). + +Fix Description: In dse_call_callback(), save the pointers to the next callback, + and its plugin, before we call the callback function. So in + case the callback function removes itself, we are not accessing + the freed callback pointer later on. + +https://fedorahosted.org/389/ticket/47686 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit a799c4670f2e6f6be1fc9a2828dc4a0f738d3021) +(cherry picked from commit 29c669e43e16611a290e1c82dfdcf5b51903319e) +--- + ldap/servers/slapd/dse.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c +index 61e2629..e8e393b 100644 +--- a/ldap/servers/slapd/dse.c ++++ b/ldap/servers/slapd/dse.c +@@ -2607,18 +2607,21 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int operation, int flags, + + if (pdse->dse_callback != NULL) { + struct dse_callback *p = pdse->dse_callback; ++ struct dse_callback *next = NULL; + int result = SLAPI_DSE_CALLBACK_OK; + + while (p != NULL) { ++ next = p->next; + if ((p->operation & operation) && (p->flags & flags)) { + if(slapi_sdn_scope_test(slapi_entry_get_sdn_const(entryBefore), p->base, p->scope)){ + if(NULL == p->slapifilter || slapi_vattr_filter_test(pb, entryBefore, p->slapifilter, 0) == 0){ ++ struct slapdplugin *plugin = p->plugin; + int plugin_started = 1; + +- if(p->plugin){ ++ if(plugin){ + /* this is a plugin callback, update the operation counter */ +- slapi_plugin_op_started(p->plugin); +- if(!p->plugin->plg_started){ ++ slapi_plugin_op_started(plugin); ++ if(!plugin->plg_started){ + /* must be a task function being called */ + result = SLAPI_DSE_CALLBACK_ERROR; + PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, +@@ -2633,11 +2636,11 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int operation, int flags, + if(result < rc){ + rc = result; + } +- slapi_plugin_op_finished(p->plugin); ++ slapi_plugin_op_finished(plugin); + } + } + } +- p = p->next; ++ p = next; + } + } + return rc; +-- +1.9.3 + diff --git a/SOURCES/0041-Ticket-47969-Fix-coverity-issue.patch b/SOURCES/0041-Ticket-47969-Fix-coverity-issue.patch deleted file mode 100644 index a99e54a..0000000 --- a/SOURCES/0041-Ticket-47969-Fix-coverity-issue.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 64010b34bb2ca9c62c6cfff70ce406bcaacef8b0 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 8 Dec 2014 09:57:50 -0500 -Subject: [PATCH 41/53] Ticket 47969 - Fix coverity issue - -Description: Fix coverity issue 12948 & 12949 (NULL pointer dereference) - -https://fedorahosted.org/389/ticket/47969 - -Reviewed by: mreynolds - -(cherry picked from commit 1553b665bfecbbccd54c439442d9a22c5d35d4a1) -(cherry picked from commit af163d345b4524c121296626cb2e9da26d6d061e) ---- - ldap/servers/plugins/cos/cos_cache.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index fd163f9..a74389d 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -1863,9 +1863,9 @@ static void cos_cache_del_schema(cosCache *pCache) - cos_cache_del_attrval_list(&(pCache->ppAttrIndex[attr_index]->pObjectclasses)); - } - } -+ /* Finally, remove the first attribute's objectclass list */ -+ cos_cache_del_attrval_list(&(pCache->ppAttrIndex[0]->pObjectclasses)); - } -- /* Finally, remove the first attribute's objectclass list */ -- cos_cache_del_attrval_list(&(pCache->ppAttrIndex[0]->pObjectclasses)); - - LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_del_schema\n",0,0,0); - } --- -1.9.3 - diff --git a/SOURCES/0042-Ticket-47511-bashisms-in-389-ds-base-admin-scripts.patch b/SOURCES/0042-Ticket-47511-bashisms-in-389-ds-base-admin-scripts.patch new file mode 100644 index 0000000..067ca01 --- /dev/null +++ b/SOURCES/0042-Ticket-47511-bashisms-in-389-ds-base-admin-scripts.patch @@ -0,0 +1,1250 @@ +From 9075d78f6878907f676fda1062779c921b23ae59 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Mon, 10 Aug 2015 17:04:25 -0700 +Subject: [PATCH 42/45] Ticket #47511 - bashisms in 389-ds-base admin scripts + +Description by mvocu (Thank you): +The shell scripts in 389-ds-base/ldap/admin/src/scripts use 'source' +to source common scripts; the 'source' keyword is bash-specific (or +c-shell, if memory serves). The interpreter is set to /bin/sh, which +is not guaranteed to be bash (and at least on Debian 7.1 it is dash). +The 'source' keyword can be replaced by '.', which should work. + +The patch was provided by tjaalton@ubuntu.com (Thank you, Timo!). + +https://fedorahosted.org/389/ticket/47511 + +Reviewed and tested by nhosoi@redhat.com. + +(cherry picked from commit 2ce7a7334bcb89e47c0f5c544144aec37010a5b9) +(cherry picked from commit 49245911410cdd04bc53b00d8973c26defa5a37b) +--- + ldap/admin/src/initconfig.in | 4 +- + ldap/admin/src/scripts/DSSharedLib.in | 92 +++++++++++++++---------------- + ldap/admin/src/scripts/bak2db.in | 23 ++++---- + ldap/admin/src/scripts/db2bak.in | 7 +-- + ldap/admin/src/scripts/db2index.in | 4 +- + ldap/admin/src/scripts/db2ldif.in | 22 ++++---- + ldap/admin/src/scripts/dbverify.in | 6 +- + ldap/admin/src/scripts/dn2rdn.in | 4 +- + ldap/admin/src/scripts/ldif2db.in | 4 +- + ldap/admin/src/scripts/ldif2ldap.in | 46 ++++++++-------- + ldap/admin/src/scripts/monitor.in | 44 +++++++-------- + ldap/admin/src/scripts/restart-dirsrv.in | 2 +- + ldap/admin/src/scripts/restoreconfig.in | 4 +- + ldap/admin/src/scripts/saveconfig.in | 6 +- + ldap/admin/src/scripts/start-dirsrv.in | 16 +++--- + ldap/admin/src/scripts/stop-dirsrv.in | 14 ++--- + ldap/admin/src/scripts/suffix2instance.in | 6 +- + ldap/admin/src/scripts/upgradedb.in | 4 +- + ldap/admin/src/scripts/upgradednformat.in | 6 +- + ldap/admin/src/scripts/vlvindex.in | 4 +- + rpm/389-ds-base-git.sh | 2 +- + rpm/add_patches.sh | 4 +- + rpm/rpmverrel.sh | 2 +- + wrappers/initscript.in | 26 +++------ + wrappers/ldap-agent-initscript.in | 28 ++++------ + 25 files changed, 181 insertions(+), 199 deletions(-) + +diff --git a/ldap/admin/src/initconfig.in b/ldap/admin/src/initconfig.in +index 134e82c..7afa315 100644 +--- a/ldap/admin/src/initconfig.in ++++ b/ldap/admin/src/initconfig.in +@@ -2,11 +2,11 @@ + OS=`uname -s` + # use the new mt slab memory allocator on Solaris + # this requires Solaris 9 update 3 or later +-if [ "$OS" = "SunOS" -a -f /usr/lib/libumem.so ] ; then ++if [ "$OS" = "SunOS" ] && [ -f /usr/lib/libumem.so ] ; then + LD_PRELOAD=/usr/lib/libumem.so + export LD_PRELOAD + fi +-if [ "$OS" = "SunOS" -a -f /usr/lib/64/libumem.so ] ; then ++if [ "$OS" = "SunOS" ] && [ -f /usr/lib/64/libumem.so ] ; then + LD_PRELOAD_64=/usr/lib/64/libumem.so + export LD_PRELOAD_64 + fi +diff --git a/ldap/admin/src/scripts/DSSharedLib.in b/ldap/admin/src/scripts/DSSharedLib.in +index 3683696..8317c58 100644 +--- a/ldap/admin/src/scripts/DSSharedLib.in ++++ b/ldap/admin/src/scripts/DSSharedLib.in +@@ -98,13 +98,13 @@ get_init_file() + do + inst_count=`expr $inst_count + 1` + id=`normalize_server_id $configfile` +- if [ -n "$servid" -a "$id" = "$servid" ] ++ if [ -n "$servid" ] && [ "$id" = "$servid" ] + then + # found it + echo $configfile + exit 0 + fi +- if [ $first == "yes" ] ++ if [ $first = "yes" ] + then + instances=$id + first="no" +@@ -114,7 +114,7 @@ get_init_file() + done + + # server id not provided, check if there is only one instance +- if [ -z "$servid" -a $inst_count -eq 1 ] ++ if [ -z "$servid" ] && [ $inst_count -eq 1 ] + then + # return the file + echo $configfile +@@ -135,48 +135,44 @@ process_dse () + configdir=$1 + pid=$2 + file="$configdir/dse.ldif" +- shopt -s nocasematch +- OLD_IFC=$IFC ++ OLD_IFS=$IFS + IFS="" + while read -r LINE + do +- if [[ $LINE != \ * ]] && [ "$output" != "" ] ++ case $LINE in ++ ' '*) ++ ;; ++ *) ++ if [ -n "$output" ] ++ then ++ echo "$output" >> /tmp/DSSharedLib.$pid ++ output="" ++ fi ++ ;; ++ esac ++ if [ -n "$output" ] + then +- echo "$output" >> /tmp/DSSharedLib.$pid +- output="" +- fi +- if [ "$output" != "" ] && [[ $LINE == \ * ]] +- then +- # continuation line, strip the space and append it +- LINE=`echo "$LINE" | sed -e 's/^ //'` +- output=$output$LINE +- elif [[ $LINE == nsslapd-port* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-localhost* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-securePort* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-security* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-ldapilisten* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-ldapifilepath* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-rootdn* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-ldapiautobind* ]] +- then +- output=$LINE; +- elif [[ $LINE == nsslapd-certdir* ]] +- then +- output=$LINE; ++ case $LINE in ++ ' '*) ++ # continuation line, strip the space and append it ++ LINE=`echo "$LINE" | sed -e 's/^ //'` ++ output=$output$LINE ++ ;; ++ esac ++ else ++ case $LINE in ++ nsslapd-certdir*|\ ++ nsslapd-ldapiautobind*|\ ++ nsslapd-ldapilisten*|\ ++ nsslapd-ldapifilepath*|\ ++ nsslapd-localhost*|\ ++ nsslapd-port*|\ ++ nsslapd-rootdn*|\ ++ nsslapd-securePort*|\ ++ nsslapd-security*) ++ output=$LINE ++ ;; ++ esac + fi + + done < $file +@@ -194,19 +190,19 @@ check_protocol () + ldapi=$3 + openldap=$4 + +- if [ "$protocol" == "LDAPI" ] && [ "$openldap" != "yes" ]; then ++ if [ "$protocol" = "LDAPI" ] && [ "$openldap" != "yes" ]; then + echo "" + exit +- elif [ "$protocol" == "LDAPI" ] && [ "$ldapi" == "off" ]; then ++ elif [ "$protocol" = "LDAPI" ] && [ "$ldapi" = "off" ]; then + echo "" + exit +- elif [ "$protocol" == "STARTTLS" ]; then +- if [ "$security" == "" ] || [ "$security" == "off" ]; then ++ elif [ "$protocol" = "STARTTLS" ]; then ++ if [ -z "$security" ] || [ "$security" = "off" ]; then + echo "" + exit + fi +- elif [ "$protocol" == "LDAPS" ]; then +- if [ "$security" == "" ] || [ "$security" == "off" ]; then ++ elif [ "$protocol" = "LDAPS" ]; then ++ if [ -z "$security" ] || [ "$security" = "off" ]; then + echo "" + exit + fi +@@ -224,4 +220,4 @@ check_protocol () + fi + + echo "$protocol" +-} +\ No newline at end of file ++} +diff --git a/ldap/admin/src/scripts/bak2db.in b/ldap/admin/src/scripts/bak2db.in +index f0cede4..a2e54cc 100755 +--- a/ldap/admin/src/scripts/bak2db.in ++++ b/ldap/admin/src/scripts/bak2db.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -26,15 +26,18 @@ if [ $# -lt 1 ] || [ $# -gt 7 ] + then + usage + exit 1 +-elif [[ $1 == -* ]] +-then +- usage +- exit 1 +-else +- archivedir=$1 +- shift + fi +- ++case $1 in ++ -*) ++ usage ++ exit 1 ++ ;; ++ *) ++ archivedir=$1 ++ shift ++ ;; ++esac ++ + while getopts "hn:Z:qd:vi:a:SD:" flag + do + case $flag in +@@ -55,7 +58,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/db2bak.in b/ldap/admin/src/scripts/db2bak.in +index dacd7b0..1896c19 100755 +--- a/ldap/admin/src/scripts/db2bak.in ++++ b/ldap/admin/src/scripts/db2bak.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -26,7 +26,6 @@ then + usage + exit 1 + fi +- + if [ "$#" -gt 0 ] + then + if [[ $1 != -* ]] +@@ -56,7 +55,7 @@ done + + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +@@ -67,7 +66,7 @@ fi + servid=`normalize_server_id $initfile` + . $initfile + +-if [ -z $bak_dir ] ++if [ -z "$bak_dir" ] + then + bak_dir=@localstatedir@/lib/@PACKAGE_NAME@/slapd-$servid/bak/$servid-`date +%Y_%m_%d_%H_%M_%S` + fi +diff --git a/ldap/admin/src/scripts/db2index.in b/ldap/admin/src/scripts/db2index.in +index a1321ea..2b76cd1 100755 +--- a/ldap/admin/src/scripts/db2index.in ++++ b/ldap/admin/src/scripts/db2index.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -59,7 +59,7 @@ then + fi + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/db2ldif.in b/ldap/admin/src/scripts/db2ldif.in +index d7e0ff0..fcf73a0 100755 +--- a/ldap/admin/src/scripts/db2ldif.in ++++ b/ldap/admin/src/scripts/db2ldif.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -39,7 +39,7 @@ make_ldiffile() + be="" + while [ "$1" != "" ] + do +- if [ "$1" = "-a" ]; then ++ if [ "x$1" = "x-a" ]; then + shift + if [ `expr "$1" : "/.*"` -gt 0 ]; then + if [ `expr "$1" : "/.*"` -gt 0 ]; then +@@ -56,17 +56,17 @@ make_ldiffile() + shift + return 0 + fi +- elif [ "$1" = "-n" ]; then ++ elif [ "x$1" = "x-n" ]; then + shift +- if [ "$be" = "" ]; then ++ if [ -z "$be" ]; then + be="$1" + else + tmpbe="$be" + be="${tmpbe}-$1" + fi +- elif [ "$1" = "-s" ]; then ++ elif [ "x$1" = "x-s" ]; then + shift +- if [ "$1" != "" ]; then ++ if [ -n "$1" ]; then + rdn=`echo $1 | awk -F, '{print $1}'` + rdnval=`echo $rdn | awk -F= '{print $2}'` + if [ "$be" = "" ]; then +@@ -76,15 +76,15 @@ make_ldiffile() + be="${tmpbe}-$rdnval" + fi + fi +- elif [ "$1" = "-M" ]; then ++ elif [ "x$1" = "x-M" ]; then + be="" + fi +- if [ "$1" != "" ]; then ++ if [ -n "$1" ]; then + shift + fi + done + +- if [ "$be" = "" ]; then ++ if [ -z "$be" ]; then + echo @localstatedir@/lib/@PACKAGE_NAME@/slapd-$servid/ldif/$servid-`date +%Y_%m_%d_%H%M%S`.ldif + else + echo @localstatedir@/lib/@PACKAGE_NAME@/slapd-$servid/ldif/$servid-${be}-`date +%Y_%m_%d_%H%M%S`.ldif +@@ -92,7 +92,7 @@ make_ldiffile() + return 0 + } + +-if [ "$#" -lt 2 ]; ++if [ $# -lt 2 ]; + then + usage + exit 1 +@@ -137,7 +137,7 @@ then + fi + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/dbverify.in b/ldap/admin/src/scripts/dbverify.in +index 461cc16..bbacc17 100755 +--- a/ldap/admin/src/scripts/dbverify.in ++++ b/ldap/admin/src/scripts/dbverify.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -47,7 +47,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +@@ -58,7 +58,7 @@ fi + . $initfile + + @sbindir@/ns-slapd dbverify -D $CONFIG_DIR $args +-if [ $display_version == "yes" ]; then ++if [ $display_version = "yes" ]; then + exit 0 + fi + if [ $? -eq 0 ]; then +diff --git a/ldap/admin/src/scripts/dn2rdn.in b/ldap/admin/src/scripts/dn2rdn.in +index 32a70c8..616969a 100755 +--- a/ldap/admin/src/scripts/dn2rdn.in ++++ b/ldap/admin/src/scripts/dn2rdn.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -39,7 +39,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/ldif2db.in b/ldap/admin/src/scripts/ldif2db.in +index ce15349..a34241a 100755 +--- a/ldap/admin/src/scripts/ldif2db.in ++++ b/ldap/admin/src/scripts/ldif2db.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -82,7 +82,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/ldif2ldap.in b/ldap/admin/src/scripts/ldif2ldap.in +index 874b1bb..1e871be 100755 +--- a/ldap/admin/src/scripts/ldif2ldap.in ++++ b/ldap/admin/src/scripts/ldif2ldap.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@ldapsdk_libdir@" + libpath_add "@libdir@" +@@ -40,14 +40,14 @@ do + esac + done + +-if [ "$input_file" == "" ] ++if [ -z "$input_file" ] + then + usage + exit 1 + fi + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +@@ -67,13 +67,13 @@ ldapi=$(grep -i 'nsslapd-ldapilisten' $file | awk '{print $2}' ) + ldapiURL=$(grep -i 'nsslapd-ldapifilepath' $file | awk '{print $2}' ) + certdir=$(grep -i 'nsslapd-certdir' $file | awk '{print $2}' ) + autobind=$(grep -i 'nsslapd-ldapiautobind' $file | awk '{print $2}' ) +-if [ "$rootdn" == "" ]; then ++if [ -z "$rootdn" ]; then + value=$(grep -i 'nsslapd-rootdn' $file) + rootdn=`echo "$value" | sed -e 's/nsslapd-rootdn: //i'` + fi + rm $file + +-if [ "$ldapiURL" != "" ]; then ++if [ -n "$ldapiURL" ]; then + ldapiURL=`echo "$ldapiURL" | sed -e 's/\//%2f/g'` + ldapiURL="ldapi://"$ldapiURL + fi +@@ -86,7 +86,7 @@ then + export LDAPTLS_CACERTDIR=$certdir + fi + +-if [ -z $security ]; then ++if [ -z "$security" ]; then + security="off" + fi + revised_protocol=$(check_protocol $protocol $security $ldapi $openldap) +@@ -99,12 +99,12 @@ protocol=$revised_protocol + # + # STARTTLS + # +-if [ "$security" == "on" ]; then +- if [ "$protocol" == "STARTTLS" ] || [ "$protocol" == "" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$security" = "on" ]; then ++ if [ "$protocol" = "STARTTLS" ] || [ -z "$protocol" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(STARTTLS)" + fi +- if [ "$openldap" == "yes" ]; then ++ if [ "$openldap" = "yes" ]; then + ldapmodify -x -ZZ -p $port -h $host -D $rootdn -w $passwd -a -f $input_file + else + ldapmodify -ZZZ -P $certdir -p $port -h $host -D $rootdn -w $passwd -a -f $input_file +@@ -116,12 +116,12 @@ fi + # + # LDAPS + # +-if [ "$security" == "on" ]; then +- if [ "$protocol" == "LDAPS" ] || [ "$protocol" == "" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$security" = "on" ]; then ++ if [ "$protocol" = "LDAPS" ] || [ -z "$protocol" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAPS)" + fi +- if [ "$openldap" == "yes" ]; then ++ if [ "$openldap" = "yes" ]; then + ldapmodify -x -H "ldaps://$host:$secure_port" -D $rootdn -w $passwd -a -f $input_file + else + ldapmodify -Z -P $certdir -p $secure_port -h $host -D $rootdn -w $passwd -a -f $input_file +@@ -133,21 +133,21 @@ fi + # + # LDAPI + # +-if [ "$ldapi" == "on" ] && [ "$openldap" == "yes" ]; then +- if [ "$protocol" == "LDAPI" ] || [ "$protocol" == "" ]; then +- if [ "$(id -u)" == "0" ] && [ "$autobind" == "on" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$ldapi" = "on" ] && [ "$openldap" = "yes" ]; then ++ if [ "$protocol" = "LDAPI" ] || [ -z "$protocol" ]; then ++ if [ $(id -u) -eq 0 ] && [ "$autobind" = "on" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAPI/AUTOBIND)" + fi + ldapmodify -H $ldapiURL -Y EXTERNAL -a -f $input_file 2>/dev/null + else +- if [ "$error" == "yes" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAPI)" + fi + ldapmodify -x -H $ldapiURL -D $rootdn -w $passwd -a -f $input_file + fi + rc=$? +- if [ $rc != 0 ] ++ if [ $rc -ne 0 ] + then + echo "Operation failed (error $rc)" + fi +@@ -158,11 +158,11 @@ fi + # + # LDAP + # +-if [ "$protocol" == "LDAP" ] || [ "$protocol" == "" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$protocol" = "LDAP" ] || [ -z "$protocol" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAP)" + fi +- if [ "$openldap" == "yes" ]; then ++ if [ "$openldap" = "yes" ]; then + ldapmodify -x -p $port -h $host -D $rootdn -w $passwd -a -f $input_file + else + ldapmodify -p $port -h $host -D $rootdn -w $passwd -a -f $input_file +diff --git a/ldap/admin/src/scripts/monitor.in b/ldap/admin/src/scripts/monitor.in +index 7b2058b..36a2fc9 100755 +--- a/ldap/admin/src/scripts/monitor.in ++++ b/ldap/admin/src/scripts/monitor.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@ldapsdk_libdir@" +@@ -41,7 +41,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +@@ -66,17 +66,17 @@ ldapi=$(grep -i 'nsslapd-ldapilisten' $file | awk '{print $2}' ) + ldapiURL=$(grep -i 'nsslapd-ldapifilepath' $file | awk '{print $2}' ) + certdir=$(grep -i 'nsslapd-certdir' $file | awk '{print $2}' ) + autobind=$(grep -i 'nsslapd-ldapiautobind' $file | awk '{print $2}' ) +-if [ "$rootdn" == "" ]; then ++if [ -z "$rootdn" ]; then + value=$(grep -i 'nsslapd-rootdn' $file) + rootdn=`echo "$value" | sed -e 's/nsslapd-rootdn: //i'` + fi + rm $file + +-if [ "$passwd" != "" ]; then ++if [ -n "$passwd" ]; then + dn="-D $rootdn" + passwd="-w$passwd" + fi +-if [ "$ldapiURL" != "" ] ++if [ -n "$ldapiURL" ] + then + ldapiURL=`echo "$ldapiURL" | sed -e 's/\//%2f/g'` + ldapiURL="ldapi://"$ldapiURL +@@ -103,12 +103,12 @@ protocol=$revised_protocol + # + # STARTTLS + # +-if [ "$security" == "on" ]; then +- if [ "$protocol" == "STARTTLS" ] || [ "$protocol" == "" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$security" = "on" ]; then ++ if [ "$protocol" = "STARTTLS" ] || [ -z "$protocol" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(STARTTLS)" + fi +- if [ "$openldap" == "yes" ]; then ++ if [ "$openldap" = "yes" ]; then + ldapsearch -x -LLL -ZZ -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" + else + ldapsearch -ZZZ -P $certdir -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" +@@ -120,12 +120,12 @@ fi + # + # LDAPS + # +-if [ "$security" == "on" ]; then +- if [ "$protocol" == "LDAPS" ] || [ "$protocol" == "" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$security" = "on" ]; then ++ if [ "$protocol" = "LDAPS" ] || [ -z "$protocol" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAPS)" + fi +- if [ "$openldap" == "yes" ]; then ++ if [ "$openldap" = "yes" ]; then + ldapsearch -x -LLL -H "ldaps://$host:$secure_port" -b "$MDN" -s base $dn $passwd "objectClass=*" + else + ldapsearch -Z -P $certdir -p $secure_port -b "$MDN" -s base $dn $passwd "objectClass=*" +@@ -137,15 +137,15 @@ fi + # + # LDAPI + # +-if [ "$ldapi" == "on" ] && [ "$openldap" == "yes" ]; then +- if [ "$protocol" == "LDAPI" ] || [ "$protocol" == "" ]; then +- if [ "$(id -u)" == "0" ] && [ "$autobind" == "on" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$ldapi" = "on" ] && [ "$openldap" = "yes" ]; then ++ if [ "$protocol" = "LDAPI" ] || [ -z "$protocol" ]; then ++ if [ $(id -u) -eq 0 ] && [ "$autobind" = "on" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAPI/AUTOBIND)" + fi + ldapsearch -LLL -H "$ldapiURL" -b "$MDN" -s base -Y EXTERNAL "objectClass=*" 2>/dev/null + else +- if [ "$error" == "yes" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAPI)" + fi + ldapsearch -x -LLL -H "$ldapiURL" -b "$MDN" -s base $dn $passwd "objectClass=*" +@@ -157,14 +157,14 @@ fi + # + # LDAP + # +-if [ "$protocol" == "LDAP" ] || [ "$protocol" == "" ]; then +- if [ "$error" == "yes" ]; then ++if [ "$protocol" = "LDAP" ] || [ "$protocol" = "" ]; then ++ if [ "$error" = "yes" ]; then + echo "Using the next most secure protocol(LDAP)" + fi +- if [ "$openldap" == "yes" ]; then ++ if [ "$openldap" = "yes" ]; then + ldapsearch -x -LLL -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" + else + ldapsearch -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" +- fi ++ fi + exit $? + fi +diff --git a/ldap/admin/src/scripts/restart-dirsrv.in b/ldap/admin/src/scripts/restart-dirsrv.in +index 130e06e..e86a24c 100644 +--- a/ldap/admin/src/scripts/restart-dirsrv.in ++++ b/ldap/admin/src/scripts/restart-dirsrv.in +@@ -7,7 +7,7 @@ + # 2: Server started successfully (was not running) + # 3: Server could not be stopped + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + restart_instance() { + SERV_ID=$1 +diff --git a/ldap/admin/src/scripts/restoreconfig.in b/ldap/admin/src/scripts/restoreconfig.in +index 9bb1acf..56c9e43 100755 +--- a/ldap/admin/src/scripts/restoreconfig.in ++++ b/ldap/admin/src/scripts/restoreconfig.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@nss_libdir@" +@@ -31,7 +31,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/saveconfig.in b/ldap/admin/src/scripts/saveconfig.in +index 65d80f3..16e3efc 100755 +--- a/ldap/admin/src/scripts/saveconfig.in ++++ b/ldap/admin/src/scripts/saveconfig.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@libdir@" +@@ -31,7 +31,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +@@ -45,7 +45,7 @@ servid=`normalize_server_id $initfile` + echo saving configuration... + conf_ldif=@localstatedir@/lib/@PACKAGE_NAME@/slapd-$servid/bak/$servid-`date +%Y_%m_%d_%H%M%S`.ldif + @sbindir@/ns-slapd db2ldif -N -D $CONFIG_DIR -s "o=NetscapeRoot" -a $conf_ldif -n NetscapeRoot 2>&1 +-if [ "$?" -ge 1 ] ++if [ $? -ge 1 ] + then + echo Error occurred while saving configuration + exit 1 +diff --git a/ldap/admin/src/scripts/start-dirsrv.in b/ldap/admin/src/scripts/start-dirsrv.in +index 481797d..458f0e8 100755 +--- a/ldap/admin/src/scripts/start-dirsrv.in ++++ b/ldap/admin/src/scripts/start-dirsrv.in +@@ -6,7 +6,7 @@ + # 1: Server could not be started + # 2: Server already running + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + # Starts a single instance + start_instance() { +@@ -44,7 +44,7 @@ start_instance() { + STARTPIDFILE=$RUN_DIR/$PRODUCT_NAME-$SERV_ID.startpid + if test -f $STARTPIDFILE ; then + PID=`cat $STARTPIDFILE` +- if kill -0 $PID > /dev/null 2>&1 ; then ++ if kill -s 0 $PID > /dev/null 2>&1 ; then + echo There is an ns-slapd process already running: $PID + return 2; + else +@@ -53,7 +53,7 @@ start_instance() { + fi + if test -f $PIDFILE ; then + PID=`cat $PIDFILE` +- if kill -0 $PID > /dev/null 2>&1 ; then ++ if kill -s 0 $PID > /dev/null 2>&1 ; then + echo There is an ns-slapd running: $PID + return 2; + else +@@ -64,7 +64,7 @@ start_instance() { + # Use systemctl if available and running as root, + # otherwise start the instance the old way. + # +- if [ -d "@systemdsystemunitdir@" ] && [ "$(id -u)" == "0" ];then ++ if [ -d "@systemdsystemunitdir@" ] && [ $(id -u) -eq 0 ];then + @bindir@/systemctl start @package_name@@$SERV_ID.service + if [ $? -ne 0 ]; then + return 1 +@@ -96,7 +96,7 @@ start_instance() { + while test $loop_counter -le $max_count; do + loop_counter=`expr $loop_counter + 1` + if test ! -f $PIDFILE ; then +- if kill -0 $PID > /dev/null 2>&1 ; then ++ if kill -s 0 $PID > /dev/null 2>&1 ; then + sleep 1 + else + echo Server failed to start !!! Please check errors log for problems +@@ -123,12 +123,12 @@ do + done + shift $(($OPTIND-1)) + +-if [ "$initconfig_dir" = "" ]; then ++if [ -z "$initconfig_dir" ]; then + initconfig_dir=@initconfigdir@ + fi + + found=0 +-if [ "$#" -eq 0 ]; then ++if [ $# -eq 0 ]; then + # We're starting all instances. + ret=0 + initfiles=`get_initconfig_files $initconfig_dir` || { echo No instances found in $initconfig_dir ; exit 1 ; } +@@ -137,7 +137,7 @@ if [ "$#" -eq 0 ]; then + echo Starting instance \"$inst\" + start_instance $inst + rv=$? +- if [ "$rv" -ne 0 ]; then ++ if [ $rv -ne 0 ]; then + ret=$rv + fi + done +diff --git a/ldap/admin/src/scripts/stop-dirsrv.in b/ldap/admin/src/scripts/stop-dirsrv.in +index 3f02e78..72e2b85 100755 +--- a/ldap/admin/src/scripts/stop-dirsrv.in ++++ b/ldap/admin/src/scripts/stop-dirsrv.in +@@ -6,7 +6,7 @@ + # 1: Server could not be stopped + # 2: Server was not running + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + stop_instance() { + SERV_ID=$1 +@@ -28,7 +28,7 @@ stop_instance() { + fi + PID=`cat $PIDFILE` + # see if the server is already stopped +- kill -0 $PID > /dev/null 2>&1 || { ++ kill -s 0 $PID > /dev/null 2>&1 || { + echo Server not running + if test -f $PIDFILE ; then + rm -f $PIDFILE +@@ -39,7 +39,7 @@ stop_instance() { + # + # use systemctl if running as root + # +- if [ -d "@systemdsystemunitdir@" ] && [ "$(id -u)" == "0" ];then ++ if [ -d "@systemdsystemunitdir@" ] && [ $(id -u) -eq 0 ];then + # + # Now, check if systemctl is aware of this running instance + # +@@ -65,7 +65,7 @@ stop_instance() { + max_count=600 + while test $loop_counter -le $max_count; do + loop_counter=`expr $loop_counter + 1` +- if kill -0 $PID > /dev/null 2>&1 ; then ++ if kill -s 0 $PID > /dev/null 2>&1 ; then + sleep 1; + else + if test -f $PIDFILE ; then +@@ -88,11 +88,11 @@ do + done + shift $(($OPTIND-1)) + +-if [ "$initconfig_dir" = "" ]; then ++if [ -z "$initconfig_dir" ]; then + initconfig_dir=@initconfigdir@ + fi + +-if [ "$#" -eq 0 ]; then ++if [ $# -eq 0 ]; then + # We're stopping all instances. + ret=0 + initfiles=`get_initconfig_files $initconfig_dir` || { echo No instances found in $initconfig_dir ; exit 1 ; } +@@ -105,7 +105,7 @@ if [ "$#" -eq 0 ]; then + echo Stopping instance \"$inst\" + stop_instance $inst + rv=$? +- if [ "$rv" -ne 0 ]; then ++ if [ $rv -ne 0 ]; then + ret=$rv + fi + done +diff --git a/ldap/admin/src/scripts/suffix2instance.in b/ldap/admin/src/scripts/suffix2instance.in +index e2f73c3..7774148 100755 +--- a/ldap/admin/src/scripts/suffix2instance.in ++++ b/ldap/admin/src/scripts/suffix2instance.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@libdir@" +@@ -32,14 +32,14 @@ do + esac + done + +-if [ "$args" == "" ] ++if [ -z "$args" ] + then + usage + exit 1 + fi + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/upgradedb.in b/ldap/admin/src/scripts/upgradedb.in +index 211bdce..bf600dd 100755 +--- a/ldap/admin/src/scripts/upgradedb.in ++++ b/ldap/admin/src/scripts/upgradedb.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@libdir@" +@@ -39,7 +39,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" + echo "Available instances: $initfile" +diff --git a/ldap/admin/src/scripts/upgradednformat.in b/ldap/admin/src/scripts/upgradednformat.in +index e9d8cab..51585ae 100755 +--- a/ldap/admin/src/scripts/upgradednformat.in ++++ b/ldap/admin/src/scripts/upgradednformat.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + # upgradednformat -- upgrade DN format to the new style (RFC 4514) + # Usgae: upgradednformat [-N] -n backend_instance -a db_instance_directory +@@ -49,13 +49,13 @@ do + esac + done + +-if [ "$be" = "" ] || [ "$dir" = "" ]; then ++if [ -z "$be" ] || [ -z "$dir" ]; then + usage + exit 1 + fi + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/ldap/admin/src/scripts/vlvindex.in b/ldap/admin/src/scripts/vlvindex.in +index 0b46b27..365e32f 100755 +--- a/ldap/admin/src/scripts/vlvindex.in ++++ b/ldap/admin/src/scripts/vlvindex.in +@@ -1,6 +1,6 @@ + #!/bin/sh + +-source @datadir@/@package_name@/data/DSSharedLib ++. @datadir@/@package_name@/data/DSSharedLib + + libpath_add "@libdir@/@package_name@/" + libpath_add "@libdir@" +@@ -45,7 +45,7 @@ do + done + + initfile=$(get_init_file "@initconfigdir@" $servid) +-if [ $? == 1 ] ++if [ $? -eq 1 ] + then + usage + echo "You must supply a valid server instance identifier. Use -Z to specify instance name" +diff --git a/rpm/389-ds-base-git.sh b/rpm/389-ds-base-git.sh +index e5aaa8a..1a38da1 100644 +--- a/rpm/389-ds-base-git.sh ++++ b/rpm/389-ds-base-git.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/bin/sh + + DATE=`date +%Y%m%d` + # use a real tag name here +diff --git a/rpm/add_patches.sh b/rpm/add_patches.sh +index 690d0b2..31823d5 100755 +--- a/rpm/add_patches.sh ++++ b/rpm/add_patches.sh +@@ -1,6 +1,6 @@ + #!/bin/sh + +-function usage() ++usage() + { + echo "Adds patches to a specfile" + echo "" +@@ -51,5 +51,5 @@ for p in $patches; do + sed -i -e "/${prefix}/a Patch${i}: ${p}" -e "/$prepprefix/a %patch${i} -p1" $specfile + prefix="Patch${i}:" + prepprefix="%patch${i}" +- i=$(($i+1)) ++ i=`expr $i + 1` + done +diff --git a/rpm/rpmverrel.sh b/rpm/rpmverrel.sh +index 86b808e..06e97c7 100755 +--- a/rpm/rpmverrel.sh ++++ b/rpm/rpmverrel.sh +@@ -6,7 +6,7 @@ srcdir=`pwd` + + # Source VERSION.sh to set the version + # and release environment variables. +-source ./VERSION.sh ++. ./VERSION.sh + + if [ "$1" = "version" ]; then + echo $RPM_VERSION +diff --git a/wrappers/initscript.in b/wrappers/initscript.in +index ad4ea2b..fa79dbd 100644 +--- a/wrappers/initscript.in ++++ b/wrappers/initscript.in +@@ -32,28 +32,20 @@ then + fi + fi + +-# figure out which echo we're using +-ECHO_N=`echo -n` +- +-# some shells echo cannot use -n - linux echo by default cannot use \c + echo_n() + { +- if [ "$ECHO_N" = '-n' ] ; then +- echo "$*\c" +- else +- echo -n "$*" +- fi ++ printf '%s' "$*" + } + + # failure and success are not defined on some platforms +-type failure > /dev/null 2>&1 || { ++which failure > /dev/null 2>&1 || { + failure() + { + echo_n " FAILED" + } + } + +-type success > /dev/null 2>&1 || { ++which success > /dev/null 2>&1 || { + success() + { + echo_n " SUCCESS" +@@ -178,7 +170,7 @@ start() { + pid=`cat $pidfile` + instlockfile="@localstatedir@/lock/@package_name@/slapd-$instance/server/$pid" + name=`ps -p $pid | tail -1 | awk '{ print $4 }'` +- if kill -0 $pid && [ $name = "ns-slapd" ]; then ++ if kill -s 0 $pid && [ $name = "ns-slapd" ]; then + echo_n " already running" + success; echo + successes=`expr $successes + 1` +@@ -239,7 +231,7 @@ start() { + while test $loop_counter -le $max_count ; do + loop_counter=`expr $loop_counter + 1` + if test ! -f $pidfile ; then +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + sleep 1 + else + break +@@ -249,7 +241,7 @@ start() { + break + fi + done +- if kill -0 $pid > /dev/null 2>&1 && test -f $pidfile ; then ++ if kill -s 0 $pid > /dev/null 2>&1 && test -f $pidfile ; then + success; echo + successes=`expr $successes + 1` + else +@@ -278,7 +270,7 @@ stop() { + if [ -f $pidfile ]; then + pid=`cat $pidfile` + server_stopped=0 +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + kill $pid + if [ $? -eq 0 ]; then + server_stopped=1 +@@ -297,7 +289,7 @@ stop() { + max_count=600 + while test $loop_counter -le $max_count; do + loop_counter=`expr $loop_counter + 1` +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + sleep 1 + else + if test -f $pidfile ; then +@@ -339,7 +331,7 @@ status() { + for instance in $INSTANCES; do + if [ -f $piddir/slapd-$instance.pid ]; then + pid=`cat $piddir/slapd-$instance.pid` +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + echo "$prog $instance (pid $pid) is running..." + else + echo "$prog $instance dead but pid file exists" +diff --git a/wrappers/ldap-agent-initscript.in b/wrappers/ldap-agent-initscript.in +index dd8ee97..b7aa4fe 100644 +--- a/wrappers/ldap-agent-initscript.in ++++ b/wrappers/ldap-agent-initscript.in +@@ -31,28 +31,20 @@ then + fi + fi + +-# figure out which echo we're using +-ECHO_N=`echo -n` +- +-# some shells echo cannot use -n - linux echo by default cannot use \c + echo_n() + { +- if [ "$ECHO_N" = '-n' ] ; then +- echo "$*\c" +- else +- echo -n "$*" +- fi ++ printf '%s' "$*" + } + + # failure and success are not defined on some platforms +-type failure > /dev/null 2>&1 || { ++which failure > /dev/null 2>&1 || { + failure() + { + echo_n " FAILED" + } + } + +-type success > /dev/null 2>&1 || { ++which success > /dev/null 2>&1 || { + success() + { + echo_n " SUCCESS" +@@ -92,7 +84,7 @@ start() { + if [ -f $pidfile ]; then + pid=`cat $pidfile` + name=`ps -p $pid | tail -1 | awk '{ print $4 }'` +- if kill -0 $pid && [ $name = "$processname" ]; then ++ if kill -s 0 $pid && [ $name = "$processname" ]; then + echo_n " already running" + success; echo + subagent_running=1 +@@ -121,7 +113,7 @@ start() { + while test $loop_counter -le $max_count ; do + loop_counter=`expr $loop_counter + 1` + if test ! -f $pidfile ; then +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + sleep 1 + else + break +@@ -131,7 +123,7 @@ start() { + break + fi + done +- if kill -0 $pid > /dev/null 2>&1 && test -f $pidfile ; then ++ if kill -s 0 $pid > /dev/null 2>&1 && test -f $pidfile ; then + success; echo + else + failure; echo +@@ -147,7 +139,7 @@ stop() { + if [ -f $pidfile ]; then + pid=`cat $pidfile` + subagent_stopped=0 +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + kill $pid + if [ $? -eq 0 ]; then + subagent_stopped=1 +@@ -164,7 +156,7 @@ stop() { + max_count=10 + while test $loop_counter -le $max_count; do + loop_counter=`expr $loop_counter + 1` +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + sleep 1 + else + if test -f $pidfile ; then +@@ -200,7 +192,7 @@ condrestart() { + if [ -f $pidfile ]; then + pid=`cat $pidfile` + name=`ps -p $pid | tail -1 | awk '{ print $4 }'` +- if kill -0 $pid && [ $name = "$processname" ]; then ++ if kill -s 0 $pid && [ $name = "$processname" ]; then + restart + fi + fi +@@ -210,7 +202,7 @@ status() { + ret=0 + if [ -f $pidfile ]; then + pid=`cat $pidfile` +- if kill -0 $pid > /dev/null 2>&1 ; then ++ if kill -s 0 $pid > /dev/null 2>&1 ; then + echo "$prog (pid $pid) is running..." + else + echo "$prog dead but pid file exists" +-- +1.9.3 + diff --git a/SOURCES/0042-Ticket-47970-Account-lockout-attributes-incorrectly-.patch b/SOURCES/0042-Ticket-47970-Account-lockout-attributes-incorrectly-.patch deleted file mode 100644 index 4621245..0000000 --- a/SOURCES/0042-Ticket-47970-Account-lockout-attributes-incorrectly-.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 42d118ae0f727026745d7846ffab878585bb529a Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 2 Dec 2014 14:10:46 -0500 -Subject: [PATCH 42/53] Ticket 47970 - Account lockout attributes incorrectly - updated after failed SASL Bind - -Bug Description: When a SASL bind fails, the target DN is not set. If password policy - account lockout is configured, it attempts to update the password retry - count on the dn ("") - which is the Root DSE entry, not a user entry. - - This also confuses the COS plugin, and it incorrectly triggers a COS - cache rebuild after the failed login. - -Fix Description: Do not update the password retry counters if it is a failed SASL bind. - -https://fedorahosted.org/389/ticket/47970 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 17e79688e05908f7fff319bdeb5167cbeaaf922c) -(cherry picked from commit 36f0d05b15a8e984c64631fb7ed070358dd8c68f) ---- - ldap/servers/slapd/result.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c -index ca2fa43..2198337 100644 ---- a/ldap/servers/slapd/result.c -+++ b/ldap/servers/slapd/result.c -@@ -364,16 +364,18 @@ send_ldap_result_ext( - BerElement *ber - ) - { -- Connection *conn = pb->pb_conn; -- int i, rc, logit = 0; -- ber_tag_t tag; -- int flush_ber_element = 1; - Slapi_Operation *operation; -- const char *dn = NULL; -+ passwdPolicy *pwpolicy = NULL; -+ Connection *conn = pb->pb_conn; - Slapi_DN *sdn = NULL; -+ const char *dn = NULL; -+ ber_tag_t tag; -+ int flush_ber_element = 1; -+ int bind_method = 0; - int internal_op; -- passwdPolicy *pwpolicy = NULL; -- -+ int i, rc, logit = 0; -+ -+ slapi_pblock_get (pb, SLAPI_BIND_METHOD, &bind_method); - slapi_pblock_get (pb, SLAPI_OPERATION, &operation); - - if (operation->o_status == SLAPI_OP_STATUS_RESULT_SENT) { -@@ -451,7 +453,7 @@ send_ldap_result_ext( - - /* invalid password. Update the password retry here */ - /* put this here for now. It could be a send_result pre-op plugin. */ -- if (err == LDAP_INVALID_CREDENTIALS) { -+ if (err == LDAP_INVALID_CREDENTIALS && bind_method != LDAP_AUTH_SASL ) { - slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn ); - dn = slapi_sdn_get_dn(sdn); - pwpolicy = new_passwdPolicy(pb, dn); --- -1.9.3 - diff --git a/SOURCES/0043-Ticket-47970-add-lib389-testcase.patch b/SOURCES/0043-Ticket-47970-add-lib389-testcase.patch deleted file mode 100644 index 7be9579..0000000 --- a/SOURCES/0043-Ticket-47970-add-lib389-testcase.patch +++ /dev/null @@ -1,232 +0,0 @@ -From b10d004f6461a8dd5d5d2766cf95e92c5d94927e Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 4 Dec 2014 15:57:40 -0500 -Subject: [PATCH 43/53] Ticket 47970 - add lib389 testcase - -https://fedorahosted.org/389/ticket/47970 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit f6929c9b7c24a43b019e966b1fc37d33b21274a1) -(cherry picked from commit b6cd13f49713fecf6b2c94a31e25cd726e216c65) ---- - dirsrvtests/tickets/ticket47970_test.py | 206 ++++++++++++++++++++++++++++++++ - 1 file changed, 206 insertions(+) - create mode 100644 dirsrvtests/tickets/ticket47970_test.py - -diff --git a/dirsrvtests/tickets/ticket47970_test.py b/dirsrvtests/tickets/ticket47970_test.py -new file mode 100644 -index 0000000..49d505a ---- /dev/null -+++ b/dirsrvtests/tickets/ticket47970_test.py -@@ -0,0 +1,206 @@ -+import os -+import sys -+import time -+import ldap -+import ldap.sasl -+import logging -+import socket -+import pytest -+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 constants import * -+ -+log = logging.getLogger(__name__) -+ -+installation_prefix = None -+ -+USER1_DN = "uid=user1,%s" % DEFAULT_SUFFIX -+USER2_DN = "uid=user2,%s" % DEFAULT_SUFFIX -+ -+ -+class TopologyStandalone(object): -+ def __init__(self, standalone): -+ standalone.open() -+ self.standalone = standalone -+ -+ -+@pytest.fixture(scope="module") -+def topology(request): -+ ''' -+ This fixture is used to standalone topology for the 'module'. -+ At the beginning, It may exists a standalone instance. -+ It may also exists a backup for the standalone instance. -+ -+ Principle: -+ If standalone instance exists: -+ restart it -+ If backup of standalone exists: -+ create/rebind to standalone -+ -+ restore standalone instance from backup -+ else: -+ Cleanup everything -+ remove instance -+ remove backup -+ Create instance -+ Create backup -+ ''' -+ global installation_prefix -+ -+ if installation_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation_prefix -+ -+ standalone = DirSrv(verbose=False) -+ -+ # Args for the standalone instance -+ args_instance[SER_HOST] = HOST_STANDALONE -+ args_instance[SER_PORT] = PORT_STANDALONE -+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE -+ args_standalone = args_instance.copy() -+ standalone.allocate(args_standalone) -+ -+ # Get the status of the backups -+ backup_standalone = standalone.checkBackupFS() -+ -+ # Get the status of the instance and restart it if it exists -+ instance_standalone = standalone.exists() -+ if instance_standalone: -+ # assuming the instance is already stopped, just wait 5 sec max -+ standalone.stop(timeout=5) -+ standalone.start(timeout=10) -+ -+ if backup_standalone: -+ # The backup exist, assuming it is correct -+ # we just re-init the instance with it -+ if not instance_standalone: -+ standalone.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # restore standalone instance from backup -+ standalone.stop(timeout=10) -+ standalone.restoreFS(backup_standalone) -+ standalone.start(timeout=10) -+ -+ else: -+ # We should be here only in two conditions -+ # - This is the first time a test involve standalone instance -+ # - Something weird happened (instance/backup destroyed) -+ # so we discard everything and recreate all -+ -+ # Remove the backup. So even if we have a specific backup file -+ # (e.g backup_standalone) we clear backup that an instance may have created -+ if backup_standalone: -+ standalone.clearBackupFS() -+ -+ # Remove the instance -+ if instance_standalone: -+ standalone.delete() -+ -+ # Create the instance -+ standalone.create() -+ -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # Time to create the backups -+ standalone.stop(timeout=10) -+ standalone.backupfile = standalone.backupFS() -+ standalone.start(timeout=10) -+ -+ # clear the tmp directory -+ standalone.clearTmpDir(__file__) -+ -+ # -+ # Here we have standalone instance up and running -+ # Either coming from a backup recovery -+ # or from a fresh (re)init -+ # Time to return the topology -+ return TopologyStandalone(standalone) -+ -+ -+def test_ticket47970(topology): -+ """ -+ Testing that a failed SASL bind does not trigger account lockout - -+ which would attempt to update the passwordRetryCount on the root dse entry -+ """ -+ -+ log.info('Testing Ticket 47970 - Testing that a failed SASL bind does not trigger account lockout') -+ -+ # -+ # Enable account lockout -+ # -+ try: -+ topology.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'passwordLockout', 'on')]) -+ log.info('account lockout enabled.') -+ except ldap.LDAPError, e: -+ log.error('Failed to enable account lockout: ' + e.message['desc']) -+ assert False -+ -+ try: -+ topology.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'passwordMaxFailure', '5')]) -+ log.info('passwordMaxFailure set.') -+ except ldap.LDAPError, e: -+ log.error('Failed to to set passwordMaxFailure: ' + e.message['desc']) -+ assert False -+ -+ # -+ # Perform SASL bind that should fail -+ # -+ failed_as_expected = False -+ try: -+ user_name = "mark" -+ pw = "secret" -+ auth_tokens = ldap.sasl.digest_md5(user_name, pw) -+ topology.standalone.sasl_interactive_bind_s("", auth_tokens) -+ except ldap.INVALID_CREDENTIALS, e: -+ log.info("SASL Bind failed as expected") -+ failed_as_expected = True -+ -+ if not failed_as_expected: -+ log.error("SASL bind unexpectedly succeeded!") -+ assert False -+ -+ # -+ # Check that passwordRetryCount was not set on the root dse entry -+ # -+ try: -+ entry = topology.standalone.search_s("", ldap.SCOPE_BASE, -+ "passwordRetryCount=*", -+ ['passwordRetryCount']) -+ except ldap.LDAPError, e: -+ log.error('Failed to search Root DSE entry: ' + e.message['desc']) -+ assert False -+ -+ if entry: -+ log.error('Root DSE was incorrectly updated') -+ assert False -+ -+ # We passed -+ log.info('Root DSE was correctly not updated') -+ log.info("Test Passed.") -+ -+ -+def test_ticket47970_final(topology): -+ topology.standalone.stop(timeout=10) -+ -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - edit this file and comment '@pytest.fixture' line before 'topology' function. -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation_prefix -+ installation_prefix = None -+ -+ topo = topology(True) -+ test_ticket47970(topo) -+ -+if __name__ == '__main__': -+ run_isolated() -\ No newline at end of file --- -1.9.3 - diff --git a/SOURCES/0043-Ticket-48245-Man-pages-and-help-for-remove-ds.pl-doe.patch b/SOURCES/0043-Ticket-48245-Man-pages-and-help-for-remove-ds.pl-doe.patch new file mode 100644 index 0000000..94219a4 --- /dev/null +++ b/SOURCES/0043-Ticket-48245-Man-pages-and-help-for-remove-ds.pl-doe.patch @@ -0,0 +1,61 @@ +From 0cb8a7e2f797b4d48a20e650cf8510b8495a35e6 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 11 Aug 2015 10:23:21 -0700 +Subject: [PATCH 43/45] Ticket #48245 - Man pages and help for remove-ds.pl + doesn't display "-a" option + +Description: Adding the description for "-a" to the man page and the help usage. + +https://fedorahosted.org/389/ticket/48245 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit a2dbb56ec5ad468972a41a500e1cdbb4ced01cb0) +(cherry picked from commit 06dafdfed1528ea6724f61492f4c93977a3ce809) +--- + ldap/admin/src/scripts/remove-ds.pl.in | 5 +++-- + man/man8/remove-ds.pl.8 | 5 ++++- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ldap/admin/src/scripts/remove-ds.pl.in b/ldap/admin/src/scripts/remove-ds.pl.in +index e7eb591..b35ae32 100755 +--- a/ldap/admin/src/scripts/remove-ds.pl.in ++++ b/ldap/admin/src/scripts/remove-ds.pl.in +@@ -21,8 +21,9 @@ Getopt::Long::Configure(qw(bundling)); # bundling allows -ddddd + my $res = new Resource("@propertydir@/setup-ds.res"); + + sub usage { +- print(STDERR "Usage: $0 [-f] [-d -d ... -d] -i instance\n\n"); +- print(STDERR " Opts: -f - force removal\n"); ++ print(STDERR "Usage: $0 [-a] [-f] [-d -d ... -d] -i instance\n\n"); ++ print(STDERR " Opts: -a - remove all\n"); ++ print(STDERR " -f - force removal\n"); + print(STDERR " -i instance - instance name to remove (e.g. - slapd-example)\n"); + print(STDERR " -d - turn on debugging output\n"); + } +diff --git a/man/man8/remove-ds.pl.8 b/man/man8/remove-ds.pl.8 +index 8c7c118..0568ff8 100644 +--- a/man/man8/remove-ds.pl.8 ++++ b/man/man8/remove-ds.pl.8 +@@ -19,7 +19,7 @@ + remove\-ds.pl \- Remove an instance of Directory Server + .SH SYNOPSIS + .B remove-ds.pl +-[\-f] [\-d \-d ... \-d] \-i \fIinstance\fR ++[\-a] [\-f] [\-d \-d ... \-d] \-i \fIinstance\fR + .SH DESCRIPTION + Removes a Directory Server instance from the system. The instance + will be shutdown and the files will be removed. The certificate +@@ -33,6 +33,9 @@ will contain the retained certificate database files. + .SH OPTIONS + A summary of options is included below: + .TP ++.B \fB\-a\fR ++Removes all files and directories belonging to the instance ++.TP + .B \fB\-f\fR + Force removal + .TP +-- +1.9.3 + diff --git a/SOURCES/0044-Ticket-47960-cookie_change_info-returns-random-negat.patch b/SOURCES/0044-Ticket-47960-cookie_change_info-returns-random-negat.patch deleted file mode 100644 index aefa76f..0000000 --- a/SOURCES/0044-Ticket-47960-cookie_change_info-returns-random-negat.patch +++ /dev/null @@ -1,88 +0,0 @@ -From bf2263bac10b890cdfc1fb7cd37f868785190cce Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 10 Dec 2014 17:12:00 -0800 -Subject: [PATCH 44/53] Ticket #47960 - cookie_change_info returns random - negative number if there was no change in a tree - -Description: When no changes had not been made, Retro Changelog db -was empty and the search callback sync_handle_cnum_entry in the -Content Synchronization had no chance to be called. If it was not -called, an uninitialized garbage value in Sync_CallBackData was set -to cookie_change_info. - -This patch checks if the search callback sync_handle_cnum_entry is -called or not. If it is not called, set 0 to cookie_change_info. - -https://fedorahosted.org/389/ticket/47960 - -Reviewed by rmeggins@redhat.com and tbordaz@redhat.com (Thank you, -Rich and Thierry!!) - -(cherry picked from commit a908c6b57cd77ff2f6e2fe0fe1fa2e0eccba77e0) -(cherry picked from commit b7a472c71db4671c127584fcf7bfd8c75930bc8c) ---- - ldap/servers/plugins/sync/sync.h | 2 ++ - ldap/servers/plugins/sync/sync_util.c | 14 ++++++++++---- - 2 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h -index 9c2d8be..0bcec7a 100644 ---- a/ldap/servers/plugins/sync/sync.h -+++ b/ldap/servers/plugins/sync/sync.h -@@ -76,6 +76,8 @@ typedef struct sync_update { - Slapi_Entry *upd_e; - } Sync_UpdateNode; - -+#define SYNC_CALLBACK_PREINIT (-1) -+ - typedef struct sync_callback { - Slapi_PBlock *orig_pb; - int changenr; -diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c -index de65b99..af22bcb 100644 ---- a/ldap/servers/plugins/sync/sync_util.c -+++ b/ldap/servers/plugins/sync/sync_util.c -@@ -373,6 +373,7 @@ sync_handle_cnum_entry(Slapi_Entry *e, void *cb_data) - if( NULL != value && NULL != value->bv_val && - '\0' != value->bv_val[0]) { - cb->changenr = sync_number2int(value->bv_val); -+ cb->cb_err = 0; /* changenr successfully set */ - } - } - } -@@ -500,7 +501,7 @@ sync_cookie_get_change_info(Sync_CallBackData *scbd) - slapi_pblock_init(seq_pb); - - slapi_seq_internal_set_pb(seq_pb, base, SLAPI_SEQ_LAST, attrname, NULL, NULL, 0, 0, -- plugin_get_default_component_id(), 0); -+ plugin_get_default_component_id(), 0); - - rc = slapi_seq_internal_callback_pb (seq_pb, scbd, NULL, sync_handle_cnum_entry, NULL); - slapi_pblock_destroy(seq_pb); -@@ -518,15 +519,20 @@ sync_cookie_create (Slapi_PBlock *pb) - - Sync_CallBackData scbd; - int rc; -- Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie)); -- -+ Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_calloc(1, sizeof(Sync_Cookie)); - -+ scbd.cb_err = SYNC_CALLBACK_PREINIT; - rc = sync_cookie_get_change_info (&scbd); - - if (rc == 0) { - sc->cookie_server_signature = sync_cookie_get_server_info(pb); - sc->cookie_client_signature = sync_cookie_get_client_info(pb); -- sc->cookie_change_info = scbd.changenr; -+ if (scbd.cb_err == SYNC_CALLBACK_PREINIT) { -+ /* changenr is not initialized. */ -+ sc->cookie_change_info = 0; -+ } else { -+ sc->cookie_change_info = scbd.changenr; -+ } - } else { - slapi_ch_free ((void **)&sc); - sc = NULL; --- -1.9.3 - diff --git a/SOURCES/0044-Ticket-48249-sync_repl-uuid-may-be-invalid.patch b/SOURCES/0044-Ticket-48249-sync_repl-uuid-may-be-invalid.patch new file mode 100644 index 0000000..75a2224 --- /dev/null +++ b/SOURCES/0044-Ticket-48249-sync_repl-uuid-may-be-invalid.patch @@ -0,0 +1,46 @@ +From 3598e701b5362633daa40380088d6ba9c8e2d103 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 14 Aug 2015 12:32:31 +0200 +Subject: [PATCH 44/45] Ticket 48249: sync_repl uuid may be invalid + +Bug Description: + uuid is computed from nsuniqueid of the entry. + If the computed uuid contains NULL char, slapi_ch_smprintf("%s") + will stop on the it, leaving the rest of the buffer with the value + that was on the heap at that time + +Fix Description: + use malloc/memcpy instead of slapi_ch_smprintf + +https://fedorahosted.org/389/ticket/48249 + +Reviewed by: Noriko Hosoi (thank you !!) + +Platforms tested: F22 + +Flag Day: no + +Doc impact: no + +(cherry picked from commit a80fe155cb302e0ef10e14cb238c88698b5995a2) +--- + ldap/servers/plugins/sync/sync_util.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c +index 00dc182..1dcff91 100644 +--- a/ldap/servers/plugins/sync/sync_util.c ++++ b/ldap/servers/plugins/sync/sync_util.c +@@ -107,7 +107,8 @@ sync_nsuniqueid2uuid(const char *nsuniqueid) + + u[16] = '\0'; + +- uuid = slapi_ch_smprintf("%s",(char *)u); ++ uuid = slapi_ch_malloc(sizeof(u)); ++ memcpy(uuid, u, sizeof(u)); + + return(uuid); + } +-- +1.9.3 + diff --git a/SOURCES/0045-Ticket-47960-cookie_change_info-returns-random-negat.patch b/SOURCES/0045-Ticket-47960-cookie_change_info-returns-random-negat.patch deleted file mode 100644 index d739ea3..0000000 --- a/SOURCES/0045-Ticket-47960-cookie_change_info-returns-random-negat.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 254ba1f6adf1575f5992ccc1a228ecd10ce96cc5 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Fri, 12 Dec 2014 15:41:36 -0800 -Subject: [PATCH 45/53] Ticket #47960 - cookie_change_info returns random - negative number if there was no change in a tree - -Description: An additional fix for the type mismatch for the change -numbers. Change Number is declared as "unsigned long" in the Retro -Changelog plugin, while cookie_change_info in the Content Sync plugin -is "int", which could end up with a negative number when the change -number passes (2^31 - 1). - -Changing the type of cookie_change_info to "unsigned long". - -https://fedorahosted.org/389/ticket/47960 - -Reviewed by rmeggins@redhat.com and tbordaz@redhat.com (Thank you, -Rich and Thierry!!) - -(cherry picked from commit 96c130b432ce0b15028e325c0e337679291aef9f) -(cherry picked from commit 61a4e7035742612a1a8bf42b16e93cc55776dc31) ---- - ldap/servers/plugins/sync/sync.h | 9 +++-- - ldap/servers/plugins/sync/sync_refresh.c | 32 +++++++++++++----- - ldap/servers/plugins/sync/sync_util.c | 56 ++++++++++++++++++++------------ - 3 files changed, 65 insertions(+), 32 deletions(-) - -diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h -index 0bcec7a..803c656 100644 ---- a/ldap/servers/plugins/sync/sync.h -+++ b/ldap/servers/plugins/sync/sync.h -@@ -64,10 +64,12 @@ - #define CL_ATTR_NEWSUPERIOR "newsuperior" - #define CL_SRCH_BASE "cn=changelog" - -+#define SYNC_INVALID_CHANGENUM ((unsigned long)-1) -+ - typedef struct sync_cookie { - char *cookie_client_signature; - char *cookie_server_signature; -- int cookie_change_info; -+ unsigned long cookie_change_info; - } Sync_Cookie; - - typedef struct sync_update { -@@ -80,8 +82,8 @@ typedef struct sync_update { - - typedef struct sync_callback { - Slapi_PBlock *orig_pb; -- int changenr; -- int change_start; -+ unsigned long changenr; -+ unsigned long change_start; - int cb_err; - Sync_UpdateNode *cb_updates; - } Sync_CallBackData; -@@ -112,6 +114,7 @@ int sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie); - void sync_cookie_free (Sync_Cookie **freecookie); - char * sync_cookie2str(Sync_Cookie *cookie); - int sync_number2int(char *nrstr); -+unsigned long sync_number2ulong(char *nrstr); - char *sync_nsuniqueid2uuid(const char *nsuniqueid); - - int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb); -diff --git a/ldap/servers/plugins/sync/sync_refresh.c b/ldap/servers/plugins/sync/sync_refresh.c -index 4e256e6..bfff77b 100644 ---- a/ldap/servers/plugins/sync/sync_refresh.c -+++ b/ldap/servers/plugins/sync/sync_refresh.c -@@ -293,9 +293,9 @@ sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie, Sync_C - cb_data.orig_pb = pb; - cb_data.change_start = client_cookie->cookie_change_info; - -- filter = slapi_ch_smprintf("(&(changenumber>=%d)(changenumber<=%d))", -- client_cookie->cookie_change_info, -- server_cookie->cookie_change_info); -+ filter = slapi_ch_smprintf("(&(changenumber>=%lu)(changenumber<=%lu))", -+ client_cookie->cookie_change_info, -+ server_cookie->cookie_change_info); - slapi_search_internal_set_pb( - seq_pb, - CL_SRCH_BASE, -@@ -305,7 +305,7 @@ sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie, Sync_C - 0, - NULL, NULL, - plugin_get_default_component_id(), -- 0); -+ 0); - - rc = slapi_search_internal_callback_pb ( - seq_pb, &cb_data, NULL, sync_read_entry_from_changelog, NULL); -@@ -460,6 +460,7 @@ sync_read_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data) - int chg_req; - int prev = 0; - int index = 0; -+ unsigned long chgnum = 0; - Sync_CallBackData *cb = (Sync_CallBackData *) cb_data; - - if (cb == NULL) { -@@ -470,13 +471,28 @@ sync_read_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data) - if (uniqueid == NULL) { - slapi_log_error (SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, - "Retro Changelog does not provied nsuniquedid." -- "Check RCL plugin configuration." ); -+ "Check RCL plugin configuration.\n" ); - return(1); - } -- chgtype = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHGTYPE); - chgnr = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHANGENUMBER); -- -- index = sync_number2int(chgnr) - cb->change_start; -+ chgnum = sync_number2ulong(chgnr); -+ if (SYNC_INVALID_CHANGENUM == chgnum) { -+ slapi_log_error (SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, -+ "Change number provided by Retro Changelog is invalid: %s\n", chgnr); -+ slapi_ch_free_string(&chgnr); -+ slapi_ch_free_string(&uniqueid); -+ return(1); -+ } -+ if (chgnum < cb->change_start) { -+ slapi_log_error (SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, -+ "Change number provided by Retro Changelog %s is less than the initial number %lu\n", -+ chgnr, cb->change_start); -+ slapi_ch_free_string(&chgnr); -+ slapi_ch_free_string(&uniqueid); -+ return(1); -+ } -+ index = chgnum - cb->change_start; -+ chgtype = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHGTYPE); - chg_req = sync_str2chgreq(chgtype); - switch (chg_req){ - case LDAP_REQ_ADD: -diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c -index af22bcb..67cb453 100644 ---- a/ldap/servers/plugins/sync/sync_util.c -+++ b/ldap/servers/plugins/sync/sync_util.c -@@ -266,10 +266,10 @@ sync_cookie2str(Sync_Cookie *cookie) - char *cookiestr = NULL; - - if (cookie) { -- cookiestr = slapi_ch_smprintf("%s#%s#%d", -- cookie->cookie_server_signature, -- cookie->cookie_client_signature, -- cookie->cookie_change_info); -+ cookiestr = slapi_ch_smprintf("%s#%s#%lu", -+ cookie->cookie_server_signature, -+ cookie->cookie_client_signature, -+ cookie->cookie_change_info); - } - return(cookiestr); - } -@@ -370,10 +370,11 @@ sync_handle_cnum_entry(Slapi_Entry *e, void *cb_data) - slapi_attr_first_value( chattr,&sval ); - if ( NULL != sval ) { - value = slapi_value_get_berval ( sval ); -- if( NULL != value && NULL != value->bv_val && -- '\0' != value->bv_val[0]) { -- cb->changenr = sync_number2int(value->bv_val); -- cb->cb_err = 0; /* changenr successfully set */ -+ if (value && value->bv_val && ('\0' != value->bv_val[0])) { -+ cb->changenr = sync_number2ulong(value->bv_val); -+ if (SYNC_INVALID_CHANGENUM != cb->changenr) { -+ cb->cb_err = 0; /* changenr successfully set */ -+ } - } - } - } -@@ -452,31 +453,30 @@ sync_cookie_get_client_info(Slapi_PBlock *pb) - clientinfo = slapi_ch_smprintf("%s:%s:%s",clientdn,targetdn,strfilter); - return (clientinfo); - } --static int -+static unsigned long - sync_cookie_get_change_number(int lastnr, const char *uniqueid) - { - Slapi_PBlock *srch_pb; - Slapi_Entry **entries; - Slapi_Entry *cl_entry; - int rv; -- int newnr = -1; -+ unsigned long newnr = SYNC_INVALID_CHANGENUM; - char *filter = slapi_ch_smprintf("(&(changenumber>=%d)(targetuniqueid=%s))",lastnr,uniqueid); - - srch_pb = slapi_pblock_new(); -- slapi_search_internal_set_pb(srch_pb, CL_SRCH_BASE, -- LDAP_SCOPE_SUBTREE, filter, -- NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0); -- slapi_search_internal_pb(srch_pb); -+ slapi_search_internal_set_pb(srch_pb, CL_SRCH_BASE, LDAP_SCOPE_SUBTREE, filter, -+ NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0); -+ slapi_search_internal_pb(srch_pb); - slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_RESULT, &rv); -- if ( rv == LDAP_SUCCESS) { -+ if (rv == LDAP_SUCCESS) { - slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); -- if (entries && *entries) { -+ if (entries && *entries) { - Slapi_Attr *attr; - Slapi_Value *val; - cl_entry = *entries; /* only use teh first one */ - slapi_entry_attr_find(cl_entry, CL_ATTR_CHANGENUMBER, &attr); - slapi_attr_first_value(attr, &val); -- newnr = sync_number2int((char *)slapi_value_get_string(val)); -+ newnr = sync_number2ulong((char *)slapi_value_get_string(val)); - } - } - -@@ -579,8 +579,8 @@ sync_cookie_parse (char *cookie) - if (p) { - *p = '\0'; - sc->cookie_client_signature = slapi_ch_strdup(q); -- sc->cookie_change_info = sync_number2int(p+1); -- if (sc->cookie_change_info < 0) { -+ sc->cookie_change_info = sync_number2ulong(p+1); -+ if (SYNC_INVALID_CHANGENUM == sc->cookie_change_info) { - goto error_return; - } - } else { -@@ -716,14 +716,28 @@ sync_pblock_copy(Slapi_PBlock *src) - return dest; - } - --int sync_number2int(char *chgnrstr) -+int -+sync_number2int(char *chgnrstr) - { - char *end; - int nr; -- nr = strtoul(chgnrstr, &end, 10); -+ nr = (int)strtoul(chgnrstr, &end, 10); - if ( *end == '\0') { - return (nr); - } else { - return (-1); - } - } -+ -+unsigned long -+sync_number2ulong(char *chgnrstr) -+{ -+ char *end; -+ unsigned long nr; -+ nr = strtoul(chgnrstr, &end, 10); -+ if ( *end == '\0') { -+ return (nr); -+ } else { -+ return SYNC_INVALID_CHANGENUM; -+ } -+} --- -1.9.3 - diff --git a/SOURCES/0045-Ticket-48250-Slapd-crashes-reported-from-latest-buil.patch b/SOURCES/0045-Ticket-48250-Slapd-crashes-reported-from-latest-buil.patch new file mode 100644 index 0000000..077923f --- /dev/null +++ b/SOURCES/0045-Ticket-48250-Slapd-crashes-reported-from-latest-buil.patch @@ -0,0 +1,180 @@ +From 0cf9e38234476a0f3680ea388351f9bf90735818 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Fri, 14 Aug 2015 11:19:24 -0700 +Subject: [PATCH 45/45] Ticket #48250 - Slapd crashes reported from latest + build + +Bug Description: There was a conflict between an import task and +deleting the instance. While the import task was still running, +the backend instance was removed, which should have been rejected. + +Fix Description: Backend tasks keeps instance refcnt positive and +disable the backend in the mapping tree. This patch adds the +check for the mapping tree in the backend deletion callback. If +the instance refcnt is positive or the mapping tree is disabled, +the deletion is backed off. + +For the backend deletion, the referral info is not needed. To +reduce unnecessary allocation and free, adding the code which +checks if the given referral variable is NULL or not to mtn_get_be. +If it is NULL, no allocation for the referral entry occurs. + +https://fedorahosted.org/389/ticket/48250 + +Reviewed by rmeggins@redhat.com (Thank you, Rich!!) + +(cherry picked from commit 01fea1f89a680358245677f72a67e9ccf196f66d) +(cherry picked from commit 7a4b0a705ec7376e704f6ae591beabf6c8f890af) +--- + ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 11 +++-- + ldap/servers/slapd/mapping_tree.c | 52 ++++++++++++++---------- + 2 files changed, 39 insertions(+), 24 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c +index 895d846..42c8ffe 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c +@@ -128,7 +128,7 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_ + + /* + * Config DSE callback for index deletes. +- */ ++ */ + int + ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) + { +@@ -138,15 +138,19 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla + const struct berval *attrValue; + int rc = SLAPI_DSE_CALLBACK_OK; + struct attrinfo *ainfo = NULL; ++ Slapi_Backend *be = NULL; + + returntext[0] = '\0'; + *returncode = LDAP_SUCCESS; + +- if (slapi_counter_get_value(inst->inst_ref_count) > 0) { ++ if ((slapi_counter_get_value(inst->inst_ref_count) > 0) || ++ /* check if the backend is ON or not. ++ * If offline or being deleted, non SUCCESS is returned. */ ++ (slapi_mapping_tree_select(pb, &be, NULL, returntext) != LDAP_SUCCESS)) { + *returncode = LDAP_UNAVAILABLE; + rc = SLAPI_DSE_CALLBACK_ERROR; ++ goto bail; + } +- + *returncode = LDAP_SUCCESS; + + slapi_entry_attr_find(e, "cn", &attr); +@@ -165,6 +169,7 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla + rc = SLAPI_DSE_CALLBACK_ERROR; + } + } ++bail: + return rc; + } + +diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c +index ca8d6af..165eba1 100644 +--- a/ldap/servers/slapd/mapping_tree.c ++++ b/ldap/servers/slapd/mapping_tree.c +@@ -2171,7 +2171,9 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry + } + + be[0] = NULL; +- referral[0] = NULL; ++ if (referral) { ++ referral[0] = NULL; ++ } + + mtn_lock(); + +@@ -2658,7 +2660,9 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, + ((SLAPI_OPERATION_SEARCH == op_type)||(SLAPI_OPERATION_BIND == op_type) || + (SLAPI_OPERATION_UNBIND == op_type) || (SLAPI_OPERATION_COMPARE == op_type))) || + override_referral) { +- *referral = NULL; ++ if (referral) { ++ *referral = NULL; ++ } + if ((target_node == mapping_tree_root) ){ + /* If we got here, then we couldn't find a matching node + * for the target. We'll use the default backend. Once +@@ -2679,22 +2683,25 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, + /* there is only one backend no choice possible */ + *index = 0; + } else { +- *index = mtn_get_be_distributed(pb, target_node, +- target_sdn, &flag_stop); +- if (*index == SLAPI_BE_NO_BACKEND) +- result = LDAP_UNWILLING_TO_PERFORM; +- } +- } +- if (*index == SLAPI_BE_REMOTE_BACKEND) { +- *be = NULL; +- *referral = (target_node->mtn_referral_entry ? +- slapi_entry_dup(target_node->mtn_referral_entry) : +- NULL); ++ *index = mtn_get_be_distributed(pb, target_node, target_sdn, &flag_stop); ++ if (*index == SLAPI_BE_NO_BACKEND) { ++ result = LDAP_UNWILLING_TO_PERFORM; ++ } ++ } ++ } ++ if (*index == SLAPI_BE_REMOTE_BACKEND) { ++ *be = NULL; ++ if (referral) { ++ *referral = (target_node->mtn_referral_entry ? ++ slapi_entry_dup(target_node->mtn_referral_entry) : NULL); ++ } + (*index)++; + }else if ((*index == SLAPI_BE_NO_BACKEND) || (*index >= target_node->mtn_be_count)) { +- /* we have already returned all backends -> return NULL */ ++ /* we have already returned all backends -> return NULL */ + *be = NULL; +- *referral = NULL; ++ if (referral) { ++ *referral = NULL; ++ } + } else { + /* return next backend, increment index */ + *be = target_node->mtn_be[*index]; +@@ -2749,7 +2756,9 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, + * send back NULL to jump to next node + */ + *be = NULL; +- *referral = NULL; ++ if (referral) { ++ *referral = NULL; ++ } + result = LDAP_SUCCESS; + } else { + /* first time we hit this referral -> return it +@@ -2758,11 +2767,12 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, + * returned this referral + */ + *be = NULL; +- *referral = (target_node->mtn_referral_entry ? +- slapi_entry_dup(target_node->mtn_referral_entry) : +- NULL); ++ if (referral) { ++ *referral = (target_node->mtn_referral_entry ? ++ slapi_entry_dup(target_node->mtn_referral_entry) : NULL); ++ } + (*index)++; +- if (NULL == *referral) { ++ if (NULL == target_node->mtn_referral_entry) { + if (errorbuf) { + PR_snprintf(errorbuf, BUFSIZ, + "Mapping tree node for %s is set to return a referral," +@@ -2782,7 +2792,7 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, + "mapping tree selected backend : %s\n", + slapi_be_get_name(*be)); + slapi_be_Rlock(*be); +- } else if (*referral) { ++ } else if (referral && *referral) { + slapi_log_error(SLAPI_LOG_ARGS, NULL, + "mapping tree selected referral at node : %s\n", + slapi_sdn_get_dn(target_node->mtn_subtree)); +-- +1.9.3 + diff --git a/SOURCES/0046-Ticket-47636-Error-log-levels-not-displayed-correctl.patch b/SOURCES/0046-Ticket-47636-Error-log-levels-not-displayed-correctl.patch deleted file mode 100644 index 84b2784..0000000 --- a/SOURCES/0046-Ticket-47636-Error-log-levels-not-displayed-correctl.patch +++ /dev/null @@ -1,79 +0,0 @@ -From cac085393e5d3ea996b9dd19811088f675c15b5f Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 8 Dec 2014 15:50:53 -0500 -Subject: [PATCH 46/53] Ticket 47636 - Error log levels not displayed correctly - -Bug Description: Searching for nsslapd-errorlog-level returns an - unexpected value (the level plus 16384). - -Fix Description: This is a regression from the first fix for this - ticket. The fix is to only adjust the level zero, - to its full default value of 16384. - -https://fedorahosted.org/389/ticket/47636 - -Reviewed by: rmeggins(Thanks!) - -(cherry picked from commit f12e1216cc7baf128911d519cc8758c1c9277957) -(cherry picked from commit 7b32ab042511f69e544f91b318387edd00129292) ---- - ldap/servers/slapd/libglobs.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c -index b437112..b2b40d3 100644 ---- a/ldap/servers/slapd/libglobs.c -+++ b/ldap/servers/slapd/libglobs.c -@@ -118,6 +118,7 @@ typedef enum { - CONFIG_CONSTANT_STRING, /* for #define values, e.g. */ - CONFIG_SPECIAL_REFERRALLIST, /* this is a berval list */ - CONFIG_SPECIAL_SSLCLIENTAUTH, /* maps strings to an enumeration */ -+ CONFIG_SPECIAL_ERRORLOGLEVEL, /* requires & with LDAP_DEBUG_ANY */ - CONFIG_STRING_OR_EMPTY, /* use an empty string */ - CONFIG_SPECIAL_ANON_ACCESS_SWITCH, /* maps strings to an enumeration */ - CONFIG_SPECIAL_VALIDATE_CERT_SWITCH, /* maps strings to an enumeration */ -@@ -289,7 +290,7 @@ slapi_onoff_t init_mempool_switch; - static int - isInt(ConfigVarType type) - { -- return type == CONFIG_INT || type == CONFIG_ON_OFF || type == CONFIG_SPECIAL_SSLCLIENTAUTH; -+ return type == CONFIG_INT || type == CONFIG_ON_OFF || type == CONFIG_SPECIAL_SSLCLIENTAUTH || type == CONFIG_SPECIAL_ERRORLOGLEVEL; - } - - /* the caller will typically have to cast the result based on the ConfigVarType */ -@@ -339,7 +340,7 @@ static struct config_get_and_set { - {CONFIG_LOGLEVEL_ATTRIBUTE, config_set_errorlog_level, - NULL, 0, - (void**)&global_slapdFrontendConfig.errorloglevel, -- CONFIG_INT, NULL, STRINGIFYDEFINE(SLAPD_DEFAULT_ERRORLOG_LEVEL)}, -+ CONFIG_SPECIAL_ERRORLOGLEVEL, NULL, NULL}, - {CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, NULL, - log_set_logging, SLAPD_ERROR_LOG, - (void**)&global_slapdFrontendConfig.errorlog_logging_enabled, -@@ -7563,6 +7564,23 @@ config_set_value( - *((char **)value) : "unknown"); - break; - -+ case CONFIG_SPECIAL_ERRORLOGLEVEL: -+ if (value) { -+ int ival = *(int *)value; -+ ival &= ~LDAP_DEBUG_ANY; -+ if (ival == 0) { -+ /* -+ * Don't store the default value as zero, -+ * but as its real value. -+ */ -+ ival = LDAP_DEBUG_ANY; -+ } -+ slapi_entry_attr_set_int(e, cgas->attr_name, ival); -+ } -+ else -+ slapi_entry_attr_set_charptr(e, cgas->attr_name, ""); -+ break; -+ - case CONFIG_SPECIAL_ANON_ACCESS_SWITCH: - if (!value) { - slapi_entry_attr_set_charptr(e, cgas->attr_name, "off"); --- -1.9.3 - diff --git a/SOURCES/0046-Ticket-48233-Server-crashes-in-ACL_LasFindFlush-duri.patch b/SOURCES/0046-Ticket-48233-Server-crashes-in-ACL_LasFindFlush-duri.patch new file mode 100644 index 0000000..245fe21 --- /dev/null +++ b/SOURCES/0046-Ticket-48233-Server-crashes-in-ACL_LasFindFlush-duri.patch @@ -0,0 +1,158 @@ +From 34024061a980fa5472fab680b873c0666413e5ec Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 17 Aug 2015 14:51:17 -0400 +Subject: [PATCH 46/47] Ticket 48233 - Server crashes in ACL_LasFindFlush + during shutdown if ACIs contain IP addresss restrictions + +Bug Description: The server will crash at shutdown if there are ACI's that use IP rules. + +Fix Description: When we stop the acl plugin we need to free aci avl list first, before + we free the libaccess ACL global lists. Otherwise, we dereference a freed + struct. + +https://fedorahosted.org/389/ticket/48233 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 22d315b910b086d3e7edca3b6b52511d5da63802) +(cherry picked from commit 57c5d35b4a5ea3e85ae2a7471cbe487531ee3835) +--- + dirsrvtests/tickets/ticket48233_test.py | 105 ++++++++++++++++++++++++++++++++ + ldap/servers/plugins/acl/aclplugin.c | 2 +- + 2 files changed, 106 insertions(+), 1 deletion(-) + create mode 100644 dirsrvtests/tickets/ticket48233_test.py + +diff --git a/dirsrvtests/tickets/ticket48233_test.py b/dirsrvtests/tickets/ticket48233_test.py +new file mode 100644 +index 0000000..387279d +--- /dev/null ++++ b/dirsrvtests/tickets/ticket48233_test.py +@@ -0,0 +1,105 @@ ++import os ++import sys ++import time ++import ldap ++import logging ++import pytest ++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 ++ ++ ++class TopologyStandalone(object): ++ def __init__(self, standalone): ++ standalone.open() ++ self.standalone = standalone ++ ++ ++@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_ticket48233(topology): ++ """Test that ACI's that use IP restrictions do not crash the server at ++ shutdown ++ """ ++ ++ # Add aci to restrict access my ip ++ aci_text = ('(targetattr != "userPassword")(version 3.0;acl ' + ++ '"Enable anonymous access - IP"; allow (read,compare,search)' + ++ '(userdn = "ldap:///anyone") and (ip="127.0.0.1");)') ++ ++ try: ++ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', aci_text)]) ++ except ldap.LDAPError as e: ++ log.error('Failed to add aci: (%s) error %s' % (aci_text, e.message['desc'])) ++ assert False ++ time.sleep(1) ++ ++ # Anonymous search to engage the aci ++ try: ++ topology.standalone.simple_bind_s("", "") ++ except ldap.LDAPError as e: ++ log.error('Failed to anonymously bind -error %s' % (e.message['desc'])) ++ assert False ++ ++ try: ++ entries = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'objectclass=*') ++ if not entries: ++ log.fatal('Failed return an entries from search') ++ assert False ++ except ldap.LDAPError, e: ++ log.fatal('Search failed: ' + e.message['desc']) ++ assert False ++ ++ # Restart the server ++ topology.standalone.restart(timeout=10) ++ ++ # Check for crash ++ if topology.standalone.detectDisorderlyShutdown(): ++ log.fatal('Server crashed!') ++ assert False ++ ++ log.info('Test complete') ++ ++ ++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 +diff --git a/ldap/servers/plugins/acl/aclplugin.c b/ldap/servers/plugins/acl/aclplugin.c +index 45a6315..d90996e 100644 +--- a/ldap/servers/plugins/acl/aclplugin.c ++++ b/ldap/servers/plugins/acl/aclplugin.c +@@ -269,13 +269,13 @@ aclplugin_stop ( Slapi_PBlock *pb ) + { + int rc = 0; /* OK */ + ++ free_acl_avl_list(); + ACL_Destroy(); + acl_destroy_aclpb_pool(); + acl_remove_ext(); + ACL_AttrGetterHashDestroy(); + ACL_MethodHashDestroy(); + ACL_DestroyPools(); +- free_acl_avl_list(); + aclanom__del_profile(1); + aclgroup_free(); + //aclext_free_lockarray(); +-- +1.9.3 + diff --git a/SOURCES/0047-Ticket-47722-Using-the-filter-file-does-not-work.patch b/SOURCES/0047-Ticket-47722-Using-the-filter-file-does-not-work.patch deleted file mode 100644 index ea339f2..0000000 --- a/SOURCES/0047-Ticket-47722-Using-the-filter-file-does-not-work.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 325de7ba798d0f1b7ab4b6e607653306032cd8cd Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 9 Dec 2014 15:29:07 -0500 -Subject: [PATCH 47/53] Ticket 47722 - Using the filter file does not work - -Bug Description: Using a filter file does not work correctly. rsearch fails to - to use the filters from the file. - -Fix Description: There was a bug where we incorrectly freed each filter right after - we added it to the local list. This left the list empty. - -https://fedorahosted.org/389/ticket/47722 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit fb22b387e4376caae35121a645a5879dbac7b4fb) -(cherry picked from commit 4002f3b946f567994de6c32c6ff713b1d341a975) ---- - ldap/servers/slapd/tools/rsearch/nametable.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/ldap/servers/slapd/tools/rsearch/nametable.c b/ldap/servers/slapd/tools/rsearch/nametable.c -index 9d56a34..03a6ae1 100644 ---- a/ldap/servers/slapd/tools/rsearch/nametable.c -+++ b/ldap/servers/slapd/tools/rsearch/nametable.c -@@ -160,7 +160,6 @@ int nt_load(NameTable *nt, const char *filename) - free(s); - break; - } -- free(s); - } - PR_Close(fd); - return nt->size; --- -1.9.3 - diff --git a/SOURCES/0047-Ticket-48243-replica-upgrade-failed-in-starting-dirs.patch b/SOURCES/0047-Ticket-48243-replica-upgrade-failed-in-starting-dirs.patch new file mode 100644 index 0000000..616cc6b --- /dev/null +++ b/SOURCES/0047-Ticket-48243-replica-upgrade-failed-in-starting-dirs.patch @@ -0,0 +1,147 @@ +From d88650af2dc614519bdb138b162d3c6e3b5ae9c5 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 18 Aug 2015 13:43:55 -0700 +Subject: [PATCH 47/47] Ticket #48243 - replica upgrade failed in starting + dirsrv service due to upgrade scripts did not run + +Description: In the upgrade process, there is a combination of requirements: + . the server is running. + . the server instance service is disabled. + . upgrade scripts are expected to run against the instance. + . the server is restarted once the upgrade is done. + . the server instance service remains disabled. +To fulfill the requirements, + . spec file is modified to enumerate slapd dir (except .remove) in the + /etc/dirsrv for getting the server instance. + . Start/Update perl scripts are modified not to create a symlink in + /etc/systemd/system/dirsrv.target.wants for the upgrade case, which + means the service remains disabled. + +https://fedorahosted.org/389/ticket/48243 + +Reviewed by mreynolds@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 29c09a5bcc7d54be1aa6880b4f2a423edd3dc463) +(cherry picked from commit 2c5e0d5692bcabe16a7e3b8e0d24eb3a88913155) +--- + ldap/admin/src/scripts/DSCreate.pm.in | 7 ++++--- + ldap/admin/src/scripts/DSMigration.pm.in | 2 +- + ldap/admin/src/scripts/DSUpdate.pm.in | 2 +- + rpm/389-ds-base.spec.in | 20 +++++++++++++------- + 4 files changed, 19 insertions(+), 12 deletions(-) + +diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in +index e4a4ed0..cdde339 100644 +--- a/ldap/admin/src/scripts/DSCreate.pm.in ++++ b/ldap/admin/src/scripts/DSCreate.pm.in +@@ -1098,6 +1098,7 @@ sub updateTmpfilesDotD { + } + + sub updateSystemD { ++ my $noservicelink = shift; + my $inf = shift; + my $unitdir = "@systemdsystemunitdir@"; + my $confbasedir = "@systemdsystemconfdir@"; +@@ -1129,7 +1130,7 @@ sub updateSystemD { + next; + } else { + my $servicelink = "$confdir/$pkgname\@$inst.service"; +- if (! -l $servicelink) { ++ if (! -l $servicelink && ! $noservicelink) { + if (!symlink($servicefile, $servicelink)) { + debug(1, "error updating link $servicelink to $servicefile - $!\n"); + push @errs, [ 'error_linking_file', $servicefile, $servicelink, $! ]; +@@ -1216,7 +1217,7 @@ sub createDSInstance { + return @errs; + } + +- if (@errs = updateSystemD($inf)) { ++ if (@errs = updateSystemD(0, $inf)) { + return @errs; + } + +@@ -1452,7 +1453,7 @@ sub removeDSInstance { + } + + # update systemd files +- push @errs, updateSystemD(); ++ push @errs, updateSystemD(0); + + # if we got here, report success + if (@errs) { +diff --git a/ldap/admin/src/scripts/DSMigration.pm.in b/ldap/admin/src/scripts/DSMigration.pm.in +index e59e667..630ab43 100644 +--- a/ldap/admin/src/scripts/DSMigration.pm.in ++++ b/ldap/admin/src/scripts/DSMigration.pm.in +@@ -1132,7 +1132,7 @@ sub migrateDS { + } + + # do the systemd stuff +- @errs = DSCreate::updateSystemD($inf); ++ @errs = DSCreate::updateSystemD(0, $inf); + if (@errs) { + $mig->msg(@errs); + goto cleanup; +diff --git a/ldap/admin/src/scripts/DSUpdate.pm.in b/ldap/admin/src/scripts/DSUpdate.pm.in +index 1809ad9..be1e67c 100644 +--- a/ldap/admin/src/scripts/DSUpdate.pm.in ++++ b/ldap/admin/src/scripts/DSUpdate.pm.in +@@ -408,7 +408,7 @@ sub updateDSInstance { + + push @errs, updateTmpfilesDotD($inf); + +- push @errs, updateSystemD($inf); ++ push @errs, updateSystemD(1, $inf); + + return @errs; + } +diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in +index d0bbb7a..b7556e1 100644 +--- a/rpm/389-ds-base.spec.in ++++ b/rpm/389-ds-base.spec.in +@@ -248,6 +248,7 @@ rm -rf $RPM_BUILD_ROOT + + %post + output=/dev/null ++output2=/dev/null + %systemd_post %{pkgname}-snmp.service + # reload to pick up any changes to systemd files + /bin/systemctl daemon-reload >$output 2>&1 || : +@@ -260,12 +261,17 @@ instances="" # instances that require a restart after upgrade + ninst=0 # number of instances found in total + if [ -n "$DEBUGPOSTTRANS" ] ; then + output=$DEBUGPOSTTRANS ++ output2=${DEBUGPOSTTRANS}.upgrade + fi +-echo looking for services in %{_sysconfdir}/systemd/system/%{groupname}.wants/* >> $output 2>&1 || : +-for service in %{_sysconfdir}/systemd/system/%{groupname}.wants/* ; do +- if [ ! -f "$service" ] ; then continue ; fi # in case nothing matches +- inst=`echo $service | sed -e 's,%{_sysconfdir}/systemd/system/%{groupname}.wants/,,'` +- echo found instance $inst - getting status >> $output 2>&1 || : ++echo looking for instances in %{_sysconfdir}/%{pkgname} > $output 2>&1 || : ++instbase="%{_sysconfdir}/%{pkgname}" ++for dir in $instbase/slapd-* ; do ++ echo dir = $dir >> $output 2>&1 || : ++ if [ ! -d "$dir" ] ; then continue ; fi ++ case "$dir" in *.removed) continue ;; esac ++ basename=`basename $dir` ++ inst="%{pkgname}@`echo $basename | sed -e 's/slapd-//g'`" ++ echo found instance $inst - getting status >> $output 2>&1 || : + if /bin/systemctl -q is-active $inst ; then + echo instance $inst is running >> $output 2>&1 || : + instances="$instances $inst" +@@ -290,9 +296,9 @@ echo remove pid files . . . >> $output 2>&1 || : + echo upgrading instances . . . >> $output 2>&1 || : + DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"` + if [ -n "$DEBUGPOSTSETUPOPT" ] ; then +- %{_sbindir}/setup-ds.pl -l $output -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : ++ %{_sbindir}/setup-ds.pl -l $output2 -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : + else +- %{_sbindir}/setup-ds.pl -l $output -u -s General.UpdateMode=offline >> $output 2>&1 || : ++ %{_sbindir}/setup-ds.pl -l $output2 -u -s General.UpdateMode=offline >> $output 2>&1 || : + fi + + # restart instances that require it +-- +1.9.3 + diff --git a/SOURCES/0048-Ticket-47451-Need-to-unregister-tasks-created-by-plu.patch b/SOURCES/0048-Ticket-47451-Need-to-unregister-tasks-created-by-plu.patch deleted file mode 100644 index 58a9168..0000000 --- a/SOURCES/0048-Ticket-47451-Need-to-unregister-tasks-created-by-plu.patch +++ /dev/null @@ -1,188 +0,0 @@ -From d9e460db38763e81f1065777dd54f95efd108017 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 13 Nov 2014 17:22:24 -0500 -Subject: [PATCH 48/53] Ticket 47451 - Need to unregister tasks created by - plugins - -Bug Description: Tasks created by plugins are not unregistered when a plugin - is stopped or deleted. Repeated stopping/starting a plugin - that registers tasks will corrupt the dse callback linked list - and will crash the server if a task is invoked. - -Fix Description: Create a plugin task unregister function, and call it in the - clsoe functions of plugins that register functions. - -https://fedorahosted.org/389/ticket/47451 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 005c4c9be360a7ebba38b61f934ace94224eef3f) -(cherry picked from commit fb7eef1c08a2d15c94eaedaabec2b07e970ffb3a) ---- - ldap/servers/plugins/automember/automember.c | 8 ++++++++ - ldap/servers/plugins/linkedattrs/linked_attrs.c | 2 ++ - ldap/servers/plugins/memberof/memberof.c | 1 + - .../plugins/posix-winsync/posix-winsync-config.c | 1 + - ldap/servers/plugins/schema_reload/schema_reload.c | 2 ++ - ldap/servers/plugins/usn/usn.c | 1 + - ldap/servers/plugins/usn/usn.h | 1 + - ldap/servers/plugins/usn/usn_cleanup.c | 8 ++++++++ - ldap/servers/slapd/slapi-plugin.h | 1 + - ldap/servers/slapd/task.c | 19 +++++++++++++++++++ - 10 files changed, 44 insertions(+) - -diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c -index c5bb0ae..c443a65 100644 ---- a/ldap/servers/plugins/automember/automember.c -+++ b/ldap/servers/plugins/automember/automember.c -@@ -397,6 +397,14 @@ automember_close(Slapi_PBlock * pb) - slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM, - "--> automember_close\n"); - -+ /* unregister the tasks */ -+ slapi_plugin_task_unregister_handler("automember rebuild membership", -+ automember_task_add); -+ slapi_plugin_task_unregister_handler("automember export updates", -+ automember_task_add_export_updates); -+ slapi_plugin_task_unregister_handler("automember map updates", -+ automember_task_add_map_entries); -+ - automember_delete_config(); - slapi_ch_free((void **)&g_automember_config); - slapi_sdn_free(&_PluginDN); -diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c -index 20bb9fa..e302867 100644 ---- a/ldap/servers/plugins/linkedattrs/linked_attrs.c -+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c -@@ -383,6 +383,8 @@ linked_attrs_close(Slapi_PBlock * pb) - slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM, - "--> linked_attrs_close\n"); - -+ slapi_plugin_task_unregister_handler("fixup linked attributes", linked_attrs_fixup_task_add); -+ - linked_attrs_delete_config(); - slapi_destroy_rwlock(g_config_lock); - g_config_lock = NULL; -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index ce48f01..cb4ef75 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -454,6 +454,7 @@ int memberof_postop_close(Slapi_PBlock *pb) - slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, - "--> memberof_postop_close\n" ); - -+ slapi_plugin_task_unregister_handler("memberof task", memberof_task_add); - memberof_release_config(); - slapi_sdn_free(&_ConfigAreaDN); - slapi_sdn_free(&_pluginDN); -diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c -index 4234080..50e3a61 100644 ---- a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c -+++ b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c -@@ -237,6 +237,7 @@ posix_winsync_config(Slapi_Entry *config_e) - void - posix_winsync_config_free() - { -+ slapi_plugin_task_unregister_handler("memberuid task", posix_group_task_add); - slapi_entry_free(theConfig.config_e); - theConfig.config_e = NULL; - slapi_destroy_mutex(theConfig.lock); -diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c -index 6cf1181..3ff4c4d 100644 ---- a/ldap/servers/plugins/schema_reload/schema_reload.c -+++ b/ldap/servers/plugins/schema_reload/schema_reload.c -@@ -131,6 +131,8 @@ schemareload_start(Slapi_PBlock *pb) - static int - schemareload_close(Slapi_PBlock *pb) - { -+ -+ slapi_plugin_task_unregister_handler("schema reload task", schemareload_add); - PR_DestroyLock(schemareload_lock); - - return 0; -diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c -index 837dc2e..6b34bf4 100644 ---- a/ldap/servers/plugins/usn/usn.c -+++ b/ldap/servers/plugins/usn/usn.c -@@ -300,6 +300,7 @@ usn_close(Slapi_PBlock *pb) - { - slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> usn_close\n"); - -+ usn_cleanup_close(); - slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, - "", LDAP_SCOPE_BASE, "(objectclass=*)", usn_rootdse_search); - -diff --git a/ldap/servers/plugins/usn/usn.h b/ldap/servers/plugins/usn/usn.h -index 8e6c5c8..4bc9e97 100644 ---- a/ldap/servers/plugins/usn/usn.h -+++ b/ldap/servers/plugins/usn/usn.h -@@ -54,4 +54,5 @@ void *usn_get_identity(); - - /* usn_cleanup.c */ - int usn_cleanup_start(Slapi_PBlock *pb); -+int usn_cleanup_close(); - -diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c -index 2b1371d..c12dfd2 100644 ---- a/ldap/servers/plugins/usn/usn_cleanup.c -+++ b/ldap/servers/plugins/usn/usn_cleanup.c -@@ -58,6 +58,14 @@ usn_cleanup_start(Slapi_PBlock *pb) - return rc; - } - -+int -+usn_cleanup_close() -+{ -+ int rc = slapi_plugin_task_unregister_handler("USN tombstone cleanup task", -+ usn_cleanup_add); -+ return rc; -+} -+ - /* - * Task thread - */ -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index 8ffc582..0ae3601 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -6604,6 +6604,7 @@ int slapi_config_remove_callback(int operation, int flags, const char *base, int - - int slapi_task_register_handler(const char *name, dseCallbackFn func); - int slapi_plugin_task_register_handler(const char *name, dseCallbackFn func, Slapi_PBlock *plugin_pb); -+int slapi_plugin_task_unregister_handler(const char *name, dseCallbackFn func); - void slapi_task_begin(Slapi_Task *task, int total_work); - void slapi_task_inc_progress(Slapi_Task *task); - void slapi_task_finish(Slapi_Task *task, int rc); -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index 2a0cb82..006ae53 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -461,6 +461,25 @@ int slapi_task_get_refcount(Slapi_Task *task) - } - - int -+slapi_plugin_task_unregister_handler(const char *name, dseCallbackFn func) -+{ -+ char *base = NULL; -+ int rc = 0; -+ -+ base = slapi_create_dn_string("cn=%s,%s", name, TASK_BASE_DN); -+ -+ slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, base, -+ LDAP_SCOPE_SUBTREE, "(objectclass=*)", func); -+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, -+ base, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny); -+ slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, -+ base, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny); -+ slapi_ch_free_string(&base); -+ -+ return rc; -+} -+ -+int - slapi_plugin_task_register_handler(const char *name, dseCallbackFn func, Slapi_PBlock *plugin_pb) - { - Slapi_PBlock *add_pb = NULL; --- -1.9.3 - diff --git a/SOURCES/0048-Ticket-47831-remove-debug-logging-from-retro-cl.patch b/SOURCES/0048-Ticket-47831-remove-debug-logging-from-retro-cl.patch new file mode 100644 index 0000000..8a3830b --- /dev/null +++ b/SOURCES/0048-Ticket-47831-remove-debug-logging-from-retro-cl.patch @@ -0,0 +1,40 @@ +From 0e44c819b72dfad40a7f9eea6067f6060fa9c35b Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 19 Aug 2015 10:03:50 -0400 +Subject: [PATCH] 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) +(cherry picked from commit 1781280f133c4877f83949400294641a558f5406) +--- + ldap/servers/plugins/retrocl/retrocl_po.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c +index f689373..d9f4e6d 100644 +--- a/ldap/servers/plugins/retrocl/retrocl_po.c ++++ b/ldap/servers/plugins/retrocl/retrocl_po.c +@@ -157,14 +157,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)){ +-- +1.9.3 + diff --git a/SOURCES/0049-Ticket-47451-Running-a-plugin-task-can-crash-the-ser.patch b/SOURCES/0049-Ticket-47451-Running-a-plugin-task-can-crash-the-ser.patch deleted file mode 100644 index 057e0d8..0000000 --- a/SOURCES/0049-Ticket-47451-Running-a-plugin-task-can-crash-the-ser.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 511ee2b326c8110678c34f66d1d043770afc5900 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 26 Nov 2014 16:23:00 -0500 -Subject: [PATCH 49/53] Ticket 47451 - Running a plugin task can crash the - server - -Bug Description: When a plugin task completes it attempts to update a counter, - but the wrong structure is accessed which can lead to a crash. - -Fix Description: When creating a new task, make sure to store the plugin structure, - not the pblock in the task structure. - -https://fedorahosted.org/389/ticket/47451 - -Reviewed by: rmeggins(Thanks!) - -(cherry picked from commit 0e0848a8385463532d53db94c0c8cae912c30eb4) -(cherry picked from commit d34b0ced2ed3ed81c6c487e90d4c372939da4677) ---- - ldap/servers/slapd/task.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index 006ae53..b1f7652 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -131,9 +131,9 @@ slapi_new_task(const char *dn) - } - - Slapi_Task * --slapi_plugin_new_task(const char *dn, void *plugin) -+slapi_plugin_new_task(const char *dn, void *plugin_pb) - { -- return new_task(dn, plugin); -+ return new_task(dn, plugin_pb); - } - - /* slapi_destroy_task: destroy a task -@@ -583,9 +583,11 @@ void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func) - ***********************************/ - /* create a new task, fill in DN, and setup modify callback */ - static Slapi_Task * --new_task(const char *rawdn, void *plugin) -+new_task(const char *rawdn, void *plugin_pb) - { - Slapi_Task *task = NULL; -+ Slapi_PBlock *pb = (Slapi_PBlock *)plugin_pb; -+ void *plugin = pb ? pb->pb_plugin : NULL; - char *dn = NULL; - - if (rawdn == NULL) { --- -1.9.3 - diff --git a/SOURCES/0049-Ticket-48254-CLI-db2index-fails-with-usage-errors.patch b/SOURCES/0049-Ticket-48254-CLI-db2index-fails-with-usage-errors.patch new file mode 100644 index 0000000..e717cd5 --- /dev/null +++ b/SOURCES/0049-Ticket-48254-CLI-db2index-fails-with-usage-errors.patch @@ -0,0 +1,62 @@ +From 6a07ebb40ee121c176f789d01937d7ceedc77776 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 20 Aug 2015 17:01:28 -0700 +Subject: [PATCH 49/52] 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@redhat.com (Thank you, Rich!!) + +(cherry picked from commit 3507c46c9f1156df11b6cf05eba695d81088b416) +(cherry picked from commit a6d7e3bd29eb63def170f73dc21e967df230f20a) +--- + ldap/admin/src/scripts/db2index.in | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/ldap/admin/src/scripts/db2index.in b/ldap/admin/src/scripts/db2index.in +index 2b76cd1..6a0785e 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 +-- +1.9.3 + diff --git a/SOURCES/0050-Ticket-47451-Dynamic-Plugin-various-fixes.patch b/SOURCES/0050-Ticket-47451-Dynamic-Plugin-various-fixes.patch deleted file mode 100644 index 97583e7..0000000 --- a/SOURCES/0050-Ticket-47451-Dynamic-Plugin-various-fixes.patch +++ /dev/null @@ -1,610 +0,0 @@ -From 78b344ff88f488aa63ccccf464e83ad55ee9e96d Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 16 Dec 2014 15:25:35 -0500 -Subject: [PATCH 50/53] Ticket 47451 - Dynamic Plugin - various fixes - -Description: The previous commit 0e0848a8385463532d53db94c0c8cae912c30eb4 on - master branch was wrong, and broke the other plugin tasks. - - Upon further testing, some memory leaks and crashes were detected - and fixed: - - automember.c - Fix memory leak, and PRCList corruption - dna.c - Fix crash caused by event context not being freed at plugin stop - memberof.c - pass in the correct function argument, not the pblock - rootdn_access.c - Fix memory leak - plugins/uiduniq/uid.c - Add start and close functions to properly handle plugin restarts - dse.c - Improve plugin restart handling, and properly handle plugin registration - plugin.c - Properly wait for a plugin to finish before restarting it. - task.c - Proprely handle the task function arguments - -https://fedorahosted.org/389/ticket/47451 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit ff023a48b7fc78711eed8ae11e67057597acdeb3) -(cherry picked from commit f17159e73ba0851599c4e50c1bf52d3d10f2711f) ---- - ldap/servers/plugins/automember/automember.c | 4 +- - ldap/servers/plugins/dna/dna.c | 14 ++- - ldap/servers/plugins/memberof/memberof.c | 2 +- - ldap/servers/plugins/rootdn_access/rootdn_access.c | 4 +- - ldap/servers/plugins/schema_reload/schema_reload.c | 2 +- - ldap/servers/plugins/uiduniq/uid.c | 63 ++++++++---- - ldap/servers/slapd/dse.c | 74 +++++++------- - ldap/servers/slapd/plugin.c | 110 ++++++++++++--------- - ldap/servers/slapd/task.c | 10 +- - 9 files changed, 161 insertions(+), 122 deletions(-) - -diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c -index c443a65..6a8fd22 100644 ---- a/ldap/servers/plugins/automember/automember.c -+++ b/ldap/servers/plugins/automember/automember.c -@@ -406,7 +406,6 @@ automember_close(Slapi_PBlock * pb) - automember_task_add_map_entries); - - automember_delete_config(); -- slapi_ch_free((void **)&g_automember_config); - slapi_sdn_free(&_PluginDN); - slapi_sdn_free(&_ConfigAreaDN); - slapi_destroy_rwlock(g_automember_config_lock); -@@ -449,6 +448,8 @@ automember_load_config() - /* Clear out any old config. */ - automember_config_write_lock(); - automember_delete_config(); -+ g_automember_config = (PRCList *)slapi_ch_calloc(1, sizeof(struct configEntry)); -+ PR_INIT_CLIST(g_automember_config); - - search_pb = slapi_pblock_new(); - -@@ -866,6 +867,7 @@ automember_delete_config() - list = PR_LIST_HEAD(g_automember_config); - automember_delete_configEntry(list); - } -+ slapi_ch_free((void **)&g_automember_config); - - return; - } -diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c -index 75edca8..ded0bbb 100644 ---- a/ldap/servers/plugins/dna/dna.c -+++ b/ldap/servers/plugins/dna/dna.c -@@ -202,6 +202,7 @@ static char *hostname = NULL; - static char *portnum = NULL; - static char *secureportnum = NULL; - -+static Slapi_Eq_Context eq_ctx = {0}; - - /** - * server struct for shared ranges -@@ -708,6 +709,7 @@ dna_close(Slapi_PBlock * pb) - slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM, - "--> dna_close\n"); - -+ slapi_eq_cancel(eq_ctx); - dna_delete_config(NULL); - slapi_ch_free((void **)&dna_global_config); - slapi_destroy_rwlock(g_dna_cache_lock); -@@ -869,7 +871,7 @@ dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq) - * starting up would cause the change to not - * get changelogged. */ - time(&now); -- slapi_eq_once(dna_update_config_event, NULL, now + 30); -+ eq_ctx = slapi_eq_once(dna_update_config_event, NULL, now + 30); - } else { - dna_update_config_event(0, NULL); - } -@@ -2404,7 +2406,7 @@ static int dna_get_next_value(struct configEntry *config_entry, - } else { - /* dna_first_free_value() failed for some unknown reason */ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -- "dna_get_next_value: failed to allocate a new ID!!\n"); -+ "dna_get_next_value: failed to allocate a new ID!! (set(%d) (max: %d)\n",setval,config_entry->maxval); - goto done; - } - } -@@ -3401,7 +3403,7 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr) - ret = dna_first_free_value(config_entry, &setval); - if (LDAP_SUCCESS != ret){ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -- "dna_pre_op: failed to allocate a new ID\n"); -+ "dna_pre_op: failed to allocate a new ID 1\n"); - /* Set an error string to be returned to the client. */ - *errstr = slapi_ch_smprintf("Allocation of a new value for range" - " %s failed! Unable to proceed.", -@@ -3412,7 +3414,9 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr) - } else { - /* dna_first_free_value() failed for some unknown reason */ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -- "dna_pre_op: failed to allocate a new ID!!\n"); -+ "dna_pre_op: failed to allocate a new ID!! 2\n"); -+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -+ "dna_get_next_value: failed to allocate a new ID!! (set(%d) (max: %d)\n",setval,config_entry->maxval); - /* Set an error string to be returned to the client. */ - *errstr = slapi_ch_smprintf("Allocation of a new value for range" - " %s failed! Unable to proceed.", -@@ -3678,6 +3682,8 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods, char **e - /* dna_first_free_value() failed for some unknown reason */ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, - "dna_pre_op: failed to allocate a new ID!!\n"); -+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -+ "dna_get_next_value: failed to allocate a new ID!! (set(%d) (max: %d)\n",setval,config_entry->maxval); - /* Set an error string to be returned to the client. */ - *errstr = slapi_ch_smprintf("Allocation of a new value for range" - " %s failed! Unable to proceed.", -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index cb4ef75..bfa733a 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -2764,7 +2764,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, - mytaskdata->bind_dn = slapi_ch_strdup(bind_dn); - - /* allocate new task now */ -- task = slapi_plugin_new_task(slapi_entry_get_ndn(e), pb); -+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg); - - /* register our destructor for cleaning up our private data */ - slapi_task_set_destructor_fn(task, memberof_task_destructor); -diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c -index 9122f9b..3045e9f 100644 ---- a/ldap/servers/plugins/rootdn_access/rootdn_access.c -+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c -@@ -217,7 +217,7 @@ rootdn_close(Slapi_PBlock *pb) - slapi_ch_array_free(hosts); - slapi_ch_array_free(hosts_to_deny); - slapi_ch_array_free(ips); -- slapi_ch_array_free(ips); -+ slapi_ch_array_free(ips_to_deny); - - return 0; - } -@@ -416,6 +416,8 @@ rootdn_load_config(Slapi_PBlock *pb) - } - } else { - /* failed to get the plugin entry */ -+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: " -+ "Failed to get plugin entry\n"); - result = -1; - } - -diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c -index 3ff4c4d..b1a5bb8 100644 ---- a/ldap/servers/plugins/schema_reload/schema_reload.c -+++ b/ldap/servers/plugins/schema_reload/schema_reload.c -@@ -273,7 +273,7 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, - schemadir = fetch_attr(e, "schemadir", NULL); - - /* allocate new task now */ -- task = slapi_plugin_new_task(slapi_entry_get_ndn(e), pb); -+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg); - if (task == NULL) { - slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "unable to allocate new task!\n"); - *returncode = LDAP_OPERATIONS_ERROR; -diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c -index 07ff0ec..f37ab8c 100644 ---- a/ldap/servers/plugins/uiduniq/uid.c -+++ b/ldap/servers/plugins/uiduniq/uid.c -@@ -1265,6 +1265,38 @@ preop_modrdn(Slapi_PBlock *pb) - - } - -+static int -+uiduniq_start(Slapi_PBlock *pb) -+{ -+ Slapi_Entry *plugin_entry = NULL; -+ struct attr_uniqueness_config *config = NULL; -+ -+ if (slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &plugin_entry) == 0){ -+ /* load the config into the config list */ -+ if ((config = uniqueness_entry_to_config(pb, plugin_entry)) == NULL) { -+ return SLAPI_PLUGIN_FAILURE; -+ } -+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, (void*) config); -+ } -+ -+ return 0; -+} -+ -+static int -+uiduniq_close(Slapi_PBlock *pb) -+{ -+ Slapi_Entry *plugin_entry = NULL; -+ struct attr_uniqueness_config *config = NULL; -+ -+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &config); -+ if (config) { -+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, NULL); -+ free_uniqueness_config(config); -+ slapi_ch_free((void **) &config); -+ } -+ return 0; -+} -+ - /* ------------------------------------------------------------ */ - /* - * Initialize the plugin -@@ -1307,13 +1339,6 @@ NSUniqueAttr_Init(Slapi_PBlock *pb) - } - slapi_ch_free_string(&plugin_type); - -- /* load the config into the config list */ -- if ((config = uniqueness_entry_to_config(pb, plugin_entry)) == NULL) { -- err = SLAPI_PLUGIN_FAILURE; -- break; -- } -- slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, (void*) config); -- - /* Provide descriptive information */ - err = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, - (void*)&pluginDesc); -@@ -1329,30 +1354,26 @@ NSUniqueAttr_Init(Slapi_PBlock *pb) - err = slapi_pblock_set(pb, premdn, (void*)preop_modrdn); - if (err) break; - -+ err = slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *) uiduniq_start); -+ if (err) break; -+ -+ err = slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *) uiduniq_close); -+ if (err) break; -+ -+ - END - - if (err) { -- slapi_log_error(SLAPI_LOG_PLUGIN, "NSUniqueAttr_Init", -- "Error: %d\n", err); -- if (config) { -- slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, NULL); -- free_uniqueness_config(config); -- slapi_ch_free((void **) &config); -- } -+ slapi_log_error(SLAPI_LOG_PLUGIN, "NSUniqueAttr_Init", "Error: %d\n", err); - err = -1; - } - else -- slapi_log_error(SLAPI_LOG_PLUGIN, "NSUniqueAttr_Init", -- "plugin loaded\n"); -+ slapi_log_error(SLAPI_LOG_PLUGIN, "NSUniqueAttr_Init", "plugin loaded\n"); - - return err; - } - --int --uidunique_init(Slapi_PBlock *pb) --{ -- return NSUniqueAttr_Init(pb); --} -+ - - - /* ------------------------------------------------------------ */ -diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c -index fc5f492..f0ce255 100644 ---- a/ldap/servers/slapd/dse.c -+++ b/ldap/servers/slapd/dse.c -@@ -1827,6 +1827,7 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi - int retval = -1; - int need_be_postop = 0; - int plugin_started = 0; -+ int internal_op = 0; - - PR_ASSERT(pb); - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &pdse ) < 0 || -@@ -1843,6 +1844,8 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi - return retval; - } - -+ internal_op = operation_is_flag_set(pb->pb_op, OP_FLAG_INTERNAL); -+ - /* Find the entry we are about to modify. */ - ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK); - if ( ec == NULL ) { -@@ -2039,20 +2042,22 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi - } - } - /* -- * Perform postop plugin configuration changes -+ * Perform postop plugin configuration changes unless this is an internal operation - */ -- if(returncode == LDAP_SUCCESS){ -- dse_post_modify_plugin(ec, ecc, mods); -- } else if(plugin_started){ -- if(plugin_started == 1){ -- /* the op failed, turn the plugin off */ -- plugin_delete(ecc, returntext, 0 /* not locked */); -- } else if (plugin_started == 2){ -- /* -- * This probably can't happen, but... -- * the op failed, turn the plugin back on. -- */ -- plugin_add(ecc, returntext, 0 /* not locked */); -+ if(!internal_op){ -+ if(returncode == LDAP_SUCCESS){ -+ dse_post_modify_plugin(ec, ecc, mods); -+ } else if(plugin_started){ -+ if(plugin_started == 1){ -+ /* the op failed, turn the plugin off */ -+ plugin_delete(ecc, returntext, 0 /* not locked */); -+ } else if (plugin_started == 2){ -+ /* -+ * This probably can't happen, but... -+ * the op failed, turn the plugin back on. -+ */ -+ plugin_add(ecc, returntext, 0 /* not locked */); -+ } - } - } - -@@ -2065,6 +2070,7 @@ static void - dse_post_modify_plugin(Slapi_Entry *entryBefore, Slapi_Entry *entryAfter, LDAPMod **mods) - { - char *enabled = NULL; -+ int restart_plugin = 1; - int i; - - if (!slapi_entry_attr_hasvalue(entryBefore, SLAPI_ATTR_OBJECTCLASS, "nsSlapdPlugin") || -@@ -2080,31 +2086,18 @@ dse_post_modify_plugin(Slapi_Entry *entryBefore, Slapi_Entry *entryAfter, LDAPMo - !strcasecmp(enabled, "on")) - { - for(i = 0; mods && mods[i]; i++){ -- /* Check if we are modifying a plugin's config, if so restart the plugin */ -- if (strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_PATH) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_INITFN) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_TYPE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_DEPENDS_ON_TYPE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_DEPENDS_ON_NAMED) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_SCHEMA_CHECK) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_BE_TXN) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_TARGET_SUBTREE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_EXCLUDE_TARGET_SUBTREE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_BIND_SUBTREE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_EXCLUDE_BIND_SUBTREE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOAD_NOW) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOAD_GLOBAL) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_PRECEDENCE) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOG_ACCESS) == 0 || -- strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOG_AUDIT) == 0 ) -- { -- /* for all other plugin config changes, restart the plugin */ -- if(plugin_restart(entryBefore, entryAfter) != LDAP_SUCCESS){ -- slapi_log_error(SLAPI_LOG_FATAL,"dse_post_modify_plugin", "The configuration change " -- "for plugin (%s) could not be applied dynamically, and will be ignored until " -- "the server is restarted.\n", -- slapi_entry_get_dn(entryBefore)); -- } -+ if (strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_ENABLED) == 0){ -+ /* we already stop/started the pugin - don't do it again */ -+ restart_plugin = 0; -+ break; -+ } -+ } -+ if(restart_plugin){ /* for all other plugin config changes, restart the plugin */ -+ if(plugin_restart(entryBefore, entryAfter) != LDAP_SUCCESS){ -+ slapi_log_error(SLAPI_LOG_FATAL,"dse_post_modify_plugin", "The configuration change " -+ "for plugin (%s) could not be applied dynamically, and will be ignored until " -+ "the server is restarted.\n", -+ slapi_entry_get_dn(entryBefore)); - } - } - } -@@ -2690,7 +2683,10 @@ slapi_config_register_callback_plugin(int operation, - Slapi_DN dn; - - slapi_sdn_init_dn_byref(&dn,base); -- rc = (NULL != dse_register_callback(pdse, operation, flags, &dn, scope, filter, fn, fn_arg, pb ? pb->pb_plugin: NULL)); -+ /* if a pblock was passed, this is a plugin, so set the f_arg as the plugin */ -+ rc = (NULL != dse_register_callback(pdse, operation, flags, &dn, scope, filter, fn, -+ pb ? (void*)pb->pb_plugin : fn_arg, -+ pb ? pb->pb_plugin: NULL)); - slapi_sdn_done(&dn); - } - } -diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c -index dde3ce5..820c25f 100644 ---- a/ldap/servers/slapd/plugin.c -+++ b/ldap/servers/slapd/plugin.c -@@ -58,6 +58,11 @@ - #define CHECK_ALL 0 - #define CHECK_TYPE 1 - -+/* plugin removal flags */ -+#define PLUGIN_NOT_FOUND 0 -+#define PLUGIN_REMOVED 1 -+#define PLUGIN_BUSY 2 -+ - static char *critical_plugins[] = { "cn=ldbm database,cn=plugins,cn=config", - "cn=ACL Plugin,cn=plugins,cn=config", - "cn=ACL preoperation,cn=plugins,cn=config", -@@ -3294,7 +3299,7 @@ plugin_remove_plugins(struct slapdplugin *plugin_entry, char *plugin_type) - struct slapdplugin *plugin = NULL; - struct slapdplugin *plugin_next = NULL; - struct slapdplugin *plugin_prev = NULL; -- int removed = 0; -+ int removed = PLUGIN_NOT_FOUND; - int type; - - /* look everywhere for other plugin functions with the plugin id */ -@@ -3315,7 +3320,13 @@ plugin_remove_plugins(struct slapdplugin *plugin_entry, char *plugin_type) - - pblock_init(&pb); - plugin_set_stopped(plugin); -- plugin_op_all_finished(plugin); -+ if (slapi_counter_get_value(plugin->plg_op_counter) > 0){ -+ /* -+ * Plugin is still busy, and we might be blocking it -+ * by holding global plugin lock so return for now. -+ */ -+ return PLUGIN_BUSY; -+ } - plugin_call_one( plugin, SLAPI_PLUGIN_CLOSE_FN, &pb); - - if(plugin_prev){ -@@ -3332,7 +3343,7 @@ plugin_remove_plugins(struct slapdplugin *plugin_entry, char *plugin_type) - plugin_remove_from_shutdown(plugin); - plugin->plg_removed = 1; - plugin->plg_started = 0; -- removed = 1; -+ removed = PLUGIN_REMOVED; - } else { - plugin_prev = plugin; - } -@@ -3362,15 +3373,10 @@ plugin_delete(Slapi_Entry *plugin_entry, char *returntext, int locked) - const char *plugin_dn = slapi_entry_get_dn_const(plugin_entry); - char *value = NULL; - int td_locked = 1; -- int removed = 0; -+ int removed = PLUGIN_BUSY; - int type = 0; - int rc = LDAP_SUCCESS; - -- if(!locked){ -- slapi_rwlock_wrlock(global_rwlock); -- } -- slapi_td_set_plugin_locked(&td_locked); -- - /* Critical server plugins can not be disabled */ - if(plugin_is_critical(plugin_entry)){ - LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: plugin \"%s\" is critical to server operations, and can not be disabled\n", -@@ -3390,54 +3396,62 @@ plugin_delete(Slapi_Entry *plugin_entry, char *returntext, int locked) - rc = -1; - goto done; - } else { -- rc = plugin_get_type_and_list(value, &type, &plugin_list); -- if ( rc != 0 ) { -- /* error: unknown plugin type */ -- LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: unknown plugin type \"%s\" in entry \"%s\"\n", -- value, slapi_entry_get_dn_const(plugin_entry), 0); -- PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Plugin delete failed: unknown plugin type " -+ while(removed == PLUGIN_BUSY){ -+ removed = PLUGIN_NOT_FOUND; -+ if(!locked){ -+ slapi_rwlock_wrlock(global_rwlock); -+ } -+ slapi_td_set_plugin_locked(&td_locked); -+ -+ rc = plugin_get_type_and_list(value, &type, &plugin_list); -+ if ( rc != 0 ) { -+ /* error: unknown plugin type */ -+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: unknown plugin type \"%s\" in entry \"%s\"\n", -+ value, slapi_entry_get_dn_const(plugin_entry), 0); -+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Plugin delete failed: unknown plugin type " - "\"%s\" in entry.",value); -- rc = -1; -- goto done; -- } -+ rc = -1; -+ goto unlock; -+ } - -- /* -- * Skip syntax/matching rule/database plugins - these can not be disabled as it -- * could break existing schema. We allow the update to occur, but it will -- * not take effect until the next server restart. -- */ -- if(type == SLAPI_PLUGIN_SYNTAX || type == SLAPI_PLUGIN_MATCHINGRULE || type == SLAPI_PLUGIN_DATABASE){ -- removed = 1; /* avoids error check below */ -- goto done; -- } -+ /* -+ * Skip syntax/matching rule/database plugins - these can not be disabled as it -+ * could break existing schema. We allow the update to occur, but it will -+ * not take effect until the next server restart. -+ */ -+ if(type == SLAPI_PLUGIN_SYNTAX || type == SLAPI_PLUGIN_MATCHINGRULE || type == SLAPI_PLUGIN_DATABASE){ -+ removed = PLUGIN_REMOVED; /* avoids error check below */ -+ goto unlock; -+ } - -- /* -- * Now remove the plugin from the list and the hashtable -- */ -- for(plugin = *plugin_list; plugin ; plugin = plugin->plg_next){ -- if(strcasecmp(plugin->plg_dn, plugin_dn) == 0){ -- /* -- * Make sure there are no other plugins that depend on this one before removing it -- */ -- if(plugin_delete_check_dependency(plugin, CHECK_ALL, returntext) != LDAP_SUCCESS){ -- LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: failed to disable/delete plugin (%s)\n", -- plugin->plg_dn,0,0); -- rc = -1; -- goto done; -+ /* -+ * Now remove the plugin from the list and the hashtable -+ */ -+ for(plugin = *plugin_list; plugin ; plugin = plugin->plg_next){ -+ if(strcasecmp(plugin->plg_dn, plugin_dn) == 0){ -+ /* -+ * Make sure there are no other plugins that depend on this one before removing it -+ */ -+ if(plugin_delete_check_dependency(plugin, CHECK_ALL, returntext) != LDAP_SUCCESS){ -+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: failed to disable/delete plugin (%s)\n", -+ plugin->plg_dn,0,0); -+ rc = -1; -+ break; -+ } -+ removed = plugin_remove_plugins(plugin, value); -+ break; - } -- removed = plugin_remove_plugins(plugin, value); -- break; - } -+unlock: -+ if(!locked){ -+ slapi_rwlock_unlock(global_rwlock); -+ } -+ td_locked = 0; -+ slapi_td_set_plugin_locked(&td_locked); - } - } - - done: -- if(!locked){ -- slapi_rwlock_unlock(global_rwlock); -- } -- td_locked = 0; -- slapi_td_set_plugin_locked(&td_locked); -- - slapi_ch_free_string(&value); - - if(!removed && rc == 0){ -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index b1f7652..98ec88c 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -131,9 +131,9 @@ slapi_new_task(const char *dn) - } - - Slapi_Task * --slapi_plugin_new_task(const char *dn, void *plugin_pb) -+slapi_plugin_new_task(const char *dn, void *plugin) - { -- return new_task(dn, plugin_pb); -+ return new_task(dn, plugin); - } - - /* slapi_destroy_task: destroy a task -@@ -540,7 +540,7 @@ slapi_plugin_task_register_handler(const char *name, dseCallbackFn func, Slapi_P - - /* register add callback */ - slapi_config_register_callback_plugin(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, -- dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)", func, NULL, plugin_pb); -+ dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)", func, plugin_pb, plugin_pb); - /* deny modify/delete of the root task entry */ - slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, - dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny, NULL); -@@ -583,11 +583,9 @@ void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func) - ***********************************/ - /* create a new task, fill in DN, and setup modify callback */ - static Slapi_Task * --new_task(const char *rawdn, void *plugin_pb) -+new_task(const char *rawdn, void *plugin) - { - Slapi_Task *task = NULL; -- Slapi_PBlock *pb = (Slapi_PBlock *)plugin_pb; -- void *plugin = pb ? pb->pb_plugin : NULL; - char *dn = NULL; - - if (rawdn == NULL) { --- -1.9.3 - diff --git a/SOURCES/0050-Ticket-48254-Shell-CLI-fails-with-usage-errors-if-an.patch b/SOURCES/0050-Ticket-48254-Shell-CLI-fails-with-usage-errors-if-an.patch new file mode 100644 index 0000000..4582e71 --- /dev/null +++ b/SOURCES/0050-Ticket-48254-Shell-CLI-fails-with-usage-errors-if-an.patch @@ -0,0 +1,375 @@ +From 94bde9f69f10e0811e261b5d53e5bebfcd891820 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 25 Aug 2015 11:48:31 -0700 +Subject: [PATCH 50/52] Ticket #48254 - Shell CLI fails with usage errors if an + argument containing white spaces is given + +Description: In addition to the patch: + Ticket #48254 - CLI db2index fails with usage errors + commit 3507c46c9f1156df11b6cf05eba695d81088b416 +applying the similar changes to all the shell CLI which could be given +arguments that include white spaces. + +https://fedorahosted.org/389/ticket/48254 + +Reviewed by mreynolds@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 5fe28921810a53dcd31525ba1f675582b6aba0f7) +(cherry picked from commit 19b0d4af54e319e3479b16bf1366568271e3daa6) +--- + ldap/admin/src/scripts/bak2db.in | 10 +++++----- + ldap/admin/src/scripts/db2bak.in | 8 ++++---- + ldap/admin/src/scripts/db2index.in | 10 +++++----- + ldap/admin/src/scripts/db2ldif.in | 14 +++++++------- + ldap/admin/src/scripts/dbverify.in | 10 +++++----- + ldap/admin/src/scripts/dn2rdn.in | 8 ++++---- + ldap/admin/src/scripts/ldif2db.in | 22 +++++++++++----------- + ldap/admin/src/scripts/monitor.in | 8 ++++---- + ldap/admin/src/scripts/suffix2instance.in | 4 ++-- + ldap/admin/src/scripts/upgradedb.in | 8 ++++---- + ldap/admin/src/scripts/upgradednformat.in | 10 +++++----- + ldap/admin/src/scripts/vlvindex.in | 16 ++++++++-------- + 12 files changed, 64 insertions(+), 64 deletions(-) + +diff --git a/ldap/admin/src/scripts/bak2db.in b/ldap/admin/src/scripts/bak2db.in +index a2e54cc..ab7c6b3 100755 +--- a/ldap/admin/src/scripts/bak2db.in ++++ b/ldap/admin/src/scripts/bak2db.in +@@ -44,12 +44,12 @@ do + h) usage + exit 0;; + Z) servid=$OPTARG;; +- n) args=$args" -n $OPTARG";; ++ n) args=$args" -n \"$OPTARG\"";; + q) args=$args" -q";; +- d) args=$args" -d $OPTARG";; ++ d) args=$args" -d \"$OPTARG\"";; + v) args=$args" -v";; +- D) args=$args" -D $OPTARG";; +- i) args=$args" -i $OPTARG";; ++ D) args=$args" -D \"$OPTARG\"";; ++ i) args=$args" -i \"$OPTARG\"";; + a) archivedir=$OPTARG;; + S) args=$args" -S";; + ?) usage +@@ -76,4 +76,4 @@ else + archivedir=`pwd`/$archivedir + fi + +-@sbindir@/ns-slapd archive2db -D $CONFIG_DIR -a $archivedir $args ++eval @sbindir@/ns-slapd archive2db -D $CONFIG_DIR -a $archivedir $args +diff --git a/ldap/admin/src/scripts/db2bak.in b/ldap/admin/src/scripts/db2bak.in +index 1896c19..adbe30b 100755 +--- a/ldap/admin/src/scripts/db2bak.in ++++ b/ldap/admin/src/scripts/db2bak.in +@@ -43,10 +43,10 @@ do + q) args=$args" -q";; + v) args=$args" -v";; + S) args=$args" -S";; +- D) args=$args" -D $OPTARG";; +- i) args=$args" -i $OPTARG";; ++ D) args=$args" -D \"$OPTARG\"";; ++ i) args=$args" -i \"$OPTARG\"";; + a) $bakdir=$OPTARG;; +- d) args=$args" -d $OPTARG";; ++ d) args=$args" -d \"$OPTARG\"";; + Z) servid=$OPTARG;; + ?) usage + exit 1;; +@@ -72,4 +72,4 @@ then + fi + + echo "Back up directory: $bak_dir" +-@sbindir@/ns-slapd db2archive -D $CONFIG_DIR -a $bak_dir $args ++eval @sbindir@/ns-slapd db2archive -D $CONFIG_DIR -a $bak_dir $args +diff --git a/ldap/admin/src/scripts/db2index.in b/ldap/admin/src/scripts/db2index.in +index 6a0785e..c8e9075 100755 +--- a/ldap/admin/src/scripts/db2index.in ++++ b/ldap/admin/src/scripts/db2index.in +@@ -35,15 +35,15 @@ do + h) usage + exit 0;; + Z) servid=$OPTARG;; +- n) args=$args" -n $OPTARG" ++ n) args=$args" -n \"$OPTARG\"" + benameopt="set";; +- s) args=$args" -s $OPTARG" ++ 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";; ++ 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";; +diff --git a/ldap/admin/src/scripts/db2ldif.in b/ldap/admin/src/scripts/db2ldif.in +index fcf73a0..e9f7f7e 100755 +--- a/ldap/admin/src/scripts/db2ldif.in ++++ b/ldap/admin/src/scripts/db2ldif.in +@@ -106,12 +106,12 @@ do + Z) servid=$OPTARG;; + n) benameopt="-n $OPTARG" + required_param="yes";; +- s) includeSuffix="-s $OPTARG" ++ s) includeSuffix="-s \"$OPTARG\"" + required_param="yes";; +- x) excludeSuffix="-x $OPTARG";; +- a) outputFile="-a $OPTARG";; +- d) args=$args" -d $OPTARG";; +- D) args=$args" -D $OPTARG";; ++ x) excludeSuffix="-x \"$OPTARG\"";; ++ a) outputFile="-a \"$OPTARG\"";; ++ d) args=$args" -d \"$OPTARG\"";; ++ D) args=$args" -D \"$OPTARG\"";; + N) args=$args" -N";; + E) args=$args" -E";; + S) args=$args" -S";; +@@ -154,7 +154,7 @@ rn=$? + echo "Exported ldif file: $ldif_file" + if [ $rn -eq 1 ] + then +- @sbindir@/ns-slapd db2ldif -D $CONFIG_DIR $benameopt $includeSuffix $excludeSuffix $outputFile $args ++ eval @sbindir@/ns-slapd db2ldif -D $CONFIG_DIR $benameopt $includeSuffix $excludeSuffix $outputFile $args + else +- @sbindir@/ns-slapd db2ldif -D $CONFIG_DIR $benameopt $includeSuffix $excludeSuffix $args -a $ldif_file ++ eval @sbindir@/ns-slapd db2ldif -D $CONFIG_DIR $benameopt $includeSuffix $excludeSuffix $args -a $ldif_file + fi +diff --git a/ldap/admin/src/scripts/dbverify.in b/ldap/admin/src/scripts/dbverify.in +index bbacc17..b98e9b2 100755 +--- a/ldap/admin/src/scripts/dbverify.in ++++ b/ldap/admin/src/scripts/dbverify.in +@@ -33,14 +33,14 @@ do + h) usage + exit 0;; + Z) servid=$OPTARG;; +- n) args=$args" -n $OPTARG";; +- d) args=$args" -d $OPTARG";; ++ n) args=$args" -n \"$OPTARG\"";; ++ d) args=$args" -d \"$OPTARG\"";; + V) args=$args" -V";; + v) args=$args" -v" + display_version="yes";; + f) args=$args" -f";; +- D) args=$args" -D $OPTARG";; +- a) args=$args" -a $OPTARG";; ++ D) args=$args" -D \"$OPTARG\"";; ++ a) args=$args" -a \"$OPTARG\"";; + ?) usage + exit 1;; + esac +@@ -57,7 +57,7 @@ fi + + . $initfile + +-@sbindir@/ns-slapd dbverify -D $CONFIG_DIR $args ++eval @sbindir@/ns-slapd dbverify -D $CONFIG_DIR $args + if [ $display_version = "yes" ]; then + exit 0 + fi +diff --git a/ldap/admin/src/scripts/dn2rdn.in b/ldap/admin/src/scripts/dn2rdn.in +index 616969a..762e63a 100755 +--- a/ldap/admin/src/scripts/dn2rdn.in ++++ b/ldap/admin/src/scripts/dn2rdn.in +@@ -27,12 +27,12 @@ do + h) usage + exit 0;; + Z) servid=$OPTARG;; +- d) arg=$arg" -d $OPTARG";; +- a) arg=$arg" -a $OPTARG" ++ d) arg=$arg" -d \"$OPTARG\"";; ++ a) arg=$arg" -a \"$OPTARG\"" + archive="provided";; + v) arg=$arg" -v";; + f) arg=$arg" -f";; +- D) arg=$arg" -D $OPTARG";; ++ D) arg=$arg" -D \"$OPTARG\"";; + ?) usage + exit 1;; + esac +@@ -55,4 +55,4 @@ if [ "$archive" != "provided" ]; then + args=$args"-a $bak_dir" + fi + +-@sbindir@/ns-slapd upgradedb -D $CONFIG_DIR -r $args ++eval @sbindir@/ns-slapd upgradedb -D $CONFIG_DIR -r $args +diff --git a/ldap/admin/src/scripts/ldif2db.in b/ldap/admin/src/scripts/ldif2db.in +index a34241a..3aed469 100755 +--- a/ldap/admin/src/scripts/ldif2db.in ++++ b/ldap/admin/src/scripts/ldif2db.in +@@ -59,16 +59,16 @@ do + h) usage + exit 0;; + Z) servid=$OPTARG;; +- n) args=$args" -n $OPTARG";; +- i) args=$args" -i $OPTARG";; +- s) args=$args" -s $OPTARG";; +- x) args=$args" -x $OPTARG";; +- c) args=$args" -c $OPTARG";; +- d) args=$args" -d $OPTARG";; +- g) args=$args" -g $OPTARG";; +- G) args=$args" -G $OPTARG";; +- t) args=$args" -t $OPTARG";; +- D) args=$args" -D $OPTARG";; ++ n) args=$args" -n \"$OPTARG\"";; ++ i) args=$args" -i \"$OPTARG\"";; ++ s) args=$args" -s \"$OPTARG\"";; ++ x) args=$args" -x \"$OPTARG\"";; ++ c) args=$args" -c \"$OPTARG\"";; ++ d) args=$args" -d \"$OPTARG\"";; ++ g) args=$args" -g \"$OPTARG\"";; ++ G) args=$args" -G \"$OPTARG\"";; ++ t) args=$args" -t \"$OPTARG\"";; ++ D) args=$args" -D \"$OPTARG\"";; + E) args=$args" -E";; + v) args=$args" -v";; + N) args=$args" -N";; +@@ -104,6 +104,6 @@ if [ $quiet -eq 0 ]; then + echo importing data ... + fi + +-@sbindir@/ns-slapd ldif2db -D $CONFIG_DIR $args 2>&1 ++eval @sbindir@/ns-slapd ldif2db -D $CONFIG_DIR $args 2>&1 + + exit $? +diff --git a/ldap/admin/src/scripts/monitor.in b/ldap/admin/src/scripts/monitor.in +index 36a2fc9..e9265a1 100755 +--- a/ldap/admin/src/scripts/monitor.in ++++ b/ldap/admin/src/scripts/monitor.in +@@ -73,8 +73,8 @@ fi + rm $file + + if [ -n "$passwd" ]; then +- dn="-D $rootdn" +- passwd="-w$passwd" ++ dn="-D \"$rootdn\"" ++ passwd="-w \"$passwd\"" + fi + if [ -n "$ldapiURL" ] + then +@@ -109,9 +109,9 @@ if [ "$security" = "on" ]; then + echo "Using the next most secure protocol(STARTTLS)" + fi + if [ "$openldap" = "yes" ]; then +- ldapsearch -x -LLL -ZZ -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" ++ eval ldapsearch -x -LLL -ZZ -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" + else +- ldapsearch -ZZZ -P $certdir -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" ++ eval ldapsearch -ZZZ -P $certdir -h $host -p $port -b "$MDN" -s base $dn $passwd "objectClass=*" + fi + exit $? + fi +diff --git a/ldap/admin/src/scripts/suffix2instance.in b/ldap/admin/src/scripts/suffix2instance.in +index 7774148..d7c6661 100755 +--- a/ldap/admin/src/scripts/suffix2instance.in ++++ b/ldap/admin/src/scripts/suffix2instance.in +@@ -24,7 +24,7 @@ while getopts "Z:s:h" flag + do + case $flag in + Z) servid=$OPTARG;; +- s) args=$args" -s $OPTARG";; ++ s) args=$args" -s \"$OPTARG\"";; + h) usage + exit 0;; + ?) usage +@@ -55,4 +55,4 @@ then + exit 1 + fi + +-@sbindir@/ns-slapd suffix2instance -D $CONFIG_DIR $args 2>&1 ++eval @sbindir@/ns-slapd suffix2instance -D $CONFIG_DIR $args 2>&1 +diff --git a/ldap/admin/src/scripts/upgradedb.in b/ldap/admin/src/scripts/upgradedb.in +index bf600dd..2b7c79d 100755 +--- a/ldap/admin/src/scripts/upgradedb.in ++++ b/ldap/admin/src/scripts/upgradedb.in +@@ -29,10 +29,10 @@ do + v) args=$args" -v";; + f) args=$args" -f";; + r) args=$args" -r";; +- d) args=$args" -d $OPTARG";; +- a) args=$args" -a $OPTARG" ++ d) args=$args" -d \"$OPTARG\"";; ++ a) args=$args" -a \"$OPTARG\"" + archive_provided="yes";; +- D) args=$args" -D $OPTARG";; ++ D) args=$args" -D \"$OPTARG\"";; + h) usage + exit 0;; + esac +@@ -56,4 +56,4 @@ then + fi + + echo upgrade index files ... +-@sbindir@/ns-slapd upgradedb -D $CONFIG_DIR $args ++eval @sbindir@/ns-slapd upgradedb -D $CONFIG_DIR $args +diff --git a/ldap/admin/src/scripts/upgradednformat.in b/ldap/admin/src/scripts/upgradednformat.in +index 51585ae..9de60ea 100755 +--- a/ldap/admin/src/scripts/upgradednformat.in ++++ b/ldap/admin/src/scripts/upgradednformat.in +@@ -36,14 +36,14 @@ do + Z) servid=$OPTARG;; + v) args=$args" -v";; + N) args=$args" -N";; +- d) args=$args" -d $OPTARG";; +- a) args=$args" -a $OPTARG" ++ d) args=$args" -d \"$OPTARG\"";; ++ a) args=$args" -a \"$OPTARG\"" + dir="set";; +- n) args=$args" -n $OPTARG" ++ n) args=$args" -n \"$OPTARG\"" + be="set";; + h) usage + exit 0;; +- D) args=$args" -D $OPTARG";; ++ D) args=$args" -D \"$OPTARG\"";; + ?) usage + exit 1;; + esac +@@ -65,7 +65,7 @@ fi + + . $initfile + +-@sbindir@/ns-slapd upgradednformat -D $CONFIG_DIR $args ++eval @sbindir@/ns-slapd upgradednformat -D $CONFIG_DIR $args + rc=$? + + exit $rc +diff --git a/ldap/admin/src/scripts/vlvindex.in b/ldap/admin/src/scripts/vlvindex.in +index 365e32f..a1696bc 100755 +--- a/ldap/admin/src/scripts/vlvindex.in ++++ b/ldap/admin/src/scripts/vlvindex.in +@@ -29,14 +29,14 @@ do + case $flag in + Z) servid=$OPTARG;; + v) args=$args" -v";; +- s) args=$args" -s $OPTARG";; +- d) args=$args" -d $OPTARG";; +- a) args=$args" -a $OPTARG";; +- T) args=$args" -T $OPTARG";; ++ s) args=$args" -s \"$OPTARG\"";; ++ d) args=$args" -d \"$OPTARG\"";; ++ a) args=$args" -a \"$OPTARG\"";; ++ T) args=$args" -T \"$OPTARG\"";; + S) args=$args" -S";; +- n) args=$args" -n $OPTARG";; +- x) args=$args" -x $OPTARG";; +- D) args=$args" -D $OPTARG";; ++ n) args=$args" -n \"$OPTARG\"";; ++ x) args=$args" -x \"$OPTARG\"";; ++ D) args=$args" -D \"$OPTARG\"";; + h) usage + exit 0;; + ?) usage +@@ -61,4 +61,4 @@ then + exit 1 + fi + +-@sbindir@/ns-slapd db2index -D $CONFIG_DIR $args ++eval @sbindir@/ns-slapd db2index -D $CONFIG_DIR $args +-- +1.9.3 + diff --git a/SOURCES/0051-Ticket-47451-Fix-jenkins-errors.patch b/SOURCES/0051-Ticket-47451-Fix-jenkins-errors.patch deleted file mode 100644 index 6e44fad..0000000 --- a/SOURCES/0051-Ticket-47451-Fix-jenkins-errors.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 7602bd4138d78c7df9479b3f760895cecd10d7d9 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 16 Dec 2014 16:10:05 -0500 -Subject: [PATCH 51/53] Ticket 47451 - Fix jenkins errors - -Description: Fix compiler warnings - -https://fedorahosted.org/389/ticket/47451 -(cherry picked from commit 3e1d97624f390b96c1de21b115619822b72ebf98) -(cherry picked from commit 15e1cdd7d01933d42b83b00e1e8c01c16fd36e8e) ---- - ldap/servers/plugins/dna/dna.c | 6 +----- - ldap/servers/plugins/uiduniq/uid.c | 2 -- - 2 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c -index ded0bbb..f4a36f0 100644 ---- a/ldap/servers/plugins/dna/dna.c -+++ b/ldap/servers/plugins/dna/dna.c -@@ -2406,7 +2406,7 @@ static int dna_get_next_value(struct configEntry *config_entry, - } else { - /* dna_first_free_value() failed for some unknown reason */ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -- "dna_get_next_value: failed to allocate a new ID!! (set(%d) (max: %d)\n",setval,config_entry->maxval); -+ "dna_get_next_value: failed to allocate a new ID!!\n"); - goto done; - } - } -@@ -3415,8 +3415,6 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr) - /* dna_first_free_value() failed for some unknown reason */ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, - "dna_pre_op: failed to allocate a new ID!! 2\n"); -- slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -- "dna_get_next_value: failed to allocate a new ID!! (set(%d) (max: %d)\n",setval,config_entry->maxval); - /* Set an error string to be returned to the client. */ - *errstr = slapi_ch_smprintf("Allocation of a new value for range" - " %s failed! Unable to proceed.", -@@ -3682,8 +3680,6 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods, char **e - /* dna_first_free_value() failed for some unknown reason */ - slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, - "dna_pre_op: failed to allocate a new ID!!\n"); -- slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, -- "dna_get_next_value: failed to allocate a new ID!! (set(%d) (max: %d)\n",setval,config_entry->maxval); - /* Set an error string to be returned to the client. */ - *errstr = slapi_ch_smprintf("Allocation of a new value for range" - " %s failed! Unable to proceed.", -diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c -index f37ab8c..2120b4f 100644 ---- a/ldap/servers/plugins/uiduniq/uid.c -+++ b/ldap/servers/plugins/uiduniq/uid.c -@@ -1285,7 +1285,6 @@ uiduniq_start(Slapi_PBlock *pb) - static int - uiduniq_close(Slapi_PBlock *pb) - { -- Slapi_Entry *plugin_entry = NULL; - struct attr_uniqueness_config *config = NULL; - - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &config); -@@ -1312,7 +1311,6 @@ NSUniqueAttr_Init(Slapi_PBlock *pb) - int preadd = SLAPI_PLUGIN_PRE_ADD_FN; - int premod = SLAPI_PLUGIN_PRE_MODIFY_FN; - int premdn = SLAPI_PLUGIN_PRE_MODRDN_FN; -- struct attr_uniqueness_config *config = NULL; - - BEGIN - --- -1.9.3 - diff --git a/SOURCES/0051-Ticket-47757-Unable-to-dereference-unqiemember-attri.patch b/SOURCES/0051-Ticket-47757-Unable-to-dereference-unqiemember-attri.patch new file mode 100644 index 0000000..f24f18a --- /dev/null +++ b/SOURCES/0051-Ticket-47757-Unable-to-dereference-unqiemember-attri.patch @@ -0,0 +1,45 @@ +From ba9f2607b8bf565e2f6d1f8751c16c0b485a7210 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Mon, 24 Aug 2015 16:13:12 -0700 +Subject: [PATCH 51/52] Ticket #47757 - Unable to dereference unqiemember + attribute because it is dn [#UID] not dn syntax + +Description: In addtion to DN syntax, adding Name and Optional UID +syntax to the deref attr's OID check. + +https://fedorahosted.org/389/ticket/47757 + +Reviewed by mreynolds@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 2dbbb9df4691590f788049a822c47eb501182c85) +(cherry picked from commit 626f2d7060390a3234ebb50b92937d1ec5a89481) +--- + ldap/servers/plugins/deref/deref.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c +index 35c2564..f476a4d 100644 +--- a/ldap/servers/plugins/deref/deref.c ++++ b/ldap/servers/plugins/deref/deref.c +@@ -20,6 +20,9 @@ + #ifndef DN_SYNTAX_OID + #define DN_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.12" + #endif ++#ifndef NAME_AND_OPTIONAL_UID_SYNTAX_OID ++#define NAME_AND_OPTIONAL_UID_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.34" ++#endif + + /* + * Plug-in globals +@@ -290,7 +293,7 @@ deref_check_for_dn_syntax(const char *derefattr) + + slapi_attr_init(attr, derefattr); + slapi_attr_get_syntax_oid_copy(attr, &oid); +- ret = oid && !strcmp(oid, DN_SYNTAX_OID); ++ ret = oid && (!strcmp(oid, DN_SYNTAX_OID) || !strcmp(oid, NAME_AND_OPTIONAL_UID_SYNTAX_OID)); + slapi_ch_free_string(&oid); + slapi_attr_free(&attr); + } +-- +1.9.3 + diff --git a/SOURCES/0052-Ticket-47451-Add-Dynamic-Plugin-CI-Suite.patch b/SOURCES/0052-Ticket-47451-Add-Dynamic-Plugin-CI-Suite.patch deleted file mode 100644 index 399e1d9..0000000 --- a/SOURCES/0052-Ticket-47451-Add-Dynamic-Plugin-CI-Suite.patch +++ /dev/null @@ -1,2590 +0,0 @@ -From c038b581bdcabcc86a33f9a3eae446b684825698 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 16 Dec 2014 16:44:33 -0500 -Subject: [PATCH 52/53] Ticket 47451 - Add Dynamic Plugin CI Suite - -Description: Add lib389(CI) testsuite for Dynamic Plugins - - Perform functional tests for plugins that have configuration settings - - Restart the plugin - - Make condfig change - - Test the plugin - - Make another config change - - Test plugin - - Test plugin dependency - - Cleanup - - Perform memory corruption test - - This test forces the global plugin linked list, DSE callbacks, - and task handlers to be rewritten in various orders while - testing all the plugins. - - Perform Stress tests - - Perform a series of operations that engage two plugins. While - there operations are being performed restart various plugins. - - Verify the server does not crash, and that hte plugins work - correctly. - -https://fedorahosted.org/389/ticket/47451 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 4e39dbbfde56ca68f5a26d0bf2ac3a261234c8cd) -(cherry picked from commit 2ace01377aec2872579f9f892361946f1d5b07d2) ---- - dirsrvtests/suites/dynamic-plugins/constants.py | 33 + - dirsrvtests/suites/dynamic-plugins/finalizer.py | 57 + - dirsrvtests/suites/dynamic-plugins/plugin_tests.py | 1973 ++++++++++++++++++++ - dirsrvtests/suites/dynamic-plugins/stress_tests.py | 133 ++ - .../suites/dynamic-plugins/test_dynamic_plugins.py | 315 ++++ - 5 files changed, 2511 insertions(+) - create mode 100644 dirsrvtests/suites/dynamic-plugins/constants.py - create mode 100644 dirsrvtests/suites/dynamic-plugins/finalizer.py - create mode 100644 dirsrvtests/suites/dynamic-plugins/plugin_tests.py - create mode 100644 dirsrvtests/suites/dynamic-plugins/stress_tests.py - create mode 100644 dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py - -diff --git a/dirsrvtests/suites/dynamic-plugins/constants.py b/dirsrvtests/suites/dynamic-plugins/constants.py -new file mode 100644 -index 0000000..cbc310e ---- /dev/null -+++ b/dirsrvtests/suites/dynamic-plugins/constants.py -@@ -0,0 +1,33 @@ -+''' -+Created on Dec 09, 2014 -+ -+@author: mreynolds -+''' -+import os -+from lib389 import DN_DM -+from lib389._constants import * -+from lib389.properties import * -+ -+SUFFIX = 'dc=example,dc=com' -+PASSWORD = 'password' -+ -+# Used for standalone topology -+HOST_STANDALONE = LOCALHOST -+PORT_STANDALONE = 33389 -+SERVERID_STANDALONE = 'dynamic-plugins' -+ -+# Each defined instance above must be added in that list -+ALL_INSTANCES = [ {SER_HOST: HOST_STANDALONE, SER_PORT: PORT_STANDALONE, SER_SERVERID_PROP: SERVERID_STANDALONE}, -+ ] -+# This is a template -+args_instance = { -+ SER_DEPLOYED_DIR: os.environ.get('PREFIX', None), -+ SER_BACKUP_INST_DIR: os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR), -+ SER_ROOT_DN: DN_DM, -+ SER_ROOT_PW: PASSWORD, -+ SER_HOST: LOCALHOST, -+ SER_PORT: DEFAULT_PORT, -+ SER_SERVERID_PROP: "template", -+ SER_CREATION_SUFFIX: DEFAULT_SUFFIX} -+ -+ -diff --git a/dirsrvtests/suites/dynamic-plugins/finalizer.py b/dirsrvtests/suites/dynamic-plugins/finalizer.py -new file mode 100644 -index 0000000..eb02332 ---- /dev/null -+++ b/dirsrvtests/suites/dynamic-plugins/finalizer.py -@@ -0,0 +1,57 @@ -+''' -+Created on Nov 5, 2013 -+ -+@author: tbordaz -+''' -+import os -+import sys -+import time -+import ldap -+import logging -+import socket -+import time -+import logging -+import pytest -+from lib389 import DirSrv, Entry, tools -+from lib389.tools import DirSrvTools -+from lib389._constants import DN_DM -+from lib389.properties import * -+from constants import * -+ -+log = logging.getLogger(__name__) -+ -+global installation_prefix -+installation_prefix=os.getenv('PREFIX') -+ -+def test_finalizer(): -+ global installation_prefix -+ -+ # for each defined instance, remove it -+ for args_instance in ALL_INSTANCES: -+ if installation_prefix: -+ # overwrite the environment setting -+ args_instance[SER_DEPLOYED_DIR] = installation_prefix -+ -+ instance = DirSrv(verbose=True) -+ instance.allocate(args_instance) -+ if instance.exists(): -+ instance.delete() -+ -+ # remove any existing backup for this instance -+ instance.clearBackupFS() -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation_prefix -+ installation_prefix = None -+ -+ test_finalizer() -+ -+if __name__ == '__main__': -+ run_isolated() -+ -diff --git a/dirsrvtests/suites/dynamic-plugins/plugin_tests.py b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py -new file mode 100644 -index 0000000..fa88145 ---- /dev/null -+++ b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py -@@ -0,0 +1,1973 @@ -+''' -+Created on Dec 09, 2014 -+ -+@author: mreynolds -+''' -+import os -+import sys -+import time -+import ldap -+import time -+import logging -+import socket -+import pytest -+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 constants import * -+ -+log = logging.getLogger(__name__) -+ -+USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX -+USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX -+USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX -+BUSER1_DN = 'uid=user1,ou=branch1,' + DEFAULT_SUFFIX -+BUSER2_DN = 'uid=user2,ou=branch2,' + DEFAULT_SUFFIX -+BUSER3_DN = 'uid=user3,ou=branch2,' + DEFAULT_SUFFIX -+BRANCH1_DN = 'ou=branch1,' + DEFAULT_SUFFIX -+BRANCH2_DN = 'ou=branch2,' + DEFAULT_SUFFIX -+GROUP_OU = 'ou=groups,' + DEFAULT_SUFFIX -+PEOPLE_OU = 'ou=people,' + DEFAULT_SUFFIX -+GROUP_DN = 'cn=group,' + DEFAULT_SUFFIX -+ -+''' -+ Functional tests for each plugin -+ -+ Test: -+ plugin restarts (test when on and off) -+ plugin config validation -+ plugin dependencies -+ plugin functionality (including plugin tasks) -+''' -+ -+ -+################################################################################ -+# -+# Test Plugin Dependency -+# -+################################################################################ -+def test_dependency(inst, plugin): -+ """ -+ Set the "account usabilty" plugin to depend on this plugin. This plugin -+ is generic, always enabled, and perfect for our testing -+ """ -+ -+ try: -+ inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config', -+ [(ldap.MOD_REPLACE, 'nsslapd-plugin-depends-on-named', plugin)]) -+ -+ except ldap.LDAPError, e: -+ log.error('test_dependency: Failed to modify ' + PLUGIN_ACCT_USABILITY + ': error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.modify_s('cn=' + plugin + ',cn=plugins,cn=config', -+ [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'off')]) -+ -+ except ldap.UNWILLING_TO_PERFORM: -+ # failed as expected -+ pass -+ else: -+ # Incorrectly succeeded -+ log.error('test_dependency: Plugin dependency check failed (%s)' % plugin) -+ assert False -+ -+ # Now undo the change -+ try: -+ inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config', -+ [(ldap.MOD_DELETE, 'nsslapd-plugin-depends-on-named', None)]) -+ except ldap.LDAPError, e: -+ log.error('test_dependency: Failed to reset ' + plugin + ': error ' + e.message['desc']) -+ assert False -+ -+ -+################################################################################ -+# -+# Test Account Policy Plugin (0) -+# -+################################################################################ -+def test_acctpolicy(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY) -+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY) -+ -+ if args == "restart": -+ return True -+ -+ CONFIG_DN = 'cn=config,cn=Account Policy Plugin,cn=plugins,cn=config' -+ log.info('Testing ' + PLUGIN_ACCT_POLICY + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ # Add the config entry -+ try: -+ inst.add_s(Entry((CONFIG_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'cn': 'config', -+ 'alwaysrecordlogin': 'yes', -+ 'stateattrname': 'lastLoginTime' -+ }))) -+ except ldap.ALREADY_EXISTS: -+ try: -+ inst.modify_s(CONFIG_DN, -+ [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'), -+ (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime')]) -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc']) -+ assert False -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to add config entry: error ' + e.message['desc']) -+ assert False -+ -+ # Now set the config entry in the plugin entry -+ #try: -+ # inst.modify_s('cn=' + PLUGIN_ACCT_POLICY + ',cn=plugins,cn=config', -+ # [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', CONFIG_DN)]) -+ #except ldap.LDAPError, e: -+ # log.error('test_acctpolicy: Failed to set config entry in plugin entry: error ' + e.message['desc']) -+ # assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # !!!! acctpolicy does have have a dse callabck to check for live updates - restart plugin for now !!!! -+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY) -+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY) -+ -+ # Add an entry -+ try: -+ inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(), -+ 'sn': '1', -+ 'cn': 'user 1', -+ 'uid': 'user1', -+ 'userpassword': 'password'}))) -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to add test user' + USER1_DN + ': error ' + e.message['desc']) -+ assert False -+ -+ # bind as user -+ try: -+ inst.simple_bind_s(USER1_DN, "password") -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy:Failed to bind as user1: ' + e.message['desc']) -+ assert False -+ -+ # Bind as Root DN -+ try: -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc']) -+ assert False -+ -+ # Check lastLoginTime of USER1 -+ try: -+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'lastLoginTime=*') -+ if not entries: -+ log.fatal('test_acctpolicy: Search failed to find an entry with lastLoginTime.') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_acctpolicy: Search failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Change config - change the stateAttrName to a new attribute -+ ############################################################################ -+ -+ try: -+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'stateattrname', 'testLastLoginTime')]) -+ -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc']) -+ assert False -+ -+ # !!!! must restart for now !!!!! -+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY) -+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY) -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # login as user -+ try: -+ inst.simple_bind_s(USER1_DN, "password") -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to bind(2nd) as user1: ' + e.message['desc']) -+ assert False -+ -+ # Bind as Root DN -+ try: -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc']) -+ assert False -+ -+ # Check testLastLoginTime was added to USER1 -+ try: -+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(testLastLoginTime=*)') -+ if not entries: -+ log.fatal('test_acctpolicy: Search failed to find an entry with testLastLoginTime.') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_acctpolicy: Search failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_ACCT_POLICY) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_acctpolicy: Failed to delete test entry: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_acctpolicy: PASS\n') -+ -+ return -+ -+ -+################################################################################ -+# -+# Test Attribute Uniqueness Plugin (1) -+# -+################################################################################ -+def test_attruniq(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_ATTR_UNIQUENESS) -+ inst.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS) -+ -+ if args == "restart": -+ return -+ -+ log.info('Testing ' + PLUGIN_ATTR_UNIQUENESS + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ try: -+ inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', -+ [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'uid')]) -+ -+ except ldap.LDAPError, e: -+ log.error('test_attruniq: Failed to configure plugin for "uid": error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add an entry -+ try: -+ inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(), -+ 'sn': '1', -+ 'cn': 'user 1', -+ 'uid': 'user1', -+ 'mail': 'user1@example.com', -+ 'userpassword': 'password'}))) -+ except ldap.LDAPError, e: -+ log.error('test_attruniq: Failed to add test user' + USER1_DN + ': error ' + e.message['desc']) -+ assert False -+ -+ # Add an entry with a duplicate "uid" -+ try: -+ inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(), -+ 'sn': '2', -+ 'cn': 'user 2', -+ 'uid': 'user2', -+ 'uid': 'user1', -+ 'userpassword': 'password'}))) -+ -+ except ldap.CONSTRAINT_VIOLATION: -+ pass -+ else: -+ log.error('test_attruniq: Adding of 2nd entry(uid) incorrectly succeeded') -+ assert False -+ -+ ############################################################################ -+ # Change config to use "mail" instead of "uid" -+ ############################################################################ -+ -+ try: -+ inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', -+ [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail')]) -+ -+ except ldap.LDAPError, e: -+ log.error('test_attruniq: Failed to configure plugin for "mail": error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin - Add an entry, that has a duplicate "mail" value -+ ############################################################################ -+ -+ try: -+ inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(), -+ 'sn': '2', -+ 'cn': 'user 2', -+ 'uid': 'user2', -+ 'mail': 'user1@example.com', -+ 'userpassword': 'password'}))) -+ except ldap.CONSTRAINT_VIOLATION: -+ pass -+ else: -+ log.error('test_attruniq: Adding of 2nd entry(mail) incorrectly succeeded') -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_ATTR_UNIQUENESS) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_attruniq: Failed to delete test entry: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_attruniq: PASS\n') -+ return -+ -+ -+################################################################################ -+# -+# Test Auto Membership Plugin (2) -+# -+################################################################################ -+def test_automember(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_AUTOMEMBER) -+ inst.plugins.enable(name=PLUGIN_AUTOMEMBER) -+ -+ if args == "restart": -+ return -+ -+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_AUTOMEMBER + ',cn=plugins,cn=config' -+ -+ log.info('Testing ' + PLUGIN_AUTOMEMBER + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ # Add the automember group -+ try: -+ inst.add_s(Entry((GROUP_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'cn': 'group' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to add group: error ' + e.message['desc']) -+ assert False -+ -+ # Add ou=branch1 -+ try: -+ inst.add_s(Entry((BRANCH1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'ou': 'branch1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to add branch1: error ' + e.message['desc']) -+ assert False -+ -+ # Add ou=branch2 -+ try: -+ inst.add_s(Entry((BRANCH2_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'ou': 'branch2' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to add branch2: error ' + e.message['desc']) -+ assert False -+ -+ # Add the automember config entry -+ try: -+ inst.add_s(Entry((CONFIG_DN, { -+ 'objectclass': 'top autoMemberDefinition'.split(), -+ 'cn': 'config', -+ 'autoMemberScope': 'ou=branch1,' + DEFAULT_SUFFIX, -+ 'autoMemberFilter': 'objectclass=top', -+ 'autoMemberDefaultGroup': 'cn=group,' + DEFAULT_SUFFIX, -+ 'autoMemberGroupingAttr': 'member:dn' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to add config entry: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test the plugin -+ ############################################################################ -+ -+ # Add a user that should get added to the group -+ try: -+ inst.add_s(Entry((BUSER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to add user: error ' + e.message['desc']) -+ assert False -+ -+ # Check the group -+ try: -+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, -+ '(member=' + BUSER1_DN + ')') -+ if not entries: -+ log.fatal('test_automember: Search failed to find member user1') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_automember: Search failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Change config -+ ############################################################################ -+ -+ try: -+ inst.modify_s(CONFIG_DN, -+ [(ldap.MOD_REPLACE, 'autoMemberGroupingAttr', 'uniquemember:dn'), -+ (ldap.MOD_REPLACE, 'autoMemberScope', 'ou=branch2,' + DEFAULT_SUFFIX)]) -+ -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to modify config entry: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add a user that should get added to the group -+ try: -+ inst.add_s(Entry((BUSER2_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user2' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to user to branch2: error ' + e.message['desc']) -+ assert False -+ -+ # Check the group -+ try: -+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, -+ '(uniquemember=' + BUSER2_DN + ')') -+ if not entries: -+ log.fatal('test_automember: Search failed to find uniquemember user2') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_automember: Search failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test Task -+ ############################################################################ -+ -+ # Disable plugin -+ inst.plugins.disable(name=PLUGIN_AUTOMEMBER) -+ -+ # Add an entry that should be picked up by automember - verify it is not(yet) -+ try: -+ inst.add_s(Entry((BUSER3_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user3' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to user3 to branch2: error ' + e.message['desc']) -+ assert False -+ -+ # Check the group - uniquemember sahould not exist -+ try: -+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, -+ '(uniquemember=' + BUSER3_DN + ')') -+ if entries: -+ log.fatal('test_automember: user3 was incorrectly added to the group') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_automember: Search failed: ' + e.message['desc']) -+ assert False -+ -+ # Enable plugin -+ inst.plugins.enable(name=PLUGIN_AUTOMEMBER) -+ -+ # Add the task -+ try: -+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=automember rebuild membership,cn=tasks,cn=config', { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'basedn': 'ou=branch2,' + DEFAULT_SUFFIX, -+ 'filter': 'objectclass=top'}))) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to add task: error ' + e.message['desc']) -+ assert False -+ -+ time.sleep(3) # Wait for the task to do its work -+ -+ # Verify the fixup task worked -+ try: -+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, -+ '(uniquemember=' + BUSER3_DN + ')') -+ if not entries: -+ log.fatal('test_automember: user3 was not added to the group') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_automember: Search failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_AUTOMEMBER) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(BUSER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete test entry1: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(BUSER2_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete test entry2: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(BUSER3_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete test entry3: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(BRANCH1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete branch1: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(BRANCH2_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete test branch2: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(GROUP_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete test group: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(CONFIG_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete plugin config entry: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_automember: PASS\n') -+ return -+ -+ -+################################################################################ -+# -+# Test DNA Plugin (3) -+# -+################################################################################ -+def test_dna(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_DNA) -+ inst.plugins.enable(name=PLUGIN_DNA) -+ -+ if args == "restart": -+ return -+ -+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_DNA + ',cn=plugins,cn=config' -+ -+ log.info('Testing ' + PLUGIN_DNA + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ try: -+ inst.add_s(Entry((CONFIG_DN, { -+ 'objectclass': 'top dnaPluginConfig'.split(), -+ 'cn': 'config', -+ 'dnatype': 'uidNumber', -+ 'dnafilter': '(objectclass=top)', -+ 'dnascope': DEFAULT_SUFFIX, -+ 'dnaMagicRegen': '-1', -+ 'dnaMaxValue': '50000', -+ 'dnaNextValue': '1' -+ }))) -+ except ldap.ALREADY_EXISTS: -+ try: -+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaNextValue', '1'), -+ (ldap.MOD_REPLACE, 'dnaMagicRegen', '-1')]) -+ except ldap.LDAPError, e: -+ log.error('test_dna: Failed to set the DNA plugin: error ' + e.message['desc']) -+ assert False -+ except ldap.LDAPError, e: -+ log.error('test_dna: Failed to add config entry: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ try: -+ inst.add_s(Entry((USER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_dna: Failed to user1: error ' + e.message['desc']) -+ assert False -+ -+ # See if the entry now has the new uidNumber assignment - uidNumber=1 -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=1)') -+ if not entries: -+ log.fatal('test_dna: user1 was not updated - (looking for uidNumber: 1)') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Test the magic regen value -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-1')]) -+ except ldap.LDAPError, e: -+ log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc']) -+ assert False -+ -+ # See if the entry now has the new uidNumber assignment - uidNumber=2 -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=2)') -+ if not entries: -+ log.fatal('test_dna: user1 was not updated (looking for uidNumber: 2)') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ################################################################################ -+ # Change the config -+ ################################################################################ -+ -+ try: -+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaMagicRegen', '-2')]) -+ except ldap.LDAPError, e: -+ log.error('test_dna: Failed to set the magic reg value to -2: error ' + e.message['desc']) -+ assert False -+ -+ ################################################################################ -+ # Test plugin -+ ################################################################################ -+ -+ # Test the magic regen value -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-2')]) -+ except ldap.LDAPError, e: -+ log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc']) -+ assert False -+ -+ # See if the entry now has the new uidNumber assignment - uidNumber=3 -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=3)') -+ if not entries: -+ log.fatal('test_dna: user1 was not updated (looking for uidNumber: 3)') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_AUTOMEMBER) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_automember: Failed to delete test entry1: ' + e.message['desc']) -+ assert False -+ -+ inst.plugins.disable(name=PLUGIN_DNA) -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_dna: PASS\n') -+ -+ return -+ -+ -+################################################################################ -+# -+# Test Linked Attrs Plugin (4) -+# -+################################################################################ -+def test_linkedattrs(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_LINKED_ATTRS) -+ inst.plugins.enable(name=PLUGIN_LINKED_ATTRS) -+ -+ if args == "restart": -+ return -+ -+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_LINKED_ATTRS + ',cn=plugins,cn=config' -+ -+ log.info('Testing ' + PLUGIN_LINKED_ATTRS + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ # Add test entries -+ try: -+ inst.add_s(Entry((USER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.add_s(Entry((USER2_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user2' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc']) -+ assert False -+ -+ # Add the linked attrs config entry -+ try: -+ inst.add_s(Entry((CONFIG_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'cn': 'config', -+ 'linkType': 'directReport', -+ 'managedType': 'manager' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add config entry: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Set "directReport" should add "manager" to the other entry -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc']) -+ assert False -+ -+ # See if manager was added to the other entry -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if not entries: -+ log.fatal('test_linkedattrs: user2 missing "manager" attribute') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Remove "directReport" should remove "manager" to the other entry -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'directReport', None)]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc']) -+ assert False -+ -+ # See if manager was removed -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if entries: -+ log.fatal('test_linkedattrs: user2 "manager" attribute not removed') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Change the config - using linkType "indirectReport" now -+ ############################################################################ -+ -+ try: -+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'linkType', 'indirectReport')]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to set linkTypee: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Make sure the old linkType(directManager) is not working -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc']) -+ assert False -+ -+ # See if manager was added to the other entry, better not be... -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if entries: -+ log.fatal('test_linkedattrs: user2 had "manager" added unexpectedly') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc']) -+ assert False -+ -+ # Now, set the new linkType "indirectReport", which should add "manager" to the other entry -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc']) -+ assert False -+ -+ # See if manager was added to the other entry, better not be -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if not entries: -+ log.fatal('test_linkedattrs: user2 missing "manager"') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc']) -+ assert False -+ -+ # Remove "indirectReport" should remove "manager" to the other entry -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'indirectReport', None)]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc']) -+ assert False -+ -+ # See if manager was removed -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if entries: -+ log.fatal('test_linkedattrs: user2 "manager" attribute not removed') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test Fixup Task -+ ############################################################################ -+ -+ # Disable plugin and make some updates that would of triggered the plugin -+ inst.plugins.disable(name=PLUGIN_LINKED_ATTRS) -+ -+ try: -+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)]) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc']) -+ assert False -+ -+ # The entry should not have a manager attribute -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if entries: -+ log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Verify that the task does not work yet(not until we enable the plugin) -+ try: -+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'basedn': DEFAULT_SUFFIX, -+ 'filter': '(objectclass=top)'}))) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc']) -+ assert False -+ -+ time.sleep(3) # Wait for the task to do, or not do, its work -+ -+ # The entry should still not have a manager attribute -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if entries: -+ log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc']) -+ assert False -+ -+ # Enable the plugin and rerun the task entry -+ inst.plugins.enable(name=PLUGIN_LINKED_ATTRS) -+ -+ # Add the task again -+ try: -+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'basedn': DEFAULT_SUFFIX, -+ 'filter': 'objectclass=top'}))) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc']) -+ assert False -+ -+ time.sleep(3) # Wait for the task to do its work -+ -+ # Check if user2 now has a manager attribute now -+ try: -+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)') -+ if not entries: -+ log.fatal('test_linkedattrs: task failed: user2 missing "manager" attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_LINKED_ATTRS) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to delete test entry1: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(USER2_DN) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to delete test entry2: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(CONFIG_DN) -+ except ldap.LDAPError, e: -+ log.error('test_linkedattrs: Failed to delete plugin config entry: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_linkedattrs: PASS\n') -+ return -+ -+ -+################################################################################ -+# -+# Test MemberOf Plugin (5) -+# -+################################################################################ -+def test_memberof(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_MEMBER_OF) -+ inst.plugins.enable(name=PLUGIN_MEMBER_OF) -+ -+ if args == "restart": -+ return -+ -+ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config' -+ -+ log.info('Testing ' + PLUGIN_MEMBER_OF + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')]) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to update config(member): error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add our test entries -+ try: -+ inst.add_s(Entry((USER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to add user1: error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.add_s(Entry((GROUP_DN, { -+ 'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(), -+ 'cn': 'group', -+ 'member': USER1_DN -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to add group: error ' + e.message['desc']) -+ assert False -+ -+ # Check if the user now has a "memberOf" attribute -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if not entries: -+ log.fatal('test_memberof: user1 missing memberOf') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Remove "member" should remove "memberOf" from the entry -+ try: -+ inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)]) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to delete member: error ' + e.message['desc']) -+ assert False -+ -+ # Check that "memberOf" was removed -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if entries: -+ log.fatal('test_memberof: user1 incorrect has memberOf attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Change the config -+ ############################################################################ -+ -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')]) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ try: -+ inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)]) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc']) -+ assert False -+ -+ # Check if the user now has a "memberOf" attribute -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if not entries: -+ log.fatal('test_memberof: user1 missing memberOf') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Remove "uniquemember" should remove "memberOf" from the entry -+ try: -+ inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'uniquemember', None)]) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to delete member: error ' + e.message['desc']) -+ assert False -+ -+ # Check that "memberOf" was removed -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if entries: -+ log.fatal('test_memberof: user1 incorrect has memberOf attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test Fixup Task -+ ############################################################################ -+ -+ inst.plugins.disable(name=PLUGIN_MEMBER_OF) -+ -+ # Add uniquemember, should not update USER1 -+ try: -+ inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)]) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc']) -+ assert False -+ -+ # Check for "memberOf" -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if entries: -+ log.fatal('test_memberof: user1 incorrect has memberOf attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Run fixup task while plugin disabled - should not add "memberOf -+ # Verify that the task does not work yet(not until we enable the plugin) -+ try: -+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'basedn': DEFAULT_SUFFIX, -+ 'filter': 'objectclass=top'}))) -+ except ldap.NO_SUCH_OBJECT: -+ pass -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to add task: error ' + e.message['desc']) -+ assert False -+ -+ time.sleep(3) # Wait for the task to do, or not do, its work -+ -+ # Check for "memberOf" -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if entries: -+ log.fatal('test_memberof: user1 incorrectly has memberOf attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ # Enable the plugin, and run the task -+ inst.plugins.enable(name=PLUGIN_MEMBER_OF) -+ -+ try: -+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'basedn': DEFAULT_SUFFIX, -+ 'filter': 'objectclass=top'}))) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to add task: error ' + e.message['desc']) -+ assert False -+ -+ time.sleep(3) # Wait for the task to do its work -+ -+ # Check for "memberOf" -+ try: -+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)') -+ if not entries: -+ log.fatal('test_memberof: user1 missing memberOf attr') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_MEMBER_OF) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to delete test entry1: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(GROUP_DN) -+ except ldap.LDAPError, e: -+ log.error('test_memberof: Failed to delete test group: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_memberof: PASS\n') -+ -+ return -+ -+ -+################################################################################ -+# -+# Test Managed Entry Plugin (6) -+# -+################################################################################ -+def test_mep(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY) -+ inst.plugins.enable(name=PLUGIN_MANAGED_ENTRY) -+ -+ if args == "restart": -+ return -+ -+ USER_DN = 'uid=user1,ou=people,' + DEFAULT_SUFFIX -+ MEP_USER_DN = 'cn=user1,ou=groups,' + DEFAULT_SUFFIX -+ USER_DN2 = 'uid=user 1,ou=people,' + DEFAULT_SUFFIX -+ MEP_USER_DN2 = 'uid=user 1,ou=groups,' + DEFAULT_SUFFIX -+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_MANAGED_ENTRY + ',cn=plugins,cn=config' -+ TEMPLATE_DN = 'cn=MEP Template,' + DEFAULT_SUFFIX -+ TEMPLATE_DN2 = 'cn=MEP Template2,' + DEFAULT_SUFFIX -+ -+ log.info('Testing ' + PLUGIN_MANAGED_ENTRY + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ # Add our org units -+ try: -+ inst.add_s(Entry((PEOPLE_OU, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'ou': 'people'}))) -+ except ldap.ALREADY_EXISTS: -+ pass -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to add people org unit: error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.add_s(Entry((GROUP_OU, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'ou': 'people'}))) -+ except ldap.ALREADY_EXISTS: -+ pass -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to add people org unit: error ' + e.message['desc']) -+ assert False -+ -+ # Add the template entry -+ try: -+ inst.add_s(Entry((TEMPLATE_DN, { -+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(), -+ 'cn': 'MEP Template', -+ 'mepRDNAttr': 'cn', -+ 'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'), -+ 'mepMappedAttr': 'cn: $cn|uid: $cn|gidNumber: $uidNumber'.split('|') -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to add template entry: error ' + e.message['desc']) -+ assert False -+ -+ # log.info('geb.....') -+ # time.sleep(30) -+ -+ # Add the config entry -+ try: -+ inst.add_s(Entry((CONFIG_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'cn': 'config', -+ 'originScope': PEOPLE_OU, -+ 'originFilter': 'objectclass=posixAccount', -+ 'managedBase': GROUP_OU, -+ 'managedTemplate': TEMPLATE_DN -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to add config entry: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add an entry that meets the MEP scope -+ try: -+ inst.add_s(Entry((USER_DN, { -+ 'objectclass': 'top posixAccount extensibleObject'.split(), -+ 'uid': 'user1', -+ 'cn': 'user1', -+ 'uidNumber': '1', -+ 'gidNumber': '1', -+ 'homeDirectory': '/home/user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to user1: error ' + e.message['desc']) -+ assert False -+ -+ # Check if a managed group entry was created -+ try: -+ inst.search_s(MEP_USER_DN, ldap.SCOPE_BASE, '(objectclass=top)') -+ except ldap.LDAPError, e: -+ log.fatal('test_mep: Unable to find MEP entry: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Change the config -+ ############################################################################ -+ -+ # Add a new template entry -+ try: -+ inst.add_s(Entry((TEMPLATE_DN2, { -+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(), -+ 'cn': 'MEP Template2', -+ 'mepRDNAttr': 'uid', -+ 'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'), -+ 'mepMappedAttr': 'cn: $uid|uid: $cn|gidNumber: $gidNumber'.split('|') -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to add template entry2: error ' + e.message['desc']) -+ assert False -+ -+ # Set the new template dn -+ try: -+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'managedTemplate', TEMPLATE_DN2)]) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to set mep plugin config: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add an entry that meets the MEP scope -+ try: -+ inst.add_s(Entry((USER_DN2, { -+ 'objectclass': 'top posixAccount extensibleObject'.split(), -+ 'uid': 'user 1', -+ 'cn': 'user 1', -+ 'uidNumber': '1', -+ 'gidNumber': '1', -+ 'homeDirectory': '/home/user2' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to user2: error ' + e.message['desc']) -+ assert False -+ -+ # Check if a managed group entry was created -+ try: -+ inst.search_s(MEP_USER_DN2, ldap.SCOPE_BASE, '(objectclass=top)') -+ except ldap.LDAPError, e: -+ log.fatal('test_mep: Unable to find MEP entry2: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_MANAGED_ENTRY) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER_DN) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to delete test user1: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(USER_DN2) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to delete test user 2: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(TEMPLATE_DN) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to delete template1: ' + e.message['desc']) -+ assert False -+ -+ inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY) -+ -+ try: -+ inst.delete_s(TEMPLATE_DN2) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to delete template2: ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(CONFIG_DN) -+ except ldap.LDAPError, e: -+ log.error('test_mep: Failed to delete config: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_mep: PASS\n') -+ return -+ -+ -+################################################################################ -+# -+# Test Passthru Plugin (7) -+# -+################################################################################ -+def test_passthru(inst, args=None): -+ # Passthru is a bit picky about the state of the entry - we can't just restart it -+ if args == "restart": -+ return -+ -+ # stop the plugin -+ inst.plugins.disable(name=PLUGIN_PASSTHRU) -+ -+ PLUGIN_DN = 'cn=' + PLUGIN_PASSTHRU + ',cn=plugins,cn=config' -+ PASSTHRU_DN = 'uid=admin,dc=pass,dc=thru' -+ PASSTHRU_DN2 = 'uid=admin2,dc=pass2,dc=thru' -+ PASS_SUFFIX1 = 'dc=pass,dc=thru' -+ PASS_SUFFIX2 = 'dc=pass2,dc=thru' -+ PASS_BE2 = 'PASS2' -+ -+ log.info('Testing ' + PLUGIN_PASSTHRU + '...') -+ -+ ############################################################################ -+ # Add a new "remote" instance, and a user for auth -+ ############################################################################ -+ -+ # Create second instance -+ passthru_inst = DirSrv(verbose=False) -+ -+ #if installation1_prefix: -+ # args_instance[SER_DEPLOYED_DIR] = installation1_prefix -+ -+ # Args for the master1 instance -+ """ -+ args_instance[SER_HOST] = '127.0.0.1' -+ args_instance[SER_PORT] = '33333' -+ args_instance[SER_SERVERID_PROP] = 'passthru' -+ """ -+ args_instance[SER_HOST] = 'localhost.localdomain' -+ args_instance[SER_PORT] = 33333 -+ args_instance[SER_SERVERID_PROP] = 'passthru' -+ -+ args_instance[SER_CREATION_SUFFIX] = PASS_SUFFIX1 -+ args_passthru_inst = args_instance.copy() -+ passthru_inst.allocate(args_passthru_inst) -+ passthru_inst.create() -+ passthru_inst.open() -+ -+ # Create a second backend -+ passthru_inst.backend.create(PASS_SUFFIX2, {BACKEND_NAME: PASS_BE2}) -+ passthru_inst.mappingtree.create(PASS_SUFFIX2, bename=PASS_BE2) -+ -+ # Create the top of the tree -+ try: -+ passthru_inst.add_s(Entry((PASS_SUFFIX2, { -+ 'objectclass': 'top domain'.split(), -+ 'dc': 'pass2'}))) -+ except ldap.ALREADY_EXISTS: -+ pass -+ except ldap.LDAPError, e: -+ log.error('test_passthru: Failed to create suffix entry: error ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ # Add user to suffix1 -+ try: -+ passthru_inst.add_s(Entry((PASSTHRU_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'admin', -+ 'userpassword': 'password' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_passthru: Failed to admin1: error ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ # Add user to suffix 2 -+ try: -+ passthru_inst.add_s(Entry((PASSTHRU_DN2, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'admin2', -+ 'userpassword': 'password' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_passthru: Failed to admin2 : error ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ ############################################################################ -+ # Configure and start plugin -+ ############################################################################ -+ -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on'), -+ (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass,dc=thru')]) -+ except ldap.LDAPError, e: -+ log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # login as user -+ try: -+ inst.simple_bind_s(PASSTHRU_DN, "password") -+ except ldap.LDAPError, e: -+ log.error('test_passthru: pass through bind failed: ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ ############################################################################ -+ # Change the config -+ ############################################################################ -+ -+ # login as root DN -+ try: -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ except ldap.LDAPError, e: -+ log.error('test_passthru: pass through bind failed: ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass2,dc=thru')]) -+ except ldap.LDAPError, e: -+ log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # login as user -+ try: -+ inst.simple_bind_s(PASSTHRU_DN2, "password") -+ except ldap.LDAPError, e: -+ log.error('test_passthru: pass through bind failed: ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ # login as root DN -+ try: -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ except ldap.LDAPError, e: -+ log.error('test_passthru: pass through bind failed: ' + e.message['desc']) -+ passthru_inst.delete() -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_PASSTHRU) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ # remove the passthru instance -+ passthru_inst.delete() -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_passthru: PASS\n') -+ -+ return -+ -+ -+################################################################################ -+# -+# Test Referential Integrity Plugin (8) -+# -+################################################################################ -+def test_referint(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_REFER_INTEGRITY) -+ inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY) -+ -+ if args == "restart": -+ return -+ -+ log.info('Testing ' + PLUGIN_REFER_INTEGRITY + '...') -+ PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config' -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'member')]) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add some users and a group -+ try: -+ inst.add_s(Entry((USER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to add user1: error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.add_s(Entry((USER2_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user2' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to add user2: error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.add_s(Entry((GROUP_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'cn': 'group', -+ 'member': USER1_DN, -+ 'uniquemember': USER2_DN -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to add group: error ' + e.message['desc']) -+ assert False -+ -+ # Delete a user -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to delete user1: ' + e.message['desc']) -+ assert False -+ -+ # Check for integrity -+ try: -+ entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')') -+ if entry: -+ log.error('test_referint: user1 was not removed from group') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_referint: Unable to search group: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Change the config -+ ############################################################################ -+ -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')]) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Delete a user -+ try: -+ inst.delete_s(USER2_DN) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to delete user1: ' + e.message['desc']) -+ assert False -+ -+ # Check for integrity -+ try: -+ entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(uniquemember=' + USER2_DN + ')') -+ if entry: -+ log.error('test_referint: user2 was not removed from group') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_referint: Unable to search group: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_REFER_INTEGRITY) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ try: -+ inst.delete_s(GROUP_DN) -+ except ldap.LDAPError, e: -+ log.error('test_referint: Failed to delete user1: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_referint: PASS\n') -+ -+ return -+ -+ -+################################################################################ -+# -+# Test Retro Changelog Plugin (9) -+# -+################################################################################ -+def test_retrocl(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG) -+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG) -+ -+ if args == "restart": -+ return -+ -+ log.info('Testing ' + PLUGIN_RETRO_CHANGELOG + '...') -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ # Gather the current change count (it's not 1 once we start the stabilty tests) -+ try: -+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)') -+ except ldap.LDAPError, e: -+ log.error('test_retrocl: Failed to get the count: error ' + e.message['desc']) -+ assert False -+ -+ entry_count = len(entry) -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Add a user -+ try: -+ inst.add_s(Entry((USER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_retrocl: Failed to add user1: error ' + e.message['desc']) -+ assert False -+ -+ # Check we logged this in the retro cl -+ try: -+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)') -+ if not entry or len(entry) == entry_count: -+ log.error('test_retrocl: changelog not updated') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_retrocl: Unable to search group: ' + e.message['desc']) -+ assert False -+ -+ entry_count += 1 -+ -+ ############################################################################ -+ # Change the config - disable plugin -+ ############################################################################ -+ -+ inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG) -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_retrocl: Failed to delete user1: ' + e.message['desc']) -+ assert False -+ -+ # Check we didn't logged this in the retro cl -+ try: -+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)') -+ if len(entry) != entry_count: -+ log.error('test_retrocl: changelog incorrectly updated - change count: ' -+ + str(len(entry)) + ' - expected 1') -+ assert False -+ except ldap.LDAPError, e: -+ log.fatal('test_retrocl: Unable to search retro changelog: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG) -+ test_dependency(inst, PLUGIN_RETRO_CHANGELOG) -+ -+ ############################################################################ -+ # Cleanup -+ ############################################################################ -+ -+ # None -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_retrocl: PASS\n') -+ -+ return -+ -+ -+################################################################################ -+# -+# Test Root DN Access Control Plugin (10) -+# -+################################################################################ -+def test_rootdn(inst, args=None): -+ # stop the plugin, and start it -+ inst.plugins.disable(name=PLUGIN_ROOTDN_ACCESS) -+ inst.plugins.enable(name=PLUGIN_ROOTDN_ACCESS) -+ -+ if args == "restart": -+ return -+ -+ PLUGIN_DN = 'cn=' + PLUGIN_ROOTDN_ACCESS + ',cn=plugins,cn=config' -+ -+ ############################################################################ -+ # Configure plugin -+ ############################################################################ -+ -+ # Add an user and aci to open up cn=config -+ try: -+ inst.add_s(Entry((USER1_DN, { -+ 'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user1', -+ 'userpassword': 'password' -+ }))) -+ except ldap.LDAPError, e: -+ log.error('test_retrocl: Failed to add user1: error ' + e.message['desc']) -+ assert False -+ -+ # Set an aci so we can modify the plugin after ew deny the root dn -+ ACI = '(target ="ldap:///cn=config")(targetattr = "*")(version 3.0;acl "all access";allow (all)(userdn="ldap:///anyone");)' -+ try: -+ inst.modify_s(DN_CONFIG, [(ldap.MOD_ADD, 'aci', ACI)]) -+ except ldap.LDAPError, e: -+ log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc']) -+ assert False -+ -+ # Set allowed IP to an unknown host - blocks root dn -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-allow-ip', '10.10.10.10')]) -+ except ldap.LDAPError, e: -+ log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Bind as Root DN -+ failed = False -+ try: -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ except ldap.LDAPError, e: -+ failed = True -+ -+ if not failed: -+ log.error('test_rootdn: Root DN was incorrectly able to bind') -+ assert False -+ -+ ############################################################################ -+ # Change the config -+ ############################################################################ -+ -+ try: -+ inst.simple_bind_s(USER1_DN, 'password') -+ except ldap.LDAPError, e: -+ log.error('test_rootdn: failed to bind as user1') -+ assert False -+ -+ # Remove the restriction -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, 'rootdn-allow-ip', None)]) -+ except ldap.LDAPError, e: -+ log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test plugin -+ ############################################################################ -+ -+ # Bind as Root DN -+ failed = False -+ try: -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ except ldap.LDAPError, e: -+ failed = True -+ -+ if failed: -+ log.error('test_rootdn: Root DN was not able to bind') -+ assert False -+ -+ ############################################################################ -+ # Test plugin dependency -+ ############################################################################ -+ -+ test_dependency(inst, PLUGIN_ROOTDN_ACCESS) -+ -+ ############################################################################ -+ # Cleanup - remove ACI from cn=config and test user -+ ############################################################################ -+ -+ try: -+ inst.modify_s(DN_CONFIG, [(ldap.MOD_DELETE, 'aci', ACI)]) -+ except ldap.LDAPError, e: -+ log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc']) -+ assert False -+ -+ try: -+ inst.delete_s(USER1_DN) -+ except ldap.LDAPError, e: -+ log.error('test_rootdn: Failed to delete user1: ' + e.message['desc']) -+ assert False -+ -+ ############################################################################ -+ # Test passed -+ ############################################################################ -+ -+ log.info('test_rootdn: PASS\n') -+ -+ return -+ -+ -+# Array of test functions -+func_tests = [test_acctpolicy, test_attruniq, test_automember, test_dna, -+ test_linkedattrs, test_memberof, test_mep, test_passthru, -+ test_referint, test_retrocl, test_rootdn] -+ -+ -+def test_all_plugins(inst, args=None): -+ for func in func_tests: -+ func(inst, args) -+ -+ return -+ -diff --git a/dirsrvtests/suites/dynamic-plugins/stress_tests.py b/dirsrvtests/suites/dynamic-plugins/stress_tests.py -new file mode 100644 -index 0000000..a1f666d ---- /dev/null -+++ b/dirsrvtests/suites/dynamic-plugins/stress_tests.py -@@ -0,0 +1,133 @@ -+''' -+Created on Dec 16, 2014 -+ -+@author: mreynolds -+''' -+import os -+import sys -+import time -+import ldap -+import time -+import logging -+import socket -+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 constants import * -+ -+log = logging.getLogger(__name__) -+ -+NUM_USERS = 250 -+ -+ -+def openConnection(inst): -+ # Open a new connection to our LDAP server -+ server = DirSrv(verbose=False) -+ args_instance[SER_HOST] = HOST_STANDALONE -+ args_instance[SER_PORT] = PORT_STANDALONE -+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE -+ args_standalone = args_instance.copy() -+ server.allocate(args_standalone) -+ server.open() -+ -+ return server -+ -+ -+# Configure Referential Integrity Plugin for stress test -+def configureRI(inst): -+ inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY) -+ PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config' -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')]) -+ except ldap.LDAPError, e: -+ log.error('configureRI: Failed to configure RI plugin: error ' + e.message['desc']) -+ assert False -+ -+ -+# Configure MemberOf Plugin for stress test -+def configureMO(inst): -+ inst.plugins.enable(name=PLUGIN_MEMBER_OF) -+ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config' -+ try: -+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')]) -+ except ldap.LDAPError, e: -+ log.error('configureMO: Failed to update config(uniquemember): error ' + e.message['desc']) -+ assert False -+ -+ -+class DelUsers(threading.Thread): -+ def __init__(self, inst, rdnval): -+ threading.Thread.__init__(self) -+ self.daemon = True -+ self.inst = inst -+ self.rdnval = rdnval -+ -+ def run(self): -+ conn = openConnection(self.inst) -+ idx = 0 -+ log.info('DelUsers - Deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...') -+ while idx < NUM_USERS: -+ USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX -+ try: -+ conn.delete_s(USER_DN) -+ except ldap.LDAPError, e: -+ log.error('DeleteUsers: failed to delete (' + USER_DN + ') error: ' + e.message['desc']) -+ assert False -+ -+ idx += 1 -+ -+ conn.close() -+ log.info('DelUsers - Finished deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').') -+ -+ -+class AddUsers(threading.Thread): -+ def __init__(self, inst, rdnval, addToGroup): -+ threading.Thread.__init__(self) -+ self.daemon = True -+ self.inst = inst -+ self.addToGroup = addToGroup -+ self.rdnval = rdnval -+ -+ def run(self): -+ # Start adding users -+ conn = openConnection(self.inst) -+ idx = 0 -+ -+ if self.addToGroup: -+ GROUP_DN = 'cn=stress-group,' + DEFAULT_SUFFIX -+ try: -+ conn.add_s(Entry((GROUP_DN, -+ {'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(), -+ 'uid': 'user' + str(idx)}))) -+ except ldap.ALREADY_EXISTS: -+ pass -+ except ldap.LDAPError, e: -+ log.error('AddUsers: failed to add group (' + USER_DN + ') error: ' + e.message['desc']) -+ assert False -+ -+ log.info('AddUsers - Adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...') -+ -+ while idx < NUM_USERS: -+ USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX -+ try: -+ conn.add_s(Entry((USER_DN, {'objectclass': 'top extensibleObject'.split(), -+ 'uid': 'user' + str(idx)}))) -+ except ldap.LDAPError, e: -+ log.error('AddUsers: failed to add (' + USER_DN + ') error: ' + e.message['desc']) -+ assert False -+ -+ if self.addToGroup: -+ # Add the user to the group -+ try: -+ conn.modify_s(GROUP_DN, [(ldap.MOD_ADD, 'uniquemember', USER_DN)]) -+ except ldap.LDAPError, e: -+ log.error('AddUsers: Failed to add user' + USER_DN + ' to group: error ' + e.message['desc']) -+ assert False -+ -+ idx += 1 -+ -+ conn.close() -+ log.info('AddUsers - Finished adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').') -diff --git a/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py -new file mode 100644 -index 0000000..3677fd5 ---- /dev/null -+++ b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py -@@ -0,0 +1,315 @@ -+''' -+Created on Dec 09, 2014 -+ -+@author: mreynolds -+''' -+import os -+import sys -+import time -+import ldap -+import ldap.sasl -+import logging -+import socket -+import pytest -+import plugin_tests -+import stress_tests -+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 constants import * -+ -+log = logging.getLogger(__name__) -+ -+installation_prefix = None -+ -+ -+class TopologyStandalone(object): -+ def __init__(self, standalone): -+ standalone.open() -+ self.standalone = standalone -+ -+ -+@pytest.fixture(scope="module") -+def topology(request): -+ ''' -+ This fixture is used to standalone topology for the 'module'. -+ At the beginning, It may exists a standalone instance. -+ It may also exists a backup for the standalone instance. -+ -+ Principle: -+ If standalone instance exists: -+ restart it -+ If backup of standalone exists: -+ create/rebind to standalone -+ -+ restore standalone instance from backup -+ else: -+ Cleanup everything -+ remove instance -+ remove backup -+ Create instance -+ Create backup -+ ''' -+ global installation_prefix -+ -+ if installation_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation_prefix -+ -+ standalone = DirSrv(verbose=False) -+ -+ # Args for the standalone instance -+ args_instance[SER_HOST] = HOST_STANDALONE -+ args_instance[SER_PORT] = PORT_STANDALONE -+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE -+ args_standalone = args_instance.copy() -+ standalone.allocate(args_standalone) -+ -+ # Get the status of the backups -+ backup_standalone = standalone.checkBackupFS() -+ -+ # Get the status of the instance and restart it if it exists -+ instance_standalone = standalone.exists() -+ if instance_standalone: -+ # assuming the instance is already stopped, just wait 5 sec max -+ standalone.stop(timeout=5) -+ standalone.start(timeout=10) -+ -+ if backup_standalone: -+ # The backup exist, assuming it is correct -+ # we just re-init the instance with it -+ if not instance_standalone: -+ standalone.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # restore standalone instance from backup -+ standalone.stop(timeout=10) -+ standalone.restoreFS(backup_standalone) -+ standalone.start(timeout=10) -+ -+ else: -+ # We should be here only in two conditions -+ # - This is the first time a test involve standalone instance -+ # - Something weird happened (instance/backup destroyed) -+ # so we discard everything and recreate all -+ -+ # Remove the backup. So even if we have a specific backup file -+ # (e.g backup_standalone) we clear backup that an instance may have created -+ if backup_standalone: -+ standalone.clearBackupFS() -+ -+ # Remove the instance -+ if instance_standalone: -+ standalone.delete() -+ -+ # Create the instance -+ standalone.create() -+ -+ # Used to retrieve configuration information (dbdir, confdir...) -+ standalone.open() -+ -+ # Time to create the backups -+ standalone.stop(timeout=10) -+ standalone.backupfile = standalone.backupFS() -+ standalone.start(timeout=10) -+ -+ # -+ # Here we have standalone instance up and running -+ # Either coming from a backup recovery -+ # or from a fresh (re)init -+ # Time to return the topology -+ return TopologyStandalone(standalone) -+ -+ -+def test_dynamic_plugins(topology): -+ """ -+ Test Dynamic Plugins - exercise each plugin and its main features, while -+ changing the configuration without restarting the server. -+ -+ Need to test: functionality, stability, and stress. -+ -+ Functionality - Make sure that as configuration changes are made they take -+ effect immediately. Cross plugin interaction (e.g. automember/memberOf) -+ needs to tested, as well as plugin tasks. Need to test plugin -+ config validation(dependencies, etc). -+ -+ Memory Corruption - Restart the plugins many times, and in different orders and test -+ functionality, and stability. This will excerise the internal -+ plugin linked lists, dse callabcks, and task handlers. -+ -+ Stress - Put the server under some type of load that is using a particular -+ plugin for each operation, and then make changes to that plugin. -+ The new changes should take effect, and the server should not crash. -+ -+ """ -+ -+ ############################################################################ -+ # Test plugin functionality -+ ############################################################################ -+ -+ # First enable dynamic plugins -+ try: -+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')]) -+ except ldap.LDAPError, e: -+ ldap.error('Failed to enable dynamic plugin!' + e.message['desc']) -+ assert False -+ -+ log.info('#####################################################') -+ log.info('Testing Dynamic Plugins Functionality...') -+ log.info('#####################################################\n') -+ -+ plugin_tests.test_all_plugins(topology.standalone) -+ -+ log.info('#####################################################') -+ log.info('Successfully Tested Dynamic Plugins Functionality.') -+ log.info('#####################################################\n') -+ -+ ############################################################################ -+ # Test the stability by exercising the internal lists, callabcks, and task handlers -+ ############################################################################ -+ -+ log.info('#####################################################') -+ log.info('Testing Dynamic Plugins for Memory Corruption...') -+ log.info('#####################################################\n') -+ prev_plugin_test = None -+ prev_prev_plugin_test = None -+ for plugin_test in plugin_tests.func_tests: -+ # -+ # Restart the plugin several times (and prev plugins) - work that linked list -+ # -+ plugin_test(topology.standalone, "restart") -+ -+ if prev_prev_plugin_test: -+ prev_prev_plugin_test(topology.standalone, "restart") -+ -+ plugin_test(topology.standalone, "restart") -+ -+ if prev_plugin_test: -+ prev_plugin_test(topology.standalone, "restart") -+ -+ plugin_test(topology.standalone, "restart") -+ -+ # Now run the functional test -+ plugin_test(topology.standalone) -+ -+ # Set the previous tests -+ if prev_plugin_test: -+ prev_prev_plugin_test = prev_plugin_test -+ prev_plugin_test = plugin_test -+ -+ log.info('#####################################################') -+ log.info('Successfully Tested Dynamic Plugins for Memory Corruption.') -+ log.info('#####################################################\n') -+ -+ ############################################################################ -+ # Stress two plugins while restarting it, and while restarting other plugins. -+ # The goal is to not crash, and have the plugins work after stressing it. -+ ############################################################################ -+ -+ log.info('#####################################################') -+ log.info('Stressing Dynamic Plugins...') -+ log.info('#####################################################\n') -+ -+ # Configure the plugins -+ stress_tests.configureMO(topology.standalone) -+ stress_tests.configureRI(topology.standalone) -+ -+ # Launch three new threads to add a bunch of users -+ add_users = stress_tests.AddUsers(topology.standalone, 'user', True) -+ add_users.start() -+ add_users2 = stress_tests.AddUsers(topology.standalone, 'entry', True) -+ add_users2.start() -+ add_users3 = stress_tests.AddUsers(topology.standalone, 'person', True) -+ add_users3.start() -+ time.sleep(1) -+ -+ # While we are adding users restart the MO plugin -+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF) -+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF) -+ time.sleep(3) -+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF) -+ time.sleep(1) -+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF) -+ -+ # Restart idle plugin -+ topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS) -+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS) -+ -+ # Wait for the 'adding' threads to complete -+ add_users.join() -+ add_users2.join() -+ add_users3.join() -+ -+ # Now launch three threads to delete the users, and restart both the MO and RI plugins -+ del_users = stress_tests.DelUsers(topology.standalone, 'user') -+ del_users.start() -+ del_users2 = stress_tests.DelUsers(topology.standalone, 'entry') -+ del_users2.start() -+ del_users3 = stress_tests.DelUsers(topology.standalone, 'person') -+ del_users3.start() -+ time.sleep(1) -+ -+ # Restart the both the MO and RI plugins during these deletes -+ -+ topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY) -+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF) -+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF) -+ topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY) -+ time.sleep(3) -+ topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY) -+ time.sleep(1) -+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF) -+ time.sleep(1) -+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF) -+ time.sleep(1) -+ topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY) -+ -+ # Restart idle plugin -+ topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS) -+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS) -+ -+ # Wait for the 'deleting' threads to complete -+ del_users.join() -+ del_users2.join() -+ del_users3.join() -+ -+ # Now make sure both the MO and RI plugins still work -+ plugin_tests.func_tests[8](topology.standalone) # RI plugin -+ plugin_tests.func_tests[5](topology.standalone) # MO plugin -+ -+ log.info('#####################################################') -+ log.info('Successfully Stressed Dynamic Plugins.') -+ log.info('#####################################################\n') -+ -+ ############################################################################ -+ # We made it to the end! -+ ############################################################################ -+ -+ log.info('#####################################################') -+ log.info('#####################################################') -+ log.info("Dynamic Plugins Testsuite: Completed Successfully!") -+ log.info('#####################################################') -+ log.info('#####################################################') -+ -+def test_dynamic_plugins_final(topology): -+ topology.standalone.stop(timeout=10) -+ -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - edit this file and comment '@pytest.fixture' line before 'topology' function. -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation_prefix -+ installation_prefix = None -+ -+ topo = topology(True) -+ test_dynamic_plugins(topo) -+ -+if __name__ == '__main__': -+ run_isolated() --- -1.9.3 - diff --git a/SOURCES/0052-Ticket-48228-wrong-password-check-if-passwordInHisto.patch b/SOURCES/0052-Ticket-48228-wrong-password-check-if-passwordInHisto.patch new file mode 100644 index 0000000..4b31ffd --- /dev/null +++ b/SOURCES/0052-Ticket-48228-wrong-password-check-if-passwordInHisto.patch @@ -0,0 +1,71 @@ +From 679e7b024e36ac9dfce85766f5d82cc272911e53 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 25 Aug 2015 16:31:10 -0700 +Subject: [PATCH 52/52] 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@redhat.com (Thank you, Rich!) + +(cherry picked from commit 391acfcf9a67b9b27ebbd98d1dfe30ef54a027c4) +(cherry picked from commit 096b386663c949136095def77a7fb12eee64e542) +--- + ldap/servers/slapd/pw.c | 21 ++++++++------------- + 1 file changed, 8 insertions(+), 13 deletions(-) + +diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c +index 3abebbf..4e222d7 100644 +--- a/ldap/servers/slapd/pw.c ++++ b/ldap/servers/slapd/pw.c +@@ -1085,8 +1085,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; +@@ -1097,23 +1095,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 ) + { +-- +1.9.3 + diff --git a/SOURCES/0053-Ticket-47525-Crash-if-setting-invalid-plugin-config-.patch b/SOURCES/0053-Ticket-47525-Crash-if-setting-invalid-plugin-config-.patch deleted file mode 100644 index d136264..0000000 --- a/SOURCES/0053-Ticket-47525-Crash-if-setting-invalid-plugin-config-.patch +++ /dev/null @@ -1,349 +0,0 @@ -From e47e64776f32a0bb593d1b9b3441e080f87f36f4 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 3 Dec 2014 16:47:59 -0500 -Subject: [PATCH 53/53] Ticket 47525 - Crash if setting invalid plugin config - area for MemberOf Plugin - -Bug Description: Setting the nsslapd-pluginconfigarea to an entry that - does not have the required config attributes causes a - crash. - -Fix Description: The plugin entry was being accidentally freed instead - of the config area entry. - - The shared config area validation was being performed - in postop - this has now been moved into the preop stage. - - Also, set the returntext when an error occurs. - -https://fedorahosted.org/389/ticket/47525 - -Reviewed by: rmeggins(Thanks!) - -(cherry picked from commit 42f935ab7406802d522f357048db1e68d729d5e5) -(cherry picked from commit d06b39743ef3b016ac25a242821a5dfc1ec67cb4) ---- - ldap/servers/plugins/memberof/memberof.c | 1 - - ldap/servers/plugins/memberof/memberof_config.c | 193 ++++++++++++++++-------- - 2 files changed, 130 insertions(+), 64 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index bfa733a..7e3e308 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -408,7 +408,6 @@ int memberof_postop_start(Slapi_PBlock *pb) - } - } - -- memberof_set_plugin_area(slapi_entry_get_sdn(config_e)); - memberof_set_config_area(slapi_entry_get_sdn(config_e)); - if (( rc = memberof_config( config_e, pb )) != LDAP_SUCCESS ) { - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c -index df8ddcb..eb83bd0 100644 ---- a/ldap/servers/plugins/memberof/memberof_config.c -+++ b/ldap/servers/plugins/memberof/memberof_config.c -@@ -342,56 +342,40 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - *returncode = LDAP_SUCCESS; - - /* -- * Apply the config settings from the shared config entry -+ * Check if this is a shared config entry - */ - sharedcfg = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA); - if(sharedcfg){ -- int rc = 0; -- -- rc = slapi_dn_syntax_check(pb, sharedcfg, 1); -- if (rc) { /* syntax check failed */ -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,"memberof_apply_config: " -- "%s does not contain a valid DN (%s)\n", -- SLAPI_PLUGIN_SHARED_CONFIG_AREA, sharedcfg); -- *returncode = LDAP_INVALID_DN_SYNTAX; -- goto done; -- } - if((config_sdn = slapi_sdn_new_dn_byval(sharedcfg))){ - slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, memberof_get_plugin_id()); - if(config_entry){ -- char errtext[SLAPI_DSE_RETURNTEXT_SIZE]; -- int err = 0; -- /* -- * If we got here, we are updating the shared config area, so we need to -- * validate and apply the settings from that config area. -- */ -- if ( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, config_entry, &err, errtext,0)) -- { -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "%s", errtext); -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- goto done; -- -- } -+ /* Set the entry to be the shared config entry. Validation was done in preop */ - e = config_entry; - } else { -- /* this should of been checked in preop validation */ -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_apply_config: " -- "Failed to locate shared config entry (%s)\n",sharedcfg); -+ /* This should of been checked in preop validation */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "memberof_apply_config: Failed to locate shared config entry (%s)", -+ sharedcfg); -+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,"%s\n",returntext); - *returncode = LDAP_UNWILLING_TO_PERFORM; - goto done; - } - } - } - -+ /* -+ * Apply the config settings -+ */ - groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR); - memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR); - allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR); - entryScope = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_ATTR); - entryScopeExcludeSubtree = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE); - -- /* We want to be sure we don't change the config in the middle of -- * a memberOf operation, so we obtain an exclusive lock here */ -+ /* -+ * We want to be sure we don't change the config in the middle of -+ * a memberOf operation, so we obtain an exclusive lock here -+ */ - memberof_wlock_config(); - - if (groupattrs) -@@ -402,8 +386,10 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - theConfig.groupattrs = groupattrs; - groupattrs = NULL; /* config now owns memory */ - -- /* We allocate a list of Slapi_Attr using the groupattrs for -- * convenience in our memberOf comparison functions */ -+ /* -+ * We allocate a list of Slapi_Attr using the groupattrs for -+ * convenience in our memberOf comparison functions -+ */ - for (i = 0; theConfig.group_slapiattrs && theConfig.group_slapiattrs[i]; i++) - { - slapi_attr_free(&theConfig.group_slapiattrs[i]); -@@ -412,8 +398,10 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - /* Count the number of groupattrs. */ - for (num_groupattrs = 0; theConfig.groupattrs && theConfig.groupattrs[num_groupattrs]; num_groupattrs++) - { -- /* Add up the total length of all attribute names. We need -- * to know this for building the group check filter later. */ -+ /* -+ * Add up the total length of all attribute names. We need -+ * to know this for building the group check filter later. -+ */ - groupattr_name_len += strlen(theConfig.groupattrs[num_groupattrs]); - } - -@@ -434,8 +422,7 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - /* Terminate the list. */ - theConfig.group_slapiattrs[i] = NULL; - -- /* The filter is based off of the groupattr, so we -- * update it here too. */ -+ /* The filter is based off of the groupattr, so we update it here too. */ - slapi_filter_free(theConfig.group_filter, 1); - - if (num_groupattrs > 1) -@@ -463,11 +450,13 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - filter_str = slapi_ch_smprintf("(%s=*)", theConfig.groupattrs[0]); - } - -- /* Log an error if we were unable to build the group filter for some -+ /* -+ * Log an error if we were unable to build the group filter for some - * reason. If this happens, the memberOf plugin will not be able to - * check if an entry is a group, causing it to not catch changes. This - * shouldn't happen, but there may be some garbage configuration that -- * could trigger this. */ -+ * could trigger this. -+ */ - if ((theConfig.group_filter = slapi_str2filter(filter_str)) == NULL) - { - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -@@ -547,13 +536,10 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - memberof_unlock_config(); - - done: -- slapi_ch_free_string(&sharedcfg); - slapi_sdn_free(&config_sdn); -- if(config_entry){ -- /* we switched the entry pointer to the shared config entry - which needs to be freed */ -- slapi_entry_free(e); -- } -+ slapi_entry_free(config_entry); - slapi_ch_array_free(groupattrs); -+ slapi_ch_free_string(&sharedcfg); - slapi_ch_free_string(&memberof_attr); - slapi_ch_free_string(&allBackends); - -@@ -745,6 +731,7 @@ memberof_config_get_entry_scope_exclude_subtree() - - return entry_exclude_subtree; - } -+ - /* - * Check if we are modifying the config, or changing the shared config entry - */ -@@ -753,53 +740,133 @@ memberof_shared_config_validate(Slapi_PBlock *pb) - { - Slapi_Entry *e = 0; - Slapi_Entry *resulting_e = 0; -- Slapi_DN *sdn = 0; -+ Slapi_Entry *config_entry = NULL; -+ Slapi_DN *sdn = NULL; -+ Slapi_DN *config_sdn = NULL; - Slapi_Mods *smods = 0; -+ Slapi_Mod *smod = NULL, *nextmod = NULL; - LDAPMod **mods = NULL; - char returntext[SLAPI_DSE_RETURNTEXT_SIZE]; -+ char *configarea_dn = NULL; - int ret = SLAPI_PLUGIN_SUCCESS; - - slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn); - -- if (slapi_sdn_issuffix(sdn, memberof_get_config_area()) && -- slapi_sdn_compare(sdn, memberof_get_config_area()) == 0) -- { -- /* -- * This is the shared config entry. Apply the mods and set/validate -- * the config -- */ -- int result = 0; -- -+ if (slapi_sdn_compare(sdn, memberof_get_plugin_area()) == 0 || -+ slapi_sdn_compare(sdn, memberof_get_config_area()) == 0) -+ { - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e); - if(e){ -+ /* -+ * Create a copy of the entry and apply the -+ * mods to create the resulting entry. -+ */ - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); - smods = slapi_mods_new(); - slapi_mods_init_byref(smods, mods); -- -- /* Create a copy of the entry and apply the -- * mods to create the resulting entry. */ - resulting_e = slapi_entry_dup(e); - if (mods && (slapi_entry_apply_mods(resulting_e, mods) != LDAP_SUCCESS)) { - /* we don't care about this, the update is invalid and will be caught later */ - goto bail; - } - -- if ( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, resulting_e, &ret, returntext,0)) { -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "%s", returntext); -- ret = LDAP_UNWILLING_TO_PERFORM; -+ if (slapi_sdn_compare(sdn, memberof_get_plugin_area())){ -+ /* -+ * This entry is a plugin config area entry, validate it. -+ */ -+ if( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, resulting_e, &ret, returntext,0)) { -+ ret = LDAP_UNWILLING_TO_PERFORM; -+ } -+ } else { -+ /* -+ * This is the memberOf plugin entry, check if we are adding/replacing the -+ * plugin config area. -+ */ -+ nextmod = slapi_mod_new(); -+ for (smod = slapi_mods_get_first_smod(smods, nextmod); -+ smod != NULL; -+ smod = slapi_mods_get_next_smod(smods, nextmod) ) -+ { -+ if ( PL_strcasecmp(SLAPI_PLUGIN_SHARED_CONFIG_AREA, slapi_mod_get_type(smod)) == 0 ) -+ { -+ /* -+ * Okay, we are modifying the plugin config area, we only care about -+ * adds and replaces. -+ */ -+ if(SLAPI_IS_MOD_REPLACE(slapi_mod_get_operation(smod)) || -+ SLAPI_IS_MOD_ADD(slapi_mod_get_operation(smod))) -+ { -+ struct berval *bv = NULL; -+ int rc = 0; -+ -+ bv = slapi_mod_get_first_value(smod); -+ configarea_dn = slapi_ch_strdup(bv->bv_val); -+ if(configarea_dn){ -+ /* Check the DN syntax */ -+ rc = slapi_dn_syntax_check(pb, configarea_dn, 1); -+ if (rc) { /* syntax check failed */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "%s does not contain a valid DN (%s)", -+ SLAPI_PLUGIN_SHARED_CONFIG_AREA, configarea_dn); -+ ret = LDAP_UNWILLING_TO_PERFORM; -+ goto bail; -+ } -+ -+ /* Check if the plugin config area entry exists */ -+ if((config_sdn = slapi_sdn_new_dn_byval(configarea_dn))){ -+ rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, -+ memberof_get_plugin_id()); -+ if(config_entry){ -+ int err = 0; -+ /* -+ * Validate the settings from the new config area. -+ */ -+ if ( memberof_validate_config(pb, NULL, config_entry, &err, returntext,0) -+ == SLAPI_DSE_CALLBACK_ERROR ) -+ { -+ ret = LDAP_UNWILLING_TO_PERFORM; -+ goto bail; -+ -+ } -+ } else { -+ /* The config area does not exist */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Unable to locate shared config entry (%s) error %d", -+ slapi_sdn_get_dn(memberof_get_config_area()), rc); -+ ret = LDAP_UNWILLING_TO_PERFORM; -+ goto bail; -+ } -+ } -+ } -+ slapi_ch_free_string(&configarea_dn); -+ slapi_sdn_free(&config_sdn); -+ slapi_entry_free(config_entry); -+ } -+ } -+ } - } - } else { -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_shared_config_validate: " -- "Unable to locate shared config entry (%s) error %d\n", -- slapi_sdn_get_dn(memberof_get_config_area()), result); -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Unable to locate shared config entry (%s)", -+ slapi_sdn_get_dn(memberof_get_config_area())); - ret = LDAP_UNWILLING_TO_PERFORM; - } - } - - bail: -+ -+ if (ret){ -+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); -+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, returntext); -+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_shared_config_validate: %s/n", -+ returntext); -+ } -+ slapi_sdn_free(&config_sdn); -+ if(nextmod) -+ slapi_mod_free(&nextmod); - slapi_mods_free(&smods); - slapi_entry_free(resulting_e); -+ slapi_entry_free(config_entry); -+ slapi_ch_free_string(&configarea_dn); - - return ret; - } --- -1.9.3 - diff --git a/SOURCES/0053-Ticket-48265-Complex-filter-in-a-search-request-doen.patch b/SOURCES/0053-Ticket-48265-Complex-filter-in-a-search-request-doen.patch new file mode 100644 index 0000000..a428a37 --- /dev/null +++ b/SOURCES/0053-Ticket-48265-Complex-filter-in-a-search-request-doen.patch @@ -0,0 +1,54 @@ +From c03a9f7c121355aefadc92ed67bcb6f400196017 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 2 Sep 2015 14:28:27 -0700 +Subject: [PATCH 53/54] 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@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 8c3d3e4648fbb5229e329e2154d46f1ae808ba02) +(cherry picked from commit 3d9dbf2d441e551495a1f3169dc2020324c484b4) +--- + ldap/servers/slapd/index_subsystem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/ldap/servers/slapd/index_subsystem.c b/ldap/servers/slapd/index_subsystem.c +index fdaef6a..93bf9d5 100644 +--- a/ldap/servers/slapd/index_subsystem.c ++++ b/ldap/servers/slapd/index_subsystem.c +@@ -412,6 +412,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; + } +-- +1.9.3 + diff --git a/SOURCES/0054-Ticket-47965-Fix-coverity-issues-2014-11-24.patch b/SOURCES/0054-Ticket-47965-Fix-coverity-issues-2014-11-24.patch deleted file mode 100644 index ddafec9..0000000 --- a/SOURCES/0054-Ticket-47965-Fix-coverity-issues-2014-11-24.patch +++ /dev/null @@ -1,433 +0,0 @@ -From 86cb4a8568160e5f5f1051506b8f24bb1312ff60 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 24 Nov 2014 12:22:34 -0500 -Subject: [PATCH 54/55] Ticket 47965 - Fix coverity issues (2014/11/24) - -12864 - nesting level adjustment - sync_presist.c -12867 - Uninitialized pointer read - repl5_replica.c -12870 - Unused value - repl5_ruv.c -12880, 12881, 12893 - Unused value - dblayer.c -12887 - nesting level adjustment - acl.c -12894 - nesting level adjustment - acl_ext.c -12898 - Logically dead code - acllas.c -12891 - Unused value - windows_inc_protocol.c -12902 - Unused value - repl5_inc_protocol.c - -https://fedorahosted.org/389/ticket/47965 - -Reviewed by: rmeggins(Thanks!) - -(cherry picked from commit da90d57c30bf93265f06499b8ea2102378a0ed12) -(cherry picked from commit 61d1211f1721355d571d570a67f36ef6baeb4866) ---- - ldap/servers/plugins/acl/acl.c | 3 +- - ldap/servers/plugins/acl/acl_ext.c | 52 +++++++------ - ldap/servers/plugins/acl/acllas.c | 4 - - .../plugins/replication/repl5_inc_protocol.c | 1 - - ldap/servers/plugins/replication/repl5_replica.c | 2 +- - ldap/servers/plugins/replication/repl5_ruv.c | 1 - - .../plugins/replication/windows_inc_protocol.c | 89 +++++++++++----------- - ldap/servers/plugins/sync/sync_persist.c | 8 +- - ldap/servers/slapd/back-ldbm/dblayer.c | 21 +++-- - ldap/servers/slapd/pw.c | 47 +++++++----- - 10 files changed, 119 insertions(+), 109 deletions(-) - -diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c -index 403c5b3..f04e258 100644 ---- a/ldap/servers/plugins/acl/acl.c -+++ b/ldap/servers/plugins/acl/acl.c -@@ -2106,9 +2106,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int * - ** acl in the entry cache list. - */ - if (!((res_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)) && -- (aci_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)))) -+ (aci_right & (SLAPI_ACL_SEARCH | SLAPI_ACL_READ)))){ - matches = ACL_FALSE; - goto acl__resource_match_aci_EXIT; -+ } - } - - -diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c -index 126a234..0863de0 100644 ---- a/ldap/servers/plugins/acl/acl_ext.c -+++ b/ldap/servers/plugins/acl/acl_ext.c -@@ -334,12 +334,14 @@ acl_operation_ext_destructor ( void *ext, void *object, void *parent ) - int attr_only = 0; - PRLock *shared_lock = aclcb->aclcb_lock; - -- if (aclcb->aclcb_lock ) PR_Lock ( shared_lock ); -+ if (aclcb->aclcb_lock ) -+ PR_Lock ( shared_lock ); - else { - goto clean_aclpb; - } - if ( !aclcb->aclcb_lock ) { -- slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "aclcb lock released! aclcb cache can't be refreshed\n"); -+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name, -+ "aclcb lock released! aclcb cache can't be refreshed\n"); - PR_Unlock ( shared_lock ); - goto clean_aclpb; - } -@@ -347,29 +349,29 @@ acl_operation_ext_destructor ( void *ext, void *object, void *parent ) - /* We need to refresh the aclcb cache */ - if ( aclpb->aclpb_state & ACLPB_UPD_ACLCB_CACHE ) - acl_clean_aclEval_context ( &aclcb->aclcb_eval_context, 0 /* clean*/ ); -- if ( aclpb->aclpb_prev_entryEval_context.acle_numof_attrs ) { -- c_evalContext = &aclpb->aclpb_prev_entryEval_context; -- } else { -- c_evalContext = &aclpb->aclpb_curr_entryEval_context; -- } -- -- if (( aclpb->aclpb_state & ACLPB_INCR_ACLCB_CACHE ) && -- ! ( aclpb->aclpb_state & ACLPB_UPD_ACLCB_CACHE )) -- attr_only = 1; -- -- acl_copyEval_context ( NULL, c_evalContext, &aclcb->aclcb_eval_context, attr_only ); -- -- aclcb->aclcb_aclsignature = aclpb->aclpb_signature; -- if ( aclcb->aclcb_sdn && -- (0 != slapi_sdn_compare ( aclcb->aclcb_sdn, -- aclpb->aclpb_authorization_sdn ) ) ) { -- slapi_sdn_set_ndn_byval( aclcb->aclcb_sdn, -- slapi_sdn_get_ndn ( aclpb->aclpb_authorization_sdn ) ); -- } -- aclcb->aclcb_state = 0; -- aclcb->aclcb_state |= ACLCB_HAS_CACHED_EVALCONTEXT; -- -- PR_Unlock ( shared_lock ); -+ if ( aclpb->aclpb_prev_entryEval_context.acle_numof_attrs ) { -+ c_evalContext = &aclpb->aclpb_prev_entryEval_context; -+ } else { -+ c_evalContext = &aclpb->aclpb_curr_entryEval_context; -+ } -+ -+ if (( aclpb->aclpb_state & ACLPB_INCR_ACLCB_CACHE ) && -+ ! ( aclpb->aclpb_state & ACLPB_UPD_ACLCB_CACHE )) -+ attr_only = 1; -+ -+ acl_copyEval_context ( NULL, c_evalContext, &aclcb->aclcb_eval_context, attr_only ); -+ -+ aclcb->aclcb_aclsignature = aclpb->aclpb_signature; -+ if ( aclcb->aclcb_sdn && -+ (0 != slapi_sdn_compare( aclcb->aclcb_sdn, aclpb->aclpb_authorization_sdn ))) -+ { -+ slapi_sdn_set_ndn_byval( aclcb->aclcb_sdn, -+ slapi_sdn_get_ndn ( aclpb->aclpb_authorization_sdn ) ); -+ } -+ aclcb->aclcb_state = 0; -+ aclcb->aclcb_state |= ACLCB_HAS_CACHED_EVALCONTEXT; -+ -+ PR_Unlock ( shared_lock ); - } - - clean_aclpb: -diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c -index 2d0dae9..439c8f1 100644 ---- a/ldap/servers/plugins/acl/acllas.c -+++ b/ldap/servers/plugins/acl/acllas.c -@@ -1726,10 +1726,6 @@ DS_LASAuthMethodEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator, - } else { - rc = (matched == ACL_TRUE ? LAS_EVAL_FALSE : LAS_EVAL_TRUE); - } -- } else { -- rc = LAS_EVAL_FAIL; -- slapi_log_error( SLAPI_LOG_ACL, plugin_name, -- "Returning UNDEFINED for authmethod evaluation.\n"); - } - - return rc; -diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c -index b867fc4..5cf170c 100644 ---- a/ldap/servers/plugins/replication/repl5_inc_protocol.c -+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c -@@ -940,7 +940,6 @@ repl5_inc_run(Private_Repl_Protocol *prp) - /* Destroy the backoff timer, since we won't need it anymore */ - backoff_delete(&prp_priv->backoff); - } -- use_busy_backoff_timer = PR_FALSE; - } else if (event_occurred(prp, EVENT_TRIGGERING_CRITERIA_MET)){ - /* changes are available */ - if ( prp_priv->backoff == NULL || backoff_expired (prp_priv->backoff, 60)){ -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index dab1c4e..77663f6 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -2140,7 +2140,7 @@ done: - char *ridstr = NULL; - char *token = NULL; - char *repl_root; -- char *iter; -+ char *iter = NULL; - int i; - - for(i = 0; clean_vals[i]; i++){ -diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c -index 500fd7a..132c641 100644 ---- a/ldap/servers/plugins/replication/repl5_ruv.c -+++ b/ldap/servers/plugins/replication/repl5_ruv.c -@@ -705,7 +705,6 @@ set_max_csn_nolock_ext(RUV *ruv, const CSN *max_csn, const char *replica_purl, P - csn_as_string(replica->csn, PR_FALSE, csn2)); - return_value = RUV_COVERS_CSN; - } -- return_value = RUV_SUCCESS; - } - return return_value; - } -diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c -index d62deec..ec6ca55 100644 ---- a/ldap/servers/plugins/replication/windows_inc_protocol.c -+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c -@@ -675,63 +675,64 @@ windows_inc_run(Private_Repl_Protocol *prp) - backoff_delete(&prp_priv->backoff); - } - else if (event_occurred(prp, EVENT_BACKOFF_EXPIRED)) -- { -+ { - rc = windows_acquire_replica(prp, &ruv, 1 /* check RUV for incremental */); - use_busy_backoff_timer = PR_FALSE; - if (rc == ACQUIRE_SUCCESS) -- { -- next_state = STATE_SENDING_UPDATES; -- } -+ { -+ next_state = STATE_SENDING_UPDATES; -+ } - else if (rc == ACQUIRE_REPLICA_BUSY) -- { -- next_state = STATE_BACKOFF; -- use_busy_backoff_timer = PR_TRUE; -- } -+ { -+ next_state = STATE_BACKOFF; -+ use_busy_backoff_timer = PR_TRUE; -+ } - else if (rc == ACQUIRE_CONSUMER_WAS_UPTODATE) -- { -+ { - next_state = STATE_WAIT_CHANGES; -- } -+ } - else if (rc == ACQUIRE_TRANSIENT_ERROR) -- { -- next_state = STATE_BACKOFF; -- } -+ { -+ next_state = STATE_BACKOFF; -+ } - else if (rc == ACQUIRE_FATAL_ERROR) -- { -- next_state = STATE_STOP_FATAL_ERROR; -- } -+ { -+ next_state = STATE_STOP_FATAL_ERROR; -+ } -+ - if (rc != ACQUIRE_SUCCESS) -- { -- int optype, ldaprc; -- windows_conn_get_error(prp->conn, &optype, &ldaprc); -- agmt_set_last_update_status(prp->agmt, ldaprc, -+ { -+ int optype, ldaprc; -+ windows_conn_get_error(prp->conn, &optype, &ldaprc); -+ agmt_set_last_update_status(prp->agmt, ldaprc, - prp->last_acquire_response_code, NULL); -- } -- /* -- * We either need to step the backoff timer, or -- * destroy it if we don't need it anymore. -- */ -+ } -+ -+ /* -+ * We either need to step the backoff timer, or -+ * destroy it if we don't need it anymore. -+ */ - if (STATE_BACKOFF == next_state) -- { -- time_t next_fire_time; -- time_t now; -- /* Step the backoff timer */ -- time(&now); -- next_fire_time = backoff_step(prp_priv->backoff); -- /* And go back to sleep */ -- slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name, -- "%s: Replication session backing off for %ld seconds\n", -- agmt_get_long_name(prp->agmt), -- next_fire_time - now); -+ { -+ time_t next_fire_time; -+ time_t now; -+ /* Step the backoff timer */ -+ time(&now); -+ next_fire_time = backoff_step(prp_priv->backoff); -+ /* And go back to sleep */ -+ slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name, -+ "%s: Replication session backing off for %ld seconds\n", -+ agmt_get_long_name(prp->agmt), -+ next_fire_time - now); - -- protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT); -- } -+ protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT); -+ } - else -- { -- /* Destroy the backoff timer, since we won't need it anymore */ -- backoff_delete(&prp_priv->backoff); -- } -- use_busy_backoff_timer = PR_FALSE; -- } -+ { -+ /* Destroy the backoff timer, since we won't need it anymore */ -+ backoff_delete(&prp_priv->backoff); -+ } -+ } - else if (event_occurred(prp, EVENT_TRIGGERING_CRITERIA_MET)) - { - /* changes are available */ -diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c -index 8d46102..f41a10c 100644 ---- a/ldap/servers/plugins/sync/sync_persist.c -+++ b/ldap/servers/plugins/sync/sync_persist.c -@@ -661,10 +661,10 @@ sync_send_results( void *arg ) - ectrls = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *)); - if (req->req_cookie) - sync_cookie_update(req->req_cookie, ec); -- sync_create_state_control(ec, &ectrls[0], chg_type, req->req_cookie); -- rc = slapi_send_ldap_search_entry( req->req_pblock, -- ec, ectrls, -- noattrs?noattrs:attrs, attrsonly ); -+ sync_create_state_control(ec, &ectrls[0], chg_type, req->req_cookie); -+ rc = slapi_send_ldap_search_entry( req->req_pblock, -+ ec, ectrls, -+ noattrs?noattrs:attrs, attrsonly ); - if (rc) { - slapi_log_error(SLAPI_LOG_CONNS, SYNC_PLUGIN_SUBSYSTEM, - "Error %d sending entry %s\n", -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index f3159a9..2524355 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -4805,19 +4805,18 @@ static int checkpoint_threadmain(void *param) - - for (inst_obj = objset_first_obj(li->li_instance_set); - inst_obj; -- inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) { -+ inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) -+ { - inst = (ldbm_instance *)object_get_data(inst_obj); - rc = dblayer_get_id2entry(inst->inst_be, &db); -- if (!db) { -+ if (!db || rc ) { - continue; - } - LDAPDebug1Arg(LDAP_DEBUG_BACKLDBM, "compactdb: Compacting DB start: %s\n", - inst->inst_name); - rc = dblayer_txn_begin(inst->inst_be, NULL, &txn); - if (rc) { -- LDAPDebug1Arg(LDAP_DEBUG_ANY, -- "compactdb: transaction begin failed: %d\n", -- rc); -+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "compactdb: transaction begin failed: %d\n", rc); - break; - } - rc = db->compact(db, txn.back_txn_txn, NULL/*start*/, NULL/*stop*/, -@@ -4826,12 +4825,20 @@ static int checkpoint_threadmain(void *param) - LDAPDebug(LDAP_DEBUG_ANY, - "compactdb: failed to compact %s; db error - %d %s\n", - inst->inst_name, rc, db_strerror(rc)); -- rc = dblayer_txn_abort(inst->inst_be, &txn); -+ if((rc = dblayer_txn_abort(inst->inst_be, &txn))){ -+ LDAPDebug(LDAP_DEBUG_ANY, "compactdb: failed to abort txn (%s) db error - %d %s\n", -+ inst->inst_name, rc, db_strerror(rc)); -+ break; -+ } - } else { - LDAPDebug2Args(LDAP_DEBUG_BACKLDBM, - "compactdb: compact %s - %d pages freed\n", - inst->inst_name, c_data.compact_pages_free); -- rc = dblayer_txn_commit(inst->inst_be, &txn); -+ if((rc = dblayer_txn_commit(inst->inst_be, &txn))){ -+ LDAPDebug(LDAP_DEBUG_ANY, "compactdb: failed to commit txn (%s) db error - %d %s\n", -+ inst->inst_name, rc, db_strerror(rc)); -+ break; -+ } - } - } - time_of_last_comapctdb_completion = current_time(); /* seconds since epoch */ -diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c -index a4d2dc6..7930be9 100644 ---- a/ldap/servers/slapd/pw.c -+++ b/ldap/servers/slapd/pw.c -@@ -2011,28 +2011,33 @@ slapi_pwpolicy_make_response_control (Slapi_PBlock *pb, int seconds, int logins, - } - - rc = ber_printf( ber, "{" ); -- if ( seconds >= 0 || logins >= 0 ) { -- if ( seconds >= 0 ) { -- rc = ber_printf( ber, "t{ti}", LDAP_TAG_PWP_WARNING, -- LDAP_TAG_PWP_SECSLEFT, -- seconds ); -- } -- else { -- rc = ber_printf( ber, "t{ti}", LDAP_TAG_PWP_WARNING, -- LDAP_TAG_PWP_GRCLOGINS, -- logins ); -+ if ( rc != -1){ -+ if(seconds >= 0 || logins >= 0 ) { -+ if ( seconds >= 0 ) { -+ rc = ber_printf( ber, "t{ti}", LDAP_TAG_PWP_WARNING, -+ LDAP_TAG_PWP_SECSLEFT, -+ seconds ); -+ } -+ else { -+ rc = ber_printf( ber, "t{ti}", LDAP_TAG_PWP_WARNING, -+ LDAP_TAG_PWP_GRCLOGINS, -+ logins ); -+ } -+ } -+ if (rc != -1){ -+ if ( error >= 0 ) { -+ rc = ber_printf( ber, "te", LDAP_TAG_PWP_ERROR, error ); -+ } -+ if (rc != -1){ -+ rc = ber_printf( ber, "}" ); -+ if ( rc != -1 ) -+ { -+ rc = ber_flatten( ber, &bvp ); -+ } -+ } - } - } -- if ( error >= 0 ) { -- rc = ber_printf( ber, "te", LDAP_TAG_PWP_ERROR, error ); -- } -- rc = ber_printf( ber, "}" ); - -- if ( rc != -1 ) -- { -- rc = ber_flatten( ber, &bvp ); -- } -- - ber_free( ber, 1 ); - - if ( rc != -1 ) -@@ -2041,11 +2046,11 @@ slapi_pwpolicy_make_response_control (Slapi_PBlock *pb, int seconds, int logins, - new_ctrl.ldctl_oid = LDAP_X_CONTROL_PWPOLICY_RESPONSE; - new_ctrl.ldctl_value = *bvp; - new_ctrl.ldctl_iscritical = 0; -- rc= slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, &new_ctrl ); -+ rc = slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL, &new_ctrl ); - ber_bvfree(bvp); - } - -- LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_pwpolicy_make_response_control", 0, 0, 0 ); -+ LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_pwpolicy_make_response_control (%d)", rc, 0, 0 ); - - return (rc==-1?LDAP_OPERATIONS_ERROR:LDAP_SUCCESS); - } --- -1.9.3 - diff --git a/SOURCES/0054-Ticket-47981-COS-cache-doesn-t-properly-mark-vattr-c.patch b/SOURCES/0054-Ticket-47981-COS-cache-doesn-t-properly-mark-vattr-c.patch new file mode 100644 index 0000000..56c535a --- /dev/null +++ b/SOURCES/0054-Ticket-47981-COS-cache-doesn-t-properly-mark-vattr-c.patch @@ -0,0 +1,38 @@ +From 8d4369e6060f7c079b02fa87a0cd0d2ae0488ecd Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 2 Sep 2015 18:04:27 -0700 +Subject: [PATCH 54/54] 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@redhat.com (Thank you, Mark!!) + +(cherry picked from commit 6557b820dca7980067afc2a33184197b2d154a51) +(cherry picked from commit c1721f1d6e2344eefaec817ed47119c15c43fcfc) +--- + ldap/servers/plugins/cos/cos_cache.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c +index ddb85ab..e0b841d 100644 +--- a/ldap/servers/plugins/cos/cos_cache.c ++++ b/ldap/servers/plugins/cos/cos_cache.c +@@ -647,7 +647,6 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca + { + *vattr_cacheable = -1; + cos_def_available = 1; +- break; + } + } + valIndex++; +-- +1.9.3 + diff --git a/SOURCES/0055-Ticket-47965-Fix-coverity-issues-2014-12-16.patch b/SOURCES/0055-Ticket-47965-Fix-coverity-issues-2014-12-16.patch deleted file mode 100644 index 3de1600..0000000 --- a/SOURCES/0055-Ticket-47965-Fix-coverity-issues-2014-12-16.patch +++ /dev/null @@ -1,170 +0,0 @@ -From c56a01740faa7af009eab4f009d334bb7b705f89 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 16 Dec 2014 11:26:04 -0800 -Subject: [PATCH 55/55] Ticket 47965 - Fix coverity issues (2014/12/16) - -12867 - Uninitialized pointer read - -Description: -The third arg for ldap_utf8strtok_r is supposed to be initialized. - -https://fedorahosted.org/389/ticket/47965 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 62072539953d0956e0f2664ef1a3691cf8fbdac0) -(cherry picked from commit a2977b4b1839f4853594a46593ac5e2e27155bed) ---- - ldap/servers/plugins/acl/acllas.c | 6 +++--- - ldap/servers/plugins/acl/aclparse.c | 4 ++-- - ldap/servers/plugins/replication/repl5_replica.c | 2 +- - ldap/servers/plugins/replication/repl_extop.c | 4 ++-- - ldap/servers/plugins/replication/windows_connection.c | 2 +- - ldap/servers/plugins/replication/windows_private.c | 2 +- - ldap/servers/plugins/rootdn_access/rootdn_access.c | 2 +- - ldap/servers/slapd/back-ldbm/ldbm_attr.c | 2 +- - 8 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c -index 439c8f1..4738a40 100644 ---- a/ldap/servers/plugins/acl/acllas.c -+++ b/ldap/servers/plugins/acl/acllas.c -@@ -1223,7 +1223,7 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator, - - /* See if we have a parent[2].attr" rule */ - if (strstr(attrName, "parent[") != NULL) { -- char *word, *str, *next; -+ char *word, *str, *next = NULL; - - numOflevels = 0; - n_currEntryDn = slapi_entry_get_ndn ( lasinfo.resourceEntry ); -@@ -1489,7 +1489,7 @@ DS_LASLdapUrlAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator, - - /* See if we have a parent[2].attr" rule */ - if (strstr(attrName, "parent[") != NULL) { -- char *word, *str, *next; -+ char *word, *str, *next = NULL; - - numOflevels = 0; - n_currEntryDn = slapi_entry_get_ndn ( lasinfo.resourceEntry ); -@@ -2659,7 +2659,7 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator, - - /* See if we have a parent[2].attr" rule */ - if (strstr(attrName, "parent[") != NULL) { -- char *word, *str, *next; -+ char *word, *str, *next = NULL; - - numOflevels = 0; - n_currEntryDn = slapi_entry_get_ndn ( lasinfo.resourceEntry ) ; -diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c -index be86c8b..fd262e8 100644 ---- a/ldap/servers/plugins/acl/aclparse.c -+++ b/ldap/servers/plugins/acl/aclparse.c -@@ -600,7 +600,7 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str) - ACLListHandle_t *handle = NULL; - char *newstr = NULL; - char *word; -- char *next; -+ char *next = NULL; - const char *brkstr = " ;"; - int checkversion = 0; - -@@ -1367,7 +1367,7 @@ __aclp__get_aci_right (char *str) - { - - char *sav_str = slapi_ch_strdup(str); -- char *t, *tt; -+ char *t, *tt = NULL; - int type = 0; - char *delimiter = ","; - char *val = NULL; -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index 77663f6..61ae7ec 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -2046,7 +2046,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e) - char *forcing; - char *csnpart; - char *ridstr; -- char *iter; -+ char *iter = NULL; - int i; - - for(i = 0; i < CLEANRIDSIZ && clean_vals[i]; i++){ -diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c -index 35014a9..4fefe9f 100644 ---- a/ldap/servers/plugins/replication/repl_extop.c -+++ b/ldap/servers/plugins/replication/repl_extop.c -@@ -1463,7 +1463,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) - char *repl_root; - char *payload = NULL; - char *certify_all; -- char *iter; -+ char *iter = NULL; - int rc = LDAP_SUCCESS; - - slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid); -@@ -1591,7 +1591,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) - char *force = NULL; - char *extop_oid; - char *repl_root; -- char *iter; -+ char *iter = NULL; - int release_it = 0; - int rid = 0; - int rc = LDAP_OPERATIONS_ERROR; -diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c -index c7c7a98..e78c367 100644 ---- a/ldap/servers/plugins/replication/windows_connection.c -+++ b/ldap/servers/plugins/replication/windows_connection.c -@@ -595,7 +595,7 @@ windows_LDAPMessage2Entry(Slapi_Entry *e, Repl_Connection *conn, - char *dupa = slapi_ch_strdup(a); - char *newa = NULL; /* dup of 'a' with next range */ - char *p, *wp, *pp; /* work pointers */ -- char *iter; -+ char *iter = NULL; - int high = 0; - int sizea = strlen(a) + 2; - /* handling subtype(s) */ -diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c -index cfa2704..9be6c7d 100644 ---- a/ldap/servers/plugins/replication/windows_private.c -+++ b/ldap/servers/plugins/replication/windows_private.c -@@ -946,7 +946,7 @@ create_subtree_pairs(char **pairs) - subtreePair *spp; - char **ptr; - char *p0, *p1; -- char *saveptr; -+ char *saveptr = NULL; - int cnt; - - for (cnt = 0, ptr = pairs; ptr && *ptr; cnt++, ptr++) ; -diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c -index 3045e9f..5c530c6 100644 ---- a/ldap/servers/plugins/rootdn_access/rootdn_access.c -+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c -@@ -229,7 +229,7 @@ rootdn_load_config(Slapi_PBlock *pb) - Slapi_Entry *e = NULL; - char *openTime = NULL; - char *closeTime = NULL; -- char *token, *iter, *copy; -+ char *token, *iter = NULL, *copy; - char hour[3], min[3]; - int result = 0; - int time; -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c -index 13ab07b..7b3f664 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c -@@ -509,7 +509,7 @@ attr_index_parse_idlistsize(struct attrinfo *ai, const char *strval, struct inde - int rc = 0; /* assume success */ - char *mystr = slapi_ch_strdup(strval); /* copy for strtok */ - char *values = NULL; -- char *lasts, *val, *ptr; -+ char *lasts = NULL, *val, *ptr; - int seen_limit = 0, seen_type = 0, seen_flags = 0, seen_values = 0; - Slapi_Attr *attr = &ai->ai_sattr; - --- -1.9.3 - diff --git a/SOURCES/0055-Ticket-48276-initialize-free_flags-in-reslimit_updat.patch b/SOURCES/0055-Ticket-48276-initialize-free_flags-in-reslimit_updat.patch new file mode 100644 index 0000000..f77fb37 --- /dev/null +++ b/SOURCES/0055-Ticket-48276-initialize-free_flags-in-reslimit_updat.patch @@ -0,0 +1,47 @@ +From 4040a7b0968db2aa5b905c7268abf57eca2ec8c2 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 14 Sep 2015 12:01:08 -0400 +Subject: [PATCH 55/61] Ticket 48276 - initialize free_flags in + reslimit_update_from_entry() + +Description: In reslimit_update_from_entry() the free_flags was not initialized, + which could lead to it being seen as set, and cause an entry's + vattrs to be incorrectly/unexpectedly freed. + +https://fedorahosted.org/389/ticket/48276 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 2311c71cec33c29863bdb1dabe1ed363679316d3) +(cherry picked from commit 5f32582d043a5498791dda5af7091bf1a4a320f0) +--- + ldap/servers/slapd/resourcelimit.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/ldap/servers/slapd/resourcelimit.c b/ldap/servers/slapd/resourcelimit.c +index 8c0a09c..7630f88 100644 +--- a/ldap/servers/slapd/resourcelimit.c ++++ b/ldap/servers/slapd/resourcelimit.c +@@ -342,11 +342,14 @@ reslimit_update_from_dn( Slapi_Connection *conn, Slapi_DN *dn ) + int + reslimit_update_from_entry( Slapi_Connection *conn, Slapi_Entry *e ) + { +- char *fnname = "reslimit_update_from_entry()"; +- char *actual_type_name, *get_ext_logname; +- int i, rc, type_name_disposition, free_flags; +- SLAPIResLimitConnData *rlcdp; +- Slapi_ValueSet *vs; ++ SLAPIResLimitConnData *rlcdp = NULL; ++ Slapi_ValueSet *vs = NULL; ++ char *fnname = "reslimit_update_from_entry()"; ++ char *actual_type_name = NULL; ++ char *get_ext_logname = NULL; ++ int type_name_disposition = 0; ++ int free_flags = 0; ++ int rc, i; + + LDAPDebug( SLAPI_RESLIMIT_TRACELEVEL, "=> %s conn=0x%x, entry=0x%x\n", + fnname, conn, e ); +-- +1.9.3 + diff --git a/SOURCES/0056-Ticket-47750-During-delete-operation-do-not-refresh-.patch b/SOURCES/0056-Ticket-47750-During-delete-operation-do-not-refresh-.patch deleted file mode 100644 index a670d02..0000000 --- a/SOURCES/0056-Ticket-47750-During-delete-operation-do-not-refresh-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 6649bbb2900841a101ab60ef43d55742ee3abb9a Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 18 Dec 2014 09:08:52 -0500 -Subject: [PATCH] Ticket 47750 - During delete operation do not refresh cache - entry if it is a tombstone - -Bug Description: After calling the betxn postop plugins do not attempt to refresh the - entry if it was converted to a tombstone. A tombstone entry does - not have its entry mutex allocated, and it will be dereferenced. - -Fix Description: If the entry is converted to a tombstone, there is no need to - refresh it in the first place. Skip the cache refresh if its a - tombstone. If its not a tombstone, we also need to return the - cache entry if it was not changed in betxn postop, because we - incremented its refcnt while checking if it was updated. - -https://fedorahosted.org/389/ticket/47750 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit 4ae67943e807b869aeda213dcd39b59feb5f8259) -(cherry picked from commit f63473228d05c56a096580ec5e66566b35ab4535) ---- - ldap/servers/slapd/back-ldbm/ldbm_delete.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -index 5f12ea3..56ea3df 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -@@ -1261,6 +1261,16 @@ ldbm_back_delete( Slapi_PBlock *pb ) - - /* delete from cache and clean up */ - if (e) { -+ if(!create_tombstone_entry){ -+ struct backentry *old_e = e; -+ e = cache_find_id(&inst->inst_cache,e->ep_id); -+ if(e != old_e){ -+ cache_unlock_entry(&inst->inst_cache, old_e); -+ CACHE_RETURN(&inst->inst_cache, &old_e); -+ } else { -+ CACHE_RETURN(&inst->inst_cache, &e); -+ } -+ } - if (cache_is_in_cache(&inst->inst_cache, e)) { - ep_id = e->ep_id; /* Otherwise, e might have been freed. */ - CACHE_REMOVE(&inst->inst_cache, e); --- -1.9.3 - diff --git a/SOURCES/0056-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch b/SOURCES/0056-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch new file mode 100644 index 0000000..adc14d9 --- /dev/null +++ b/SOURCES/0056-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch @@ -0,0 +1,76 @@ +From 14e08bde4a48a8e8b56edc817b5d1e3d56b96c72 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Tue, 15 Sep 2015 18:25:02 -0700 +Subject: [PATCH 56/61] Ticket #48226 - In MMR, double free coould occur under + some special condition + +Description: commit a0f8e0f981a046882db299a7a6d6d1c01bc19571 introduced +a memory leak in the case of resolve_attribute_state_present_to_deleted. +In the case, csnset is not consumed. Thus, it has to be freed by csnset_ +free. + +https://fedorahosted.org/389/ticket/48226 + +Reviewed by mreynolds@redhat.com (Thank you, Mark!!) + +(cherry picked from commit b26ec6762fe2b5d37ade59243086cfd2308e8f0a) +(cherry picked from commit 4a3efc3330a034fa485f33e453054758561d4cea) +--- + ldap/servers/slapd/entrywsi.c | 22 +++++++++++----------- + ldap/servers/slapd/valueset.c | 1 + + 2 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c +index e719dce..a8f8455 100644 +--- a/ldap/servers/slapd/entrywsi.c ++++ b/ldap/servers/slapd/entrywsi.c +@@ -1280,23 +1280,23 @@ resolve_attribute_state_present_to_deleted(Slapi_Entry *e, Slapi_Attr *a, Slapi_ + const CSN *adcsn= attr_get_deletion_csn(a); + int i; + if ( valuestoupdate != NULL && valuestoupdate[0] != NULL ) { +- for (i=0;valuestoupdate[i]!=NULL;++i) { +- /* This call ensures that the value does not contain a deletion_csn +- * which is before the presence_csn or distinguished_csn of the value. +- */ +- purge_attribute_state_multi_valued(a, valuestoupdate[i]); +- vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED); +- vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED); +- deletedcsn= csn_max(vdcsn, adcsn); ++ for (i=0;valuestoupdate[i]!=NULL;++i) { ++ /* This call ensures that the value does not contain a deletion_csn ++ * which is before the presence_csn or distinguished_csn of the value. ++ */ ++ purge_attribute_state_multi_valued(a, valuestoupdate[i]); ++ vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED); ++ vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED); ++ deletedcsn= csn_max(vdcsn, adcsn); + if(csn_compare(vucsn,deletedcsn)<0) + { +- if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn)) ++ if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn)) + { + entry_present_value_to_deleted_value(a,valuestoupdate[i]); + } + } +- valuestoupdate[i]->v_csnset = NULL; +- } ++ csnset_free(&valuestoupdate[i]->v_csnset); ++ } + } + } + +diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c +index 7eabb82..50c0e52 100644 +--- a/ldap/servers/slapd/valueset.c ++++ b/ldap/servers/slapd/valueset.c +@@ -1416,6 +1416,7 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a, + { + value_update_csn(v,t,csn); + if (csnref_updated) { ++ csnset_free(&valuestoupdate[i]->v_csnset); + valuestoupdate[i]->v_csnset = csnset_dup(value_get_csnset(v)); + } + valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]); +-- +1.9.3 + diff --git a/SOURCES/0057-Ticket-47989-Windows-Sync-accidentally-cleared-raw_e.patch b/SOURCES/0057-Ticket-47989-Windows-Sync-accidentally-cleared-raw_e.patch deleted file mode 100644 index c36f08e..0000000 --- a/SOURCES/0057-Ticket-47989-Windows-Sync-accidentally-cleared-raw_e.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 5907e7902b3d586d6ce534c542728bd9d153f575 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Fri, 16 Jan 2015 16:28:06 -0800 -Subject: [PATCH 57/59] Ticket #47989 - Windows Sync accidentally cleared - raw_entry - -Description: raw_entry in the private area in Windows Agreement stores -raw_entry that is un-schema processed last entry read from AD. -The pointer was cleared before it is being accessed by the Plug-ins that -call Windows Sync API, e.g., Posix Sync. The bug was introduced by -commit f6397113666f06848412bb12f754f04258cfa5fa. - -This patch removed the raw_entry cleanup code in windows_search_entry_ext. -And in case the raw_entry is NULL, pass remote_entry for the AD entry. - -https://fedorahosted.org/389/ticket/47989 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 3305a6b849f79a9684799bec4cc155c7147daea6) -(cherry picked from commit f6d8b2ec3dee5760826892f522c0f1e1989f9fcb) ---- - ldap/servers/plugins/replication/windows_connection.c | 4 ---- - ldap/servers/plugins/replication/windows_protocol_util.c | 8 ++++++-- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c -index e78c367..317386b 100644 ---- a/ldap/servers/plugins/replication/windows_connection.c -+++ b/ldap/servers/plugins/replication/windows_connection.c -@@ -814,10 +814,6 @@ next: - slapi_ch_free_string(&filter_copy); - ldap_controls_free(serverctrls_copy); - serverctrls_copy = NULL; -- -- /* clear it here in case the search fails and -- we are left with a bogus old entry */ -- windows_private_set_raw_entry(conn->agmt, NULL); - conn->last_ldap_error = ldap_rc; - if (NULL != res) - { -diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c -index c424590..dabc936 100644 ---- a/ldap/servers/plugins/replication/windows_protocol_util.c -+++ b/ldap/servers/plugins/replication/windows_protocol_util.c -@@ -1689,7 +1689,9 @@ windows_replay_update(Private_Repl_Protocol *prp, slapi_operation_parameters *op - windows_map_mods_for_replay(prp,op->p.p_modify.modify_mods, &mapped_mods, is_user, &password); - if (is_user) { - winsync_plugin_call_pre_ad_mod_user_mods_cb(prp->agmt, -- windows_private_get_raw_entry(prp->agmt), -+ windows_private_get_raw_entry(prp->agmt)? -+ windows_private_get_raw_entry(prp->agmt): -+ remote_entry, - local_dn, - local_entry, - op->p.p_modify.modify_mods, -@@ -1697,7 +1699,9 @@ windows_replay_update(Private_Repl_Protocol *prp, slapi_operation_parameters *op - &mapped_mods); - } else if (is_group) { - winsync_plugin_call_pre_ad_mod_group_mods_cb(prp->agmt, -- windows_private_get_raw_entry(prp->agmt), -+ windows_private_get_raw_entry(prp->agmt)? -+ windows_private_get_raw_entry(prp->agmt): -+ remote_entry, - local_dn, - local_entry, - op->p.p_modify.modify_mods, --- -1.9.3 - diff --git a/SOURCES/0057-Ticket-48266-Fractional-replication-evaluates-severa.patch b/SOURCES/0057-Ticket-48266-Fractional-replication-evaluates-severa.patch new file mode 100644 index 0000000..35347f1 --- /dev/null +++ b/SOURCES/0057-Ticket-48266-Fractional-replication-evaluates-severa.patch @@ -0,0 +1,335 @@ +From 05e127c89281cece8bc1fa79bac6b95cc23dcca9 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 11 Sep 2015 18:56:53 +0200 +Subject: [PATCH 57/61] Ticket 48266: Fractional replication evaluates several + times the same CSN + +Bug Description: + In fractional replication if there are only skipped updates and many of them, the supplier + acquire the replica for a long time. At the end of the session, RUV is not updated + so the next session will restart evaluating the same skipped updates + +Fix Description: + The fix introduces subentries under the suffix: 'cn=repl keep alive ,$SUFFIX' + During an incremental replication session, if the session only contains skipped updates + and the number of them overpass a threshold (100), it triggers an update on that subentry. + + This update will eventually be replicated, moving forward the RUV + +https://fedorahosted.org/389/ticket/48266 + +Reviewed by: Noriko Hosoi, Rich Megginson, Simon Pichugin + +Platforms tested: + +Flag Day: no + +Doc impact: no + +(cherry picked from commit 6343e4cba17802e19daa5c971120fa352ff80ad4) +--- + ldap/servers/plugins/replication/repl5.h | 2 + + .../plugins/replication/repl5_inc_protocol.c | 39 ++++++ + ldap/servers/plugins/replication/repl5_replica.c | 156 +++++++++++++++++++++ + .../plugins/replication/repl5_tot_protocol.c | 13 +- + 4 files changed, 209 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 0b0f26b..17282bb 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -523,6 +523,8 @@ Replica *windows_replica_new(const Slapi_DN *root); + during addition of the replica over LDAP */ + Replica *replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation); + void replica_destroy(void **arg); ++int replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid); ++int replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid); + PRBool replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opid, + const char *locking_purl, + char **current_purl); +diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c +index 216de3c..e0599e5 100644 +--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c +@@ -1672,6 +1672,11 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + int finished = 0; + ConnResult replay_crc; + char csn_str[CSN_STRSIZE]; ++ PRBool subentry_update_sent = PR_FALSE; ++ PRBool subentry_update_needed = PR_FALSE; ++ int skipped_updates = 0; ++ int fractional_repl; ++#define FRACTIONAL_SKIPPED_THRESHOLD 100 + + /* Start the results reading thread */ + rd = repl5_inc_rd_new(prp); +@@ -1688,6 +1693,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + + memset ( (void*)&op, 0, sizeof (op) ); + entry.op = &op; ++ fractional_repl = agmt_is_fractional(prp->agmt); + do { + cl5_operation_parameters_done ( entry.op ); + memset ( (void*)entry.op, 0, sizeof (op) ); +@@ -1783,6 +1789,15 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + csn_as_string(entry.op->csn, PR_FALSE, csn_str); + replica_id = csn_get_replicaid(entry.op->csn); + uniqueid = entry.op->target_address.uniqueid; ++ ++ if (fractional_repl && message_id) ++ { ++ /* This update was sent no need to update the subentry ++ * and restart counting the skipped updates ++ */ ++ subentry_update_needed = PR_FALSE; ++ skipped_updates = 0; ++ } + + if (prp->repl50consumer && message_id) + { +@@ -1813,6 +1828,16 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + agmt_get_long_name(prp->agmt), + entry.op->target_address.uniqueid, csn_str); + agmt_inc_last_update_changecount (prp->agmt, csn_get_replicaid(entry.op->csn), 1 /*skipped*/); ++ if (fractional_repl) ++ { ++ skipped_updates++; ++ if (skipped_updates > FRACTIONAL_SKIPPED_THRESHOLD) { ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, ++ "%s: skipped updates is too high (%d) if no other update is sent we will update the subentry\n", ++ agmt_get_long_name(prp->agmt), skipped_updates); ++ subentry_update_needed = PR_TRUE; ++ } ++ } + } + } + break; +@@ -1878,6 +1903,20 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + PR_Unlock(rd->lock); + } while (!finished); + ++ if (fractional_repl && subentry_update_needed) ++ { ++ Replica *replica; ++ ReplicaId rid = -1; /* Used to create the replica keep alive subentry */ ++ replica = (Replica*) object_get_data(prp->replica_object); ++ if (replica) ++ { ++ rid = replica_get_rid(replica); ++ } ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, ++ "%s: skipped updates was definitely too high (%d) update the subentry now\n", ++ agmt_get_long_name(prp->agmt), skipped_updates); ++ replica_subentry_update(agmt_get_replarea(prp->agmt), rid); ++ } + /* Terminate the results reading thread */ + if (!prp->repl50consumer) + { +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 92b4e96..6ac28c1 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -414,6 +414,161 @@ replica_destroy(void **arg) + slapi_ch_free((void **)arg); + } + ++#define KEEP_ALIVE_ATTR "keepalivetimestamp" ++#define KEEP_ALIVE_ENTRY "repl keep alive" ++#define KEEP_ALIVE_DN_FORMAT "cn=%s %d,%s" ++ ++ ++static int ++replica_subentry_create(Slapi_DN *repl_root, ReplicaId rid) ++{ ++ char *entry_string = NULL; ++ Slapi_Entry *e = NULL; ++ Slapi_PBlock *pb = NULL; ++ int return_value; ++ int rc = 0; ++ ++ entry_string = slapi_ch_smprintf("dn: cn=%s %d,%s\nobjectclass: top\nobjectclass: ldapsubentry\nobjectclass: extensibleObject\ncn: %s %d", ++ KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root), KEEP_ALIVE_ENTRY, rid); ++ if (entry_string == NULL) { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, ++ "replica_subentry_create add failed in slapi_ch_smprintf\n"); ++ rc = -1; ++ goto done; ++ } ++ ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "add %s\n", entry_string); ++ e = slapi_str2entry(entry_string, 0); ++ ++ /* create the entry */ ++ pb = slapi_pblock_new(); ++ ++ ++ slapi_add_entry_internal_set_pb(pb, e, NULL, /* controls */ ++ repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0 /* flags */); ++ slapi_add_internal_pb(pb); ++ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value); ++ if (return_value != LDAP_SUCCESS && return_value != LDAP_ALREADY_EXISTS) ++ { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Warning: unable to " ++ "create replication keep alive entry %s: %s\n", slapi_entry_get_dn_const(e), ++ ldap_err2string(return_value)); ++ rc = -1; ++ slapi_entry_free(e); /* The entry was not consumed */ ++ goto done; ++ } ++ ++done: ++ ++ slapi_pblock_destroy(pb); ++ slapi_ch_free_string(&entry_string); ++ return rc; ++ ++} ++ ++int ++replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid) ++{ ++ Slapi_PBlock *pb; ++ char *filter = NULL; ++ Slapi_Entry **entries = NULL; ++ int res; ++ int rc = 0; ++ ++ pb = slapi_pblock_new(); ++ filter = slapi_ch_smprintf("(&(objectclass=ldapsubentry)(cn=%s %d))", KEEP_ALIVE_ENTRY, rid); ++ slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(repl_root), LDAP_SCOPE_ONELEVEL, ++ filter, NULL, 0, NULL, NULL, ++ repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0); ++ slapi_search_internal_pb(pb); ++ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &res); ++ if (res == LDAP_SUCCESS) ++ { ++ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); ++ if (entries && (entries[0] == NULL)) ++ { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, ++ "Need to create replication keep alive entry \n", KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root)); ++ rc = replica_subentry_create(repl_root, rid); ++ } else { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, ++ "replication keep alive entry already exists\n", KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root)); ++ rc = 0; ++ } ++ } else { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, ++ "Error accessing replication keep alive entry res=%d\n", ++ KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root), res); ++ /* The status of the entry is not clear, do not attempt to create it */ ++ rc = 1; ++ } ++ slapi_free_search_results_internal(pb); ++ ++ slapi_pblock_destroy(pb); ++ slapi_ch_free_string(&filter); ++ return rc; ++} ++ ++int ++replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid) ++{ ++ int ldrc; ++ int rc = LDAP_SUCCESS; /* Optimistic default */ ++ LDAPMod * mods[2]; ++ LDAPMod mod; ++ struct berval * vals[2]; ++ char buf[20]; ++ time_t curtime; ++ struct tm ltm; ++ struct berval val; ++ Slapi_PBlock *modpb = NULL; ++ char *dn; ++ ++ replica_subentry_check(repl_root, rid); ++ curtime = current_time(); ++ gmtime_r(&curtime, <m); ++ strftime(buf, sizeof (buf), "%Y%m%d%H%M%SZ", <m); ++ ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "subentry_update called at %s\n", buf); ++ ++ ++ val.bv_val = buf; ++ val.bv_len = strlen(val.bv_val); ++ ++ vals [0] = &val; ++ vals [1] = NULL; ++ ++ mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES; ++ mod.mod_type = KEEP_ALIVE_ATTR; ++ mod.mod_bvalues = vals; ++ ++ mods[0] = &mod; ++ mods[1] = NULL; ++ ++ modpb = slapi_pblock_new(); ++ dn = slapi_ch_smprintf(KEEP_ALIVE_DN_FORMAT, KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root)); ++ ++ slapi_modify_internal_set_pb(modpb, dn, mods, NULL, NULL, ++ repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0); ++ slapi_modify_internal_pb(modpb); ++ ++ slapi_pblock_get(modpb, SLAPI_PLUGIN_INTOP_RESULT, &ldrc); ++ ++ if (ldrc != LDAP_SUCCESS) ++ { ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, ++ "Failure (%d) to update replication keep alive entry \"%s: %s\"\n", ldrc, KEEP_ALIVE_ATTR, buf); ++ rc = ldrc; ++ } else { ++ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, ++ "Successful update of replication keep alive entry \"%s: %s\"\n", KEEP_ALIVE_ATTR, buf); ++ } ++ ++ slapi_pblock_destroy(modpb); ++ slapi_ch_free_string(&dn); ++ return rc; ++ ++} + /* + * Attempt to obtain exclusive access to replica (advisory only) + * +@@ -3816,6 +3971,7 @@ replica_enable_replication (Replica *r) + /* What to do ? */ + } + ++ replica_subentry_check(r->repl_root, replica_get_rid(r)); + /* Replica came back online, Check if the total update was terminated. + If flag is still set, it was not terminated, therefore the data is + very likely to be incorrect, and we should not restart Replication threads... +diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c +index d9401cf..e004af4 100644 +--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c +@@ -318,6 +318,9 @@ repl5_tot_run(Private_Repl_Protocol *prp) + int portnum = 0; + Slapi_DN *area_sdn = NULL; + CSN *remote_schema_csn = NULL; ++ int init_retry = 0; ++ Replica *replica; ++ ReplicaId rid = 0; /* Used to create the replica keep alive subentry */ + + PR_ASSERT(NULL != prp); + +@@ -395,7 +398,15 @@ repl5_tot_run(Private_Repl_Protocol *prp) + ctrls = (LDAPControl **)slapi_ch_calloc (3, sizeof (LDAPControl *)); + ctrls[0] = create_managedsait_control (); + ctrls[1] = create_backend_control(area_sdn); +- ++ ++ /* Time to make sure it exists a keep alive subentry for that replica */ ++ replica = (Replica*) object_get_data(prp->replica_object); ++ if (replica) ++ { ++ rid = replica_get_rid(replica); ++ } ++ replica_subentry_check(area_sdn, rid); ++ + slapi_search_internal_set_pb (pb, slapi_sdn_get_dn (area_sdn), + LDAP_SCOPE_SUBTREE, "(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))", NULL, 0, ctrls, NULL, + repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0); +-- +1.9.3 + diff --git a/SOURCES/0058-Ticket-47991-upgrade-script-fails-if-etc-and-var-are.patch b/SOURCES/0058-Ticket-47991-upgrade-script-fails-if-etc-and-var-are.patch deleted file mode 100644 index 11bd5af..0000000 --- a/SOURCES/0058-Ticket-47991-upgrade-script-fails-if-etc-and-var-are.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 454afeaa481ee389dadc7ce62a53e6f0ff4952b1 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Tue, 20 Jan 2015 10:34:41 +0100 -Subject: [PATCH 58/59] Ticket 47991 - upgrade script fails if /etc and /var - are on different file systems - -Bug Description: the script to upgrade configfiles creates a backup dir in /var - and tries to move files fro /etc to this backup dir - using the perl rename function. - this fails if /etc and /var are different fiel systems - -Fix Description: create the backup dir also in /etc - -https://fedorahosted.org/389/ticket/47991 - -Reviewed by: Mark, Thanks - -(cherry picked from commit 96850932c054edcc477d070cf619006344b1d443) ---- - ldap/admin/src/scripts/60upgradeconfigfiles.pl | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/admin/src/scripts/60upgradeconfigfiles.pl b/ldap/admin/src/scripts/60upgradeconfigfiles.pl -index 4b37353..189eb03 100644 ---- a/ldap/admin/src/scripts/60upgradeconfigfiles.pl -+++ b/ldap/admin/src/scripts/60upgradeconfigfiles.pl -@@ -16,7 +16,7 @@ sub runinst { - # make a backup directory to store the deleted config file, then - # don't really delete it, just move it to that directory - my $mode = (stat($inf->{slapd}->{config_dir}))[2]; -- my $bakdir = $inf->{slapd}->{bak_dir} . ".bak"; -+ my $bakdir = $inf->{slapd}->{config_dir} . "/bak" ; - if (! -d $bakdir) { - $! = 0; # clear - mkdir $bakdir, $mode; --- -1.9.3 - diff --git a/SOURCES/0058-Ticket-48266-coverity-issue.patch b/SOURCES/0058-Ticket-48266-coverity-issue.patch new file mode 100644 index 0000000..7cbc726 --- /dev/null +++ b/SOURCES/0058-Ticket-48266-coverity-issue.patch @@ -0,0 +1,25 @@ +From 25fa7a078549404141f1fd36b277a857a615df83 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 18 Sep 2015 18:38:19 +0200 +Subject: [PATCH 58/61] Ticket 48266: coverity issue + +(cherry picked from commit 8cd4f45a9621dfaea7249179919b783857c9f22c) +--- + ldap/servers/plugins/replication/repl5_inc_protocol.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c +index e0599e5..7680340 100644 +--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c +@@ -1672,7 +1672,6 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + int finished = 0; + ConnResult replay_crc; + char csn_str[CSN_STRSIZE]; +- PRBool subentry_update_sent = PR_FALSE; + PRBool subentry_update_needed = PR_FALSE; + int skipped_updates = 0; + int fractional_repl; +-- +1.9.3 + diff --git a/SOURCES/0059-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch b/SOURCES/0059-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch deleted file mode 100644 index 9dec1bf..0000000 --- a/SOURCES/0059-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch +++ /dev/null @@ -1,628 +0,0 @@ -From e68a455c1191bfc597d95ce1f6326a9f6397c39d Mon Sep 17 00:00:00 2001 -From: "Thierry bordaz (tbordaz)" -Date: Thu, 22 Jan 2015 14:29:52 +0100 -Subject: [PATCH 59/59] Ticket 47988: Schema learning mechanism, in - replication, unable to extend an existing definition - -Bug Description: - At the beginning of a replication session, a supplier checks the status of remote schema vs - its own schema. If the remote schema contains new/extended definitions, the supplier learns - those definitions. - It learns through internal MOD_ADD operation on cn=schema. - For extending definition, this fails because the definition already exists. - -Fix Description: - It needs to MOD_DEL and MOD_ADD those extended definitions while it needs to do MOD_ADD for new definitions. - It uses the field 'old_value' in 'struct schema_mods_indexes' to determine if it needs to del some definitions. - Some definitions can not be deleted - - if an objectclass is standard or is a superior of others oc - - if an attribute is a standard definition or is used in objectclass - This was problematic for updating the schema, so the fix is relaxing those controls for - internal operations - -https://fedorahosted.org/389/ticket/47988 - -Reviewed by: ? - -Platforms tested: F17 - -Flag Day: no - -Doc impact: no - -(cherry picked from commit 51e05df9c37c66206041f026c9a67ec17bc9ea4a) -(cherry picked from commit 107316806d291e584028e278c9ce1e0e99ff5617) ---- - .../servers/plugins/replication/repl5_connection.c | 17 + - ldap/servers/slapd/schema.c | 365 ++++++++++++++++----- - 2 files changed, 309 insertions(+), 73 deletions(-) - -diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c -index 2971025..eddcae8 100644 ---- a/ldap/servers/plugins/replication/repl5_connection.c -+++ b/ldap/servers/plugins/replication/repl5_connection.c -@@ -1779,6 +1779,7 @@ conn_push_schema(Repl_Connection *conn, CSN **remotecsn) - CSN *localcsn = NULL; - Slapi_PBlock *spb = NULL; - char localcsnstr[CSN_STRSIZE + 1] = {0}; -+ char remotecnsstr[CSN_STRSIZE+1] = {0}; - - if (!remotecsn) - { -@@ -1807,6 +1808,16 @@ conn_push_schema(Repl_Connection *conn, CSN **remotecsn) - } - else - { -+ if (*remotecsn) { -+ csn_as_string (*remotecsn, PR_FALSE, remotecnsstr); -+ csn_as_string (localcsn, PR_FALSE, localcsnstr); -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, -+ "[S] Checking consumer schema localcsn:%s / remotecsn:%s\n", localcsnstr, remotecnsstr); -+ } else { -+ csn_as_string (localcsn, PR_FALSE, localcsnstr); -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, -+ "[S] Checking consumer schema localcsn:%s / remotecsn:NULL\n", localcsnstr); -+ } - if (!update_consumer_schema(conn)) { - /* At least one schema definition (attributetypes/objectclasses) of the consumer - * is a superset of the supplier. -@@ -1815,7 +1826,11 @@ conn_push_schema(Repl_Connection *conn, CSN **remotecsn) - * So it could be possible that a second attempt (right now) of update_consumer_schema - * would be successful - */ -+ slapi_log_error(SLAPI_LOG_REPL, "schema", -+ "[S] schema definitions may have been learned\n"); - if (!update_consumer_schema(conn)) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", -+ "[S] learned definitions are not suffisant to try to push the schema \n"); - return_value = CONN_OPERATION_FAILED; - } - } -@@ -1831,6 +1846,8 @@ conn_push_schema(Repl_Connection *conn, CSN **remotecsn) - memcpy(remotecsnstr, remote_schema_csn_bervals[0]->bv_val, - remote_schema_csn_bervals[0]->bv_len); - remotecsnstr[remote_schema_csn_bervals[0]->bv_len] = '\0'; -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, -+ "[S] Reread remotecsn:%s\n", remotecsnstr); - *remotecsn = csn_new_by_string(remotecsnstr); - if (*remotecsn && (csn_compare(localcsn, *remotecsn) <= 0)) { - return_value = CONN_SCHEMA_NO_UPDATE_NEEDED; -diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c -index 8744a6d..05329a6 100644 ---- a/ldap/servers/slapd/schema.c -+++ b/ldap/servers/slapd/schema.c -@@ -139,6 +139,7 @@ typedef struct repl_schema_policy { - struct schema_mods_indexes { - int index; - char *new_value; -+ char *old_value; - struct schema_mods_indexes *next; - }; - -@@ -155,9 +156,9 @@ static int oc_check_required(Slapi_PBlock *, Slapi_Entry *,struct objclass *); - static int oc_check_allowed_sv(Slapi_PBlock *, Slapi_Entry *e, const char *type, struct objclass **oclist ); - static int schema_delete_objectclasses ( Slapi_Entry *entryBefore, - LDAPMod *mod, char *errorbuf, size_t errorbufsize, -- int schema_ds4x_compat ); -+ int schema_ds4x_compat, int is_internal_operation); - static int schema_delete_attributes ( Slapi_Entry *entryBefore, -- LDAPMod *mod, char *errorbuf, size_t errorbufsize); -+ LDAPMod *mod, char *errorbuf, size_t errorbufsize, int is_internal_operation); - static int schema_add_attribute ( Slapi_PBlock *pb, LDAPMod *mod, - char *errorbuf, size_t errorbufsize, int schema_ds4x_compat ); - static int schema_add_objectclass ( Slapi_PBlock *pb, LDAPMod *mod, -@@ -2074,7 +2075,9 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr - int schema_modify_enabled = config_get_schemamod(); - int reapply_mods = 0; - int is_replicated_operation = 0; -- -+ int is_internal_operation = 0; -+ Slapi_Operation *operation = NULL; -+ - if (!schema_modify_enabled) { - *returncode = LDAP_UNWILLING_TO_PERFORM; - schema_create_errormsg( returntext, SLAPI_DSE_RETURNTEXT_SIZE, -@@ -2085,6 +2088,8 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr - - slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ); - slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation); -+ slapi_pblock_get( pb, SLAPI_OPERATION, &operation); -+ is_internal_operation = slapi_operation_is_flag_set(operation, SLAPI_OP_FLAG_INTERNAL); - - /* In case we receive a schema from a supplier, check if we can accept it - * (it is a superset of our own schema). -@@ -2153,11 +2158,11 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr - if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op)) { - if (strcasecmp (mods[i]->mod_type, "objectclasses") == 0) { - *returncode = schema_delete_objectclasses (entryBefore, mods[i], -- returntext, SLAPI_DSE_RETURNTEXT_SIZE, schema_ds4x_compat ); -+ returntext, SLAPI_DSE_RETURNTEXT_SIZE, schema_ds4x_compat, is_internal_operation); - } - else if (strcasecmp (mods[i]->mod_type, "attributetypes") == 0) { - *returncode = schema_delete_attributes (entryBefore, mods[i], -- returntext, SLAPI_DSE_RETURNTEXT_SIZE ); -+ returntext, SLAPI_DSE_RETURNTEXT_SIZE, is_internal_operation); - } - else { - *returncode= LDAP_NO_SUCH_ATTRIBUTE; -@@ -2196,6 +2201,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr - schema_create_errormsg( returntext, SLAPI_DSE_RETURNTEXT_SIZE, - schema_errprefix_generic, mods[i]->mod_type, - "Replace is not allowed on the subschema subentry" ); -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "modify_schema_dse: Replace is not allowed on the subschema subentry\n"); - rc = SLAPI_DSE_CALLBACK_ERROR; - } else { - if (strcasecmp (mods[i]->mod_type, "attributetypes") == 0) { -@@ -2264,7 +2270,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr - * Add a new objectclass - */ - *returncode = schema_add_objectclass ( pb, mods[i], returntext, -- SLAPI_DSE_RETURNTEXT_SIZE, schema_ds4x_compat ); -+ SLAPI_DSE_RETURNTEXT_SIZE, schema_ds4x_compat); - } - else { - if ( schema_ds4x_compat ) { -@@ -2465,16 +2471,20 @@ oc_add_nolock(struct objclass *newoc) - */ - static int - schema_delete_objectclasses( Slapi_Entry *entryBefore, LDAPMod *mod, -- char *errorbuf, size_t errorbufsize, int schema_ds4x_compat ) -+ char *errorbuf, size_t errorbufsize, int schema_ds4x_compat, int is_internal_operation) - { - int i; - int rc = LDAP_SUCCESS; /* optimistic */ - struct objclass *poc, *poc2, *delete_oc = NULL; - - if ( NULL == mod->mod_bvalues ) { -- schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc, -- NULL, "Cannot remove all schema object classes" ); -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_objectclasses: Remove all objectclass in Internal op\n"); -+ } else { -+ schema_create_errormsg(errorbuf, errorbufsize, schema_errprefix_oc, -+ NULL, "Cannot remove all schema object classes"); - return LDAP_UNWILLING_TO_PERFORM; -+ } - } - - for (i = 0; mod->mod_bvalues[i]; i++) { -@@ -2492,11 +2502,19 @@ schema_delete_objectclasses( Slapi_Entry *entryBefore, LDAPMod *mod, - for (poc2 = g_get_global_oc_nolock(); poc2 != NULL; poc2 = poc2->oc_next) { - if (poc2->oc_superior && - (strcasecmp (poc2->oc_superior, delete_oc->oc_name) == 0)) { -- schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc, -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_objectclasses: Should not delete object class (%s) which has child object classes" -+ ". But accept it because it is internal operation\n", -+ delete_oc->oc_name); -+ } else { -+ schema_create_errormsg(errorbuf, errorbufsize, schema_errprefix_oc, - delete_oc->oc_name, "Cannot delete an object class" -- " which has child object classes" ); -- rc = LDAP_UNWILLING_TO_PERFORM; -- goto unlock_and_return; -+ " which has child object classes"); -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_objectclasses: Cannot delete an object class (%s) which has child object classes\n", -+ delete_oc->oc_name); -+ rc = LDAP_UNWILLING_TO_PERFORM; -+ goto unlock_and_return; -+ } - } - } - -@@ -2505,10 +2523,19 @@ schema_delete_objectclasses( Slapi_Entry *entryBefore, LDAPMod *mod, - } - - else { -- schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc, -- delete_oc->oc_name, "Cannot delete a standard object class" ); -- rc = LDAP_UNWILLING_TO_PERFORM; -- goto unlock_and_return; -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_objectclasses: Should not delete a standard object class (%s)" -+ ". But accept it because it is internal operation\n", -+ delete_oc->oc_name); -+ oc_delete_nolock (poc->oc_name); -+ } else { -+ schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc, -+ delete_oc->oc_name, "Cannot delete a standard object class" ); -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_objectclasses: Cannot delete a standard object class (%s)\n", -+ delete_oc->oc_name); -+ rc = LDAP_UNWILLING_TO_PERFORM; -+ goto unlock_and_return; -+ } - } - } - else { -@@ -2552,7 +2579,7 @@ schema_return(int rc,struct sizedbuffer * psb1,struct sizedbuffer *psb2,struct s - */ - static int - schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod, -- char *errorbuf, size_t errorbufsize) -+ char *errorbuf, size_t errorbufsize, int is_internal_operation) - { - char *attr_ldif, *oc_list_type = ""; - asyntaxinfo *a; -@@ -2563,10 +2590,14 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod, - struct sizedbuffer *psbAttrSyntax= sizedbuffer_construct(BUFSIZ); - - if (NULL == mod->mod_bvalues) { -- schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at, -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_attributes: Remove all attributetypes in Internal op\n"); -+ } else { -+ schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at, - NULL, "Cannot remove all schema attribute types" ); -- return schema_return(LDAP_UNWILLING_TO_PERFORM,psbAttrOid,psbAttrName, -+ return schema_return(LDAP_UNWILLING_TO_PERFORM,psbAttrOid,psbAttrName, - psbAttrSyntax,NULL); -+ } - } - - for (i = 0; mod->mod_bvalues[i]; i++) { -@@ -2592,12 +2623,20 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod, - if ((a = attr_syntax_get_by_name ( psbAttrName->buffer)) != NULL ) { - /* only modify attrs which were user defined */ - if (a->asi_flags & SLAPI_ATTR_FLAG_STD_ATTR) { -- schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at, -- psbAttrName->buffer, -- "Cannot delete a standard attribute type" ); -- attr_syntax_return( a ); -- return schema_return(LDAP_UNWILLING_TO_PERFORM,psbAttrOid,psbAttrName, -- psbAttrSyntax,NULL); -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_attributes: Should not delete a standard attribute type (%s)" -+ ". But accept it because it is internal operation\n", -+ psbAttrName->buffer); -+ } else { -+ schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at, -+ psbAttrName->buffer, -+ "Cannot delete a standard attribute type"); -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_attributes: Cannot delete a standard attribute type (%s)\n", -+ psbAttrName->buffer); -+ attr_syntax_return(a); -+ return schema_return(LDAP_UNWILLING_TO_PERFORM, psbAttrOid, psbAttrName, -+ psbAttrSyntax, NULL); -+ } - } - - /* Do not allow deletion if referenced by an object class. */ -@@ -2627,17 +2666,32 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod, - } - - if (attr_in_use_by_an_oc) { -- schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at, -- psbAttrName->buffer, "Is included in the %s list for object class %s. Cannot delete.", -- oc_list_type, oc->oc_name ); -- break; -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_attributes: Should not delete an attribute (%s) used in oc (%s)" -+ ". But accept it because it is internal operation\n", -+ oc_list_type, oc->oc_name); -+ } else { -+ schema_create_errormsg(errorbuf, errorbufsize, schema_errprefix_at, -+ psbAttrName->buffer, "Is included in the %s list for object class %s. Cannot delete.", -+ oc_list_type, oc->oc_name); -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_attributes: Could delete an attribute (%s) used in oc (%s)" -+ ". But accept it because it is internal operation\n", -+ oc_list_type, oc->oc_name); -+ break; -+ } - } - } - oc_unlock(); - if (attr_in_use_by_an_oc) { -- attr_syntax_return( a ); -- return schema_return(LDAP_UNWILLING_TO_PERFORM,psbAttrOid,psbAttrName, -- psbAttrSyntax,NULL); -+ if (is_internal_operation) { -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_delete_attributes: Should not delete an attribute used in oc" -+ ". But accept it because it is internal operation\n"); -+ -+ } else { -+ attr_syntax_return(a); -+ return schema_return(LDAP_UNWILLING_TO_PERFORM, psbAttrOid, psbAttrName, -+ psbAttrSyntax, NULL); -+ } - } - - /* Delete it. */ -@@ -2744,7 +2798,10 @@ add_oc_internal(struct objclass *pnew_oc, char *errorbuf, size_t errorbufsize, - } - } - -- /* check to see if the superior oc exists */ -+ /* check to see if the superior oc exists -+ * This is not enforced for internal op (when learning new schema -+ * definitions from a replication session) -+ */ - if (!rc && pnew_oc->oc_superior && - ((psup_oc = oc_find_nolock (pnew_oc->oc_superior, NULL, PR_FALSE)) == NULL)) { - schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc, -@@ -2798,7 +2855,10 @@ add_oc_internal(struct objclass *pnew_oc, char *errorbuf, size_t errorbufsize, - sizedbuffer_destroy(psbOcOid); - } - -- /* check to see if the oc's attributes are valid */ -+ /* check to see if the oc's attributes are valid -+ * This is not checked if this is an internal operation (learning schema -+ * definitions from a replication session) -+ */ - if (!rc && !(flags & DSE_SCHEMA_NO_CHECK) && - schema_check_oc_attrs ( pnew_oc, errorbuf, errorbufsize, - 0 /* don't strip options */ ) == 0 ) { -@@ -6265,11 +6325,101 @@ schema_oc_superset_check(struct objclass *oc_list1, struct objclass *oc_list2, c - - return rc; - } -+ -+static char * -+schema_oc_to_string(struct objclass *oc) -+{ -+ char *oc_str; -+ int i; -+ int size = 0; -+ -+ /* Compute the size of the string that can contain -+ * the oc definition and allocates it -+ */ -+ if (oc->oc_oid) size += strlen(oc->oc_oid); -+ if (oc->oc_name) size += strlen(oc->oc_name); -+ if (oc->oc_desc) size += strlen(oc->oc_desc); -+ if (oc->oc_orig_required) { -+ for (i =0; oc->oc_orig_required[i] != NULL; i++) { -+ size += strlen(oc->oc_orig_required[i]); -+ size += 3; -+ } -+ } -+ if (oc->oc_orig_allowed) { -+ for (i =0; oc->oc_orig_allowed[i] != NULL; i++) { -+ size += strlen(oc->oc_orig_allowed[i]); -+ size += 3; -+ } -+ } -+ size += strlen(schema_oc_kind_strings_with_spaces[oc->oc_kind]); -+ -+ size += 128; /* for all keywords: NAME, DESC, SUP... */ -+ if ((oc_str = (char *) slapi_ch_calloc(1, size)) == NULL) { -+ return NULL; -+ } -+ -+ /* OID + name */ -+ sprintf(oc_str, "( %s NAME '%s'", (oc->oc_oid) ? oc->oc_oid : "", oc->oc_name); -+ -+ /* description */ -+ strcat(oc_str, " DESC '"); -+ if (oc->oc_desc) { -+ strcat(oc_str, oc->oc_desc); -+ } -+ strcat(oc_str, "'"); -+ -+ /* SUP */ -+ if (oc->oc_superior) { -+ strcat(oc_str, " SUP '"); -+ strcat(oc_str, oc->oc_superior); -+ strcat(oc_str, "'"); -+ } -+ -+ /* oc_kind */ -+ strcat(oc_str, schema_oc_kind_strings_with_spaces[oc->oc_kind]); -+ -+ /* MUST */ -+ if (oc->oc_orig_required) { -+ strcat(oc_str, " MUST ( "); -+ for ( i = 0; oc->oc_orig_required[i] != NULL; ++i ) { -+ if (i > 0) { -+ strcat(oc_str, " $ "); -+ } -+ strcat(oc_str, oc->oc_orig_required[i]); -+ } -+ strcat(oc_str, " ) "); -+ } -+ -+ /* MAY */ -+ if (oc->oc_orig_allowed) { -+ strcat(oc_str, " MAY ( "); -+ for ( i = 0; oc->oc_orig_allowed[i] != NULL; ++i ) { -+ if (i > 0) { -+ strcat(oc_str, " $ "); -+ } -+ strcat(oc_str, oc->oc_orig_allowed[i]); -+ } -+ strcat(oc_str, " ) "); -+ } -+ -+ /* flags */ -+ if (oc->oc_flags & OC_FLAG_USER_OC) { -+ strcat(oc_str, " X-ORIGIN 'blahblahblah'"); -+ } -+ -+ strcat(oc_str, " )"); -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "schema_oc_to_string: replace (old[%d]=%s)\n", -+ size, oc_str); -+ -+ return(oc_str); -+ -+} - /* call must hold oc_lock at least in read */ - static struct schema_mods_indexes * - schema_list_oc2learn(struct objclass *oc_remote_list, struct objclass *oc_local_list, int replica_role) { - struct objclass *oc_remote, *oc_local; - struct schema_mods_indexes *head = NULL, *mods_index; -+ struct schema_mods_indexes *tail = NULL; - int index = 0; - int repl_schema_policy; - const char *message; -@@ -6309,11 +6459,22 @@ schema_list_oc2learn(struct objclass *oc_remote_list, struct objclass *oc_local_ - continue; - } - -- /* insert it in the list */ -+ /* insert it at the end of the list -+ * to keep the order of the original schema -+ * For example superior oc should be declared first -+ */ - mods_index->index = index; -- mods_index->next = head; -+ mods_index->next = NULL; - mods_index->new_value = NULL; -- head = mods_index; -+ if (oc_local) { -+ mods_index->old_value = schema_oc_to_string(oc_local); -+ } -+ if (head == NULL) { -+ head = mods_index; -+ } else { -+ tail->next = mods_index; -+ } -+ tail = mods_index; - } - } - slapi_rwlock_unlock( schema_policy_lock ); -@@ -7173,17 +7334,27 @@ modify_schema_internal_mod(Slapi_DN *sdn, Slapi_Mods *smods) - /* do modify */ - slapi_modify_internal_pb (newpb); - slapi_pblock_get (newpb, SLAPI_PLUGIN_INTOP_RESULT, &op_result); -- if (op_result == LDAP_SUCCESS) { -- /* Update the schema csn if the operation succeeded */ -- schema_csn = csn_new(); -- if (NULL != schema_csn) { -- csn_set_replicaid(schema_csn, 0); -- csn_set_time(schema_csn, current_time()); -- g_set_global_schema_csn(schema_csn); -- } -- } -+ if (op_result == LDAP_SUCCESS) { -+ char *type; - -- slapi_pblock_destroy(newpb); -+ if (smods && smods->mods) { -+ type = smods->mods[0]->mod_type; -+ } else { -+ type = "unknown"; -+ } -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "modify_schema_internal_mod: successfully learn %s definitions\n", type); -+ /* Update the schema csn if the operation succeeded */ -+ schema_csn = csn_new(); -+ if (NULL != schema_csn) { -+ csn_set_replicaid(schema_csn, 0); -+ csn_set_time(schema_csn, current_time()); -+ g_set_global_schema_csn(schema_csn); -+ } -+ } else { -+ slapi_log_error(SLAPI_LOG_FATAL, "schema", "modify_schema_internal_mod: fail to learn schema definitions (%d) \n", op_result); -+ } -+ -+ slapi_pblock_destroy(newpb); - } - - /* Prepare slapi_mods for the internal mod -@@ -7191,32 +7362,80 @@ modify_schema_internal_mod(Slapi_DN *sdn, Slapi_Mods *smods) - */ - static void - modify_schema_prepare_mods(Slapi_Mods *smods, char *type, struct schema_mods_indexes *values) --{ -- struct schema_mods_indexes *object; -- struct berval *bv; -- struct berval **bvps; -- int nb_values, i; -- -- for (object = values, nb_values = 0; object != NULL; object = object->next, nb_values++); -- bvps = (struct berval **) slapi_ch_calloc(1, (nb_values + 1) * sizeof(struct berval *)); -- -- -+{ -+ struct schema_mods_indexes *object; -+ struct berval *bv; -+ struct berval **bvps_del = NULL; -+ struct berval **bvps_add = NULL; -+ int nb_values_del, nb_values_add, i; -+ int nb_mods; -+ -+ /* Checks the values to delete */ -+ for (object = values, nb_values_del = 0; object != NULL; object = object->next) { -+ if (object->old_value) { -+ nb_values_del++; -+ } -+ } -+ if (nb_values_del) { -+ bvps_del = (struct berval **) slapi_ch_calloc(1, (nb_values_del + 1) * sizeof (struct berval *)); -+ -+ for (i = 0, object = values; object != NULL; object = object->next) { -+ if (object->old_value) { -+ bv = (struct berval *) slapi_ch_malloc(sizeof (struct berval)); -+ bv->bv_len = strlen(object->old_value); -+ bv->bv_val = (void*) object->old_value; -+ bvps_del[i] = bv; -+ i++; -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "MOD[%d] del (%s): %s\n", i, type, object->old_value); -+ } -+ } -+ bvps_del[nb_values_del] = NULL; -+ } -+ -+ /* Checks the values to add */ -+ for (object = values, nb_values_add = 0; object != NULL; object = object->next, nb_values_add++); -+ -+ if (nb_values_add) { -+ bvps_add = (struct berval **) slapi_ch_calloc(1, (nb_values_add + 1) * sizeof (struct berval *)); -+ -+ - for (i = 0, object = values; object != NULL; i++, object = object->next) { -- bv = (struct berval *) slapi_ch_malloc(sizeof(struct berval)); -- bv->bv_len = strlen(object->new_value); -- bv->bv_val = (void*) object->new_value; -- bvps[i] = bv; -- slapi_log_error(SLAPI_LOG_REPL, "schema", "MOD[%d] add (%s): %s\n", i, type, object->new_value); -- } -- bvps[nb_values] = NULL; -- slapi_mods_init (smods, 2); -- slapi_mods_add_modbvps( smods, LDAP_MOD_ADD, type, bvps ); -- for (i = 0; bvps[i] != NULL; i++) { -- /* bv_val should not be free. It belongs to the incoming MOD */ -- slapi_ch_free((void **) &bvps[i]); -- } -- slapi_ch_free((void **) &bvps); -- -+ bv = (struct berval *) slapi_ch_malloc(sizeof (struct berval)); -+ bv->bv_len = strlen(object->new_value); -+ bv->bv_val = (void*) object->new_value; -+ bvps_add[i] = bv; -+ slapi_log_error(SLAPI_LOG_REPL, "schema", "MOD[%d] add (%s): %s\n", i, type, object->new_value); -+ } -+ bvps_add[nb_values_add] = NULL; -+ } -+ -+ /* Prepare the mods */ -+ nb_mods = 1; -+ if (bvps_del) nb_mods++; -+ if (bvps_add) nb_mods++; -+ slapi_mods_init(smods, nb_mods); -+ if (bvps_del) slapi_mods_add_modbvps(smods, LDAP_MOD_DELETE, type, bvps_del); -+ if (bvps_add) slapi_mods_add_modbvps(smods, LDAP_MOD_ADD, type, bvps_add); -+ -+ -+ /* clean up */ -+ if (bvps_del) { -+ -+ for (i = 0; bvps_del[i] != NULL; i++) { -+ /* bv_val should not be free. It belongs to the incoming MOD */ -+ slapi_ch_free((void **) &bvps_del[i]); -+ } -+ slapi_ch_free((void **) &bvps_del); -+ } -+ -+ if (bvps_add) { -+ -+ for (i = 0; bvps_add[i] != NULL; i++) { -+ /* bv_val should not be free. It belongs to the incoming MOD */ -+ slapi_ch_free((void **) &bvps_add[i]); -+ } -+ slapi_ch_free((void **) &bvps_add); -+ } - } - - /* called by modify_schema_dse/supplier_learn_new_definitions to learn new --- -1.9.3 - diff --git a/SOURCES/0059-Ticket-48217-cleanallruv-fix-regression-with-server-.patch b/SOURCES/0059-Ticket-48217-cleanallruv-fix-regression-with-server-.patch new file mode 100644 index 0000000..b6f97be --- /dev/null +++ b/SOURCES/0059-Ticket-48217-cleanallruv-fix-regression-with-server-.patch @@ -0,0 +1,67 @@ +From ac98944372376a0d41a33dfe84a99bfaa151699f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 18 Sep 2015 11:56:29 -0400 +Subject: [PATCH 59/61] Ticket 48217 - cleanallruv - fix regression with server + shutdown + +Bug Description: Recent checks for server shutdown were added to cleanallruv task, + but we did not properly check for "shutdown" at the end of the task. + This caused the server to think the task successfully finished, + when in fact it did not. + +Fix Description: Properly check for shutdown at the end of the task, and handler it + appropriately. + +https://fedorahosted.org/389/ticket/48217 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit c41d36de0ca438bf23e4e810bfec0fd59cbc790b) +(cherry picked from commit d9f03f5fddfc8ba7009c9dcc584686e43d6339e8) +--- + ldap/servers/plugins/replication/repl5_replica_config.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 446da3f..8d3c481 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -1948,7 +1948,7 @@ done: + /* + * If the replicas are cleaned, release the rid + */ +- if(!aborted){ ++ if(!aborted && !slapi_is_shutting_down()){ + delete_cleaned_rid_config(data); + /* make sure all the replicas have been "pre_cleaned" before finishing */ + check_replicas_are_done_cleaning(data); +@@ -3005,7 +3005,7 @@ replica_abort_task_thread(void *arg) + } + + /* +- * Now send the cleanruv extended op to all the agreements ++ * Now send the abort cleanruv extended op to all the agreements + */ + while(agmt_not_notified && !slapi_is_shutting_down()){ + agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica); +@@ -3013,7 +3013,7 @@ replica_abort_task_thread(void *arg) + agmt_not_notified = 0; + break; + } +- while (agmt_obj){ ++ while (agmt_obj && !slapi_is_shutting_down()){ + agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ + agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj); +@@ -3058,7 +3058,7 @@ replica_abort_task_thread(void *arg) + } /* while */ + + done: +- if(agmt_not_notified){ ++ if(agmt_not_notified || slapi_is_shutting_down()){ + /* failure */ + cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup."); + } else { +-- +1.9.3 + diff --git a/SOURCES/0060-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch b/SOURCES/0060-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch deleted file mode 100644 index ed0fc9c..0000000 --- a/SOURCES/0060-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 602e9ef126808491be5d33d9c4faa9c86e63730a Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Sun, 25 Jan 2015 22:05:12 -0800 -Subject: [PATCH] Ticket 47988: Schema learning mechanism, in replication, - unable to extend an existing definition - -Description: Covscan FORWARD_NULL fix introduced by commit -commit 51e05df9c37c66206041f026c9a67ec17bc9ea4a - -1. ldap/servers/slapd/schema.c:2490: var_deref_op: Dereferencing null pointer "mod->mod_vals.modv_bvals". -2. ldap/servers/slapd/schema.c:2603: var_deref_op: Dereferencing null pointer "mod->mod_vals.modv_bvals". - -Added NULL check on mod->mod_bvalues to the for loop stop condition. - -(cherry picked from commit cfa8e4daef9253df0bd8a348f302299bda16b37c) -(cherry picked from commit 1e2bf2b1ee6cd4c08a171edfedb10ee6bb1c3420) ---- - ldap/servers/slapd/schema.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c -index 05329a6..a251aa7 100644 ---- a/ldap/servers/slapd/schema.c -+++ b/ldap/servers/slapd/schema.c -@@ -2487,7 +2487,7 @@ schema_delete_objectclasses( Slapi_Entry *entryBefore, LDAPMod *mod, - } - } - -- for (i = 0; mod->mod_bvalues[i]; i++) { -+ for (i = 0; mod->mod_bvalues && mod->mod_bvalues[i]; i++) { - if ( LDAP_SUCCESS != ( rc = parse_oc_str ( - (const char *)mod->mod_bvalues[i]->bv_val, &delete_oc, - errorbuf, errorbufsize, 0, 0, schema_ds4x_compat, NULL))) { -@@ -2600,7 +2600,7 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod, - } - } - -- for (i = 0; mod->mod_bvalues[i]; i++) { -+ for (i = 0; mod->mod_bvalues && mod->mod_bvalues[i]; i++) { - attr_ldif =(char *) mod->mod_bvalues[i]->bv_val; - - /* normalize the attr ldif */ --- -1.9.3 - diff --git a/SOURCES/0060-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch b/SOURCES/0060-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch new file mode 100644 index 0000000..f9138cf --- /dev/null +++ b/SOURCES/0060-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch @@ -0,0 +1,78 @@ +From caab3e19a97d58450bbf06034974d4631aa904b6 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Fri, 18 Sep 2015 11:13:43 -0700 +Subject: [PATCH 60/61] Ticket #48188 - segfault in ns-slapd due to accessing + Slapi_DN freed in pre bind plug-in + +This patch is based upon the patch provided by Simo Sorce for +Ticket #48272 - Allow PRE_BIND plugins to mangle DNs + +Description: +Allow a pre_bind plugin to map a DN to another + +This is useful for plugins that deal with virtual trees or non-standard +clients binding with values that are not proper DNs and similar situations. + +Signed-off-by: Simo Sorce + +2 changes are made to the original patch: +1. removed "slapi_sdn_free(&sdn)" with this comment: + * It is a plug-in's responsibility to free the original Slapi_DN. + Note: slapi-nis already freed the original sdn. +2. reset dn from the new sdn. + dn = slapi_sdn_get_dn(sdn); + +https://fedorahosted.org/389/ticket/48188 + +Reviewed by rmeggins@redhat.com and lkrispen@redhat.com. + +(cherry picked from commit 40e0d0f80d6fd1271431e105580293747c43c327) +(cherry picked from commit 6871f4f6d14198563f7f3cb0646a00faa28d35ea) +--- + ldap/servers/slapd/bind.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c +index 1bd604f..4ec276a 100644 +--- a/ldap/servers/slapd/bind.c ++++ b/ldap/servers/slapd/bind.c +@@ -669,7 +669,7 @@ do_bind( Slapi_PBlock *pb ) + + slapi_pblock_set( pb, SLAPI_BACKEND, be ); + +- /* not root dn - pass to the backend */ ++ /* not root dn - pass to the backend */ + if ( be->be_bind != NULL ) { + + /* +@@ -677,10 +677,25 @@ do_bind( Slapi_PBlock *pb ) + * the backend bind function. then call the post-bind + * plugins. + */ +- if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) +- == 0 ) { ++ if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) == 0 ) { + rc = 0; + ++ /* Check if a pre_bind plugin mapped the DN to another backend */ ++ Slapi_DN *pb_sdn; ++ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn); ++ if (pb_sdn != sdn) { ++ /* ++ * Slapi_DN set in pblock was changed by a pre bind plug-in. ++ * It is a plug-in's responsibility to free the original Slapi_DN. ++ */ ++ sdn = pb_sdn; ++ dn = slapi_sdn_get_dn(sdn); ++ ++ slapi_be_Unlock(be); ++ be = slapi_be_select(sdn); ++ slapi_be_Rlock(be); ++ } ++ + /* + * Is this account locked ? + * could be locked through the account inactivation +-- +1.9.3 + diff --git a/SOURCES/0061-Ticket-48005-ns-slapd-crash-in-shutdown-phase.patch b/SOURCES/0061-Ticket-48005-ns-slapd-crash-in-shutdown-phase.patch deleted file mode 100644 index 3d59efe..0000000 --- a/SOURCES/0061-Ticket-48005-ns-slapd-crash-in-shutdown-phase.patch +++ /dev/null @@ -1,1057 +0,0 @@ -From 2e87dafa9d39e6ab08382612be762c25afa80d4f Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Sun, 15 Feb 2015 17:34:12 -0800 -Subject: [PATCH] Ticket #48005 - ns-slapd crash in shutdown phase - -Description: There was a small window that long running tasks access its -own task object after it's aready released by main thread in the shutdown -period. This patch adds refcounter to such threads and make destructor -wait until the counter becomes 0. Plus, the shutdown check is added to -their task callbacks. - -Following tasks are updated by this patch: - slapd/task.c: "fixup tombstones" - posix-winsync/posix-winsync-config.c: "memberuid task" - replication/repl5_replica_config.c: "cleanallruv" - replication/repl5_replica_config.c: "abort cleanallruv" - syntaxes/validate_task.c: "syntax validate" - automember/automember.c: "automember rebuild membership" - automember/automember.c: "automember export updates" - automember/automember.c: "automember map updates" - linkedattrs/linked_attrs.c: "fixup linked attributes" - memberof/memberof.c: "memberof task" - schema_reload/schema_reload.c: "schema reload task" - usn/usn_cleanup.c: "USN tombstone cleanup task" - -Following tasks are already covered: - slapd/task.c: "import" - slapd/task.c: "index" - slapd/task.c: "upgradedb" - -Following tasks are processed in an ordinary worker thread; no need to change - slapd/task.c: "sysconfig reload" - slapd/task.c: "export" - slapd/task.c: "backup" - slapd/task.c: "restore" - -(cherry picked from commit ab2e26de21beb5a92d2a18ab5a20db9637b83c7a) -(cherry picked from commit eebbabbaba8f024671158f527a169fc378ff01d6) - -Conflicts: - ldap/servers/plugins/memberof/memberof.c ---- - ldap/servers/plugins/automember/automember.c | 70 ++++++++++++++++++---- - ldap/servers/plugins/linkedattrs/fixup_task.c | 40 +++++++++++-- - ldap/servers/plugins/memberof/memberof.c | 26 +++++++- - ldap/servers/plugins/memberof/memberof.h | 2 +- - .../plugins/posix-winsync/posix-group-task.c | 40 ++++++++++--- - .../plugins/replication/repl5_replica_config.c | 58 ++++++++++++++++++ - ldap/servers/plugins/schema_reload/schema_reload.c | 23 ++++++- - ldap/servers/plugins/syntaxes/validate_task.c | 26 +++++++- - ldap/servers/plugins/usn/usn_cleanup.c | 58 +++++++++++++----- - ldap/servers/slapd/slapi-plugin.h | 9 +++ - ldap/servers/slapd/slapi-private.h | 2 - - ldap/servers/slapd/task.c | 47 +++++++++++++-- - 12 files changed, 348 insertions(+), 53 deletions(-) - -diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c -index 6a8fd22..b2914db 100644 ---- a/ldap/servers/plugins/automember/automember.c -+++ b/ldap/servers/plugins/automember/automember.c -@@ -119,9 +119,9 @@ static int automember_task_add_map_entries(Slapi_PBlock *pb, Slapi_Entry *e, Sla - void automember_rebuild_task_thread(void *arg); - void automember_export_task_thread(void *arg); - void automember_map_task_thread(void *arg); --void automember_task_destructor(Slapi_Task *task); --void automember_task_export_destructor(Slapi_Task *task); --void automember_task_map_destructor(Slapi_Task *task); -+static void automember_task_destructor(Slapi_Task *task); -+static void automember_task_export_destructor(Slapi_Task *task); -+static void automember_task_map_destructor(Slapi_Task *task); - - #define DEFAULT_FILE_MODE PR_IRUSR | PR_IWUSR - -@@ -1962,11 +1962,15 @@ fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val) - return slapi_value_get_string(val); - } - --void -+static void - automember_task_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->bind_dn); - slapi_sdn_free(&mydata->base_dn); -@@ -1976,11 +1980,15 @@ automember_task_destructor(Slapi_Task *task) - } - } - --void -+static void - automember_task_export_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->ldif_out); - slapi_ch_free_string(&mydata->bind_dn); -@@ -1991,11 +1999,15 @@ automember_task_export_destructor(Slapi_Task *task) - } - } - --void -+static void - automember_task_map_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->ldif_out); - slapi_ch_free_string(&mydata->ldif_in); -@@ -2114,7 +2126,8 @@ out: - * Search using the basedn, filter, and scope provided from the task data. - * Then loop of each entry, and apply the membership if applicable. - */ --void automember_rebuild_task_thread(void *arg){ -+void automember_rebuild_task_thread(void *arg) -+{ - Slapi_Task *task = (Slapi_Task *)arg; - struct configEntry *config = NULL; - Slapi_PBlock *search_pb = NULL, *fixup_pb = NULL; -@@ -2124,6 +2137,12 @@ void automember_rebuild_task_thread(void *arg){ - int result = 0; - int i = 0; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error( SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, -+ "automember_rebuild_task_thread --> refcount incremented.\n" ); - /* - * Fetch our task data from the task - */ -@@ -2192,7 +2211,8 @@ void automember_rebuild_task_thread(void *arg){ - if (slapi_dn_issuffix(slapi_entry_get_dn(entries[i]), config->scope) && - (slapi_filter_test_simple(entries[i], config->filter) == 0)) - { -- if(automember_update_membership(config, entries[i], NULL)){ -+ if (slapi_is_shutting_down() || -+ automember_update_membership(config, entries[i], NULL)) { - result = SLAPI_PLUGIN_FAILURE; - automember_config_unlock(); - goto out; -@@ -2226,6 +2246,9 @@ out: - } - slapi_task_inc_progress(task); - slapi_task_finish(task, result); -+ slapi_task_dec_refcount(task); -+ slapi_log_error( SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, -+ "automember_rebuild_task_thread <-- refcount decremented.\n" ); - } - - /* -@@ -2328,7 +2351,8 @@ out: - return rv; - } - --void automember_export_task_thread(void *arg){ -+void automember_export_task_thread(void *arg) -+{ - Slapi_Task *task = (Slapi_Task *)arg; - Slapi_PBlock *search_pb = NULL; - Slapi_Entry **entries = NULL; -@@ -2340,6 +2364,13 @@ void automember_export_task_thread(void *arg){ - int i = 0; - int rc = 0; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error( SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, -+ "automember_export_task_thread --> refcount incremented.\n" ); -+ - td = (task_data *)slapi_task_get_data(task); - slapi_task_begin(task, 1); - slapi_task_log_notice(task, "Automember export task starting. Exporting changes to (%s)", td->ldif_out); -@@ -2394,7 +2425,8 @@ void automember_export_task_thread(void *arg){ - if (slapi_dn_issuffix(slapi_sdn_get_dn(td->base_dn), config->scope) && - (slapi_filter_test_simple(entries[i], config->filter) == 0)) - { -- if(automember_update_membership(config, entries[i], ldif_fd)){ -+ if (slapi_is_shutting_down() || -+ automember_update_membership(config, entries[i], ldif_fd)) { - result = SLAPI_DSE_CALLBACK_ERROR; - automember_config_unlock(); - goto out; -@@ -2423,6 +2455,9 @@ out: - } - slapi_task_inc_progress(task); - slapi_task_finish(task, result); -+ slapi_task_dec_refcount(task); -+ slapi_log_error( SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, -+ "automember_export_task_thread <-- refcount decremented.\n" ); - } - - /* -@@ -2507,7 +2542,8 @@ out: - * Read in the text entries from ldif_in, and convert them to slapi_entries. - * Then, write to ldif_out what the updates would be if these entries were added - */ --void automember_map_task_thread(void *arg){ -+void automember_map_task_thread(void *arg) -+{ - Slapi_Task *task = (Slapi_Task *)arg; - Slapi_Entry *e = NULL; - int result = SLAPI_DSE_CALLBACK_OK; -@@ -2527,6 +2563,12 @@ void automember_map_task_thread(void *arg){ - #endif - int rc = 0; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error( SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, -+ "automember_map_task_thread --> refcount incremented.\n" ); - td = (task_data *)slapi_task_get_data(task); - slapi_task_begin(task, 1); - slapi_task_log_notice(task, "Automember map task starting... Reading entries from (%s)" -@@ -2586,7 +2628,8 @@ void automember_map_task_thread(void *arg){ - if (slapi_dn_issuffix(slapi_entry_get_dn_const(e), config->scope) && - (slapi_filter_test_simple(e, config->filter) == 0)) - { -- if(automember_update_membership(config, e, ldif_fd_out)){ -+ if (slapi_is_shutting_down() || -+ automember_update_membership(config, e, ldif_fd_out)) { - result = SLAPI_DSE_CALLBACK_ERROR; - slapi_entry_free(e); - slapi_ch_free_string(&entrystr); -@@ -2620,6 +2663,9 @@ out: - } - slapi_task_inc_progress(task); - slapi_task_finish(task, result); -+ slapi_task_dec_refcount(task); -+ slapi_log_error( SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, -+ "automember_map_task_thread <-- refcount decremented.\n" ); - } - - /* -diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c -index db3c693..3a01fed 100644 ---- a/ldap/servers/plugins/linkedattrs/fixup_task.c -+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c -@@ -119,6 +119,10 @@ linked_attrs_fixup_task_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->linkdn); - slapi_ch_free_string(&mydata->bind_dn); -@@ -137,6 +141,12 @@ linked_attrs_fixup_task_thread(void *arg) - int found_config = 0; - int rc = 0; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, LINK_PLUGIN_SUBSYSTEM, -+ "linked_attrs_fixup_task_thread --> refcount incremented.\n" ); - /* Fetch our task data from the task */ - td = (task_data *)slapi_task_get_data(task); - -@@ -154,8 +164,8 @@ linked_attrs_fixup_task_thread(void *arg) - linked_attrs_read_lock(); - main_config = linked_attrs_get_config(); - if (!PR_CLIST_IS_EMPTY(main_config)) { -- struct configEntry *config_entry = NULL; -- PRCList *list = PR_LIST_HEAD(main_config); -+ struct configEntry *config_entry = NULL; -+ PRCList *list = PR_LIST_HEAD(main_config); - - while (list != main_config) { - config_entry = (struct configEntry *) list; -@@ -204,6 +214,10 @@ linked_attrs_fixup_task_thread(void *arg) - - /* this will queue the destruction of the task */ - slapi_task_finish(task, rc); -+ -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, LINK_PLUGIN_SUBSYSTEM, -+ "linked_attrs_fixup_task_thread <-- refcount decremented.\n"); - } - - static void -@@ -269,7 +283,7 @@ linked_attrs_fixup_links(struct configEntry *config) - if(rc == 0){ - slapi_back_transaction_commit(fixup_pb); - } else { -- slapi_back_transaction_abort(fixup_pb); -+ slapi_back_transaction_abort(fixup_pb); - } - slapi_pblock_destroy(fixup_pb); - } -@@ -352,11 +366,20 @@ linked_attrs_remove_backlinks_callback(Slapi_Entry *e, void *callback_data) - int rc = 0; - Slapi_DN *sdn = slapi_entry_get_sdn(e); - char *type = (char *)callback_data; -- Slapi_PBlock *pb = slapi_pblock_new(); -+ Slapi_PBlock *pb = NULL; - char *val[1]; - LDAPMod mod; - LDAPMod *mods[2]; - -+ /* -+ * If the server is ordered to shutdown, stop the fixup and return an error. -+ */ -+ if (slapi_is_shutting_down()) { -+ rc = -1; -+ goto bail; -+ } -+ -+ pb = slapi_pblock_new(); - /* Remove all values of the passed in type. */ - val[0] = 0; - -@@ -377,7 +400,7 @@ linked_attrs_remove_backlinks_callback(Slapi_Entry *e, void *callback_data) - slapi_modify_internal_pb(pb); - - slapi_pblock_destroy(pb); -- -+bail: - return rc; - } - -@@ -394,6 +417,13 @@ linked_attrs_add_backlinks_callback(Slapi_Entry *e, void *callback_data) - LDAPMod mod; - LDAPMod *mods[2]; - -+ /* -+ * If the server is ordered to shutdown, stop the fixup and return an error. -+ */ -+ if (slapi_is_shutting_down()) { -+ rc = -1; -+ goto done; -+ } - /* Setup the modify operation. Only the target will - * change, so we only need to do this once. */ - val[0] = linkdn; -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index 7e3e308..14bad98 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -2636,6 +2636,12 @@ void memberof_fixup_task_thread(void *arg) - int rc = 0; - Slapi_PBlock *fixup_pb = NULL; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_fixup_task_thread --> refcount incremented.\n" ); - /* Fetch our task data from the task */ - td = (task_data *)slapi_task_get_data(task); - -@@ -2702,6 +2708,9 @@ void memberof_fixup_task_thread(void *arg) - - /* this will queue the destruction of the task */ - slapi_task_finish(task, rc); -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_fixup_task_thread <-- refcount decremented.\n"); - } - - /* extract a single value from the entry (as a string) -- if it's not in the -@@ -2793,8 +2802,14 @@ out: - void - memberof_task_destructor(Slapi_Task *task) - { -+ slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_task_destructor -->\n" ); - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->dn); - slapi_ch_free_string(&mydata->bind_dn); -@@ -2803,6 +2818,8 @@ memberof_task_destructor(Slapi_Task *task) - slapi_ch_free((void **)&mydata); - } - } -+ slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_task_destructor <--\n" ); - } - - int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str) -@@ -2841,6 +2858,13 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) - memberof_del_dn_data del_data = {0, config->memberof_attr}; - Slapi_ValueSet *groups = 0; - -+ /* -+ * If the server is ordered to shutdown, stop the fixup and return an error. -+ */ -+ if (slapi_is_shutting_down()) { -+ rc = -1; -+ goto bail; -+ } - /* get a list of all of the groups this user belongs to */ - groups = memberof_get_groups(config, sdn); - -@@ -2889,6 +2913,6 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) - } - - slapi_valueset_free(groups); -- -+bail: - return rc; - } -diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h -index 6d56081..59029d7 100644 ---- a/ldap/servers/plugins/memberof/memberof.h -+++ b/ldap/servers/plugins/memberof/memberof.h -@@ -81,7 +81,7 @@ typedef struct memberofconfig { - char *memberof_attr; - int allBackends; - Slapi_DN *entryScope; -- Slapi_DN *entryScopeExcludeSubtree; -+ Slapi_DN *entryScopeExcludeSubtree; - Slapi_Filter *group_filter; - Slapi_Attr **group_slapiattrs; - } MemberOfConfig; -diff --git a/ldap/servers/plugins/posix-winsync/posix-group-task.c b/ldap/servers/plugins/posix-winsync/posix-group-task.c -index c5ea729..c76545a 100644 ---- a/ldap/servers/plugins/posix-winsync/posix-group-task.c -+++ b/ldap/servers/plugins/posix-winsync/posix-group-task.c -@@ -165,6 +165,10 @@ posix_group_task_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *) slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->dn); - slapi_ch_free_string(&mydata->filter_str); -@@ -172,6 +176,8 @@ posix_group_task_destructor(Slapi_Task *task) - slapi_ch_free((void **) &mydata); - } - } -+ slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, -+ "posix_group_task_destructor <--\n"); - } - - #if 0 /* NOT USED */ -@@ -245,17 +251,28 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) - "_fix_memberuid ==>\n"); - cb_data *the_cb_data = (cb_data *) callback_data; - -- int rc; -+ int rc = 0; - Slapi_Attr *muid_attr = NULL; - Slapi_Value *v = NULL; - -- Slapi_Mods *smods = slapi_mods_new(); -- -- char *dn = slapi_entry_get_dn(e); -- Slapi_DN *sdn = slapi_entry_get_sdn(e); -+ Slapi_Mods *smods = NULL; -+ char *dn = NULL; -+ Slapi_DN *sdn = NULL; - LDAPMod **mods = NULL; - int is_posix_group = 0; - -+ /* -+ * If the server is ordered to shutdown, stop the fixup and return an error. -+ */ -+ if (slapi_is_shutting_down()) { -+ rc = -1; -+ goto bail; -+ } -+ -+ smods = slapi_mods_new(); -+ dn = slapi_entry_get_dn(e); -+ sdn = slapi_entry_get_sdn(e); -+ - if (hasObjectClass(e, "posixGroup")) { - is_posix_group = 1; - } -@@ -441,7 +458,7 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) - slapi_pblock_destroy(mod_pb); - } - slapi_mods_free(&smods); -- -+bail: - slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, - "_fix_memberuid <==\n"); - /* -@@ -450,7 +467,7 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) - * uniqueMember attribute. But "not found" error shoud not - * be returned, which stops the further fixup task. - */ -- return 0; -+ return rc; - } - - static void -@@ -463,6 +480,12 @@ posix_group_fixup_task_thread(void *arg) - task_data *td = NULL; - int rc = 0; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, -+ "posix_group_fixup_task_thread --> refcount incremented.\n" ); - /* Fetch our task data from the task */ - td = (task_data *) slapi_task_get_data(task); - -@@ -491,4 +514,7 @@ posix_group_fixup_task_thread(void *arg) - - slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, - "_task_thread <==\n"); -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, -+ "posix_group_fixup_task_thread <-- refcount decremented.\n"); - } -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 3bc3916..1570ba7 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -109,6 +109,8 @@ static CSN* replica_cleanallruv_find_maxcsn(Replica *replica, ReplicaId rid, cha - static int replica_cleanallruv_get_replica_maxcsn(Repl_Agmt *agmt, char *rid_text, char *basedn, CSN **csn); - static void preset_cleaned_rid(ReplicaId rid); - static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e); -+static void replica_cleanall_ruv_destructor(Slapi_Task *task); -+static void replica_cleanall_ruv_abort_destructor(Slapi_Task *task); - - /* - * Note: internal add/modify/delete operations should not be run while -@@ -1509,6 +1511,10 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, - rc = SLAPI_DSE_CALLBACK_ERROR; - goto out; - } -+ -+ /* register our destructor for waiting the task is done */ -+ slapi_task_set_destructor_fn(task, replica_cleanall_ruv_destructor); -+ - /* - * Get our task settings - */ -@@ -1752,6 +1758,13 @@ replica_cleanallruv_thread(void *arg) - int aborted = 0; - int rc = 0; - -+ if (!data) { -+ return; /* no data */ -+ } -+ if (data->task) { -+ slapi_task_inc_refcount(data->task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, "replica_cleanallruv_thread --> refcount incremented.\n"); -+ } - /* - * Initialize our settings - */ -@@ -1974,6 +1987,8 @@ done: - } - if(data->task){ - slapi_task_finish(data->task, rc); -+ slapi_task_dec_refcount(data->task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, "replica_cleanallruv_thread <-- refcount decremented.\n"); - } - if(data->payload){ - ber_bvfree(data->payload); -@@ -1989,6 +2004,36 @@ done: - slapi_ch_free((void **)&data); - } - -+static void -+replica_cleanall_ruv_destructor(Slapi_Task *task) -+{ -+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, -+ "replica_cleanall_ruv_destructor -->\n" ); -+ if (task) { -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } -+ } -+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, -+ "replica_cleanall_ruv_destructor <--\n" ); -+} -+ -+static void -+replica_cleanall_ruv_abort_destructor(Slapi_Task *task) -+{ -+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, -+ "replica_cleanall_ruv_abort_destructor -->\n" ); -+ if (task) { -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } -+ } -+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, -+ "replica_cleanall_ruv_abort_destructor <--\n" ); -+} -+ - /* - * Loop over the agmts, and check if they are in the last phase of cleaning, meaning they have - * released cleanallruv data from the config -@@ -2775,6 +2820,10 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter - - /* allocate new task now */ - task = slapi_new_task(slapi_entry_get_ndn(e)); -+ -+ /* register our destructor for waiting the task is done */ -+ slapi_task_set_destructor_fn(task, replica_cleanall_ruv_abort_destructor); -+ - /* - * Get our task settings - */ -@@ -2921,6 +2970,13 @@ replica_abort_task_thread(void *arg) - int release_it = 0; - int count = 0, rc = 0; - -+ if (!data) { -+ return; /* no data */ -+ } -+ if (data->task) { -+ slapi_task_inc_refcount(data->task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, "replica_abort_task_thread --> refcount incremented.\n"); -+ } - cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Aborting task for rid(%d)...",data->rid); - - /* -@@ -3028,6 +3084,8 @@ done: - - if(data->task){ - slapi_task_finish(data->task, agmt_not_notified); -+ slapi_task_dec_refcount(data->task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name, "replica_abort_task_thread <-- refcount incremented.\n"); - } - if(data->repl_obj && release_it) - object_release(data->repl_obj); -diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c -index b1a5bb8..25336fe 100644 ---- a/ldap/servers/plugins/schema_reload/schema_reload.c -+++ b/ldap/servers/plugins/schema_reload/schema_reload.c -@@ -86,6 +86,7 @@ static int schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, - void *arg); - static int schemareload_start(Slapi_PBlock *pb); - static int schemareload_close(Slapi_PBlock *pb); -+static void schemareload_destructor(Slapi_Task *task); - - /* - * Init function -@@ -159,6 +160,12 @@ schemareload_thread(void *arg) - int total_work = 2; - task_data *td = NULL; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, "schemareload", -+ "schemareload_thread --> refcount incremented.\n" ); - /* Fetch our task data from the task */ - td = (task_data *)slapi_task_get_data(task); - -@@ -174,7 +181,11 @@ schemareload_thread(void *arg) - rv = slapi_validate_schema_files(td->schemadir); - slapi_task_inc_progress(task); - -- if (LDAP_SUCCESS == rv) { -+ if (slapi_is_shutting_down()) { -+ slapi_task_log_notice(task, "Server is shuttoing down; Schema validation aborted."); -+ slapi_task_log_status(task, "Server is shuttoing down; Schema validation aborted."); -+ slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Server is shuttoing down; Schema validation aborted."); -+ } else if (LDAP_SUCCESS == rv) { - slapi_task_log_notice(task, "Schema validation passed."); - slapi_task_log_status(task, "Schema validation passed."); - slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema validation passed.\n"); -@@ -199,16 +210,18 @@ schemareload_thread(void *arg) - slapi_task_log_status(task, "Schema reload task failed."); - slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task failed.\n"); - } -- PR_Unlock(schemareload_lock); - } else { - slapi_task_log_notice(task, "Schema validation failed."); - slapi_task_log_status(task, "Schema validation failed."); - slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema validation failed.\n"); -- PR_Unlock(schemareload_lock); - } -+ PR_Unlock(schemareload_lock); - - /* this will queue the destruction of the task */ - slapi_task_finish(task, rv); -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, "schemareload", -+ "schemareload_thread <-- refcount decremented.\n"); - } - - /* extract a single value from the entry (as a string) -- if it's not in the -@@ -233,6 +246,10 @@ schemareload_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->schemadir); - slapi_ch_free_string(&mydata->bind_dn); -diff --git a/ldap/servers/plugins/syntaxes/validate_task.c b/ldap/servers/plugins/syntaxes/validate_task.c -index 99f6309..71b4b7e 100644 ---- a/ldap/servers/plugins/syntaxes/validate_task.c -+++ b/ldap/servers/plugins/syntaxes/validate_task.c -@@ -179,6 +179,10 @@ syntax_validate_task_destructor(Slapi_Task *task) - { - if (task) { - task_data *mydata = (task_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } - if (mydata) { - slapi_ch_free_string(&mydata->dn); - slapi_ch_free_string(&mydata->filter_str); -@@ -197,6 +201,12 @@ syntax_validate_task_thread(void *arg) - task_data *td = NULL; - Slapi_PBlock *search_pb = slapi_pblock_new(); - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, SYNTAX_PLUGIN_SUBSYSTEM, -+ "syntax_validate_task_thread --> refcount incremented.\n" ); - /* Fetch our task data from the task */ - td = (task_data *)slapi_task_get_data(task); - -@@ -231,16 +241,26 @@ syntax_validate_task_thread(void *arg) - - /* this will queue the destruction of the task */ - slapi_task_finish(task, rc); -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, SYNTAX_PLUGIN_SUBSYSTEM, -+ "syntax_validate_task_thread <-- refcount decremented.\n"); - } - - static int - syntax_validate_task_callback(Slapi_Entry *e, void *callback_data) - { -- int rc = 0; -- char *dn = slapi_entry_get_dn(e); -+ int rc = 0; -+ char *dn = slapi_entry_get_dn(e); - task_data *td = (task_data *)callback_data; - Slapi_PBlock *pb = NULL; - -+ /* -+ * If the server is ordered to shutdown, stop the fixup and return an error. -+ */ -+ if (slapi_is_shutting_down()) { -+ rc = -1; -+ goto bail; -+ } - /* Override the syntax checking config to force syntax checking. */ - if (slapi_entry_syntax_check(NULL, e, 1) != 0) { - char *error_text = NULL; -@@ -261,7 +281,7 @@ syntax_validate_task_callback(Slapi_Entry *e, void *callback_data) - /* Keep a tally of the number of invalid entries found. */ - slapi_counter_increment(td->invalid_entries); - } -- -+bail: - return rc; - } - -diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c -index c12dfd2..dd07b4c 100644 ---- a/ldap/servers/plugins/usn/usn_cleanup.c -+++ b/ldap/servers/plugins/usn/usn_cleanup.c -@@ -49,6 +49,8 @@ struct usn_cleanup_data { - - static int usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, - Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg); -+static void usn_cleanup_task_destructor(Slapi_Task *task); -+ - - int - usn_cleanup_start(Slapi_PBlock *pb) -@@ -83,8 +85,14 @@ usn_cleanup_thread(void *arg) - Slapi_PBlock *delete_pb = NULL; - char *filter = "objectclass=nsTombstone"; - -+ if (!task) { -+ return; /* no task */ -+ } - slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, - "--> usn_cleanup_thread\n"); -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, USN_PLUGIN_SUBSYSTEM, -+ "usn_cleanup_thread --> refcount incremented.\n" ); - - if (NULL == usn_get_identity()) { /* plugin is not initialized */ - slapi_task_log_notice(task, "USN plugin is not initialized\n"); -@@ -195,14 +203,12 @@ bail: - if (cleanup_data->maxusn_to_delete) { - slapi_ch_free_string(&filter); - } -- slapi_ch_free_string(&cleanup_data->maxusn_to_delete); -- slapi_ch_free_string(&cleanup_data->suffix); -- slapi_ch_free_string(&cleanup_data->bind_dn); -- slapi_ch_free((void **)&cleanup_data); - - /* this will queue the destruction of the task */ - slapi_task_finish(task, rv); -- -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, USN_PLUGIN_SUBSYSTEM, -+ "usn_cleanup_thread <-- refcount decremented.\n"); - slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, - "<-- usn_cleanup_thread\n"); - } -@@ -283,7 +289,7 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, - backend = slapi_entry_attr_get_charptr(e, "backend"); - maxusn = slapi_entry_attr_get_charptr(e, "maxusn_to_delete"); - -- if (NULL == suffix && NULL == backend) { -+ if (!suffix && !backend) { - slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, - "USN tombstone cleanup: Both suffix and backend are missing.\n"); - *returncode = LDAP_PARAM_ERROR; -@@ -292,7 +298,7 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, - } - - /* suffix is not given, but backend is; get the suffix */ -- if (NULL == suffix && NULL != backend) { -+ if (!suffix && backend) { - be = slapi_be_select_by_instance_name(backend); - be_suffix = slapi_be_getsuffix(be, 0); - if (be_suffix) { -@@ -317,12 +323,6 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, - goto bail; - } - -- cleanup_data = -- (struct usn_cleanup_data *)slapi_ch_malloc(sizeof(struct usn_cleanup_data)); -- cleanup_data->suffix = slapi_ch_strdup(suffix); -- cleanup_data->maxusn_to_delete = slapi_ch_strdup(maxusn); -- cleanup_data->bind_dn = slapi_ch_strdup(bind_dn); -- - /* allocate new task now */ - task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg); - if (task == NULL) { -@@ -330,11 +330,21 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, - "USN tombstone cleanup: unable to allocate new task.\n"); - *returncode = LDAP_OPERATIONS_ERROR; - rv = SLAPI_DSE_CALLBACK_ERROR; -- slapi_ch_free((void**)&cleanup_data); - goto bail; - } - -+ /* register our destructor for cleaning up our private data */ -+ slapi_task_set_destructor_fn(task, usn_cleanup_task_destructor); -+ - /* Stash our argument in the task for use by the task thread */ -+ cleanup_data = -+ (struct usn_cleanup_data *)slapi_ch_malloc(sizeof(struct usn_cleanup_data)); -+ cleanup_data->suffix = suffix; -+ suffix = NULL; /* don't free in this function */ -+ cleanup_data->maxusn_to_delete = maxusn; -+ maxusn = NULL; /* don't free in this function */ -+ cleanup_data->bind_dn = bind_dn; -+ bind_dn = NULL; /* don't free in this function */ - slapi_task_set_data(task, cleanup_data); - - /* start the USN tombstone cleanup task as a separate thread */ -@@ -361,3 +371,23 @@ bail: - return rv; - } - -+static void -+usn_cleanup_task_destructor(Slapi_Task *task) -+{ -+ slapi_log_error(SLAPI_LOG_PLUGIN, USN_PLUGIN_SUBSYSTEM, "usn_cleanup_task_destructor -->\n"); -+ if (task) { -+ struct usn_cleanup_data *mydata = (struct usn_cleanup_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } -+ if (mydata) { -+ slapi_ch_free_string(&mydata->suffix); -+ slapi_ch_free_string(&mydata->maxusn_to_delete); -+ slapi_ch_free_string(&mydata->bind_dn); -+ /* Need to cast to avoid a compiler warning */ -+ slapi_ch_free((void **)&mydata); -+ } -+ } -+ slapi_log_error(SLAPI_LOG_PLUGIN, USN_PLUGIN_SUBSYSTEM, "usn_cleanup_task_destructor <--\n"); -+} -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index 0ae3601..dfe75eb 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -7958,6 +7958,15 @@ void slapi_plugin_op_finished(void *arg); - #define RDN_IS_CONFLICT 0x2 - int slapi_is_special_rdn(const char *rdn, int flag); - -+/** -+ * Sleeps for PRIntervalTime ticks defined in NSPR library -+ * -+ * \param PRIntervalTime ticks -+ * -+ * \return Nothing -+ */ -+void DS_Sleep(PRIntervalTime ticks); -+ - #ifdef __cplusplus - } - #endif -diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h -index 921c397..9ca1950 100644 ---- a/ldap/servers/slapd/slapi-private.h -+++ b/ldap/servers/slapd/slapi-private.h -@@ -1245,8 +1245,6 @@ void bervalarray_add_berval_fast(struct berval ***vals, const struct berval *add - - /***** End of items added for the replication plugin. ***********************/ - --void DS_Sleep(PRIntervalTime ticks); -- - /* macro to specify the behavior of upgradedb & upgradednformat */ - #define SLAPI_UPGRADEDB_FORCE 0x1 /* reindex all (no check w/ idl switch) */ - #define SLAPI_UPGRADEDB_SKIPINIT 0x2 /* call upgradedb as part of other op */ -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index 98ec88c..19a52a3 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -113,6 +113,8 @@ static const char *fetch_attr(Slapi_Entry *e, const char *attrname, - static Slapi_Entry *get_internal_entry(Slapi_PBlock *pb, char *dn); - static void modify_internal_entry(char *dn, LDAPMod **mods); - -+static void fixup_tombstone_task_destructor(Slapi_Task *task); -+ - /*********************************** - * Public Functions - ***********************************/ -@@ -2218,6 +2220,12 @@ task_fixup_tombstone_thread(void *arg) - int fixup_count = 0; - int rc, i, j; - -+ if (!task) { -+ return; /* no task */ -+ } -+ slapi_task_inc_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, TASK_TOMBSTONE_FIXUP, -+ "fixup_tombstone_task_thread --> refcount incremented.\n" ); - slapi_task_begin(task, 1); - slapi_task_log_notice(task, "Beginning tombstone fixup task...\n"); - slapi_log_error(SLAPI_LOG_REPL, TASK_TOMBSTONE_FIXUP, -@@ -2233,8 +2241,14 @@ task_fixup_tombstone_thread(void *arg) - - /* Okay check the specified backends only */ - for(i = 0; base && base[i]; i++){ -- Slapi_PBlock *search_pb = slapi_pblock_new(); -+ Slapi_PBlock *search_pb = NULL; -+ -+ if (slapi_is_shutting_down()) { -+ rc = -1; -+ goto bail; -+ } - -+ search_pb = slapi_pblock_new(); - /* find entries that need fixing... */ - slapi_search_internal_set_pb(search_pb, base[i], LDAP_SCOPE_SUBTREE, - filter, NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0); -@@ -2247,8 +2261,7 @@ task_fixup_tombstone_thread(void *arg) - slapi_log_error(SLAPI_LOG_REPL, TASK_TOMBSTONE_FIXUP, - "Failed to search backend for tombstones, error %d\n", rc); - slapi_pblock_destroy(search_pb); -- slapi_task_finish(task, rc); -- return; -+ goto bail; - } - - slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); -@@ -2281,9 +2294,11 @@ task_fixup_tombstone_thread(void *arg) - slapi_log_error(SLAPI_LOG_REPL, TASK_TOMBSTONE_FIXUP, "%s %d tombstones.\n", - task_data->stripcsn ? "Stripped" : "Fixed", fixup_count); - slapi_task_inc_progress(task); -+bail: - slapi_task_finish(task, rc); -- slapi_ch_array_free(base); -- slapi_ch_free((void **)&task_data); -+ slapi_task_dec_refcount(task); -+ slapi_log_error(SLAPI_LOG_PLUGIN, TASK_TOMBSTONE_FIXUP, -+ "fixup_tombstone_task_thread <-- refcount decremented.\n" ); - } - - -@@ -2387,6 +2402,8 @@ task_fixup_tombstones_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, - } - - task = slapi_new_task(slapi_entry_get_ndn(e)); -+ /* register our destructor for cleaning up our private data */ -+ slapi_task_set_destructor_fn(task, fixup_tombstone_task_destructor); - task_data = (struct task_tombstone_data *)slapi_ch_calloc(1, sizeof(struct task_tombstone_data)); - task_data->base = base; - task_data->task = task; -@@ -2422,6 +2439,26 @@ done: - return SLAPI_DSE_CALLBACK_OK; - } - -+static void -+fixup_tombstone_task_destructor(Slapi_Task *task) -+{ -+ slapi_log_error(SLAPI_LOG_PLUGIN, TASK_TOMBSTONE_FIXUP, -+ "fixup_tombstone_task_destructor -->\n" ); -+ if (task) { -+ struct task_tombstone_data *mydata = (struct task_tombstone_data *)slapi_task_get_data(task); -+ while (slapi_task_get_refcount(task) > 0) { -+ /* Yield to wait for the fixup task finishes. */ -+ DS_Sleep (PR_MillisecondsToInterval(100)); -+ } -+ if (mydata) { -+ slapi_ch_array_free(mydata->base); -+ slapi_ch_free((void **)&mydata); -+ } -+ } -+ slapi_log_error(SLAPI_LOG_PLUGIN, TASK_TOMBSTONE_FIXUP, -+ "fixup_tombstone_task_destructor <--\n" ); -+} -+ - /* cleanup old tasks that may still be in the DSE from a previous session - * (this can happen if the server crashes [no matter how unlikely we like - * to think that is].) --- -1.9.3 - diff --git a/SOURCES/0061-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch b/SOURCES/0061-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch new file mode 100644 index 0000000..0ce22e8 --- /dev/null +++ b/SOURCES/0061-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch @@ -0,0 +1,172 @@ +From 91e8872841e18eb96f2680fba180d636bb0a2a67 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Fri, 18 Sep 2015 15:19:51 -0700 +Subject: [PATCH 61/61] Ticket #48188 - segfault in ns-slapd due to accessing + Slapi_DN freed in pre bind plug-in + +Description: Additional fixes based upon the comments by rmeggins@redhat.com +(Thank you, Rich!!). +https://fedorahosted.org/389/ticket/48188?replyto=24#comment:24 +1. Implemented the case 2) + If the plugin changes the SLAPI_BIND_TARGET_SDN *value*, + we need to select a different backend. It is possible + (but not very useful) for the plugin to change the pointer, + but use the same value. +2. Added an api slapi_be_select_exact which returns NULL if + there is no matching backend. + +https://fedorahosted.org/389/ticket/48188 + +Reviewed by rmeggins@redhat.com (Thank you!) + +(cherry picked from commit 8212a8913b748cd1f5e986a754c37ef41db8272a) +(cherry picked from commit a215c006e0900caaa555def9e047e295844d8652) +--- + ldap/servers/slapd/bind.c | 47 +++++++++++++++++++++++++++++---------- + ldap/servers/slapd/mapping_tree.c | 19 ++++++++++++++++ + ldap/servers/slapd/slapi-plugin.h | 1 + + 3 files changed, 55 insertions(+), 12 deletions(-) + +diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c +index 4ec276a..474b508 100644 +--- a/ldap/servers/slapd/bind.c ++++ b/ldap/servers/slapd/bind.c +@@ -107,6 +107,7 @@ do_bind( Slapi_PBlock *pb ) + int auto_bind = 0; + int minssf = 0; + int minssf_exclude_rootdse = 0; ++ Slapi_DN *original_sdn = NULL; + + LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 ); + +@@ -660,10 +661,9 @@ do_bind( Slapi_PBlock *pb ) + goto free_and_return; + } + +- if (referral) +- { +- send_referrals_from_entry(pb,referral); +- slapi_entry_free(referral); ++ if (referral) { ++ send_referrals_from_entry(pb,referral); ++ slapi_entry_free(referral); + goto free_and_return; + } + +@@ -671,29 +671,50 @@ do_bind( Slapi_PBlock *pb ) + + /* not root dn - pass to the backend */ + if ( be->be_bind != NULL ) { +- ++ original_sdn = slapi_sdn_dup(sdn); + /* + * call the pre-bind plugins. if they succeed, call + * the backend bind function. then call the post-bind + * plugins. + */ + if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) == 0 ) { ++ int sdn_updated = 0; + rc = 0; + + /* Check if a pre_bind plugin mapped the DN to another backend */ + Slapi_DN *pb_sdn; + slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn); +- if (pb_sdn != sdn) { ++ if (!pb_sdn) { ++ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set NULL dn\n"); ++ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL); ++ goto free_and_return; ++ } else if ((pb_sdn != sdn) || (sdn_updated = slapi_sdn_compare(original_sdn, pb_sdn))) { + /* + * Slapi_DN set in pblock was changed by a pre bind plug-in. + * It is a plug-in's responsibility to free the original Slapi_DN. + */ + sdn = pb_sdn; + dn = slapi_sdn_get_dn(sdn); +- +- slapi_be_Unlock(be); +- be = slapi_be_select(sdn); +- slapi_be_Rlock(be); ++ if (!dn) { ++ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn\n"); ++ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL); ++ goto free_and_return; ++ } ++ if (!sdn_updated) { /* pb_sdn != sdn; need to compare the dn's. */ ++ sdn_updated = slapi_sdn_compare(original_sdn, sdn); ++ } ++ if (sdn_updated) { /* call slapi_be_select only when the DN is updated. */ ++ slapi_be_Unlock(be); ++ be = slapi_be_select_exact(sdn); ++ if (be) { ++ slapi_be_Rlock(be); ++ slapi_pblock_set( pb, SLAPI_BACKEND, be ); ++ } else { ++ PR_snprintf(errorbuf, sizeof(errorbuf), "No matching backend for %s\n", dn); ++ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL); ++ goto free_and_return; ++ } ++ } + } + + /* +@@ -845,10 +866,12 @@ account_locked: + } + + free_and_return:; +- if (be) ++ slapi_sdn_free(&original_sdn); ++ if (be) { + slapi_be_Unlock(be); ++ } + if (bind_sdn_in_pb) { +- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn); ++ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn); + } + slapi_sdn_free(&sdn); + slapi_ch_free_string( &saslmech ); +diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c +index 165eba1..20c2cc3 100644 +--- a/ldap/servers/slapd/mapping_tree.c ++++ b/ldap/servers/slapd/mapping_tree.c +@@ -3095,6 +3095,25 @@ slapi_be_select( const Slapi_DN *sdn ) /* JCM - The name of this should change?? + return be; + } + ++Slapi_Backend * ++slapi_be_select_exact(const Slapi_DN *sdn) ++{ ++ Slapi_Backend *be = NULL; ++ mapping_tree_node *node = NULL; ++ ++ if (!sdn) { ++ LDAPDebug0Args(LDAP_DEBUG_ANY, "slapi_be_select_exact: Empty Slapi_DN is given.\n"); ++ return NULL; ++ } ++ node = slapi_get_mapping_tree_node_by_dn(sdn); ++ ++ if (node && node->mtn_be) { ++ be = node->mtn_be[0]; ++ } ++ ++ return be; ++} ++ + /* Check if the dn targets an internal reserved backends */ + int + slapi_on_internal_backends(const Slapi_DN *sdn) +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index 6b04610..564da44 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -6338,6 +6338,7 @@ Slapi_Backend *slapi_be_new( const char *type, const char *name, + int isprivate, int logchanges ); + void slapi_be_free(Slapi_Backend **be); + Slapi_Backend *slapi_be_select( const Slapi_DN *sdn ); ++Slapi_Backend *slapi_be_select_exact(const Slapi_DN *sdn); + Slapi_Backend *slapi_be_select_by_instance_name( const char *name ); + int slapi_be_exist(const Slapi_DN *sdn); + void slapi_be_delete_onexit(Slapi_Backend *be); +-- +1.9.3 + diff --git a/SOURCES/0062-CVE-2015-1854-389ds-base-access-control-bypass-with-.patch b/SOURCES/0062-CVE-2015-1854-389ds-base-access-control-bypass-with-.patch deleted file mode 100644 index 903a69d..0000000 --- a/SOURCES/0062-CVE-2015-1854-389ds-base-access-control-bypass-with-.patch +++ /dev/null @@ -1,347 +0,0 @@ -From 205bce153c7db8258a8a28498cf54e7374dca588 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 14 Apr 2015 16:24:44 +0200 -Subject: [PATCH] CVE-2015-1854 389ds-base: access control bypass with modrdn - -Bug Description: - 47553 fix checks the write right access only if the RDN is - modified. This allows to rename entries even if the - authenticated user is not allowed of that. - -Fix Description: - Roll back a wrong optimization that tested the write access - only if RDN value was changed. - -https://fedorahosted.org/389/ticket/47553 - -Reviewed by: ? - -Platforms tested: F17 (upstream test) - -Flag Day: no - -Doc impact: no - -(cherry picked from commit 44e5c0998bdf7dcb167e8472713ff393b776e4e3) - -Conflicts: - dirsrvtests/tickets/ticket47553_single_aci_test.py ---- - dirsrvtests/tickets/ticket47553_rdn_write_test.py | 132 +++++++++++++++++++++ - dirsrvtests/tickets/ticket47553_single_aci_test.py | 52 ++++++-- - ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 32 ++--- - 3 files changed, 184 insertions(+), 32 deletions(-) - create mode 100644 dirsrvtests/tickets/ticket47553_rdn_write_test.py - -diff --git a/dirsrvtests/tickets/ticket47553_rdn_write_test.py b/dirsrvtests/tickets/ticket47553_rdn_write_test.py -new file mode 100644 -index 0000000..f15d9b3 ---- /dev/null -+++ b/dirsrvtests/tickets/ticket47553_rdn_write_test.py -@@ -0,0 +1,132 @@ -+import os -+import sys -+import time -+import ldap -+import logging -+import pytest -+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 * -+from ldap.controls.simple import GetEffectiveRightsControl -+ -+logging.getLogger(__name__).setLevel(logging.DEBUG) -+log = logging.getLogger(__name__) -+ -+installation1_prefix = None -+ -+SRC_ENTRY_CN = "tuser" -+EXT_RDN = "01" -+DST_ENTRY_CN = SRC_ENTRY_CN + EXT_RDN -+ -+SRC_ENTRY_DN = "cn=%s,%s" % (SRC_ENTRY_CN, SUFFIX) -+DST_ENTRY_DN = "cn=%s,%s" % (DST_ENTRY_CN, SUFFIX) -+ -+class TopologyStandalone(object): -+ def __init__(self, standalone): -+ standalone.open() -+ self.standalone = standalone -+ -+ -+#@pytest.fixture(scope="module") -+def topology(request): -+ global installation1_prefix -+ -+ # Creating standalone instance ... -+ standalone = DirSrv(verbose=False) -+ if installation1_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix -+ 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() -+ -+ # Clear out the tmp dir -+ standalone.clearTmpDir(__file__) -+ -+ return TopologyStandalone(standalone) -+ -+def test_ticket47553_rdn_write_init(topology): -+ topology.standalone.log.info("\n\n######################### Add entry tuser ######################\n") -+ topology.standalone.add_s(Entry((SRC_ENTRY_DN, { -+ 'objectclass': "top person".split(), -+ 'sn': SRC_ENTRY_CN, -+ 'cn': SRC_ENTRY_CN}))) -+ -+def test_ticket47553_rdn_write_get_ger(topology): -+ ANONYMOUS_DN = "" -+ topology.standalone.log.info("\n\n######################### GER rights for anonymous ######################\n") -+ request_ctrl = GetEffectiveRightsControl(criticality=True, authzId="dn:" + ANONYMOUS_DN) -+ msg_id = topology.standalone.search_ext(SUFFIX, ldap.SCOPE_SUBTREE, "objectclass=*", serverctrls=[request_ctrl]) -+ rtype, rdata, rmsgid, response_ctrl = topology.standalone.result3(msg_id) -+ value = '' -+ for dn, attrs in rdata: -+ topology.standalone.log.info("dn: %s" % dn) -+ for value in attrs['entryLevelRights']: -+ topology.standalone.log.info("############### entryLevelRights: %r" % value) -+ assert 'n' not in value -+ -+def test_ticket47553_rdn_write_modrdn_anonymous(topology): -+ ANONYMOUS_DN = "" -+ topology.standalone.close() -+ topology.standalone.binddn = ANONYMOUS_DN -+ topology.standalone.open() -+ msg_id = topology.standalone.search_ext("", ldap.SCOPE_BASE, "objectclass=*") -+ rtype, rdata, rmsgid, response_ctrl = topology.standalone.result3(msg_id) -+ value = '' -+ for dn, attrs in rdata: -+ topology.standalone.log.info("dn: %s" % dn) -+ for attr in attrs: -+ topology.standalone.log.info("############### %r: %r" % (attr, attrs[attr])) -+ -+ -+ try: -+ topology.standalone.rename_s(SRC_ENTRY_DN, "cn=%s" % DST_ENTRY_CN, delold=True) -+ except Exception as e: -+ topology.standalone.log.info("Exception (expected): %s" % type(e).__name__) -+ isinstance(e, ldap.INSUFFICIENT_ACCESS) -+ -+ try: -+ topology.standalone.getEntry(DST_ENTRY_DN, ldap.SCOPE_BASE, "objectclass=*") -+ assert False -+ except Exception as e: -+ topology.standalone.log.info("The entry was not renamed (expected)") -+ isinstance(e, ldap.NO_SUCH_OBJECT) -+ -+def test_ticket47553_rdn_write(topology): -+ ''' -+ Write your testcase here... -+ ''' -+ -+ log.info('Test complete') -+ -+ -+def test_ticket47553_rdn_write_final(topology): -+ topology.standalone.delete() -+ log.info('Testcase PASSED') -+ -+ -+def run_isolated(): -+ global installation1_prefix -+ installation1_prefix = '/home/tbordaz/install_master' -+ -+ topo = topology(True) -+ test_ticket47553_rdn_write_init(topo) -+ test_ticket47553_rdn_write_get_ger(topo) -+ test_ticket47553_rdn_write(topo) -+ test_ticket47553_rdn_write_modrdn_anonymous(topo) -+ test_ticket47553_rdn_write_final(topo) -+ -+ -+if __name__ == '__main__': -+ run_isolated() -+ -diff --git a/dirsrvtests/tickets/ticket47553_single_aci_test.py b/dirsrvtests/tickets/ticket47553_single_aci_test.py -index 4be2470..0c8d7e9 100644 ---- a/dirsrvtests/tickets/ticket47553_single_aci_test.py -+++ b/dirsrvtests/tickets/ticket47553_single_aci_test.py -@@ -276,7 +276,27 @@ def _moddn_aci_deny_tree(topology, mod_type=None, target_from=STAGING_DN, target - #topology.master1.modify_s(SUFFIX, mod) - topology.master1.log.info("Add a DENY aci under %s " % PROD_EXCEPT_DN) - topology.master1.modify_s(PROD_EXCEPT_DN, mod) -- -+ -+def _write_aci_staging(topology, mod_type=None): -+ assert mod_type is not None -+ -+ ACI_TARGET = "(targetattr= \"cn\")(target=\"ldap:///cn=*,%s\")" % STAGING_DN -+ ACI_ALLOW = "(version 3.0; acl \"write staging entries\"; allow (write)" -+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN -+ ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT -+ mod = [(mod_type, 'aci', ACI_BODY)] -+ topology.master1.modify_s(SUFFIX, mod) -+ -+def _write_aci_production(topology, mod_type=None): -+ assert mod_type is not None -+ -+ ACI_TARGET = "(targetattr= \"cn\")(target=\"ldap:///cn=*,%s\")" % PRODUCTION_DN -+ ACI_ALLOW = "(version 3.0; acl \"write production entries\"; allow (write)" -+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN -+ ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT -+ mod = [(mod_type, 'aci', ACI_BODY)] -+ topology.master1.modify_s(SUFFIX, mod) -+ - def _moddn_aci_staging_to_production(topology, mod_type=None, target_from=STAGING_DN, target_to=PRODUCTION_DN): - assert mod_type != None - -@@ -293,6 +313,8 @@ def _moddn_aci_staging_to_production(topology, mod_type=None, target_from=STAGIN - ACI_BODY = ACI_TARGET_FROM + ACI_TARGET_TO + ACI_ALLOW + ACI_SUBJECT - mod = [(mod_type, 'aci', ACI_BODY)] - topology.master1.modify_s(SUFFIX, mod) -+ -+ _write_aci_staging(topology, mod_type=mod_type) - - def _moddn_aci_from_production_to_staging(topology, mod_type=None): - assert mod_type != None -@@ -303,6 +325,8 @@ def _moddn_aci_from_production_to_staging(topology, mod_type=None): - ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT - mod = [(mod_type, 'aci', ACI_BODY)] - topology.master1.modify_s(SUFFIX, mod) -+ -+ _write_aci_production(topology, mod_type=mod_type) - - - def test_ticket47553_init(topology): -@@ -347,12 +371,9 @@ def test_ticket47553_init(topology): - 'description': "production except DIT"}))) - - # enable acl error logging -- #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')] -- #topology.master1.modify_s(DN_CONFIG, mod) -- #topology.master2.modify_s(DN_CONFIG, mod) -- -- -- -+ mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', str(128+262144))] -+ topology.master1.modify_s(DN_CONFIG, mod) -+ topology.master2.modify_s(DN_CONFIG, mod) - - - # add dummy entries in the staging DIT -@@ -883,6 +904,7 @@ def test_ticket47553_moddn_staging_prod_9(topology): - _bind_manager(topology) - mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)] - topology.master1.modify_s(PRODUCTION_DN, mod) -+ _write_aci_staging(topology, mod_type=ldap.MOD_ADD) - _bind_normal(topology) - - topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior)) -@@ -891,6 +913,7 @@ def test_ticket47553_moddn_staging_prod_9(topology): - _bind_manager(topology) - mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)] - topology.master1.modify_s(PRODUCTION_DN, mod) -+ _write_aci_staging(topology, mod_type=ldap.MOD_DELETE) - _bind_normal(topology) - - -@@ -934,6 +957,7 @@ def test_ticket47553_moddn_staging_prod_9(topology): - _bind_manager(topology) - mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)] - topology.master1.modify_s(PRODUCTION_DN, mod) -+ _write_aci_staging(topology, mod_type=ldap.MOD_ADD) - _bind_normal(topology) - - try: -@@ -949,6 +973,7 @@ def test_ticket47553_moddn_staging_prod_9(topology): - _bind_manager(topology) - mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)] - topology.master1.modify_s(PRODUCTION_DN, mod) -+ _write_aci_staging(topology, mod_type=ldap.MOD_DELETE) - _bind_normal(topology) - - # Add the moddn aci that will be evaluated because of the config flag -@@ -1009,7 +1034,12 @@ def test_ticket47553_moddn_prod_staging(topology): - old_dn = "%s,%s" % (old_rdn, PRODUCTION_DN) - new_rdn = old_rdn - new_superior = STAGING_DN -- -+ -+ # add the write right because we want to check the moddn -+ _bind_manager(topology) -+ _write_aci_production(topology, mod_type=ldap.MOD_ADD) -+ _bind_normal(topology) -+ - try: - topology.master1.log.info("Try to move back MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior)) - topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior) -@@ -1019,7 +1049,11 @@ def test_ticket47553_moddn_prod_staging(topology): - except Exception as e: - topology.master1.log.info("Exception (expected): %s" % type(e).__name__) - assert isinstance(e, ldap.INSUFFICIENT_ACCESS) -- -+ -+ _bind_manager(topology) -+ _write_aci_production(topology, mod_type=ldap.MOD_DELETE) -+ _bind_normal(topology) -+ - # successfull MOD with the both ACI - _bind_manager(topology) - _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN) -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -index 6a4982c..4129318 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -@@ -677,31 +677,17 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) - - /* JCMACL - Should be performed before the child check. */ - /* JCMACL - Why is the check performed against the copy, rather than the existing entry? */ -+ /* This check must be performed even if the entry is renamed with its own name -+ * No optimization here we need to check we have the write access to the target entry -+ */ -+ ldap_result_code = plugin_call_acl_plugin(pb, ec->ep_entry, -+ NULL /*attr*/, NULL /*value*/, SLAPI_ACL_WRITE, -+ ACLPLUGIN_ACCESS_MODRDN, &errbuf); -+ if (ldap_result_code != LDAP_SUCCESS) - { -- Slapi_RDN *new_rdn; -- Slapi_RDN *old_rdn; -- -- /* Taken from the entry */ -- old_rdn = slapi_entry_get_srdn(ec->ep_entry); -- -- /* Taken from the request */ -- new_rdn = slapi_rdn_new(); -- slapi_sdn_get_rdn(&dn_newrdn, new_rdn); -- -- /* Only if we change the RDN value, we need the write access to the entry */ -- if (slapi_rdn_compare(old_rdn, new_rdn)) { -- ldap_result_code = plugin_call_acl_plugin(pb, ec->ep_entry, -- NULL /*attr*/, NULL /*value*/, SLAPI_ACL_WRITE, -- ACLPLUGIN_ACCESS_MODRDN, &errbuf); -- } -- -- slapi_rdn_free(&new_rdn); -+ goto error_return; -+ } - -- if (ldap_result_code != LDAP_SUCCESS) { -- goto error_return; -- } -- } -- - /* Set the new dn to the copy of the entry */ - slapi_entry_set_sdn( ec->ep_entry, &dn_newdn ); - if (entryrdn_get_switch()) { /* subtree-rename: on */ --- -1.9.3 - diff --git a/SOURCES/0062-Ticket-48266-coverity-unused-variable-init_retry.patch b/SOURCES/0062-Ticket-48266-coverity-unused-variable-init_retry.patch new file mode 100644 index 0000000..6f83044 --- /dev/null +++ b/SOURCES/0062-Ticket-48266-coverity-unused-variable-init_retry.patch @@ -0,0 +1,27 @@ +From 02c520c6fa44f9f2499c79e48531b59d62875a39 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Sat, 19 Sep 2015 09:58:39 -0700 +Subject: [PATCH] Ticket 48266 - coverity -- unused variable 'init_retry' + +Description: Backport error for Ticket 48266 - Fractional replication + evaluates several times the same CSN + (commit 05e127c89281cece8bc1fa79bac6b95cc23dcca9) +--- + ldap/servers/plugins/replication/repl5_tot_protocol.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c +index e004af4..7da893a 100644 +--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c +@@ -318,7 +318,6 @@ repl5_tot_run(Private_Repl_Protocol *prp) + int portnum = 0; + Slapi_DN *area_sdn = NULL; + CSN *remote_schema_csn = NULL; +- int init_retry = 0; + Replica *replica; + ReplicaId rid = 0; /* Used to create the replica keep alive subentry */ + +-- +1.9.3 + diff --git a/SOURCES/0063-Ticket-48190-idm-ipa-389-ds-base-entry-cache-converg.patch b/SOURCES/0063-Ticket-48190-idm-ipa-389-ds-base-entry-cache-converg.patch deleted file mode 100644 index e98f7e6..0000000 --- a/SOURCES/0063-Ticket-48190-idm-ipa-389-ds-base-entry-cache-converg.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 82d69a381183cf5125ba8d4afdfd12c65544e348 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Sun, 31 May 2015 17:08:29 -0700 -Subject: [PATCH 63/72] Ticket #48190 - idm/ipa 389-ds-base entry cache - converges to 500 KB in dblayer_is_cachesize_sane - -Description: This issue was introduced by the fix for Ticket 47499 -commit 1e035d1111f6abcb87e760a2b9e41fa9e05a7ebd. - -The function dblayer_is_cachesize_sane was originally implemented for -db cache to check if the given db cache size is larger than the available -memory or not. The function resets the size to the available memory size -if it is larger. Also, considering the extra metadata size needed for the -db cache, it multiplies by 0.8 every time it starts the server. It is not -needed even for the db cache. The code is old and we don't have to save -the memory there. Thus, this patch removes the resetting code. - -https://fedorahosted.org/389/ticket/48190 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit bf9ef718cfd48c26eaf11662f522451d866e7681) ---- - ldap/servers/slapd/back-ldbm/dblayer.c | 7 ------- - ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 6 ++++-- - 2 files changed, 4 insertions(+), 9 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index 2524355..d3deff8 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -1116,13 +1116,6 @@ int dblayer_is_cachesize_sane(size_t *cachesize) - if (!issane) { - *cachesize = (size_t)((pages - procpages) * pagesize); - } -- /* We now compensate for DB's own compensation for metadata size -- * They increase the actual cache size by 25%, but only for sizes -- * less than 500Meg. -- */ -- if (*cachesize < 500*MEGABYTE) { -- *cachesize = (size_t)((double)*cachesize * (double)0.8); -- } - - return issane; - } -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c -index 9b93f9a..f75ca97 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c -@@ -121,11 +121,12 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in - ldbm_instance *inst = (ldbm_instance *) arg; - int retval = LDAP_SUCCESS; - size_t val = (size_t) value; -+ size_t chkval = val; - - /* Do whatever we can to make sure the data is ok. */ - - if (apply) { -- if (!dblayer_is_cachesize_sane(&val)){ -+ if (!dblayer_is_cachesize_sane(&chkval)){ - PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, - "Error: cachememsize value is too large."); - LDAPDebug( LDAP_DEBUG_ANY,"Error: cachememsize value is too large.\n", -@@ -152,11 +153,12 @@ ldbm_instance_config_dncachememsize_set(void *arg, void *value, char *errorbuf, - ldbm_instance *inst = (ldbm_instance *) arg; - int retval = LDAP_SUCCESS; - size_t val = (size_t)value; -+ size_t chkval = val; - - /* Do whatever we can to make sure the data is ok. */ - - if (apply) { -- if (!dblayer_is_cachesize_sane(&val)){ -+ if (!dblayer_is_cachesize_sane(&chkval)){ - PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, - "Error: dncachememsize value is too large."); - LDAPDebug( LDAP_DEBUG_ANY,"Error: dncachememsize value is too large.\n", --- -1.9.3 - diff --git a/SOURCES/0063-Ticket-48266-Online-init-crashes-consumer.patch b/SOURCES/0063-Ticket-48266-Online-init-crashes-consumer.patch new file mode 100644 index 0000000..2d85f36 --- /dev/null +++ b/SOURCES/0063-Ticket-48266-Online-init-crashes-consumer.patch @@ -0,0 +1,41 @@ +From 060b9298fd03cbdac725be398e7754f67aa2b5c1 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 22 Sep 2015 09:49:12 -0400 +Subject: [PATCH 63/65] Ticket 48266 - Online init crashes consumer + +Bug Description: When trying to create the 'replica keep alive' entry + on a consumer during an online init, the entry gets freed + in op_shared_add(), and then freed again in + replica_subentry_create() which leads to a crash. + +Fix Description: Do not free the "keep alive" entry if a referral is + returned when trying to create the keep-alive entry. + +https://fedorahosted.org/389/ticket/48266 + +Reviewed by: tbordaz(Thanks!) + +(cherry picked from commit 5538bac519c5363bb456e98d615c9366dedd57d8) +(cherry picked from commit 1c127b40c1c7298839562326babbf2cba65cce1b) +--- + ldap/servers/plugins/replication/repl5_replica.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 6ac28c1..708008c 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -448,7 +448,9 @@ replica_subentry_create(Slapi_DN *repl_root, ReplicaId rid) + repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0 /* flags */); + slapi_add_internal_pb(pb); + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value); +- if (return_value != LDAP_SUCCESS && return_value != LDAP_ALREADY_EXISTS) ++ if (return_value != LDAP_SUCCESS && ++ return_value != LDAP_ALREADY_EXISTS && ++ return_value != LDAP_REFERRAL /* CONSUMER */) + { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Warning: unable to " + "create replication keep alive entry %s: %s\n", slapi_entry_get_dn_const(e), +-- +1.9.3 + diff --git a/SOURCES/0064-Ticket-48146-async-simple-paged-results-issue.patch b/SOURCES/0064-Ticket-48146-async-simple-paged-results-issue.patch deleted file mode 100644 index 6027eef..0000000 --- a/SOURCES/0064-Ticket-48146-async-simple-paged-results-issue.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 577fa6ada5d860e5ed7291aff2e41938ca92793b Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Sun, 26 Apr 2015 14:46:44 -0700 -Subject: [PATCH 64/72] Ticket #48146 - async simple paged results issue - -Description: When the last page of the single paged results is returned, -the search results structure is freed in the simple paged results code -(in op_shared_search). The search results structure is stashed in the -simple paged results object across the pages. The free and the clean up -of the stashed address should have been atomic, but it was not. - -https://fedorahosted.org/389/ticket/48146 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 947477f2e2367337a8c220d8c9d03a62bf1bbf1c) -(cherry picked from commit ec8801a69adbe2f502513fabcbb79bc5e38bf197) ---- - ldap/servers/slapd/opshared.c | 18 +++++++----------- - ldap/servers/slapd/pagedresults.c | 36 +++++++++++------------------------- - 2 files changed, 18 insertions(+), 36 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index ebd4fdf..e7cee8a 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -881,7 +881,10 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); - if (PAGEDRESULTS_SEARCH_END == pr_stat) { - if (sr) { /* in case a left over sr is found, clean it up */ -+ PR_Lock(pb->pb_conn->c_mutex); -+ pagedresults_set_search_result(pb->pb_conn, operation, NULL, 1, pr_idx); - be->be_search_results_release(&sr); -+ PR_Unlock(pb->pb_conn->c_mutex); - } - if (NULL == next_be) { - /* no more entries && no more backends */ -@@ -897,17 +900,10 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate); - pagedresults_lock(pb->pb_conn, pr_idx); - if ((pagedresults_set_current_be(pb->pb_conn, be, pr_idx) < 0) || -- (pagedresults_set_search_result(pb->pb_conn, operation, -- sr, 0, pr_idx) < 0) || -- (pagedresults_set_search_result_count(pb->pb_conn, operation, -- curr_search_count, -- pr_idx) < 0) || -- (pagedresults_set_search_result_set_size_estimate(pb->pb_conn, -- operation, -- estimate, -- pr_idx) < 0) || -- (pagedresults_set_with_sort(pb->pb_conn, operation, -- with_sort, pr_idx) < 0)) { -+ (pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx) < 0) || -+ (pagedresults_set_search_result_count(pb->pb_conn, operation, curr_search_count, pr_idx) < 0) || -+ (pagedresults_set_search_result_set_size_estimate(pb->pb_conn, operation, estimate, pr_idx) < 0) || -+ (pagedresults_set_with_sort(pb->pb_conn, operation, with_sort, pr_idx) < 0)) { - pagedresults_unlock(pb->pb_conn, pr_idx); - goto free_and_return; - } -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index d589708..e61c000 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -100,26 +100,20 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - ber_free(ber, 1); - if ( cookie.bv_len <= 0 ) { - int i; -- int maxlen; - /* first time? */ -- maxlen = conn->c_pagedresults.prl_maxlen; -+ int maxlen = conn->c_pagedresults.prl_maxlen; - if (conn->c_pagedresults.prl_count == maxlen) { - if (0 == maxlen) { /* first time */ - conn->c_pagedresults.prl_maxlen = 1; -- conn->c_pagedresults.prl_list = -- (PagedResults *)slapi_ch_calloc(1, -- sizeof(PagedResults)); -+ conn->c_pagedresults.prl_list = (PagedResults *)slapi_ch_calloc(1, sizeof(PagedResults)); - } else { - /* new max length */ - conn->c_pagedresults.prl_maxlen *= 2; -- conn->c_pagedresults.prl_list = -- (PagedResults *)slapi_ch_realloc( -+ conn->c_pagedresults.prl_list = (PagedResults *)slapi_ch_realloc( - (char *)conn->c_pagedresults.prl_list, -- sizeof(PagedResults) * -- conn->c_pagedresults.prl_maxlen); -+ sizeof(PagedResults) * conn->c_pagedresults.prl_maxlen); - /* initialze newly allocated area */ -- memset(conn->c_pagedresults.prl_list + maxlen, '\0', -- sizeof(PagedResults) * maxlen); -+ memset(conn->c_pagedresults.prl_list + maxlen, '\0', sizeof(PagedResults) * maxlen); - } - *index = maxlen; /* the first position in the new area */ - } else { -@@ -276,8 +270,8 @@ pagedresults_free_one( Connection *conn, Operation *op, int index ) - prp->pr_current_be->be_search_results_release && - prp->pr_search_result_set) { - prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); -- prp->pr_current_be = NULL; - } -+ prp->pr_current_be = NULL; - if (prp->pr_mutex) { - /* pr_mutex is reused; back it up and reset it. */ - prmutex = prp->pr_mutex; -@@ -314,8 +308,8 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid ) - prp->pr_current_be->be_search_results_release && - prp->pr_search_result_set) { - prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); -- prp->pr_current_be = NULL; - } -+ prp->pr_current_be = NULL; - prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED; - prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING; - conn->c_pagedresults.prl_count--; -@@ -404,16 +398,8 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, - if (conn && (index > -1)) { - if (!locked) PR_Lock(conn->c_mutex); - if (index < conn->c_pagedresults.prl_maxlen) { -- if (sr) { /* set */ -- if (NULL == -- conn->c_pagedresults.prl_list[index].pr_search_result_set) { -- conn->c_pagedresults.prl_list[index].pr_search_result_set = sr; -- rc = 0; -- } -- } else { /* reset */ -- conn->c_pagedresults.prl_list[index].pr_search_result_set = sr; -- rc = 0; -- } -+ conn->c_pagedresults.prl_list[index].pr_search_result_set = sr; -+ rc = 0; - } - if (!locked) PR_Unlock(conn->c_mutex); - } -@@ -732,9 +718,9 @@ pagedresults_cleanup(Connection *conn, int needlock) - if (prp->pr_current_be && prp->pr_search_result_set && - prp->pr_current_be->be_search_results_release) { - prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); -- prp->pr_current_be = NULL; - rc = 1; - } -+ prp->pr_current_be = NULL; - if (prp->pr_mutex) { - PR_DestroyLock(prp->pr_mutex); - } -@@ -780,9 +766,9 @@ pagedresults_cleanup_all(Connection *conn, int needlock) - if (prp->pr_current_be && prp->pr_search_result_set && - prp->pr_current_be->be_search_results_release) { - prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); -- prp->pr_current_be = NULL; - rc = 1; - } -+ prp->pr_current_be = NULL; - } - slapi_ch_free((void **)&conn->c_pagedresults.prl_list); - conn->c_pagedresults.prl_maxlen = 0; --- -1.9.3 - diff --git a/SOURCES/0064-Ticket-48284-free-entry-when-internal-add-fails.patch b/SOURCES/0064-Ticket-48284-free-entry-when-internal-add-fails.patch new file mode 100644 index 0000000..ebe138e --- /dev/null +++ b/SOURCES/0064-Ticket-48284-free-entry-when-internal-add-fails.patch @@ -0,0 +1,53 @@ +From d1598673937a83127249e6c26de6af3a18a5f51c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 22 Sep 2015 13:41:06 -0400 +Subject: [PATCH 64/65] Ticket 48284 - free entry when internal add fails + +Bug Description: The entry passed to an internal add operaton is expected + to be consumed, but it is not freed during an internal + add when setting slapi_add_internal_pb() returns an error. + +Fix Description: Free the entry in slapi_add_internal_pb() when the operation + is not allowed. + +https://fedorahosted.org/389/ticket/48284 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit 622be8bfbc942fe100b8880df72db26e99e1c954) +(cherry picked from commit 99dbfb7601daea80f80d1ea9d29766d76555e01a) +--- + ldap/servers/slapd/add.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c +index 5eb2042..31012a2 100644 +--- a/ldap/servers/slapd/add.c ++++ b/ldap/servers/slapd/add.c +@@ -316,6 +316,12 @@ int slapi_add_internal_pb (Slapi_PBlock *pb) + + if (!allow_operation (pb)) + { ++ /* free the entry as it's expected to be consumed */ ++ Slapi_Entry *e; ++ slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e); ++ slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); ++ slapi_entry_free(e); ++ + slapi_send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, + "This plugin is not configured to access operation target data", 0, NULL ); + return 0; +@@ -727,8 +733,8 @@ static void op_shared_add (Slapi_PBlock *pb) + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); + do_ps_service(pse, NULL, LDAP_CHANGETYPE_ADD, 0); + /* +- * If be_add succeeded, then e is consumed except the resurect case. +- * If it is resurect, the corresponding tombstone entry is resurected ++ * If be_add succeeded, then e is consumed except the resurrect case. ++ * If it is resurrect, the corresponding tombstone entry is resurrected + * and put into the cache. + * Otherwise, we set e to NULL to prevent freeing it ourselves. + */ +-- +1.9.3 + diff --git a/SOURCES/0065-Ticket-48146-async-simple-paged-results-issue-log-pr.patch b/SOURCES/0065-Ticket-48146-async-simple-paged-results-issue-log-pr.patch deleted file mode 100644 index e07e791..0000000 --- a/SOURCES/0065-Ticket-48146-async-simple-paged-results-issue-log-pr.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 01fb4193778aa165070c3a8b4fe2c48e83ce3828 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Fri, 1 May 2015 10:50:39 -0700 -Subject: [PATCH 65/72] Ticket #48146 - async simple paged results issue; log - pr index - -Description: When the request is a simple paged results search, - log pr index in the access log. -Sample access log for "getent netgroup ": - [..] conn=23 op=521 SRCH base="cn=accounts,dc=testrelm,dc=test" scope=2 filter="(&(|(memberOf=ipaUniqueID=3036b6a0-ee18-11e4-b7dd-00215e2032c0,cn=ng,cn=alt,dc=testrelm,dc=test))(objectClass=ipaHost))" attrs="objectClass cn fqdn serverHostName memberOf ipaSshPubKey ipaUniqueID" - [..] conn=23 op=521 RESULT err=0 tag=101 nentries=200 etime=0 notes=P pr_idx=3 - -https://fedorahosted.org/389/ticket/48146 - -Reviewed by rmeggins@redhat.com (Thanks, Rich!!) - -(cherry picked from commit 9eb20d89755160aa916544c7cfce0ad066e538f7) ---- - ldap/servers/slapd/result.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c -index 2198337..226f01c 100644 ---- a/ldap/servers/slapd/result.c -+++ b/ldap/servers/slapd/result.c -@@ -1961,6 +1961,9 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie - CSN *operationcsn = NULL; - char csn_str[CSN_STRSIZE + 5]; - char etime[ETIME_BUFSIZ]; -+ int pr_idx = -1; -+ -+ slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx); - - internal_op = operation_is_flag_set( op, OP_FLAG_INTERNAL ); - -@@ -2054,7 +2057,34 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie - } - slapi_ch_free((void**)&dn); - } else { -- if ( !internal_op ) -+ if (pr_idx > -1) -+ { -+ if ( !internal_op ) -+ { -+ slapi_log_access( LDAP_DEBUG_STATS, -+ "conn=%" NSPRIu64 " op=%d RESULT err=%d" -+ " tag=%" BERTAG_T " nentries=%d etime=%s%s%s" -+ " pr_idx=%d\n", -+ op->o_connid, -+ op->o_opid, -+ err, tag, nentries, -+ etime, -+ notes_str, csn_str, pr_idx ); -+ } -+ else -+ { -+ slapi_log_access( LDAP_DEBUG_ARGS, -+ "conn=%s op=%d RESULT err=%d" -+ " tag=%" BERTAG_T " nentries=%d etime=%s%s%s" -+ " pr_idx=%d\n", -+ LOG_INTERNAL_OP_CON_ID, -+ LOG_INTERNAL_OP_OP_ID, -+ err, tag, nentries, -+ etime, -+ notes_str, csn_str, pr_idx ); -+ } -+ } -+ else if ( !internal_op ) - { - slapi_log_access( LDAP_DEBUG_STATS, - "conn=%" NSPRIu64 " op=%d RESULT err=%d" --- -1.9.3 - diff --git a/SOURCES/0065-Ticket-48266-do-not-free-repl-keep-alive-entry-on-er.patch b/SOURCES/0065-Ticket-48266-do-not-free-repl-keep-alive-entry-on-er.patch new file mode 100644 index 0000000..23541a8 --- /dev/null +++ b/SOURCES/0065-Ticket-48266-do-not-free-repl-keep-alive-entry-on-er.patch @@ -0,0 +1,35 @@ +From 3a3d1f22ea262270bc859aeb4c80928d5a085817 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 22 Sep 2015 13:58:38 -0400 +Subject: [PATCH 65/65] Ticket 48266 - do not free repl keep alive entry on + error + +Description: There is no need to free the "repl keep alive" entry + if any stage of the "add" fails. Otherwise we could + potentially run into a double free. + +https://fedorahosted.org/389/ticket/48266 + +Reviewed by: nhosoi(Thanks!) + +(cherry picked from commit e5d9b0c741af1c3ea5e8212148a3ba95ee18925b) +(cherry picked from commit f95e73f620987de9107246b30b28fd463024b61f) +--- + ldap/servers/plugins/replication/repl5_replica.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 708008c..8b53f3c 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -456,7 +456,6 @@ replica_subentry_create(Slapi_DN *repl_root, ReplicaId rid) + "create replication keep alive entry %s: %s\n", slapi_entry_get_dn_const(e), + ldap_err2string(return_value)); + rc = -1; +- slapi_entry_free(e); /* The entry was not consumed */ + goto done; + } + +-- +1.9.3 + diff --git a/SOURCES/0066-Ticket-48146-async-simple-paged-results-issue-need-t.patch b/SOURCES/0066-Ticket-48146-async-simple-paged-results-issue-need-t.patch deleted file mode 100644 index 4b7aec6..0000000 --- a/SOURCES/0066-Ticket-48146-async-simple-paged-results-issue-need-t.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 39e430f55e61605d27849c0f17e37e046cbbda72 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Fri, 1 May 2015 12:01:13 -0700 -Subject: [PATCH 66/72] Ticket #48146 - async simple paged results issue; need - to close a small window for a pr index competed among multiple threads. - -Description: If multiple async simple paged results requests come in via one -connection simultaneously, the same slot in the paged results array in the -connection could be shared. If one of them has to do paging, the search -request object stashed in the paged result array slot could be freed by the -other request if it has the shorter life cycle. - -These 3 reqs use the same paged results array slot. -req0: <--------------><----x -page1 page2 -req1: <-----> -req2: <-------> -frees search result object of req0 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit 3cf85d1ad6cbc0feac5578dee5ce259c0f65055f) ---- - ldap/servers/slapd/opshared.c | 93 +++++++++++++++++++-------------------- - ldap/servers/slapd/pagedresults.c | 3 +- - ldap/servers/slapd/proto-slap.h | 2 +- - 3 files changed, 49 insertions(+), 49 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index e7cee8a..430b0c6 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -408,6 +408,51 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - */ - operation_set_target_spec (pb->pb_op, basesdn); - -+ if (be_name == NULL) -+ { -+ /* no specific backend was requested, use the mapping tree -+ */ -+ err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); -+ if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) -+ || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) -+ { -+ send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); -+ rc = -1; -+ goto free_and_return; -+ } -+ if (be_list[0] != NULL) -+ { -+ index = 0; -+ if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */ -+ /* move the index in the be_list which matches pr_be */ -+ while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) -+ index++; -+ } else { -+ while (be_list[index] && be_list[index+1]) -+ index++; -+ } -+ /* "be" is either pr_be or the last backend */ -+ be = be_list[index]; -+ } -+ else -+ be = pr_be?pr_be:NULL; -+ } -+ else -+ { -+ /* specific backend be_name was requested, use slapi_be_select_by_instance_name -+ */ -+ if (pr_be) { -+ be_single = be = pr_be; -+ } else { -+ be_single = be = slapi_be_select_by_instance_name(be_name); -+ } -+ if (be_single) -+ slapi_be_Rlock(be_single); -+ be_list[0] = NULL; -+ referral_list[0] = NULL; -+ referral = NULL; -+ } -+ - /* this is time to check if mapping tree specific control - * was used to specify that we want to parse only - * one backend -@@ -478,8 +523,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - if ( slapi_control_present (ctrlp, LDAP_CONTROL_PAGEDRESULTS, - &ctl_value, &iscritical) ) - { -- rc = pagedresults_parse_control_value(pb, ctl_value, -- &pagesize, &pr_idx); -+ rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be); - /* Let's set pr_idx even if it fails; in case, pr_idx == -1. */ - slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx); - if ((LDAP_SUCCESS == rc) || -@@ -520,51 +564,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - } - } - -- if (be_name == NULL) -- { -- /* no specific backend was requested, use the mapping tree -- */ -- err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); -- if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) -- || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) -- { -- send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); -- rc = -1; -- goto free_and_return; -- } -- if (be_list[0] != NULL) -- { -- index = 0; -- if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */ -- /* move the index in the be_list which matches pr_be */ -- while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) -- index++; -- } else { -- while (be_list[index] && be_list[index+1]) -- index++; -- } -- /* "be" is either pr_be or the last backend */ -- be = be_list[index]; -- } -- else -- be = pr_be?pr_be:NULL; -- } -- else -- { -- /* specific backend be_name was requested, use slapi_be_select_by_instance_name -- */ -- if (pr_be) { -- be_single = be = pr_be; -- } else { -- be_single = be = slapi_be_select_by_instance_name(be_name); -- } -- if (be_single) -- slapi_be_Rlock(be_single); -- be_list[0] = NULL; -- referral_list[0] = NULL; -- referral = NULL; -- } -- - slapi_pblock_set(pb, SLAPI_BACKEND_COUNT, &index); - - if (be) -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index e61c000..a3a5fc4 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -58,7 +58,7 @@ - int - pagedresults_parse_control_value( Slapi_PBlock *pb, - struct berval *psbvp, ber_int_t *pagesize, -- int *index ) -+ int *index, Slapi_Backend *be ) - { - int rc = LDAP_SUCCESS; - struct berval cookie = {0}; -@@ -119,6 +119,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - } else { - for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { - if (!conn->c_pagedresults.prl_list[i].pr_current_be) { -+ conn->c_pagedresults.prl_list[i].pr_current_be = be; - *index = i; - break; - } -diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h -index c987b4a..80504b2 100644 ---- a/ldap/servers/slapd/proto-slap.h -+++ b/ldap/servers/slapd/proto-slap.h -@@ -1467,7 +1467,7 @@ int slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt, - * pagedresults.c - */ - int pagedresults_parse_control_value(Slapi_PBlock *pb, struct berval *psbvp, -- ber_int_t *pagesize, int *index); -+ ber_int_t *pagesize, int *index, Slapi_Backend *be); - void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, - ber_int_t estimate, - int curr_search_count, int index); --- -1.9.3 - diff --git a/SOURCES/0066-Ticket-48299-pagedresults-when-timed-out-search-resu.patch b/SOURCES/0066-Ticket-48299-pagedresults-when-timed-out-search-resu.patch new file mode 100644 index 0000000..d2e826c --- /dev/null +++ b/SOURCES/0066-Ticket-48299-pagedresults-when-timed-out-search-resu.patch @@ -0,0 +1,123 @@ +From 695f06f02f6285bad4c494fda98f8f17ace2d1aa Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Wed, 30 Sep 2015 13:32:05 -0700 +Subject: [PATCH 66/68] Ticket #48299 - pagedresults - when timed out, search + results could have been already freed. + +Description: When a search results object is freed, there is a window +until the information is set to the pagedresults handle. If the paged- +results handle is released due to a timeout in the window, double free +occurs. + +This patch sets NULL just before the search results object is freed +in the backend as well as in dse. + +Plus, fixed a minor memory leak in pagedresults_parse_control_value. + +https://fedorahosted.org/389/ticket/48299 + +Reviewed and a bug found by tbordaz@redhat.com (Thank you, Thierry!!) + +(cherry picked from commit f90c3a6e1933b9cc19a51b17a038f26652c4b2bc) +(cherry picked from commit 56151ed75bbd63af80932fe73a512df835b17593) +--- + ldap/servers/slapd/back-ldbm/ldbm_search.c | 1 + + ldap/servers/slapd/dse.c | 1 + + ldap/servers/slapd/pagedresults.c | 33 +++++++++++++++++++++++++++++- + ldap/servers/slapd/proto-slap.h | 1 + + 4 files changed, 35 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c +index 73c54d3..8ed6b4d 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c +@@ -1890,6 +1890,7 @@ delete_search_result_set( Slapi_PBlock *pb, back_search_result_set **sr ) + /* If the op is pagedresults, let the module clean up sr. */ + return; + } ++ pagedresults_set_search_result_pb(pb, NULL, 0); + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); + } + if ( NULL != (*sr)->sr_candidates ) +diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c +index e8e393b..68ce751 100644 +--- a/ldap/servers/slapd/dse.c ++++ b/ldap/servers/slapd/dse.c +@@ -2830,6 +2830,7 @@ dse_next_search_entry (Slapi_PBlock *pb) + /* we reached the end of the list */ + if (e == NULL) + { ++ pagedresults_set_search_result_pb(pb, NULL, 0); + dse_search_set_delete (ss); + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); + } +diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c +index d0c93cd..6dd6432 100644 +--- a/ldap/servers/slapd/pagedresults.c ++++ b/ldap/servers/slapd/pagedresults.c +@@ -172,7 +172,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, + } + /* reset sizelimit */ + op->o_pagedresults_sizelimit = -1; +- slapi_ch_free((void **)&cookie.bv_val); + + if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) { + if (conn->c_pagedresults.prl_list[*index].pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) { +@@ -189,6 +188,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, + LDAPDebug1Arg(LDAP_DEBUG_ANY, "pagedresults_parse_control_value: invalid cookie: %d\n", *index); + } + bail: ++ slapi_ch_free((void **)&cookie.bv_val); + /* cleaning up the rest of the timedout or abandoned if any */ + prp = conn->c_pagedresults.prl_list; + for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) { +@@ -1010,3 +1010,34 @@ pagedresults_is_abandoned_or_notavailable( Connection *conn, int index ) + PR_Unlock(conn->c_mutex); + return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; + } ++ ++int ++pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked) ++{ ++ int rc = -1; ++ Connection *conn = NULL; ++ Operation *op = NULL; ++ int index = -1; ++ if (!pb) { ++ return 0; ++ } ++ slapi_pblock_get(pb, SLAPI_OPERATION, &op); ++ if (!op_is_pagedresults(op)) { ++ return 0; /* noop */ ++ } ++ slapi_pblock_get(pb, SLAPI_CONNECTION, &conn); ++ slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &index); ++ LDAPDebug2Args(LDAP_DEBUG_TRACE, ++ "--> pagedresults_set_search_result_pb: idx=%d, sr=%p\n", index, sr); ++ if (conn && (index > -1)) { ++ if (!locked) PR_Lock(conn->c_mutex); ++ if (index < conn->c_pagedresults.prl_maxlen) { ++ conn->c_pagedresults.prl_list[index].pr_search_result_set = sr; ++ rc = 0; ++ } ++ if (!locked) PR_Unlock(conn->c_mutex); ++ } ++ LDAPDebug1Arg(LDAP_DEBUG_TRACE, ++ "<-- pagedresults_set_search_result_pb: %d\n", rc); ++ return rc; ++} +diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h +index e8673e1..b10c1eb 100644 +--- a/ldap/servers/slapd/proto-slap.h ++++ b/ldap/servers/slapd/proto-slap.h +@@ -1488,6 +1488,7 @@ void op_set_pagedresults(Operation *op); + void pagedresults_lock(Connection *conn, int index); + void pagedresults_unlock(Connection *conn, int index); + int pagedresults_is_abandoned_or_notavailable(Connection *conn, int index); ++int pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked); + + /* + * sort.c +-- +1.9.3 + diff --git a/SOURCES/0067-Ticket-48146-async-simple-paged-results-issue.patch b/SOURCES/0067-Ticket-48146-async-simple-paged-results-issue.patch deleted file mode 100644 index a89acd4..0000000 --- a/SOURCES/0067-Ticket-48146-async-simple-paged-results-issue.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3e34dcaf4899a5379d40d80f2eee7821b2604702 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 4 May 2015 14:06:43 -0700 -Subject: [PATCH 67/72] Ticket #48146 - async simple paged results issue - -Description: Invalid index could cause Invalid read. - -https://fedorahosted.org/389/ticket/48146 -(cherry picked from commit 8e21bfbe4fcac79cf39e5c6b579c4bc88e05257e) ---- - ldap/servers/slapd/pagedresults.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index a3a5fc4..327da54 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -138,6 +138,13 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - memcpy(ptr, cookie.bv_val, cookie.bv_len); - *(ptr+cookie.bv_len) = '\0'; - *index = strtol(ptr, NULL, 10); -+ if (conn->c_pagedresults.prl_maxlen <= *index) { -+ rc = LDAP_PROTOCOL_ERROR; -+ LDAPDebug1Arg(LDAP_DEBUG_ANY, -+ "pagedresults_parse_control_value: invalid cookie: %d\n", -+ *index); -+ goto bail; -+ } - slapi_ch_free_string(&ptr); - prp = conn->c_pagedresults.prl_list + *index; - if (!(prp->pr_search_result_set)) { /* freed and reused for the next backend. */ -@@ -162,6 +169,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - "pagedresults_parse_control_value: invalid cookie: %d\n", - *index); - } -+bail: - PR_Unlock(conn->c_mutex); - - LDAPDebug1Arg(LDAP_DEBUG_TRACE, --- -1.9.3 - diff --git a/SOURCES/0067-Ticket-48192-Individual-abandoned-simple-paged-resul.patch b/SOURCES/0067-Ticket-48192-Individual-abandoned-simple-paged-resul.patch new file mode 100644 index 0000000..913e0c4 --- /dev/null +++ b/SOURCES/0067-Ticket-48192-Individual-abandoned-simple-paged-resul.patch @@ -0,0 +1,53 @@ +From 6b1aeee584c74c47abf8f7190d4783c061607279 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Thu, 1 Oct 2015 15:11:24 -0700 +Subject: [PATCH 67/68] Ticket #48192 - Individual abandoned simple paged + results request has no chance to be cleaned up + +Description: If CONN_FLAG_PAGEDRESULTS_ABANDONED is set to pr_flags, +the search results in the pagedresults handle is supposed to have been +cleaned up. But when there is a contention, there is a case that it +is reset with the already released search results. This patch adds an +additional check for abandoned flag in pagedresults_set_search_result. +If the pagedresults handle shows it is abandoned, the search results +is not set to the handle unless it is for cleaning up with NULL. + +https://fedorahosted.org/389/ticket/48192 + +Reviewed by rmeggins@redhat.com (Thanks, Rich!!) + +(cherry picked from commit 6e453918e82af6c597390aebf92a8eb3283c3591) +(cherry picked from commit 96b9b6794e0a6bfa0d74c84f6c80131c4f820fa7) +--- + ldap/servers/slapd/pagedresults.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c +index 6dd6432..87447c4 100644 +--- a/ldap/servers/slapd/pagedresults.c ++++ b/ldap/servers/slapd/pagedresults.c +@@ -337,7 +337,7 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid ) + for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { + if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) { + PagedResults *prp = conn->c_pagedresults.prl_list + i; +- if (prp && prp->pr_current_be && ++ if (prp->pr_current_be && + prp->pr_current_be->be_search_results_release && + prp->pr_search_result_set) { + prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); +@@ -429,7 +429,11 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, + if (conn && (index > -1)) { + if (!locked) PR_Lock(conn->c_mutex); + if (index < conn->c_pagedresults.prl_maxlen) { +- conn->c_pagedresults.prl_list[index].pr_search_result_set = sr; ++ PagedResults *prp = conn->c_pagedresults.prl_list + index; ++ if (!(prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) || !sr) { ++ /* If abandoned, don't set the search result unless it is NULL */ ++ prp->pr_search_result_set = sr; ++ } + rc = 0; + } + if (!locked) PR_Unlock(conn->c_mutex); +-- +1.9.3 + diff --git a/SOURCES/0068-Ticket-48146-async-simple-paged-results-issue.patch b/SOURCES/0068-Ticket-48146-async-simple-paged-results-issue.patch deleted file mode 100644 index 8feeef8..0000000 --- a/SOURCES/0068-Ticket-48146-async-simple-paged-results-issue.patch +++ /dev/null @@ -1,160 +0,0 @@ -From ef82e8471b3bc171ae99ffd753937b55aa0e6e2f Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 26 May 2015 10:41:03 -0700 -Subject: [PATCH 68/72] Ticket #48146 - async simple paged results issue - -Description: commit 5060d11f5039efa8534a8b65392ac6e10cbd2168 introduced -a regression. Handling backend "be" should be done after checking OID -MTN_CONTROL_USE_ONE_BACKEND_EXT_OID in the request control. - -https://fedorahosted.org/389/ticket/48146 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit bd2c0d0b6a499d7f91a36e8a9feb83e4fbd3dac5) -(cherry picked from commit 0c7b38abfb4c5c02286efd5e698616534a798993) ---- - ldap/servers/slapd/opshared.c | 108 ++++++++++++++++++++++-------------------- - 1 file changed, 57 insertions(+), 51 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 430b0c6..ff67a9b 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -408,57 +408,12 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - */ - operation_set_target_spec (pb->pb_op, basesdn); - -- if (be_name == NULL) -- { -- /* no specific backend was requested, use the mapping tree -- */ -- err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); -- if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) -- || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) -- { -- send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); -- rc = -1; -- goto free_and_return; -- } -- if (be_list[0] != NULL) -- { -- index = 0; -- if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */ -- /* move the index in the be_list which matches pr_be */ -- while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) -- index++; -- } else { -- while (be_list[index] && be_list[index+1]) -- index++; -- } -- /* "be" is either pr_be or the last backend */ -- be = be_list[index]; -- } -- else -- be = pr_be?pr_be:NULL; -- } -- else -- { -- /* specific backend be_name was requested, use slapi_be_select_by_instance_name -- */ -- if (pr_be) { -- be_single = be = pr_be; -- } else { -- be_single = be = slapi_be_select_by_instance_name(be_name); -- } -- if (be_single) -- slapi_be_Rlock(be_single); -- be_list[0] = NULL; -- referral_list[0] = NULL; -- referral = NULL; -- } -- -- /* this is time to check if mapping tree specific control -- * was used to specify that we want to parse only -- * one backend -+ /* -+ * this is time to check if mapping tree specific control was used to -+ * specify that we want to parse only one backend. - */ - slapi_pblock_get(pb, SLAPI_REQCONTROLS, &ctrlp); -- if (NULL != ctrlp) -+ if (ctrlp) - { - if (slapi_control_present(ctrlp, MTN_CONTROL_USE_ONE_BACKEND_EXT_OID, - &ctl_value, &iscritical)) -@@ -513,7 +468,57 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - } - } - } -+ } -+ -+ if (be_name == NULL) -+ { -+ /* no specific backend was requested, use the mapping tree -+ */ -+ err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); -+ if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) -+ || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) -+ { -+ send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); -+ rc = -1; -+ goto free_and_return; -+ } -+ if (be_list[0] != NULL) -+ { -+ index = 0; -+ if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */ -+ /* move the index in the be_list which matches pr_be */ -+ while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) -+ index++; -+ } else { -+ while (be_list[index] && be_list[index+1]) -+ index++; -+ } -+ /* "be" is either pr_be or the last backend */ -+ be = be_list[index]; -+ } -+ else -+ be = pr_be?pr_be:NULL; -+ } -+ else -+ { -+ /* specific backend be_name was requested, use slapi_be_select_by_instance_name -+ */ -+ if (pr_be) { -+ be_single = be = pr_be; -+ } else { -+ be_single = be = slapi_be_select_by_instance_name(be_name); -+ } -+ if (be_single) { -+ slapi_be_Rlock(be_single); -+ } -+ be_list[0] = NULL; -+ referral_list[0] = NULL; -+ referral = NULL; -+ } - -+ /* Handle the rest of the controls. */ -+ if (ctrlp) -+ { - if ( slapi_control_present (ctrlp, LDAP_CONTROL_GET_EFFECTIVE_RIGHTS, - &ctl_value, &iscritical) ) - { -@@ -1024,10 +1029,11 @@ next_be: - } - - free_and_return: -- if ((be_list[0] != NULL) || (referral_list[0] != NULL)) -+ if ((be_list[0] != NULL) || (referral_list[0] != NULL)) { - slapi_mapping_tree_free_all(be_list, referral_list); -- else if (be_single) -+ } else if (be_single) { - slapi_be_Unlock(be_single); -+ } - - free_and_return_nolock: - slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc); --- -1.9.3 - diff --git a/SOURCES/0068-Ticket-48298-ns-slapd-crash-during-ipa-replica-manag.patch b/SOURCES/0068-Ticket-48298-ns-slapd-crash-during-ipa-replica-manag.patch new file mode 100644 index 0000000..0e44b72 --- /dev/null +++ b/SOURCES/0068-Ticket-48298-ns-slapd-crash-during-ipa-replica-manag.patch @@ -0,0 +1,343 @@ +From 5b2efd34c07c65e24f4129430064f7299803dbf8 Mon Sep 17 00:00:00 2001 +From: Noriko Hosoi +Date: Fri, 2 Oct 2015 11:38:01 -0700 +Subject: [PATCH 68/68] Ticket #48298 - ns-slapd crash during + ipa-replica-manage del + +Bug Description: The cause of the problem is rather not a race condition but +accessing an already freed agreement in a plug-in: +> The crashed thread is deleting an agreement object, which calls mep_pre_op. +> It eventually calls op_shared_search with the deleted agreement object with +> base scope and filter "(|(objectclass=*)(objectclass=ldapsubentry))" +> Since it is a DSE entry it goes to dse_search, in which it calls agmt_get_ +> replarea and crashes in slapi_sdn_copy by NULL dereference in from SDN... + +Fix Description: This patch adds the check to agmt_get_replarea, in which if +the agreement is not in the agreement list, it returnes NULL repl area. When +the NULL repl area is returned the callers back off with an error. + +https://fedorahosted.org/389/ticket/48298 + +Reviewed by rmeggins@redhat.com (Thanks, Rich!) + +(cherry picked from commit 3cbdfa613ed8668337213fe9c3c15cf54ce798aa) +(cherry picked from commit f09eb8c0f8ee315b2a20d6460c975a546207411e) +--- + ldap/servers/plugins/replication/repl5.h | 1 + + ldap/servers/plugins/replication/repl5_agmt.c | 17 +++++++++-- + ldap/servers/plugins/replication/repl5_agmtlist.c | 34 ++++++++++++++++++---- + .../plugins/replication/repl5_inc_protocol.c | 10 ++++++- + .../plugins/replication/repl5_replica_config.c | 6 +++- + .../plugins/replication/repl5_tot_protocol.c | 12 ++++++-- + .../plugins/replication/repl_session_plugin.c | 22 +++++++++++--- + .../plugins/replication/windows_protocol_util.c | 12 ++++++++ + 8 files changed, 98 insertions(+), 16 deletions(-) + +diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 17282bb..df92ca0 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -390,6 +390,7 @@ void agmtlist_shutdown(); + void agmtlist_notify_all(Slapi_PBlock *pb); + Object* agmtlist_get_first_agreement_for_replica (Replica *r); + Object* agmtlist_get_next_agreement_for_replica (Replica *r, Object *prev); ++int agmtlist_agmt_exists(const Repl_Agmt *ra); + + /* In repl5_backoff.c */ + typedef struct backoff_timer Backoff_Timer; +diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c +index f84eacb..76d26a1 100644 +--- a/ldap/servers/plugins/replication/repl5_agmt.c ++++ b/ldap/servers/plugins/replication/repl5_agmt.c +@@ -696,6 +696,12 @@ agmt_start(Repl_Agmt *ra) + * index. + */ + repl_sdn = agmt_get_replarea(ra); ++ if (!repl_sdn) { ++ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, ++ "agmt_start: failed to get repl area. Please check agreement.\n"); ++ prot_free(&prot); ++ return -1; ++ } + + pb = slapi_pblock_new(); + attrs[0] = (char*)type_agmtMaxCSN; +@@ -770,7 +776,7 @@ agmt_start(Repl_Agmt *ra) + slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), + ra->hostname, ra->port); + if(strstr(maxcsns[i], buf) || strstr(maxcsns[i], unavail_buf)){ +- /* Set the maxcsn */ ++ /* Set the maxcsn */ + slapi_ch_free_string(&ra->maxcsn); + ra->maxcsn = slapi_ch_strdup(maxcsns[i]); + ra->consumerRID = agmt_maxcsn_get_rid(maxcsns[i]); +@@ -976,8 +982,11 @@ agmt_get_bindmethod(const Repl_Agmt *ra) + Slapi_DN * + agmt_get_replarea(const Repl_Agmt *ra) + { +- Slapi_DN *return_value; ++ Slapi_DN *return_value = NULL; + PR_ASSERT(NULL != ra); ++ if (!agmtlist_agmt_exists(ra)) { ++ return return_value; ++ } + PR_Lock(ra->lock); + return_value = slapi_sdn_new(); + slapi_sdn_copy(ra->replarea, return_value); +@@ -2690,6 +2699,9 @@ get_agmt_status(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + Object *repl_obj = NULL; + + replarea_sdn = agmt_get_replarea(ra); ++ if (!replarea_sdn) { ++ goto bail; ++ } + repl_obj = replica_get_replica_from_dn(replarea_sdn); + slapi_sdn_free(&replarea_sdn); + if (repl_obj) { +@@ -2748,6 +2760,7 @@ get_agmt_status(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + slapi_entry_add_string(e, "nsds5replicaLastInitStatus", ra->last_init_status); + } + } ++bail: + return SLAPI_DSE_CALLBACK_OK; + } + +diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c +index 34650b4..f50862f 100644 +--- a/ldap/servers/plugins/replication/repl5_agmtlist.c ++++ b/ldap/servers/plugins/replication/repl5_agmtlist.c +@@ -109,6 +109,24 @@ agmtlist_release_agmt(Repl_Agmt *ra) + } + } + ++int ++agmtlist_agmt_exists(const Repl_Agmt *ra) ++{ ++ Object *ro; ++ int exists = 0; ++ ++ PR_ASSERT(NULL != agmt_set); ++ if (!ra) { ++ return exists; ++ } ++ ro = objset_find(agmt_set, agmt_ptr_cmp, (const void *)ra); ++ if (ro) { ++ exists = 1; ++ object_release(ro); ++ } ++ return exists; ++} ++ + + /* + * Note: when we add the new object, we have a reference to it. We hold +@@ -135,6 +153,9 @@ add_new_agreement(Slapi_Entry *e) + + /* get the replica for this agreement */ + replarea_sdn = agmt_get_replarea(ra); ++ if (!replarea_sdn) { ++ return 1; ++ } + repl_obj = replica_get_replica_from_dn(replarea_sdn); + slapi_sdn_free(&replarea_sdn); + if (repl_obj) { +@@ -841,13 +862,16 @@ Object* agmtlist_get_next_agreement_for_replica (Replica *r, Object *prev) + else + obj = objset_first_obj(agmt_set); + +- while (obj) +- { ++ for ( ; obj; obj = objset_next_obj(agmt_set, obj)) { + agmt = (Repl_Agmt*)object_get_data (obj); +- PR_ASSERT (agmt); ++ if (!agmt) { ++ continue; ++ } + + agmt_root = agmt_get_replarea(agmt); +- PR_ASSERT (agmt_root); ++ if (!agmt_root) { ++ continue; ++ } + + if (slapi_sdn_compare (replica_root, agmt_root) == 0) + { +@@ -856,7 +880,7 @@ Object* agmtlist_get_next_agreement_for_replica (Replica *r, Object *prev) + } + + slapi_sdn_free (&agmt_root); +- obj = objset_next_obj(agmt_set, obj); ++ + } + + return NULL; +diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c +index 7680340..244bbb2 100644 +--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c +@@ -1906,6 +1906,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + { + Replica *replica; + ReplicaId rid = -1; /* Used to create the replica keep alive subentry */ ++ Slapi_DN *replarea_sdn = NULL; + replica = (Replica*) object_get_data(prp->replica_object); + if (replica) + { +@@ -1914,7 +1915,14 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu + slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, + "%s: skipped updates was definitely too high (%d) update the subentry now\n", + agmt_get_long_name(prp->agmt), skipped_updates); +- replica_subentry_update(agmt_get_replarea(prp->agmt), rid); ++ replarea_sdn = agmt_get_replarea(prp->agmt); ++ if (!replarea_sdn) { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, ++ "send_updates: Unknown replication area due to agreement not found."); ++ return_value = UPDATE_FATAL_ERROR; ++ } else { ++ replica_subentry_update(replarea_sdn, rid); ++ } + } + /* Terminate the results reading thread */ + if (!prp->repl50consumer) +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 8d3c481..e85ae3e 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -2368,13 +2368,17 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, cleanruv_data *clean_data) + conn_delete_internal_ext(conn); + return; + } +- val.bv_len = PR_snprintf(data, sizeof(data), "CLEANRUV%d", clean_data->rid); + sdn = agmt_get_replarea(agmt); ++ if (!sdn) { ++ conn_delete_internal_ext(conn); ++ return; ++ } + mod.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES; + mod.mod_type = "nsds5task"; + mod.mod_bvalues = vals; + vals [0] = &val; + vals [1] = NULL; ++ val.bv_len = PR_snprintf(data, sizeof(data), "CLEANRUV%d", clean_data->rid); + val.bv_val = data; + mods[0] = &mod; + mods[1] = NULL; +diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c +index 7da893a..16b51b5 100644 +--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c +@@ -329,6 +329,13 @@ repl5_tot_run(Private_Repl_Protocol *prp) + goto done; + } + ++ area_sdn = agmt_get_replarea(prp->agmt); ++ if (!area_sdn) { ++ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Warning: unable to " ++ "get repl area. Please check agreement.\n"); ++ goto done; ++ } ++ + conn_set_timeout(prp->conn, agmt_get_timeout(prp->agmt)); + + /* acquire remote replica */ +@@ -387,11 +394,10 @@ repl5_tot_run(Private_Repl_Protocol *prp) + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Beginning total update of replica " + "\"%s\".\n", agmt_get_long_name(prp->agmt)); + +- pb = slapi_pblock_new (); ++ /* RMREPL - need to send schema here */ + +- /* RMREPL - need to send schema here */ ++ pb = slapi_pblock_new (); + +- area_sdn = agmt_get_replarea(prp->agmt); + /* we need to provide managedsait control so that referral entries can + be replicated */ + ctrls = (LDAPControl **)slapi_ch_calloc (3, sizeof (LDAPControl *)); +diff --git a/ldap/servers/plugins/replication/repl_session_plugin.c b/ldap/servers/plugins/replication/repl_session_plugin.c +index 1c04089..2fa993d 100644 +--- a/ldap/servers/plugins/replication/repl_session_plugin.c ++++ b/ldap/servers/plugins/replication/repl_session_plugin.c +@@ -48,6 +48,10 @@ repl_session_plugin_call_agmt_init_cb(Repl_Agmt *ra) + } + if (initfunc) { + replarea = agmt_get_replarea(ra); ++ if (!replarea) { ++ LDAPDebug0Args(LDAP_DEBUG_ANY, "repl_session_plugin_call_agmt_init_cb -- Aborted -- No replication area\n"); ++ return; ++ } + cookie = (*initfunc)(replarea); + slapi_sdn_free(&replarea); + } +@@ -73,8 +77,11 @@ repl_session_plugin_call_pre_acquire_cb(const Repl_Agmt *ra, int is_total, + + if (thefunc) { + replarea = agmt_get_replarea(ra); +- rc = (*thefunc)(agmt_get_priv(ra), replarea, is_total, +- data_guid, data); ++ if (!replarea) { ++ LDAPDebug0Args(LDAP_DEBUG_ANY, "repl_session_plugin_call_pre_acquire_cb -- Aborted -- No replication area\n"); ++ return 1; ++ } ++ rc = (*thefunc)(agmt_get_priv(ra), replarea, is_total, data_guid, data); + slapi_sdn_free(&replarea); + } + +@@ -95,8 +102,11 @@ repl_session_plugin_call_post_acquire_cb(const Repl_Agmt *ra, int is_total, + + if (thefunc) { + replarea = agmt_get_replarea(ra); +- rc = (*thefunc)(agmt_get_priv(ra), replarea, +- is_total, data_guid, data); ++ if (!replarea) { ++ LDAPDebug0Args(LDAP_DEBUG_ANY, "repl_session_plugin_call_post_acquire_cb -- Aborted -- No replication area\n"); ++ return 1; ++ } ++ rc = (*thefunc)(agmt_get_priv(ra), replarea, is_total, data_guid, data); + slapi_sdn_free(&replarea); + } + +@@ -151,6 +161,10 @@ repl_session_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra) + + if (thefunc) { + replarea = agmt_get_replarea(ra); ++ if (!replarea) { ++ LDAPDebug0Args(LDAP_DEBUG_ANY, "repl_session_plugin_call_destroy_agmt_cb -- Aborted -- No replication area\n"); ++ return; ++ } + (*thefunc)(agmt_get_priv(ra), replarea); + slapi_sdn_free(&replarea); + } +diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c +index 5c12af7..084b520 100644 +--- a/ldap/servers/plugins/replication/windows_protocol_util.c ++++ b/ldap/servers/plugins/replication/windows_protocol_util.c +@@ -5319,6 +5319,13 @@ windows_update_local_entry(Private_Repl_Protocol *prp,Slapi_Entry *remote_entry, + * in the groups caused by moving member entries. + * We need to update the local groups manually... */ + local_subtree = agmt_get_replarea(prp->agmt); ++ if (!local_subtree) { ++ slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name, ++ "failed to get local subtree from agreement\n"); ++ local_entry = orig_local_entry; ++ orig_local_entry = NULL; ++ goto bail; ++ } + local_subtree_sdn = local_subtree; + orig_local_sdn = slapi_entry_get_sdn_const(orig_local_entry); + escaped_filter_val = slapi_escape_filter_value((char *)slapi_sdn_get_ndn(orig_local_sdn), +@@ -5651,6 +5658,11 @@ windows_search_local_entry_by_uniqueid(Private_Repl_Protocol *prp, + *ret_entry = NULL; + if (is_global) { /* Search from the suffix (rename case) */ + local_subtree = agmt_get_replarea(prp->agmt); ++ if (!local_subtree) { ++ slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name, ++ "failed to get local subtree from agreement\n"); ++ return LDAP_PARAM_ERROR; ++ } + local_subtree_sdn = local_subtree; + } else { + local_subtree_sdn = windows_private_get_directory_treetop(prp->agmt); +-- +1.9.3 + diff --git a/SOURCES/0069-Ticket-48146-async-simple-paged-results-issue.patch b/SOURCES/0069-Ticket-48146-async-simple-paged-results-issue.patch deleted file mode 100644 index 110279e..0000000 --- a/SOURCES/0069-Ticket-48146-async-simple-paged-results-issue.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 2c5b4ef85d492732050f3bec57eec1b7afbb1120 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Sat, 30 May 2015 16:44:14 -0700 -Subject: [PATCH 69/72] Ticket #48146 - async simple paged results issue - -Description: commit 5e9c4f1f09596dd076a6c3a0bb419580e8fd705e broke the -CI test case ticket47824_test.py. - -If the simple paged results search is operated on a backend having one -or more sub-backends underneath, it fails to pick up the next sub-back -ends, but repeats the search on the parent backend. The problem was -fixed. - -https://fedorahosted.org/389/ticket/48146 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 03d3455dfbe84f034a234df2ebd8cfdd7ad15f48) -(cherry picked from commit f6fe5bfe4c1fb1402af789a0f935c765c299d103) ---- - ldap/servers/slapd/opshared.c | 87 ++++++++++++++++++++----------------------- - 1 file changed, 41 insertions(+), 46 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index ff67a9b..5dff42f 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -470,46 +470,31 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - } - } - -- if (be_name == NULL) -- { -- /* no specific backend was requested, use the mapping tree -- */ -- err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); -- if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) -- || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) -- { -- send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); -- rc = -1; -- goto free_and_return; -- } -- if (be_list[0] != NULL) -- { -- index = 0; -- if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */ -- /* move the index in the be_list which matches pr_be */ -- while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) -- index++; -+ if (be_name == NULL) { -+ /* no specific backend was requested, use the mapping tree -+ */ -+ err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); -+ if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) -+ || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) { -+ send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); -+ rc = -1; -+ goto free_and_return; -+ } -+ if (be_list[0] != NULL) { -+ index = 0; -+ while (be_list[index] && be_list[index+1]) { -+ index++; -+ } -+ be = be_list[index]; - } else { -- while (be_list[index] && be_list[index+1]) -- index++; -+ be = NULL; - } -- /* "be" is either pr_be or the last backend */ -- be = be_list[index]; -- } -- else -- be = pr_be?pr_be:NULL; -- } -- else -- { -+ } else { - /* specific backend be_name was requested, use slapi_be_select_by_instance_name - */ -- if (pr_be) { -- be_single = be = pr_be; -- } else { -- be_single = be = slapi_be_select_by_instance_name(be_name); -- } -+ be_single = be = slapi_be_select_by_instance_name(be_name); - if (be_single) { -- slapi_be_Rlock(be_single); -+ slapi_be_Rlock(be_single); - } - be_list[0] = NULL; - referral_list[0] = NULL; -@@ -528,6 +513,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - if ( slapi_control_present (ctrlp, LDAP_CONTROL_PAGEDRESULTS, - &ctl_value, &iscritical) ) - { -+ /* be is set only when this request is new. otherwise, prev be is honored. */ - rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be); - /* Let's set pr_idx even if it fails; in case, pr_idx == -1. */ - slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx); -@@ -536,13 +522,24 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED; - op_set_pagedresults(operation); - pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx); -- pr_search_result = pagedresults_get_search_result(pb->pb_conn, -- operation, -- pr_idx); -- estimate = -- pagedresults_get_search_result_set_size_estimate(pb->pb_conn, -- operation, -- pr_idx); -+ if (be_name) { -+ if (pr_be != be_single) { -+ slapi_be_Unlock(be_single); -+ be_single = be = pr_be; -+ slapi_be_Rlock(be_single); -+ } -+ } else if (be_list[0]) { -+ if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */ -+ /* move the index in the be_list which matches pr_be */ -+ index = 0; -+ while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) { -+ index++; -+ } -+ be = be_list[index]; -+ } -+ } -+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx); -+ estimate = pagedresults_get_search_result_set_size_estimate(pb->pb_conn, operation, pr_idx); - if (pagedresults_get_unindexed(pb->pb_conn, operation, pr_idx)) { - opnote |= SLAPI_OP_NOTE_UNINDEXED; - } -@@ -687,7 +684,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - * change ONE-LEVEL searches to BASE - */ - -- /* that's mean we only support one suffix per backend */ -+ /* that means we only support one suffix per backend */ - be_suffix = slapi_be_getsuffix(be, 0); - - if (be_list[0] == NULL) -@@ -711,9 +708,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - * In async paged result case, the search result might be released - * by other theads. We need to double check it in the locked region. - */ -- pr_search_result = pagedresults_get_search_result(pb->pb_conn, -- operation, -- pr_idx); -+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx); - if (pr_search_result) { - slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result ); - rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat); --- -1.9.3 - diff --git a/SOURCES/0070-Ticket-48192-Individual-abandoned-simple-paged-resul.patch b/SOURCES/0070-Ticket-48192-Individual-abandoned-simple-paged-resul.patch deleted file mode 100644 index dfb25f9..0000000 --- a/SOURCES/0070-Ticket-48192-Individual-abandoned-simple-paged-resul.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 810e825adebf9f1669bab9f61831f158e0c2f941 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 4 Jun 2015 16:27:05 -0700 -Subject: [PATCH 70/72] Ticket #48192 - Individual abandoned simple paged - results request has no chance to be cleaned up - -Description: When allocating a slot in simple paged results array stashed -in a connection in pagedresults_parse_control_value, a new code is added -to scan the array if the existing slot is timed out or not. If it is, the -slot is released and a search results is released if it is attached. - -Also, if a request is abandoned, instead of returning a valid cookie, it -changed to return an empty cookie to inform the client the request was not -successfully completed. - -https://fedorahosted.org/389/ticket/48192 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit f3c3125fc9fd4dc1cbd41027d6442cb525efd014) -(cherry picked from commit 97c707df4e11936202310e99bcf5f45d15b49f0f) ---- - ldap/servers/slapd/opshared.c | 41 +++++++------- - ldap/servers/slapd/pagedresults.c | 110 ++++++++++++++++++++++++-------------- - 2 files changed, 89 insertions(+), 62 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 5dff42f..9cf431c 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -517,8 +517,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be); - /* Let's set pr_idx even if it fails; in case, pr_idx == -1. */ - slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx); -- if ((LDAP_SUCCESS == rc) || -- (LDAP_CANCELLED == rc) || (0 == pagesize)) { -+ if ((LDAP_SUCCESS == rc) || (LDAP_CANCELLED == rc) || (0 == pagesize)) { - unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED; - op_set_pagedresults(operation); - pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx); -@@ -545,9 +544,8 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - } - slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote ); - if ((LDAP_CANCELLED == rc) || (0 == pagesize)) { -- /* paged-results-request was abandoned */ -- pagedresults_set_response_control(pb, 0, estimate, -- curr_search_count, pr_idx); -+ /* paged-results-request was abandoned; making an empty cookie. */ -+ pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx); - send_ldap_result(pb, 0, NULL, - "Simple Paged Results Search abandoned", - 0, NULL); -@@ -574,10 +572,21 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - - /* adjust time and size limits */ - compute_limits (pb); -- -- /* call the pre-search plugins. if they succeed, call the backend -- search function. then call the post-search plugins. */ - -+ /* set the timelimit to clean up the too-long-lived-paged results requests */ -+ if (op_is_pagedresults(operation)) { -+ time_t optime, time_up; -+ int tlimit; -+ slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit ); -+ slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime ); -+ time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */ -+ pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, time_up, pr_idx); -+ } -+ -+ /* -+ * call the pre-search plugins. if they succeed, call the backend -+ * search function. then call the post-search plugins. -+ */ - /* ONREPL - should regular plugin be called for internal searches ? */ - if (plugin_call_plugins(pb, SLAPI_PLUGIN_PRE_SEARCH_FN) == 0) - { -@@ -642,16 +651,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - } - } - -- /* set the timelimit to clean up the too-long-lived-paged results requests */ -- if (op_is_pagedresults(operation)) { -- time_t optime, time_up; -- int tlimit; -- slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit ); -- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime ); -- time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */ -- pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, time_up, pr_idx); -- } -- - /* PAR: now filters have been rewritten, we can assign plugins to work on them */ - index_subsys_assign_filter_decoders(pb); - -@@ -880,10 +879,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); - if (PAGEDRESULTS_SEARCH_END == pr_stat) { - if (sr) { /* in case a left over sr is found, clean it up */ -- PR_Lock(pb->pb_conn->c_mutex); -- pagedresults_set_search_result(pb->pb_conn, operation, NULL, 1, pr_idx); -- be->be_search_results_release(&sr); -- PR_Unlock(pb->pb_conn->c_mutex); -+ pagedresults_free_one(pb->pb_conn, operation, pr_idx); - } - if (NULL == next_be) { - /* no more entries && no more backends */ -@@ -1306,7 +1302,6 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, - operation_out_of_disk_space(); - } - pr_stat = PAGEDRESULTS_SEARCH_END; -- pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, 0, pr_idx); - rval = -1; - done = 1; - continue; -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index 327da54..402dd10 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -41,6 +41,27 @@ - - #include "slap.h" - -+/* helper function to clean up one prp slot */ -+static void -+_pr_cleanup_one_slot(PagedResults *prp) -+{ -+ PRLock *prmutex = NULL; -+ if (!prp) { -+ return; -+ } -+ if (prp->pr_current_be && prp->pr_current_be->be_search_results_release) { -+ /* sr is left; release it. */ -+ prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); -+ } -+ /* clean up the slot */ -+ if (prp->pr_mutex) { -+ /* pr_mutex is reused; back it up and reset it. */ -+ prmutex = prp->pr_mutex; -+ } -+ memset(prp, '\0', sizeof(PagedResults)); -+ prp->pr_mutex = prmutex; -+} -+ - /* - * Parse the value from an LDAPv3 "Simple Paged Results" control. They look - * like this: -@@ -65,6 +86,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - Connection *conn = pb->pb_conn; - Operation *op = pb->pb_op; - BerElement *ber = NULL; -+ PagedResults *prp = NULL; - - LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_parse_control_value\n"); - if ( NULL == conn || NULL == op || NULL == pagesize || NULL == index ) { -@@ -117,13 +139,31 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - } - *index = maxlen; /* the first position in the new area */ - } else { -- for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { -- if (!conn->c_pagedresults.prl_list[i].pr_current_be) { -- conn->c_pagedresults.prl_list[i].pr_current_be = be; -+ time_t ctime = current_time(); -+ prp = conn->c_pagedresults.prl_list; -+ for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) { -+ if (!prp->pr_current_be) { /* unused slot; take it */ -+ prp->pr_current_be = be; -+ *index = i; -+ break; -+ } else if (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */ -+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) /* abandoned */) { -+ _pr_cleanup_one_slot(prp); -+ conn->c_pagedresults.prl_count--; -+ prp->pr_current_be = be; - *index = i; - break; - } - } -+ /* cleaning up the rest of the timedout if any */ -+ for (++i; i < conn->c_pagedresults.prl_maxlen; i++, prp++) { -+ if (prp->pr_current_be && -+ (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */ -+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED)) /* abandoned */) { -+ _pr_cleanup_one_slot(prp); -+ conn->c_pagedresults.prl_count--; -+ } -+ } - } - if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen) && - !conn->c_pagedresults.prl_list[*index].pr_mutex) { -@@ -131,7 +171,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - } - conn->c_pagedresults.prl_count++; - } else { -- PagedResults *prp = NULL; - /* Repeated paged results request. - * PagedResults is already allocated. */ - char *ptr = slapi_ch_malloc(cookie.bv_len + 1); -@@ -156,8 +195,10 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - slapi_ch_free((void **)&cookie.bv_val); - - if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) { -- if (conn->c_pagedresults.prl_list[*index].pr_flags & -- CONN_FLAG_PAGEDRESULTS_ABANDONED) { -+ if (conn->c_pagedresults.prl_list[*index].pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) { -+ /* repeated case? */ -+ prp = conn->c_pagedresults.prl_list + *index; -+ _pr_cleanup_one_slot(prp); - rc = LDAP_CANCELLED; - } else { - /* Need to keep the latest msgid to prepare for the abandon. */ -@@ -273,20 +314,8 @@ pagedresults_free_one( Connection *conn, Operation *op, int index ) - "conn=%d paged requests list count is %d\n", - conn->c_connid, conn->c_pagedresults.prl_count); - } else if (index < conn->c_pagedresults.prl_maxlen) { -- PRLock *prmutex = NULL; - PagedResults *prp = conn->c_pagedresults.prl_list + index; -- if (prp && prp->pr_current_be && -- prp->pr_current_be->be_search_results_release && -- prp->pr_search_result_set) { -- prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); -- } -- prp->pr_current_be = NULL; -- if (prp->pr_mutex) { -- /* pr_mutex is reused; back it up and reset it. */ -- prmutex = prp->pr_mutex; -- } -- memset(prp, '\0', sizeof(PagedResults)); -- prp->pr_mutex = prmutex; -+ _pr_cleanup_one_slot(prp); - conn->c_pagedresults.prl_count--; - rc = 0; - } -@@ -309,7 +338,7 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid ) - ; /* Not a paged result. */ - } else { - LDAPDebug1Arg(LDAP_DEBUG_TRACE, -- "--> pagedresults_free_one: msgid=%d\n", msgid); -+ "--> pagedresults_free_one_msgid_nolock: msgid=%d\n", msgid); - for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { - if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) { - PagedResults *prp = conn->c_pagedresults.prl_list + i; -@@ -318,16 +347,14 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid ) - prp->pr_search_result_set) { - prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); - } -- prp->pr_current_be = NULL; - prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED; - prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING; -- conn->c_pagedresults.prl_count--; - rc = 0; - break; - } - } - LDAPDebug1Arg(LDAP_DEBUG_TRACE, -- "<-- pagedresults_free_one: %d\n", rc); -+ "<-- pagedresults_free_one_msgid_nolock: %d\n", rc); - } - } - -@@ -845,37 +872,42 @@ pagedresults_reset_processing(Connection *conn, int index) - } - #endif - --/* Are all the paged results requests timed out? */ -+/* -+ * This timedout is mainly for an end user leaves a commandline untouched -+ * for a long time. This should not affect a permanent connection which -+ * manages multiple simple paged results requests over the connection. -+ * -+ * [rule] -+ * If there is just one slot and it's timed out, we return it is timedout. -+ * If there are multiple slots, the connection may be a permanent one. -+ * Do not return timed out here. But let the next request take care the -+ * timedout slot(s). -+ */ - int - pagedresults_is_timedout_nolock(Connection *conn) - { -- int i; - PagedResults *prp = NULL; - time_t ctime; -- int rc = 0; - - LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_is_timedout\n"); - -- if (NULL == conn || 0 == conn->c_pagedresults.prl_count) { -- LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: -\n"); -- return rc; -+ if (!conn || (0 == conn->c_pagedresults.prl_maxlen)) { -+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: false\n"); -+ return 0; - } - - ctime = current_time(); -- for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { -- prp = conn->c_pagedresults.prl_list + i; -+ prp = conn->c_pagedresults.prl_list; -+ if (prp && (1 == conn->c_pagedresults.prl_maxlen)) { - if (prp->pr_current_be && (prp->pr_timelimit > 0)) { -- if (ctime < prp->pr_timelimit) { -- LDAPDebug0Args(LDAP_DEBUG_TRACE, -- "<-- pagedresults_is_timedout: 0\n"); -- return 0; /* at least, one request is not timed out. */ -- } else { -- rc = 1; /* possibly timed out */ -+ if (ctime > prp->pr_timelimit) { -+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: true\n"); -+ return 1; - } - } - } -- LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: 1\n"); -- return rc; /* all requests are timed out. */ -+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: false\n"); -+ return 0; - } - - /* reset all timeout */ --- -1.9.3 - diff --git a/SOURCES/0071-Ticket-48192-Individual-abandoned-simple-paged-resul.patch b/SOURCES/0071-Ticket-48192-Individual-abandoned-simple-paged-resul.patch deleted file mode 100644 index 7e126e2..0000000 --- a/SOURCES/0071-Ticket-48192-Individual-abandoned-simple-paged-resul.patch +++ /dev/null @@ -1,42 +0,0 @@ -From aa6561d02969ce1db1a50da2b8af8679f6aeca69 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Fri, 5 Jun 2015 10:13:17 -0700 -Subject: [PATCH 71/72] Ticket #48192 - Individual abandoned simple paged - results request has no chance to be cleaned up - -Description: Checking the cookie value passed by the client was not -sufficient. The negative value check was missing, which lead to -the simple paged results array out of bounds. Plus, a minor memory -leak was fixed. Thanks to Thierry Bordaz for his reviews! - -https://fedorahosted.org/389/ticket/48192 -(cherry picked from commit 298371d372678cf553594ae73ae57a6ea35358bf) -(cherry picked from commit 7718eb6a6714d1a284c3c706e621a7eb0ca5655a) ---- - ldap/servers/slapd/pagedresults.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index 402dd10..2e70e19 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -177,14 +177,14 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - memcpy(ptr, cookie.bv_val, cookie.bv_len); - *(ptr+cookie.bv_len) = '\0'; - *index = strtol(ptr, NULL, 10); -- if (conn->c_pagedresults.prl_maxlen <= *index) { -+ slapi_ch_free_string(&ptr); -+ if ((conn->c_pagedresults.prl_maxlen <= *index) || (*index < 0)){ - rc = LDAP_PROTOCOL_ERROR; - LDAPDebug1Arg(LDAP_DEBUG_ANY, - "pagedresults_parse_control_value: invalid cookie: %d\n", - *index); - goto bail; - } -- slapi_ch_free_string(&ptr); - prp = conn->c_pagedresults.prl_list + *index; - if (!(prp->pr_search_result_set)) { /* freed and reused for the next backend. */ - conn->c_pagedresults.prl_count++; --- -1.9.3 - diff --git a/SOURCES/0072-Ticket-48192-Individual-abandoned-simple-paged-resul.patch b/SOURCES/0072-Ticket-48192-Individual-abandoned-simple-paged-resul.patch deleted file mode 100644 index 5ea6c6c..0000000 --- a/SOURCES/0072-Ticket-48192-Individual-abandoned-simple-paged-resul.patch +++ /dev/null @@ -1,314 +0,0 @@ -From 504609eadf933c726d829e1532dbe525ab71d1b2 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 9 Jun 2015 10:02:02 -0700 -Subject: [PATCH 72/72] Ticket #48192 - Individual abandoned simple paged - results request has no chance to be cleaned up - -Description: When a simple paged results is abandoned immediately and -asynchronously just after the request, the abandon request has a chance -to be handled before the simple paged results control is received and -processed. In the case, the search could be executed and the search -result structure could be leaked. - -This patch adds more abandon checks. In op_shared_search, after the -send_results_ext call, if the SLAPI_OP_STATUS_ABANDONED bit is set in -the status in the operation object, it cleans up the search results -again, which gives the second chance. - -https://fedorahosted.org/389/ticket/48192 - -Reviewed by tbordaz@redhat.com (Thank you so much, Thierry!!) - -(cherry picked from commit 1d18dd0107d48ac1d79f7c9988adf18b0905bbdb) -(cherry picked from commit 798eae4f2240a5b47963a2bb09a2a17acfc488ec) ---- - ldap/servers/slapd/abandon.c | 10 +++--- - ldap/servers/slapd/back-ldbm/ldbm_search.c | 13 ++++++-- - ldap/servers/slapd/opshared.c | 36 +++++++++++++-------- - ldap/servers/slapd/pagedresults.c | 52 +++++++++++++++++------------- - ldap/servers/slapd/proto-slap.h | 2 +- - 5 files changed, 69 insertions(+), 44 deletions(-) - -diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c -index 6b4bbf2..d80087e 100644 ---- a/ldap/servers/slapd/abandon.c -+++ b/ldap/servers/slapd/abandon.c -@@ -132,8 +132,7 @@ do_abandon( Slapi_PBlock *pb ) - } - - operation_set_abandoned_op (pb->pb_op, o->o_abandoned_op); -- if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_ABANDON_FN ) -- == 0 ) { -+ if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_ABANDON_FN ) == 0 ) { - int rc = 0; - - if ( o->o_status != SLAPI_OP_STATUS_RESULT_SENT ) { -@@ -148,14 +147,13 @@ do_abandon( Slapi_PBlock *pb ) - suppressed_by_plugin = 1; - } - } else { -- LDAPDebug( LDAP_DEBUG_TRACE, "do_abandon: op not found\n", 0, 0, -- 0 ); -+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "do_abandon: op not found\n"); - } - - if ( 0 == pagedresults_free_one_msgid_nolock(pb->pb_conn, id) ) { - slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 -- " op=%d ABANDON targetop=Simple Paged Results\n", -- (long long unsigned int)pb->pb_conn->c_connid, pb->pb_op->o_opid ); -+ " op=%d ABANDON targetop=Simple Paged Results msgid=%d\n", -+ (long long unsigned int)pb->pb_conn->c_connid, pb->pb_op->o_opid, id ); - } else if ( NULL == o ) { - slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON" - " targetop=NOTFOUND msgid=%d\n", -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c -index e1951a0..c6c5735 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_search.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c -@@ -1817,12 +1817,21 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension ) - } - } - } -+ /* check for the final abandon */ -+ if (slapi_op_abandoned(pb)) { -+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate ); -+ if ( use_extension ) { -+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY_EXT, NULL ); -+ } -+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, NULL ); -+ delete_search_result_set(pb, &sr); -+ rc = SLAPI_FAIL_GENERAL; -+ } - - bail: -- if(rc){ -+ if (rc && op) { - op->o_reverse_search_state = 0; - } -- - return rc; - } - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 9cf431c..4be5366 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -748,7 +748,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - pagedresults_unlock(pb->pb_conn, pr_idx); - if (next_be) { - /* no more entries, but at least another backend */ -- if (pagedresults_set_current_be(pb->pb_conn, next_be, pr_idx) < 0) { -+ if (pagedresults_set_current_be(pb->pb_conn, next_be, pr_idx, 0) < 0) { - goto free_and_return; - } - } -@@ -878,23 +878,23 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - curr_search_count = pnentries; - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); - if (PAGEDRESULTS_SEARCH_END == pr_stat) { -- if (sr) { /* in case a left over sr is found, clean it up */ -- pagedresults_free_one(pb->pb_conn, operation, pr_idx); -- } -+ /* no more entries, but at least another backend */ -+ PR_Lock(pb->pb_conn->c_mutex); -+ pagedresults_set_search_result(pb->pb_conn, operation, NULL, 1, pr_idx); -+ be->be_search_results_release(&sr); -+ rc = pagedresults_set_current_be(pb->pb_conn, next_be, pr_idx, 1); -+ PR_Unlock(pb->pb_conn->c_mutex); - if (NULL == next_be) { -- /* no more entries && no more backends */ -- curr_search_count = -1; -- } else { -- /* no more entries, but at least another backend */ -- if (pagedresults_set_current_be(pb->pb_conn, next_be, pr_idx) < 0) { -+ /* no more entries && no more backends */ -+ curr_search_count = -1; -+ } else if (rc < 0) { - goto free_and_return; -- } - } - } else { - curr_search_count = pnentries; - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate); - pagedresults_lock(pb->pb_conn, pr_idx); -- if ((pagedresults_set_current_be(pb->pb_conn, be, pr_idx) < 0) || -+ if ((pagedresults_set_current_be(pb->pb_conn, be, pr_idx, 0) < 0) || - (pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx) < 0) || - (pagedresults_set_search_result_count(pb->pb_conn, operation, curr_search_count, pr_idx) < 0) || - (pagedresults_set_search_result_set_size_estimate(pb->pb_conn, operation, estimate, pr_idx) < 0) || -@@ -904,10 +904,20 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - } - pagedresults_unlock(pb->pb_conn, pr_idx); - } -- pagedresults_set_response_control(pb, 0, estimate, -- curr_search_count, pr_idx); - slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL ); - next_be = NULL; /* to break the loop */ -+ if (operation->o_status & SLAPI_OP_STATUS_ABANDONED) { -+ /* It turned out this search was abandoned. */ -+ PR_Lock(pb->pb_conn->c_mutex); -+ pagedresults_free_one_msgid_nolock( pb->pb_conn, operation->o_msgid); -+ PR_Unlock(pb->pb_conn->c_mutex); -+ /* paged-results-request was abandoned; making an empty cookie. */ -+ pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx); -+ send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); -+ rc = LDAP_SUCCESS; -+ goto free_and_return; -+ } -+ pagedresults_set_response_control(pb, 0, estimate, curr_search_count, pr_idx); - if (curr_search_count == -1) { - pagedresults_free_one(pb->pb_conn, operation, pr_idx); - } -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index 2e70e19..a7fe2cd 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -87,6 +87,8 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - Operation *op = pb->pb_op; - BerElement *ber = NULL; - PagedResults *prp = NULL; -+ time_t ctime = current_time(); -+ int i; - - LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_parse_control_value\n"); - if ( NULL == conn || NULL == op || NULL == pagesize || NULL == index ) { -@@ -121,7 +123,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - /* the ber encoding is no longer needed */ - ber_free(ber, 1); - if ( cookie.bv_len <= 0 ) { -- int i; - /* first time? */ - int maxlen = conn->c_pagedresults.prl_maxlen; - if (conn->c_pagedresults.prl_count == maxlen) { -@@ -138,15 +139,16 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - memset(conn->c_pagedresults.prl_list + maxlen, '\0', sizeof(PagedResults) * maxlen); - } - *index = maxlen; /* the first position in the new area */ -+ prp = conn->c_pagedresults.prl_list + *index; -+ prp->pr_current_be = be; - } else { -- time_t ctime = current_time(); - prp = conn->c_pagedresults.prl_list; - for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) { - if (!prp->pr_current_be) { /* unused slot; take it */ - prp->pr_current_be = be; - *index = i; - break; -- } else if (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */ -+ } else if (((prp->pr_timelimit > 0) && (ctime > prp->pr_timelimit)) || /* timelimit exceeded */ - (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) /* abandoned */) { - _pr_cleanup_one_slot(prp); - conn->c_pagedresults.prl_count--; -@@ -155,15 +157,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - break; - } - } -- /* cleaning up the rest of the timedout if any */ -- for (++i; i < conn->c_pagedresults.prl_maxlen; i++, prp++) { -- if (prp->pr_current_be && -- (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */ -- (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED)) /* abandoned */) { -- _pr_cleanup_one_slot(prp); -- conn->c_pagedresults.prl_count--; -- } -- } - } - if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen) && - !conn->c_pagedresults.prl_list[*index].pr_mutex) { -@@ -181,8 +174,8 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - if ((conn->c_pagedresults.prl_maxlen <= *index) || (*index < 0)){ - rc = LDAP_PROTOCOL_ERROR; - LDAPDebug1Arg(LDAP_DEBUG_ANY, -- "pagedresults_parse_control_value: invalid cookie: %d\n", -- *index); -+ "pagedresults_parse_control_value: invalid cookie: %d\n", *index); -+ *index = -1; /* index is invalid. reinitializing it. */ - goto bail; - } - prp = conn->c_pagedresults.prl_list + *index; -@@ -206,11 +199,24 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, - } - } else { - rc = LDAP_PROTOCOL_ERROR; -- LDAPDebug1Arg(LDAP_DEBUG_ANY, -- "pagedresults_parse_control_value: invalid cookie: %d\n", -- *index); -+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "pagedresults_parse_control_value: invalid cookie: %d\n", *index); - } - bail: -+ /* cleaning up the rest of the timedout or abandoned if any */ -+ prp = conn->c_pagedresults.prl_list; -+ for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) { -+ if (prp->pr_current_be && -+ (((prp->pr_timelimit > 0) && (ctime > prp->pr_timelimit)) || /* timelimit exceeded */ -+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED)) /* abandoned */) { -+ _pr_cleanup_one_slot(prp); -+ conn->c_pagedresults.prl_count--; -+ if (i == *index) { -+ /* registered slot is expired and cleaned up. return cancelled. */ -+ *index = -1; -+ rc = LDAP_CANCELLED; -+ } -+ } -+ } - PR_Unlock(conn->c_mutex); - - LDAPDebug1Arg(LDAP_DEBUG_TRACE, -@@ -326,7 +332,9 @@ pagedresults_free_one( Connection *conn, Operation *op, int index ) - return rc; - } - --/* Used for abandoning */ -+/* -+ * Used for abandoning - conn->c_mutex is already locked in do_abandone. -+ */ - int - pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid ) - { -@@ -334,7 +342,7 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid ) - int i; - - if (conn && (msgid > -1)) { -- if (conn->c_pagedresults.prl_count <= 0) { -+ if (conn->c_pagedresults.prl_maxlen <= 0) { - ; /* Not a paged result. */ - } else { - LDAPDebug1Arg(LDAP_DEBUG_TRACE, -@@ -381,18 +389,18 @@ pagedresults_get_current_be(Connection *conn, int index) - } - - int --pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index) -+pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int nolock) - { - int rc = -1; - LDAPDebug1Arg(LDAP_DEBUG_TRACE, - "--> pagedresults_set_current_be: idx=%d\n", index); - if (conn && (index > -1)) { -- PR_Lock(conn->c_mutex); -+ if (!nolock) PR_Lock(conn->c_mutex); - if (index < conn->c_pagedresults.prl_maxlen) { - conn->c_pagedresults.prl_list[index].pr_current_be = be; - } -- PR_Unlock(conn->c_mutex); - rc = 0; -+ if (!nolock) PR_Unlock(conn->c_mutex); - } - LDAPDebug1Arg(LDAP_DEBUG_TRACE, - "<-- pagedresults_set_current_be: %d\n", rc); -diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h -index 80504b2..c5c412d 100644 ---- a/ldap/servers/slapd/proto-slap.h -+++ b/ldap/servers/slapd/proto-slap.h -@@ -1472,7 +1472,7 @@ void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, - ber_int_t estimate, - int curr_search_count, int index); - Slapi_Backend *pagedresults_get_current_be(Connection *conn, int index); --int pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index); -+int pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int nolock); - void *pagedresults_get_search_result(Connection *conn, Operation *op, - int index); - int pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, --- -1.9.3 - diff --git a/SOURCES/0073-Ticket-48194-nsSSL3Ciphers-preference-not-enforced-s.patch b/SOURCES/0073-Ticket-48194-nsSSL3Ciphers-preference-not-enforced-s.patch deleted file mode 100644 index 8e2ba49..0000000 --- a/SOURCES/0073-Ticket-48194-nsSSL3Ciphers-preference-not-enforced-s.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 413ac674d497a981b30bdc81b47ea2bb3e14ad57 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 11 Jun 2015 22:25:14 -0700 -Subject: [PATCH] Ticket #48194 - nsSSL3Ciphers preference not enforced server - side - -Description: The fix for ticket 47838 accidentally changed the timing -of setting default cipher preferences and creating a sslSocket which -broke setting the default preferences to each sslSocket. - -https://fedorahosted.org/389/ticket/48194 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit 53c9c4e84e3bcbc40de87b1e7cf7634d14599e1c) -(cherry picked from commit 99109e38ca671951c50724018fce71e2e362f0ff) ---- - ldap/servers/slapd/ssl.c | 97 +++++++++++++++++++++++++----------------------- - 1 file changed, 50 insertions(+), 47 deletions(-) - -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 6b51e0c..36a4788 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -1342,9 +1342,6 @@ slapd_ssl_init() - freeConfigEntry( &entry ); - } - -- /* ugaston- Cipher preferences must be set before any sslSocket is created -- * for such sockets to take preferences into account. -- */ - freeConfigEntry( &entry ); - - /* Introduce a way of knowing whether slapd_ssl_init has -@@ -1590,6 +1587,45 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - - errorbuf[0] = '\0'; - -+ /* -+ * Cipher preferences must be set before any sslSocket is created -+ * for such sockets to take preferences into account. -+ */ -+ getConfigEntry(configDN, &e); -+ if (e == NULL) { -+ slapd_SSL_warn("Security Initialization: Failed get config entry %s", configDN); -+ return 1; -+ } -+ val = slapi_entry_attr_get_charptr(e, "allowWeakCipher"); -+ if (val) { -+ if (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -+ !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no")) { -+ allowweakcipher = CIPHER_SET_DISALLOWWEAKCIPHER; -+ } else if (!PL_strcasecmp(val, "on") || !PL_strcasecmp(val, "true") || -+ !PL_strcmp(val, "1") || !PL_strcasecmp(val, "yes")) { -+ allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; -+ } else { -+ slapd_SSL_warn("The value of allowWeakCipher \"%s\" in %s is invalid.", -+ "Ignoring it and set it to default.", val, configDN); -+ } -+ } -+ slapi_ch_free((void **) &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)) ) { -+ errorCode = PR_GetError(); -+ slapd_SSL_warn("Security Initialization: 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); -+ } -+ freeConfigEntry(&e); -+ - /* Import pr fd into SSL */ - pr_sock = SSL_ImportFD( NULL, sock ); - if( pr_sock == (PRFileDesc *)NULL ) { -@@ -1632,8 +1668,6 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - slapd_pk11_setSlotPWValues(slot, 0, 0); - } - -- -- - /* - * Now, get the complete list of cipher families. Each family - * has a token name and personality name which we'll use to find -@@ -1816,9 +1850,8 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - "out of disk space! Make more room in /tmp " - "and try again. (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", - errorCode, slapd_pr_strerror(errorCode)); -- } -- else { -- slapd_SSL_error("Config of server nonce cache failed (error %d - %s)", -+ } else { -+ slapd_SSL_error("Config of server nonce cache failed (error %d - %s)", - errorCode, slapd_pr_strerror(errorCode)); - } - return rv; -@@ -1985,36 +2018,6 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - #if !defined(NSS_TLS10) /* NSS_TLS11 or newer */ - } - #endif -- val = slapi_entry_attr_get_charptr(e, "allowWeakCipher"); -- if (val) { -- if (!PL_strcasecmp(val, "off") || !PL_strcasecmp(val, "false") || -- !PL_strcmp(val, "0") || !PL_strcasecmp(val, "no")) { -- allowweakcipher = CIPHER_SET_DISALLOWWEAKCIPHER; -- } else if (!PL_strcasecmp(val, "on") || !PL_strcasecmp(val, "true") || -- !PL_strcmp(val, "1") || !PL_strcasecmp(val, "yes")) { -- allowweakcipher = CIPHER_SET_ALLOWWEAKCIPHER; -- } else { -- slapd_SSL_warn("The value of allowWeakCipher \"%s\" in %s is invalid.", -- "Ignoring it and set it to default.", val, configDN); -- } -- } -- slapi_ch_free((void **) &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)) ) { -- errorCode = PR_GetError(); -- slapd_SSL_warn("Security Initialization: Failed to set SSL cipher " -- "preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", -- val, errorCode, slapd_pr_strerror(errorCode)); -- rv = 3; -- slapi_ch_free((void **) &val); -- } -- - freeConfigEntry( &e ); - - if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) { -@@ -2059,17 +2062,17 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) - /* richm 20020227 - To do LDAP client SSL init, we need to do - -- static void -- ldapssl_basic_init( void ) -- { -- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); -+ static void -+ ldapssl_basic_init( void ) -+ { -+ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - -- PR_SetConcurrency( 4 ); -- } -+ PR_SetConcurrency( 4 ); -+ } - NSS_Init(certdbpath); - SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE); -- SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE); -- s = NSS_SetDomesticPolicy(); -+ SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE); -+ s = NSS_SetDomesticPolicy(); - We already do pr_init, we don't need pr_setconcurrency, we already do nss_init and the rest - - */ -@@ -2095,7 +2098,7 @@ slapd_SSL_client_auth (LDAP* ld) - char **family; - char *personality = NULL; - char *activation = NULL; -- char *cipher = NULL; -+ char *cipher = NULL; - - for (family = family_list; *family; family++) { - getConfigEntry( *family, &entry ); --- -1.9.3 - diff --git a/SOURCES/0074-Ticket-48192-Individual-abandoned-simple-paged-resul.patch b/SOURCES/0074-Ticket-48192-Individual-abandoned-simple-paged-resul.patch deleted file mode 100644 index 959a784..0000000 --- a/SOURCES/0074-Ticket-48192-Individual-abandoned-simple-paged-resul.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 22b0f8f0de1ee208a8c06c171bc2069da0adcc87 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 6 Jul 2015 14:06:11 -0700 -Subject: [PATCH] Ticket #48192 - Individual abandoned simple paged results - request has no chance to be cleaned up - -Description: There was a small window that the search on the next page -after the previous page abandoned referred the cleaned up simple paged -object. - -This patch introduces a pagedresults_is_abandoned helper function to -check the simple paged results was abandoned or not with some improvements -based upon the comments by rmeggins@redhat.com (Thank you!!): -1) adding locking when getting a simplepaged object in pagedresults_is_ - abandoned_or_notavailable as well as in pagedresults_{un}lock. -2) sending "Simple Paged Results Search abandoned" if the previous page - with the same cookie in the same connection was abandoned. - -https://fedorahosted.org/389/ticket/48192 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit e4d83c91fc88fcf9e6c823c608c629ac10e362f8) -(cherry picked from commit b513a502250f93cfb43df000c2140b27c4ef0d39) -(cherry picked from commit 7b17c488de280f29264920b4e53dce862ed5b7e4) ---- - ldap/servers/slapd/opshared.c | 22 ++++++++++++++++------ - ldap/servers/slapd/pagedresults.c | 24 +++++++++++++++++++++++- - ldap/servers/slapd/proto-slap.h | 1 + - 3 files changed, 40 insertions(+), 7 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 4be5366..1bad7ef 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -709,12 +709,20 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - */ - pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx); - if (pr_search_result) { -- slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result ); -- rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat); -+ if (pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) { -+ pagedresults_unlock(pb->pb_conn, pr_idx); -+ /* Previous operation was abandoned and the simplepaged object is not in use. */ -+ send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); -+ rc = LDAP_SUCCESS; -+ goto free_and_return; -+ } else { -+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result ); -+ rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat); - -- /* search result could be reset in the backend/dse */ -- slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); -- pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx); -+ /* search result could be reset in the backend/dse */ -+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); -+ pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx); -+ } - } else { - pr_stat = PAGEDRESULTS_SEARCH_END; - } -@@ -744,7 +752,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result) - if (PAGEDRESULTS_SEARCH_END == pr_stat) { - pagedresults_lock(pb->pb_conn, pr_idx); - slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); -- pagedresults_free_one(pb->pb_conn, operation, pr_idx); -+ if (!pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) { -+ pagedresults_free_one(pb->pb_conn, operation, pr_idx); -+ } - pagedresults_unlock(pb->pb_conn, pr_idx); - if (next_be) { - /* no more entries, but at least another backend */ -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index a7fe2cd..010e5c1 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -890,6 +890,8 @@ pagedresults_reset_processing(Connection *conn, int index) - * If there are multiple slots, the connection may be a permanent one. - * Do not return timed out here. But let the next request take care the - * timedout slot(s). -+ * -+ * must be called within conn->c_mutex - */ - int - pagedresults_is_timedout_nolock(Connection *conn) -@@ -918,7 +920,10 @@ pagedresults_is_timedout_nolock(Connection *conn) - return 0; - } - --/* reset all timeout */ -+/* -+ * reset all timeout -+ * must be called within conn->c_mutex -+ */ - int - pagedresults_reset_timedout_nolock(Connection *conn) - { -@@ -981,7 +986,9 @@ pagedresults_lock( Connection *conn, int index ) - if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { - return; - } -+ PR_Lock(conn->c_mutex); - prp = conn->c_pagedresults.prl_list + index; -+ PR_Unlock(conn->c_mutex); - if (prp->pr_mutex) { - PR_Lock(prp->pr_mutex); - } -@@ -995,9 +1002,24 @@ pagedresults_unlock( Connection *conn, int index ) - if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { - return; - } -+ PR_Lock(conn->c_mutex); - prp = conn->c_pagedresults.prl_list + index; -+ PR_Unlock(conn->c_mutex); - if (prp->pr_mutex) { - PR_Unlock(prp->pr_mutex); - } - return; - } -+ -+int -+pagedresults_is_abandoned_or_notavailable( Connection *conn, int index ) -+{ -+ PagedResults *prp; -+ if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { -+ return 1; /* not abandoned, but do not want to proceed paged results op. */ -+ } -+ PR_Lock(conn->c_mutex); -+ prp = conn->c_pagedresults.prl_list + index; -+ PR_Unlock(conn->c_mutex); -+ return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; -+} -diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h -index c5c412d..4c0d1ce 100644 ---- a/ldap/servers/slapd/proto-slap.h -+++ b/ldap/servers/slapd/proto-slap.h -@@ -1515,6 +1515,7 @@ int pagedresults_cleanup_all(Connection *conn, int needlock); - void op_set_pagedresults(Operation *op); - void pagedresults_lock(Connection *conn, int index); - void pagedresults_unlock(Connection *conn, int index); -+int pagedresults_is_abandoned_or_notavailable(Connection *conn, int index); - - /* - * sort.c --- -1.9.3 - diff --git a/SOURCES/0075-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch b/SOURCES/0075-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch deleted file mode 100644 index 97aef2a..0000000 --- a/SOURCES/0075-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 8eef70242e661d55cdc0fae7f5328c780ec6d60a Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Mon, 13 Jul 2015 17:51:01 -0700 -Subject: [PATCH] Ticket #48223 - Winsync fails when AD users have multiple - spaces (two)inside the value of the rdn attribute - -Description: When the dirsync search returns a remote entry, winsync -search the entry with DN to retrieve the whole attribute value pairs. -The DN used for the search was normalized which replaced multiple white- -spaces with one in the DN. This patch does not used the normalized DN, -but the same DN given by AD. - -The DN normalization behaviour was introduced to fix a ticket #529 - -dn normalization must handle multiple space characters in attributes. - -Added additional debugging to get the info which entry failed to sync. - -https://fedorahosted.org/389/ticket/48223 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit 2c484cc6e89e473bced0e9b25dd6e68d53024bb3) -(cherry picked from commit 69fd1f188105b2c3ca1bee04b05909e53c980b34) -(cherry picked from commit 8622b69a733a6126414876f11ab627211cb3bd06) ---- - ldap/servers/plugins/posix-winsync/posix-group-func.c | 2 +- - ldap/servers/plugins/replication/windows_protocol_util.c | 11 +++++++---- - 2 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.c b/ldap/servers/plugins/posix-winsync/posix-group-func.c -index 5f841e5..a497f3f 100644 ---- a/ldap/servers/plugins/posix-winsync/posix-group-func.c -+++ b/ldap/servers/plugins/posix-winsync/posix-group-func.c -@@ -95,7 +95,7 @@ getEntry(const char *udn, char **attrs) - } - else { - slapi_log_error(SLAPI_LOG_FATAL, POSIX_WINSYNC_PLUGIN_NAME, -- "getEntry: error searching for uid: %d\n", rc); -+ "getEntry: error searching for uid %s: %d\n", udn, rc); - } - - return NULL; -diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c -index dabc936..ca79021 100644 ---- a/ldap/servers/plugins/replication/windows_protocol_util.c -+++ b/ldap/servers/plugins/replication/windows_protocol_util.c -@@ -3244,7 +3244,7 @@ windows_get_remote_entry (Private_Repl_Protocol *prp, const Slapi_DN* remote_dn, - const char *searchbase = NULL; - Slapi_Entry *found_entry = NULL; - -- searchbase = slapi_sdn_get_dn(remote_dn); -+ searchbase = slapi_sdn_get_udn(remote_dn); - cres = windows_search_entry_ext(prp->conn, (char*)searchbase, filter, &found_entry, NULL, LDAP_SCOPE_BASE); - if (cres) - { -@@ -5904,13 +5904,16 @@ retry: - remote_entry = NULL; - } else - { -- slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name,"%s: windows_process_dirsync_entry: failed to fetch inbound entry.\n",agmt_get_long_name(prp->agmt)); -+ slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name, -+ "%s: windows_process_dirsync_entry: failed to fetch inbound entry %s.\n", -+ agmt_get_long_name(prp->agmt), slapi_sdn_get_dn(slapi_entry_get_sdn_const(e))); - } - slapi_entry_free(local_entry); - if (rc) { - /* Something bad happened */ -- slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"%s: windows_process_dirsync_entry: failed to update inbound entry for %s.\n",agmt_get_long_name(prp->agmt), -- slapi_sdn_get_dn(slapi_entry_get_sdn_const(e))); -+ slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name, -+ "%s: windows_process_dirsync_entry: failed to update inbound entry for %s.\n", -+ agmt_get_long_name(prp->agmt), slapi_sdn_get_dn(slapi_entry_get_sdn_const(e))); - } - } else - { --- -1.9.3 - diff --git a/SOURCES/0076-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch b/SOURCES/0076-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch deleted file mode 100644 index cf4cac8..0000000 --- a/SOURCES/0076-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b9771a9a3202b4d3a8562ed7359c824f8922b4fe Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 15 Oct 2014 16:20:51 -0700 -Subject: [PATCH 76/84] Ticket #47553 - Enhance ACIs to have more control over - MODRDN operations - -Description: Macro SLAPI_ACL_ALL does not contain SLAPI_ACL_MODDN. -Thus, even though all operations are allowed by "allow (all)", just -modrdn fails with "Insufficient access (50)". - -https://fedorahosted.org/389/ticket/47553 - -Reviewed by tbordaz@redhat.com (Thank you, Thierry!!) - -(cherry picked from commit 4aafe7444d983c08b16a84b7c23c8d303de45dc6) ---- - ldap/servers/slapd/slapi-plugin.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index dfe75eb..5a7af5e 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -237,12 +237,12 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...) - #define SLAPI_ACL_ADD 0x20 - #define SLAPI_ACL_SELF 0x40 - #define SLAPI_ACL_PROXY 0x80 --#define SLAPI_ACL_ALL 0x7f - /* Values 0x200 and 0x400 are booked (acl.h) by - * ACLPB_SLAPI_ACL_WRITE_ADD - * ACLPB_SLAPI_ACL_WRITE_DEL - */ - #define SLAPI_ACL_MODDN 0x0800 -+#define SLAPI_ACL_ALL 0x087f - - - /* --- -1.9.3 - diff --git a/SOURCES/0077-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch b/SOURCES/0077-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch deleted file mode 100644 index c56fbc8..0000000 --- a/SOURCES/0077-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch +++ /dev/null @@ -1,676 +0,0 @@ -From b19dc5b453751ca63545e39537bfb87707cf867e Mon Sep 17 00:00:00 2001 -From: "Thierry bordaz (tbordaz)" -Date: Thu, 16 Oct 2014 17:24:15 +0200 -Subject: [PATCH 77/84] Ticket 47553: Enhance ACIs to have more control over - MODRDN operations - -Bug Description: - The ticket 47553 introduces a new aci right: moddn. - This rights allows/deny to do a MODDN from a part of the DIT to an other. - Before the right allow/deny to do a MODDN was granted if the subject had 'write' access to the rdn attribute. - To switch from the previous mode to the new one, there is a toggle 'nsslapd-moddn-aci'. - The getEffectiveRight control, should report the MODDN right ('n') according to - the acis and the value of this toggle - -Fix Description: - test 'nsslapd-moddn-aci' in the geteffectiveright code - -https://fedorahosted.org/389/ticket/47553 - -Reviewed by: Noriko (Thanks !) - -Platforms tested: F17 - -Flag Day: no - -Doc impact: no - -(cherry picked from commit be67f8128d4a19edec95a6b1b022fd9262710e74) ---- - dirsrvtests/tickets/ticket47553_ger.py | 553 ++++++++++++++++++++++++++ - ldap/servers/plugins/acl/acleffectiverights.c | 67 ++-- - 2 files changed, 590 insertions(+), 30 deletions(-) - create mode 100644 dirsrvtests/tickets/ticket47553_ger.py - -diff --git a/dirsrvtests/tickets/ticket47553_ger.py b/dirsrvtests/tickets/ticket47553_ger.py -new file mode 100644 -index 0000000..d688c70 ---- /dev/null -+++ b/dirsrvtests/tickets/ticket47553_ger.py -@@ -0,0 +1,553 @@ -+''' -+Created on Nov 7, 2013 -+ -+@author: tbordaz -+''' -+import os -+import sys -+import time -+import ldap -+import logging -+import socket -+import time -+import logging -+import pytest -+import re -+from lib389 import DirSrv, Entry, tools -+from lib389.tools import DirSrvTools -+from lib389._constants import * -+from lib389.properties import * -+from constants import * -+from lib389._constants import REPLICAROLE_MASTER -+from ldap.controls.simple import GetEffectiveRightsControl -+ -+logging.getLogger(__name__).setLevel(logging.DEBUG) -+log = logging.getLogger(__name__) -+ -+# -+# important part. We can deploy Master1 and Master2 on different versions -+# -+installation1_prefix = None -+installation2_prefix = None -+ -+TEST_REPL_DN = "cn=test_repl, %s" % SUFFIX -+ -+STAGING_CN = "staged user" -+PRODUCTION_CN = "accounts" -+EXCEPT_CN = "excepts" -+ -+STAGING_DN = "cn=%s,%s" % (STAGING_CN, SUFFIX) -+PRODUCTION_DN = "cn=%s,%s" % (PRODUCTION_CN, SUFFIX) -+PROD_EXCEPT_DN = "cn=%s,%s" % (EXCEPT_CN, PRODUCTION_DN) -+ -+STAGING_PATTERN = "cn=%s*,%s" % (STAGING_CN[:2], SUFFIX) -+PRODUCTION_PATTERN = "cn=%s*,%s" % (PRODUCTION_CN[:2], SUFFIX) -+BAD_STAGING_PATTERN = "cn=bad*,%s" % (SUFFIX) -+BAD_PRODUCTION_PATTERN = "cn=bad*,%s" % (SUFFIX) -+ -+BIND_CN = "bind_entry" -+BIND_DN = "cn=%s,%s" % (BIND_CN, SUFFIX) -+BIND_PW = "password" -+ -+NEW_ACCOUNT = "new_account" -+MAX_ACCOUNTS = 20 -+ -+CONFIG_MODDN_ACI_ATTR = "nsslapd-moddn-aci" -+ -+class TopologyMaster1Master2(object): -+ def __init__(self, master1, master2): -+ master1.open() -+ self.master1 = master1 -+ -+ master2.open() -+ self.master2 = master2 -+ -+ -+@pytest.fixture(scope="module") -+def topology(request): -+ ''' -+ This fixture is used to create a replicated topology for the 'module'. -+ The replicated topology is MASTER1 <-> Master2. -+ At the beginning, It may exists a master2 instance and/or a master2 instance. -+ It may also exists a backup for the master1 and/or the master2. -+ -+ Principle: -+ If master1 instance exists: -+ restart it -+ If master2 instance exists: -+ restart it -+ If backup of master1 AND backup of master2 exists: -+ create or rebind to master1 -+ create or rebind to master2 -+ -+ restore master1 from backup -+ restore master2 from backup -+ else: -+ Cleanup everything -+ remove instances -+ remove backups -+ Create instances -+ Initialize replication -+ Create backups -+ ''' -+ global installation1_prefix -+ global installation2_prefix -+ -+ # allocate master1 on a given deployement -+ master1 = DirSrv(verbose=False) -+ if installation1_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix -+ -+ # Args for the master1 instance -+ args_instance[SER_HOST] = HOST_MASTER_1 -+ args_instance[SER_PORT] = PORT_MASTER_1 -+ args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1 -+ args_master = args_instance.copy() -+ master1.allocate(args_master) -+ -+ # allocate master1 on a given deployement -+ master2 = DirSrv(verbose=False) -+ if installation2_prefix: -+ args_instance[SER_DEPLOYED_DIR] = installation2_prefix -+ -+ # Args for the consumer instance -+ args_instance[SER_HOST] = HOST_MASTER_2 -+ args_instance[SER_PORT] = PORT_MASTER_2 -+ args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2 -+ args_master = args_instance.copy() -+ master2.allocate(args_master) -+ -+ -+ # Get the status of the backups -+ backup_master1 = master1.checkBackupFS() -+ backup_master2 = master2.checkBackupFS() -+ -+ # Get the status of the instance and restart it if it exists -+ instance_master1 = master1.exists() -+ if instance_master1: -+ master1.stop(timeout=10) -+ master1.start(timeout=10) -+ -+ instance_master2 = master2.exists() -+ if instance_master2: -+ master2.stop(timeout=10) -+ master2.start(timeout=10) -+ -+ if backup_master1 and backup_master2: -+ # The backups exist, assuming they are correct -+ # we just re-init the instances with them -+ if not instance_master1: -+ master1.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ master1.open() -+ -+ if not instance_master2: -+ master2.create() -+ # Used to retrieve configuration information (dbdir, confdir...) -+ master2.open() -+ -+ # restore master1 from backup -+ master1.stop(timeout=10) -+ master1.restoreFS(backup_master1) -+ master1.start(timeout=10) -+ -+ # restore master2 from backup -+ master2.stop(timeout=10) -+ master2.restoreFS(backup_master2) -+ master2.start(timeout=10) -+ else: -+ # We should be here only in two conditions -+ # - This is the first time a test involve master-consumer -+ # so we need to create everything -+ # - Something weird happened (instance/backup destroyed) -+ # so we discard everything and recreate all -+ -+ # Remove all the backups. So even if we have a specific backup file -+ # (e.g backup_master) we clear all backups that an instance my have created -+ if backup_master1: -+ master1.clearBackupFS() -+ if backup_master2: -+ master2.clearBackupFS() -+ -+ # Remove all the instances -+ if instance_master1: -+ master1.delete() -+ if instance_master2: -+ master2.delete() -+ -+ # Create the instances -+ master1.create() -+ master1.open() -+ master2.create() -+ master2.open() -+ -+ # -+ # Now prepare the Master-Consumer topology -+ # -+ # First Enable replication -+ master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1) -+ master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2) -+ -+ # Initialize the supplier->consumer -+ -+ properties = {RA_NAME: r'meTo_$host:$port', -+ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], -+ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], -+ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], -+ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} -+ repl_agreement = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties) -+ -+ if not repl_agreement: -+ log.fatal("Fail to create a replica agreement") -+ sys.exit(1) -+ -+ log.debug("%s created" % repl_agreement) -+ -+ properties = {RA_NAME: r'meTo_$host:$port', -+ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN], -+ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW], -+ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD], -+ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]} -+ master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties) -+ -+ master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2) -+ master1.waitForReplInit(repl_agreement) -+ -+ # Check replication is working fine -+ master1.add_s(Entry((TEST_REPL_DN, { -+ 'objectclass': "top person".split(), -+ 'sn': 'test_repl', -+ 'cn': 'test_repl'}))) -+ loop = 0 -+ while loop <= 10: -+ try: -+ ent = master2.getEntry(TEST_REPL_DN, ldap.SCOPE_BASE, "(objectclass=*)") -+ break -+ except ldap.NO_SUCH_OBJECT: -+ time.sleep(1) -+ loop += 1 -+ -+ # Time to create the backups -+ master1.stop(timeout=10) -+ master1.backupfile = master1.backupFS() -+ master1.start(timeout=10) -+ -+ master2.stop(timeout=10) -+ master2.backupfile = master2.backupFS() -+ master2.start(timeout=10) -+ -+ # clear the tmp directory -+ master1.clearTmpDir(__file__) -+ -+ # -+ # Here we have two instances master and consumer -+ # with replication working. Either coming from a backup recovery -+ # or from a fresh (re)init -+ # Time to return the topology -+ return TopologyMaster1Master2(master1, master2) -+ -+ -+ -+def _bind_manager(topology): -+ topology.master1.log.info("Bind as %s " % DN_DM) -+ topology.master1.simple_bind_s(DN_DM, PASSWORD) -+ -+def _bind_normal(topology): -+ # bind as bind_entry -+ topology.master1.log.info("Bind as %s" % BIND_DN) -+ topology.master1.simple_bind_s(BIND_DN, BIND_PW) -+ -+def _moddn_aci_deny_tree(topology, mod_type=None, target_from=STAGING_DN, target_to=PROD_EXCEPT_DN): -+ ''' -+ It denies the access moddn_to in cn=except,cn=accounts,SUFFIX -+ ''' -+ assert mod_type != None -+ -+ ACI_TARGET_FROM = "" -+ ACI_TARGET_TO = "" -+ if target_from: -+ ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from) -+ if target_to: -+ ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to) -+ -+ ACI_ALLOW = "(version 3.0; acl \"Deny MODDN to prod_except\"; deny (moddn)" -+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN -+ ACI_BODY = ACI_TARGET_TO + ACI_TARGET_FROM + ACI_ALLOW + ACI_SUBJECT -+ mod = [(mod_type, 'aci', ACI_BODY)] -+ #topology.master1.modify_s(SUFFIX, mod) -+ topology.master1.log.info("Add a DENY aci under %s " % PROD_EXCEPT_DN) -+ topology.master1.modify_s(PROD_EXCEPT_DN, mod) -+ -+def _moddn_aci_staging_to_production(topology, mod_type=None, target_from=STAGING_DN, target_to=PRODUCTION_DN): -+ assert mod_type != None -+ -+ -+ ACI_TARGET_FROM = "" -+ ACI_TARGET_TO = "" -+ if target_from: -+ ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from) -+ if target_to: -+ ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to) -+ -+ ACI_ALLOW = "(version 3.0; acl \"MODDN from staging to production\"; allow (moddn)" -+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN -+ ACI_BODY = ACI_TARGET_FROM + ACI_TARGET_TO + ACI_ALLOW + ACI_SUBJECT -+ mod = [(mod_type, 'aci', ACI_BODY)] -+ topology.master1.modify_s(SUFFIX, mod) -+ -+def _moddn_aci_from_production_to_staging(topology, mod_type=None): -+ assert mod_type != None -+ -+ ACI_TARGET = "(target_from = \"ldap:///%s\") (target_to = \"ldap:///%s\")" % (PRODUCTION_DN, STAGING_DN) -+ ACI_ALLOW = "(version 3.0; acl \"MODDN from production to staging\"; allow (moddn)" -+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN -+ ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT -+ mod = [(mod_type, 'aci', ACI_BODY)] -+ topology.master1.modify_s(SUFFIX, mod) -+ -+ -+def test_ticket47553_init(topology): -+ """ -+ Creates -+ - a staging DIT -+ - a production DIT -+ - add accounts in staging DIT -+ - enable ACL logging (commented for performance reason) -+ -+ """ -+ -+ topology.master1.log.info("\n\n######################### INITIALIZATION ######################\n") -+ -+ # entry used to bind with -+ topology.master1.log.info("Add %s" % BIND_DN) -+ topology.master1.add_s(Entry((BIND_DN, { -+ 'objectclass': "top person".split(), -+ 'sn': BIND_CN, -+ 'cn': BIND_CN, -+ 'userpassword': BIND_PW}))) -+ -+ # DIT for staging -+ topology.master1.log.info("Add %s" % STAGING_DN) -+ topology.master1.add_s(Entry((STAGING_DN, { -+ 'objectclass': "top organizationalRole".split(), -+ 'cn': STAGING_CN, -+ 'description': "staging DIT"}))) -+ -+ # DIT for production -+ topology.master1.log.info("Add %s" % PRODUCTION_DN) -+ topology.master1.add_s(Entry((PRODUCTION_DN, { -+ 'objectclass': "top organizationalRole".split(), -+ 'cn': PRODUCTION_CN, -+ 'description': "production DIT"}))) -+ -+ # DIT for production/except -+ topology.master1.log.info("Add %s" % PROD_EXCEPT_DN) -+ topology.master1.add_s(Entry((PROD_EXCEPT_DN, { -+ 'objectclass': "top organizationalRole".split(), -+ 'cn': EXCEPT_CN, -+ 'description': "production except DIT"}))) -+ -+ # enable acl error logging -+ #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')] -+ #topology.master1.modify_s(DN_CONFIG, mod) -+ #topology.master2.modify_s(DN_CONFIG, mod) -+ -+ -+ -+ -+ -+ # add dummy entries in the staging DIT -+ for cpt in range(MAX_ACCOUNTS): -+ name = "%s%d" % (NEW_ACCOUNT, cpt) -+ topology.master1.add_s(Entry(("cn=%s,%s" % (name, STAGING_DN), { -+ 'objectclass': "top person".split(), -+ 'sn': name, -+ 'cn': name}))) -+ -+ -+def test_ticket47553_mode_default_add_deny(topology): -+ ''' -+ This test case checks that the ADD operation fails (no ADD aci on production) -+ ''' -+ -+ topology.master1.log.info("\n\n######################### mode moddn_aci : ADD (should fail) ######################\n") -+ -+ _bind_normal(topology) -+ -+ # -+ # First try to add an entry in production => INSUFFICIENT_ACCESS -+ # -+ try: -+ topology.master1.log.info("Try to add %s" % PRODUCTION_DN) -+ name = "%s%d" % (NEW_ACCOUNT, 0) -+ topology.master1.add_s(Entry(("cn=%s,%s" % (name, PRODUCTION_DN), { -+ 'objectclass': "top person".split(), -+ 'sn': name, -+ 'cn': name}))) -+ assert 0 # this is an error, we should not be allowed to add an entry in production -+ except Exception as e: -+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__) -+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS) -+ -+def test_ticket47553_mode_default_ger_no_moddn(topology): -+ topology.master1.log.info("\n\n######################### mode moddn_aci : GER no moddn ######################\n") -+ request_ctrl = GetEffectiveRightsControl(criticality=True,authzId="dn: " + BIND_DN) -+ msg_id = topology.master1.search_ext(PRODUCTION_DN, ldap.SCOPE_SUBTREE, "objectclass=*", serverctrls=[request_ctrl]) -+ rtype,rdata,rmsgid,response_ctrl = topology.master1.result3(msg_id) -+ ger={} -+ value='' -+ for dn, attrs in rdata: -+ topology.master1.log.info ("dn: %s" % dn) -+ value = attrs['entryLevelRights'][0] -+ -+ topology.master1.log.info ("############### entryLevelRights: %r" % value) -+ assert 'n' not in value -+ -+def test_ticket47553_mode_default_ger_with_moddn(topology): -+ ''' -+ This test case adds the moddn aci and check ger contains 'n' -+ ''' -+ -+ topology.master1.log.info("\n\n######################### mode moddn_aci: GER with moddn ######################\n") -+ -+ # successfull MOD with the ACI -+ _bind_manager(topology) -+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN) -+ _bind_normal(topology) -+ -+ request_ctrl = GetEffectiveRightsControl(criticality=True,authzId="dn: " + BIND_DN) -+ msg_id = topology.master1.search_ext(PRODUCTION_DN, ldap.SCOPE_SUBTREE, "objectclass=*", serverctrls=[request_ctrl]) -+ rtype,rdata,rmsgid,response_ctrl = topology.master1.result3(msg_id) -+ ger={} -+ value = '' -+ for dn, attrs in rdata: -+ topology.master1.log.info ("dn: %s" % dn) -+ value = attrs['entryLevelRights'][0] -+ -+ topology.master1.log.info ("############### entryLevelRights: %r" % value) -+ assert 'n' in value -+ -+ # successfull MOD with the both ACI -+ _bind_manager(topology) -+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN) -+ _bind_normal(topology) -+ -+def test_ticket47553_mode_switch_default_to_legacy(topology): -+ ''' -+ This test switch the server from default mode to legacy -+ ''' -+ topology.master1.log.info("\n\n######################### Disable the moddn aci mod ######################\n" ) -+ _bind_manager(topology) -+ mod = [(ldap.MOD_REPLACE, CONFIG_MODDN_ACI_ATTR, 'off')] -+ topology.master1.modify_s(DN_CONFIG, mod) -+ -+def test_ticket47553_mode_legacy_ger_no_moddn1(topology): -+ topology.master1.log.info("\n\n######################### mode legacy 1: GER no moddn ######################\n") -+ request_ctrl = GetEffectiveRightsControl(criticality=True,authzId="dn: " + BIND_DN) -+ msg_id = topology.master1.search_ext(PRODUCTION_DN, ldap.SCOPE_SUBTREE, "objectclass=*", serverctrls=[request_ctrl]) -+ rtype,rdata,rmsgid,response_ctrl = topology.master1.result3(msg_id) -+ ger={} -+ value='' -+ for dn, attrs in rdata: -+ topology.master1.log.info ("dn: %s" % dn) -+ value = attrs['entryLevelRights'][0] -+ -+ topology.master1.log.info ("############### entryLevelRights: %r" % value) -+ assert 'n' not in value -+ -+def test_ticket47553_mode_legacy_ger_no_moddn2(topology): -+ topology.master1.log.info("\n\n######################### mode legacy 2: GER no moddn ######################\n") -+ # successfull MOD with the ACI -+ _bind_manager(topology) -+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN) -+ _bind_normal(topology) -+ -+ request_ctrl = GetEffectiveRightsControl(criticality=True,authzId="dn: " + BIND_DN) -+ msg_id = topology.master1.search_ext(PRODUCTION_DN, ldap.SCOPE_SUBTREE, "objectclass=*", serverctrls=[request_ctrl]) -+ rtype,rdata,rmsgid,response_ctrl = topology.master1.result3(msg_id) -+ ger={} -+ value='' -+ for dn, attrs in rdata: -+ topology.master1.log.info ("dn: %s" % dn) -+ value = attrs['entryLevelRights'][0] -+ -+ topology.master1.log.info ("############### entryLevelRights: %r" % value) -+ assert 'n' not in value -+ -+ # successfull MOD with the both ACI -+ _bind_manager(topology) -+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN) -+ _bind_normal(topology) -+ -+def test_ticket47553_mode_legacy_ger_with_moddn(topology): -+ topology.master1.log.info("\n\n######################### mode legacy : GER with moddn ######################\n") -+ -+ # being allowed to read/write the RDN attribute use to allow the RDN -+ ACI_TARGET = "(target = \"ldap:///%s\")(targetattr=\"cn\")" % (PRODUCTION_DN) -+ ACI_ALLOW = "(version 3.0; acl \"MODDN production changing the RDN attribute\"; allow (read,search,write)" -+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN -+ ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT -+ -+ # successfull MOD with the ACI -+ _bind_manager(topology) -+ mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)] -+ topology.master1.modify_s(SUFFIX, mod) -+ _bind_normal(topology) -+ -+ request_ctrl = GetEffectiveRightsControl(criticality=True,authzId="dn: " + BIND_DN) -+ msg_id = topology.master1.search_ext(PRODUCTION_DN, ldap.SCOPE_SUBTREE, "objectclass=*", serverctrls=[request_ctrl]) -+ rtype,rdata,rmsgid,response_ctrl = topology.master1.result3(msg_id) -+ ger={} -+ value='' -+ for dn, attrs in rdata: -+ topology.master1.log.info ("dn: %s" % dn) -+ value = attrs['entryLevelRights'][0] -+ -+ topology.master1.log.info ("############### entryLevelRights: %r" % value) -+ assert 'n' in value -+ -+ # successfull MOD with the both ACI -+ _bind_manager(topology) -+ mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)] -+ topology.master1.modify_s(SUFFIX, mod) -+ _bind_normal(topology) -+ -+ -+def test_ticket47553_final(topology): -+ topology.master1.stop(timeout=10) -+ topology.master2.stop(timeout=10) -+ -+def run_isolated(): -+ ''' -+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..) -+ To run isolated without py.test, you need to -+ - edit this file and comment '@pytest.fixture' line before 'topology' function. -+ - set the installation prefix -+ - run this program -+ ''' -+ global installation1_prefix -+ global installation2_prefix -+ installation1_prefix = None -+ installation2_prefix = None -+ -+ topo = topology(True) -+ topo.master1.log.info("\n\n######################### Ticket 47553 ######################\n") -+ test_ticket47553_init(topo) -+ -+ # Check that without appropriate aci we are not allowed to add/delete -+ test_ticket47553_mode_default_add_deny(topo) -+ test_ticket47553_mode_default_ger_no_moddn(topo) -+ test_ticket47553_mode_default_ger_with_moddn(topo) -+ test_ticket47553_mode_switch_default_to_legacy(topo) -+ test_ticket47553_mode_legacy_ger_no_moddn1(topo) -+ test_ticket47553_mode_legacy_ger_no_moddn2(topo) -+ test_ticket47553_mode_legacy_ger_with_moddn(topo) -+ -+ test_ticket47553_final(topo) -+ -+ -+ -+ -+if __name__ == '__main__': -+ run_isolated() -+ -diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c -index b9e2055..3c7d635 100644 ---- a/ldap/servers/plugins/acl/acleffectiverights.c -+++ b/ldap/servers/plugins/acl/acleffectiverights.c -@@ -456,38 +456,45 @@ _ger_get_entry_rights ( - entryrights |= SLAPI_ACL_DELETE; - _append_gerstr(gerstr, gerstrsize, gerstrcap, "d", NULL); - } -- /* -- * Some limitation/simplification applied here: -- * - The modrdn right requires the rights to delete the old rdn and -- * the new one. However we have no knowledge of what the new rdn -- * is going to be. -- * - In multi-valued RDN case, we check the right on -- * the first rdn type only for now. -- */ -- rdn = slapi_rdn_new_dn ( slapi_entry_get_ndn (e) ); -- slapi_rdn_get_first(rdn, &rdntype, &rdnvalue); -- if ( NULL != rdntype ) { -- slapi_log_error (SLAPI_LOG_ACL, plugin_name, -- "_ger_get_entry_rights: SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype ); -- if (acl_access_allowed(gerpb, e, rdntype, NULL, -- ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS && -- acl_access_allowed(gerpb, e, rdntype, NULL, -- ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) -- { -- /* n - rename e */ -- entryrights |= SLAPI_ACL_WRITE; -- _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL); -- } -- } -- slapi_rdn_free ( &rdn ); -- -- if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_MODDN) == LDAP_SUCCESS) { -- slapi_log_error (SLAPI_LOG_ACL, plugin_name, -- "_ger_get_entry_rights: SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn (e) ); -+ -+ if (config_get_moddn_aci()) { -+ /* The server enforces the new MODDN aci right. -+ * So the status 'n' is set if this right is granted. -+ * Opposed to the legacy mode where this flag is set if -+ * WRITE was granted on rdn attrbibute -+ */ -+ if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_MODDN) == LDAP_SUCCESS) { -+ slapi_log_error(SLAPI_LOG_ACL, plugin_name, -+ "_ger_get_entry_rights: SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn(e)); -+ /* n - rename e */ -+ entryrights |= SLAPI_ACL_MODDN; -+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL); -+ } -+ } else { -+ /* -+ * Some limitation/simplification applied here: -+ * - The modrdn right requires the rights to delete the old rdn and -+ * the new one. However we have no knowledge of what the new rdn -+ * is going to be. -+ * - In multi-valued RDN case, we check the right on -+ * the first rdn type only for now. -+ */ -+ rdn = slapi_rdn_new_dn(slapi_entry_get_ndn(e)); -+ slapi_rdn_get_first(rdn, &rdntype, &rdnvalue); -+ if (NULL != rdntype) { -+ slapi_log_error(SLAPI_LOG_ACL, plugin_name, -+ "_ger_get_entry_rights: SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype); -+ if (acl_access_allowed(gerpb, e, rdntype, NULL, -+ ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS && -+ acl_access_allowed(gerpb, e, rdntype, NULL, -+ ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) { - /* n - rename e */ -- entryrights |= SLAPI_ACL_MODDN; -- _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL); -+ entryrights |= SLAPI_ACL_WRITE; -+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL); -+ } - } -+ slapi_rdn_free(&rdn); -+ } - if ( entryrights == 0 ) - { - _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL); --- -1.9.3 - diff --git a/SOURCES/0078-Ticket-48265-Complex-filter-in-a-search-request-doen.patch b/SOURCES/0078-Ticket-48265-Complex-filter-in-a-search-request-doen.patch deleted file mode 100644 index 9b9e18f..0000000 --- a/SOURCES/0078-Ticket-48265-Complex-filter-in-a-search-request-doen.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 924a6ec6ca3131ff7233fd664ede9051907d96b1 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Wed, 2 Sep 2015 14:28:27 -0700 -Subject: [PATCH 78/84] 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@redhat.com (Thank you, Mark!!) - -(cherry picked from commit 8c3d3e4648fbb5229e329e2154d46f1ae808ba02) -(cherry picked from commit 3d9dbf2d441e551495a1f3169dc2020324c484b4) -(cherry picked from commit c03a9f7c121355aefadc92ed67bcb6f400196017) ---- - ldap/servers/slapd/index_subsystem.c | 5 +++++ - 1 file changed, 5 insertions(+) - -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; - } --- -1.9.3 - diff --git a/SOURCES/0079-Ticket-47912-Proper-handling-of-No-original_tombston.patch b/SOURCES/0079-Ticket-47912-Proper-handling-of-No-original_tombston.patch deleted file mode 100644 index 8fe2078..0000000 --- a/SOURCES/0079-Ticket-47912-Proper-handling-of-No-original_tombston.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 8f54c897c404164c618c808435d3887e62d32915 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 7 Oct 2014 14:02:20 -0700 -Subject: [PATCH 79/84] Ticket #47912 - Proper handling of "No - original_tombstone for changenumber" errors - -Bug Description: As analyzed by Ludwig Krispen in - https://fedorahosted.org/389/ticket/47912#comment:1, -an error message "No original_tombstone for ..." is always logged -if original_tombstone does not exist. It should be just for the -case create_tombstone_entry. - -Fix Description: This patch place the original_tombstone handling -in "if (create_tombstone_entry)" clause. - -https://fedorahosted.org/389/ticket/47912 - -Reviewed by lkrispen@redhat.com (Thank you, Ludwig!!) - -(cherry picked from commit 36381c120773872d3d4d2cb2417f155e6ac790a6) ---- - ldap/servers/slapd/back-ldbm/ldbm_delete.c | 48 +++++++++++++++--------------- - 1 file changed, 24 insertions(+), 24 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -index 56ea3df..3de8efa 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -@@ -225,33 +225,33 @@ ldbm_back_delete( Slapi_PBlock *pb ) - free_delete_existing_entry = 1; /* must free the dup */ - if (create_tombstone_entry) { - slapi_sdn_set_ndn_byval(&nscpEntrySDN, slapi_sdn_get_ndn(slapi_entry_get_sdn(e->ep_entry))); -- } - -- /* reset tombstone entry */ -- if (original_tombstone) { -- /* must duplicate tombstone before returning it to cache, -- * which could free the entry. */ -- if ( (tmptombstone = backentry_dup( original_tombstone )) == NULL ) { -- 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_RETURN(&inst->inst_cache, &tombstone); -- if (tombstone) { -+ /* reset tombstone entry */ -+ if (original_tombstone) { -+ /* must duplicate tombstone before returning it to cache, -+ * which could free the entry. */ -+ if ( (tmptombstone = backentry_dup( original_tombstone )) == NULL ) { -+ 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_RETURN(&inst->inst_cache, &tombstone); -+ if (tombstone) { -+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete", -+ "conn=%lu op=%d [retry: %d] tombstone %s is not freed!!! refcnt %d, state %d\n", -+ conn_id, op_id, retry_count, slapi_entry_get_dn(tombstone->ep_entry), -+ tombstone->ep_refcnt, tombstone->ep_state); -+ } -+ tombstone = original_tombstone; -+ original_tombstone = tmptombstone; -+ tmptombstone = NULL; -+ } else { - slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete", -- "conn=%lu op=%d [retry: %d] tombstone %s is not freed!!! refcnt %d, state %d\n", -- conn_id, op_id, retry_count, slapi_entry_get_dn(tombstone->ep_entry), -- tombstone->ep_refcnt, tombstone->ep_state); -+ "conn=%lu op=%d [retry: %d] No original_tombstone for %s!!\n", -+ conn_id, op_id, retry_count, slapi_entry_get_dn(e->ep_entry)); - } -- tombstone = original_tombstone; -- original_tombstone = tmptombstone; -- tmptombstone = NULL; -- } else { -- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete", -- "conn=%lu op=%d [retry: %d] No original_tombstone for %s!!\n", -- conn_id, op_id, retry_count, slapi_entry_get_dn(e->ep_entry)); - } - if (ruv_c_init) { - /* reset the ruv txn stuff */ --- -1.9.3 - diff --git a/SOURCES/0080-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch b/SOURCES/0080-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch deleted file mode 100644 index 2ae359c..0000000 --- a/SOURCES/0080-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch +++ /dev/null @@ -1,809 +0,0 @@ -From d32a172a4bc927a5eb72acecfe07ba7fa8ea3a55 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 8 Jul 2015 11:48:27 -0400 -Subject: [PATCH 80/84] Ticket 48208 - CleanAllRUV should completely purge - changelog - -Bug Description: After cleanAllRUV finishes, the changelog still - contains entries from the cleaned rid. Under certain - conditions this can allow the RUV to get polluted - again, and the ruv element will be missing the replica - url. - -Fix Description: At the end of the cleaning task, fire of a thread to - to completely purge the changelog of all entries - containing the cleaned rid. - - Also, improved the cleanAllRUV task when dealing - with a server shutdown - previously if the timing is - right the task can "delay/hang" the shutdown process. - -https://fedorahosted.org/389/ticket/48208 - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit ff1c34538b0600259dba4801da2b2f0993fa5404) -(cherry picked from commit 9e4cf12cfbfde0761325b75c3fd5a8b39223760a) -(cherry picked from commit 46cd28db8402517febf0c5db4f2f869c491c41c0) ---- - ldap/servers/plugins/replication/cl5_api.c | 447 ++++++++++++++++++--- - ldap/servers/plugins/replication/cl5_api.h | 5 +- - .../plugins/replication/repl5_replica_config.c | 44 +- - 3 files changed, 430 insertions(+), 66 deletions(-) - -diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c -index 42e52ae..c5840b5 100644 ---- a/ldap/servers/plugins/replication/cl5_api.c -+++ b/ldap/servers/plugins/replication/cl5_api.c -@@ -353,14 +353,17 @@ static void _cl5TrimCleanup (); - static int _cl5TrimMain (void *param); - static void _cl5DoTrimming (ReplicaId rid); - static void _cl5CompactDBs(); --static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid); -+static void _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid); -+static int _cl5PurgeGetFirstEntry (Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key); -+static int _cl5PurgeGetNextEntry (CL5Entry *entry, void *iterator, DBT *key); -+static void _cl5TrimFile (Object *obj, long *numToTrim); - static PRBool _cl5CanTrim (time_t time, long *numToTrim); - static int _cl5ReadRUV (const char *replGen, Object *obj, PRBool purge); - static int _cl5WriteRUV (CL5DBFile *file, PRBool purge); - static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge); - static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge); - static int _cl5GetRUV2Purge2 (Object *fileObj, RUV **ruv); --void trigger_cl_trimming_thread(void *rid); -+void trigger_cl_purging_thread(void *rid); - - /* bakup/recovery, import/export */ - static int _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, -@@ -3499,9 +3502,17 @@ static void _cl5DoTrimming (ReplicaId rid) - trimmed more often than other. We might have to fix that by, for - example, randomizing starting point */ - obj = objset_first_obj (s_cl5Desc.dbFiles); -- while (obj && _cl5CanTrim ((time_t)0, &numToTrim)) -+ while (obj && (_cl5CanTrim ((time_t)0, &numToTrim) || rid)) - { -- _cl5TrimFile (obj, &numToTrim, rid); -+ if (rid){ -+ /* -+ * We are cleaning an invalid rid, and need to strip it -+ * from the changelog. -+ */ -+ _cl5PurgeRID (obj, rid); -+ } else { -+ _cl5TrimFile (obj, &numToTrim); -+ } - obj = objset_next_obj (s_cl5Desc.dbFiles, obj); - } - -@@ -3578,12 +3589,351 @@ bail: - return; - } - -+/* -+ * If the rid is not set it is the very first iteration of the changelog. -+ * If the rid is set, we are doing another pass, and we have a key as our -+ * starting point. -+ */ -+static int -+_cl5PurgeGetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key) -+{ -+ DBC *cursor = NULL; -+ DBT data = {0}; -+ CL5Iterator *it; -+ CL5DBFile *file; -+ int rc; -+ -+ file = (CL5DBFile*)object_get_data (obj); -+ -+ /* create cursor */ -+ rc = file->db->cursor(file->db, txnid, &cursor, 0); -+ if (rc != 0) -+ { -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeGetFirstEntry: failed to create cursor; db error - %d %s\n", rc, db_strerror(rc)); -+ rc = CL5_DB_ERROR; -+ goto done; -+ } -+ -+ key->flags = DB_DBT_MALLOC; -+ data.flags = DB_DBT_MALLOC; -+ while ((rc = cursor->c_get(cursor, key, &data, rid?DB_SET:DB_NEXT)) == 0) -+ { -+ /* skip service entries on the first pass (rid == 0)*/ -+ if (!rid && cl5HelperEntry ((char*)key->data, NULL)) -+ { -+ slapi_ch_free(&key->data); -+ slapi_ch_free(&(data.data)); -+ continue; -+ } -+ -+ /* format entry */ -+ rc = cl5DBData2Entry(data.data, data.size, entry); -+ slapi_ch_free(&(data.data)); -+ if (rc != 0) -+ { -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, -+ "_cl5PurgeGetFirstEntry: failed to format entry: %d\n", rc); -+ goto done; -+ } -+ -+ it = (CL5Iterator*)slapi_ch_malloc(sizeof (CL5Iterator)); -+ it->cursor = cursor; -+ object_acquire (obj); -+ it->file = obj; -+ *(CL5Iterator**)iterator = it; -+ -+ return CL5_SUCCESS; -+ } -+ -+ slapi_ch_free(&key->data); -+ slapi_ch_free(&(data.data)); -+ -+ /* walked of the end of the file */ -+ if (rc == DB_NOTFOUND) -+ { -+ rc = CL5_NOTFOUND; -+ goto done; -+ } -+ -+ /* db error occured while iterating */ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeGetFirstEntry: failed to get entry; db error - %d %s\n", -+ rc, db_strerror(rc)); -+ rc = CL5_DB_ERROR; -+ -+done: -+ /* -+ * We didn't success in assigning this cursor to the iterator, -+ * so we need to free the cursor here. -+ */ -+ if (cursor) -+ cursor->c_close(cursor); -+ -+ return rc; -+} -+ -+/* -+ * Get the next entry. If we get a lock error we will restart the process -+ * starting at the current key. -+ */ -+static int -+_cl5PurgeGetNextEntry (CL5Entry *entry, void *iterator, DBT *key) -+{ -+ CL5Iterator *it; -+ DBT data={0}; -+ int rc; -+ -+ it = (CL5Iterator*) iterator; -+ -+ key->flags = DB_DBT_MALLOC; -+ data.flags = DB_DBT_MALLOC; -+ while ((rc = it->cursor->c_get(it->cursor, key, &data, DB_NEXT)) == 0) -+ { -+ if (cl5HelperEntry ((char*)key->data, NULL)) -+ { -+ slapi_ch_free(&key->data); -+ slapi_ch_free(&(data.data)); -+ continue; -+ } -+ -+ /* format entry */ -+ rc = cl5DBData2Entry (data.data, data.size, entry); -+ slapi_ch_free (&(data.data)); -+ if (rc != 0) -+ { -+ if (rc != CL5_DB_LOCK_ERROR){ -+ /* Not a lock error, free the key */ -+ slapi_ch_free(&key->data); -+ } -+ slapi_log_error(rc == CL5_DB_LOCK_ERROR?SLAPI_LOG_REPL:SLAPI_LOG_FATAL, -+ repl_plugin_name_cl, -+ "_cl5PurgeGetNextEntry: failed to format entry: %d\n", -+ rc); -+ -+ } -+ -+ return rc; -+ } -+ slapi_ch_free(&(data.data)); -+ -+ /* walked of the end of the file or entry is out of range */ -+ if (rc == 0 || rc == DB_NOTFOUND){ -+ slapi_ch_free(&key->data); -+ return CL5_NOTFOUND; -+ } -+ if (rc != CL5_DB_LOCK_ERROR){ -+ /* Not a lock error, free the key */ -+ slapi_ch_free(&key->data); -+ } -+ -+ /* cursor operation failed */ -+ slapi_log_error(rc == CL5_DB_LOCK_ERROR?SLAPI_LOG_REPL:SLAPI_LOG_FATAL, -+ repl_plugin_name_cl, -+ "_cl5PurgeGetNextEntry: failed to get entry; db error - %d %s\n", -+ rc, db_strerror(rc)); -+ -+ return rc; -+} -+ -+#define MAX_RETRIES 10 -+/* -+ * _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) -+ * -+ * Clean the entire changelog of updates from the "cleaned rid" via CLEANALLRUV -+ * Delete entries in batches so we don't consume too many db locks, and we don't -+ * lockup the changelog during the entire purging process using one transaction. -+ * We save the key from the last iteration so we don't have to start from the -+ * beginning for each new iteration. -+ */ -+static void -+_cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) -+{ -+ slapi_operation_parameters op = {0}; -+ ReplicaId csn_rid; -+ CL5Entry entry; -+ DB_TXN *txnid = NULL; -+ DBT key = {0}; -+ void *iterator = NULL; -+ long totalTrimmed = 0; -+ long trimmed = 0; -+ char *starting_key = NULL; -+ int batch_count = 0; -+ int db_lock_retry_count = 0; -+ int first_pass = 1; -+ int finished = 0; -+ int rc = 0; -+ -+ PR_ASSERT (obj); -+ entry.op = &op; -+ -+ /* -+ * Keep processing the changelog until we are done, shutting down, or we -+ * maxed out on the db lock retries. -+ */ -+ while (!finished && db_lock_retry_count < MAX_RETRIES && !slapi_is_shutting_down()){ -+ trimmed = 0; -+ -+ /* -+ * Sleep a bit to allow others to use the changelog - we can't hog the -+ * changelog for the entire purge. -+ */ -+ DS_Sleep(PR_MillisecondsToInterval(100)); -+ -+ rc = TXN_BEGIN(s_cl5Desc.dbEnv, NULL, &txnid, 0); -+ if (rc != 0){ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeRID: failed to begin transaction; db error - %d %s. " -+ "Changelog was not purged of rid(%d)\n", -+ rc, db_strerror(rc), cleaned_rid); -+ return; -+ } -+ -+ /* -+ * Check every changelog entry for the cleaned rid -+ */ -+ rc = _cl5PurgeGetFirstEntry(obj, &entry, &iterator, txnid, first_pass?0:cleaned_rid, &key); -+ first_pass = 0; -+ while (rc == CL5_SUCCESS && !slapi_is_shutting_down()) { -+ /* -+ * Store the new starting key - we need this starting key in case -+ * we run out of locks and have to start the transaction over. -+ */ -+ slapi_ch_free_string(&starting_key); -+ starting_key = slapi_ch_strdup((char*)key.data); -+ -+ if(trimmed == 10000 || (batch_count && trimmed == batch_count)){ -+ /* -+ * Break out, and commit these deletes. Do not free the key, -+ * we need it for the next pass. -+ */ -+ cl5_operation_parameters_done (&op); -+ db_lock_retry_count = 0; /* reset the retry count */ -+ break; -+ } -+ if(op.csn){ -+ csn_rid = csn_get_replicaid (op.csn); -+ if (csn_rid == cleaned_rid){ -+ rc = _cl5CurrentDeleteEntry (iterator); -+ if (rc != CL5_SUCCESS){ -+ /* log error */ -+ cl5_operation_parameters_done (&op); -+ if (rc == CL5_DB_LOCK_ERROR){ -+ /* -+ * Ran out of locks, need to restart the transaction. -+ * Reduce the the batch count and reset the key to -+ * the starting point -+ */ -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, -+ "_cl5PurgeRID: Ran out of db locks deleting entry. " -+ "Reduce the batch value and restart.\n"); -+ batch_count = trimmed - 10; -+ if (batch_count < 10){ -+ batch_count = 10; -+ } -+ trimmed = 0; -+ slapi_ch_free(&(key.data)); -+ key.data = starting_key; -+ starting_key = NULL; -+ db_lock_retry_count++; -+ break; -+ } else { -+ /* fatal error */ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeRID: fatal error (%d)\n", rc); -+ slapi_ch_free(&(key.data)); -+ finished = 1; -+ break; -+ } -+ } -+ trimmed++; -+ } -+ } -+ slapi_ch_free(&(key.data)); -+ cl5_operation_parameters_done (&op); -+ -+ rc = _cl5PurgeGetNextEntry (&entry, iterator, &key); -+ if (rc == CL5_DB_LOCK_ERROR){ -+ /* -+ * Ran out of locks, need to restart the transaction. -+ * Reduce the the batch count and reset the key to the starting -+ * point. -+ */ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeRID: Ran out of db locks getting the next entry. " -+ "Reduce the batch value and restart.\n"); -+ batch_count = trimmed - 10; -+ if (batch_count < 10){ -+ batch_count = 10; -+ } -+ trimmed = 0; -+ cl5_operation_parameters_done (&op); -+ slapi_ch_free(&(key.data)); -+ key.data = starting_key; -+ starting_key = NULL; -+ db_lock_retry_count++; -+ break; -+ } -+ } -+ -+ if (rc == CL5_NOTFOUND){ -+ /* Scanned the entire changelog, we're done */ -+ finished = 1; -+ } -+ -+ /* Destroy the iterator before we finish with the txn */ -+ cl5DestroyIterator (iterator); -+ -+ /* -+ * Commit or abort the txn -+ */ -+ if (rc == CL5_SUCCESS || rc == CL5_NOTFOUND){ -+ rc = TXN_COMMIT (txnid, 0); -+ if (rc != 0){ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeRID: failed to commit transaction; db error - %d %s. " -+ "Changelog was not completely purged of rid (%d)\n", -+ rc, db_strerror(rc), cleaned_rid); -+ break; -+ } else if (finished){ -+ /* We're done */ -+ totalTrimmed += trimmed; -+ break; -+ } else { -+ /* Not done yet */ -+ totalTrimmed += trimmed; -+ trimmed = 0; -+ } -+ } else { -+ rc = TXN_ABORT (txnid); -+ if (rc != 0){ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeRID: failed to abort transaction; db error - %d %s. " -+ "Changelog was not completely purged of rid (%d)\n", -+ rc, db_strerror(rc), cleaned_rid); -+ } -+ if (batch_count == 0){ -+ /* This was not a retry. Fatal error, break out */ -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5PurgeRID: Changelog was not purged of rid (%d)\n", -+ cleaned_rid); -+ break; -+ } -+ } -+ } -+ slapi_ch_free_string(&starting_key); -+ -+ slapi_log_error (SLAPI_LOG_REPL, repl_plugin_name_cl, -+ "_cl5PurgeRID: Removed (%ld entries) that originated from rid (%d)\n", -+ totalTrimmed, cleaned_rid); -+} -+ - /* Note that each file contains changes for a single replicated area. - trimming algorithm: - */ - #define CL5_TRIM_MAX_PER_TRANSACTION 10 - --static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) -+static void _cl5TrimFile (Object *obj, long *numToTrim) - { - DB_TXN *txnid; - RUV *ruv = NULL; -@@ -3606,7 +3956,6 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) - } - - entry.op = &op; -- - while ( !finished && !slapi_is_shutting_down() ) - { - it = NULL; -@@ -3627,7 +3976,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) - } - - finished = _cl5GetFirstEntry (obj, &entry, &it, txnid); -- while ( !finished ) -+ while ( !finished && !slapi_is_shutting_down()) - { - /* - * This change can be trimmed if it exceeds purge -@@ -3641,11 +3990,12 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) - continue; - } - csn_rid = csn_get_replicaid (op.csn); -+ - if ( (*numToTrim > 0 || _cl5CanTrim (entry.time, numToTrim)) && - ruv_covers_csn_strict (ruv, op.csn) ) - { - rc = _cl5CurrentDeleteEntry (it); -- if ( rc == CL5_SUCCESS && cleaned_rid != csn_rid) -+ if ( rc == CL5_SUCCESS) - { - rc = _cl5UpdateRUV (obj, op.csn, PR_FALSE, PR_TRUE); - } -@@ -3659,7 +4009,6 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) - /* The above two functions have logged the error */ - abort = PR_TRUE; - } -- - } - else - { -@@ -3716,7 +4065,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) - rc = TXN_ABORT (txnid); - if (rc != 0) - { -- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, - "_cl5TrimFile: failed to abort transaction; db error - %d %s\n", - rc, db_strerror(rc)); - } -@@ -3727,7 +4076,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid) - if (rc != 0) - { - finished = 1; -- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, - "_cl5TrimFile: failed to commit transaction; db error - %d %s\n", - rc, db_strerror(rc)); - } -@@ -4751,9 +5100,9 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, - goto done; - } - #endif -- /* back off */ -+ /* back off */ - interval = PR_MillisecondsToInterval(slapi_rand() % 100); -- DS_Sleep(interval); -+ DS_Sleep(interval); - } - #if USE_DB_TXN - /* begin transaction */ -@@ -4799,19 +5148,19 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, - } - cnt ++; - } -- -+ - if (rc == 0) /* we successfully added entry */ - { - #if USE_DB_TXN - rc = TXN_COMMIT (txnid, 0); - #endif - } -- else -+ else - { -- char s[CSN_STRSIZE]; -- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ char s[CSN_STRSIZE]; -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, - "_cl5WriteOperationTxn: failed to write entry with csn (%s); " -- "db error - %d %s\n", csn_as_string(op->csn,PR_FALSE,s), -+ "db error - %d %s\n", csn_as_string(op->csn,PR_FALSE,s), - rc, db_strerror(rc)); - #if USE_DB_TXN - rc = TXN_ABORT (txnid); -@@ -4832,7 +5181,7 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, - /* update purge vector if we have not seen any changes from this replica before */ - _cl5UpdateRUV (file_obj, op->csn, PR_TRUE, PR_TRUE); - -- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl, -+ slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl, - "cl5WriteOperationTxn: successfully written entry with csn (%s)\n", csnStr); - rc = CL5_SUCCESS; - done: -@@ -4846,7 +5195,7 @@ done: - return rc; - } - --static int _cl5WriteOperation(const char *replName, const char *replGen, -+static int _cl5WriteOperation(const char *replName, const char *replGen, - const slapi_operation_parameters *op, PRBool local) - { - return _cl5WriteOperationTxn(replName, replGen, op, local, NULL); -@@ -4897,7 +5246,7 @@ static int _cl5GetFirstEntry (Object *obj, CL5Entry *entry, void **iterator, DB_ - goto done; - } - -- it = (CL5Iterator*)slapi_ch_malloc (sizeof (CL5Iterator)); -+ it = (CL5Iterator*)slapi_ch_malloc(sizeof (CL5Iterator)); - it->cursor = cursor; - object_acquire (obj); - it->file = obj; -@@ -4972,7 +5321,7 @@ static int _cl5GetNextEntry (CL5Entry *entry, void *iterator) - slapi_ch_free (&(data.data)); - if (rc != 0) - { -- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, - "_cl5GetNextEntry: failed to format entry: %d\n", rc); - } - -@@ -5001,38 +5350,42 @@ static int _cl5GetNextEntry (CL5Entry *entry, void *iterator) - } - - /* cursor operation failed */ -- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -- "_cl5GetNextEntry: failed to get entry; db error - %d %s\n", -- rc, db_strerror(rc)); -+ slapi_log_error(rc == CL5_DB_LOCK_ERROR?SLAPI_LOG_REPL:SLAPI_LOG_FATAL, -+ repl_plugin_name_cl, -+ "_cl5GetNextEntry: failed to get entry; db error - %d %s\n", -+ rc, db_strerror(rc)); - -- return CL5_DB_ERROR; -+ return rc; - } - - static int _cl5CurrentDeleteEntry (void *iterator) - { - int rc; - CL5Iterator *it; -- CL5DBFile *file; -+ CL5DBFile *file; - -- PR_ASSERT (iterator); -+ PR_ASSERT (iterator); - - it = (CL5Iterator*)iterator; - - rc = it->cursor->c_del (it->cursor, 0); - - if (rc == 0) { -- /* decrement entry count */ -- file = (CL5DBFile*)object_get_data (it->file); -- PR_AtomicDecrement (&file->entryCount); -- return CL5_SUCCESS; -- } else { -- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -- "_cl5CurrentDeleteEntry failed, err=%d %s\n", -- rc, db_strerror(rc)); -- /* We don't free(close) the cursor here, as the caller will free it by a call to cl5DestroyIterator */ -- /* Freeing it here is a potential bug, as the cursor can't be referenced later once freed */ -- return CL5_DB_ERROR; -- } -+ /* decrement entry count */ -+ file = (CL5DBFile*)object_get_data (it->file); -+ PR_AtomicDecrement (&file->entryCount); -+ return CL5_SUCCESS; -+ } else { -+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -+ "_cl5CurrentDeleteEntry failed, err=%d %s\n", -+ rc, db_strerror(rc)); -+ /* -+ * We don't free(close) the cursor here, as the caller will free it by -+ * a call to cl5DestroyIterator. Freeing it here is a potential bug, -+ * as the cursor can't be referenced later once freed. -+ */ -+ return rc; -+ } - } - - static PRBool _cl5IsValidIterator (const CL5Iterator *iterator) -@@ -6304,7 +6657,7 @@ static int _cl5ExportFile (PRFileDesc *prFile, Object *obj) - slapi_write_buffer (prFile, "\n", strlen("\n")); - - entry.op = &op; -- rc = _cl5GetFirstEntry (obj, &entry, &iterator, NULL); -+ rc = _cl5GetFirstEntry (obj, &entry, &iterator, NULL); - while (rc == CL5_SUCCESS) - { - rc = _cl5Operation2LDIF (&op, file->replGen, &buff, &len); -@@ -6725,16 +7078,16 @@ cl5CleanRUV(ReplicaId rid){ - slapi_rwlock_unlock (s_cl5Desc.stLock); - } - --void trigger_cl_trimming(ReplicaId rid){ -+void trigger_cl_purging(ReplicaId rid){ - PRThread *trim_tid = NULL; - -- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "trigger_cl_trimming: rid (%d)\n",(int)rid); -- trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_trimming_thread, -+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "trigger_cl_purging: rid (%d)\n",(int)rid); -+ trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_purging_thread, - (void *)&rid, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE); - if (NULL == trim_tid){ - slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -- "trigger_cl_trimming: failed to create trimming " -+ "trigger_cl_purging: failed to create trimming " - "thread; NSPR error - %d\n", PR_GetError ()); - } else { - /* need a little time for the thread to get started */ -@@ -6743,7 +7096,7 @@ void trigger_cl_trimming(ReplicaId rid){ - } - - void --trigger_cl_trimming_thread(void *arg){ -+trigger_cl_purging_thread(void *arg){ - ReplicaId rid = *(ReplicaId *)arg; - - /* make sure we have a change log, and we aren't closing it */ -@@ -6752,7 +7105,7 @@ trigger_cl_trimming_thread(void *arg){ - } - if (CL5_SUCCESS != _cl5AddThread()) { - slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, -- "trigger_cl_trimming: failed to increment thread count " -+ "trigger_cl_purging: failed to increment thread count " - "NSPR error - %d\n", PR_GetError ()); - } - _cl5DoTrimming(rid); -diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h -index ba9eb32..5dcc8e2 100644 ---- a/ldap/servers/plugins/replication/cl5_api.h -+++ b/ldap/servers/plugins/replication/cl5_api.h -@@ -145,6 +145,9 @@ enum - CL5_CSN_ERROR, /* CSN API failed */ - CL5_RUV_ERROR, /* RUV API failed */ - CL5_OBJSET_ERROR, /* namedobjset api failed */ -+ CL5_DB_LOCK_ERROR, /* bdb returns error 12 when the db runs out of locks, -+ this var needs to be in slot 12 of the list. -+ Do not re-order enum above! */ - CL5_PURGED_DATA, /* requested data has been purged */ - CL5_MISSING_DATA, /* data should be in the changelog, but is missing */ - CL5_UNKNOWN_ERROR, /* unclassified error */ -@@ -492,6 +495,6 @@ int cl5WriteRUV(); - int cl5DeleteRUV(); - void cl5CleanRUV(ReplicaId rid); - void cl5NotifyCleanup(int rid); --void trigger_cl_trimming(ReplicaId rid); -+void trigger_cl_purging(ReplicaId rid); - - #endif -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 1570ba7..974778c 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -1468,6 +1468,11 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not - */ - cl5CleanRUV(rid); - -+ /* -+ * Now purge the changelog -+ */ -+ trigger_cl_purging(rid); -+ - if (rc != RUV_SUCCESS){ - slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_task: task failed(%d)\n",rc); - return LDAP_OPERATIONS_ERROR; -@@ -1867,7 +1872,7 @@ replica_cleanallruv_thread(void *arg) - /* no agmts, just clean this replica */ - break; - } -- while (agmt_obj){ -+ while (agmt_obj && !slapi_is_shutting_down()){ - agmt = (Repl_Agmt*)object_get_data (agmt_obj); - if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ - agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj); -@@ -1947,13 +1952,15 @@ replica_cleanallruv_thread(void *arg) - break; - } - /* -- * need to sleep between passes -+ * Need to sleep between passes unless we are shutting down - */ -- cleanruv_log(data->task, CLEANALLRUV_ID, "Replicas have not been cleaned yet, " -- "retrying in %d seconds", interval); -- PR_Lock( notify_lock ); -- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); -- PR_Unlock( notify_lock ); -+ if (!slapi_is_shutting_down()){ -+ cleanruv_log(data->task, CLEANALLRUV_ID, "Replicas have not been cleaned yet, " -+ "retrying in %d seconds", interval); -+ PR_Lock( notify_lock ); -+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); -+ PR_Unlock( notify_lock ); -+ } - - if(interval < 14400){ /* 4 hour max */ - interval = interval * 2; -@@ -1964,10 +1971,9 @@ replica_cleanallruv_thread(void *arg) - - done: - /* -- * If the replicas are cleaned, release the rid, and trim the changelog -+ * If the replicas are cleaned, release the rid - */ - if(!aborted){ -- trigger_cl_trimming(data->rid); - delete_cleaned_rid_config(data); - /* make sure all the replicas have been "pre_cleaned" before finishing */ - check_replicas_are_done_cleaning(data); -@@ -1977,7 +1983,7 @@ done: - /* - * Shutdown or abort - */ -- if(!is_task_aborted(data->rid)){ -+ if(!is_task_aborted(data->rid) || slapi_is_shutting_down()){ - cleanruv_log(data->task, CLEANALLRUV_ID,"Server shutting down. Process will resume at server startup"); - } else { - cleanruv_log(data->task, CLEANALLRUV_ID,"Task aborted for rid(%d).",data->rid); -@@ -2212,7 +2218,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn) - not_all_caughtup = 0; - break; - } -- while (agmt_obj){ -+ while (agmt_obj && !slapi_is_shutting_down()){ - agmt = (Repl_Agmt*)object_get_data (agmt_obj); - if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ - agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj); -@@ -2269,7 +2275,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task) - not_all_alive = 0; - break; - } -- while (agmt_obj){ -+ while (agmt_obj && !slapi_is_shutting_down()){ - agmt = (Repl_Agmt*)object_get_data (agmt_obj); - if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){ - agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj); -@@ -3034,12 +3040,14 @@ replica_abort_task_thread(void *arg) - break; - } - /* -- * need to sleep between passes -+ * Need to sleep between passes. unless we are shutting down - */ -- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Retrying in %d seconds",interval); -- PR_Lock( notify_lock ); -- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); -- PR_Unlock( notify_lock ); -+ if (!slapi_is_shutting_down()){ -+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Retrying in %d seconds",interval); -+ PR_Lock( notify_lock ); -+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) ); -+ PR_Unlock( notify_lock ); -+ } - - if(interval < 14400){ /* 4 hour max */ - interval = interval * 2; -@@ -3057,7 +3065,7 @@ done: - * Wait for this server to stop its cleanallruv task(which removes the rid from the cleaned list) - */ - cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Waiting for CleanAllRUV task to abort..."); -- while(is_cleaned_rid(data->rid)){ -+ while(is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){ - DS_Sleep(PR_SecondsToInterval(1)); - count++; - if(count == 60){ /* it should not take this long */ --- -1.9.3 - diff --git a/SOURCES/0081-Ticket-47931-memberOf-retrocl-deadlocks.patch b/SOURCES/0081-Ticket-47931-memberOf-retrocl-deadlocks.patch deleted file mode 100644 index c5ce9dc..0000000 --- a/SOURCES/0081-Ticket-47931-memberOf-retrocl-deadlocks.patch +++ /dev/null @@ -1,1317 +0,0 @@ -From 570d9af5ceed18e600bbf040e48752f923718a01 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 4 Aug 2015 12:19:31 -0400 -Subject: [PATCH 81/84] Ticket 47931 - memberOf & retrocl deadlocks - -Bug Description: When concurrently updating multiple backends the - memberOf and retrocl plugins can deadlock on each - other. This is caused by the required retrocl lock, - and the db lock on the changenumber index in the - retrocl db. - -Fix Description: Added scoping to the retrocl that allows subtrees/suffixes - to be included or excluded. Also moved the existing - memberOf scoping outside of its global lock. - - Also improved the memberOf config copying to be consistent - and more efficient. Improved the memberOf scoping attributes - to be multivalued. And, properly valdiated new config - settings in the preop valdiation function, instead of the - "apply config" function. - -https://fedorahosted.org/389/ticket/47931 - -Valgrind: passed - -Reviewed by: nhosoi(Thanks!) - -(cherry picked from commit fd959ac864d6d86d24928bc2c6f097d1a6031ecd) -(cherry picked from commit d8108476d3bedbcc03f6c61bfb3d50e921faaf42) -(cherry picked from commit 9ba3240a177c156e365f22c721432321bb0a679e) ---- - ldap/servers/plugins/memberof/memberof.c | 247 ++++++++++++++--------- - ldap/servers/plugins/memberof/memberof.h | 8 +- - ldap/servers/plugins/memberof/memberof_config.c | 253 +++++++++++++++++------- - ldap/servers/plugins/retrocl/retrocl.c | 183 +++++++++++++++-- - ldap/servers/plugins/retrocl/retrocl.h | 4 + - ldap/servers/plugins/retrocl/retrocl_po.c | 41 +++- - 6 files changed, 536 insertions(+), 200 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index 14bad98..1840e34 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -148,7 +148,7 @@ static int memberof_compare(MemberOfConfig *config, const void *a, const void *b - static int memberof_qsort_compare(const void *a, const void *b); - static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr); - static int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN *sdn); --static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, -+static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, MemberOfConfig *config, - char **types, plugin_search_entry_callback callback, void *callback_data); - static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, - Slapi_Value *memberdn); -@@ -176,7 +176,7 @@ static const char *fetch_attr(Slapi_Entry *e, const char *attrname, - static void memberof_fixup_task_thread(void *arg); - static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str); - static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data); -- -+static int memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn); - - /*** implementation ***/ - -@@ -521,7 +521,8 @@ memberof_get_plugin_area() - int memberof_postop_del(Slapi_PBlock *pb) - { - int ret = SLAPI_PLUGIN_SUCCESS; -- MemberOfConfig configCopy = {0, 0, 0, 0}; -+ MemberOfConfig *mainConfig = NULL; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - Slapi_DN *sdn; - void *caller_id = NULL; - -@@ -541,12 +542,13 @@ int memberof_postop_del(Slapi_PBlock *pb) - struct slapi_entry *e = NULL; - - slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e ); -- -- /* We need to get the config lock first. Trying to get the -- * config lock after we already hold the op lock can cause -- * a deadlock. */ - memberof_rlock_config(); -- /* copy config so it doesn't change out from under us */ -+ mainConfig = memberof_get_config(); -+ if(!memberof_entry_in_scope(mainConfig, slapi_entry_get_sdn(e))){ -+ /* The entry is not in scope, bail...*/ -+ memberof_unlock_config(); -+ goto bail; -+ } - memberof_copy_config(&configCopy, memberof_get_config()); - memberof_unlock_config(); - -@@ -561,7 +563,6 @@ int memberof_postop_del(Slapi_PBlock *pb) - "memberof_postop_del: error deleting dn (%s) from group. Error (%d)\n", - slapi_sdn_get_dn(sdn),ret); - memberof_unlock(); -- memberof_free_config(&configCopy); - goto bail; - } - -@@ -586,10 +587,10 @@ int memberof_postop_del(Slapi_PBlock *pb) - } - } - memberof_unlock(); -+bail: - memberof_free_config(&configCopy); - } - --bail: - if(ret){ - slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); - ret = SLAPI_PLUGIN_FAILURE; -@@ -623,7 +624,7 @@ memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN * - - groupattrs[0] = config->groupattrs[i]; - -- rc = memberof_call_foreach_dn(pb, sdn, groupattrs, -+ rc = memberof_call_foreach_dn(pb, sdn, config, groupattrs, - memberof_del_dn_type_callback, &data); - } - -@@ -673,6 +674,20 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) - return rc; - } - -+/* Check if the the entry include scope is a child of the sdn */ -+static Slapi_DN* -+memberof_scope_is_child_of_dn(MemberOfConfig *config, Slapi_DN *sdn) -+{ -+ int i = 0; -+ -+ while(config->entryScopes && config->entryScopes[i]){ -+ if(slapi_sdn_issuffix(config->entryScopes[i], sdn)){ -+ return config->entryScopes[i]; -+ } -+ i++; -+ } -+ return NULL; -+} - /* - * Does a callback search of "type=dn" under the db suffix that "dn" is in, - * unless all_backends is set, then we look at all the backends. If "dn" -@@ -681,7 +696,7 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) - */ - int - memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, -- char **types, plugin_search_entry_callback callback, void *callback_data) -+ MemberOfConfig *config, char **types, plugin_search_entry_callback callback, void *callback_data) - { - Slapi_PBlock *search_pb = NULL; - Slapi_DN *base_sdn = NULL; -@@ -689,9 +704,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, - char *escaped_filter_val; - char *filter_str = NULL; - char *cookie = NULL; -- int all_backends = memberof_config_get_all_backends(); -- Slapi_DN *entry_scope = memberof_config_get_entry_scope(); -- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree(); -+ int all_backends = config->allBackends; - int types_name_len = 0; - int num_types = 0; - int dn_len = slapi_sdn_get_ndn_len(sdn); -@@ -699,11 +712,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, - int rc = 0; - int i = 0; - -- if (entry_scope && !slapi_sdn_issuffix(sdn, entry_scope)) { -- return (rc); -- } -- -- if (entry_scope_exclude_subtree && slapi_sdn_issuffix(sdn, entry_scope_exclude_subtree)) { -+ if (!memberof_entry_in_scope(config, sdn)) { - return (rc); - } - -@@ -760,6 +769,8 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, - search_pb = slapi_pblock_new(); - be = slapi_get_first_backend(&cookie); - while(be){ -+ Slapi_DN *scope_sdn = NULL; -+ - if(!all_backends){ - be = slapi_be_select(sdn); - if(be == NULL){ -@@ -775,13 +786,14 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, - continue; - } - } -- if (entry_scope) { -- if (slapi_sdn_issuffix(base_sdn, entry_scope)) { -+ -+ if (config->entryScopes || config->entryScopeExcludeSubtrees) { -+ if (memberof_entry_in_scope(config, base_sdn)) { - /* do nothing, entry scope is spanning - * multiple suffixes, start at suffix */ -- } else if (slapi_sdn_issuffix(entry_scope, base_sdn)) { -+ } else if ((scope_sdn = memberof_scope_is_child_of_dn(config, base_sdn))) { - /* scope is below suffix, set search base */ -- base_sdn = entry_scope; -+ base_sdn = scope_sdn; - } else if(!all_backends){ - break; - } else { -@@ -799,7 +811,6 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, - break; - } - -- - if(!all_backends){ - break; - } -@@ -824,10 +835,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - { - int ret = SLAPI_PLUGIN_SUCCESS; - void *caller_id = NULL; -- Slapi_DN *entry_scope = NULL; -- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree(); - -- entry_scope = memberof_config_get_entry_scope(); - slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, - "--> memberof_postop_modrdn\n" ); - -@@ -842,7 +850,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - if(memberof_oktodo(pb)) - { - MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - struct slapi_entry *pre_e = NULL; - struct slapi_entry *post_e = NULL; - Slapi_DN *pre_sdn = 0; -@@ -850,7 +858,6 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - - slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e ); - slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e ); -- - if(pre_e && post_e) - { - pre_sdn = slapi_entry_get_sdn(pre_e); -@@ -863,11 +870,19 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - memberof_copy_config(&configCopy, mainConfig); - memberof_unlock_config(); - -+ /* Need to check both the pre/post entries */ -+ if((pre_sdn && !memberof_entry_in_scope(&configCopy, pre_sdn)) && -+ (post_sdn && !memberof_entry_in_scope(&configCopy, post_sdn))) -+ { -+ /* The entry is not in scope */ -+ goto bail; -+ } -+ - memberof_lock(); - - /* update any downstream members */ - if(pre_sdn && post_sdn && configCopy.group_filter && -- 0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) -+ 0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) - { - int i = 0; - Slapi_Attr *attr = 0; -@@ -879,7 +894,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - if(0 == slapi_entry_attr_find(post_e, configCopy.groupattrs[i], &attr)) - { - if((ret = memberof_moddn_attr_list(pb, &configCopy, pre_sdn, -- post_sdn, attr) != 0)) -+ post_sdn, attr) != 0)) - { - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, - "memberof_postop_modrdn - update failed for (%s), error (%d)\n", -@@ -894,49 +909,49 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - * of other group entries. We need to update any member - * attributes to refer to the new name. */ - if (ret == LDAP_SUCCESS && pre_sdn && post_sdn) { -- if ((entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) || -- (entry_scope_exclude_subtree && slapi_sdn_issuffix(post_sdn, entry_scope_exclude_subtree))) { -+ if (!memberof_entry_in_scope(&configCopy, post_sdn)){ - if((ret = memberof_del_dn_from_groups(pb, &configCopy, pre_sdn))){ - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, - "memberof_postop_modrdn - delete dn failed for (%s), error (%d)\n", - slapi_sdn_get_dn(pre_sdn), ret); - } - if(ret == LDAP_SUCCESS && pre_e && configCopy.group_filter && -- 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) { -+ 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) -+ { - /* is the entry of interest as a group? */ -- int i = 0; -- Slapi_Attr *attr = 0; -- -- /* Loop through to find each grouping attribute separately. */ -- for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) { -- if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) { -- if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){ -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n", -- slapi_sdn_get_dn(pre_sdn),ret); -- } -+ int i = 0; -+ Slapi_Attr *attr = 0; - -+ /* Loop through to find each grouping attribute separately. */ -+ for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) { -+ if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) { -+ if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){ -+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n", -+ slapi_sdn_get_dn(pre_sdn),ret); - } -+ - } -- } -+ } -+ } - if(ret == LDAP_SUCCESS) { -- memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; -- if((ret = memberof_del_dn_type_callback(post_e, &del_data))){ -- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", -- slapi_entry_get_dn(post_e), ret); -- } -+ memberof_del_dn_data del_data = {0, configCopy.memberof_attr}; -+ if((ret = memberof_del_dn_type_callback(post_e, &del_data))){ -+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n", -+ slapi_entry_get_dn(post_e), ret); - } -+ } - } else { - if((ret = memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn))){ - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "memberof_postop_modrdn - replace dne failed for (%s), error (%d)\n", -+ "memberof_postop_modrdn - replace dn failed for (%s), error (%d)\n", - slapi_sdn_get_dn(pre_sdn), ret); - } - } - } -- - memberof_unlock(); -+bail: - memberof_free_config(&configCopy); - } - -@@ -978,7 +993,7 @@ memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, - - groupattrs[0] = config->groupattrs[i]; - -- if((ret = memberof_call_foreach_dn(pb, pre_sdn, groupattrs, -+ if((ret = memberof_call_foreach_dn(pb, pre_sdn, config, groupattrs, - memberof_replace_dn_type_callback, - &data))) - { -@@ -1096,12 +1111,11 @@ int memberof_postop_modify(Slapi_PBlock *pb) - goto done; - } - -- -- if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) -+ if(memberof_oktodo(pb)) - { - int config_copied = 0; - MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - /* get the mod set */ - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); -@@ -1120,19 +1134,22 @@ int memberof_postop_modify(Slapi_PBlock *pb) - * only copy the config the first time it's needed so - * it remains the same for all mods in the operation, - * despite any config changes that may be made. */ -- if (!config_copied) -- { -+ if (!config_copied){ - memberof_rlock_config(); - mainConfig = memberof_get_config(); - - if (memberof_is_grouping_attr(type, mainConfig)) - { - interested = 1; -+ if (!memberof_entry_in_scope(mainConfig, sdn)){ -+ /* Entry is not in scope */ -+ memberof_unlock_config(); -+ goto bail; -+ } - /* copy config so it doesn't change out from under us */ - memberof_copy_config(&configCopy, mainConfig); - config_copied = 1; - } -- - memberof_unlock_config(); - } else { - if (memberof_is_grouping_attr(type, &configCopy)) -@@ -1229,8 +1246,7 @@ int memberof_postop_modify(Slapi_PBlock *pb) - } - - bail: -- if (config_copied) -- { -+ if (config_copied){ - memberof_free_config(&configCopy); - } - -@@ -1276,22 +1292,25 @@ int memberof_postop_add(Slapi_PBlock *pb) - - if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) - { -- MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0}; - struct slapi_entry *e = NULL; -- -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig *mainConfig; - slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e ); -- - - /* is the entry of interest? */ - memberof_rlock_config(); - mainConfig = memberof_get_config(); - if(e && mainConfig && mainConfig->group_filter && - 0 == slapi_filter_test_simple(e, mainConfig->group_filter)) -+ - { - interested = 1; -- /* copy config so it doesn't change out from under us */ -- memberof_copy_config(&configCopy, mainConfig); -+ if(!memberof_entry_in_scope(mainConfig, slapi_entry_get_sdn(e))){ -+ /* Entry is not in scope */ -+ memberof_unlock_config(); -+ goto bail; -+ } -+ memberof_copy_config(&configCopy, memberof_get_config()); - } - memberof_unlock_config(); - -@@ -1316,11 +1335,11 @@ int memberof_postop_add(Slapi_PBlock *pb) - } - - memberof_unlock(); -- - memberof_free_config(&configCopy); - } - } - -+bail: - if(ret){ - slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); - ret = SLAPI_PLUGIN_FAILURE; -@@ -1358,26 +1377,61 @@ int memberof_oktodo(Slapi_PBlock *pb) - } - - if(slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0) -- { -+ { - slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, - "memberof_postop_oktodo: could not get parameters\n" ); - ret = -1; - } - -- /* this plugin should only execute if the operation succeeded -- */ -- if(oprc != 0) -+ /* this plugin should only execute if the operation succeeded */ -+ if(oprc != 0) - { - ret = 0; - } -- -+ -+bail: - slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, - "<-- memberof_postop_oktodo\n" ); - --bail: - return ret; - } - -+/* -+ * Return 1 if the entry is in the scope. -+ * For MODRDN the caller should check both the preop -+ * and postop entries. If we are moving out of, or -+ * into scope, we should process it. -+ */ -+static int -+memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn) -+{ -+ if (config->entryScopeExcludeSubtrees){ -+ int i = 0; -+ -+ /* check the excludes */ -+ while(config->entryScopeExcludeSubtrees[i]){ -+ if (slapi_sdn_issuffix(sdn, config->entryScopeExcludeSubtrees[i])){ -+ return 0; -+ } -+ i++; -+ } -+ } -+ if (config->entryScopes){ -+ int i = 0; -+ -+ /* check the excludes */ -+ while(config->entryScopes[i]){ -+ if (slapi_sdn_issuffix(sdn, config->entryScopes[i])){ -+ return 1; -+ } -+ i++; -+ } -+ return 0; -+ } -+ -+ return 1; -+} -+ - static Slapi_DN * - memberof_getsdn(Slapi_PBlock *pb) - { -@@ -2045,7 +2099,7 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn, - { - /* Search for any grouping attributes that point to memberdn. - * For each match, add it to the list, recurse and do same search */ -- return memberof_call_foreach_dn(NULL, member_sdn, config->groupattrs, -+ return memberof_call_foreach_dn(NULL, member_sdn, config, config->groupattrs, - memberof_get_groups_callback, data); - } - -@@ -2057,12 +2111,12 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) - { - Slapi_DN *group_sdn = slapi_entry_get_sdn(e); - char *group_ndn = slapi_entry_get_ndn(e); -- char *group_dn = slapi_entry_get_dn(e); -+ char *group_dn = slapi_entry_get_dn(e); - Slapi_Value *group_ndn_val = 0; -- Slapi_Value *group_dn_val = 0; -+ Slapi_Value *group_dn_val = 0; - Slapi_ValueSet *groupvals = *((memberof_get_groups_data*)callback_data)->groupvals; -- Slapi_ValueSet *group_norm_vals = *((memberof_get_groups_data*)callback_data)->group_norm_vals; -- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree(); -+ Slapi_ValueSet *group_norm_vals = *((memberof_get_groups_data*)callback_data)->group_norm_vals; -+ MemberOfConfig *config = ((memberof_get_groups_data*)callback_data)->config; - int rc = 0; - - if(slapi_is_shutting_down()){ -@@ -2116,18 +2170,19 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) - goto bail; - } - -- /* if the group does not belong to an excluded subtree, adds it to the valueset */ -- if (!(entry_scope_exclude_subtree && slapi_sdn_issuffix(group_sdn, entry_scope_exclude_subtree))) { -- /* Push group_dn_val into the valueset. This memory is now owned -- * by the valueset. */ -- group_dn_val = slapi_value_new_string(group_dn); -- slapi_valueset_add_value_ext(groupvals, group_dn_val, SLAPI_VALUE_FLAG_PASSIN); -- slapi_valueset_add_value_ext(group_norm_vals, group_ndn_val, SLAPI_VALUE_FLAG_PASSIN); -- } -- -- /* now recurse to find parent groups of e */ -- memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config, -- group_sdn, callback_data); -+ /* if the group does not belong to an excluded subtree, adds it to the valueset */ -+ if (memberof_entry_in_scope(config, group_sdn)) { -+ /* Push group_dn_val into the valueset. This memory is now owned -+ * by the valueset. */ -+ group_dn_val = slapi_value_new_string(group_dn); -+ slapi_valueset_add_value_ext(groupvals, group_dn_val, SLAPI_VALUE_FLAG_PASSIN); -+ slapi_valueset_add_value_ext(group_norm_vals, group_ndn_val, SLAPI_VALUE_FLAG_PASSIN); -+ } -+ if(!config->skip_nested || config->fixup_task){ -+ /* now recurse to find parent groups of e */ -+ memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config, -+ group_sdn, callback_data); -+ } - - bail: - return rc; -@@ -2218,8 +2273,8 @@ memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, - { - char *attrs[2] = {config->memberof_attr, 0}; - -- return memberof_call_foreach_dn(pb, group_sdn, attrs, -- memberof_test_membership_callback , config); -+ return memberof_call_foreach_dn(pb, group_sdn, config, attrs, -+ memberof_test_membership_callback, config); - } - - /* -diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h -index 59029d7..4516387 100644 ---- a/ldap/servers/plugins/memberof/memberof.h -+++ b/ldap/servers/plugins/memberof/memberof.h -@@ -80,8 +80,10 @@ typedef struct memberofconfig { - char **groupattrs; - char *memberof_attr; - int allBackends; -- Slapi_DN *entryScope; -- Slapi_DN *entryScopeExcludeSubtree; -+ Slapi_DN **entryScopes; -+ int entryScopeCount; -+ Slapi_DN **entryScopeExcludeSubtrees; -+ int entryExcludeScopeCount; - Slapi_Filter *group_filter; - Slapi_Attr **group_slapiattrs; - } MemberOfConfig; -@@ -100,8 +102,6 @@ void memberof_rlock_config(); - void memberof_wlock_config(); - void memberof_unlock_config(); - int memberof_config_get_all_backends(); --Slapi_DN * memberof_config_get_entry_scope(); --Slapi_DN * memberof_config_get_entry_scope_exclude_subtree(); - void memberof_set_config_area(Slapi_DN *sdn); - Slapi_DN * memberof_get_config_area(); - void memberof_set_plugin_area(Slapi_DN *sdn); -diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c -index eb83bd0..5fc1314 100644 ---- a/ldap/servers/plugins/memberof/memberof_config.c -+++ b/ldap/servers/plugins/memberof/memberof_config.c -@@ -77,7 +77,7 @@ static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_En - /* This is the main configuration which is updated from dse.ldif. The - * config will be copied when it is used by the plug-in to prevent it - * being changed out from under a running memberOf operation. */ --static MemberOfConfig theConfig = {NULL, NULL,0, NULL, NULL, NULL, NULL}; -+static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - static Slapi_RWLock *memberof_config_lock = 0; - static int inited = 0; - -@@ -89,6 +89,19 @@ static int dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Ent - return SLAPI_DSE_CALLBACK_ERROR; - } - -+static void -+memberof_free_scope(Slapi_DN **scopes, int *count) -+{ -+ int i = 0; -+ -+ while(scopes && scopes[i]){ -+ slapi_sdn_free(&scopes[i]); -+ i++; -+ } -+ slapi_ch_free((void**)&scopes); -+ *count = 0; -+} -+ - /* - * memberof_config() - * -@@ -184,16 +197,22 @@ memberof_release_config() - * - * Validate the pending changes in the e entry. - */ --static int -+int - memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, - int *returncode, char *returntext, void *arg) - { - Slapi_Attr *memberof_attr = NULL; - Slapi_Attr *group_attr = NULL; - Slapi_DN *config_sdn = NULL; -+ Slapi_DN **include_dn = NULL; -+ Slapi_DN **exclude_dn = NULL; - char *syntaxoid = NULL; - char *config_dn = NULL; -+ char *skip_nested = NULL; -+ char **entry_scopes = NULL; -+ char **entry_exclude_scopes = NULL; - int not_dn_syntax = 0; -+ int num_vals = 0; - - *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */ - -@@ -301,8 +320,112 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr - *returncode = LDAP_UNWILLING_TO_PERFORM; - } - } -+ /* -+ * Check the entry scopes -+ */ -+ entry_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals); -+ if(entry_scopes){ -+ int i = 0; -+ -+ /* Validate the syntax before we create our DN array */ -+ for (i = 0;i < num_vals; i++){ -+ if(slapi_dn_syntax_check(pb, entry_scopes[i], 1)){ -+ /* invalid dn syntax */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "%s: Invalid DN (%s) for include suffix.", -+ MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); -+ slapi_ch_array_free(entry_scopes); -+ theConfig.entryScopeCount = 0; -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ goto done; -+ } -+ } -+ /* Now create our SDN array for conflict checking */ -+ include_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1); -+ for (i = 0;i < num_vals; i++){ -+ include_dn[i] = slapi_sdn_new_dn_passin(entry_scopes[i]); -+ } -+ } -+ /* -+ * Check and process the entry exclude scopes -+ */ -+ entry_exclude_scopes = -+ slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals); -+ if(entry_exclude_scopes){ -+ int i = 0; -+ -+ /* Validate the syntax before we create our DN array */ -+ for (i = 0;i < num_vals; i++){ -+ if(slapi_dn_syntax_check(pb, entry_exclude_scopes[i], 1)){ -+ /* invalid dn syntax */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "%s: Invalid DN (%s) for exclude suffix.", -+ MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); -+ slapi_ch_array_free(entry_exclude_scopes); -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ goto done; -+ } -+ } -+ /* Now create our SDN array for conflict checking */ -+ exclude_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); -+ for (i = 0;i < num_vals; i++){ -+ exclude_dn[i] = slapi_sdn_new_dn_passin(entry_exclude_scopes[i]); -+ } -+ } -+ /* -+ * Need to do conflict checking -+ */ -+ if(include_dn && exclude_dn){ -+ /* -+ * Make sure we haven't mixed the same suffix, and there are no -+ * conflicts between the includes and excludes -+ */ -+ int i = 0; -+ -+ while(include_dn[i]){ -+ int x = 0; -+ while(exclude_dn[x]){ -+ if(slapi_sdn_compare(include_dn[i], exclude_dn[x] ) == 0) -+ { -+ /* we have a conflict */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "%s: include suffix (%s) is also listed as an exclude suffix list", -+ MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i])); -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ goto done; -+ } -+ x++; -+ } -+ i++; -+ } -+ -+ /* Check for parent/child conflicts */ -+ i = 0; -+ while(include_dn[i]){ -+ int x = 0; -+ while(exclude_dn[x]){ -+ if(slapi_sdn_issuffix(include_dn[i], exclude_dn[x])) -+ { -+ /* we have a conflict */ -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "%s: include suffix (%s) is a child of the exclude suffix(%s)", -+ MEMBEROF_PLUGIN_SUBSYSTEM, -+ slapi_sdn_get_dn(include_dn[i]), -+ slapi_sdn_get_dn(exclude_dn[i])); -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ goto done; -+ } -+ x++; -+ } -+ i++; -+ } -+ } - - done: -+ memberof_free_scope(exclude_dn, &num_vals); -+ memberof_free_scope(include_dn, &num_vals); -+ slapi_ch_free((void**)&entry_scopes); -+ slapi_ch_free((void**)&entry_exclude_scopes); - slapi_sdn_free(&config_sdn); - slapi_ch_free_string(&config_dn); - -@@ -316,7 +439,6 @@ done: - } - } - -- - /* - * memberof_apply_config() - * -@@ -335,9 +457,11 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - int num_groupattrs = 0; - int groupattr_name_len = 0; - char *allBackends = NULL; -- char *entryScope = NULL; -- char *entryScopeExcludeSubtree = NULL; -+ char **entryScopes = NULL; -+ char **entryScopeExcludeSubtrees = NULL; - char *sharedcfg = NULL; -+ char *skip_nested = NULL; -+ int num_vals = 0; - - *returncode = LDAP_SUCCESS; - -@@ -369,8 +493,7 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR); - memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR); - allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR); -- entryScope = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_ATTR); -- entryScopeExcludeSubtree = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE); -+ skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR); - - /* - * We want to be sure we don't change the config in the middle of -@@ -487,49 +610,39 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - theConfig.allBackends = 0; - } - -- slapi_sdn_free(&theConfig.entryScope); -- if (entryScope) -- { -- if (slapi_dn_syntax_check(NULL, entryScope, 1) == 1) { -- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "Error: Ignoring invalid DN used as plugin entry scope: [%s]\n", -- entryScope); -- theConfig.entryScope = NULL; -- slapi_ch_free_string(&entryScope); -- } else { -- theConfig.entryScope = slapi_sdn_new_dn_passin(entryScope); -+ /* -+ * Check and process the entry scopes -+ */ -+ memberof_free_scope(theConfig.entryScopes, &theConfig.entryScopeCount); -+ entryScopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals); -+ if(entryScopes){ -+ int i = 0; -+ -+ /* Validation has already been performed in preop, just build the DN's */ -+ theConfig.entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1); -+ for (i = 0;i < num_vals; i++){ -+ theConfig.entryScopes[i] = slapi_sdn_new_dn_passin(entryScopes[i]); - } -- } else { -- theConfig.entryScope = NULL; -+ theConfig.entryScopeCount = num_vals; /* shortcut for config copy */ - } -- -- slapi_sdn_free(&theConfig.entryScopeExcludeSubtree); -- if (entryScopeExcludeSubtree) -- { -- if (theConfig.entryScope == NULL) { -- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "Error: Ignoring ExcludeSubtree (%s) because entryScope is not define\n", -- entryScopeExcludeSubtree); -- theConfig.entryScopeExcludeSubtree = NULL; -- slapi_ch_free_string(&entryScopeExcludeSubtree); -- } else if (slapi_dn_syntax_check(NULL, entryScopeExcludeSubtree, 1) == 1) { -- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "Error: Ignoring invalid DN used as plugin entry exclude subtree: [%s]\n", -- entryScopeExcludeSubtree); -- theConfig.entryScopeExcludeSubtree = NULL; -- slapi_ch_free_string(&entryScopeExcludeSubtree); -- } else { -- theConfig.entryScopeExcludeSubtree = slapi_sdn_new_dn_passin(entryScopeExcludeSubtree); -+ /* -+ * Check and process the entry exclude scopes -+ */ -+ memberof_free_scope(theConfig.entryScopeExcludeSubtrees, -+ &theConfig.entryExcludeScopeCount); -+ entryScopeExcludeSubtrees = -+ slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals); -+ if(entryScopeExcludeSubtrees){ -+ int i = 0; -+ -+ /* Validation has already been performed in preop, just build the DN's */ -+ theConfig.entryScopeExcludeSubtrees = -+ (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); -+ for (i = 0;i < num_vals; i++){ -+ theConfig.entryScopeExcludeSubtrees[i] = -+ slapi_sdn_new_dn_passin(entryScopeExcludeSubtrees[i]); - } -- } else { -- theConfig.entryScopeExcludeSubtree = NULL; -- } -- if (theConfig.entryScopeExcludeSubtree && theConfig.entryScope && !slapi_sdn_issuffix(theConfig.entryScopeExcludeSubtree, theConfig.entryScope)) { -- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, -- "Error: Ignoring ExcludeSubtree (%s) that is out of the scope (%s)\n", -- slapi_sdn_get_dn(theConfig.entryScopeExcludeSubtree), -- slapi_sdn_get_dn(theConfig.entryScope)); -- slapi_sdn_free(&theConfig.entryScopeExcludeSubtree); -+ theConfig.entryExcludeScopeCount = num_vals; /* shortcut for config copy */ - } - - /* release the lock */ -@@ -542,6 +655,9 @@ done: - slapi_ch_free_string(&sharedcfg); - slapi_ch_free_string(&memberof_attr); - slapi_ch_free_string(&allBackends); -+ slapi_ch_free_string(&skip_nested); -+ slapi_ch_free((void **)&entryScopes); -+ slapi_ch_free((void **)&entryScopeExcludeSubtrees); - - if (*returncode != LDAP_SUCCESS) - { -@@ -618,6 +734,23 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) - { - dest->allBackends = src->allBackends; - } -+ -+ if(src->entryScopes){ -+ int num_vals = 0; -+ -+ dest->entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryScopeCount+1); -+ for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){ -+ dest->entryScopes[num_vals] = slapi_sdn_dup(src->entryScopes[num_vals]); -+ } -+ } -+ if(src->entryScopeExcludeSubtrees){ -+ int num_vals = 0; -+ -+ dest->entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryExcludeScopeCount+1); -+ for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){ -+ dest->entryScopeExcludeSubtrees[num_vals] = slapi_sdn_dup(src->entryScopeExcludeSubtrees[num_vals]); -+ } -+ } - } - } - -@@ -643,6 +776,8 @@ memberof_free_config(MemberOfConfig *config) - slapi_ch_free((void **)&config->group_slapiattrs); - - slapi_ch_free_string(&config->memberof_attr); -+ memberof_free_scope(config->entryScopes, &config->entryScopeCount); -+ memberof_free_scope(config->entryScopeExcludeSubtrees, &config->entryExcludeScopeCount); - } - } - -@@ -708,30 +843,6 @@ memberof_config_get_all_backends() - return all_backends; - } - --Slapi_DN * --memberof_config_get_entry_scope() --{ -- Slapi_DN *entry_scope; -- -- slapi_rwlock_rdlock(memberof_config_lock); -- entry_scope = theConfig.entryScope; -- slapi_rwlock_unlock(memberof_config_lock); -- -- return entry_scope; --} -- --Slapi_DN * --memberof_config_get_entry_scope_exclude_subtree() --{ -- Slapi_DN *entry_exclude_subtree; -- -- slapi_rwlock_rdlock(memberof_config_lock); -- entry_exclude_subtree = theConfig.entryScopeExcludeSubtree; -- slapi_rwlock_unlock(memberof_config_lock); -- -- return entry_exclude_subtree; --} -- - /* - * Check if we are modifying the config, or changing the shared config entry - */ -diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c -index 8a0f350..7679c29 100644 ---- a/ldap/servers/plugins/retrocl/retrocl.c -+++ b/ldap/servers/plugins/retrocl/retrocl.c -@@ -82,6 +82,9 @@ char **retrocl_attributes = NULL; - char **retrocl_aliases = NULL; - int retrocl_log_deleted = 0; - -+static Slapi_DN **retrocl_includes = NULL; -+static Slapi_DN **retrocl_excludes = NULL; -+ - /* ----------------------------- Retrocl Plugin */ - - static Slapi_PluginDesc retrocldesc = {"retrocl", VENDOR, DS_PACKAGE_VERSION, "Retrocl Plugin"}; -@@ -386,6 +389,8 @@ static int retrocl_start (Slapi_PBlock *pb) - int rc = 0; - Slapi_Entry *e = NULL; - char **values = NULL; -+ int num_vals = 0; -+ int i = 0; - - retrocl_rootdse_init(pb); - -@@ -406,6 +411,87 @@ static int retrocl_start (Slapi_PBlock *pb) - return -1; - } - -+ /* Get the exclude suffixes */ -+ values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_EXCLUDE_SUFFIX, &num_vals); -+ if(values){ -+ /* Validate the syntax before we create our DN array */ -+ for (i = 0;i < num_vals; i++){ -+ if(slapi_dn_syntax_check(pb, values[i], 1)){ -+ /* invalid dn syntax */ -+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, -+ "Invalid DN (%s) for exclude suffix.\n", values[i] ); -+ slapi_ch_array_free(values); -+ return -1; -+ } -+ } -+ /* Now create our SDN array */ -+ retrocl_excludes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); -+ for (i = 0;i < num_vals; i++){ -+ retrocl_excludes[i] = slapi_sdn_new_dn_byval(values[i]); -+ } -+ slapi_ch_array_free(values); -+ } -+ /* Get the include suffixes */ -+ values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_INCLUDE_SUFFIX, &num_vals); -+ if(values){ -+ for (i = 0;i < num_vals; i++){ -+ /* Validate the syntax before we create our DN array */ -+ if(slapi_dn_syntax_check(pb, values[i], 1)){ -+ /* invalid dn syntax */ -+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, -+ "Invalid DN (%s) for include suffix.\n", values[i] ); -+ slapi_ch_array_free(values); -+ return -1; -+ } -+ } -+ /* Now create our SDN array */ -+ retrocl_includes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); -+ for (i = 0;i < num_vals; i++){ -+ retrocl_includes[i] = slapi_sdn_new_dn_byval(values[i]); -+ } -+ slapi_ch_array_free(values); -+ } -+ if(retrocl_includes && retrocl_excludes){ -+ /* -+ * Make sure we haven't mixed the same suffix, and there are no -+ * conflicts between the includes and excludes -+ */ -+ int i = 0; -+ -+ while(retrocl_includes[i]){ -+ int x = 0; -+ while(retrocl_excludes[x]){ -+ if(slapi_sdn_compare(retrocl_includes[i], retrocl_excludes[x] ) == 0){ -+ /* we have a conflict */ -+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, -+ "include suffix (%s) is also listed in exclude suffix list\n", -+ slapi_sdn_get_dn(retrocl_includes[i])); -+ return -1; -+ } -+ x++; -+ } -+ i++; -+ } -+ -+ /* Check for parent/child conflicts */ -+ i = 0; -+ while(retrocl_includes[i]){ -+ int x = 0; -+ while(retrocl_excludes[x]){ -+ if(slapi_sdn_issuffix(retrocl_includes[i], retrocl_excludes[x])){ -+ /* we have a conflict */ -+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, -+ "include suffix (%s) is a child of the exclude suffix(%s)\n", -+ slapi_sdn_get_dn(retrocl_includes[i]), -+ slapi_sdn_get_dn(retrocl_excludes[i])); -+ return -1; -+ } -+ x++; -+ } -+ i++; -+ } -+ } -+ - values = slapi_entry_attr_get_charray(e, "nsslapd-attribute"); - if (values != NULL) { - int n = 0; -@@ -471,6 +557,49 @@ static int retrocl_start (Slapi_PBlock *pb) - } - - /* -+ * Check if an entry is in the configured scope. -+ * Return 1 if entry is in the scope, or 0 otherwise. -+ * For MODRDN the caller should check both the preop -+ * and postop entries. If we are moving out of, or -+ * into scope, we should record it. -+ */ -+int -+retrocl_entry_in_scope(Slapi_Entry *e) -+{ -+ Slapi_DN *sdn = slapi_entry_get_sdn(e); -+ -+ if (e == NULL){ -+ return 1; -+ } -+ -+ if (retrocl_excludes){ -+ int i = 0; -+ -+ /* check the excludes */ -+ while(retrocl_excludes[i]){ -+ if (slapi_sdn_issuffix(sdn, retrocl_excludes[i])){ -+ return 0; -+ } -+ i++; -+ } -+ } -+ if (retrocl_includes){ -+ int i = 0; -+ -+ /* check the excludes */ -+ while(retrocl_includes[i]){ -+ if (slapi_sdn_issuffix(sdn, retrocl_includes[i])){ -+ return 1; -+ } -+ i++; -+ } -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/* - * Function: retrocl_stop - * - * Returns: 0 -@@ -483,26 +612,40 @@ static int retrocl_start (Slapi_PBlock *pb) - - static int retrocl_stop (Slapi_PBlock *pb) - { -- int rc = 0; -- -- slapi_ch_array_free(retrocl_attributes); -- retrocl_attributes = NULL; -- slapi_ch_array_free(retrocl_aliases); -- retrocl_aliases = NULL; -- -- retrocl_stop_trimming(); -- retrocl_be_changelog = NULL; -- retrocl_forget_changenumbers(); -- PR_DestroyLock(retrocl_internal_lock); -- retrocl_internal_lock = NULL; -- slapi_destroy_rwlock(retrocl_cn_lock); -- retrocl_cn_lock = NULL; -- legacy_initialised = 0; -- -- slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "", -- LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search); -- -- return rc; -+ int rc = 0; -+ int i = 0; -+ -+ slapi_ch_array_free(retrocl_attributes); -+ retrocl_attributes = NULL; -+ slapi_ch_array_free(retrocl_aliases); -+ retrocl_aliases = NULL; -+ -+ while(retrocl_excludes && retrocl_excludes[i]){ -+ slapi_sdn_free(&retrocl_excludes[i]); -+ i++; -+ } -+ slapi_ch_free((void**)&retrocl_excludes); -+ i = 0; -+ -+ while(retrocl_includes && retrocl_includes[i]){ -+ slapi_sdn_free(&retrocl_includes[i]); -+ i++; -+ } -+ slapi_ch_free((void**)&retrocl_includes); -+ -+ retrocl_stop_trimming(); -+ retrocl_be_changelog = NULL; -+ retrocl_forget_changenumbers(); -+ PR_DestroyLock(retrocl_internal_lock); -+ retrocl_internal_lock = NULL; -+ slapi_destroy_rwlock(retrocl_cn_lock); -+ retrocl_cn_lock = NULL; -+ legacy_initialised = 0; -+ -+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "", -+ LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search); -+ -+ return rc; - } - - /* -diff --git a/ldap/servers/plugins/retrocl/retrocl.h b/ldap/servers/plugins/retrocl/retrocl.h -index 27f55dc..fe8bf84 100644 ---- a/ldap/servers/plugins/retrocl/retrocl.h -+++ b/ldap/servers/plugins/retrocl/retrocl.h -@@ -96,6 +96,8 @@ typedef struct _cnumRet { - /* was originally changelogmaximumage */ - #define CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE "nsslapd-changelogmaxage" - #define CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE "nsslapd-changelogdir" -+#define CONFIG_CHANGELOG_INCLUDE_SUFFIX "nsslapd-include-suffix" -+#define CONFIG_CHANGELOG_EXCLUDE_SUFFIX "nsslapd-exclude-suffix" - - #define RETROCL_CHANGELOG_DN "cn=changelog" - #define RETROCL_MAPPINGTREE_DN "cn=\"cn=changelog\",cn=mapping tree,cn=config" -@@ -169,4 +171,6 @@ extern void retrocl_init_trimming(void); - extern void retrocl_stop_trimming(void); - extern char *retrocl_get_config_str(const char *attrt); - -+int retrocl_entry_in_scope(Slapi_Entry *e); -+ - #endif /* _H_RETROCL */ -diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c -index 3f8af81..8010db0 100644 ---- a/ldap/servers/plugins/retrocl/retrocl_po.c -+++ b/ldap/servers/plugins/retrocl/retrocl_po.c -@@ -169,6 +169,7 @@ write_replog_db( - int flag, - time_t curtime, - Slapi_Entry *log_e, -+ Slapi_Entry *post_entry, - const char *newrdn, - LDAPMod **modrdn_mods, - const char *newsuperior -@@ -185,11 +186,26 @@ 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)){ -+ /* modrdn: entry not in scope, just return... */ -+ return ret; -+ } -+ } else { -+ if(!retrocl_entry_in_scope(log_e)){ -+ /* entry not in scope, just return... */ -+ return ret; -+ } -+ } - - PR_Lock(retrocl_internal_lock); - changenum = retrocl_assign_changenumber(); -@@ -348,7 +364,7 @@ write_replog_db( - break; - - case OP_DELETE: -- if (log_e) { -+ if (retrocl_log_deleted) { - /* we have to log the full entry */ - if ( entry2reple( e, log_e, OP_DELETE ) != 0 ) { - err = SLAPI_PLUGIN_FAILURE; -@@ -588,7 +604,8 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) - char *dn; - LDAPMod **log_m = NULL; - int flag = 0; -- Slapi_Entry *te = NULL; -+ Slapi_Entry *entry = NULL; -+ Slapi_Entry *post_entry = NULL; - Slapi_Operation *op = NULL; - LDAPMod **modrdn_mods = NULL; - char *newrdn = NULL; -@@ -649,7 +666,12 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) - LDAPDebug0Args(LDAP_DEBUG_TRACE,"not applying change for nsTombstone entries\n"); - return SLAPI_PLUGIN_SUCCESS; - } -- -+ /* -+ * Start by grabbing the preop entry, ADD will replace it as needed. Getting the entry -+ * allows up to perform scoping in write_replog_db() for all op types. -+ */ -+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry); -+ - switch ( optype ) { - case OP_MODIFY: - (void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &log_m ); -@@ -659,14 +681,14 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) - * For adds, we want the unnormalized dn, so we can preserve - * spacing, case, when replicating it. - */ -- (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &te ); -- if ( NULL != te ) { -- dn = slapi_entry_get_dn( te ); -+ (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &entry ); -+ if ( NULL != entry ) { -+ dn = slapi_entry_get_dn( entry ); - } - break; - case OP_DELETE: - if (retrocl_log_deleted) -- (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &te); -+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry); - break; - case OP_MODRDN: - /* newrdn is used just for logging; no need to be normalized */ -@@ -674,13 +696,14 @@ int retrocl_postob (Slapi_PBlock *pb, int optype) - (void)slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &flag ); - (void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &modrdn_mods ); - (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior ); -+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &post_entry); - break; - } - - /* check if we should log change to retro changelog, and - * if so, do it here */ -- if((rc = write_replog_db( pb, optype, dn, log_m, flag, curtime, te, -- newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior) ))) -+ if((rc = write_replog_db( pb, optype, dn, log_m, flag, curtime, entry, -+ post_entry, newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior) ))) - { - slapi_log_error(SLAPI_LOG_FATAL, "retrocl-plugin", - "retrocl_postob: operation failure [%d]\n", rc); --- -1.9.3 - diff --git a/SOURCES/0082-Ticket-47931-Fix-coverity-issues.patch b/SOURCES/0082-Ticket-47931-Fix-coverity-issues.patch deleted file mode 100644 index eeaab2e..0000000 --- a/SOURCES/0082-Ticket-47931-Fix-coverity-issues.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 476ffd9a01ac5bb55d32edad64c68eebd8773861 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 10 Aug 2015 10:42:40 -0400 -Subject: [PATCH 82/84] Ticket 47931 - Fix coverity issues - -Description: Fix coverity issues in memberof_config.c - - 13316 - double free - 13315 - Dereference after null check - 13314 - Dereference after null check - 13313 - copy/paste error - -https://fedorahosted.org/389/ticket/47931 - -Reviewed by: rmeggins(Thanks!) - -(cherry picked from commit 5daea973e4526584ee41d7b9f4b1b4993b4de6f1) -(cherry picked from commit 9a0047ef75f6dbeb1980ac77fab5d62865c77e6a) -(cherry picked from commit a389bc3bafccb1f7bd9917a734230680e382af91) ---- - ldap/servers/plugins/memberof/memberof_config.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c -index 5fc1314..c335cab 100644 ---- a/ldap/servers/plugins/memberof/memberof_config.c -+++ b/ldap/servers/plugins/memberof/memberof_config.c -@@ -335,6 +335,7 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr - "%s: Invalid DN (%s) for include suffix.", - MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); - slapi_ch_array_free(entry_scopes); -+ entry_scopes = NULL; - theConfig.entryScopeCount = 0; - *returncode = LDAP_UNWILLING_TO_PERFORM; - goto done; -@@ -360,8 +361,9 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr - /* invalid dn syntax */ - PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, - "%s: Invalid DN (%s) for exclude suffix.", -- MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); -+ MEMBEROF_PLUGIN_SUBSYSTEM, entry_exclude_scopes[i]); - slapi_ch_array_free(entry_exclude_scopes); -+ entry_exclude_scopes = NULL; - *returncode = LDAP_UNWILLING_TO_PERFORM; - goto done; - } -@@ -747,7 +749,7 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) - int num_vals = 0; - - dest->entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryExcludeScopeCount+1); -- for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){ -+ for(num_vals = 0; src->entryScopeExcludeSubtrees[num_vals]; num_vals++){ - dest->entryScopeExcludeSubtrees[num_vals] = slapi_sdn_dup(src->entryScopeExcludeSubtrees[num_vals]); - } - } --- -1.9.3 - diff --git a/SOURCES/0083-Ticket-47831-remove-debug-logging-from-retro-cl.patch b/SOURCES/0083-Ticket-47831-remove-debug-logging-from-retro-cl.patch deleted file mode 100644 index c426060..0000000 --- a/SOURCES/0083-Ticket-47831-remove-debug-logging-from-retro-cl.patch +++ /dev/null @@ -1,41 +0,0 @@ -From cbab8a3051994db662348a3c9a1a19d56a8545ca Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 19 Aug 2015 10:03:50 -0400 -Subject: [PATCH 83/84] 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) -(cherry picked from commit 1781280f133c4877f83949400294641a558f5406) -(cherry picked from commit 0e44c819b72dfad40a7f9eea6067f6060fa9c35b) ---- - ldap/servers/plugins/retrocl/retrocl_po.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c -index 8010db0..d0cc5e8 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)){ --- -1.9.3 - diff --git a/SOURCES/0084-Ticket-47831-remove-debug-logging-from-retro-cl.patch b/SOURCES/0084-Ticket-47831-remove-debug-logging-from-retro-cl.patch deleted file mode 100644 index 69426c4..0000000 --- a/SOURCES/0084-Ticket-47831-remove-debug-logging-from-retro-cl.patch +++ /dev/null @@ -1,115 +0,0 @@ -From f5b9a4be65641b29e37e9a0f9a15fee91db2a1e6 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 8 Sep 2015 12:20:33 -0700 -Subject: [PATCH 84/84] Ticket 47831 - remove debug logging from retro cl - -Description: 47831 patch expects "skip_nested" which is not supposed -to be in the branch rhel-7.1. ---- - ldap/servers/plugins/memberof/memberof.c | 16 +++++++--------- - ldap/servers/plugins/memberof/memberof_config.c | 6 +----- - 2 files changed, 8 insertions(+), 14 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index 1840e34..4d79cf6 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -522,7 +522,7 @@ int memberof_postop_del(Slapi_PBlock *pb) - { - int ret = SLAPI_PLUGIN_SUCCESS; - MemberOfConfig *mainConfig = NULL; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - Slapi_DN *sdn; - void *caller_id = NULL; - -@@ -850,7 +850,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb) - if(memberof_oktodo(pb)) - { - MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - struct slapi_entry *pre_e = NULL; - struct slapi_entry *post_e = NULL; - Slapi_DN *pre_sdn = 0; -@@ -1115,7 +1115,7 @@ int memberof_postop_modify(Slapi_PBlock *pb) - { - int config_copied = 0; - MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - - /* get the mod set */ - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); -@@ -1293,7 +1293,7 @@ int memberof_postop_add(Slapi_PBlock *pb) - if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) - { - struct slapi_entry *e = NULL; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - MemberOfConfig *mainConfig; - slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e ); - -@@ -2178,11 +2178,9 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data) - slapi_valueset_add_value_ext(groupvals, group_dn_val, SLAPI_VALUE_FLAG_PASSIN); - slapi_valueset_add_value_ext(group_norm_vals, group_ndn_val, SLAPI_VALUE_FLAG_PASSIN); - } -- if(!config->skip_nested || config->fixup_task){ -- /* now recurse to find parent groups of e */ -- memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config, -- group_sdn, callback_data); -- } -+ /* now recurse to find parent groups of e */ -+ memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config, -+ group_sdn, callback_data); - - bail: - return rc; -diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c -index c335cab..6be7f3c 100644 ---- a/ldap/servers/plugins/memberof/memberof_config.c -+++ b/ldap/servers/plugins/memberof/memberof_config.c -@@ -77,7 +77,7 @@ static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_En - /* This is the main configuration which is updated from dse.ldif. The - * config will be copied when it is used by the plug-in to prevent it - * being changed out from under a running memberOf operation. */ --static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - static Slapi_RWLock *memberof_config_lock = 0; - static int inited = 0; - -@@ -208,7 +208,6 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr - Slapi_DN **exclude_dn = NULL; - char *syntaxoid = NULL; - char *config_dn = NULL; -- char *skip_nested = NULL; - char **entry_scopes = NULL; - char **entry_exclude_scopes = NULL; - int not_dn_syntax = 0; -@@ -462,7 +461,6 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - char **entryScopes = NULL; - char **entryScopeExcludeSubtrees = NULL; - char *sharedcfg = NULL; -- char *skip_nested = NULL; - int num_vals = 0; - - *returncode = LDAP_SUCCESS; -@@ -495,7 +493,6 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* - groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR); - memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR); - allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR); -- skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR); - - /* - * We want to be sure we don't change the config in the middle of -@@ -657,7 +654,6 @@ done: - slapi_ch_free_string(&sharedcfg); - slapi_ch_free_string(&memberof_attr); - slapi_ch_free_string(&allBackends); -- slapi_ch_free_string(&skip_nested); - slapi_ch_free((void **)&entryScopes); - slapi_ch_free((void **)&entryScopeExcludeSubtrees); - --- -1.9.3 - diff --git a/SOURCES/0085-Ticket-48195-Slow-replication-when-deleting-large-qu.patch b/SOURCES/0085-Ticket-48195-Slow-replication-when-deleting-large-qu.patch deleted file mode 100644 index f36fa21..0000000 --- a/SOURCES/0085-Ticket-48195-Slow-replication-when-deleting-large-qu.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e9faf2091c545c8967db41961ef3d14f449e6c8a Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Thu, 18 Jun 2015 15:22:54 +0200 -Subject: [PATCH 85/86] Ticket 48195 - Slow replication when deleting large - quantities of multi-valued attributes - -https://fedorahosted.org/389/ticket/48195 - -In update resoultion for entry deletion, there is still use of valuearray_find() to find an existingvalue to update its csn. -with the fix for ticket #346 there exists slapi_valueset_find() which uses the possibility to do a binary search on the -values. -Fix: do not use valuearray_find - -Review: Rich, Thanks -(cherry picked from commit 09ab8c799fc3d87db7a5b3aa07eccf9b41ea43d5) -(cherry picked from commit a980b795ac03200fd01a2d05ce568691681d50ef) -(cherry picked from commit 229ee77872d34acd53707e92c4d0861fa80b3d1f) ---- - ldap/servers/slapd/valueset.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index 1378bd1..9d77b0c 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -1440,12 +1440,12 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a, - int del_index = -1, del_count = 0; - for (i=0;valuestoupdate[i]!=NULL;++i) - { -- int index= valuearray_find(a, vs->va, valuestoupdate[i]); -- if(index!=-1) -+ Slapi_Value *v = slapi_valueset_find(a, vs, valuestoupdate[i]); -+ if(v) - { -- value_update_csn(vs->va[index],t,csn); -+ value_update_csn(v,t,csn); - if (csnref_updated) -- valuestoupdate[i]->v_csnset = (CSNSet *)value_get_csnset(vs->va[index]); -+ valuestoupdate[i]->v_csnset = (CSNSet *)value_get_csnset(v); - valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]); - valuestoupdate[i]= NULL; - del_count++; --- -1.9.3 - diff --git a/SOURCES/0086-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch b/SOURCES/0086-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch deleted file mode 100644 index e5ed2ee..0000000 --- a/SOURCES/0086-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 4c82238f0c4273dbf7cf945eebc2ede66f47f680 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Thu, 16 Jul 2015 10:34:47 -0700 -Subject: [PATCH 86/86] Ticket #48226 - In MMR, double free coould occur under - some special condition - -Bug description: - In a replicated topology, a authenticated user that have write access - on an entry can send a series of operations that crash the server. - The crash is due to an access to a already freed buffer. -Fix description: - To avoid the double free, duplicate a CSNSet and assign it to the - Slapi_Value. - -https://fedorahosted.org/389/ticket/48226 - -Reviewed by rmeggins@redhat.com (Thank you, Rich!!) - -(cherry picked from commit a0f8e0f981a046882db299a7a6d6d1c01bc19571) -(cherry picked from commit bdbc81e62eb8d7b8dfb298c7ba983cf86353fe66) -(cherry picked from commit 413414c98313a076111d8e40a7a10fa369433e6e) ---- - ldap/servers/slapd/valueset.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index 9d77b0c..fb7a99b 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -1444,8 +1444,9 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a, - if(v) - { - value_update_csn(v,t,csn); -- if (csnref_updated) -- valuestoupdate[i]->v_csnset = (CSNSet *)value_get_csnset(v); -+ if (csnref_updated) { -+ valuestoupdate[i]->v_csnset = csnset_dup(value_get_csnset(v)); -+ } - valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]); - valuestoupdate[i]= NULL; - del_count++; --- -1.9.3 - diff --git a/SOURCES/0087-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch b/SOURCES/0087-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch deleted file mode 100644 index c6cc32e..0000000 --- a/SOURCES/0087-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 92af3c54655cdac45271d2111a53ba6bd6400052 Mon Sep 17 00:00:00 2001 -From: Noriko Hosoi -Date: Tue, 15 Sep 2015 18:25:02 -0700 -Subject: [PATCH] Ticket #48226 - In MMR, double free coould occur under some - special condition - -Description: commit a0f8e0f981a046882db299a7a6d6d1c01bc19571 introduced -a memory leak in the case of resolve_attribute_state_present_to_deleted. -In the case, csnset is not consumed. Thus, it has to be freed by csnset_ -free. - -https://fedorahosted.org/389/ticket/48226 - -Reviewed by mreynolds@redhat.com (Thank you, Mark!!) - -(cherry picked from commit b26ec6762fe2b5d37ade59243086cfd2308e8f0a) -(cherry picked from commit 4a3efc3330a034fa485f33e453054758561d4cea) -(cherry picked from commit 14e08bde4a48a8e8b56edc817b5d1e3d56b96c72) ---- - ldap/servers/slapd/entrywsi.c | 22 +++++++++++----------- - ldap/servers/slapd/valueset.c | 1 + - 2 files changed, 12 insertions(+), 11 deletions(-) - -diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c -index 41afe1a..6773b9f 100644 ---- a/ldap/servers/slapd/entrywsi.c -+++ b/ldap/servers/slapd/entrywsi.c -@@ -1305,23 +1305,23 @@ resolve_attribute_state_present_to_deleted(Slapi_Entry *e, Slapi_Attr *a, Slapi_ - const CSN *adcsn= attr_get_deletion_csn(a); - int i; - if ( valuestoupdate != NULL && valuestoupdate[0] != NULL ) { -- for (i=0;valuestoupdate[i]!=NULL;++i) { -- /* This call ensures that the value does not contain a deletion_csn -- * which is before the presence_csn or distinguished_csn of the value. -- */ -- purge_attribute_state_multi_valued(a, valuestoupdate[i]); -- vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED); -- vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED); -- deletedcsn= csn_max(vdcsn, adcsn); -+ for (i=0;valuestoupdate[i]!=NULL;++i) { -+ /* This call ensures that the value does not contain a deletion_csn -+ * which is before the presence_csn or distinguished_csn of the value. -+ */ -+ purge_attribute_state_multi_valued(a, valuestoupdate[i]); -+ vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED); -+ vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED); -+ deletedcsn= csn_max(vdcsn, adcsn); - if(csn_compare(vucsn,deletedcsn)<0) - { -- if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn)) -+ if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn)) - { - entry_present_value_to_deleted_value(a,valuestoupdate[i]); - } - } -- valuestoupdate[i]->v_csnset = NULL; -- } -+ csnset_free(&valuestoupdate[i]->v_csnset); -+ } - } - } - -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index fb7a99b..7b5fa01 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -1445,6 +1445,7 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a, - { - value_update_csn(v,t,csn); - if (csnref_updated) { -+ csnset_free(&valuestoupdate[i]->v_csnset); - valuestoupdate[i]->v_csnset = csnset_dup(value_get_csnset(v)); - } - valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]); --- -1.9.3 - diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index 76f89d2..1aa513f 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -11,6 +11,15 @@ %global use_db4 0 # If perl-Socket-2.000 or newer is available, set 0 to use_Socket6. %global use_Socket6 0 +# nunc-stans only builds on x86_64 for now +%ifarch x86_64 +# To build without nunc-stans, set 0 to use_nunc_stans. +%global use_nunc_stans 1 +%else +%global use_nunc_stans 0 +%endif + +%global nunc_stans_ver 0.1.5 # fedora 15 and later uses tmpfiles.d # otherwise, comment this out @@ -24,8 +33,8 @@ Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 1.3.3.1 -Release: %{?relprefix}23%{?prerel}%{?dist} +Version: 1.3.4.0 +Release: %{?relprefix}19%{?prerel}%{?dist} License: GPLv2 with exceptions URL: http://port389.org/ Group: System Environment/Daemons @@ -105,8 +114,7 @@ Requires(postun): systemd-units # for setup-ds.pl to support ipv6 %if %{use_Socket6} Requires: perl-Socket6 -%else -Requires: perl-Socket +%else Requires: perl-Socket %endif Requires: perl-NetAddr-IP @@ -114,94 +122,75 @@ Source0: http://port389.org/sources/%{name}-%{version}%{?prerel}.tar.bz # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README -Patch0: 0000-Ticket-47748-Simultaneous-adding-a-user-and-binding-.patch -Patch1: 0001-Ticket-47834-Tombstone_to_glue-if-parents-are-also-c.patch -Patch2: 0002-Ticket-47890-minor-memory-leaks-in-utilities.patch -Patch3: 0003-fix-for-47885-did-not-always-return-a-response-contr.patch -Patch4: 0004-Ticket-47838-harden-the-list-of-ciphers-available-by.patch -Patch5: 0005-Ticket-47838-47895-CI-test-add-test-cases-for-ticket.patch -Patch6: 0006-Ticket-47895-If-no-effective-ciphers-are-available-d.patch -Patch7: 0007-Ticket-47889-DS-crashed-during-ipa-server-install-on.patch -Patch8: 0008-Ticket-47892-coverity-defects-found-in-1.3.3.1.patch -Patch9: 0009-Ticket-47750-Creating-a-glue-fails-if-one-above-leve.patch -Patch10: 0010-Ticket-47908-389-ds-1.3.3.0-does-not-adjust-cipher-s.patch -Patch11: 0011-Ticket-47838-harden-the-list-of-ciphers-available-by.patch -Patch12: 0012-Ticket-47838-CI-test-adjusted-test-cases-based-on-th.patch -Patch13: 0013-Ticket-47880-provide-enabled-ciphers-as-search-resul.patch -Patch14: 0014-Ticket-47880-CI-test-added-test-cases-for-ticket-478.patch -Patch15: 0015-Ticket-47892-coverity-defects-found-in-1.3.3.x.patch -Patch16: 0016-Ticket-47918-result-of-dna_dn_is_shared_config-is-in.patch -Patch17: 0017-Ticket-47892-Fix-remaining-compiler-warnings.patch -Patch18: 0018-Ticket-47919-ldbm_back_modify-SLAPI_PLUGIN_BE_PRE_MO.patch -Patch19: 0019-Ticket-47920-Encoding-of-SearchResultEntry-is-missin.patch -Patch20: 0020-Ticket-47897-Need-to-move-slapi_pblock_set-pb-SLAPI_.patch -Patch21: 0021-Ticket-47922-dynamically-added-macro-aci-is-not-eval.patch -Patch22: 0022-Ticket-47928-Disable-SSL-v3-by-default.patch -Patch23: 0023-Ticket-47928-CI-test-added-test-cases-for-ticket-479.patch -Patch24: 0024-Ticket-47937-Crash-in-entry_add_present_values_wsi_m.patch -Patch25: 0025-Ticket-47928-Disable-SSL-v3-by-default.patch -Patch26: 0026-Ticket-47939-Malformed-cookie-for-LDAP-Sync-makes-DS.patch -Patch27: 0027-Ticket-47945-Add-SSL-TLS-version-info-to-the-access-.patch -Patch28: 0028-Ticket-47948-ldap_sasl_bind-fails-assertion-ld-NULL-.patch -Patch29: 0029-Ticket-47953-Should-not-check-aci-syntax-when-deleti.patch -Patch30: 0030-Ticket-47928-Disable-SSL-v3-by-default.patch -Patch31: 0031-Fix-for-CVE-2014-8112.patch -Patch32: 0032-Ticket-47942-DS-hangs-during-online-total-update.patch -Patch33: 0033-Fix-for-CVE-2014-8105.patch -Patch34: 0034-Additional-fix-for-ticket-47526-v3.patch -Patch35: 0035-fix-jenkins-warning.patch -Patch36: 0036-Ticket-47950-Bind-DN-tracking-unable-to-write-to-int.patch -Patch37: 0037-Ticket-47949-logconv.pl-support-parsing-showing-repo.patch -Patch38: 0038-Ticket-47947-start-dirsrv-after-chrony-on-RHEL7-and-.patch -Patch39: 0039-Ticket-47967-cos_cache_build_definition_list-does-no.patch -Patch40: 0040-Ticket-47969-COS-memory-leak-when-rebuilding-the-cac.patch -Patch41: 0041-Ticket-47969-Fix-coverity-issue.patch -Patch42: 0042-Ticket-47970-Account-lockout-attributes-incorrectly-.patch -Patch43: 0043-Ticket-47970-add-lib389-testcase.patch -Patch44: 0044-Ticket-47960-cookie_change_info-returns-random-negat.patch -Patch45: 0045-Ticket-47960-cookie_change_info-returns-random-negat.patch -Patch46: 0046-Ticket-47636-Error-log-levels-not-displayed-correctl.patch -Patch47: 0047-Ticket-47722-Using-the-filter-file-does-not-work.patch -Patch48: 0048-Ticket-47451-Need-to-unregister-tasks-created-by-plu.patch -Patch49: 0049-Ticket-47451-Running-a-plugin-task-can-crash-the-ser.patch -Patch50: 0050-Ticket-47451-Dynamic-Plugin-various-fixes.patch -Patch51: 0051-Ticket-47451-Fix-jenkins-errors.patch -Patch52: 0052-Ticket-47451-Add-Dynamic-Plugin-CI-Suite.patch -Patch53: 0053-Ticket-47525-Crash-if-setting-invalid-plugin-config-.patch -Patch54: 0054-Ticket-47965-Fix-coverity-issues-2014-11-24.patch -Patch55: 0055-Ticket-47965-Fix-coverity-issues-2014-12-16.patch -Patch56: 0056-Ticket-47750-During-delete-operation-do-not-refresh-.patch -Patch57: 0057-Ticket-47989-Windows-Sync-accidentally-cleared-raw_e.patch -Patch58: 0058-Ticket-47991-upgrade-script-fails-if-etc-and-var-are.patch -Patch59: 0059-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch -Patch60: 0060-Ticket-47988-Schema-learning-mechanism-in-replicatio.patch -Patch61: 0061-Ticket-48005-ns-slapd-crash-in-shutdown-phase.patch -Patch62: 0062-CVE-2015-1854-389ds-base-access-control-bypass-with-.patch -Patch63: 0063-Ticket-48190-idm-ipa-389-ds-base-entry-cache-converg.patch -Patch64: 0064-Ticket-48146-async-simple-paged-results-issue.patch -Patch65: 0065-Ticket-48146-async-simple-paged-results-issue-log-pr.patch -Patch66: 0066-Ticket-48146-async-simple-paged-results-issue-need-t.patch -Patch67: 0067-Ticket-48146-async-simple-paged-results-issue.patch -Patch68: 0068-Ticket-48146-async-simple-paged-results-issue.patch -Patch69: 0069-Ticket-48146-async-simple-paged-results-issue.patch -Patch70: 0070-Ticket-48192-Individual-abandoned-simple-paged-resul.patch -Patch71: 0071-Ticket-48192-Individual-abandoned-simple-paged-resul.patch -Patch72: 0072-Ticket-48192-Individual-abandoned-simple-paged-resul.patch -Patch73: 0073-Ticket-48194-nsSSL3Ciphers-preference-not-enforced-s.patch -Patch74: 0074-Ticket-48192-Individual-abandoned-simple-paged-resul.patch -Patch75: 0075-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch -Patch76: 0076-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch -Patch77: 0077-Ticket-47553-Enhance-ACIs-to-have-more-control-over-.patch -Patch78: 0078-Ticket-48265-Complex-filter-in-a-search-request-doen.patch -Patch79: 0079-Ticket-47912-Proper-handling-of-No-original_tombston.patch -Patch80: 0080-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch -Patch81: 0081-Ticket-47931-memberOf-retrocl-deadlocks.patch -Patch82: 0082-Ticket-47931-Fix-coverity-issues.patch -Patch83: 0083-Ticket-47831-remove-debug-logging-from-retro-cl.patch -Patch84: 0084-Ticket-47831-remove-debug-logging-from-retro-cl.patch -Patch85: 0085-Ticket-48195-Slow-replication-when-deleting-large-qu.patch -Patch86: 0086-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch -Patch87: 0087-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch +Source3: https://git.fedorahosted.org/cgit/nunc-stans.git/snapshot/nunc-stans-%{nunc_stans_ver}.tar.bz2 +Patch0: 0001-Ticket-48203-Fix-coverity-issues-06-22-2015.patch +Patch1: 0002-Ticket-48195-Slow-replication-when-deleting-large-qu.patch +Patch2: 0003-Ticket-48212-Dynamic-nsMatchingRule-changes-had-no-e.patch +Patch3: 0004-Ticket-48212-CI-test-added-test-cases-for-ticket-482.patch +Patch4: 0005-Ticket-48214-ldapsearch-on-nsslapd-maxbersize-return.patch +Patch5: 0006-Ticket-48214-CI-test-added-test-cases-for-ticket-482.patch +Patch6: 0007-Ticket-48192-Individual-abandoned-simple-paged-resul.patch +Patch7: 0008-Ticket-48119-setup-ds.pl-does-not-log-invalid-file-p.patch +Patch8: 0009-Ticket-48203-Fix-coverity-issues-07-07-2015.patch +Patch9: 0010-Ticket-48208-CleanAllRUV-should-completely-purge-cha.patch +Patch10: 0011-Ticket-47799-Any-negative-LDAP-error-code-number-rep.patch +Patch11: 0012-Ticket-48013-Inconsistent-behaviour-of-DS-when-LDAP-.patch +Patch12: 0013-Ticket-48217-cleanAllRUV-hangs-shutdown-if-not-all-o.patch +Patch13: 0014-Ticket-48216-crash-in-ns-slapd-when-deleting-winSync.patch +Patch14: 0015-Ticket-48119-Silent-install-needs-to-properly-exit-w.patch +Patch15: 0016-Ticket-47878-Remove-warning-suppression-in-1.3.4.patch +Patch16: 0017-Ticket-48223-Winsync-fails-when-AD-users-have-multip.patch +Patch17: 0018-Ticket-47910-logconv.pl-validate-start-and-end-time-.patch +Patch18: 0019-Ticket-48224-logconv.pl-should-handle-.tar.xz-.txz-..patch +Patch19: 0020-Ticket-48194-CI-test-fixing-test-cases-for-ticket-48.patch +Patch20: 0021-Ticket-48203-Fix-coverity-issues-07-14-2015.patch +Patch21: 0022-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch +Patch22: 0023-Ticket-48224-redux-logconv.pl-should-handle-.tar.xz-.patch +Patch23: 0024-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch +Patch24: 0025-Ticket-48226-CI-test-added-test-cases-for-ticket-482.patch +Patch25: 0026-Ticket-48179-Starting-a-replica-agreement-can-lead-t.patch +Patch26: 0027-Ticket-47910-logconv.pl-check-that-the-end-time-is-g.patch +Patch27: 0028-Ticket-48224-redux-2-logconv.pl-should-handle-.tar.x.patch +Patch28: 0029-Ticket-48206-Crash-during-retro-changelog-trimming.patch +Patch29: 0030-Ticket-48010-winsync-range-retrieval-gets-only-5000-.patch +Patch30: 0031-Ticket-48232-winsync-lastlogon-attribute-not-syncing.patch +Patch31: 0032-Ticket-48231-logconv-autobind-handling-regression-ca.patch +Patch32: 0033-Ticket-47810-memberOf-plugin-not-properly-rejecting-.patch +Patch33: 0034-Ticket-48215-verify_db.pl-doesn-t-verify-DB-specifie.patch +Patch34: 0035-Ticket-48215-update-dbverify-usage.patch +Patch35: 0036-Ticket-48215-update-dbverify-usage-in-main.c.patch +Patch36: 0037-Ticket-48228-wrong-password-check-if-passwordInHisto.patch +Patch37: 0038-Ticket-48228-CI-test-added-test-cases-for-ticket-482.patch +Patch38: 0039-Ticket-47931-memberOf-retrocl-deadlocks.patch +Patch39: 0040-Ticket-47931-Fix-coverity-issues.patch +Patch40: 0041-Ticket-47686-removing-chaining-database-links-trigge.patch +Patch41: 0042-Ticket-47511-bashisms-in-389-ds-base-admin-scripts.patch +Patch42: 0043-Ticket-48245-Man-pages-and-help-for-remove-ds.pl-doe.patch +Patch43: 0044-Ticket-48249-sync_repl-uuid-may-be-invalid.patch +Patch44: 0045-Ticket-48250-Slapd-crashes-reported-from-latest-buil.patch +Patch45: 0046-Ticket-48233-Server-crashes-in-ACL_LasFindFlush-duri.patch +Patch46: 0047-Ticket-48243-replica-upgrade-failed-in-starting-dirs.patch +Patch47: 0048-Ticket-47831-remove-debug-logging-from-retro-cl.patch +Patch48: 0049-Ticket-48254-CLI-db2index-fails-with-usage-errors.patch +Patch49: 0050-Ticket-48254-Shell-CLI-fails-with-usage-errors-if-an.patch +Patch50: 0051-Ticket-47757-Unable-to-dereference-unqiemember-attri.patch +Patch51: 0052-Ticket-48228-wrong-password-check-if-passwordInHisto.patch +Patch52: 0053-Ticket-48265-Complex-filter-in-a-search-request-doen.patch +Patch53: 0054-Ticket-47981-COS-cache-doesn-t-properly-mark-vattr-c.patch +Patch54: 0055-Ticket-48276-initialize-free_flags-in-reslimit_updat.patch +Patch55: 0056-Ticket-48226-In-MMR-double-free-coould-occur-under-s.patch +Patch56: 0057-Ticket-48266-Fractional-replication-evaluates-severa.patch +Patch57: 0058-Ticket-48266-coverity-issue.patch +Patch58: 0059-Ticket-48217-cleanallruv-fix-regression-with-server-.patch +Patch59: 0060-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch +Patch60: 0061-Ticket-48188-segfault-in-ns-slapd-due-to-accessing-S.patch +Patch61: 0062-Ticket-48266-coverity-unused-variable-init_retry.patch +Patch62: 0063-Ticket-48266-Online-init-crashes-consumer.patch +Patch63: 0064-Ticket-48284-free-entry-when-internal-add-fails.patch +Patch64: 0065-Ticket-48266-do-not-free-repl-keep-alive-entry-on-er.patch +Patch65: 0066-Ticket-48299-pagedresults-when-timed-out-search-resu.patch +Patch66: 0067-Ticket-48192-Individual-abandoned-simple-paged-resul.patch +Patch67: 0068-Ticket-48298-ns-slapd-crash-during-ipa-replica-manag.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -226,6 +215,11 @@ BuildRequires: libdb-devel BuildRequires: cyrus-sasl-devel BuildRequires: libicu-devel BuildRequires: pcre-devel +%if %{use_nunc_stans} +BuildRequires: libtalloc-devel +BuildRequires: libevent-devel +BuildRequires: libtevent-devel +%endif %description libs Core libraries for the 389 Directory Server base package. These libraries @@ -245,12 +239,20 @@ Requires: openldap-devel %else Requires: mozldap-devel %endif +%if %{use_nunc_stans} +Requires: libtalloc +Requires: libevent +Requires: libtevent +%endif %description devel Development Libraries and headers for the 389 Directory Server base package. %prep %setup -q -n %{name}-%{version}%{?prerel} +%if %{use_nunc_stans} +%setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3 +%endif cp %{SOURCE2} README.devel %patch0 -p1 %patch1 -p1 @@ -320,38 +322,32 @@ cp %{SOURCE2} README.devel %patch65 -p1 %patch66 -p1 %patch67 -p1 -%patch68 -p1 -%patch69 -p1 -%patch70 -p1 -%patch71 -p1 -%patch72 -p1 -%patch73 -p1 -%patch74 -p1 -%patch75 -p1 -%patch76 -p1 -%patch77 -p1 -%patch78 -p1 -%patch79 -p1 -%patch80 -p1 -%patch81 -p1 -%patch82 -p1 -%patch83 -p1 -%patch84 -p1 -%patch85 -p1 -%patch86 -p1 -%patch87 -p1 %build +%if %{use_nunc_stans} +pushd ../nunc-stans-%{nunc_stans_ver} +%configure --with-fhs --libdir=%{_libdir}/%{pkgname} +make %{?_smp_mflags} +mkdir lib +cp .libs/libnunc-stans.so.0.0.0 lib/libnunc-stans.so +mkdir -p include/nunc-stans +cp nunc-stans.h include/nunc-stans/nunc-stans.h +popd +%endif + %if %{use_openldap} OPENLDAP_FLAG="--with-openldap" %endif %{?with_tmpfiles_d: TMPFILES_FLAG="--with-tmpfiles-d=%{with_tmpfiles_d}"} # hack hack hack https://bugzilla.redhat.com/show_bug.cgi?id=833529 NSSARGS="--with-svrcore-inc=%{_includedir} --with-svrcore-lib=%{_libdir} --with-nss-lib=%{_libdir} --with-nss-inc=%{_includedir}/nss3" +%if %{use_nunc_stans} +NUNC_STANS_FLAGS="--enable-nunc-stans --with-nunc-stans=../nunc-stans-%{nunc_stans_ver}" +%endif %configure --enable-autobind --with-selinux $OPENLDAP_FLAG $TMPFILES_FLAG \ --with-systemdsystemunitdir=%{_unitdir} \ --with-systemdsystemconfdir=%{_sysconfdir}/systemd/system \ - --with-systemdgroupname=%{groupname} $NSSARGS + --with-systemdgroupname=%{groupname} $NSSARGS $NUNC_STANS_FLAGS # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS @@ -366,6 +362,14 @@ make %{?_smp_mflags} %install rm -rf $RPM_BUILD_ROOT +%if %{use_nunc_stans} +pushd ../nunc-stans-%{nunc_stans_ver} +make DESTDIR="$RPM_BUILD_ROOT" install +rm -rf $RPM_BUILD_ROOT%{_includedir} $RPM_BUILD_ROOT%{_datadir} \ + $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/pkgconfig +popd +%endif + make DESTDIR="$RPM_BUILD_ROOT" install mkdir -p $RPM_BUILD_ROOT/var/log/%{pkgname} @@ -389,6 +393,7 @@ rm -rf $RPM_BUILD_ROOT %post output=/dev/null +output2=/dev/null %systemd_post %{pkgname}-snmp.service # reload to pick up any changes to systemd files /bin/systemctl daemon-reload >$output 2>&1 || : @@ -401,12 +406,17 @@ instances="" # instances that require a restart after upgrade ninst=0 # number of instances found in total if [ -n "$DEBUGPOSTTRANS" ] ; then output=$DEBUGPOSTTRANS + output2=${DEBUGPOSTTRANS}.upgrade fi -echo looking for services in %{_sysconfdir}/systemd/system/%{groupname}.wants/* >> $output 2>&1 || : -for service in %{_sysconfdir}/systemd/system/%{groupname}.wants/* ; do - if [ ! -f "$service" ] ; then continue ; fi # in case nothing matches - inst=`echo $service | sed -e 's,%{_sysconfdir}/systemd/system/%{groupname}.wants/,,'` - echo found instance $inst - getting status >> $output 2>&1 || : +echo looking for instances in %{_sysconfdir}/%{pkgname} > $output 2>&1 || : +instbase="%{_sysconfdir}/%{pkgname}" +for dir in $instbase/slapd-* ; do + echo dir = $dir >> $output 2>&1 || : + if [ ! -d "$dir" ] ; then continue ; fi + case "$dir" in *.removed) continue ;; esac + basename=`basename $dir` + inst="%{pkgname}@`echo $basename | sed -e 's/slapd-//g'`" + echo found instance $inst - getting status >> $output 2>&1 || : if /bin/systemctl -q is-active $inst ; then echo instance $inst is running >> $output 2>&1 || : instances="$instances $inst" @@ -431,9 +441,9 @@ echo remove pid files . . . >> $output 2>&1 || : echo upgrading instances . . . >> $output 2>&1 || : DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"` if [ -n "$DEBUGPOSTSETUPOPT" ] ; then - %{_sbindir}/setup-ds.pl -l $output -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : + %{_sbindir}/setup-ds.pl -l $output2 -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : else - %{_sbindir}/setup-ds.pl -l $output -u -s General.UpdateMode=offline >> $output 2>&1 || : + %{_sbindir}/setup-ds.pl -l $output2 -u -s General.UpdateMode=offline >> $output 2>&1 || : fi # restart instances that require it @@ -459,7 +469,7 @@ fi %files %defattr(-,root,root,-) -%doc LICENSE EXCEPTION LICENSE.GPLv2 +%doc LICENSE LICENSE.GPLv3+ LICENSE.openssl %dir %{_sysconfdir}/%{pkgname} %dir %{_sysconfdir}/%{pkgname}/schema %config(noreplace)%{_sysconfdir}/%{pkgname}/schema/*.ldif @@ -487,51 +497,170 @@ fi %files devel %defattr(-,root,root,-) -%doc LICENSE EXCEPTION LICENSE.GPLv2 README.devel +%doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel %{_includedir}/%{pkgname} %{_libdir}/%{pkgname}/libslapd.so +%if %{use_nunc_stans} +%{_libdir}/%{pkgname}/libnunc-stans.so +%endif %{_libdir}/pkgconfig/* %files libs %defattr(-,root,root,-) -%doc LICENSE EXCEPTION LICENSE.GPLv2 README.devel +%doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel %dir %{_libdir}/%{pkgname} %{_libdir}/%{pkgname}/libslapd.so.* %{_libdir}/%{pkgname}/libns-dshttpd.so* +%if %{use_nunc_stans} +%{_libdir}/%{pkgname}/libnunc-stans.so* +%endif %changelog -* Thu Sep 24 2015 Noriko Hosoi - 1.3.3.1-23 -- release 1.3.3.1-23 -- Resolves: bug 1262363 - In MMR, double free coould occur under some special condition (DS 48226) - -* Fri Sep 11 2015 Noriko Hosoi - 1.3.3.1-22 -- release 1.3.3.1-22 -- Resolves: bug 1262363 - In MMR, double free coould occur under some special condition (DS 48226) - -* Tue Sep 8 2015 Noriko Hosoi - 1.3.3.1-21 -- release 1.3.3.1-21 -- Resolves: bug 1258318 - Deadlock with retrochangelog, memberof plugin (DS 47931) -- Resolves: bug 1259466 - Enhance ACIs to have more control over MODRDN operations (DS 47553) -- Resolves: bug 1259999 - Some filters in RHDS10 are not working fine. (DS 48265) -- Resolves: bug 1260000 - handling of "No original_tombstone for changenumber" errors (DS 47912) -- Resolves: bug 1260001 - cleanallruv should completely clean changelog (DS 48208) - -* Thu Jul 16 2015 Noriko Hosoi - 1.3.3.1-20 -- release 1.3.3.1-20 -- Resolves: bug 1243718 - Winsync fails when AD users have multiple spaces (two)inside the value of the rdn attribute (DS 48223) - -* Mon Jul 6 2015 Noriko Hosoi - 1.3.3.1-19 +* Mon Oct 5 2015 Noriko Hosoi - 1.3.4.0-19 +- release 1.3.4.0-19 +- Resolves: bug 1228823 - async simple paged results issue (DS 48299, DS 48192) +- Resolves: bug 1266944 - ns-slapd crash during ipa-replica-manage del (DS 48298) + +* Tue Sep 22 2015 Noriko Hosoi - 1.3.4.0-18 +- release 1.3.4.0-18 +- Resolves: bug 1259949 - Fractional replication evaluates several times the same CSN (DS 48266, DS 48284) + +* Fri Sep 18 2015 Noriko Hosoi - 1.3.4.0-17 +- release 1.3.4.0-17 +- Resolves: bug 1259949 - A backport error (coverity -- unused variable 'init_retry') + +* Fri Sep 18 2015 Noriko Hosoi - 1.3.4.0-16 +- release 1.3.4.0-16 +- Resolves: bug 1243970 - In MMR, double free coould occur under some special condition (DS 48276, DS 48226) +- Resolves: bug 1259949 - Fractional replication evaluates several times the same CSN (DS 48266) +- Resolves: bug 1241723 - cleanallruv - fix regression with server shutdown (DS 48217) +- Resolves: bug 1264224 - segfault in ns-slapd due to accessing Slapi_DN freed in pre bind plug-in (DS 48188) + +* Fri Sep 4 2015 Noriko Hosoi - 1.3.4.0-15 +- release 1.3.4.0-15 +- Resolves: bug 1258996 - Complex filter in a search request doen't work as expected. (regression) (DS 48265) +- Resolves: bug 1179370 - COS cache doesn't properly mark vattr cache as invalid when there are multiple suffixes (DS 47981) + +* Tue Aug 25 2015 Noriko Hosoi - 1.3.4.0-14 +- release 1.3.4.0-14 +- Resolves: bug 1246389 - wrong password check if passwordInHistory is decreased. (DS 48228) +- Resolves: bug 1255851 - Shell CLI fails with usage errors if an argument containing white spaces is given (DS 48254) +- Resolves: bug 1256938 - Unable to dereference unqiemember attribute because it is dn [#UID] not dn syntax (DS 47757) + +* Wed Aug 19 2015 Noriko Hosoi - 1.3.4.0-13 +- release 1.3.4.0-13 +- Resolves: bug 1245519 - remove debug logging from retro cl (DS 47831) + +* Tue Aug 18 2015 Noriko Hosoi - 1.3.4.0-12 +- release 1.3.4.0-12 +- Resolves: bug 1252133 - replica upgrade failed in starting dirsrv service (DS 48243) +- Resolves: bug 1254344 - Server crashes in ACL_LasFindFlush during shutdown if ACIs contain IP addresss restrictions (DS 48233) + +* Fri Aug 14 2015 Noriko Hosoi - 1.3.4.0-11 +- release 1.3.4.0-11 +- Resolves: bug 1249784 - ipa-dnskeysyncd unhandled exception on named-pkcs11 start (DS 48249) +- Resolves: bug 1252082 - removing chaining database links trigger valgrind read error (DS 47686) +- Resolves: bug 1252207 - bashisms in 389-ds-base admin scripts (DS 47511) +- Resolves: bug 1252533 - Man pages and help for remove-ds.pl doesn't display "-a" option (DS 48245) +- Resolves: bug 1252781 - Slapd crashes reported from latest builds (DS 48250) + +* Mon Aug 10 2015 Noriko Hosoi - 1.3.4.0-10 +- release 1.3.4.0-10 +- Resolves: bug 1245519 - Fix coverity issues (DS 47931) + +* Fri Aug 7 2015 Noriko Hosoi - 1.3.4.0-9 +- release 1.3.4.0-9 +- Resolves: bug 1240876 - verify_db.pl doesn't verify DB specified by -a option. (DS 48215) +- Resolves: bug 1245235 - winsync lastlogon attribute not syncing between IPA & Windows 2008. (DS 48232) +- Resolves: bug 1245519 - Deadlock with retrochangelog, memberof plugin (DS 47931) +- Resolves: bug 1246389 - wrong password check if passwordInHistory is decreased. (DS 48228) +- Resolves: bug 1247811 - logconv autobind handling regression caused by 47446 (DS 48231) +- Resolves: bug 1250177 - Investigate betxn plugins to ensure they return the correct error code (DS 47810) + +* Thu Jul 23 2015 Noriko Hosoi - 1.3.4.0-8 +- release 1.3.4.0-8 +- Resolves: bug 1160243 - [RFE] allow logconv.pl -S/-E switches to work even when exact/same timestamps are not present in access log file (DS 47910) +- Resolves: bug 1172037 - winsync range retrieval gets only 5000 values upon initialization (DS 48010) +- Resolves: bug 1242531 - logconv.pl should handle *.tar.xz, *.txz, *.xz log files (DS 48224) +- Resolves: bug 1243950 - When starting a replica agreement a deadlock can occur with an op updating nsuniqueid index (DS 48179) +- Resolves: bug 1243970 - In MMR, double free coould occur under some special condition (DS 48226) +- Resolves: bug 1244926 - Crash while triming the retro changelog (DS 48206) + +* Thu Jul 16 2015 Noriko Hosoi - 1.3.4.0-7 +- release 1.3.4.0-7 +- Resolves: bug 1235060 - Fix coverity issues - 07/14/2015 (DS 48203) +- Resolves: bug 1242531 - redux - logconv.pl should handle *.tar.xz, *.txz, *.xz log files (DS 48224) + +* Tue Jul 14 2015 Noriko Hosoi - 1.3.4.0-6 +- release 1.3.4.0-6 +- Resolves: bug 1240845 - cleanallruv should completely clean changelog (DS 48208) +- Resolves: bug 1095603 - Any negative LDAP error code number reported as Illegal error by ldclt. (DS 47799) +- Resolves: bug 1168675 - Inconsistent behaviour of DS when LDAP Sync is used with an invalid cookie (DS 48013) +- Resolves: bug 1241723 - cleanAllRUV hangs shutdown if not all of the replicas are online (DS 48217) +- Resolves: bug 1241497 - crash in ns-slapd when deleting winSyncSubtreePair from sync agreement (DS 48216) +- Resolves: bug 1240404 - Silent install needs to properly exit when INF file is missing (DS 48119) +- Resolves: bug 1240406 - Remove warning suppression in 1.3.4 (DS 47878) +- Resolves: bug 1242683 - Winsync fails when AD users have multiple spaces (two)inside the value of the rdn attribute (DS 48223) +- Resolves: bug 1160243 - logconv.pl - validate start and end time args (DS 47910) +- Resolves: bug 1242531 - logconv.pl should handle *.tar.xz, *.txz, *.xz log files (DS 48224) +- Resolves: bug 1230996 - CI test: fixing test cases for ticket 48194 (DS 48194) + +* Tue Jul 7 2015 Noriko Hosoi - 1.3.4.0-5 +- release 1.3.4.0-5 +- Resolves: bug 1235060 - Fix coverity issues (DS 48203) + +* Tue Jul 7 2015 Noriko Hosoi - 1.3.4.0-4 +- release 1.3.4.0-4 +- Resolves: bug 1240404 - setup-ds.pl does not log invalid --file path errors the same (DS 48119) +- Resolves: bug 1240406 - setup -u stops after first failure (DS 47878) + +* Mon Jul 6 2015 Noriko Hosoi - 1.3.4.0-3 +- release 1.3.4.0-3 +- Resolves: bug 1228823 - async simple paged results issue (DS 48192) +- Resolves: bug 1237325 - reindex off-line twice could provoke index corruption (DS 48212) +- Resolves: bug 1238790 - ldapsearch on nsslapd-maxbersize returns 0 instead of current value (DS 48214) + +* Wed Jun 24 2015 Noriko Hosoi - 1.3.4.0-2 +- release 1.3.4.0-2 +- Resolves: bug 1235060 - Fix coverity issues +- Resolves: bug 1235387 - Slow replication when deleting large quantities of multi-valued attributes (DS 48195) + +* Fri Jun 19 2015 Noriko Hosoi - 1.3.4.0-1 +- Release 1.3.4.0-1 (rebase) +- Enable nunc-stans for x86_64. +- Resolves: bug 1034325 - Linked attributes betxnpreoperation - transaction not aborted when linked entry does not exit (DS 47640) +- Resolves: bug 1052755 - Retro Changelog Plugin accepts invalid value in nsslapd-changelogmaxage attribute (DS 47669) +- Resolves: bug 1096409 - RHDS keeps on logging write_changelog_and_ruv: failed to update RUV for unknown (DS 47801) +- Resolves: bug 1145378 - Adding an entry with an invalid password as rootDN is incorrectly rejected (DS 47900) +- Resolves: bug 1145382 - Bad manipulation of passwordhistory (DS 47905) +- Resolves: bug 1154147 - Uniqueness plugin: should allow to exclude some subtrees from its scope (DS 47927) +- Resolves: bug 1171358 - Make ReplicaWaitForAsyncResults configurable (DS 47957) +- Resolves: bug 1171663 - MODDN fails when entry doesn't have memberOf attribute and new DN is in the scope of memberOfExcludeSubtree (DS 47526) +- Resolves: bug 1174457 - [RFE] memberOf - add option to skip nested group lookups during delete operations (DS 47963) +- Resolves: bug 1178640 - db2bak.pl man page should be improved. (DS 48008) +- Resolves: bug 1179370 - COS cache doesn't properly mark vattr cache as invalid when there are multiple suffixes (DS 47981) +- Resolves: bug 1180331 - Local Password Policies for Nested OU's not honoured (DS 47980) +- Resolves: bug 1180776 - nsslapd-db-locks modify not taking into account (DS 47934) +- Resolves: bug 1181341 - nsslapd-changelogtrim-interval and nsslapd-changelogcompactdb-interval are not validated (DS 47617) +- Resolves: bug 1185882 - ns-activate.pl fails to activate account if it was disabled on AD (DS 48001) +- Resolves: bug 1186548 - ns-slapd crash in shutdown phase (DS 48005) +- Resolves: bug 1189154 - DNS errors after IPA upgrade due to broken ReplSync (DS 48030) +- Resolves: bug 1206309 - winsync sets AccountUserControl in AD to 544 (DS 47723) +- Resolves: bug 1210845 - slapd crashes during Dogtag clone reinstallation (DS 47966) +- Resolves: bug 1210850 - add an option '-u' to dbgen.pl for adding group entries with (DS 48025) +- Resolves: bug 1210852 - aci with wildcard and macro not correctly evaluated (DS 48141) + +* Fri Jun 12 2015 Noriko Hosoi - 1.3.3.1-19 - release 1.3.3.1-19 -- Resolves: bug 1230037 - async simple paged results issue (DS 48192) +- Resolves: bug 1230996 - nsSSL3Ciphers preference not enforced server side (DS 48194) -* Tue Jun 16 2015 Noriko Hosoi - 1.3.3.1-18 +* Fri Jun 5 2015 Noriko Hosoi - 1.3.3.1-18 - release 1.3.3.1-18 -- Resolves: bug 1232100 - CVE-2015-3230 389-ds-base: nsSSL3Ciphers preference not enforced server side (DS 48194) +- Resolves: bug 1228823 - async simple paged results issue (DS 48146, DS 48192) -* Wed Jun 10 2015 Noriko Hosoi - 1.3.3.1-17 +* Tue Jun 2 2015 Noriko Hosoi - 1.3.3.1-17 - release 1.3.3.1-17 -- Resolves: bug 1230038 - idm/ipa 389-ds-base entry cache converges to 500 KB in dblayer_is_cachesize_sane (DS 48190) -- Resolves: bug 1230037 - async simple paged results issue (DS 48146, DS 48192) +- Resolves: bug 1226510 - idm/ipa 389-ds-base entry cache converges to 500 KB in dblayer_is_cachesize_sane (DS 48190) * Tue Apr 21 2015 Noriko Hosoi - 1.3.3.1-16 - release 1.3.3.1-16