From 92192e30acb5e11452288cb75b85b06a7a63dc44 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 25 2018 17:32:53 +0000 Subject: import 389-ds-base-1.3.7.5-28.el7_5 --- diff --git a/SOURCES/0093-Ticket-49893-disable-nunc-stans-by-default.patch b/SOURCES/0093-Ticket-49893-disable-nunc-stans-by-default.patch new file mode 100644 index 0000000..cfc5ea5 --- /dev/null +++ b/SOURCES/0093-Ticket-49893-disable-nunc-stans-by-default.patch @@ -0,0 +1,32 @@ +From 911038990df1357f452b0e38309261faf1de898f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 8 Aug 2018 17:19:27 -0400 +Subject: [PATCH] Ticket 49893 - disable nunc-stans by default + +Description: Until nunc-stans is stablized we need to disable it + +https://pagure.io/389-ds-base/issue/49893 + +Reviewed by: ? + +(cherry picked from commit 2f2d3b1d7e7d847de1bb9ddf2f63e71dbc90f710) +--- + ldap/servers/slapd/libglobs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c +index 3bd5c1826..f8741028d 100644 +--- a/ldap/servers/slapd/libglobs.c ++++ b/ldap/servers/slapd/libglobs.c +@@ -1681,7 +1681,7 @@ FrontendConfig_init(void) + cfg->maxbersize = SLAPD_DEFAULT_MAXBERSIZE; + cfg->logging_backend = slapi_ch_strdup(SLAPD_INIT_LOGGING_BACKEND_INTERNAL); + cfg->rootdn = slapi_ch_strdup(SLAPD_DEFAULT_DIRECTORY_MANAGER); +- init_enable_nunc_stans = cfg->enable_nunc_stans = LDAP_ON; ++ init_enable_nunc_stans = cfg->enable_nunc_stans = LDAP_OFF; + #if defined(LINUX) + init_malloc_mxfast = cfg->malloc_mxfast = DEFAULT_MALLOC_UNSET; + init_malloc_trim_threshold = cfg->malloc_trim_threshold = DEFAULT_MALLOC_UNSET; +-- +2.17.1 + diff --git a/SOURCES/0094-Ticket-49890-ldapsearch-with-server-side-sort-crashe.patch b/SOURCES/0094-Ticket-49890-ldapsearch-with-server-side-sort-crashe.patch new file mode 100644 index 0000000..0af0b6f --- /dev/null +++ b/SOURCES/0094-Ticket-49890-ldapsearch-with-server-side-sort-crashe.patch @@ -0,0 +1,137 @@ +From 1013a1bfe0882d213f48e900ab89e00651188489 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 9 Aug 2018 15:27:59 -0400 +Subject: [PATCH] Ticket 49890 : ldapsearch with server side sort crashes the + ldap server + +Bug Description: + Server side sort with a specified matching rule trigger a crash + +Fix Description: + Check if the we are able to index the provided value. + If we are not then slapd_qsort returns an error (LDAP_OPERATION_ERROR) + +https://pagure.io/389-ds-base/issue/49890 + +Reviewed by: mreynolds + +Platforms tested: F27 + +Flag Day: no + +Doc impact: no + +(cherry picked from commit c989e18f7a3da060b16d39919b920b6b2a19a0ac) +--- + dirsrvtests/tests/suites/syntax/mr_test.py | 59 ++++++++++++++++++++++ + ldap/servers/slapd/back-ldbm/sort.c | 14 +++++ + 2 files changed, 73 insertions(+) + create mode 100644 dirsrvtests/tests/suites/syntax/mr_test.py + +diff --git a/dirsrvtests/tests/suites/syntax/mr_test.py b/dirsrvtests/tests/suites/syntax/mr_test.py +new file mode 100644 +index 000000000..57061222a +--- /dev/null ++++ b/dirsrvtests/tests/suites/syntax/mr_test.py +@@ -0,0 +1,59 @@ ++import logging ++import pytest ++import os ++import ldap ++from lib389.dbgen import dbgen ++from lib389._constants import * ++from lib389.topologies import topology_st as topo ++from lib389._controls import SSSRequestControl ++ ++DEBUGGING = os.getenv("DEBUGGING", default=False) ++if DEBUGGING: ++ logging.getLogger(__name__).setLevel(logging.DEBUG) ++else: ++ logging.getLogger(__name__).setLevel(logging.INFO) ++log = logging.getLogger(__name__) ++ ++ ++def test_sss_mr(topo): ++ """Test matching rule/server side sort does not crash DS ++ ++ :id: 48c73d76-1694-420f-ab55-187135f2d260 ++ :setup: Standalone Instance ++ :steps: ++ 1. Add sample entries to the database ++ 2. Perform search using server side control (uid:2.5.13.3) ++ :expectedresults: ++ 1. Success ++ 2. Success ++ """ ++ ++ log.info("Creating LDIF...") ++ ldif_dir = topo.standalone.get_ldif_dir() ++ ldif_file = os.path.join(ldif_dir, 'mr-crash.ldif') ++ dbgen(topo.standalone, 5, ldif_file, DEFAULT_SUFFIX) ++ ++ log.info("Importing LDIF...") ++ topo.standalone.stop() ++ assert topo.standalone.ldif2db(DEFAULT_BENAME, None, None, None, ldif_file) ++ topo.standalone.start() ++ ++ log.info('Search using server side sorting using undefined mr in the attr...') ++ sort_ctrl = SSSRequestControl(True, ['uid:2.5.13.3']) ++ controls = [sort_ctrl] ++ msg_id = topo.standalone.search_ext(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, ++ "objectclass=*", serverctrls=controls) ++ try: ++ rtype, rdata, rmsgid, response_ctrl = topo.standalone.result3(msg_id) ++ except ldap.OPERATIONS_ERROR: ++ pass ++ ++ log.info("Test PASSED") ++ ++ ++if __name__ == '__main__': ++ # Run isolated ++ # -s for DEBUG mode ++ CURRENT_FILE = os.path.realpath(__file__) ++ pytest.main(["-s", CURRENT_FILE]) ++ +diff --git a/ldap/servers/slapd/back-ldbm/sort.c b/ldap/servers/slapd/back-ldbm/sort.c +index 5b84d87f3..70ac60803 100644 +--- a/ldap/servers/slapd/back-ldbm/sort.c ++++ b/ldap/servers/slapd/back-ldbm/sort.c +@@ -546,6 +546,16 @@ compare_entries_sv(ID *id_a, ID *id_b, sort_spec *s, baggage_carrier *bc, int *e + /* Now copy it, so the second call doesn't crap on it */ + value_a = slapi_ch_bvecdup(temp_value); /* Really, we'd prefer to not call the chXXX variant...*/ + matchrule_values_to_keys(this_one->mr_pb, actual_value_b, &value_b); ++ ++ if ((actual_value_a && !value_a) || ++ (actual_value_b && !value_b)) { ++ ber_bvecfree(actual_value_a); ++ ber_bvecfree(actual_value_b); ++ CACHE_RETURN(&inst->inst_cache, &a); ++ CACHE_RETURN(&inst->inst_cache, &b); ++ *error = 1; ++ return 0; ++ } + if (actual_value_a) + ber_bvecfree(actual_value_a); + if (actual_value_b) +@@ -717,6 +727,8 @@ recurse: + A[i] >= A[lo] for higuy <= i <= hi */ + + do { ++ if (error) ++ return LDAP_OPERATIONS_ERROR; + loguy++; + } while (loguy <= hi && compare_entries_sv(loguy, lo, s, bc, &error) <= 0); + +@@ -724,6 +736,8 @@ recurse: + either loguy > hi or A[loguy] > A[lo] */ + + do { ++ if (error) ++ return LDAP_OPERATIONS_ERROR; + higuy--; + } while (higuy > lo && compare_entries_sv(higuy, lo, s, bc, &error) >= 0); + +-- +2.17.1 + diff --git a/SOURCES/0095-Ticket-49742-Fine-grained-password-policy-can-impact.patch b/SOURCES/0095-Ticket-49742-Fine-grained-password-policy-can-impact.patch new file mode 100644 index 0000000..77d030c --- /dev/null +++ b/SOURCES/0095-Ticket-49742-Fine-grained-password-policy-can-impact.patch @@ -0,0 +1,287 @@ +From d1c87a502dc969198aa0e6a210e1303ae71bdeae Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Thu, 7 Jun 2018 18:35:34 +0200 +Subject: [PATCH] Ticket 49742 - Fine grained password policy can impact search + performance + +Bug Description: + new_passwdPolicy is called with an entry DN. + In case of fine grain password policy we need to retrieve + the possible password policy (pwdpolicysubentry) that applies to + that entry. + It triggers an internal search to retrieve the entry. + + In case of a search operation (add_shadow_ext_password_attrs), the + entry is already in the pblock. So it is useless to do an additional + internal search for it. + +Fix Description: + in case of fine grain password policy and a SRCH operation, + if the entry DN matches the entry stored in the pblock (SLAPI_SEARCH_RESULT_ENTRY) + then use that entry instead of doing an internal search + +https://pagure.io/389-ds-base/issue/49742 + +Reviewed by: Mark Reynolds + +Platforms tested: F26 + +Flag Day: no + +Doc impact: no +--- + dirsrvtests/tests/tickets/ticket48228_test.py | 18 +++---- + dirsrvtests/tests/tickets/ticket548_test.py | 18 ++++--- + ldap/servers/slapd/pw.c | 48 +++++++++++++++++-- + 3 files changed, 66 insertions(+), 18 deletions(-) + +diff --git a/dirsrvtests/tests/tickets/ticket48228_test.py b/dirsrvtests/tests/tickets/ticket48228_test.py +index 4f4494e0b..1ab741b94 100644 +--- a/dirsrvtests/tests/tickets/ticket48228_test.py ++++ b/dirsrvtests/tests/tickets/ticket48228_test.py +@@ -7,6 +7,7 @@ + # --- END COPYRIGHT BLOCK --- + # + import logging ++import time + + import pytest + from lib389.tasks import * +@@ -33,14 +34,14 @@ def set_global_pwpolicy(topology_st, inhistory): + topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) + # Enable password policy + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', b'on')]) + except ldap.LDAPError as e: + log.error('Failed to set pwpolicy-local: error ' + e.message['desc']) + assert False + + log.info(" Set global password history on\n") + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordHistory', 'on')]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordHistory', b'on')]) + except ldap.LDAPError as e: + log.error('Failed to set passwordHistory: error ' + e.message['desc']) + assert False +@@ -48,7 +49,7 @@ def set_global_pwpolicy(topology_st, inhistory): + log.info(" Set global passwords in history\n") + try: + count = "%d" % inhistory +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordInHistory', count)]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordInHistory', count.encode())]) + except ldap.LDAPError as e: + log.error('Failed to set passwordInHistory: error ' + e.message['desc']) + assert False +@@ -113,9 +114,9 @@ def check_passwd_inhistory(topology_st, user, cpw, passwd): + topology_st.standalone.simple_bind_s(user, cpw) + time.sleep(1) + try: +- topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', passwd)]) ++ topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', passwd.encode())]) + except ldap.LDAPError as e: +- log.info(' The password ' + passwd + ' of user' + USER1_DN + ' in history: error ' + e.message['desc']) ++ log.info(' The password ' + passwd + ' of user' + USER1_DN + ' in history: error {0}'.format(e)) + inhistory = 1 + time.sleep(1) + return inhistory +@@ -130,7 +131,7 @@ def update_passwd(topology_st, user, passwd, times): + # Now update the value for this iter. + cpw = 'password%d' % i + try: +- topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', cpw)]) ++ topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', cpw.encode())]) + except ldap.LDAPError as e: + log.fatal( + 'test_ticket48228: Failed to update the password ' + cpw + ' of user ' + user + ': error ' + e.message[ +@@ -146,7 +147,6 @@ def test_ticket48228_test_global_policy(topology_st): + """ + Check global password policy + """ +- + log.info(' Set inhistory = 6') + set_global_pwpolicy(topology_st, 6) + +@@ -201,7 +201,7 @@ def test_ticket48228_test_global_policy(topology_st): + log.info("Global policy was successfully verified.") + + +-def test_ticket48228_test_subtree_policy(topology_st): ++def text_ticket48228_text_subtree_policy(topology_st): + """ + Check subtree level password policy + """ +@@ -233,7 +233,7 @@ def test_ticket48228_test_subtree_policy(topology_st): + log.info(' Set inhistory = 4') + topology_st.standalone.simple_bind_s(DN_DM, PASSWORD) + try: +- topology_st.standalone.modify_s(SUBTREE_PWP, [(ldap.MOD_REPLACE, 'passwordInHistory', '4')]) ++ topology_st.standalone.modify_s(SUBTREE_PWP, [(ldap.MOD_REPLACE, 'passwordInHistory', b'4')]) + except ldap.LDAPError as e: + log.error('Failed to set pwpolicy-local: error ' + e.message['desc']) + assert False +diff --git a/dirsrvtests/tests/tickets/ticket548_test.py b/dirsrvtests/tests/tickets/ticket548_test.py +index d354cc802..0d71ab6ca 100644 +--- a/dirsrvtests/tests/tickets/ticket548_test.py ++++ b/dirsrvtests/tests/tickets/ticket548_test.py +@@ -42,7 +42,7 @@ def set_global_pwpolicy(topology_st, min_=1, max_=10, warn=3): + log.info(" +++++ Enable global password policy +++++\n") + # Enable password policy + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', b'on')]) + except ldap.LDAPError as e: + log.error('Failed to set pwpolicy-local: error ' + e.message['desc']) + assert False +@@ -54,28 +54,28 @@ def set_global_pwpolicy(topology_st, min_=1, max_=10, warn=3): + + log.info(" Set global password Min Age -- %s day\n" % min_) + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMinAge', '%s' % min_secs)]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMinAge', ('%s' % min_secs).encode())]) + except ldap.LDAPError as e: + log.error('Failed to set passwordMinAge: error ' + e.message['desc']) + assert False + + log.info(" Set global password Expiration -- on\n") + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordExp', 'on')]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordExp', b'on')]) + except ldap.LDAPError as e: + log.error('Failed to set passwordExp: error ' + e.message['desc']) + assert False + + log.info(" Set global password Max Age -- %s days\n" % max_) + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMaxAge', '%s' % max_secs)]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMaxAge', ('%s' % max_secs).encode())]) + except ldap.LDAPError as e: + log.error('Failed to set passwordMaxAge: error ' + e.message['desc']) + assert False + + log.info(" Set global password Warning -- %s days\n" % warn) + try: +- topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordWarning', '%s' % warn_secs)]) ++ topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordWarning', ('%s' % warn_secs).encode())]) + except ldap.LDAPError as e: + log.error('Failed to set passwordWarning: error ' + e.message['desc']) + assert False +@@ -93,6 +93,8 @@ def set_subtree_pwpolicy(topology_st, min_=2, max_=20, warn=6): + try: + topology_st.standalone.add_s(Entry((SUBTREE_CONTAINER, {'objectclass': 'top nsContainer'.split(), + 'cn': 'nsPwPolicyContainer'}))) ++ except ldap.ALREADY_EXISTS: ++ pass + except ldap.LDAPError as e: + log.error('Failed to add subtree container: error ' + e.message['desc']) + # assert False +@@ -128,6 +130,8 @@ def set_subtree_pwpolicy(topology_st, min_=2, max_=20, warn=6): + 'cosPriority': '1', + 'cn': SUBTREE_COS_TMPLDN, + 'pwdpolicysubentry': SUBTREE_PWP}))) ++ except ldap.ALREADY_EXISTS: ++ pass + except ldap.LDAPError as e: + log.error('Failed to add COS template: error ' + e.message['desc']) + # assert False +@@ -139,6 +143,8 @@ def set_subtree_pwpolicy(topology_st, min_=2, max_=20, warn=6): + 'cn': SUBTREE_PWPDN, + 'costemplatedn': SUBTREE_COS_TMPL, + 'cosAttribute': 'pwdpolicysubentry default operational-default'}))) ++ except ldap.ALREADY_EXISTS: ++ pass + except ldap.LDAPError as e: + log.error('Failed to add COS def: error ' + e.message['desc']) + # assert False +@@ -150,7 +156,7 @@ def update_passwd(topology_st, user, passwd, newpasswd): + log.info(" Bind as {%s,%s}" % (user, passwd)) + topology_st.standalone.simple_bind_s(user, passwd) + try: +- topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', newpasswd)]) ++ topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', newpasswd.encode())]) + except ldap.LDAPError as e: + log.fatal('test_ticket548: Failed to update the password ' + cpw + ' of user ' + user + ': error ' + e.message[ + 'desc']) +diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c +index 451be364d..10b8e7254 100644 +--- a/ldap/servers/slapd/pw.c ++++ b/ldap/servers/slapd/pw.c +@@ -1625,6 +1625,10 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) + int attr_free_flags = 0; + int rc = 0; + int optype = -1; ++ int free_e = 1; /* reset if e is taken from pb */ ++ if (pb) { ++ slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &optype); ++ } + + /* If we already allocated a pw policy, return it */ + if (pb != NULL) { +@@ -1688,7 +1692,43 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) + /* If we're not doing an add, we look for the pwdpolicysubentry + attribute in the target entry itself. */ + } else { +- if ((e = get_entry(pb, dn)) != NULL) { ++ if (optype == SLAPI_OPERATION_SEARCH) { ++ Slapi_Entry *pb_e; ++ ++ /* During a search the entry should be in the pblock ++ * For safety check entry DN is identical to 'dn' ++ */ ++ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &pb_e); ++ if (pb_e) { ++ Slapi_DN * sdn; ++ const char *ndn; ++ char *pb_ndn; ++ ++ pb_ndn = slapi_entry_get_ndn(pb_e); ++ ++ sdn = slapi_sdn_new_dn_byval(dn); ++ ndn = slapi_sdn_get_ndn(sdn); ++ ++ if (strcasecmp(pb_ndn, ndn) == 0) { ++ /* We are using the candidate entry that is already loaded in the pblock ++ * Do not trigger an additional internal search ++ * Also we will not need to free the entry that will remain in the pblock ++ */ ++ e = pb_e; ++ free_e = 0; ++ } else { ++ e = get_entry(pb, dn); ++ } ++ slapi_sdn_free(&sdn); ++ } else { ++ e = get_entry(pb, dn); ++ } ++ } else { ++ /* For others operations but SEARCH */ ++ e = get_entry(pb, dn); ++ } ++ ++ if (e) { + Slapi_Attr *attr = NULL; + rc = slapi_entry_attr_find(e, "pwdpolicysubentry", &attr); + if (attr && (0 == rc)) { +@@ -1718,7 +1758,9 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) + } + } + slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags); +- slapi_entry_free(e); ++ if (free_e) { ++ slapi_entry_free(e); ++ } + + if (pw_entry == NULL) { + slapi_log_err(SLAPI_LOG_ERR, "new_passwdPolicy", +@@ -1916,7 +1958,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) + slapi_pblock_set_pwdpolicy(pb, pwdpolicy); + } + return pwdpolicy; +- } else if (e) { ++ } else if (free_e) { + slapi_entry_free(e); + } + } +-- +2.17.1 + diff --git a/SOURCES/0096-Bug-1623247-Crash-in-vslapd_log_emergency_error.patch b/SOURCES/0096-Bug-1623247-Crash-in-vslapd_log_emergency_error.patch new file mode 100644 index 0000000..81a9a8a --- /dev/null +++ b/SOURCES/0096-Bug-1623247-Crash-in-vslapd_log_emergency_error.patch @@ -0,0 +1,85 @@ +From 9d2aa18fb5c48a11300d2309df89213bbdb614e1 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 23 Aug 2018 13:43:36 -0400 +Subject: [PATCH 1/2] Bug 1623247 - Crash in vslapd_log_emergency_error + + Description: We were not locking the error log fd before closing and reopening + the log file. This could cause a crash when multiple threads are + trying to log tothe errors log. +--- + ldap/servers/slapd/log.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index 998efaef3..90ce6ac0a 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -2231,11 +2231,11 @@ vslapd_log_emergency_error(LOGFD fp, const char *msg, int locked) + if (logging_hr_timestamps_enabled == 1) { + struct timespec tsnow; + if (clock_gettime(CLOCK_REALTIME, &tsnow) != 0) { +- syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to determine system time for message :: %s", msg); ++ syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to determine system time for message :: %s\n", msg); + return; + } + if (format_localTime_hr_log(tsnow.tv_sec, tsnow.tv_nsec, sizeof(tbuf), tbuf, &size) != 0) { +- syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to format system time for message :: %s", msg); ++ syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to format system time for message :: %s\n", msg); + return; + } + } else { +@@ -2243,14 +2243,14 @@ vslapd_log_emergency_error(LOGFD fp, const char *msg, int locked) + time_t tnl; + tnl = slapi_current_utc_time(); + if (format_localTime_log(tnl, sizeof(tbuf), tbuf, &size) != 0) { +- syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to format system time for message :: %s", msg); ++ syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to format system time for message :: %s\n", msg); + return; + } + #ifdef HAVE_CLOCK_GETTIME + } + #endif + +- PR_snprintf(buffer, sizeof(buffer), "%s - EMERG - %s", tbuf, msg); ++ PR_snprintf(buffer, sizeof(buffer), "%s - EMERG - %s\n", tbuf, msg); + size = strlen(buffer); + + if (!locked) { +@@ -2531,7 +2531,7 @@ vslapd_log_access(char *fmt, va_list ap) + + if (SLAPI_LOG_BUFSIZ - blen < vlen) { + /* We won't be able to fit the message in! Uh-oh! */ +- /* Should we actually just do the snprintf, and warn that message was trunced? */ ++ /* Should we actually just do the snprintf, and warn that message was truncated? */ + log__error_emergency("Insufficent buffer capacity to fit timestamp and message!", 1, 0); + return -1; + } +@@ -4447,6 +4447,13 @@ log__error_emergency(const char *errstr, int reopen, int locked) + if (!reopen) { + return; + } ++ if (!locked) { ++ /* ++ * Take the lock because we are closing and reopening the error log (fd), ++ * and we don't want any other threads trying to use this fd ++ */ ++ LOG_ERROR_LOCK_WRITE(); ++ } + if (NULL != loginfo.log_error_fdes) { + LOG_CLOSE(loginfo.log_error_fdes); + } +@@ -4455,7 +4462,10 @@ log__error_emergency(const char *errstr, int reopen, int locked) + PRErrorCode prerr = PR_GetError(); + syslog(LOG_ERR, "Failed to reopen errors log file, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_pr_strerror(prerr)); + } else { +- vslapd_log_emergency_error(loginfo.log_error_fdes, errstr, locked); ++ vslapd_log_emergency_error(loginfo.log_error_fdes, errstr, 1 /* locked */); ++ } ++ if (!locked) { ++ LOG_ERROR_UNLOCK_WRITE(); + } + return; + } +-- +2.17.1 + diff --git a/SOURCES/0097-Ticket-49768-Under-network-intensive-load-persistent.patch b/SOURCES/0097-Ticket-49768-Under-network-intensive-load-persistent.patch new file mode 100644 index 0000000..cee161a --- /dev/null +++ b/SOURCES/0097-Ticket-49768-Under-network-intensive-load-persistent.patch @@ -0,0 +1,65 @@ +From 2136ba8dd18e72bfbe037517c10187bfe695628f Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Thu, 24 May 2018 15:36:34 +0200 +Subject: [PATCH] Ticket 49768 - Under network intensive load persistent search + can erronously decrease connection refcnt + +Bug Description: + If a connection enters in turbo mode (because of high traffic) or + a worker reads several requests in the read buffer (more_data), the thread + keeps processing connection. + In that condition it should not decrease the refcnt. + In case the operation is a persistent search, it decreases systematically + the refcnt. + So refcnt can become lower than the actual number of threads active on the connection. + + Most of the time it can create messages like + Attempt to release connection that is not acquired + In some rare case, if the a connection is out of the active list but a remaining thread + tries to remove it again it can lead to a crash + +Fix Description: + The fix consist, when processing a PS, to decrease the refcnt at the condition + the connection is not in turbo mode or in more_data. + +https://pagure.io/389-ds-base/issue/49768 + +Reviewed by: Mark Reynolds + +Platforms tested: F26 + +Flag Day: no + +Doc impact: no +--- + ldap/servers/slapd/connection.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index c54e7c26c..1dbb49f06 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -1811,9 +1811,17 @@ connection_threadmain() + slapi_counter_increment(ops_completed); + /* If this op isn't a persistent search, remove it */ + if (op->o_flags & OP_FLAG_PS) { +- PR_EnterMonitor(conn->c_mutex); +- connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */ +- PR_ExitMonitor(conn->c_mutex); ++ /* Release the connection (i.e. decrease refcnt) at the condition ++ * this thread will not loop on it. ++ * If we are in turbo mode (dedicated to that connection) or ++ * more_data (continue reading buffered req) this thread ++ * continues to hold the connection ++ */ ++ if (!thread_turbo_flag && !more_data) { ++ PR_EnterMonitor(conn->c_mutex); ++ connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */ ++ PR_ExitMonitor(conn->c_mutex); ++ } + /* ps_add makes a shallow copy of the pb - so we + * can't free it or init it here - just set operation to NULL. + * ps_send_results will call connection_remove_operation_ext to free it +-- +2.17.1 + diff --git a/SOURCES/0098-Ticket-49932-Crash-in-delete_passwdPolicy-when-persi.patch b/SOURCES/0098-Ticket-49932-Crash-in-delete_passwdPolicy-when-persi.patch new file mode 100644 index 0000000..f7b8a04 --- /dev/null +++ b/SOURCES/0098-Ticket-49932-Crash-in-delete_passwdPolicy-when-persi.patch @@ -0,0 +1,39 @@ +From 1bb5fd7fac9c5b93d3dfb8b8a2a648e238a158bc Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 30 Aug 2018 14:28:10 -0400 +Subject: [PATCH] Ticket 49932 - Crash in delete_passwdPolicy when persistent + search connections are terminated unexpectedly + +Bug Description: We clone a pblock in a psearch search, and under certain + error conditions this pblock is freed, but it frees the + password policy struct which can lead to a double free + when the original pblock is destroyed. + +Fix Description: During the cloning, set the pwppolicy struct to NULL + so the clone allocates its own policy if needed + +https://pagure.io/389-ds-base/issue/49932 + +Reviewed by: ? + +(cherry picked from commit 78fc627accacfa4061ce48977e22301f81ea8d73) +--- + ldap/servers/slapd/pblock.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c +index 4514c3ce6..bc18a7b18 100644 +--- a/ldap/servers/slapd/pblock.c ++++ b/ldap/servers/slapd/pblock.c +@@ -322,6 +322,8 @@ slapi_pblock_clone(Slapi_PBlock *pb) + if (pb->pb_intop != NULL) { + _pblock_assert_pb_intop(new_pb); + *(new_pb->pb_intop) = *(pb->pb_intop); ++ /* set pwdpolicy to NULL so this clone allocates its own policy */ ++ new_pb->pb_intop->pwdpolicy = NULL; + } + if (pb->pb_intplugin != NULL) { + _pblock_assert_pb_intplugin(new_pb); +-- +2.17.1 + diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index 5d9af60..6c9df65 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -39,7 +39,7 @@ Summary: 389 Directory Server (%{variant}) Name: 389-ds-base Version: 1.3.7.5 -Release: %{?relprefix}25%{?prerel}%{?dist} +Release: %{?relprefix}28%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org/ Group: System Environment/Daemons @@ -239,6 +239,12 @@ Patch89: 0089-Ticket-49652-DENY-aci-s-are-not-handled-properly.patch Patch90: 0090-Ticket-49576-ds-replcheck-fix-certificate-directory-.patch Patch91: 0091-Ticket-49765-Async-operations-can-hang-when-the-serv.patch Patch92: 0092-Ticket-49765-compiler-warning.patch +Patch93: 0093-Ticket-49893-disable-nunc-stans-by-default.patch +Patch94: 0094-Ticket-49890-ldapsearch-with-server-side-sort-crashe.patch +Patch95: 0095-Ticket-49742-Fine-grained-password-policy-can-impact.patch +Patch96: 0096-Bug-1623247-Crash-in-vslapd_log_emergency_error.patch +Patch97: 0097-Ticket-49768-Under-network-intensive-load-persistent.patch +Patch98: 0098-Ticket-49932-Crash-in-delete_passwdPolicy-when-persi.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -593,6 +599,21 @@ fi %{_sysconfdir}/%{pkgname}/dirsrvtests %changelog +* Thu Sep 13 2018 Mark Reynolds - 1.3.7.5-28 +- Bump version to 1.3.7.5-28 +- Resolves: Bug 1628676 - 389-ds-base: race condition on reference counter leads to DoS using persistent search +- Resolves: Bug 1628677 - Crash in delete_passwdPolicy when persistent search connections are terminated unexpectedly + +* Wed Aug 29 2018 Mark Reynolds - 1.3.7.5-27 +- Bump version to 1.3.7.5-27 +- Resolves: Bug 1623247 - Crash in vslapd_log_emergency_error + +* Tue Aug 14 2018 Mark Reynolds - 1.3.7.5-26 +- Bump version to 1.3.7.5-26 +- Resolves: Bug 1615924 - Fine grained password policy can impact search performance +- Resolves: Bug 1614836 - Disable nunc-stans by default +- Resolves: Bug 1614861 - ldapsearch with server side sort crashes the ldap server + * Tue Jul 3 2018 Mark Reynolds - 1.3.7.5-25 - Bump version to 1.3.7.5-25 - Resolves: Bug 1597530 - Async operations can hang when the server is running nunc-stans