From 23263335ebf0cded2bfc5bc2e4fdf293bdd18a30 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 05 2019 19:03:17 +0000 Subject: import 389-ds-base-1.4.1.3-7.module+el8.1.0+4150+5b8c2c1f --- diff --git a/.389-ds-base.metadata b/.389-ds-base.metadata index b65531c..ffac167 100644 --- a/.389-ds-base.metadata +++ b/.389-ds-base.metadata @@ -1,2 +1,2 @@ -3a3a21c4189ba8c71fc0ddf06f8bf49f592e8cc5 SOURCES/389-ds-base-1.4.0.20-10.tar.bz2 -92fdc0b38680aaee1fa7ccd89cbf1af61224ff46 SOURCES/jemalloc-5.1.0.tar.bz2 +50c525db2c9adfc7cca119ed13110a42d88d079c SOURCES/389-ds-base-1.4.1.3.tar.bz2 +5a5255f7bca3e79a063f26f292cf93f17fe3b14f SOURCES/jemalloc-5.2.0.tar.bz2 diff --git a/.gitignore b/.gitignore index 410b34c..ab2d85c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/389-ds-base-1.4.0.20-10.tar.bz2 -SOURCES/jemalloc-5.1.0.tar.bz2 +SOURCES/389-ds-base-1.4.1.3.tar.bz2 +SOURCES/jemalloc-5.2.0.tar.bz2 diff --git a/SOURCES/0000-Issue-49602-Revise-replication-status-messages.patch b/SOURCES/0000-Issue-49602-Revise-replication-status-messages.patch new file mode 100644 index 0000000..949a707 --- /dev/null +++ b/SOURCES/0000-Issue-49602-Revise-replication-status-messages.patch @@ -0,0 +1,353 @@ +From 45f4abd6befa50b129fc49b331b42c280f37199a Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 13 Jun 2019 13:01:35 -0400 +Subject: [PATCH] Issue 49602 - Revise replication status messages + +Bug Description: All agreement status messages start with "Error (##)" followed + by a text string. Even success states start with "Error", and + this is confusing. + + Added new attributes to display the status in a JSON format + for easier parsing for applications: + + replicaLastUpdateStatusJSON + replicaLastInitStatusJSON + +Design Doc: https://www.port389.org/docs/389ds/design/repl-agmt-status-design.html + +https://pagure.io/389-ds-base/issue/49602 + +Reviewed by: firstyear(Thanks!) +--- + .../suites/replication/single_master_test.py | 19 +++-- + ldap/schema/01core389.ldif | 2 + + ldap/servers/plugins/replication/repl5_agmt.c | 84 ++++++++++++++++--- + .../plugins/replication/repl5_protocol_util.c | 13 +-- + 4 files changed, 96 insertions(+), 22 deletions(-) + +diff --git a/dirsrvtests/tests/suites/replication/single_master_test.py b/dirsrvtests/tests/suites/replication/single_master_test.py +index 5b73e23ae..78f849da7 100644 +--- a/dirsrvtests/tests/suites/replication/single_master_test.py ++++ b/dirsrvtests/tests/suites/replication/single_master_test.py +@@ -23,6 +23,7 @@ from lib389._constants import (ReplicaRole, DEFAULT_SUFFIX, REPLICAID_MASTER_1, + REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT, DEFAULT_BACKUPDIR, + RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD, RA_TRANSPORT_PROT, + defaultProperties) ++import json + + pytestmark = pytest.mark.tier1 + +@@ -95,7 +96,7 @@ def test_mail_attr_repl(topo_r): + consumer.start() + + log.info("Make a search for mail attribute in attempt to crash server") +- consumer.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(mail=testuser@redhat.com)", ["mail"]) ++ c_user.get_attr_val("mail") + + log.info("Make sure that server hasn't crashed") + repl.test_replication(master, consumer) +@@ -111,11 +112,13 @@ def test_lastupdate_attr_before_init(topo_nr): + 1. Check nsds5replicaLastUpdateStart value + 2. Check nsds5replicaLastUpdateEnd value + 3. Check nsds5replicaLastUpdateStatus value ++ 4. Check nsds5replicaLastUpdateStatusJSON is parsable + :expectedresults: + 1. nsds5replicaLastUpdateStart should be equal to 0 + 2. nsds5replicaLastUpdateEnd should be equal to 0 + 3. nsds5replicaLastUpdateStatus should not be equal +- to "0 Replica acquired successfully: Incremental update started" ++ to "Replica acquired successfully: Incremental update started" ++ 4. Success + """ + + master = topo_nr.ins["standalone1"] +@@ -139,11 +142,15 @@ def test_lastupdate_attr_before_init(topo_nr): + with pytest.raises(Exception): + repl.wait_for_replication(master, consumer, timeout=5) + +- assert agmt.get_attr_val_bytes('nsds5replicaLastUpdateStart') == b"19700101000000Z" +- assert agmt.get_attr_val_bytes("nsds5replicaLastUpdateEnd") == b"19700101000000Z" +- assert b"Replica acquired successfully" not in agmt.get_attr_val_bytes("nsds5replicaLastUpdateStatus") +- ++ assert agmt.get_attr_val_utf8('nsds5replicaLastUpdateStart') == "19700101000000Z" ++ assert agmt.get_attr_val_utf8("nsds5replicaLastUpdateEnd") == "19700101000000Z" ++ assert "replica acquired successfully" not in agmt.get_attr_val_utf8_l("nsds5replicaLastUpdateStatus") + ++ # make sure the JSON attribute is parsable ++ json_status = agmt.get_attr_val_utf8("nsds5replicaLastUpdateStatusJSON") ++ if json_status is not None: ++ json_obj = json.loads(json_status) ++ log.debug("JSON status message: {}".format(json_obj)) + + if __name__ == '__main__': + # Run isolated +diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif +index 993fa4a6d..7bf4acc5b 100644 +--- a/ldap/schema/01core389.ldif ++++ b/ldap/schema/01core389.ldif +@@ -312,6 +312,8 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2341 NAME 'nsslapd-changelogmaxentries' + attributeTypes: ( 2.16.840.1.113730.3.1.2344 NAME 'nsslapd-tls-check-crl' DESC 'Check CRL when opening outbound TLS connections. Valid options are none, peer, all.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' ) + attributeTypes: ( 2.16.840.1.113730.3.1.2353 NAME 'nsslapd-encryptionalgorithm' DESC 'The encryption algorithm used to encrypt the changelog' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' ) + attributeTypes: ( 2.16.840.1.113730.3.1.2084 NAME 'nsSymmetricKey' DESC 'A symmetric key - currently used by attribute encryption' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'attribute encryption' ) ++attributeTypes: ( 2.16.840.1.113730.3.1.2364 NAME 'nsds5replicaLastInitStatusJSON' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' ) ++attributeTypes: ( 2.16.840.1.113730.3.1.2365 NAME 'nsds5replicaLastUpdateStatusJSON' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' ) + # + # objectclasses + # +diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c +index 53e6708c8..8e4586d8b 100644 +--- a/ldap/servers/plugins/replication/repl5_agmt.c ++++ b/ldap/servers/plugins/replication/repl5_agmt.c +@@ -60,7 +60,11 @@ + #define DEFAULT_TIMEOUT 120 /* (seconds) default outbound LDAP connection */ + #define DEFAULT_FLOWCONTROL_WINDOW 1000 /* #entries sent without acknowledgment */ + #define DEFAULT_FLOWCONTROL_PAUSE 2000 /* msec of pause when #entries sent witout acknowledgment */ +-#define STATUS_LEN 1024 ++#define STATUS_LEN 2048 ++#define STATUS_GOOD "green" ++#define STATUS_WARNING "amber" ++#define STATUS_BAD "red" ++ + + struct changecounter + { +@@ -93,11 +97,13 @@ typedef struct repl5agmt + time_t last_update_start_time; /* Local start time of last update session */ + time_t last_update_end_time; /* Local end time of last update session */ + char last_update_status[STATUS_LEN]; /* Status of last update. Format = numeric code textual description */ ++ char last_update_status_json[STATUS_LEN]; + PRBool update_in_progress; + PRBool is_enabled; + time_t last_init_start_time; /* Local start time of last total init */ + time_t last_init_end_time; /* Local end time of last total init */ + char last_init_status[STATUS_LEN]; /* Status of last total init. Format = numeric code textual description */ ++ char last_init_status_json[STATUS_LEN]; + PRLock *lock; + Object *consumerRUV; /* last RUV received from the consumer - used for changelog purging */ + CSN *consumerSchemaCSN; /* last schema CSN received from the consumer */ +@@ -2443,6 +2449,21 @@ agmt_set_last_init_end(Repl_Agmt *ra, time_t end_time) + } + } + ++static void ++agmt_set_last_update_status_json(Repl_Agmt *ra, char *state, int ldaprc, int replrc) ++{ ++ char ts[SLAPI_TIMESTAMP_BUFSIZE]; ++ time_t now; ++ ++ time(&now); ++ strftime(ts, sizeof ts, "%FT%TZ", gmtime(&now)); ++ PR_snprintf(ra->last_update_status_json, STATUS_LEN, ++ "{\"state\": \"%s\", \"ldap_rc\": \"%d\", \"ldap_rc_text\": \"%s\", " ++ "\"repl_rc\": \"%d\", \"repl_rc_text\": \"%s\", \"date\": \"%s\", \"message\": \"%s\"}", ++ state, ldaprc, ldap_err2string(ldaprc), replrc, protocol_response2string(replrc), ++ ts, ra->last_update_status); ++} ++ + void + agmt_set_last_update_status(Repl_Agmt *ra, int ldaprc, int replrc, const char *message) + { +@@ -2463,19 +2484,29 @@ agmt_set_last_update_status(Repl_Agmt *ra, int ldaprc, int replrc, const char *m + PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (%d) %s%s - LDAP error: %s%s%s%s", + ldaprc, message ? message : "", message ? "" : " - ", + slapi_err2string(ldaprc), replmsg ? " (" : "", replmsg ? replmsg : "", replmsg ? ")" : ""); ++ agmt_set_last_update_status_json(ra, STATUS_BAD, ldaprc, replrc); + } + /* ldaprc == LDAP_SUCCESS */ + else if (replrc != 0) { + if (replrc == NSDS50_REPL_REPLICA_BUSY) { + PR_snprintf(ra->last_update_status, STATUS_LEN, +- "Error (%d) Can't acquire busy replica", replrc); ++ "Error (%d) Can't acquire busy replica (%s)", ++ replrc, message ? message : ""); ++ agmt_set_last_update_status_json(ra, STATUS_WARNING, ldaprc, replrc); ++ } else if (replrc == NSDS50_REPL_TRANSIENT_ERROR || replrc == NSDS50_REPL_BACKOFF) { ++ PR_snprintf(ra->last_update_status, STATUS_LEN, ++ "Error (%d) Can't acquire replica (%s)", ++ replrc, message ? message : ""); ++ agmt_set_last_update_status_json(ra, STATUS_WARNING, ldaprc, replrc); + } else if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED) { + PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (0) Replication session successful"); ++ agmt_set_last_update_status_json(ra, STATUS_GOOD, ldaprc, replrc); + } else if (replrc == NSDS50_REPL_DISABLED) { + PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (%d) Incremental update aborted: " + "Replication agreement for %s\n can not be updated while the replica is disabled.\n" + "(If the suffix is disabled you must enable it then restart the server for replication to take place).", + replrc, ra->long_name ? ra->long_name : "a replica"); ++ agmt_set_last_update_status_json(ra, STATUS_BAD, ldaprc, replrc); + /* Log into the errors log, as "ra->long_name" is not accessible from the caller */ + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "Incremental update aborted: Replication agreement for \"%s\" " +@@ -2487,17 +2518,35 @@ agmt_set_last_update_status(Repl_Agmt *ra, int ldaprc, int replrc, const char *m + PR_snprintf(ra->last_update_status, STATUS_LEN, + "Error (%d) Replication error acquiring replica: %s%s(%s)", + replrc, message ? message : "", message ? " " : "", protocol_response2string(replrc)); ++ agmt_set_last_update_status_json(ra, STATUS_BAD, ldaprc, replrc); + } + } else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */ + { + PR_snprintf(ra->last_update_status, STATUS_LEN, + "Error (0) Replica acquired successfully: %s", message); ++ agmt_set_last_update_status_json(ra, STATUS_GOOD, ldaprc, replrc); + } else { /* agmt_set_last_update_status(0,0,NULL) to reset agmt */ + ra->last_update_status[0] = '\0'; ++ ra->last_update_status_json[0] = '\0'; + } + } + } + ++static void ++agmt_set_last_init_status_json(Repl_Agmt *ra, char *state, int ldaprc, int replrc, int connrc) ++{ ++ char ts[SLAPI_TIMESTAMP_BUFSIZE]; ++ time_t now; ++ ++ time(&now); ++ strftime(ts, sizeof ts, "%FT%TZ", gmtime(&now)); ++ PR_snprintf(ra->last_init_status_json, STATUS_LEN, ++ "{\"state\": \"%s\", \"ldap_rc\": \"%d\", \"ldap_rc_text\": \"%s\", \"repl_rc\": \"%d\", \"repl_rc_text\": \"%s\", " ++ "\"conn_rc\": \"%d\", \"conn_rc_text\": \"%s\", \"date\": \"%s\", \"message\": \"%s\"}", ++ state, ldaprc, ldap_err2string(ldaprc), replrc, protocol_response2string(replrc), ++ connrc, conn_result2string(connrc), ts, ra->last_init_status); ++} ++ + void + agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, const char *message) + { +@@ -2523,16 +2572,16 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con + replmsg = NULL; + } + } +- PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s%sLDAP error: %s%s%s%s%s", ++ PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d)%s%sLDAP error: %s%s%s%s%s", + ldaprc, message ? message : "", message ? "" : " - ", + slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "", + connrc ? " - " : "", connrc ? connmsg : ""); ++ agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc); + } + /* ldaprc == LDAP_SUCCESS */ + else if (replrc != 0) { + if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED) { +- PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s", +- ldaprc, "Replication session successful"); ++ PR_snprintf(ra->last_init_status, STATUS_LEN, "Replication session successful"); + } else if (replrc == NSDS50_REPL_DISABLED) { + if (agmt_is_enabled(ra)) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "Total update aborted: " +@@ -2543,6 +2592,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con + "Replication agreement for \"%s\" can not be updated while the suffix is disabled.\n" + "You must enable it then restart the server for replication to take place).", + replrc, ra->long_name ? ra->long_name : "a replica"); ++ agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc); + } else { + /* You do not need to restart the server after enabling the agreement */ + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "Total update aborted: " +@@ -2551,6 +2601,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con + PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) Total update aborted: " + "Replication agreement for \"%s\" can not be updated while the agreement is disabled.", + replrc, ra->long_name ? ra->long_name : "a replica"); ++ agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc); + } + } else { + PR_snprintf(ra->last_init_status, STATUS_LEN, +@@ -2558,19 +2609,21 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con + replrc, protocol_response2string(replrc), + message ? " - " : "", message ? message : "", + connrc ? " - " : "", connrc ? connmsg : ""); ++ agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc); + } + } else if (connrc != CONN_OPERATION_SUCCESS) { + PR_snprintf(ra->last_init_status, STATUS_LEN, + "Error (%d) connection error: %s%s%s", + connrc, connmsg, + message ? " - " : "", message ? message : ""); +- } else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */ +- { ++ agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc); ++ } else if (message != NULL) { /* replrc == NSDS50_REPL_REPLICA_READY == 0 */ + PR_snprintf(ra->last_init_status, STATUS_LEN, +- "Error (%d) %s", +- ldaprc, message); ++ "Error (%d) %s", ldaprc, message); ++ agmt_set_last_init_status_json(ra, STATUS_GOOD, ldaprc, replrc, connrc); + } else { /* agmt_set_last_init_status(0,0,NULL) to reset agmt */ +- PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d)", ldaprc); ++ ra->last_init_status[0] = '\0'; ++ ra->last_init_status_json[0] = '\0'; + } + } + } +@@ -2705,10 +2758,20 @@ get_agmt_status(Slapi_PBlock *pb __attribute__((unused)), + agmt_get_changecount_string(ra, changecount_string, sizeof(changecount_string)); + slapi_entry_add_string(e, "nsds5replicaChangesSentSinceStartup", changecount_string); + if (ra->last_update_status[0] == '\0') { ++ char status_msg[STATUS_LEN]; ++ char ts[SLAPI_TIMESTAMP_BUFSIZE]; ++ time_t now; ++ time(&now); ++ strftime(ts, sizeof ts, "%FT%TZ", gmtime(&now)); + slapi_entry_add_string(e, "nsds5replicaLastUpdateStatus", + "Error (0) No replication sessions started since server startup"); ++ PR_snprintf(status_msg, STATUS_LEN, ++ "{\"state\": \"green\", \"ldap_rc\": \"0\", \"ldap_rc_text\": \"success\", \"repl_rc\": \"0\", \"repl_rc_text\": \"replica acquired\", " ++ "\"date\": \"%s\", \"message\": \"Error (0) No replication sessions started since server startup\"}", ts); ++ slapi_entry_add_string(e, "nsds5replicaLastUpdateStatusJSON", status_msg); + } else { + slapi_entry_add_string(e, "nsds5replicaLastUpdateStatus", ra->last_update_status); ++ slapi_entry_add_string(e, "nsds5replicaLastUpdateStatusJSON", ra->last_update_status_json); + } + slapi_entry_add_string(e, "nsds5replicaUpdateInProgress", ra->update_in_progress ? "TRUE" : "FALSE"); + +@@ -2724,6 +2787,7 @@ get_agmt_status(Slapi_PBlock *pb __attribute__((unused)), + + if (ra->last_init_status[0] != '\0') { + slapi_entry_add_string(e, "nsds5replicaLastInitStatus", ra->last_init_status); ++ slapi_entry_add_string(e, "nsds5replicaLastInitStatusJSON", ra->last_init_status_json); + } + } + bail: +diff --git a/ldap/servers/plugins/replication/repl5_protocol_util.c b/ldap/servers/plugins/replication/repl5_protocol_util.c +index a48d4d02a..bb9f9e7e1 100644 +--- a/ldap/servers/plugins/replication/repl5_protocol_util.c ++++ b/ldap/servers/plugins/replication/repl5_protocol_util.c +@@ -374,13 +374,13 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv) + "has the same Replica ID as this one. " + "Replication is aborting.\n", + agmt_get_long_name(prp->agmt)); +- agmt_set_last_update_status(prp->agmt, 0, 0, +- "Unable to aquire replica: the replica has the same " ++ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_REPLICAID_ERROR, ++ "Unable to acquire replica: the replica has the same " + "Replica ID as this one. Replication is aborting."); + return_value = ACQUIRE_FATAL_ERROR; + break; + case NSDS50_REPL_BACKOFF: +- /* A replication sesssion hook on the replica ++ /* A replication session hook on the replica + * wants us to go into backoff mode. */ + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "acquire_replica - " +@@ -487,9 +487,8 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv) + "%s: Unable to obtain current CSN. " + "Replication is aborting.\n", + agmt_get_long_name(prp->agmt)); +- agmt_set_last_update_status(prp->agmt, 0, 0, +- "Unable to obtain current CSN. " +- "Replication is aborting."); ++ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_INTERNAL_ERROR, ++ "Unable to obtain current CSN. Replication is aborting."); + return_value = ACQUIRE_FATAL_ERROR; + } + } +@@ -665,6 +664,8 @@ protocol_response2string(int response) + return "transient warning"; + case NSDS50_REPL_RUV_ERROR: + return "RUV error"; ++ case NSDS50_REPL_REPLICA_NO_RESPONSE: ++ return "no response received"; + default: + return "unknown error"; + } +-- +2.21.0 + diff --git a/SOURCES/0001-Issue-49875-Move-SystemD-service-config-to-a-drop-in.patch b/SOURCES/0001-Issue-49875-Move-SystemD-service-config-to-a-drop-in.patch new file mode 100644 index 0000000..5664290 --- /dev/null +++ b/SOURCES/0001-Issue-49875-Move-SystemD-service-config-to-a-drop-in.patch @@ -0,0 +1,336 @@ +From 5b36c591ef0e79ee1fd4a0db4644d9d0e8d183ca Mon Sep 17 00:00:00 2001 +From: Matus Honek +Date: Mon, 27 May 2019 10:59:03 +0000 +Subject: [PATCH] Issue 49875 - Move SystemD service config to a drop-in file + +Bug Description: +Runtime configuration options are mixed into the service specification +which should seldom be changed by users. + +Fix Description: +Move the runtime configuration options into a drop-in file. These options +are then automatically pulled in by SystemD. + +Additional Info: +Erasing the default values of the mentioned options to implicitly pull in +system defaults which are more sane nowadays. + +The .service file is now common for xsan and non-xsan builds, the former +differring only by an additional drop-in file. + +Related https://pagure.io/389-ds-base/issue/49875 + +Author: Matus Honek + +Review by: firstyear, mreynolds, vashirov (thanks!) +--- + Makefile.am | 23 ++++-- + configure.ac | 2 + + .../systemd.template.service.custom.conf.in | 52 +++++++++++++ + wrappers/systemd.template.service.in | 57 +------------- + .../systemd.template.service.xsan.conf.in | 11 +++ + wrappers/systemd.template.xsan.service.in | 77 ------------------- + 6 files changed, 85 insertions(+), 137 deletions(-) + create mode 100644 wrappers/systemd.template.service.custom.conf.in + create mode 100644 wrappers/systemd.template.service.xsan.conf.in + delete mode 100644 wrappers/systemd.template.xsan.service.in + +diff --git a/Makefile.am b/Makefile.am +index 01ac3a04d..de9e0c460 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -300,6 +300,7 @@ serverdir = $(libdir)/@serverdir@ + serverplugindir = $(libdir)@serverplugindir@ + taskdir = $(datadir)@scripttemplatedir@ + systemdsystemunitdir = @with_systemdsystemunitdir@ ++systemdsystemunitdropindir = @with_systemdsystemunitdir@/$(PACKAGE_NAME)@.service.d + systemdsystemconfdir = @with_systemdsystemconfdir@ + systemdgroupname = @with_systemdgroupname@ + initdir = @initdir@ +@@ -880,6 +881,11 @@ if SYSTEMD + systemdsystemunit_DATA = wrappers/$(PACKAGE_NAME)@.service \ + wrappers/$(systemdgroupname) \ + wrappers/$(PACKAGE_NAME)-snmp.service ++ ++systemdsystemunitdropin_DATA = wrappers/$(PACKAGE_NAME)@.service.d/custom.conf ++if with_sanitizer ++systemdsystemunitdropin_DATA += wrappers/$(PACKAGE_NAME)@.service.d/xsan.conf ++endif + else + if INITDDIR + init_SCRIPTS = wrappers/$(PACKAGE_NAME) \ +@@ -2314,12 +2320,17 @@ endif + # yes, that is an @ in the filename . . . + %/$(PACKAGE_NAME)@.service: %/systemd.template.service.in + if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi +- if [ ! -z ${SANITIZER} ] ; then \ +- service_template=$(shell echo $^ | sed 's/template/template.xsan/g'); \ +- else \ +- service_template=$^; \ +- fi; \ +- $(fixupcmd) $$service_template > $@ ++ $(fixupcmd) $^ > $@ ++ ++%/$(PACKAGE_NAME)@.service.d/custom.conf: %/systemd.template.service.custom.conf.in ++ if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi ++ $(fixupcmd) $^ > $@ ++ ++if with_sanitizer ++%/$(PACKAGE_NAME)@.service.d/xsan.conf: %/systemd.template.service.xsan.conf.in ++ if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi ++ $(fixupcmd) $^ > $@ ++endif + + %/$(systemdgroupname): %/systemd.group.in + if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi +diff --git a/configure.ac b/configure.ac +index 3660e6816..d329e84a9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -196,6 +196,8 @@ AC_SUBST([ubsan_cflags]) + AC_SUBST([ubsan_rust_defs]) + AM_CONDITIONAL(enable_ubsan,test "$enable_ubsan" = "yes") + ++AM_CONDITIONAL(with_sanitizer,test "$enable_asan" = "yes" -o "$enable_msan" = "yes" -o "$enable_tsan" = "yes" -o "$enable_ubsan" = "yes") ++ + # Enable CLANG + AC_MSG_CHECKING(for --enable-clang) + AC_ARG_ENABLE(clang, AS_HELP_STRING([--enable-clang], [Enable clang (default: no)]), +diff --git a/wrappers/systemd.template.service.custom.conf.in b/wrappers/systemd.template.service.custom.conf.in +new file mode 100644 +index 000000000..0dce62826 +--- /dev/null ++++ b/wrappers/systemd.template.service.custom.conf.in +@@ -0,0 +1,52 @@ ++# To change any of the below values, please use a drop-in file in which ++# you can declare overrides according to systemd.unit(5), either of: ++# - applying to all instances: ++# /etc/systemd/system/dirsrv@.service.d/custom.conf ++# - applying to a single instance (overriding the above): ++# /etc/systemd/system/dirsrv@.service.d/custom.conf ++# ++# Some of the most interesting coniguration options are mentioned below. ++# See systemd.service(5) and systemd.exec(5) for the respective documentation. ++# ++# After updating the service configuration, do not forget to apply the changes: ++# - reload systemd configuration: systemctl daemon-reload ++# - restart the service: systemctl restart @package_name@@.service ++ ++[Service] ++TimeoutStartSec=0 ++TimeoutStopSec=600 ++ ++# These are from man systemd.exec and man systemd.resource-control ++ ++# This controls the resources to the direct child of systemd, in ++# this case ns-slapd. Because we are type notify we recieve these ++# limits correctly. ++ ++# This controls the number of file handles avaliable. File handles ++# correlate to sockets for the process, and our access to logs and ++# databases. Note, the configuration setting in Directory Server, ++# "nsslapd-maxdescriptors", can override this limit. ++#LimitNOFILE= ++ ++# You can limit the memory in the cgroup with these, and ns-slapd ++# will account for them in it's autotuning. ++# Memory account may be controlled by DefaultMemoryAccounting= in systemd-system.conf ++#MemoryAccounting=yes ++#MemoryLimit= ++ ++# Limits on the size of coredump that may be produced by the process. It's not ++# specified how this interacts with coredumpd. ++# 0 means not to produce cores. ++#LimitCORE= ++ ++# Limit number of processes (threads) we may spawn. We don't advise you change ++# this as DS will autodetect your threads / cpus and adjust as needed. ++#LimitNPROC= ++ ++# Possible hardening options: ++#PrivateDevices=yes ++#ProtectSystem=yes ++#ProtectHome=yes ++#PrivateTmp=yes ++ ++ +diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in +index 7142c3492..2ac6f978f 100644 +--- a/wrappers/systemd.template.service.in ++++ b/wrappers/systemd.template.service.in +@@ -1,17 +1,6 @@ +-# you usually do not want to edit this file - instead, edit the +-# @initconfigdir@/@package_name@.systemd file instead - otherwise, +-# do not edit this file in /lib/systemd/system - instead, do the following: +-# cp /lib/systemd/system/dirsrv\@.service /etc/systemd/system/dirsrv\@.service +-# mkdir -p /etc/systemd/system/@systemdgroupname@.wants +-# edit /etc/systemd/system/dirsrv\@.service - uncomment the LimitNOFILE=8192 line +-# where %i is the name of the instance +-# you may already have a symlink in +-# /etc/systemd/system/@systemdgroupname@.wants/dirsrv@%i.service pointing to +-# /lib/systemd/system/dirsrv\@.service - you will have to change it to link +-# to /etc/systemd/system/dirsrv\@.service instead +-# ln -s /etc/systemd/system/dirsrv\@.service /etc/systemd/system/@systemdgroupname@.wants/dirsrv@%i.service +-# systemctl daemon-reload +-# systemctl (re)start @systemdgroupname@ ++# You should not need to edit this file. Instead, use a drop-in file as described in: ++# /usr/lib/systemd/system/@package_name@@.service.d/custom.conf ++ + [Unit] + Description=@capbrand@ Directory Server %i. + PartOf=@systemdgroupname@ +@@ -21,51 +10,11 @@ Before=radiusd.service + [Service] + Type=notify + NotifyAccess=all +-TimeoutStartSec=0 +-TimeoutStopSec=600 + EnvironmentFile=-@initconfigdir@/@package_name@ + EnvironmentFile=-@initconfigdir@/@package_name@-%i + PIDFile=@localstatedir@/run/@package_name@/slapd-%i.pid + ExecStartPre=@libexecdir@/ds_systemd_ask_password_acl @instconfigdir@/slapd-%i/dse.ldif + ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/@package_name@/slapd-%i.pid + +-#### To change any of these values or directives, you should use a drop in file +-# such as: /etc/systemd/system/dirsrv@.d/custom.conf +- +-# These are from man systemd.exec and man systemd.resource-control +- +-# This controls the resources to the direct child of systemd, in +-# this case ns-slapd. Because we are type notify we recieve these +-# limits correctly. +- +-# This controls the number of file handles avaliable. File handles +-# correlate to sockets for the process, and our access to logs and +-# databases. Note, the configuration setting in Directory Server, +-# "nsslapd-maxdescriptors", can override this limit. +-LimitNOFILE=16384 +- +-# You can limit the memory in the cgroup with these, and ns-slapd +-# will account for them in it's autotuning. +-# Memory account may be controlled by DefaultMemoryAccounting= in systemd-system.conf +-# MemoryAccounting=true +-# MemoryLimit=bytes +- +-# Limits on the size of coredump that may be produced by the process. It's not +-# specified how this interacts with coredumpd. +-# 0 means not to produce cores. +-# This value is 64G +-LimitCORE=68719476736 +- +-# Limit number of processes (threads) we may spawn. We don't advise you change +-# this as DS will autodetect your threads / cpus and adjust as needed. +-# LimitNPROC= +- +-# Hardening options: +-# PrivateDevices=true +-# ProtectSystem=true +-# ProtectHome=true +-# PrivateTmp=true +- + [Install] + WantedBy=multi-user.target +- +diff --git a/wrappers/systemd.template.service.xsan.conf.in b/wrappers/systemd.template.service.xsan.conf.in +new file mode 100644 +index 000000000..f4bf809b9 +--- /dev/null ++++ b/wrappers/systemd.template.service.xsan.conf.in +@@ -0,0 +1,11 @@ ++# This file is present because the server has been built with a sanitizer. ++# It is not meant for a production usage. ++[Unit] ++Description=@capbrand@ Directory Server with @SANITIZER@ %i. ++ ++[Service] ++# We can't symbolize here, as llvm symbolize crashes when it goes near systemd. ++Environment=ASAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.asan:print_stacktrace=1 ++Environment=TSAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.tsan:print_stacktrace=1:second_deadlock_stack=1:history_size=7 ++Environment=MSAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.msan:print_stacktrace=1 ++Environment=UBSAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.ubsan:print_stacktrace=1 +diff --git a/wrappers/systemd.template.xsan.service.in b/wrappers/systemd.template.xsan.service.in +deleted file mode 100644 +index 541392ff8..000000000 +--- a/wrappers/systemd.template.xsan.service.in ++++ /dev/null +@@ -1,77 +0,0 @@ +-# you usually do not want to edit this file - instead, edit the +-# @initconfigdir@/@package_name@.systemd file instead - otherwise, +-# do not edit this file in /lib/systemd/system - instead, do the following: +-# cp /lib/systemd/system/dirsrv\@.service /etc/systemd/system/dirsrv\@.service +-# mkdir -p /etc/systemd/system/@systemdgroupname@.wants +-# edit /etc/systemd/system/dirsrv\@.service - uncomment the LimitNOFILE=8192 line +-# where %i is the name of the instance +-# you may already have a symlink in +-# /etc/systemd/system/@systemdgroupname@.wants/dirsrv@%i.service pointing to +-# /lib/systemd/system/dirsrv\@.service - you will have to change it to link +-# to /etc/systemd/system/dirsrv\@.service instead +-# ln -s /etc/systemd/system/dirsrv\@.service /etc/systemd/system/@systemdgroupname@.wants/dirsrv@%i.service +-# systemctl daemon-reload +-# systemctl (re)start @systemdgroupname@ +-[Unit] +-Description=@capbrand@ Directory Server with @SANITIZER@ %i. +-PartOf=@systemdgroupname@ +-After=chronyd.service ntpd.service network-online.target syslog.target +-Before=radiusd.service +- +-[Service] +-Type=notify +-NotifyAccess=all +-TimeoutStartSec=0 +-TimeoutStopSec=600 +-EnvironmentFile=@initconfigdir@/@package_name@ +-EnvironmentFile=@initconfigdir@/@package_name@-%i +-PIDFile=@localstatedir@/run/@package_name@/slapd-%i.pid +-# We can't symbolize here, as llvm symbolize crashes when it goes near systemd. +-Environment=ASAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.asan:print_stacktrace=1 +-Environment=TSAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.tsan:print_stacktrace=1:second_deadlock_stack=1:history_size=7 +-Environment=MSAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.msan:print_stacktrace=1 +-Environment=UBSAN_OPTIONS=log_path=@localstatedir@/run/@package_name@/ns-slapd-%i.ubsan:print_stacktrace=1 +-LimitCORE=infinity +-ExecStartPre=@libexecdir@/ds_systemd_ask_password_acl @instconfigdir@/slapd-%i/dse.ldif +-ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/@package_name@/slapd-%i.pid +- +-#### To change any of these values or directives, you should use a drop in file +-# such as: /etc/systemd/system/dirsrv@.d/custom.conf +- +-# These are from man systemd.exec and man systemd.resource-control +- +-# This controls the resources to the direct child of systemd, in +-# this case ns-slapd. Because we are type notify we recieve these +-# limits correctly. +- +-# This controls the number of file handles avaliable. File handles +-# correlate to sockets for the process, and our access to logs and +-# databases. +-LimitNOFILE=16384 +- +-# You can limit the memory in the cgroup with these, and ns-slapd +-# will account for them in it's autotuning. +-# Memory account may be controlled by DefaultMemoryAccounting= in systemd-system.conf +-# MemoryAccounting=true +-# MemoryLimit=bytes +- +-# Limits on the size of coredump that may be produced by the process. It's not +-# specified how this interacts with coredumpd. +-# 0 means not to produce cores. +-# This value is 64G +-LimitCORE=68719476736 +- +-# Limit number of processes (threads) we may spawn. We don't advise you change +-# this as DS will autodetect your threads / cpus and adjust as needed. +-# LimitNPROC= +- +-# Hardening options: +-# PrivateDevices=true +-# ProtectSystem=true +-# ProtectHome=true +-# PrivateTmp=true +- +- +-[Install] +-WantedBy=multi-user.target +- +-- +2.21.0 + diff --git a/SOURCES/0002-Ticket-50355-NSS-can-change-the-requested-SSL-min-an.patch b/SOURCES/0002-Ticket-50355-NSS-can-change-the-requested-SSL-min-an.patch new file mode 100644 index 0000000..3196f08 --- /dev/null +++ b/SOURCES/0002-Ticket-50355-NSS-can-change-the-requested-SSL-min-an.patch @@ -0,0 +1,174 @@ +From 9208a7d1a9869a963c29d11def4a31a85eeaeeec Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 14 May 2019 16:58:55 -0400 +Subject: [PATCH] Ticket 50355 - NSS can change the requested SSL min and max + versions + +Description: If we try and set a min and max SSL version in the server, + it is actually only a request. After setting the min and + max, you need to retrieve the min and max to see what NSS + did. Then you have to reset the min and max versions one + more time to actually set the valid range. So yes, you do + have to do a set() -> get() -> set(). + + There also another outstanding issue with NSS where it says + the default max SSL version in FIPS mode is 1.3, but in fact + it is 1.2. So this patch has a hack fix to workaround that + bug. It should be able to be removed soon... + +https://pagure.io/389-ds-base/issue/50355 + +Reviewed by: mhonek(Thanks!) +--- + ldap/servers/slapd/ssl.c | 95 ++++++++++++++++++++++++---------------- + 1 file changed, 57 insertions(+), 38 deletions(-) + +diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c +index a7c3ab7b1..2d7bc2bd6 100644 +--- a/ldap/servers/slapd/ssl.c ++++ b/ldap/servers/slapd/ssl.c +@@ -41,15 +41,15 @@ + * 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 ++ * nsTLS1: on -- nsTLS1 == SSL_LIBRARY_VERSION_TLS_1_2 and greater + * Note: TLS1.0 is defined in RFC2246, which is close to SSL 3.0. + * New SSL version attributes: +- * sslVersionMin: TLS1.0 ++ * sslVersionMin: TLS1.2 + * sslVersionMax: max ssl version supported by NSS + ******************************************************************************/ + +-#define DEFVERSION "TLS1.0" +-#define CURRENT_DEFAULT_SSL_VERSION SSL_LIBRARY_VERSION_TLS_1_0 ++#define DEFVERSION "TLS1.2" ++#define CURRENT_DEFAULT_SSL_VERSION SSL_LIBRARY_VERSION_TLS_1_2 + + extern char *slapd_SSL3ciphers; + extern symbol_t supported_ciphers[]; +@@ -435,8 +435,13 @@ getSSLVersionRange(char **min, char **max) + return -1; + } + if (!slapd_ssl_listener_is_initialized()) { ++ /* ++ * We have not initialized NSS yet, so we will set the default for ++ * now. Then it will get adjusted to NSS's default min and max once ++ * we complete the security initialization in slapd_ssl_init2() ++ */ + if (min) { +- *min = slapi_getSSLVersion_str(LDAP_OPT_X_TLS_PROTOCOL_TLS1_0, NULL, 0); ++ *min = slapi_getSSLVersion_str(LDAP_OPT_X_TLS_PROTOCOL_TLS1_2, NULL, 0); + } + if (max) { + *max = slapi_getSSLVersion_str(LDAP_OPT_X_TLS_PROTOCOL_TLS1_2, NULL, 0); +@@ -457,7 +462,7 @@ getSSLVersionRangeOL(int *min, int *max) + { + /* default range values */ + if (min) { +- *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; ++ *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; + } + if (max) { + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; +@@ -2099,43 +2104,57 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) + } + } + +- if (NSSVersionMin > 0) { +- /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */ +- 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_err(SLAPI_LOG_INFO, "Security Initialization", +- "slapd_ssl_init2 - Configured SSL version range: min: %s, max: %s\n", +- mymin, mymax); ++ /* Handle the SSL version range */ ++ 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_err(SLAPI_LOG_INFO, "Security Initialization", ++ "slapd_ssl_init2 - Configured SSL version range: min: %s, max: %s\n", ++ mymin, mymax); ++ sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions); ++ if (sslStatus != SECSuccess) { ++ errorCode = PR_GetError(); ++ slapd_SSL_error("Security Initialization - " ++ "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)\n", ++ mymin, mymax, errorCode, slapd_pr_strerror(errorCode)); ++ } ++ /* ++ * Get the version range as NSS might have adjusted our requested range. FIPS mode is ++ * pretty picky about this stuff. ++ */ ++ sslStatus = SSL_VersionRangeGet(pr_sock, &slapdNSSVersions); ++ if (sslStatus == SECSuccess) { ++ if (slapdNSSVersions.max > LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 && slapd_pk11_isFIPS()) { ++ /* ++ * FIPS & NSS currently only support a max version of TLS1.2 ++ * (although NSS advertises 1.3 as a max range in FIPS mode), ++ * hopefully this code block can be removed soon... ++ */ ++ slapdNSSVersions.max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; ++ } ++ /* Reset request range */ + sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions); + if (sslStatus == SECSuccess) { +- /* Set the restricted value to the cn=encryption entry */ ++ (void)slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin)); ++ (void)slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax)); ++ slapi_log_err(SLAPI_LOG_INFO, "Security Initialization", ++ "slapd_ssl_init2 - NSS adjusted SSL version range: min: %s, max: %s\n", ++ mymin, mymax); + } else { ++ errorCode = PR_GetError(); ++ (void)slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin)); ++ (void)slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax)); + slapd_SSL_error("Security Initialization - " +- "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s\n", +- mymin, mymax); ++ "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)\n", ++ mymin, mymax, errorCode, slapd_pr_strerror(errorCode)); + } + } else { +- /* deprecated code */ +- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3); +- if (sslStatus != SECSuccess) { +- errorCode = PR_GetError(); +- slapd_SSL_warn("Failed to %s SSLv3 " +- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", +- enableSSL3 ? "enable" : "disable", +- errorCode, slapd_pr_strerror(errorCode)); +- } +- +- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1); +- if (sslStatus != SECSuccess) { +- errorCode = PR_GetError(); +- slapd_SSL_warn("Failed to %s TLSv1 " +- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", +- enableTLS1 ? "enable" : "disable", +- errorCode, slapd_pr_strerror(errorCode)); +- } ++ errorCode = PR_GetError(); ++ slapd_SSL_error("Security Initialization - ", ++ "slapd_ssl_init2 - Failed to get SSL range from socket - error %d (%s)\n", ++ errorCode, slapd_pr_strerror(errorCode)); + } + + val = NULL; +@@ -2221,7 +2240,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS) + * that matters. */ + + if (!startTLS) +- _ssl_listener_initialized = 1; /* --ugaston */ ++ _ssl_listener_initialized = 1; + + return 0; + } +-- +2.21.0 + diff --git a/SOURCES/0003-Ticket-49361-Use-IPv6-friendly-network-functions.patch b/SOURCES/0003-Ticket-49361-Use-IPv6-friendly-network-functions.patch new file mode 100644 index 0000000..5af8d83 --- /dev/null +++ b/SOURCES/0003-Ticket-49361-Use-IPv6-friendly-network-functions.patch @@ -0,0 +1,1002 @@ +From a652ff67c89888a61ce3da7cc55c45fb1f63cf7f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 30 May 2019 16:52:58 -0400 +Subject: [PATCH] Ticket 49361 - Use IPv6 friendly network functions + +Description: We use these functions that are not reliable with IPv6: + + - gethostbyname() + - inet_ntoa() + - inet_aton() + - inet_addr() + + This patch replaces these calls using one of the following + preferred functions: + + - inet_ntop() + - inet_pton() + + Also fixed a few failures in the replication CI test + regression_test.py as replication uses code touched by this + patch. + +ASAN approved + +https://pagure.io/389-ds-base/issue/49361 + +Reviewed by: firstyear(Thanks!) +--- + Makefile.am | 2 - + configure.ac | 2 +- + .../suites/replication/regression_test.py | 53 ++++--- + include/base/util.h | 3 - + ldap/include/portable.h | 50 ------ + ldap/servers/slapd/connection.c | 70 +++++---- + ldap/servers/slapd/localhost.c | 61 ++++---- + ldap/servers/slapd/tools/ldclt/repcheck.c | 30 +++- + ldap/servers/slapd/tools/ldclt/repslave.c | 25 ++- + lib/base/dns.cpp | 142 ------------------ + lib/base/net.cpp | 66 -------- + 11 files changed, 134 insertions(+), 370 deletions(-) + delete mode 100644 lib/base/dns.cpp + delete mode 100644 lib/base/net.cpp + +diff --git a/Makefile.am b/Makefile.am +index de9e0c460..c23686ea3 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1260,12 +1260,10 @@ libns_dshttpd_la_SOURCES = lib/libaccess/access_plhash.cpp \ + lib/libadmin/template.c \ + lib/libadmin/util.c \ + lib/base/crit.cpp \ +- lib/base/dns.cpp \ + lib/base/dnsdmain.cpp \ + lib/base/ereport.cpp \ + lib/base/file.cpp \ + lib/base/fsmutex.cpp \ +- lib/base/net.cpp \ + lib/base/nscperror.c \ + lib/base/plist.cpp \ + lib/base/pool.cpp \ +diff --git a/configure.ac b/configure.ac +index d329e84a9..0cc36fabe 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -76,7 +76,7 @@ AC_FUNC_STAT + AC_FUNC_STRERROR_R + AC_FUNC_STRFTIME + AC_FUNC_VPRINTF +-AC_CHECK_FUNCS([endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset]) ++AC_CHECK_FUNCS([endpwent ftruncate getcwd getaddrinfo inet_pton inet_ntop localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset]) + + # These functions are *required* without option. + AC_CHECK_FUNCS([clock_gettime], [], AC_MSG_ERROR([unable to locate required symbol clock_gettime])) +diff --git a/dirsrvtests/tests/suites/replication/regression_test.py b/dirsrvtests/tests/suites/replication/regression_test.py +index cf34a1a6a..830ef63ab 100644 +--- a/dirsrvtests/tests/suites/replication/regression_test.py ++++ b/dirsrvtests/tests/suites/replication/regression_test.py +@@ -13,11 +13,9 @@ from lib389.idm.user import TEST_USER_PROPERTIES, UserAccounts + from lib389.utils import * + from lib389.topologies import topology_m2 as topo_m2, TopologyMain, topology_m3 as topo_m3, create_topology, _remove_ssca_db + from lib389._constants import * +-from . import get_repl_entries + from lib389.idm.organizationalunit import OrganizationalUnits + from lib389.agreement import Agreements + from lib389.idm.user import UserAccount +-from lib389 import Entry + from lib389.idm.group import Groups, Group + from lib389.replica import Replicas, ReplicationManager + from lib389.changelog import Changelog5 +@@ -40,6 +38,7 @@ else: + logging.getLogger(__name__).setLevel(logging.INFO) + log = logging.getLogger(__name__) + ++ + def find_start_location(file, no): + log_pattern = re.compile("slapd_daemon - slapd started.") + count = 0 +@@ -59,7 +58,7 @@ def find_start_location(file, no): + def pattern_errorlog(file, log_pattern, start_location=0): + + count = 0 +- log.debug("_pattern_errorlog: start from the beginning" ) ++ log.debug("_pattern_errorlog: start from the beginning") + file.seek(start_location) + + # Use a while true iteration because 'for line in file: hit a +@@ -76,6 +75,7 @@ def pattern_errorlog(file, log_pattern, start_location=0): + log.debug("_pattern_errorlog: complete (count=%d)" % count) + return count + ++ + def _move_ruv(ldif_file): + """ Move RUV entry in an ldif file to the top""" + +@@ -108,16 +108,13 @@ def topo_with_sigkill(request): + subprocess.Popen(cmd, stdout=subprocess.PIPE) + + def fin(): ++ # Kill the hanging process at the end of test to prevent failures in the following tests + if DEBUGGING: +- # Kill the hanging process at the end of test to prevent failures in the following tests + [_kill_ns_slapd(inst) for inst in topology] +- #[inst.stop() for inst in topology] + else: +- # Kill the hanging process at the end of test to prevent failures in the following tests + [_kill_ns_slapd(inst) for inst in topology] + assert _remove_ssca_db(topology) + [inst.delete() for inst in topology if inst.exists()] +- + request.addfinalizer(fin) + + return topology +@@ -167,6 +164,7 @@ def test_double_delete(topo_m2, create_entry): + repl.test_replication(m1, m2) + repl.test_replication(m2, m1) + ++ + @pytest.mark.bz1506831 + def test_repl_modrdn(topo_m2): + """Test that replicated MODRDN does not break replication +@@ -228,10 +226,10 @@ def test_repl_modrdn(topo_m2): + topo_m2.pause_all_replicas() + + log.info("Apply modrdn to M1 - move test user from OU A -> C") +- master1.rename_s(tuser_A.dn,'uid=testuser1',newsuperior=OU_C.dn,delold=1) ++ master1.rename_s(tuser_A.dn, 'uid=testuser1', newsuperior=OU_C.dn, delold=1) + + log.info("Apply modrdn on M2 - move test user from OU B -> C") +- master2.rename_s(tuser_B.dn,'uid=testuser1',newsuperior=OU_C.dn,delold=1) ++ master2.rename_s(tuser_B.dn, 'uid=testuser1', newsuperior=OU_C.dn, delold=1) + + log.info("Start Replication") + topo_m2.resume_all_replicas() +@@ -252,7 +250,6 @@ def test_repl_modrdn(topo_m2): + repl.test_replication(master2, master1) + + +- + def test_password_repl_error(topo_m2, create_entry): + """Check that error about userpassword replication is properly logged + +@@ -329,7 +326,7 @@ def test_invalid_agmt(topo_m2): + 'cn': 'whatever', + 'nsDS5ReplicaRoot': DEFAULT_SUFFIX, + 'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config', +- 'nsDS5ReplicaBindMethod': 'simple' , ++ 'nsDS5ReplicaBindMethod': 'simple', + 'nsDS5ReplicaTransportInfo': 'LDAP', + 'nsds5replicaTimeout': '5', + 'description': "test agreement", +@@ -344,6 +341,7 @@ def test_invalid_agmt(topo_m2): + repl.test_replication(m1, m2) + repl.test_replication(m2, m1) + ++ + def test_fetch_bindDnGroup(topo_m2): + """Check the bindDNGroup is fetched on first replication session + +@@ -380,13 +378,13 @@ def test_fetch_bindDnGroup(topo_m2): + M2 = topo_m2.ms['master2'] + + # Enable replication log level. Not really necessary +- M1.modify_s('cn=config',[(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) +- M2.modify_s('cn=config',[(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) ++ M1.modify_s('cn=config', [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) ++ M2.modify_s('cn=config', [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) + + # Create a group and a user + PEOPLE = "ou=People,%s" % SUFFIX + PASSWD = 'password' +- REPL_MGR_BOUND_DN='repl_mgr_bound_dn' ++ REPL_MGR_BOUND_DN = 'repl_mgr_bound_dn' + + uid = REPL_MGR_BOUND_DN.encode() + users = UserAccounts(M1, PEOPLE, rdn=None) +@@ -396,14 +394,12 @@ def test_fetch_bindDnGroup(topo_m2): + + groups_M1 = Groups(M1, DEFAULT_SUFFIX) + group_properties = { +- 'cn' : 'group1', +- 'description' : 'testgroup'} ++ 'cn': 'group1', ++ 'description': 'testgroup'} + group_M1 = groups_M1.create(properties=group_properties) + group_M2 = Group(M2, group_M1.dn) + assert(not group_M1.is_member(create_user.dn)) + +- +- + # Check that M1 and M2 are in sync + repl = ReplicationManager(DEFAULT_SUFFIX) + repl.wait_for_replication(M1, M2, timeout=20) +@@ -414,13 +410,11 @@ def test_fetch_bindDnGroup(topo_m2): + replica.apply_mods([(ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroupCheckInterval', '60'), + (ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroup', group_M1.dn)]) + +- + replicas = Replicas(M2) + replica = replicas.list()[0] + replica.apply_mods([(ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroupCheckInterval', '60'), + (ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroup', group_M1.dn)]) + +- + # Then pause the replication agreement to prevent them trying to acquire + # while the user is not member of the group + topo_m2.pause_all_replicas() +@@ -432,7 +426,6 @@ def test_fetch_bindDnGroup(topo_m2): + agmt.replace('nsDS5ReplicaBindDN', create_user.dn.encode()) + agmt.replace('nsds5ReplicaCredentials', PASSWD.encode()) + +- + # Key step + # The restart will fetch the group/members define in the replica + # +@@ -451,8 +444,8 @@ def test_fetch_bindDnGroup(topo_m2): + topo_m2.resume_all_replicas() + + # trigger updates to be sure to have a replication session, giving some time +- M1.modify_s(create_user.dn,[(ldap.MOD_ADD, 'description', b'value_1_1')]) +- M2.modify_s(create_user.dn,[(ldap.MOD_ADD, 'description', b'value_2_2')]) ++ M1.modify_s(create_user.dn, [(ldap.MOD_ADD, 'description', b'value_1_1')]) ++ M2.modify_s(create_user.dn, [(ldap.MOD_ADD, 'description', b'value_2_2')]) + time.sleep(10) + + # Check replication is working +@@ -494,12 +487,13 @@ def test_fetch_bindDnGroup(topo_m2): + count = pattern_errorlog(errorlog_M1, regex, start_location=restart_location_M1) + assert(count <= 1) + count = pattern_errorlog(errorlog_M2, regex, start_location=restart_location_M2) +- assert(count <=1) ++ assert(count <= 1) + + if DEBUGGING: + # Add debugging steps(if any)... + pass + ++ + def test_cleanallruv_repl(topo_m3): + """Test that cleanallruv could not break replication if anchor csn in ruv originated in deleted replica + :id: 46faba9a-897e-45b8-98dc-aec7fa8cec9a +@@ -546,7 +540,7 @@ def test_cleanallruv_repl(topo_m3): + user_props = TEST_USER_PROPERTIES.copy() + + user_props.update({'uid': "testuser10"}) +- user10 = users_m1.create(properties=user_props) ++ user10 = users_m1.create(properties=user_props) + + user_props.update({'uid': "testuser20"}) + user20 = users_m2.create(properties=user_props) +@@ -587,7 +581,7 @@ def test_cleanallruv_repl(topo_m3): + # ClearRuv is launched but with Force + M3.stop() + M1.tasks.cleanAllRUV(suffix=SUFFIX, replicaid='3', +- force=True,args={TASK_WAIT: False}) ++ force=True, args={TASK_WAIT: False}) + + # here M1 should clear 31 + M2.start() +@@ -595,11 +589,16 @@ def test_cleanallruv_repl(topo_m3): + M1.agreement.resume(m1_m2[0].dn) + time.sleep(10) + +- #Check the users after CleanRUV ++ # Check the users after CleanRUV + expected_m1_users = [user31.dn, user11.dn, user21.dn, user32.dn, user33.dn, user12.dn] ++ expected_m1_users = [x.lower() for x in expected_m1_users] + expected_m2_users = [user31.dn, user11.dn, user21.dn, user12.dn] ++ expected_m2_users = [x.lower() for x in expected_m2_users] ++ + current_m1_users = [user.dn for user in users_m1.list()] ++ current_m1_users = [x.lower() for x in current_m1_users] + current_m2_users = [user.dn for user in users_m2.list()] ++ current_m2_users = [x.lower() for x in current_m2_users] + + assert set(expected_m1_users).issubset(current_m1_users) + assert set(expected_m2_users).issubset(current_m2_users) +diff --git a/include/base/util.h b/include/base/util.h +index 94506d5e0..8ad5ddfbb 100644 +--- a/include/base/util.h ++++ b/include/base/util.h +@@ -36,8 +36,6 @@ + + NSPR_BEGIN_EXTERN_C + +-NSAPI_PUBLIC char *INTutil_hostname(void); +- + NSAPI_PUBLIC int INTutil_itoa(int i, char *a); + + NSAPI_PUBLIC +@@ -75,7 +73,6 @@ NSAPI_PUBLIC int INTutil_strncasecmp(CASECMPARG_T char *one, CASECMPARG_T char * + + NSPR_END_EXTERN_C + +-#define util_hostname INTutil_hostname + #define util_itoa INTutil_itoa + #define util_vsprintf INTutil_vsprintf + #define util_sprintf INTutil_sprintf +diff --git a/ldap/include/portable.h b/ldap/include/portable.h +index 63cc4d461..fddc9c80e 100644 +--- a/ldap/include/portable.h ++++ b/ldap/include/portable.h +@@ -241,30 +241,9 @@ int strncasecmp(const char *, const char *, size_t); + #endif /* SNI || LINUX1_2 */ + + #if defined(_WINDOWS) || defined(macintosh) +-#define GETHOSTBYNAME(n, r, b, l, e) gethostbyname(n) + #define CTIME(c, b, l) ctime(c) + #define STRTOK(s1, s2, l) strtok(s1, s2) + #else /* UNIX */ +-#if defined(sgi) || defined(HPUX9) || defined(LINUX1_2) || defined(SCOOS) || \ +- defined(UNIXWARE) || defined(SUNOS4) || defined(SNI) || defined(BSDI) || \ +- defined(NCR) || defined(OSF1) || defined(NEC) || \ +- (defined(HPUX10) && !defined(_REENTRANT)) || defined(HPUX11) || \ +- defined(UnixWare) || defined(LINUX) || defined(__FreeBSD__) +-#define GETHOSTBYNAME(n, r, b, l, e) gethostbyname(n) +-#elif defined(AIX) +-#define GETHOSTBYNAME_BUF_T struct hostent_data +-#define GETHOSTBYNAME(n, r, b, l, e) \ +- (memset(&b, 0, l), gethostbyname_r(n, r, &b) ? NULL : r) +-#elif defined(HPUX10) +-#define GETHOSTBYNAME_BUF_T struct hostent_data +-#define GETHOSTBYNAME(n, r, b, l, e) nsldapi_compat_gethostbyname_r(n, r, (char *)&b, l, e) +-#else +-#include /* BUFSIZ */ +-typedef char GETHOSTBYNAME_buf_t[BUFSIZ /* XXX might be too small */]; +-#define GETHOSTBYNAME_BUF_T GETHOSTBYNAME_buf_t +-#define GETHOSTBYNAME(n, r, b, l, e) gethostbyname_r(n, r, b, l, e) +-#endif +- + /* + * XXXmcs: GETHOSTBYADDR() is only defined for IRIX/SGI and Solaris for now. + */ +@@ -319,35 +298,6 @@ extern char *strdup(); + #include /* for inet_addr() */ + #endif /* SOLARIS */ + +-#ifdef SUNOS4 +-#include /* for toupper() */ +-int fprintf(FILE *, char *, ...); +-int fseek(FILE *, long, int); +-int fread(char *, int, int, FILE *); +-int fclose(FILE *); +-int fflush(FILE *); +-int rewind(FILE *); +-void *memmove(void *, const void *, size_t); +-int strcasecmp(char *, char *); +-int strncasecmp(char *, char *, int); +-time_t time(time_t *); +-void perror(char *); +-int fputc(char, FILE *); +-int fputs(char *, FILE *); +-int LDAP_CALL re_exec(char *); +-int socket(int, int, int); +-void bzero(char *, int); +-unsigned long inet_addr(char *); +-char *inet_ntoa(struct in_addr); +-int getdtablesize(); +-int connect(int, struct sockaddr *, int); +-#endif /* SUNOS4 */ +- +-/* #if defined(SUNOS4) || defined(SNI) */ +-#if defined(SUNOS4) +-int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +-#endif /* SUNOS4 || SNI */ +- + /* + * SAFEMEMCPY is an overlap-safe copy from s to d of n bytes + */ +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index 1dc53434c..4a611e7f4 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -244,6 +244,28 @@ connection_cleanup(Connection *conn) + conn->c_ns_close_jobs = 0; + } + ++static char * ++get_ip_str(struct sockaddr *addr, char *str) ++{ ++ switch(addr->sa_family) { ++ case AF_INET: ++ if (sizeof(str) < INET_ADDRSTRLEN) { ++ break; ++ } ++ inet_ntop(AF_INET, &(((struct sockaddr_in *)addr)->sin_addr), str, INET_ADDRSTRLEN); ++ break; ++ ++ case AF_INET6: ++ if (sizeof(str) < INET6_ADDRSTRLEN) { ++ break; ++ } ++ inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)addr)->sin6_addr), str, INET6_ADDRSTRLEN); ++ break; ++ } ++ ++ return str; ++} ++ + /* + * Callers of connection_reset() must hold the conn->c_mutex lock. + */ +@@ -252,7 +274,8 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib + { + char *pTmp = is_SSL ? "SSL " : ""; + char *str_ip = NULL, *str_destip; +- char buf_ip[256], buf_destip[256]; ++ char buf_ip[INET6_ADDRSTRLEN + 1] = {0}; ++ char buf_destip[INET6_ADDRSTRLEN + 1] = {0}; + char *str_unknown = "unknown"; + int in_referral_mode = config_check_referral_mode(); + +@@ -288,10 +311,10 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib + (from->ipv6.ip.pr_s6_addr32[1] != 0) || + (from->ipv6.ip.pr_s6_addr32[2] != 0) || + (from->ipv6.ip.pr_s6_addr32[3] != 0)) || +- ((conn->c_prfd != NULL) && (PR_GetPeerName(conn->c_prfd, from) == 0))) { ++ ((conn->c_prfd != NULL) && (PR_GetPeerName(conn->c_prfd, from) == 0))) ++ { + conn->cin_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr)); + memcpy(conn->cin_addr, from, sizeof(PRNetAddr)); +- + if (PR_IsNetAddrType(conn->cin_addr, PR_IpAddrV4Mapped)) { + PRNetAddr v4addr = {{0}}; + v4addr.inet.family = PR_AF_INET; +@@ -305,7 +328,7 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib + } else { + /* try syscall since "from" was not given and PR_GetPeerName failed */ + /* a corner case */ +- struct sockaddr_in addr = {0}; /* assuming IPv4 */ ++ struct sockaddr addr = {0}; + #if (defined(hpux)) + int addrlen; + #else +@@ -315,23 +338,15 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib + addrlen = sizeof(addr); + + if ((conn->c_prfd == NULL) && +- (getpeername(conn->c_sd, (struct sockaddr *)&addr, &addrlen) == 0)) { ++ (getpeername(conn->c_sd, (struct sockaddr *)&addr, &addrlen) == 0)) ++ { + conn->cin_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr)); + memset(conn->cin_addr, 0, sizeof(PRNetAddr)); + PR_NetAddrFamily(conn->cin_addr) = AF_INET6; + /* note: IPv4-mapped IPv6 addr does not work on Windows */ +- PR_ConvertIPv4AddrToIPv6(addr.sin_addr.s_addr, &(conn->cin_addr->ipv6.ip)); +- PRLDAP_SET_PORT(conn->cin_addr, addr.sin_port); +- +- /* copy string equivalent of address into a buffer to use for +- * logging since each call to inet_ntoa() returns a pointer to a +- * single thread-specific buffer (which prevents us from calling +- * inet_ntoa() twice in one call to slapi_log_access()). +- */ +- str_ip = inet_ntoa(addr.sin_addr); +- strncpy(buf_ip, str_ip, sizeof(buf_ip) - 1); +- buf_ip[sizeof(buf_ip) - 1] = '\0'; +- str_ip = buf_ip; ++ PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)&addr)->sin_addr.s_addr, &(conn->cin_addr->ipv6.ip)); ++ PRLDAP_SET_PORT(conn->cin_addr, ((struct sockaddr_in *)&addr)->sin_port); ++ str_ip = get_ip_str(&addr, buf_ip); + } else { + str_ip = str_unknown; + } +@@ -367,38 +382,27 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib + } else { + /* try syscall since c_prfd == NULL */ + /* a corner case */ +- struct sockaddr_in destaddr = {0}; /* assuming IPv4 */ ++ struct sockaddr destaddr = {0}; /* assuming IPv4 */ + #if (defined(hpux)) + int destaddrlen; + #else + socklen_t destaddrlen; + #endif +- + destaddrlen = sizeof(destaddr); + +- if ((getsockname(conn->c_sd, (struct sockaddr *)&destaddr, &destaddrlen) == 0)) { ++ if ((getsockname(conn->c_sd, &destaddr, &destaddrlen) == 0)) { + conn->cin_destaddr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr)); + memset(conn->cin_destaddr, 0, sizeof(PRNetAddr)); + PR_NetAddrFamily(conn->cin_destaddr) = AF_INET6; +- PRLDAP_SET_PORT(conn->cin_destaddr, destaddr.sin_port); ++ PRLDAP_SET_PORT(conn->cin_destaddr, ((struct sockaddr_in *)&destaddr)->sin_port); + /* note: IPv4-mapped IPv6 addr does not work on Windows */ +- PR_ConvertIPv4AddrToIPv6(destaddr.sin_addr.s_addr, &(conn->cin_destaddr->ipv6.ip)); +- +- /* copy string equivalent of address into a buffer to use for +- * logging since each call to inet_ntoa() returns a pointer to a +- * single thread-specific buffer (which prevents us from calling +- * inet_ntoa() twice in one call to slapi_log_access()). +- */ +- str_destip = inet_ntoa(destaddr.sin_addr); +- strncpy(buf_destip, str_destip, sizeof(buf_destip) - 1); +- buf_destip[sizeof(buf_destip) - 1] = '\0'; +- str_destip = buf_destip; ++ PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)&destaddr)->sin_addr.s_addr, &(conn->cin_destaddr->ipv6.ip)); ++ str_destip = get_ip_str(&destaddr, buf_destip); + } else { + str_destip = str_unknown; + } + } + +- + if (!in_referral_mode) { + /* create a sasl connection */ + ids_sasl_server_new(conn); +diff --git a/ldap/servers/slapd/localhost.c b/ldap/servers/slapd/localhost.c +index f2aff28f4..993143cbd 100644 +--- a/ldap/servers/slapd/localhost.c ++++ b/ldap/servers/slapd/localhost.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -45,22 +46,14 @@ + static char * + find_localhost_DNS(void) + { +- /* This implementation could (and should) be entirely replaced by: +- dns_ip2host ("127.0.0.1", 1); defined in ldapserver/lib/base/dns.c +- */ + char hostname[MAXHOSTNAMELEN + 1]; +- struct hostent *hp; +-#ifdef GETHOSTBYNAME_BUF_T +- struct hostent hent; +- GETHOSTBYNAME_BUF_T hbuf; +- int err; +-#endif +- char **alias; + FILE *f; + char *cp; + char *domain; + char line[MAXHOSTNAMELEN + 8]; +- ++ int gai_result; ++ struct addrinfo hints = {0}; ++ struct addrinfo *info = NULL, *p = NULL; + if (gethostname(hostname, MAXHOSTNAMELEN)) { + int oserr = errno; + +@@ -69,32 +62,34 @@ find_localhost_DNS(void) + oserr, slapd_system_strerror(oserr)); + return NULL; + } +- hp = GETHOSTBYNAME(hostname, &hent, hbuf, sizeof(hbuf), &err); +- if (hp == NULL) { +- int oserr = errno; + +- slapi_log_err(SLAPI_LOG_ERR, +- "find_localhost_DNS - gethostbyname(\"%s\") failed, error %d (%s)\n", +- hostname, oserr, slapd_system_strerror(oserr)); +- return NULL; +- } +- if (hp->h_name == NULL) { ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_flags = AI_CANONNAME; ++ if ((gai_result = getaddrinfo(hostname, NULL, &hints, &info)) != 0) { + slapi_log_err(SLAPI_LOG_ERR, "find_localhost_DNS", +- "gethostbyname(\"%s\")->h_name == NULL\n", hostname); ++ "getaddrinfo: %s\n", gai_strerror(gai_result)); + return NULL; + } +- if (strchr(hp->h_name, '.') != NULL) { +- slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "h_name == %s\n", hp->h_name); +- return slapi_ch_strdup(hp->h_name); +- } else if (hp->h_aliases != NULL) { +- for (alias = hp->h_aliases; *alias != NULL; ++alias) { +- if (strchr(*alias, '.') != NULL && +- strncmp(*alias, hp->h_name, strlen(hp->h_name))) { +- slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "h_alias == %s\n", *alias); +- return slapi_ch_strdup(*alias); +- } ++ ++ if (strchr(info->ai_canonname, '.') != NULL) { ++ char *return_name = slapi_ch_strdup(info->ai_canonname); ++ freeaddrinfo(info); ++ slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "initial ai_canonname == %s\n", return_name); ++ return return_name; ++ } ++ for(p = info; p != NULL; p = p->ai_next) { ++ if (strchr(p->ai_canonname, '.') != NULL && ++ strncmp(p->ai_canonname, info->ai_canonname, strlen(info->ai_canonname))) ++ { ++ char *return_name = slapi_ch_strdup(p->ai_canonname); ++ freeaddrinfo(info); ++ slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "next ai_canonname == %s\n", return_name); ++ return return_name; + } + } ++ ++ + /* The following is copied from dns_guess_domain(), + in ldapserver/lib/base/dnsdmain.c */ + domain = NULL; +@@ -134,9 +129,10 @@ find_localhost_DNS(void) + } + #endif + if (domain == NULL) { ++ freeaddrinfo(info); + return NULL; + } +- PL_strncpyz(hostname, hp->h_name, sizeof(hostname)); ++ PL_strncpyz(hostname, info->ai_canonname, sizeof(hostname)); + if (domain[0] == '.') + ++domain; + if (domain[0]) { +@@ -144,6 +140,7 @@ find_localhost_DNS(void) + PL_strcatn(hostname, sizeof(hostname), domain); + } + slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "hostname == %s\n", hostname); ++ freeaddrinfo(info); + return slapi_ch_strdup(hostname); + } + +diff --git a/ldap/servers/slapd/tools/ldclt/repcheck.c b/ldap/servers/slapd/tools/ldclt/repcheck.c +index 4340055e5..05ea65a8b 100644 +--- a/ldap/servers/slapd/tools/ldclt/repcheck.c ++++ b/ldap/servers/slapd/tools/ldclt/repcheck.c +@@ -19,6 +19,10 @@ + #include "remote.h" + #include "lber.h" + #include "ldap.h" ++#include ++#include ++#include ++ + + enum + { +@@ -90,13 +94,15 @@ send_op(char *s, int sfd) + + main(int argc, char **argv) + { +- int i, port = 16000; +- int sockfd; ++ struct sockaddr_in srvsaddr; + static char logline[512]; + char **tmp; +- struct hostent *serveraddr; +- struct sockaddr_in srvsaddr; + char *p; ++ struct addrinfo hints = {0}; ++ struct addrinfo *info = NULL; ++ int gai_result = 0; ++ int i, port = 16000; ++ int sockfd; + + while ((i = getopt(argc, argv, "p:")) != EOF) { + switch (i) { +@@ -105,15 +111,25 @@ main(int argc, char **argv) + break; + } + } +- serveraddr = gethostbyname(argv[optind]); +- srvsaddr.sin_addr.s_addr = htonl(*((u_long *)(serveraddr->h_addr_list[0]))); ++ ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_flags = AI_CANONNAME; ++ if ((gai_result = getaddrinfo(argv[optind], NULL, &hints, &info)) != 0) { ++ slapi_log_err(SLAPI_LOG_ERR, "ldclt", ++ "getaddrinfo: %s\n", gai_strerror(gai_result)); ++ return NULL; ++ } ++ ++ srvsaddr.sin_addr.s_addr = htonl(*((u_long *)(info->ai_addr))); + srvsaddr.sin_family = AF_INET; + srvsaddr.sin_port = htons(port); ++ freeaddrinfo(info); + maxop = npend = 0; + pendops = (Optype *)malloc(sizeof(Optype) * 20); + sigset(SIGPIPE, SIG_IGN); + while (fgets(logline, sizeof(logline), stdin)) { +- if (p = strchr(logline, '\n')) { ++ if ((p = strchr(logline, '\n'))) { + *p = 0; + } + if (!connected) { +diff --git a/ldap/servers/slapd/tools/ldclt/repslave.c b/ldap/servers/slapd/tools/ldclt/repslave.c +index a04a73f5c..8df2a0ace 100644 +--- a/ldap/servers/slapd/tools/ldclt/repslave.c ++++ b/ldap/servers/slapd/tools/ldclt/repslave.c +@@ -62,6 +62,9 @@ dd/mm/yy | Author | Comments + #include "remote.h" + #include "lber.h" + #include "ldap.h" ++#include ++#include ++#include + + /* + * Enumeration for internal list +@@ -221,7 +224,8 @@ main(int argc, char **argv) + int sockfd, log = 0; + static char logline[512]; + char **tmp, *hn, *hp, *hf; +- struct hostent *serveraddr; ++ struct addrinfo hints = {0}; ++ struct addrinfo *info = NULL; + + while ((i = getopt(argc, argv, "tdP:s:")) != EOF) { + switch (i) { +@@ -251,12 +255,17 @@ main(int argc, char **argv) + /* + * Get master address, just the first. + */ +- if ((serveraddr = gethostbyname(hn)) == NULL) { ++ ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_flags = AI_CANONNAME; ++ if (getaddrinfo(hn, NULL, &hints, &info) != 0) { + printf("Unknown host %s\n", hn); + break; + } ++ + srvlist = (Towho *)realloc(srvlist, (nsrv + 1) * sizeof(Towho)); +- srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(serveraddr->h_addr_list[0]))); ++ srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(info->ai_addr))); + srvlist[nsrv].addr.sin_family = AF_INET; + srvlist[nsrv].addr.sin_port = htonl((hp == hf ? port : atoi(hp))); + if ((srvlist[nsrv].filter = regcmp(hf, NULL)) == NULL) +@@ -264,6 +273,7 @@ main(int argc, char **argv) + srvlist[nsrv].fd = open_cnx((struct sockaddr *)&srvlist[nsrv].addr); + srvlist[nsrv].hname = strdup(hn); + nsrv++; ++ freeaddrinfo(info); + break; + } + } +@@ -273,18 +283,19 @@ main(int argc, char **argv) + printf("\t-t\tprints input on stdout.\n\t-d\tdebug mode.\n"); + exit(1); + } +- srvlist = (Towho *)malloc(sizeof(Towho)); +- if ((serveraddr = gethostbyname(argv[optind])) == NULL) { +- printf("Unknown host %s\n", argv[optind]); ++ if (getaddrinfo(argv[optind], NULL, &hints, &info) != 0) { ++ printf("Unknown host %s\n", hn); + exit(1); + } +- srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(serveraddr->h_addr_list[0]))); ++ srvlist = (Towho *)malloc(sizeof(Towho)); ++ srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(info->ai_addr))); + srvlist[nsrv].addr.sin_family = AF_INET; + srvlist[nsrv].addr.sin_port = htons(port); + srvlist[nsrv].filter = NULL; + srvlist[nsrv].fd = open_cnx((struct sockaddr *)&srvlist[nsrv].addr); + srvlist[nsrv].hname = strdup(argv[optind]); + nsrv++; ++ freeaddrinfo(info); + } + maxop = npend = 0; + pendops = (Optype *)malloc(sizeof(Optype) * 20); +diff --git a/lib/base/dns.cpp b/lib/base/dns.cpp +deleted file mode 100644 +index e704094db..000000000 +--- a/lib/base/dns.cpp ++++ /dev/null +@@ -1,142 +0,0 @@ +-/** BEGIN COPYRIGHT BLOCK +- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2005 Red Hat, Inc. +- * All rights reserved. +- * +- * License: GPL (version 3 or any later version). +- * See LICENSE for details. +- * END COPYRIGHT BLOCK **/ +- +-#ifdef HAVE_CONFIG_H +-# include +-#endif +- +-/* +- * dns.c: DNS resolution routines +- * +- * Rob McCool +- */ +-#define DNS_GUESSING +- +-#include "netsite.h" +-#include "systems.h" +- +-/* Under NT, these are taken care of by net.h including winsock.h */ +-#include /* inet_ntoa */ +-#include /* struct hostent */ +-#ifdef NEED_GHN_PROTO +-extern "C" int gethostname (char *name, size_t namelen); +-#endif +-#include +-#include +- +-/* ---------------------------- dns_find_fqdn ----------------------------- */ +- +- +-/* defined in dnsdmain.c */ +-extern "C" NSAPI_PUBLIC char *dns_guess_domain(char * hname); +- +-char *net_find_fqdn(PRHostEnt *p) +-{ +- int x; +- +- if((!p->h_name) || (!p->h_aliases)) +- return NULL; +- +- if(!strchr(p->h_name, '.')) { +- for(x = 0; p->h_aliases[x]; ++x) { +- if((strchr(p->h_aliases[x], '.')) && +- (!strncmp(p->h_aliases[x], p->h_name, strlen(p->h_name)))) +- { +- return STRDUP(p->h_aliases[x]); +- } +- } +-#ifdef DNS_GUESSING +- return dns_guess_domain(p->h_name); +-#else +- return NULL; +-#endif /* DNS_GUESSING */ +- } +- else +- return STRDUP(p->h_name); +-} +- +- +-/* ----------------------------- dns_ip2host ------------------------------ */ +- +- +-char *dns_ip2host(char *ip, int verify) +-{ +- /* struct in_addr iaddr; */ +- PRNetAddr iaddr; +- char *hn; +- static unsigned long laddr = 0; +- static char myhostname[256]; +- PRHostEnt hent; +- char buf[PR_NETDB_BUF_SIZE]; +- PRStatus err; +- +- +- err = PR_InitializeNetAddr(PR_IpAddrNull, 0, &iaddr); +- +- /* richm: ipv6 cleanup - use inet_aton or other more appropriate function +- instead of inet_addr */ +- if((iaddr.inet.ip = inet_addr(ip)) == (in_addr_t)-1) +- goto bong; +- +- /* +- * See if it happens to be the localhost IP address, and try +- * the local host name if so. +- */ +- if (laddr == 0) { +- laddr = inet_addr("127.0.0.1"); +- myhostname[0] = 0; +- PR_GetSystemInfo(PR_SI_HOSTNAME, myhostname, sizeof(myhostname)); +- } +- +- /* Have to match the localhost IP address and have a hostname */ +- if ((iaddr.inet.ip == laddr) && (myhostname[0] != 0)) { +- /* +- * Now try for a fully-qualified domain name, starting with +- * the local hostname. +- */ +- err = PR_GetHostByName(myhostname, +- buf, +- PR_NETDB_BUF_SIZE, +- &hent); +- +- /* Don't verify if we get a fully-qualified name this way */ +- verify = 0; +- } +- else { +- err = PR_GetHostByAddr(&iaddr, +- buf, +- PR_NETDB_BUF_SIZE, +- &hent); +- } +- +- if ((err == PR_FAILURE) || !(hn = net_find_fqdn(&hent))) goto bong; +- +- +- if(verify) { +- char **haddr = 0; +- err = PR_GetHostByName(hn, +- buf, +- PR_NETDB_BUF_SIZE, +- &hent); +- +- if(err == PR_SUCCESS) { +- for(haddr = hent.h_addr_list; *haddr; haddr++) { +- if(((struct in_addr *)(*haddr))->s_addr == iaddr.inet.ip) +- break; +- } +- } +- +- if((err == PR_FAILURE) || (!(*haddr))) +- goto bong; +- } +- +- return hn; +- bong: +- return NULL; +-} +diff --git a/lib/base/net.cpp b/lib/base/net.cpp +deleted file mode 100644 +index 7227d9584..000000000 +--- a/lib/base/net.cpp ++++ /dev/null +@@ -1,66 +0,0 @@ +-/** BEGIN COPYRIGHT BLOCK +- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2005 Red Hat, Inc. +- * All rights reserved. +- * +- * License: GPL (version 3 or any later version). +- * See LICENSE for details. +- * END COPYRIGHT BLOCK **/ +- +-#ifdef HAVE_CONFIG_H +-# include +-#endif +- +-/* +- * net.c: sockets abstraction and DNS related things +- * +- * Note: sockets created with net_socket are placed in non-blocking mode, +- * however this API simulates that the calls are blocking. +- * +- * Rob McCool +- */ +- +- +-#include "netsite.h" +-#include +- +-#include "util.h" +-#include +-#include /* inet_ntoa */ +-#include /* hostent stuff */ +-#ifdef NEED_GHN_PROTO +-extern "C" int gethostname (char *name, size_t namelen); +-#endif +-#ifdef LINUX +-#include /* ioctl */ +-#endif +- +-#include "libadmin/libadmin.h" +- +-/* ---------------------------- util_hostname ----------------------------- */ +- +- +-#include +- +-/* Defined in dns.cpp */ +-char *net_find_fqdn(PRHostEnt *p); +- +-NSAPI_PUBLIC char *util_hostname(void) +-{ +- char str[MAXHOSTNAMELEN]; +- PRHostEnt hent; +- char buf[PR_NETDB_BUF_SIZE]; +- PRStatus err; +- +- gethostname(str, MAXHOSTNAMELEN); +- err = PR_GetHostByName( +- str, +- buf, +- PR_NETDB_BUF_SIZE, +- &hent); +- +- if (err == PR_FAILURE) +- return NULL; +- return net_find_fqdn(&hent); +-} +- +-- +2.21.0 + diff --git a/SOURCES/0004-Ticket-50431-Fix-covscan-warnings.patch b/SOURCES/0004-Ticket-50431-Fix-covscan-warnings.patch new file mode 100644 index 0000000..302ce9d --- /dev/null +++ b/SOURCES/0004-Ticket-50431-Fix-covscan-warnings.patch @@ -0,0 +1,1635 @@ +From 3d8e1c62134fe5e98edef167ce88f473adda722a Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 5 Jun 2019 14:09:52 -0400 +Subject: [PATCH] Ticket 50431 - Fix covscan warnings + +Description: Most coverity errors happen when something fails. + +https://pagure.io/389-ds-base/issue/50431 + +Reviewed by: firstyear & spichugi(Thanks!) +--- + autogen.sh | 8 ++- + ldap/servers/plugins/acl/acl.c | 15 ++--- + ldap/servers/plugins/acl/acleffectiverights.c | 12 ++-- + ldap/servers/plugins/acl/acllist.c | 4 +- + .../plugins/linkedattrs/linked_attrs.c | 4 +- + .../plugins/memberof/memberof_config.c | 12 +++- + .../plugins/posix-winsync/posix-winsync.c | 2 +- + ldap/servers/plugins/replication/cl5_api.c | 1 + + .../plugins/replication/repl5_replica.c | 2 +- + .../replication/repl5_replica_config.c | 8 ++- + ldap/servers/plugins/replication/urp.c | 1 + + ldap/servers/plugins/roles/roles_cache.c | 2 + + ldap/servers/plugins/views/views.c | 16 ++++-- + ldap/servers/slapd/agtmmap.c | 2 +- + ldap/servers/slapd/back-ldbm/dblayer.c | 55 ++++++++++-------- + ldap/servers/slapd/back-ldbm/index.c | 9 +-- + ldap/servers/slapd/back-ldbm/ldbm_add.c | 3 +- + .../slapd/back-ldbm/ldbm_attrcrypt_config.c | 4 +- + ldap/servers/slapd/back-ldbm/ldbm_delete.c | 3 +- + ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 4 +- + ldap/servers/slapd/back-ldbm/vlv_srch.c | 3 +- + ldap/servers/slapd/connection.c | 1 + + ldap/servers/slapd/dse.c | 7 ++- + ldap/servers/slapd/entrywsi.c | 57 ++++++++++--------- + ldap/servers/slapd/main.c | 9 +-- + ldap/servers/slapd/mapping_tree.c | 46 +++++++-------- + ldap/servers/slapd/modify.c | 6 +- + ldap/servers/slapd/opshared.c | 3 +- + ldap/servers/slapd/plugin_internal_op.c | 3 +- + ldap/servers/slapd/plugin_syntax.c | 4 +- + ldap/servers/slapd/rdn.c | 5 +- + ldap/servers/slapd/sasl_map.c | 4 +- + ldap/servers/slapd/schema.c | 6 +- + ldap/servers/slapd/search.c | 7 ++- + ldap/servers/slapd/tools/dbscan.c | 9 ++- + ldap/servers/slapd/tools/ldclt/ldapfct.c | 8 +-- + ldap/servers/slapd/tools/ldclt/ldclt.c | 2 +- + ldap/servers/slapd/tools/ldif.c | 10 +++- + ldap/servers/slapd/tools/mmldif.c | 5 +- + ldap/servers/slapd/tools/pwenc.c | 1 + + ldap/servers/slapd/tools/rsearch/infadd.c | 2 +- + ldap/servers/slapd/tools/rsearch/rsearch.c | 5 +- + lib/ldaputil/certmap.c | 15 ++--- + lib/libaccess/usrcache.cpp | 6 +- + .../389-console/src/lib/database/chaining.jsx | 2 +- + .../389-console/src/lib/database/suffix.jsx | 4 +- + src/cockpit/389-console/src/replication.js | 2 +- + src/lib389/lib389/agreement.py | 1 + + src/lib389/lib389/backend.py | 8 ++- + src/lib389/lib389/cli_conf/backend.py | 2 +- + 50 files changed, 229 insertions(+), 181 deletions(-) + +diff --git a/autogen.sh b/autogen.sh +index 8bb628b25..06a5facd1 100755 +--- a/autogen.sh ++++ b/autogen.sh +@@ -35,12 +35,16 @@ checkvers() { + vers="$1"; shift + needmaj="$1"; shift + needmin="$1"; shift +- needrev="$1"; shift ++ if [ "$#" != "0" ]; then ++ needrev="$1"; shift ++ fi + verslist=`echo $vers | tr '.' ' '` + set $verslist + maj=$1; shift + min=$1; shift +- rev=$1; shift ++ if [ "$#" != "0" ]; then ++ rev=$1; shift ++ fi + if [ "$maj" -gt "$needmaj" ] ; then return 0; fi + if [ "$maj" -lt "$needmaj" ] ; then return 1; fi + # if we got here, maj == needmaj +diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c +index 6d105f4fa..5680de669 100644 +--- a/ldap/servers/plugins/acl/acl.c ++++ b/ldap/servers/plugins/acl/acl.c +@@ -644,7 +644,8 @@ cleanup_and_ret: + if (aclpb) + aclpb->aclpb_curr_attrEval = NULL; + +- print_access_control_summary("main", ret_val, clientDn, aclpb, right, ++ print_access_control_summary("main", ret_val, clientDn, aclpb, ++ (right ? right : "NULL"), + (attr ? attr : "NULL"), n_edn, + &decision_reason); + TNF_PROBE_0_DEBUG(acl_cleanup_end, "ACL", ""); +@@ -2590,12 +2591,9 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a + * that applies to the current attribute. + * Then the (attribute,value) pair being added/deleted better + * match that filter. +- * +- * + */ +- + Targetattrfilter **attrFilterArray = NULL; +- Targetattrfilter *attrFilter; ++ Targetattrfilter *attrFilter = NULL; + int found = 0; + + if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) && +@@ -2606,15 +2604,13 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a + attrFilterArray = aci->targetAttrDelFilters; + } + +- + /* + * Scan this filter list for an applicable filter. + */ +- + found = 0; + num_attrs = 0; + +- while (attrFilterArray[num_attrs] && !found) { ++ while (attrFilterArray && attrFilterArray[num_attrs] && !found) { + attrFilter = attrFilterArray[num_attrs]; + + /* If this filter applies to the attribute, stop. */ +@@ -2630,8 +2626,7 @@ acl__resource_match_aci(Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a + * Here, if found an applicable filter, then apply the filter to the + * (attr,val) pair. + * Otherwise, ignore the targetattrfilters. +- */ +- ++ */ + if (found) { + + if (acl__make_filter_test_entry(&aclpb->aclpb_filter_test_entry, +diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c +index 8a0cb9122..5dd46a064 100644 +--- a/ldap/servers/plugins/acl/acleffectiverights.c ++++ b/ldap/servers/plugins/acl/acleffectiverights.c +@@ -869,14 +869,14 @@ _ger_generate_template_entry( + if (dntype) { + siz += strlen(dntype) + 30 + strlen(object) + strlen(dn); + } else { +- siz += strlen(attrs[0]) + 30 + strlen(object) + strlen(dn); ++ siz += strlen(attrs[0] ? attrs[0] : "") + 30 + strlen(object) + strlen(dn); + } + } else { + /* dn: =\n\0 */ + if (dntype) { + siz += strlen(dntype) + 30 + strlen(object); + } else { +- siz += strlen(attrs[0]) + 30 + strlen(object); ++ siz += strlen(attrs[0] ? attrs[0] : "") + 30 + strlen(object); + } + } + templateentry = (char *)slapi_ch_malloc(siz); +@@ -1030,7 +1030,9 @@ bailout: + * slapi_pblock_set() will free any previous data, and + * pblock_done() will free SLAPI_PB_RESULT_TEXT. + */ +- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr); ++ if (gerstr) { ++ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr); ++ } + + if (!iscritical) { + /* +@@ -1040,7 +1042,7 @@ bailout: + rc = LDAP_SUCCESS; + } + +- slapi_ch_free((void **)&subjectndn); +- slapi_ch_free((void **)&gerstr); ++ slapi_ch_free_string(&subjectndn); ++ slapi_ch_free_string(&gerstr); + return rc; + } +diff --git a/ldap/servers/plugins/acl/acllist.c b/ldap/servers/plugins/acl/acllist.c +index 79786b723..e80c567c3 100644 +--- a/ldap/servers/plugins/acl/acllist.c ++++ b/ldap/servers/plugins/acl/acllist.c +@@ -255,7 +255,9 @@ __acllist_add_aci(aci_t *aci) + t_aci = t_aci->aci_next; + + /* Now add the new one to the end of the list */ +- t_aci->aci_next = aci; ++ if (t_aci) { ++ t_aci->aci_next = aci; ++ } + + slapi_log_err(SLAPI_LOG_ACL, plugin_name, "__acllist_add_aci - Added the ACL:%s to existing container:[%d]%s\n", + aci->aclName, head->acic_index, slapi_sdn_get_ndn(head->acic_sdn)); +diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c +index f6eee1957..4f9fb102b 100644 +--- a/ldap/servers/plugins/linkedattrs/linked_attrs.c ++++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c +@@ -1256,7 +1256,9 @@ linked_attrs_del_backpointers(Slapi_PBlock *pb, char *linkdn, struct configEntry + + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &pre_e); + slapi_entry_attr_find(pre_e, config->linktype, &pre_attr); +- slapi_attr_get_valueset(pre_attr, &vals); ++ if (pre_attr) { ++ slapi_attr_get_valueset(pre_attr, &vals); ++ } + } else { + vals = slapi_valueset_new(); + slapi_valueset_set_from_smod(vals, smod); +diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c +index 89fd012e7..124217ee0 100644 +--- a/ldap/servers/plugins/memberof/memberof_config.c ++++ b/ldap/servers/plugins/memberof/memberof_config.c +@@ -550,13 +550,17 @@ memberof_apply_config(Slapi_PBlock *pb __attribute__((unused)), + } + + /* Build the new list */ +- for (i = 0; theConfig.group_slapiattrs && theConfig.groupattrs && theConfig.groupattrs[i]; i++) { ++ for (i = 0; theConfig.group_slapiattrs && theConfig.group_slapiattrs[i] && ++ theConfig.groupattrs && theConfig.groupattrs[i]; i++) ++ { + theConfig.group_slapiattrs[i] = slapi_attr_new(); + slapi_attr_init(theConfig.group_slapiattrs[i], theConfig.groupattrs[i]); + } + + /* Terminate the list. */ +- theConfig.group_slapiattrs[i] = NULL; ++ if (theConfig.group_slapiattrs) { ++ theConfig.group_slapiattrs[i] = NULL; ++ } + + /* The filter is based off of the groupattr, so we update it here too. */ + slapi_filter_free(theConfig.group_filter, 1); +@@ -736,7 +740,9 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) + } + + /* Terminate the array. */ +- dest->group_slapiattrs[i] = NULL; ++ if (dest->group_slapiattrs) { ++ dest->group_slapiattrs[i] = NULL; ++ } + } + + if (src->memberof_attr) { +diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c +index 8e5ca4fff..c56e55f49 100644 +--- a/ldap/servers/plugins/posix-winsync/posix-winsync.c ++++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c +@@ -1114,7 +1114,7 @@ posix_winsync_pre_ds_mod_group_cb(void *cbdata __attribute__((unused)), + + slapi_value_init_string(voc, "posixGroup"); + slapi_entry_attr_find(ds_entry, "objectClass", &oc_attr); +- if (slapi_attr_value_find(oc_attr, slapi_value_get_berval(voc)) != 0) { ++ if (oc_attr && slapi_attr_value_find(oc_attr, slapi_value_get_berval(voc)) != 0) { + Slapi_ValueSet *oc_vs = NULL; + Slapi_Value *oc_nv = slapi_value_new(); + +diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c +index c035db290..6b5b28b0b 100644 +--- a/ldap/servers/plugins/replication/cl5_api.c ++++ b/ldap/servers/plugins/replication/cl5_api.c +@@ -2749,6 +2749,7 @@ _cl5UpgradeMajor(char *fromVersion, char *toVersion) + if (rc != CL5_SUCCESS) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, + "_cl5UpgradeMajor - Failed to open the db env\n"); ++ s_cl5Desc.dbOpenMode = backup; + return rc; + } + s_cl5Desc.dbOpenMode = backup; +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index b3d619862..6a5363e43 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -2317,7 +2317,7 @@ replica_check_for_tasks(time_t when __attribute__((unused)), void *arg) + "missing original task flag. Aborting abort task!\n", + clean_vals[i]); + replica_delete_task_config(e, (char *)type_replicaAbortCleanRUV, orig_val); +- goto done; ++ goto done2; + } + + if (!is_cleaned_rid(rid)) { +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 02b645f41..7649aa14e 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -223,6 +223,7 @@ replica_config_add(Slapi_PBlock *pb __attribute__((unused)), + } + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_add - "MSG_NOREPLICANORMRDN); + slapi_rdn_free(&replicardn); ++ slapi_ch_free_string(&replica_root); + *returncode = LDAP_UNWILLING_TO_PERFORM; + return SLAPI_DSE_CALLBACK_ERROR; + } else { +@@ -232,6 +233,7 @@ replica_config_add(Slapi_PBlock *pb __attribute__((unused)), + } + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,"replica_config_add - "MSG_CNREPLICA, nrdn, REPLICA_RDN); + slapi_rdn_free(&replicardn); ++ slapi_ch_free_string(&replica_root); + *returncode = LDAP_UNWILLING_TO_PERFORM; + return SLAPI_DSE_CALLBACK_ERROR; + } +@@ -242,6 +244,7 @@ replica_config_add(Slapi_PBlock *pb __attribute__((unused)), + strcpy(errortext, MSG_NOREPLICARDN); + } + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_add - "MSG_NOREPLICARDN); ++ slapi_ch_free_string(&replica_root); + *returncode = LDAP_UNWILLING_TO_PERFORM; + return SLAPI_DSE_CALLBACK_ERROR; + } +@@ -287,7 +290,7 @@ done: + + PR_Unlock(s_configLock); + /* slapi_ch_free accepts NULL pointer */ +- slapi_ch_free((void **)&replica_root); ++ slapi_ch_free_string(&replica_root); + + if (*returncode != LDAP_SUCCESS) { + if (mtnode_ext->replica) +@@ -2083,7 +2086,6 @@ check_replicas_are_done_cleaning(cleanruv_data *data) + while (not_all_cleaned && !is_task_aborted(data->rid) && !slapi_is_shutting_down()) { + agmt_obj = agmtlist_get_first_agreement_for_replica(data->replica); + if (agmt_obj == NULL) { +- not_all_cleaned = 0; + break; + } + while (agmt_obj && !slapi_is_shutting_down()) { +@@ -2196,7 +2198,6 @@ check_replicas_are_done_aborting(cleanruv_data *data) + while (not_all_aborted && !slapi_is_shutting_down()) { + agmt_obj = agmtlist_get_first_agreement_for_replica(data->replica); + if (agmt_obj == NULL) { +- not_all_aborted = 0; + break; + } + while (agmt_obj && !slapi_is_shutting_down()) { +@@ -2803,6 +2804,7 @@ delete_cleaned_rid_config(cleanruv_data *clean_data) + cleanruv_log(clean_data->task, clean_data->rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, + "delete_cleaned_rid_config - Failed to remove task data from (%s) error (%d), rid (%d)", + edn, rc, clean_data->rid); ++ slapi_ch_array_free(attr_val); + goto bail; + } + } +diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c +index 37fe77379..b134409e4 100644 +--- a/ldap/servers/plugins/replication/urp.c ++++ b/ldap/servers/plugins/replication/urp.c +@@ -1602,6 +1602,7 @@ urp_find_tombstone_for_glue (Slapi_PBlock *pb, char *sessionid, const Slapi_Entr + for (int i = 0; entries && (entries[i] != NULL); i++) { + char *tombstone_csn_value = slapi_entry_attr_get_charptr(entries[i], "nstombstonecsn"); + if (tombstone_csn_value) { ++ csn_free(&tombstone_csn); + tombstone_csn = csn_new_by_string(tombstone_csn_value); + slapi_ch_free_string(&tombstone_csn_value); + if( csn_compare(tombstone_csn, conflict_csn) > 0 ) { +diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c +index 1e5865af8..4e3b0af54 100644 +--- a/ldap/servers/plugins/roles/roles_cache.c ++++ b/ldap/servers/plugins/roles/roles_cache.c +@@ -1276,6 +1276,8 @@ roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_object **resu + + if (rc == 0) { + *result = this_role; ++ } else { ++ slapi_ch_free((void **)&this_role); + } + + slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, +diff --git a/ldap/servers/plugins/views/views.c b/ldap/servers/plugins/views/views.c +index 6f784f599..5d8464761 100644 +--- a/ldap/servers/plugins/views/views.c ++++ b/ldap/servers/plugins/views/views.c +@@ -783,10 +783,12 @@ views_cache_create_applied_filter(viewEntry *pView) + "views_cache_create_applied_filter - View filter [%s] in entry [%s] is not valid\n", + buf, current->pDn); + } +- if (pBuiltFilter && pCurrentFilter) ++ if (pBuiltFilter && pCurrentFilter) { + pBuiltFilter = slapi_filter_join_ex(LDAP_FILTER_AND, pBuiltFilter, pCurrentFilter, 0); +- else ++ } else { ++ slapi_filter_free(pBuiltFilter, 1); + pBuiltFilter = pCurrentFilter; ++ } + + slapi_ch_free((void **)&buf); + +@@ -952,10 +954,12 @@ views_cache_create_descendent_filter(viewEntry *ancestor, PRBool useEntryID) + "views_cache_create_descendent_filter - View filter [%s] in entry [%s] is invalid\n", + buf, currentChild->pDn); + } +- if (pOrSubFilter && pCurrentFilter) ++ if (pOrSubFilter && pCurrentFilter) { + pOrSubFilter = slapi_filter_join_ex(LDAP_FILTER_OR, pOrSubFilter, pCurrentFilter, 0); +- else ++ } else { ++ slapi_filter_free(pOrSubFilter, 1); + pOrSubFilter = pCurrentFilter; ++ } + + PR_smprintf_free(buf); + } +@@ -1756,7 +1760,9 @@ view_search_rewrite_callback(Slapi_PBlock *pb) + #endif + + /* make it happen */ +- slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter); ++ if (outFilter) { ++ slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter); ++ } + + ret = -2; + +diff --git a/ldap/servers/slapd/agtmmap.c b/ldap/servers/slapd/agtmmap.c +index 352ccefda..bc5fe1ee1 100644 +--- a/ldap/servers/slapd/agtmmap.c ++++ b/ldap/servers/slapd/agtmmap.c +@@ -243,7 +243,7 @@ agt_mread_stats(int hdl, struct hdr_stats_t *pHdrInfo, struct ops_stats_t *pDsOp + return (EINVAL); /* Inavlid handle */ + } + +- if (mmap_tbl[hdl].fp <= (caddr_t)0) { ++ if (mmap_tbl[hdl].fp <= 0) { + return (EFAULT); /* Something got corrupted */ + } + +diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c +index f813447b6..1fee8050a 100644 +--- a/ldap/servers/slapd/back-ldbm/dblayer.c ++++ b/ldap/servers/slapd/back-ldbm/dblayer.c +@@ -3009,7 +3009,7 @@ dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, PRBool use_lock, in + ldbm_instance *inst = NULL; + dblayer_handle *handle = NULL; + char dbName[MAXPATHLEN] = {0}; +- char *dbNamep; ++ char *dbNamep = NULL; + char *p; + int dbbasenamelen, dbnamelen; + int rc = 0; +@@ -3102,11 +3102,12 @@ dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, PRBool use_lock, in + sprintf(p, "%c%s%s", get_sep(dbNamep), a->ai_type, LDBM_FILENAME_SUFFIX); + rc = dblayer_db_remove_ex(pEnv, dbNamep, 0, 0); + a->ai_dblayer = NULL; +- if (dbNamep != dbName) +- slapi_ch_free_string(&dbNamep); + } else { + rc = -1; + } ++ if (dbNamep != dbName) { ++ slapi_ch_free_string(&dbNamep); ++ } + slapi_ch_free((void **)&handle); + } else { + /* no handle to close */ +@@ -5661,7 +5662,9 @@ dblayer_copy_directory(struct ldbminfo *li, + inst_dir, MAXPATHLEN); + if (!inst_dirp || !*inst_dirp) { + slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_directory", "Instance dir is NULL.\n"); +- slapi_ch_free_string(&inst_dirp); ++ if (inst_dirp != inst_dir) { ++ slapi_ch_free_string(&inst_dirp); ++ } + return return_value; + } + len = strlen(inst_dirp); +@@ -5975,7 +5978,9 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) + slapi_task_log_notice(task, + "Backup: Instance dir is empty\n"); + } +- slapi_ch_free_string(&inst_dirp); ++ if (inst_dirp != inst_dir) { ++ slapi_ch_free_string(&inst_dirp); ++ } + return_value = -1; + goto bail; + } +@@ -5993,8 +5998,9 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) + "(%s -> %s): err=%d\n", + inst_dirp, dest_dir, return_value); + } +- if (inst_dirp != inst_dir) ++ if (inst_dirp != inst_dir) { + slapi_ch_free_string(&inst_dirp); ++ } + goto bail; + } + if (inst_dirp != inst_dir) +@@ -6292,7 +6298,6 @@ dblayer_copy_dirand_contents(char *src_dir, char *dst_dir, int mode, Slapi_Task + break; + } + +- + PR_snprintf(filename1, MAXPATHLEN, "%s/%s", src_dir, direntry->name); + PR_snprintf(filename2, MAXPATHLEN, "%s/%s", dst_dir, direntry->name); + slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_dirand_contents", "Moving file %s\n", +@@ -6305,8 +6310,7 @@ dblayer_copy_dirand_contents(char *src_dir, char *dst_dir, int mode, Slapi_Task + mode, task); + if (return_value) { + if (task) { +- slapi_task_log_notice(task, +- "Failed to copy directory %s", filename1); ++ slapi_task_log_notice(task, "Failed to copy directory %s", filename1); + } + break; + } +@@ -6523,13 +6527,13 @@ dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *bena + return LDAP_UNWILLING_TO_PERFORM; + } + if (!dbversion_exists(li, src_dir)) { +- slapi_log_err(SLAPI_LOG_ERR, "dblayer_restore", "Backup directory %s does not " +- "contain a complete backup\n", ++ slapi_log_err(SLAPI_LOG_ERR, "dblayer_restore", ++ "Backup directory %s does not contain a complete backup\n", + src_dir); + if (task) { +- slapi_task_log_notice(task, "Restore: backup directory %s does not " +- "contain a complete backup", +- src_dir); ++ slapi_task_log_notice(task, ++ "Restore: backup directory %s does not contain a complete backup", ++ src_dir); + } + return LDAP_UNWILLING_TO_PERFORM; + } +@@ -6585,13 +6589,10 @@ dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *bena + } + if (slapd_comp_path(src_dir, inst->inst_parent_dir_name) == 0) { + slapi_log_err(SLAPI_LOG_ERR, +- "dblayer_restore", "Backup dir %s and target dir %s " +- "are identical\n", ++ "dblayer_restore", "Backup dir %s and target dir %s are identical\n", + src_dir, inst->inst_parent_dir_name); + if (task) { + slapi_task_log_notice(task, +- "Restore: backup dir %s and target dir %s " +- "are identical\n", + src_dir, inst->inst_parent_dir_name); + } + PR_CloseDir(dirhandle); +@@ -7060,8 +7061,12 @@ dblayer_get_instance_data_dir(backend *be) + full_namep = dblayer_get_full_inst_dir(inst->inst_li, inst, + full_name, MAXPATHLEN); + if (!full_namep || !*full_namep) { ++ if (full_namep != full_name) { ++ slapi_ch_free_string(&full_namep); ++ } + return ret; + } ++ + /* Does this directory already exist? */ + if ((db_dir = PR_OpenDir(full_namep)) != NULL) { + /* yep. */ +@@ -7072,8 +7077,9 @@ dblayer_get_instance_data_dir(backend *be) + ret = mkdir_p(full_namep, 0700); + } + +- if (full_name != full_namep) ++ if (full_name != full_namep) { + slapi_ch_free_string(&full_namep); ++ } + + return ret; + } +@@ -7097,7 +7103,6 @@ dblayer_in_import(ldbm_instance *inst) + inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst, + inst_dir, MAXPATHLEN); + if (!inst_dirp || !*inst_dirp) { +- slapi_ch_free_string(&inst_dirp); + rval = -1; + goto done; + } +@@ -7117,8 +7122,9 @@ dblayer_in_import(ldbm_instance *inst) + } + PR_CloseDir(dirhandle); + done: +- if (inst_dirp != inst_dir) ++ if (inst_dirp != inst_dir) { + slapi_ch_free_string(&inst_dirp); ++ } + return rval; + } + +@@ -7149,7 +7155,9 @@ dblayer_update_db_ext(ldbm_instance *inst, char *oldext, char *newext) + if (NULL == inst_dirp || '\0' == *inst_dirp) { + slapi_log_err(SLAPI_LOG_ERR, + "dblayer_update_db_ext", "Instance dir is NULL\n"); +- slapi_ch_free_string(&inst_dirp); ++ if (inst_dirp != inst_dir) { ++ slapi_ch_free_string(&inst_dirp); ++ } + return -1; /* non zero */ + } + for (a = (struct attrinfo *)avl_getfirst(inst->inst_attrs); +@@ -7210,8 +7218,9 @@ dblayer_update_db_ext(ldbm_instance *inst, char *oldext, char *newext) + done: + slapi_ch_free_string(&ofile); + slapi_ch_free_string(&nfile); +- if (inst_dirp != inst_dir) ++ if (inst_dirp != inst_dir) { + slapi_ch_free_string(&inst_dirp); ++ } + + return rval; + } +diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c +index f0b969ff4..2a7529b81 100644 +--- a/ldap/servers/slapd/back-ldbm/index.c ++++ b/ldap/servers/slapd/back-ldbm/index.c +@@ -1776,13 +1776,14 @@ index_range_read_ext( + } + #endif + error: ++ slapi_log_err(SLAPI_LOG_TRACE, "index_range_read_ext", "(%s,%s) %lu candidates\n", ++ type, prefix ? prefix : "", (u_long)IDL_NIDS(idl)); ++ + index_free_prefix(prefix); + DBT_FREE_PAYLOAD(cur_key); + DBT_FREE_PAYLOAD(upperkey); +- + dblayer_release_index_file(be, ai, db); +- slapi_log_err(SLAPI_LOG_TRACE, "index_range_read_ext", "(%s,%s) %lu candidates\n", +- type, prefix, (u_long)IDL_NIDS(idl)); ++ + return (idl); + } + +@@ -2406,7 +2407,7 @@ index_free_prefix(char *prefix) + prefix == prefix_SUB) { + /* do nothing */ + } else { +- slapi_ch_free((void **)&prefix); ++ slapi_ch_free_string(&prefix); + } + } + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c +index 0d82ae92b..a2585575f 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c +@@ -162,7 +162,8 @@ ldbm_back_add(Slapi_PBlock *pb) + txn.back_txn_txn = parent_txn; + } else { + parent_txn = txn.back_txn_txn; +- slapi_pblock_set(pb, SLAPI_TXN, parent_txn); ++ if (parent_txn) ++ slapi_pblock_set(pb, SLAPI_TXN, parent_txn); + } + + /* The dblock serializes writes to the database, +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c +index 9ecb09903..fd2c7dbc8 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c +@@ -142,7 +142,7 @@ ldbm_instance_attrcrypt_config_add_callback(Slapi_PBlock *pb __attribute__((unus + + /* If the cipher was invalid, return unwilling to perform */ + if (0 == cipher) { +- returntext = "invalid cipher"; ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "invalid cipher"); + *returncode = LDAP_UNWILLING_TO_PERFORM; + ret = SLAPI_DSE_CALLBACK_ERROR; + } else { +@@ -167,7 +167,7 @@ ldbm_instance_attrcrypt_config_add_callback(Slapi_PBlock *pb __attribute__((unus + slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_attrcrypt_config_add_callback - " + "Attempt to encryption on a non-existent attribute: %s\n", + attribute_name, 0, 0); +- returntext = "attribute does not exist"; ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "attribute does not exist"); + *returncode = LDAP_UNWILLING_TO_PERFORM; + ret = SLAPI_DSE_CALLBACK_ERROR; + } +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c +index e9f3e32cc..76e37ae14 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c +@@ -113,7 +113,8 @@ ldbm_back_delete(Slapi_PBlock *pb) + txn.back_txn_txn = parent_txn; + } else { + parent_txn = txn.back_txn_txn; +- slapi_pblock_set(pb, SLAPI_TXN, parent_txn); ++ if (parent_txn) ++ slapi_pblock_set(pb, SLAPI_TXN, parent_txn); + } + + if (pb_conn) { +diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +index 60437f116..fb0fc5d1e 100644 +--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c ++++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +@@ -1154,7 +1154,7 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb) + int task_flags; + Slapi_Task *task; + int run_from_cmdline = 0; +- char *instance_name; ++ char *instance_name = NULL; + ldbm_instance *inst = NULL; + int str2entry_options = 0; + int retry; +@@ -1203,11 +1203,11 @@ ldbm_back_ldbm2ldif(Slapi_PBlock *pb) + goto bye; + } + ++ slapi_pblock_get(pb, SLAPI_BACKEND_INSTANCE_NAME, &instance_name); + if (run_from_cmdline) { + + /* Now that we have processed the config information, we look for + * the be that should do the db2ldif. */ +- slapi_pblock_get(pb, SLAPI_BACKEND_INSTANCE_NAME, &instance_name); + inst = ldbm_instance_find_by_name(li, instance_name); + if (NULL == inst) { + slapi_task_log_notice(task, "Unknown backend instance: %s", instance_name); +diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c +index 368417483..1ac3e009e 100644 +--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c ++++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c +@@ -168,7 +168,8 @@ vlvSearch_init(struct vlvSearch *p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm + + /* switch context back to the DSE backend */ + slapi_pblock_set(pb, SLAPI_BACKEND, oldbe); +- slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe ? oldbe->be_database: NULL); ++ if (oldbe) ++ slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe->be_database); + } + + /* make (&(parentid=idofbase)(|(originalfilter)(objectclass=referral))) */ +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index 4a611e7f4..d3bf82b67 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -1864,6 +1864,7 @@ connection_threadmain() + signal_listner(); + } + } else if (1 == is_timedout) { ++ /* covscan reports this code is unreachable (2019/6/4) */ + connection_make_readable_nolock(conn); + signal_listner(); + } +diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c +index 1f1f51630..125684329 100644 +--- a/ldap/servers/slapd/dse.c ++++ b/ldap/servers/slapd/dse.c +@@ -2530,7 +2530,8 @@ dse_delete(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi + dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, ec, NULL, &returncode, returntext); + done: + slapi_pblock_get(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, &orig_entry); +- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec); ++ if (ec) ++ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec); + /* make sure OPRETURN and RESULT_CODE are set */ + slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc); + if (returncode || rc) { +@@ -2571,8 +2572,8 @@ done: + rc = LDAP_UNWILLING_TO_PERFORM; + } + } +- +- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry); ++ if (orig_entry) ++ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry); + slapi_send_ldap_result(pb, returncode, NULL, returntext, 0, NULL); + return dse_delete_return(returncode, ec); + } +diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c +index 080eb15aa..5d1d7238a 100644 +--- a/ldap/servers/slapd/entrywsi.c ++++ b/ldap/servers/slapd/entrywsi.c +@@ -359,7 +359,6 @@ entry_add_present_attribute_wsi(Slapi_Entry *e, Slapi_Attr *a) + * Preserves LDAP Information Model constraints, + * returning an LDAP result code. + */ +-static void entry_dump_stateinfo(char *msg, Slapi_Entry* e); + static Slapi_Value *attr_most_recent_deleted_value(Slapi_Attr *a); + static void resolve_single_valued_two_values(Slapi_Entry *e, Slapi_Attr *a, int attribute_state, Slapi_Value *current_value, Slapi_Value *second_current_value); + static void resolve_single_valued_check_restore_deleted_value(Slapi_Entry *e, Slapi_Attr *a); +@@ -397,6 +396,7 @@ entry_add_present_values_wsi(Slapi_Entry *e, const char *type, struct berval **b + /* Used for debug purpose, it dumps into the error log the + * entry with the replication stateinfo + */ ++#if 0 + static void + entry_dump_stateinfo(char *msg, Slapi_Entry* e) + { +@@ -407,6 +407,7 @@ entry_dump_stateinfo(char *msg, Slapi_Entry* e) + slapi_log_err(SLAPI_LOG_ERR, msg, "%s\n", s); + slapi_ch_free((void **)&s); + } ++#endif + + 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) +@@ -1270,7 +1271,7 @@ attr_most_recent_deleted_value(Slapi_Attr *a) + most_recent_v = v; + + while (i != -1) { +- vdcsn = value_get_csn(v, CSN_TYPE_VALUE_DELETED); ++ vdcsn = (CSN *)value_get_csn(v, CSN_TYPE_VALUE_DELETED); + + if (csn_compare((const CSN *)most_recent_vdcsn, (const CSN *)vdcsn) < 0) { + most_recent_v = v; +@@ -1289,20 +1290,20 @@ static void + resolve_single_valued_two_values(Slapi_Entry *e, Slapi_Attr *a, int attribute_state, Slapi_Value *current_value, Slapi_Value *second_current_value) + { + +- CSN *current_value_vucsn; +- CSN *second_current_value_vucsn; ++ const CSN *current_value_vucsn; ++ const CSN *second_current_value_vucsn; + Slapi_Value *value_to_zap; + + current_value_vucsn = value_get_csn(current_value, CSN_TYPE_VALUE_UPDATED); + second_current_value_vucsn = value_get_csn(second_current_value, CSN_TYPE_VALUE_UPDATED); + + /* First determine which present value will be zapped */ +- if (csn_compare((const CSN *)second_current_value_vucsn, (const CSN *)current_value_vucsn) < 0) { ++ if (csn_compare(second_current_value_vucsn, current_value_vucsn) < 0) { + /* + * The second value is older but was distinguished at the time the current value was added + * then the second value should become current + */ +- if (value_distinguished_at_csn(e, a, second_current_value, (const CSN *)current_value_vucsn)) { ++ if (value_distinguished_at_csn(e, a, second_current_value, current_value_vucsn)) { + value_to_zap = current_value; + } else { + /* The second value being not distinguished, zap it as it is a single valued attribute */ +@@ -1311,7 +1312,7 @@ resolve_single_valued_two_values(Slapi_Entry *e, Slapi_Attr *a, int attribute_st + + } else { + /* Here the current_value is older than the second_current_value */ +- if (value_distinguished_at_csn(e, a, current_value, (const CSN *)second_current_value_vucsn)) { ++ if (value_distinguished_at_csn(e, a, current_value, second_current_value_vucsn)) { + /* current_value was distinguished at the time the second value was added + * then the current_value should become the current */ + value_to_zap = second_current_value; +@@ -1348,17 +1349,17 @@ resolve_single_valued_check_restore_deleted_value(Slapi_Entry *e, Slapi_Attr *a) + /* An attribute needs a present value */ + entry_deleted_value_to_present_value(a, deleted_value); + } else { +- CSN *current_value_vucsn; +- CSN *deleted_value_vucsn; +- CSN *deleted_value_vdcsn; ++ const CSN *current_value_vucsn; ++ const CSN *deleted_value_vucsn; ++ const CSN *deleted_value_vdcsn; + + deleted_value_vucsn = value_get_csn(deleted_value, CSN_TYPE_VALUE_UPDATED); + deleted_value_vdcsn = value_get_csn(deleted_value, CSN_TYPE_VALUE_DELETED); + current_value_vucsn = value_get_csn(current_value, CSN_TYPE_VALUE_UPDATED); + if (deleted_value_vucsn && +- !value_distinguished_at_csn(e, a, current_value, (const CSN *)deleted_value_vucsn) && +- (csn_compare((const CSN *)current_value_vucsn, (const CSN *)deleted_value_vucsn) < 0) && +- (csn_compare((const CSN *)deleted_value_vdcsn, (const CSN *)current_value_vucsn) < 0)) { ++ !value_distinguished_at_csn(e, a, current_value, deleted_value_vucsn) && ++ (csn_compare((const CSN *)current_value_vucsn, deleted_value_vucsn) < 0) && ++ (csn_compare((const CSN *)deleted_value_vdcsn, current_value_vucsn) < 0)) { + /* the condition to resurrect the deleted value is + * - it is more recent than the current value + * - its value was deleted before the current value +@@ -1376,8 +1377,8 @@ static void + resolve_single_valued_zap_current(Slapi_Entry *e, Slapi_Attr *a) + { + Slapi_Value *current_value = NULL; +- CSN *current_value_vucsn; +- CSN *adcsn; ++ const CSN *current_value_vucsn; ++ const CSN *adcsn; + + /* check if the current value should be deleted because + * older than adcsn and not distinguished +@@ -1386,7 +1387,7 @@ resolve_single_valued_zap_current(Slapi_Entry *e, Slapi_Attr *a) + current_value_vucsn = value_get_csn(current_value, CSN_TYPE_VALUE_UPDATED); + adcsn = attr_get_deletion_csn(a); + if (current_value != NULL) { +- if (csn_compare((const CSN *)adcsn, (const CSN *) current_value_vucsn) > 0) { ++ if (csn_compare(adcsn, (const CSN *) current_value_vucsn) > 0) { + /* the attribute was deleted after the value was last updated */ + if (!value_distinguished_at_csn(e, a, current_value, (const CSN *) current_value_vucsn)) { + entry_present_value_to_zapped_value(a, current_value); +@@ -1404,17 +1405,17 @@ resolve_single_valued_set_adcsn(Slapi_Attr *a) + { + Slapi_Value *deleted_value = NULL; + Slapi_Value *current_value = NULL; +- CSN *current_value_vucsn; +- CSN *deleted_value_vucsn; +- CSN *adcsn; ++ const CSN *current_value_vucsn; ++ const CSN *deleted_value_vucsn; ++ const CSN *adcsn; + + slapi_attr_first_value(a, ¤t_value); + current_value_vucsn = value_get_csn(current_value, CSN_TYPE_VALUE_UPDATED); + deleted_value = attr_most_recent_deleted_value(a); + deleted_value_vucsn = value_get_csn(deleted_value, CSN_TYPE_VALUE_UPDATED); + adcsn = attr_get_deletion_csn(a); +- if ((deleted_value != NULL && (csn_compare(adcsn, (const CSN *) deleted_value_vucsn) < 0)) || +- (deleted_value == NULL && (csn_compare(adcsn, (const CSN *) current_value_vucsn) < 0))) { ++ if ((deleted_value != NULL && (csn_compare(adcsn, deleted_value_vucsn) < 0)) || ++ (deleted_value == NULL && (csn_compare(adcsn, current_value_vucsn) < 0))) { + attr_set_deletion_csn(a, NULL); + } + } +@@ -1430,10 +1431,10 @@ resolve_single_valued_zap_deleted(Slapi_Attr *a) + { + Slapi_Value *deleted_value = NULL; + Slapi_Value *current_value = NULL; +- CSN *current_value_vucsn; +- CSN *deleted_value_vucsn; +- CSN *deleted_value_vdcsn; +- CSN *deleted_value_csn; ++ const CSN *current_value_vucsn; ++ const CSN *deleted_value_vucsn; ++ const CSN *deleted_value_vdcsn; ++ const CSN *deleted_value_csn; + PRBool deleted_on_mod_del = PR_FALSE; /* flag if a value was deleted specifically */ + + /* Now determine if the deleted value worth to be kept */ +@@ -1445,16 +1446,16 @@ resolve_single_valued_zap_deleted(Slapi_Attr *a) + deleted_value_vdcsn = value_get_csn(deleted_value, CSN_TYPE_VALUE_DELETED); + + /* get the appropriate csn to take into consideration: either from MOD_REPL or from MOD_DEL_specific */ +- if (csn_compare((const CSN *) deleted_value_vdcsn, (const CSN *) deleted_value_vucsn) <= 0) { ++ if (csn_compare(deleted_value_vdcsn, deleted_value_vucsn) <= 0) { + deleted_value_csn = deleted_value_vucsn; + } else { + deleted_value_csn = deleted_value_vdcsn; +- if (0 == csn_compare_ext((const CSN *) current_value_vucsn, (const CSN *) deleted_value_vdcsn, CSN_COMPARE_SKIP_SUBSEQ)) { ++ if (0 == csn_compare_ext(current_value_vucsn, deleted_value_vdcsn, CSN_COMPARE_SKIP_SUBSEQ)) { + /* the deleted value was specifically delete in the same operation that set the current value */ + deleted_on_mod_del = PR_TRUE; + } + } +- if ((csn_compare((const CSN *) deleted_value_csn, (const CSN *) current_value_vucsn) < 0) || deleted_on_mod_del) { ++ if ((csn_compare(deleted_value_csn, current_value_vucsn) < 0) || deleted_on_mod_del) { + entry_deleted_value_to_zapped_value(a, deleted_value); + } + } +diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c +index 33ca9ce1d..2c7b53214 100644 +--- a/ldap/servers/slapd/main.c ++++ b/ldap/servers/slapd/main.c +@@ -1220,6 +1220,7 @@ main(int argc, char **argv) + vattr_cleanup(); + sasl_map_done(); + cleanup: ++ slapi_ch_free_string(&(mcfg.myname)); + compute_terminate(); + SSL_ShutdownServerSessionIDCache(); + SSL_ClearSessionCache(); +@@ -2194,7 +2195,6 @@ slapd_exemode_ldif2db(struct main_config *mcfg) + return_value = -1; + } + slapi_pblock_destroy(pb); +- slapi_ch_free((void **)&(mcfg->myname)); + charray_free(instances); + charray_free(mcfg->cmd_line_instance_names); + charray_free(mcfg->db2ldif_include); +@@ -2377,7 +2377,6 @@ slapd_exemode_db2ldif(int argc, char **argv, struct main_config *mcfg) + slapi_ch_free((void **)&my_ldiffile); + } + } +- slapi_ch_free((void **)&(mcfg->myname)); + charray_free(mcfg->cmd_line_instance_names); + charray_free(mcfg->db2ldif_include); + if (mcfg->db2ldif_dump_replica) { +@@ -2505,8 +2504,6 @@ slapd_exemode_db2index(struct main_config *mcfg) + + slapi_pblock_destroy(pb); + charray_free(mcfg->db2index_attrs); +- slapi_ch_free((void **)&(mcfg->myname)); +- + charray_free(mcfg->db2ldif_include); + /* This frees mcfg->cmd_line_instance_name */ + charray_free(instances); +@@ -2557,7 +2554,6 @@ slapd_exemode_db2archive(struct main_config *mcfg) + int32_t task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; + slapi_pblock_set(pb, SLAPI_TASK_FLAGS, &task_flags); + return_value = (backend_plugin->plg_db2archive)(pb); +- slapi_ch_free((void **)&(mcfg->myname)); + slapi_pblock_destroy(pb); + return return_value; + } +@@ -2605,7 +2601,6 @@ slapd_exemode_archive2db(struct main_config *mcfg) + slapi_pblock_set(pb, SLAPI_TASK_FLAGS, &task_flags); + slapi_pblock_set(pb, SLAPI_BACKEND_INSTANCE_NAME, mcfg->cmd_line_instance_name); + return_value = (backend_plugin->plg_archive2db)(pb); +- slapi_ch_free((void **)&(mcfg->myname)); + slapi_pblock_destroy(pb); + return return_value; + } +@@ -2674,7 +2669,6 @@ slapd_exemode_upgradedb(struct main_config *mcfg) + return_value = -1; + } + slapi_pblock_destroy(pb); +- slapi_ch_free((void **)&(mcfg->myname)); + return (return_value); + } + +@@ -2747,7 +2741,6 @@ slapd_exemode_upgradednformat(struct main_config *mcfg) + } + slapi_pblock_destroy(pb); + bail: +- slapi_ch_free((void **)&(mcfg->myname)); + return (rc); + } + +diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c +index 834949a67..b90424985 100644 +--- a/ldap/servers/slapd/mapping_tree.c ++++ b/ldap/servers/slapd/mapping_tree.c +@@ -539,9 +539,6 @@ free_mapping_tree_node_arrays(backend ***be_list, char ***be_names, int **be_sta + { + int i; + +- /* sanity check */ +- PR_ASSERT(be_list != NULL && be_names != NULL && be_states != NULL && be_list_count != NULL); +- + if (*be_names != NULL) + for (i = 0; i < *be_list_count; ++i) { + slapi_ch_free((void **)&((*be_names)[i])); +@@ -647,9 +644,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + + if (get_backends_from_attr(attr, &be_list, &be_names, &be_states, + &be_list_count, &be_list_size, NULL)) { +- free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); +- slapi_sdn_free(&subtree); +- return lderr; ++ goto free_and_return; + } + + if (NULL == be_list) { +@@ -660,6 +655,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + } + + } else if (!strcasecmp(type, "nsslapd-referral")) { ++ slapi_ch_array_free(referral); + referral = mtn_get_referral_from_entry(entry); + + } else if (!strcasecmp(type, "nsslapd-state")) { +@@ -684,6 +680,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + slapi_entry_get_dn(entry)); + continue; + } ++ slapi_ch_free_string(&plugin_lib); + plugin_lib = slapi_ch_strdup(slapi_value_get_string(val)); + } else if (!strcasecmp(type, "nsslapd-distribution-funct")) { + slapi_attr_first_value(attr, &val); +@@ -693,6 +690,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + slapi_entry_get_dn(entry)); + continue; + } ++ slapi_ch_free_string(&plugin_funct); + plugin_funct = slapi_ch_strdup(slapi_value_get_string(val)); + } else if (!strcasecmp(type, "nsslapd-distribution-root-update")) { + const char *sval; +@@ -737,13 +735,16 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + if (be == NULL) { + slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_add", + "Default container has not been created for the NULL SUFFIX node.\n"); +- slapi_sdn_free(&subtree); +- return -1; ++ lderr = -1; ++ goto free_and_return; + } + + be_list_size = 1; + be_list_count = 0; + ++ /* We're in a loop and potentially overwriting these pointers so free them first */ ++ free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); ++ + be_list = (backend **)slapi_ch_calloc(1, sizeof(backend *)); + be_names = (char **)slapi_ch_calloc(1, sizeof(char *)); + be_states = (int *)slapi_ch_calloc(1, sizeof(int)); +@@ -767,17 +768,13 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + slapi_log_err(SLAPI_LOG_ERR, + "Node %s must define a backend\n", + slapi_entry_get_dn(entry), 0, 0); +- slapi_sdn_free(&subtree); +- free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); +- return lderr; ++ goto free_and_return; + } + if (((state == MTN_REFERRAL) || (state == MTN_REFERRAL_ON_UPDATE)) && (referral == NULL)) { + slapi_log_err(SLAPI_LOG_ERR, + "Node %s must define referrals to be in referral state\n", + slapi_entry_get_dn(entry), 0, 0); +- slapi_sdn_free(&subtree); +- free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); +- return lderr; ++ goto free_and_return; + } + + if (plugin_lib && plugin_funct) { +@@ -787,11 +784,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_add", + "Node %s cannot find distribution plugin. " SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n", + slapi_entry_get_dn(entry), PR_GetError(), slapd_pr_strerror(PR_GetError())); +- slapi_sdn_free(&subtree); +- slapi_ch_free((void **)&plugin_funct); +- slapi_ch_free((void **)&plugin_lib); +- free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); +- return lderr; ++ goto free_and_return; + } + } else if ((plugin_lib == NULL) && (plugin_funct == NULL)) { + /* nothing configured -> OK */ +@@ -801,11 +794,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_add", + "Node %s must define both lib and funct for distribution plugin\n", + slapi_entry_get_dn(entry)); +- slapi_sdn_free(&subtree); +- slapi_ch_free((void **)&plugin_funct); +- slapi_ch_free((void **)&plugin_lib); +- free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); +- return lderr; ++ goto free_and_return; + } + + /* Now we can create the node for this mapping tree entry. */ +@@ -838,6 +827,15 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep) + *newnodep = node; + } + ++ return lderr; ++ ++free_and_return: ++ slapi_sdn_free(&subtree); ++ slapi_ch_array_free(referral); ++ slapi_ch_free_string(&plugin_funct); ++ slapi_ch_free_string(&plugin_lib); ++ free_mapping_tree_node_arrays(&be_list, &be_names, &be_states, &be_list_count); ++ + return lderr; + } + +diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c +index 896cccfb9..bbc0ab71a 100644 +--- a/ldap/servers/slapd/modify.c ++++ b/ldap/servers/slapd/modify.c +@@ -1444,9 +1444,11 @@ optimize_mods(Slapi_Mods *smods) + + prev_mod = slapi_mods_get_first_mod(smods); + while ((mod = slapi_mods_get_next_mod(smods))) { +- if ((SLAPI_IS_MOD_ADD(prev_mod->mod_op) || SLAPI_IS_MOD_DELETE(prev_mod->mod_op)) && ++ if (prev_mod && ++ (SLAPI_IS_MOD_ADD(prev_mod->mod_op) || SLAPI_IS_MOD_DELETE(prev_mod->mod_op)) && + (prev_mod->mod_op == mod->mod_op) && +- (!strcasecmp(prev_mod->mod_type, mod->mod_type))) { ++ (!strcasecmp(prev_mod->mod_type, mod->mod_type))) ++ { + /* Get the current number of mod values from the previous mod. Do it once per attr */ + if (mod_count == 0) { + for (; prev_mod->mod_bvalues != NULL && prev_mod->mod_bvalues[mod_count] != NULL; mod_count++) +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index dd6917363..dac42eb13 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -998,7 +998,8 @@ free_and_return_nolock: + slapi_sdn_free(&sdn); + } + slapi_sdn_free(&basesdn); +- slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn); ++ if (orig_sdn) ++ slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn); + + slapi_ch_free_string(&proxydn); + slapi_ch_free_string(&proxystr); +diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c +index 9da266b61..622daffdb 100644 +--- a/ldap/servers/slapd/plugin_internal_op.c ++++ b/ldap/servers/slapd/plugin_internal_op.c +@@ -368,7 +368,8 @@ seq_internal_callback_pb(Slapi_PBlock *pb, void *callback_data, plugin_result_ca + slapi_pblock_set(pb, SLAPI_BACKEND, be); + slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database); + slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname); +- slapi_pblock_set(pb, SLAPI_SEQ_VAL, val); ++ if (val) ++ slapi_pblock_set(pb, SLAPI_SEQ_VAL, val); + slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls); + + /* set actions taken to process the operation */ +diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c +index e208442d5..dc7106da5 100644 +--- a/ldap/servers/slapd/plugin_syntax.c ++++ b/ldap/servers/slapd/plugin_syntax.c +@@ -247,7 +247,9 @@ plugin_call_syntax_filter_sub_sv( + Operation *op = NULL; + /* to pass SLAPI_SEARCH_TIMELIMIT & SLAPI_OPINITATED_TIME */ + slapi_pblock_get(pb, SLAPI_OPERATION, &op); +- slapi_pblock_set(pipb, SLAPI_OPERATION, op); ++ if (op) { ++ slapi_pblock_set(pipb, SLAPI_OPERATION, op); ++ } + } + rc = (*sub_fn)(pipb, fsub->sf_initial, fsub->sf_any, fsub->sf_final, va); + } else { +diff --git a/ldap/servers/slapd/rdn.c b/ldap/servers/slapd/rdn.c +index 41c075036..fdb6b1773 100644 +--- a/ldap/servers/slapd/rdn.c ++++ b/ldap/servers/slapd/rdn.c +@@ -934,10 +934,7 @@ slapi_rdn_get_dn(Slapi_RDN *srdn, char **dn) + if (NULL == srdn || NULL == srdn->all_rdns || NULL == dn) { + return -1; + } +- for (rdnp = srdn->all_rdns; rdnp && *rdnp; rdnp++) { +- len += strlen(*rdnp) + 1; /* 1 for ',' */ +- } +- len += 1; ++ + len = slapi_rdn_get_dn_len(srdn); + *dn = (char *)slapi_ch_malloc(len); + enddn = *dn + len - 1; +diff --git a/ldap/servers/slapd/sasl_map.c b/ldap/servers/slapd/sasl_map.c +index 72bd01079..9593fd075 100644 +--- a/ldap/servers/slapd/sasl_map.c ++++ b/ldap/servers/slapd/sasl_map.c +@@ -336,7 +336,9 @@ _sasl_unescape_parenthesis(char *input) + *d++ = *s; + } + } +- *d = '\0'; ++ if (d) { ++ *d = '\0'; ++ } + return input; + } + +diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c +index 379fe208b..f609c220d 100644 +--- a/ldap/servers/slapd/schema.c ++++ b/ldap/servers/slapd/schema.c +@@ -2363,9 +2363,9 @@ schema_delete_attributes(Slapi_Entry *entryBefore __attribute__((unused)), LDAPM + attr_ldif[k] = tolower(attr_ldif[k]); + } + +- sizedbuffer_allocate(psbAttrName, strlen(attr_ldif)); +- sizedbuffer_allocate(psbAttrOid, strlen(attr_ldif)); +- sizedbuffer_allocate(psbAttrSyntax, strlen(attr_ldif)); ++ sizedbuffer_allocate(psbAttrName, strlen(attr_ldif) + 1); ++ sizedbuffer_allocate(psbAttrOid, strlen(attr_ldif) + 1); ++ sizedbuffer_allocate(psbAttrSyntax, strlen(attr_ldif) + 1); + + sscanf(attr_ldif, "%s name %s syntax %s", + psbAttrOid->buffer, psbAttrName->buffer, psbAttrSyntax->buffer); +diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c +index 7e253f535..953227ba0 100644 +--- a/ldap/servers/slapd/search.c ++++ b/ldap/servers/slapd/search.c +@@ -37,7 +37,7 @@ do_search(Slapi_PBlock *pb) + { + Slapi_Operation *operation; + BerElement *ber; +- int i, err, attrsonly; ++ int i, err = 0, attrsonly; + ber_int_t scope, deref, sizelimit, timelimit; + char *rawbase = NULL; + int rawbase_set_in_pb = 0; /* was rawbase set in pb? */ +@@ -232,6 +232,7 @@ do_search(Slapi_PBlock *pb) + log_search_access(pb, base, scope, fstr, "invalid attribute request"); + send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL); + slapi_ch_free_string(&normaci); ++ err = 1; /* Make sure we free everything */ + goto free_and_return; + } + } +@@ -357,8 +358,8 @@ do_search(Slapi_PBlock *pb) + ps_add(pb, changetypes, send_entchg_controls); + } + +-free_and_return:; +- if (!psearch || rc != 0) { ++free_and_return: ++ if (!psearch || rc != 0 || err != 0) { + slapi_ch_free_string(&fstr); + slapi_filter_free(filter, 1); + slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &attrs); +diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c +index 53cdb8985..c74d4823c 100644 +--- a/ldap/servers/slapd/tools/dbscan.c ++++ b/ldap/servers/slapd/tools/dbscan.c +@@ -532,7 +532,7 @@ print_changelog(unsigned char *data, int len __attribute__((unused))) + replgen = ntohl(thetime32); + pos += sizeof(uint32_t); + thetime = (time_t)replgen; +- db_printf("\treplgen: %ld %s", replgen, ctime((time_t *)&thetime)); ++ db_printf("\treplgen: %u %s", replgen, ctime((time_t *)&thetime)); + + /* read csn */ + print_attr("csn", &pos); +@@ -717,12 +717,15 @@ display_item(DBC *cursor, DBT *key, DBT *data) + tmpbuflen = (key->size > data->size ? key->size : data->size) + 1024; + } + if (buflen < tmpbuflen) { ++ unsigned char *tmp = NULL; + buflen = tmpbuflen; +- buf = (unsigned char *)realloc(buf, buflen); +- if (NULL == buf) { ++ tmp = (unsigned char *)realloc(buf, buflen); ++ if (NULL == tmp) { ++ free(buf); + printf("\t(malloc failed -- %d bytes)\n", buflen); + return; + } ++ buf = tmp; + } + + if (display_mode & RAWDATA) { +diff --git a/ldap/servers/slapd/tools/ldclt/ldapfct.c b/ldap/servers/slapd/tools/ldclt/ldapfct.c +index 373076500..ca0912d6c 100644 +--- a/ldap/servers/slapd/tools/ldclt/ldapfct.c ++++ b/ldap/servers/slapd/tools/ldclt/ldapfct.c +@@ -986,9 +986,9 @@ buildVersatileAttribute( + break; + default: + /* +- * Should not happen, unless new variant parsed and not +- * integrated here, or "jardinage".... +- */ ++ * Should not happen, unless new variant parsed and not ++ * integrated here, or "jardinage".... ++ */ + field = NULL; + field->how = 22; /* Crash !!! */ + break; +@@ -3231,7 +3231,7 @@ doExactSearch( + case LDAP_RES_SEARCH_ENTRY: + nentries++; + /* get dereferenced value into resctrls: deref parsing */ +- parse_rc = ldap_get_entry_controls(tttctx->ldapCtx, e, &resctrls); ++ ldap_get_entry_controls(tttctx->ldapCtx, e, &resctrls); + if (resctrls != NULL) { /* parse it only when we have return saved in server control */ + /* get dn */ + if ((dn = ldap_get_dn(tttctx->ldapCtx, e)) != NULL) { +diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.c b/ldap/servers/slapd/tools/ldclt/ldclt.c +index e72b775e2..586a14713 100644 +--- a/ldap/servers/slapd/tools/ldclt/ldclt.c ++++ b/ldap/servers/slapd/tools/ldclt/ldclt.c +@@ -816,7 +816,7 @@ trapVector( + int + initMainThread(void) + { +- struct sigaction act; ++ struct sigaction act = {0}; + + /* + * Trap SIGINT. +diff --git a/ldap/servers/slapd/tools/ldif.c b/ldap/servers/slapd/tools/ldif.c +index 3548c7d49..a13e99f89 100644 +--- a/ldap/servers/slapd/tools/ldif.c ++++ b/ldap/servers/slapd/tools/ldif.c +@@ -92,11 +92,13 @@ main(int argc, char **argv) + } + if (nread + cur > max) { + max += BUFSIZ; +- if ((val = (char *)realloc(val, max)) == +- NULL) { ++ char *tmp = NULL; ++ if ((tmp = (char *)realloc(val, max)) == NULL) { ++ free(val); + perror("realloc"); + return (1); + } ++ val = tmp; + } + memcpy(val + cur, buf, nread); + cur += nread; +@@ -125,12 +127,14 @@ main(int argc, char **argv) + /* if buffer was filled, expand and keep reading unless last char + is linefeed, in which case it is OK for buffer to be full */ + while (((curlen = strlen(buf)) == (maxlen - 1)) && buf[curlen - 1] != '\n') { ++ char *tmp = NULL; + maxlen *= 2; +- if ((buf = (char *)realloc(buf, maxlen)) == NULL) { ++ if ((tmp = (char *)realloc(buf, maxlen)) == NULL) { + perror("realloc"); + free(buf); + return (1); + } ++ buf = tmp; + if (NULL == fgets(buf + curlen, maxlen / 2 + 1, stdin)) { + /* no more input to read. */ + break; +diff --git a/ldap/servers/slapd/tools/mmldif.c b/ldap/servers/slapd/tools/mmldif.c +index cdcf4b16d..96b606a29 100644 +--- a/ldap/servers/slapd/tools/mmldif.c ++++ b/ldap/servers/slapd/tools/mmldif.c +@@ -700,7 +700,6 @@ readrec(edfFILE *edf1, attrib1_t **attrib) + attrib1_t *freelist = *attrib; + attrib1_t *newlist = NULL; + attrib1_t *a; +- int ignore_rec = FALSE; + int free_it = 0; + + *attrib = NULL; +@@ -758,7 +757,7 @@ readrec(edfFILE *edf1, attrib1_t **attrib) + if (!stricmp(line, "authoritative")) + continue; + if (!freelist) { +- att = (attrib1_t *)malloc(sizeof(attrib1_t)); ++ att = (attrib1_t *)calloc(1, sizeof(struct attrib1_t *)); + free_it = 1; + } else { + att = freelist; +@@ -881,8 +880,6 @@ readrec(edfFILE *edf1, attrib1_t **attrib) + } + *attrib = newlist; + freefreelist(freelist); +- if (ignore_rec) +- return IDDS_MM_ABSENT; + return IDDS_MM_OK; + } + +diff --git a/ldap/servers/slapd/tools/pwenc.c b/ldap/servers/slapd/tools/pwenc.c +index d92e94e17..87ca17488 100644 +--- a/ldap/servers/slapd/tools/pwenc.c ++++ b/ldap/servers/slapd/tools/pwenc.c +@@ -362,6 +362,7 @@ slapd_config(const char *configdir, const char *givenconfigfile) + } + } else if (slapi_sdn_compare(&config_dn, slapi_entry_get_sdn_const(e)) == 0) { + /* Get the root scheme out and initialise it (if it exists) */ ++ slapi_ch_free_string(&rootschemename); + rootschemename = slapi_entry_attr_get_charptr(e, CONFIG_ROOTPWSTORAGESCHEME_ATTRIBUTE); + } + +diff --git a/ldap/servers/slapd/tools/rsearch/infadd.c b/ldap/servers/slapd/tools/rsearch/infadd.c +index db6fb23ae..6fe84f9e1 100644 +--- a/ldap/servers/slapd/tools/rsearch/infadd.c ++++ b/ldap/servers/slapd/tools/rsearch/infadd.c +@@ -309,7 +309,7 @@ main(int argc, char **argv) + at_getThread(threads[x], NULL), min, max, count, + ntot); + } +- if (!quiet && (numThreads > 1 || !verbose)) { ++ if (numThreads > 1 && !quiet && !verbose) { + double val = 1000.0 * (double)total / (double)sampleInterval; + fprintf(stdout, "Rate: %7.2f/thr (%6.2f/sec =%7.4fms/op), " + "total: %u (%d thr)\n", +diff --git a/ldap/servers/slapd/tools/rsearch/rsearch.c b/ldap/servers/slapd/tools/rsearch/rsearch.c +index 7602b16d8..347c84d2a 100644 +--- a/ldap/servers/slapd/tools/rsearch/rsearch.c ++++ b/ldap/servers/slapd/tools/rsearch/rsearch.c +@@ -467,7 +467,10 @@ main(int argc, char **argv) + printf("T%d min=%4ums, max=%4ums, count = %u\n", + st_getThread(threads[x], NULL), min, max, count); + } +- rate = (double)total / (double)numThreads; ++ rate = 0.0; ++ if (numThreads) { ++ rate = (double)total / (double)numThreads; ++ } + val = 1000.0 * (double)total / (double)sampleInterval; + cumrate += rate; + if ((numThreads > 1) || (!verbose)) { +diff --git a/lib/ldaputil/certmap.c b/lib/ldaputil/certmap.c +index efe531a51..dc2fdde43 100644 +--- a/lib/ldaputil/certmap.c ++++ b/lib/ldaputil/certmap.c +@@ -374,6 +374,7 @@ dbinfo_to_certinfo(DBConfDBInfo_t *db_info, + rv = ldapu_list_add_info(propval_list, propval); + + if (rv != LDAPU_SUCCESS) { ++ ldapu_propval_free((void *)propval, (void *)propval); + goto error; + } + +@@ -700,15 +701,14 @@ certmap_read_certconfig_file(const char *file) + while (curdb) { + nextdb = curdb->next; + rv = dbinfo_to_certinfo(curdb, &certinfo); +- + if (rv != LDAPU_SUCCESS) { + dbconf_free_confinfo(conf_info); + return rv; + } + + rv = process_certinfo(certinfo); +- + if (rv != LDAPU_SUCCESS) { ++ ldapu_certinfo_free(certinfo); + dbconf_free_confinfo(conf_info); + return rv; + } +@@ -1330,8 +1330,11 @@ ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage * + + rv = (*mapfn)(cert, ld, certmap_info, &ldapDN, &filter); + +- if (rv != LDAPU_SUCCESS) ++ if (rv != LDAPU_SUCCESS) { ++ free(ldapDN); ++ free(filter); + return rv; ++ } + + /* Get the search function from the certmap_info - certinfo maybe NULL */ + searchfn = ldapu_get_cert_searchfn_sub(certmap_info); +@@ -1339,10 +1342,8 @@ ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage * + rv = (*searchfn)(cert, ld, certmap_info, basedn, ldapDN, filter, + certmap_attrs, &res_array); + +- if (ldapDN) +- free(ldapDN); +- if (filter) +- free(filter); ++ free(ldapDN); ++ free(filter); + + /* + * Get the verify cert function & call it. +diff --git a/lib/libaccess/usrcache.cpp b/lib/libaccess/usrcache.cpp +index 5ea8259fe..b6ac58d3c 100644 +--- a/lib/libaccess/usrcache.cpp ++++ b/lib/libaccess/usrcache.cpp +@@ -157,11 +157,11 @@ int acl_usr_cache_init () + } + else { + singleDbTable = 0; +- databaseUserCacheTable = PR_NewHashTable(0, ++ databaseUserCacheTable = PR_NewHashTable(0, + PR_HashCaseString, + PR_CompareCaseStrings, + PR_CompareValues, +- &ACLPermAllocOps, ++ &ACLPermAllocOps, + usrcache_pool); + } + +@@ -176,7 +176,7 @@ int acl_usr_cache_init () + for(i = 0; i < num_usrobj; i++){ + usrobj = (UserCacheObj *)pool_malloc(usrcache_pool, + sizeof(UserCacheObj)); +- ++ + if (!usrobj) return -1; + memset((void *)usrobj, 0, sizeof(UserCacheObj)); + PR_INSERT_AFTER(&usrobj->list, usrobj_list); +diff --git a/src/cockpit/389-console/src/lib/database/chaining.jsx b/src/cockpit/389-console/src/lib/database/chaining.jsx +index 3dd3ec48e..c169e7bd3 100644 +--- a/src/cockpit/389-console/src/lib/database/chaining.jsx ++++ b/src/cockpit/389-console/src/lib/database/chaining.jsx +@@ -916,7 +916,7 @@ export class ChainingConfig extends React.Component { + ; + } else { + proxiedAuth = +- + Allow Proxied Authentication + ; +diff --git a/src/cockpit/389-console/src/lib/database/suffix.jsx b/src/cockpit/389-console/src/lib/database/suffix.jsx +index 9cfb95b92..3f3bc82ec 100644 +--- a/src/cockpit/389-console/src/lib/database/suffix.jsx ++++ b/src/cockpit/389-console/src/lib/database/suffix.jsx +@@ -254,10 +254,10 @@ export class Suffix extends React.Component { + // Do import + let export_cmd = [ + "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", +- "backend", "export", this.props.suffix, "--ldif=" + this.state.ldifLocation, "--encrypted" ++ "backend", "export", this.props.suffix, "--ldif=" + this.state.ldifLocation + ]; + +- if (this.state.attrEncrpytion) { ++ if (this.state.attrEncryption) { + export_cmd.push("--encrypted"); + } + +diff --git a/src/cockpit/389-console/src/replication.js b/src/cockpit/389-console/src/replication.js +index 6ef363523..2fe3a6e48 100644 +--- a/src/cockpit/389-console/src/replication.js ++++ b/src/cockpit/389-console/src/replication.js +@@ -1185,7 +1185,7 @@ $(document).ready( function() { + } + } else { + if ( !('nsds5replicatedattributelisttotal' in repl_agmt_values) || +- agmt_tot_exclude != repl_agmt_values['nsds5replicatedattributelisttotal'].replace(frac_prefix, "")); ++ agmt_tot_exclude != repl_agmt_values['nsds5replicatedattributelisttotal'].replace(frac_prefix, "")) + { + cmd_args.push('--frac-list-total=' + frac_prefix + ' ' + agmt_tot_exclude); + } +diff --git a/src/lib389/lib389/agreement.py b/src/lib389/lib389/agreement.py +index dcab900b8..84e2f8c61 100644 +--- a/src/lib389/lib389/agreement.py ++++ b/src/lib389/lib389/agreement.py +@@ -266,6 +266,7 @@ class Agreement(DSLdapObject): + + # Extract the csn timstamps and compare them + agmt_time = 0 ++ con_time = 0 + match = Agreement.csnre.match(agmt_maxcsn) + if match: + agmt_time = int(match.group(1), 16) +diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py +index 64a40c15a..353a3e117 100644 +--- a/src/lib389/lib389/backend.py ++++ b/src/lib389/lib389/backend.py +@@ -480,6 +480,9 @@ class Backend(DSLdapObject): + :returns: DSLdapObject of the created entry + """ + ++ sample_entries = False ++ parent_suffix = False ++ + # normalize suffix (remove spaces between comps) + if dn is not None: + dn_comps = ldap.dn.explode_dn(dn.lower()) +@@ -490,9 +493,8 @@ class Backend(DSLdapObject): + dn_comps = ldap.dn.explode_dn(suffix_dn) + ndn = ",".join(dn_comps) + properties['nsslapd-suffix'] = ndn +- +- sample_entries = properties.pop(BACKEND_SAMPLE_ENTRIES, False) +- parent_suffix = properties.pop('parent', False) ++ sample_entries = properties.pop(BACKEND_SAMPLE_ENTRIES, False) ++ parent_suffix = properties.pop('parent', False) + + # Okay, now try to make the backend. + super(Backend, self).create(dn, properties, basedn) +diff --git a/src/lib389/lib389/cli_conf/backend.py b/src/lib389/lib389/cli_conf/backend.py +index 77ce3ddec..36e32ec48 100644 +--- a/src/lib389/lib389/cli_conf/backend.py ++++ b/src/lib389/lib389/cli_conf/backend.py +@@ -422,7 +422,7 @@ def backend_set(inst, basedn, log, args): + if args.add_referral: + be.add('nsslapd-referral', args.add_referral) + if args.del_referral: +- be.remove('nsslapd-referral', args.add_referral) ++ be.remove('nsslapd-referral', args.del_referral) + if args.cache_size: + be.set('nsslapd-cachesize', args.cache_size) + if args.cache_memsize: +-- +2.21.0 + diff --git a/SOURCES/0005-Issue-50431-Fix-regression-from-coverity-fix.patch b/SOURCES/0005-Issue-50431-Fix-regression-from-coverity-fix.patch new file mode 100644 index 0000000..799619b --- /dev/null +++ b/SOURCES/0005-Issue-50431-Fix-regression-from-coverity-fix.patch @@ -0,0 +1,138 @@ +From 6aa839f96f5ac880d45b0e98ed05445784476745 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 13 Jun 2019 17:55:25 -0400 +Subject: [PATCH] Issue 50431 - Fix regression from coverity fix + +Description: Fix a regression from the initial coverity commit + where we did not allow NULL pointers to set into + the pblock. They were false positives reported by + covscan. + +https://pagure.io/389-ds-base/issue/50431 + +Reviewed by: mreynolds (one line commit rule) +--- + ldap/servers/plugins/acl/acleffectiverights.c | 4 +--- + ldap/servers/plugins/views/views.c | 4 +--- + ldap/servers/slapd/back-ldbm/vlv_srch.c | 3 ++- + ldap/servers/slapd/dse.c | 6 ++---- + ldap/servers/slapd/opshared.c | 3 +-- + ldap/servers/slapd/plugin_internal_op.c | 3 +-- + ldap/servers/slapd/plugin_syntax.c | 4 +--- + 7 files changed, 9 insertions(+), 18 deletions(-) + +diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c +index 5dd46a064..8a34ac5eb 100644 +--- a/ldap/servers/plugins/acl/acleffectiverights.c ++++ b/ldap/servers/plugins/acl/acleffectiverights.c +@@ -1030,9 +1030,7 @@ bailout: + * slapi_pblock_set() will free any previous data, and + * pblock_done() will free SLAPI_PB_RESULT_TEXT. + */ +- if (gerstr) { +- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr); +- } ++ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, gerstr); + + if (!iscritical) { + /* +diff --git a/ldap/servers/plugins/views/views.c b/ldap/servers/plugins/views/views.c +index 5d8464761..64e305a3f 100644 +--- a/ldap/servers/plugins/views/views.c ++++ b/ldap/servers/plugins/views/views.c +@@ -1760,9 +1760,7 @@ view_search_rewrite_callback(Slapi_PBlock *pb) + #endif + + /* make it happen */ +- if (outFilter) { +- slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter); +- } ++ slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, outFilter); + + ret = -2; + +diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c +index 1ac3e009e..65b876647 100644 +--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c ++++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c +@@ -168,8 +168,9 @@ vlvSearch_init(struct vlvSearch *p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm + + /* switch context back to the DSE backend */ + slapi_pblock_set(pb, SLAPI_BACKEND, oldbe); +- if (oldbe) ++ if (oldbe) { + slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe->be_database); ++ } + } + + /* make (&(parentid=idofbase)(|(originalfilter)(objectclass=referral))) */ +diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c +index 125684329..8f2a14c9a 100644 +--- a/ldap/servers/slapd/dse.c ++++ b/ldap/servers/slapd/dse.c +@@ -2530,8 +2530,7 @@ dse_delete(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi + dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, ec, NULL, &returncode, returntext); + done: + slapi_pblock_get(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, &orig_entry); +- if (ec) +- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec); ++ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec); + /* make sure OPRETURN and RESULT_CODE are set */ + slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc); + if (returncode || rc) { +@@ -2572,8 +2571,7 @@ done: + rc = LDAP_UNWILLING_TO_PERFORM; + } + } +- if (orig_entry) +- slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry); ++ slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry); + slapi_send_ldap_result(pb, returncode, NULL, returntext, 0, NULL); + return dse_delete_return(returncode, ec); + } +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index dac42eb13..dd6917363 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -998,8 +998,7 @@ free_and_return_nolock: + slapi_sdn_free(&sdn); + } + slapi_sdn_free(&basesdn); +- if (orig_sdn) +- slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn); ++ slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, orig_sdn); + + slapi_ch_free_string(&proxydn); + slapi_ch_free_string(&proxystr); +diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c +index 622daffdb..9da266b61 100644 +--- a/ldap/servers/slapd/plugin_internal_op.c ++++ b/ldap/servers/slapd/plugin_internal_op.c +@@ -368,8 +368,7 @@ seq_internal_callback_pb(Slapi_PBlock *pb, void *callback_data, plugin_result_ca + slapi_pblock_set(pb, SLAPI_BACKEND, be); + slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database); + slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname); +- if (val) +- slapi_pblock_set(pb, SLAPI_SEQ_VAL, val); ++ slapi_pblock_set(pb, SLAPI_SEQ_VAL, val); + slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls); + + /* set actions taken to process the operation */ +diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c +index dc7106da5..e208442d5 100644 +--- a/ldap/servers/slapd/plugin_syntax.c ++++ b/ldap/servers/slapd/plugin_syntax.c +@@ -247,9 +247,7 @@ plugin_call_syntax_filter_sub_sv( + Operation *op = NULL; + /* to pass SLAPI_SEARCH_TIMELIMIT & SLAPI_OPINITATED_TIME */ + slapi_pblock_get(pb, SLAPI_OPERATION, &op); +- if (op) { +- slapi_pblock_set(pipb, SLAPI_OPERATION, op); +- } ++ slapi_pblock_set(pipb, SLAPI_OPERATION, op); + } + rc = (*sub_fn)(pipb, fsub->sf_initial, fsub->sf_any, fsub->sf_final, va); + } else { +-- +2.21.0 + diff --git a/SOURCES/0006-Revert-Issue-49960-Core-schema-contains-strings-inst.patch b/SOURCES/0006-Revert-Issue-49960-Core-schema-contains-strings-inst.patch new file mode 100644 index 0000000..5b170bb --- /dev/null +++ b/SOURCES/0006-Revert-Issue-49960-Core-schema-contains-strings-inst.patch @@ -0,0 +1,316 @@ +From d5e6f5a3faa2ee4e488cabb575f36f55009d10bd Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 7 Jun 2019 14:38:50 -0400 +Subject: [PATCH 02/12] Revert "Issue 49960 - Core schema contains strings + instead of numer oids" + +This reverts commit 2738fd00ffd7b9bced16e2e9ce61da80eec51206. +--- + ldap/schema/01core389.ldif | 28 ++++---- + ldap/schema/30ns-common.ldif | 102 +++++++++++++++--------------- + ldap/schema/50ns-admin.ldif | 62 +++++++++--------- + ldap/schema/50ns-certificate.ldif | 4 +- + ldap/schema/50ns-directory.ldif | 4 +- + ldap/schema/50ns-mail.ldif | 4 +- + 6 files changed, 102 insertions(+), 102 deletions(-) + +diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif +index 7bf4acc5b..f4123f29e 100644 +--- a/ldap/schema/01core389.ldif ++++ b/ldap/schema/01core389.ldif +@@ -86,26 +86,26 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2064 NAME 'nsSaslMapRegexString' DESC 'N + attributeTypes: ( 2.16.840.1.113730.3.1.2065 NAME 'nsSaslMapBaseDNTemplate' 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.2066 NAME 'nsSaslMapFilterTemplate' 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.2142 NAME 'nsSaslMapPriority' 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.309 NAME 'nsCertfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.310 NAME 'nsKeyfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.311 NAME 'nsSSL2' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.312 NAME 'nsSSL3' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsCertfile-oid NAME 'nsCertfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsKeyfile-oid NAME 'nsKeyfile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSSL2-oid NAME 'nsSSL2' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSSL3-oid NAME 'nsSSL3' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( nsTLS1-oid NAME 'nsTLS1' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( nsTLS10-oid NAME 'nsTLS10' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( nsTLS11-oid NAME 'nsTLS11' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( nsTLS12-oid NAME 'nsTLS12' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( sslVersionMin-oid NAME 'sslVersionMin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( sslVersionMax-oid NAME 'sslVersionMax' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.313 NAME 'nsSSLClientAuth' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.314 NAME 'nsSSLSessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.315 NAME 'nsSSL3SessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.316 NAME 'nsSSL2Ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.317 NAME 'nsSSL3Ciphers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSSLClientAuth-oid NAME 'nsSSLClientAuth' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSSLSessionTimeout-oid NAME 'nsSSLSessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSSL3SessionTimeout-oid NAME 'nsSSL3SessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++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: ( 2.16.840.1.113730.3.1.318 NAME 'nsSSLToken' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.319 NAME 'nsSSLPersonalitySSL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.320 NAME 'nsSSLActivation' 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' ) + attributeTypes: ( CACertExtractFile-oid NAME 'CACertExtractFile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( nsTLSAllowClientRenegotiation-oid NAME 'nsTLSAllowClientRenegotiation' DESC 'Allow clients to renegotiate open TLS connections using RFC 5746 secure renegotiation' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( ServerKeyExtractFile-oid NAME 'ServerKeyExtractFile' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +@@ -329,8 +329,8 @@ 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: ( 2.16.840.1.113730.3.2.60 NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ nsTLS10 $ nsTLS11 $ nsTLS12 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers $ allowWeakCipher $ CACertExtractFile $ allowWeakDHParam $ nsTLSAllowClientRenegotiation ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.61 NAME 'nsEncryptionModule' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsSSLToken $ nsSSLPersonalityssl $ nsSSLActivation $ ServerKeyExtractFile $ ServerCertExtractFile ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ nsTLS10 $ nsTLS11 $ nsTLS12 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers $ allowWeakCipher $ CACertExtractFile $ allowWeakDHParam $ nsTLSAllowClientRenegotiation ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsEncryptionModule-oid NAME 'nsEncryptionModule' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsSSLToken $ nsSSLPersonalityssl $ nsSSLActivation $ ServerKeyExtractFile $ ServerCertExtractFile ) 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' ) + objectClasses: ( 2.16.840.1.113730.3.2.332 NAME 'nsChangelogConfig' DESC 'Configuration of the changelog5 object' SUP top MUST ( cn $ nsslapd-changelogdir ) MAY ( nsslapd-changelogmaxage $ nsslapd-changelogtrim-interval $ nsslapd-changelogmaxentries $ nsslapd-changelogsuffix $ nsslapd-changelogcompactdb-interval $ nsslapd-encryptionalgorithm $ nsSymmetricKey ) X-ORIGIN '389 Directory Server' ) +diff --git a/ldap/schema/30ns-common.ldif b/ldap/schema/30ns-common.ldif +index 58eeae5b0..80b8cf6fc 100644 +--- a/ldap/schema/30ns-common.ldif ++++ b/ldap/schema/30ns-common.ldif +@@ -12,60 +12,60 @@ + # Common Netscape schema. + # + dn: cn=schema +-attributeTypes: ( 2.16.840.1.113730.3.1.276 NAME 'nsServerID' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.277 NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.278 NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.279 NAME 'nsBindPassword' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.280 NAME 'nsServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.281 NAME 'nsServerAddress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.282 NAME 'nsDirectoryInfoRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.283 NAME 'nsDirectoryURL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 1.3.6.1.4.1.42.2.27.10.1.31 NAME 'nsDirectoryFailoverList' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.284 NAME 'nsAdminDomainName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.285 NAME 'nsHostLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.286 NAME 'nsHardwarePlatform' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.287 NAME 'nsOsVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.288 NAME 'nsAdminGroupName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.289 NAME 'nsConfigRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 1.3.6.1.4.1.42.2.27.10.1.72 NAME 'nsAdminSIEDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.290 NAME 'nsVendor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.291 NAME 'nsProductName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.292 NAME 'nsNickName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.293 NAME 'nsProductVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.294 NAME 'nsBuildNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.295 NAME 'nsRevisionNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.296 NAME 'nsSerialNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.297 NAME 'nsInstalledLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.298 NAME 'nsExpirationDate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.299 NAME 'nsBuildSecurity' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.300 NAME 'nsServerMigrationClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.301 NAME 'nsServerCreationClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.302 NAME 'nsLdapSchemaVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.303 NAME 'nsSuiteSpotUser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.304 NAME 'nsErrorLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.305 NAME 'nsPidLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.306 NAME 'nsAccessLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.307 NAME 'nsDefaultAcceptLanguage' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.308 NAME 'nsServerSecurity' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.321 NAME 'nsTaskLabel' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.322 NAME 'nsHelpRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.323 NAME 'nsExecRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.329 NAME 'nsLogSuppress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.324 NAME 'nsJarfilename' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.325 NAME 'nsClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsServerID-oid NAME 'nsServerID' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsBindPassword-oid NAME 'nsBindPassword' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsServerPort-oid NAME 'nsServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsServerAddress-oid NAME 'nsServerAddress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsDirectoryInfoRef-oid NAME 'nsDirectoryInfoRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsDirectoryURL-oid NAME 'nsDirectoryURL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsDirectoryFailoverList-oid NAME 'nsDirectoryFailoverList' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsAdminDomainName-oid NAME 'nsAdminDomainName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsHostLocation-oid NAME 'nsHostLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsHardwarePlatform-oid NAME 'nsHardwarePlatform' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsOsVersion-oid NAME 'nsOsVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsAdminGroupName-oid NAME 'nsAdminGroupName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsConfigRoot-oid NAME 'nsConfigRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsAdminSIEDN-oid NAME 'nsAdminSIEDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsVendor-oid NAME 'nsVendor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsProductName-oid NAME 'nsProductName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsNickName-oid NAME 'nsNickName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsProductVersion-oid NAME 'nsProductVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsBuildNumber-oid NAME 'nsBuildNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsRevisionNumber-oid NAME 'nsRevisionNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSerialNumber-oid NAME 'nsSerialNumber' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsInstalledLocation-oid NAME 'nsInstalledLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsExpirationDate-oid NAME 'nsExpirationDate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsBuildSecurity-oid NAME 'nsBuildSecurity' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsServerMigrationClassname-oid NAME 'nsServerMigrationClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsServerCreationClassname-oid NAME 'nsServerCreationClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsLdapSchemaVersion-oid NAME 'nsLdapSchemaVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsSuiteSpotUser-oid NAME 'nsSuiteSpotUser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsErrorLog-oid NAME 'nsErrorLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsPidLog-oid NAME 'nsPidLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsAccessLog-oid NAME 'nsAccessLog' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsDefaultAcceptLanguage-oid NAME 'nsDefaultAcceptLanguage' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsServerSecurity-oid NAME 'nsServerSecurity' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsTaskLabel-oid NAME 'nsTaskLabel' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsHelpRef-oid NAME 'nsHelpRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsExecRef-oid NAME 'nsExecRef' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsLogSuppress-oid NAME 'nsLogSuppress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsJarfilename-oid NAME 'nsJarfilename' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) ++attributeTypes: ( nsClassname-oid NAME 'nsClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' ) + attributeTypes: ( 2.16.840.1.113730.3.1.2337 NAME 'nsCertSubjectDN' DESC 'An x509 DN from a certificate used to map during a TLS bind process' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN '389 Directory Server Project' ) + attributeTypes: ( 2.16.840.1.113730.3.1.2342 NAME 'nsSshPublicKey' DESC 'An nsSshPublicKey record' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server Project' ) + attributeTypes: ( 2.16.840.1.113730.3.1.2343 NAME 'legalName' DESC 'An individuals legalName' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server Project' ) +-objectClasses: ( 2.16.840.1.113730.3.2.56 NAME 'nsAdminDomain' DESC 'Netscape defined objectclass' SUP organizationalUnit MAY ( nsAdminDomainName ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.57 NAME 'nsHost' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( serverHostName $ description $ l $ nsHostLocation $ nsHardwarePlatform $ nsOsVersion ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.58 NAME 'nsAdminGroup' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsAdminGroupName $ description $ nsConfigRoot $ nsAdminSIEDN ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.59 NAME 'nsApplication' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsVendor $ description $ nsProductName $ nsNickName $ nsProductVersion $ nsBuildNumber $ nsRevisionNumber $ nsSerialNumber $ nsInstalledLocation $ installationTimeStamp $ nsExpirationDate $ nsBuildSecurity $ nsLdapSchemaVersion $ nsServerMigrationClassname $ nsServerCreationClassname ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.62 NAME 'nsResourceRef' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( seeAlso ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.63 NAME 'nsTask' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsTaskLabel $ nsHelpref $ nsExecref $ nsLogSuppress ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.64 NAME 'nsTaskGroup' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsTaskLabel ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.65 NAME 'nsAdminObject' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsJarFilename $ nsClassName ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.66 NAME 'nsConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( description $ nsServerPort $ nsServerAddress $ nsSuiteSpotUser $ nsErrorLog $ nsPidLog $ nsAccessLog $ nsDefaultAcceptLanguage $ nsServerSecurity ) X-ORIGIN 'Netscape' ) +-objectClasses: ( 2.16.840.1.113730.3.2.67 NAME 'nsDirectoryInfo' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsBindDN $ nsBindPassword $ nsDirectoryURL $ nsDirectoryFailoverList $ nsDirectoryInfoRef ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsAdminDomain-oid NAME 'nsAdminDomain' DESC 'Netscape defined objectclass' SUP organizationalUnit MAY ( nsAdminDomainName ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsHost-oid NAME 'nsHost' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( serverHostName $ description $ l $ nsHostLocation $ nsHardwarePlatform $ nsOsVersion ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsAdminGroup-oid NAME 'nsAdminGroup' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsAdminGroupName $ description $ nsConfigRoot $ nsAdminSIEDN ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsApplication-oid NAME 'nsApplication' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsVendor $ description $ nsProductName $ nsNickName $ nsProductVersion $ nsBuildNumber $ nsRevisionNumber $ nsSerialNumber $ nsInstalledLocation $ installationTimeStamp $ nsExpirationDate $ nsBuildSecurity $ nsLdapSchemaVersion $ nsServerMigrationClassname $ nsServerCreationClassname ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsResourceRef-oid NAME 'nsResourceRef' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( seeAlso ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsTask-oid NAME 'nsTask' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsTaskLabel $ nsHelpref $ nsExecref $ nsLogSuppress ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsTaskGroup-oid NAME 'nsTaskGroup' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsTaskLabel ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsAdminObject-oid NAME 'nsAdminObject' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsJarFilename $ nsClassName ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsConfig-oid NAME 'nsConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( description $ nsServerPort $ nsServerAddress $ nsSuiteSpotUser $ nsErrorLog $ nsPidLog $ nsAccessLog $ nsDefaultAcceptLanguage $ nsServerSecurity ) X-ORIGIN 'Netscape' ) ++objectClasses: ( nsDirectoryInfo-oid NAME 'nsDirectoryInfo' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsBindDN $ nsBindPassword $ nsDirectoryURL $ nsDirectoryFailoverList $ nsDirectoryInfoRef ) X-ORIGIN 'Netscape' ) + objectClasses: ( 2.16.840.1.113730.3.2.329 NAME 'nsMemberOf' DESC 'Allow memberOf assignment on groups for nesting and users' SUP top AUXILIARY MAY ( memberOf ) X-ORIGIN '389 Directory Server Project' ) + objectClasses: ( 2.16.840.1.113730.3.2.331 NAME 'nsAccount' DESC 'A representation of a binding user in a directory server' SUP top AUXILIARY MAY ( userCertificate $ nsCertSubjectDN $ nsSshPublicKey $ userPassword ) X-ORIGIN '389 Directory Server Project' ) + objectClasses: ( 2.16.840.1.113730.3.2.333 NAME 'nsPerson' DESC 'A representation of a person in a directory server' SUP top STRUCTURAL MUST ( displayName $ cn ) MAY ( userPassword $ seeAlso $ description $ legalName $ mail $ preferredLanguage ) X-ORIGIN '389 Directory Server Project' ) +diff --git a/ldap/schema/50ns-admin.ldif b/ldap/schema/50ns-admin.ldif +index a553c58cc..aceaf759a 100644 +--- a/ldap/schema/50ns-admin.ldif ++++ b/ldap/schema/50ns-admin.ldif +@@ -12,34 +12,34 @@ + # Schema used by Netscape Administration Services + # + dn: cn=schema +-attributeTypes: ( 2.16.840.1.113730.3.1.255 NAME 'nsAdminCgiWaitPid' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.256 NAME 'nsAdminUsers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.257 NAME 'nsAdminAccessHosts' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.258 NAME 'nsAdminAccessAddresses' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.259 NAME 'nsAdminOneACLDir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.260 NAME 'nsAdminEnableDSGW' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.261 NAME 'nsAdminEnableEnduser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.262 NAME 'nsAdminCacheLifetime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.263 NAME 'nsAdminAccountInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.264 NAME 'nsDeleteclassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.265 NAME 'nsAdminEndUserHTMLIndex' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.266 NAME 'nsUniqueAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.267 NAME 'nsUserIDFormat' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.268 NAME 'nsUserRDNComponent' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.269 NAME 'nsGroupRDNComponent' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.270 NAME 'nsWellKnownJarfiles' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.271 NAME 'nsNYR' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.272 NAME 'nsDefaultObjectClass' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.273 NAME 'nsPreference' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.274 NAME 'nsDisplayName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-attributeTypes: ( 2.16.840.1.113730.3.1.275 NAME 'nsViewConfiguration' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.46 NAME 'nsAdminServer' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsServerID ) MAY ( description ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.47 NAME 'nsAdminConfig' DESC 'Netscape defined objectclass' SUP nsConfig MAY ( nsAdminCgiWaitPid $ nsAdminUsers $ nsAdminAccessHosts $ nsAdminAccessAddresses $ nsAdminOneACLDir $ nsAdminEnableDSGW $ nsAdminEnableEnduser $ nsAdminCacheLifetime ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.48 NAME 'nsAdminResourceEditorExtension' DESC 'Netscape defined objectclass' SUP nsAdminObject MUST ( cn ) MAY ( nsAdminAccountInfo $ nsDeleteclassname ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.49 NAME 'nsAdminGlobalParameters' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsAdminEndUserHTMLIndex $ nsNickname ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.50 NAME 'nsGlobalParameters' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsUniqueAttribute $ nsUserIDFormat $ nsUserRDNComponent $ nsGroupRDNComponent $ nsWellKnownJarFiles $ nsNYR ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.51 NAME 'nsDefaultObjectClasses' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsDefaultObjectClass ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.52 NAME 'nsAdminConsoleUser' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsPreference ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.53 NAME 'nsCustomView' DESC 'Netscape defined objectclass' SUP nsAdminObject MAY ( nsDisplayName ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.54 NAME 'nsTopologyCustomView' DESC 'Netscape defined objectclass' SUP nsCustomView MUST ( cn ) MAY ( nsViewConfiguration ) X-ORIGIN 'Netscape Administration Services' ) +-objectClasses: ( 2.16.840.1.113730.3.2.55 NAME 'nsTopologyPlugin' DESC 'Netscape defined objectclass' SUP nsAdminObject X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminCgiWaitPid-oid NAME 'nsAdminCgiWaitPid' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminUsers-oid NAME 'nsAdminUsers' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminAccessHosts-oid NAME 'nsAdminAccessHosts' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminAccessAddresses-oid NAME 'nsAdminAccessAddresses' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminOneACLDir-oid NAME 'nsAdminOneACLDir' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminEnableDSGW-oid NAME 'nsAdminEnableDSGW' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminEnableEnduser-oid NAME 'nsAdminEnableEnduser' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminCacheLifetime-oid NAME 'nsAdminCacheLifetime' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminAccountInfo-oid NAME 'nsAdminAccountInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsDeleteclassname-oid NAME 'nsDeleteclassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsAdminEndUserHTMLIndex-oid NAME 'nsAdminEndUserHTMLIndex' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsUniqueAttribute-oid NAME 'nsUniqueAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsUserIDFormat-oid NAME 'nsUserIDFormat' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsUserRDNComponent-oid NAME 'nsUserRDNComponent' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsGroupRDNComponent-oid NAME 'nsGroupRDNComponent' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsWellKnownJarfiles-oid NAME 'nsWellKnownJarfiles' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsNYR-oid NAME 'nsNYR' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsDefaultObjectClass-oid NAME 'nsDefaultObjectClass' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsPreference-oid NAME 'nsPreference' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsDisplayName-oid NAME 'nsDisplayName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++attributeTypes: ( nsViewConfiguration-oid NAME 'nsViewConfiguration' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsAdminServer-oid NAME 'nsAdminServer' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsServerID ) MAY ( description ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsAdminConfig-oid NAME 'nsAdminConfig' DESC 'Netscape defined objectclass' SUP nsConfig MAY ( nsAdminCgiWaitPid $ nsAdminUsers $ nsAdminAccessHosts $ nsAdminAccessAddresses $ nsAdminOneACLDir $ nsAdminEnableDSGW $ nsAdminEnableEnduser $ nsAdminCacheLifetime ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsAdminResourceEditorExtension-oid NAME 'nsAdminResourceEditorExtension' DESC 'Netscape defined objectclass' SUP nsAdminObject MUST ( cn ) MAY ( nsAdminAccountInfo $ nsDeleteclassname ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsAdminGlobalParameters-oid NAME 'nsAdminGlobalParameters' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsAdminEndUserHTMLIndex $ nsNickname ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsGlobalParameters-oid NAME 'nsGlobalParameters' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsUniqueAttribute $ nsUserIDFormat $ nsUserRDNComponent $ nsGroupRDNComponent $ nsWellKnownJarFiles $ nsNYR ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsDefaultObjectClasses-oid NAME 'nsDefaultObjectClasses' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsDefaultObjectClass ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsAdminConsoleUser-oid NAME 'nsAdminConsoleUser' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsPreference ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsCustomView-oid NAME 'nsCustomView' DESC 'Netscape defined objectclass' SUP nsAdminObject MAY ( nsDisplayName ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsTopologyCustomView-oid NAME 'nsTopologyCustomView' DESC 'Netscape defined objectclass' SUP nsCustomView MUST ( cn ) MAY ( nsViewConfiguration ) X-ORIGIN 'Netscape Administration Services' ) ++objectClasses: ( nsTopologyPlugin-oid NAME 'nsTopologyPlugin' DESC 'Netscape defined objectclass' SUP nsAdminObject X-ORIGIN 'Netscape Administration Services' ) +diff --git a/ldap/schema/50ns-certificate.ldif b/ldap/schema/50ns-certificate.ldif +index 42d0f3e70..e89680a18 100644 +--- a/ldap/schema/50ns-certificate.ldif ++++ b/ldap/schema/50ns-certificate.ldif +@@ -12,6 +12,6 @@ + # Schema for Netscape Certificate Management System + # + dn: cn=schema +-attributeTypes: ( 1.3.6.1.4.1.42.2.27.10.1.190 NAME 'nsCertConfig' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Certificate Management System' ) ++attributeTypes: ( nsCertConfig-oid NAME 'nsCertConfig' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Certificate Management System' ) + objectClasses: ( 2.16.840.1.113730.3.2.18 NAME 'netscapeCertificateServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass ) X-ORIGIN 'Netscape Certificate Management System' ) +-objectClasses: ( 1.3.6.1.4.1.42.2.27.10.2.32 NAME 'nsCertificateServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass $ nsServerID ) MAY ( serverHostName $ nsServerPort $ nsCertConfig ) X-ORIGIN 'Netscape Certificate Management System' ) ++objectClasses: ( nsCertificateServer-oid NAME 'nsCertificateServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass $ nsServerID ) MAY ( serverHostName $ nsServerPort $ nsCertConfig ) X-ORIGIN 'Netscape Certificate Management System' ) +diff --git a/ldap/schema/50ns-directory.ldif b/ldap/schema/50ns-directory.ldif +index 63502482b..298d60770 100644 +--- a/ldap/schema/50ns-directory.ldif ++++ b/ldap/schema/50ns-directory.ldif +@@ -12,7 +12,7 @@ + # Additional schema used by Netscape Directory Server 4.x + # + dn: cn=schema +-attributeTypes: ( 1.3.6.1.4.1.42.2.27.10.1.73 NAME 'nsSecureServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) ++attributeTypes: ( nsSecureServerPort-oid NAME 'nsSecureServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) + attributeTypes: ( 2.16.840.1.113730.3.1.206 NAME 'filterInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) + attributeTypes: ( 2.16.840.1.113730.3.1.48 NAME 'replicaPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) + attributeTypes: ( 2.16.840.1.113730.3.1.49 NAME 'replicaUpdateFailedAt' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) +@@ -83,7 +83,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.57 NAME 'replicaRoot' DESC 'Netscape def + attributeTypes: ( 2.16.840.1.113730.3.1.58 NAME 'replicaBindDn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' ) + attributeTypes: ( 2.16.840.1.113730.3.1.69 NAME 'subtreeACI' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server 1.0' ) + objectClasses: ( 2.16.840.1.113730.3.2.23 NAME 'netscapeDirectoryServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass ) X-ORIGIN 'Netscape Directory Server' ) +-objectClasses: ( 1.3.6.1.4.1.42.2.27.10.2.31 NAME 'nsDirectoryServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass $ nsServerID ) MAY ( serverHostName $ nsServerPort $ nsSecureServerPort $ nsBindPassword $ nsBindDN $ nsBaseDN ) X-ORIGIN 'Netscape Directory Server' ) ++objectClasses: ( nsDirectoryServer-oid NAME 'nsDirectoryServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass $ nsServerID ) MAY ( serverHostName $ nsServerPort $ nsSecureServerPort $ nsBindPassword $ nsBindDN $ nsBaseDN ) X-ORIGIN 'Netscape Directory Server' ) + objectClasses: ( 2.16.840.1.113730.3.2.8 NAME 'ntUser' DESC 'Netscape defined objectclass' SUP top MUST ( ntUserDomainId ) MAY ( description $ l $ ou $ seeAlso $ ntUserPriv $ ntUserHomeDir $ ntUserComment $ ntUserFlags $ ntUserScriptPath $ ntUserAuthFlags $ ntUserUsrComment $ ntUserParms $ ntUserWorkstations $ ntUserLastLogon $ ntUserLastLogoff $ ntUserAcctExpires $ ntUserMaxStorage $ ntUserUnitsPerWeek $ ntUserLogonHours $ ntUserBadPwCount $ ntUserNumLogons $ ntUserLogonServer $ ntUserCountryCode $ ntUserCodePage $ ntUserUniqueId $ ntUserPrimaryGroupId $ ntUserProfile $ ntUserHomeDirDrive $ ntUserPasswordExpired $ ntUserCreateNewAccount $ ntUserDeleteAccount $ ntUniqueId $ ntUserNtPassword ) X-ORIGIN 'Netscape NT Synchronization' ) + objectClasses: ( 2.16.840.1.113730.3.2.9 NAME 'ntGroup' DESC 'Netscape defined objectclass' SUP top MUST ( ntUserDomainId ) MAY ( description $ l $ ou $ seeAlso $ ntGroupId $ ntGroupAttributes $ ntGroupCreateNewGroup $ ntGroupDeleteGroup $ ntGroupType $ ntUniqueId $ mail ) X-ORIGIN 'Netscape NT Synchronization' ) + objectClasses: ( 2.16.840.1.113730.3.2.82 NAME 'nsChangelog4Config' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' ) +diff --git a/ldap/schema/50ns-mail.ldif b/ldap/schema/50ns-mail.ldif +index 3e4783e6c..53d766977 100644 +--- a/ldap/schema/50ns-mail.ldif ++++ b/ldap/schema/50ns-mail.ldif +@@ -18,7 +18,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.707 NAME ( 'vacationstartdate' ) DESC 'N + attributeTypes: ( 2.16.840.1.113730.3.1.18 NAME ( 'mailHost' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.33 NAME ( 'mgrpModerator' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.25 NAME ( 'mgrpDeliverTo' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) +-attributeTypes: ( 1.3.6.1.4.1.42.2.27.10.1.81 NAME ( 'mgrpApprovePassword' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' ) ++attributeTypes: ( mgrpApprovePassword-oid NAME ( 'mgrpApprovePassword' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.31 NAME ( 'mailEnhancedUniqueMember' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.781 NAME ( 'mgrpAddHeader' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.22 NAME ( 'mgrpAllowedBroadcaster' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) +@@ -39,7 +39,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.520 NAME ( 'nswmExtendedUserPrefs' ) DES + attributeTypes: ( 2.16.840.1.113730.3.1.26 NAME ( 'mgrpErrorsTo' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.23 NAME ( 'mgrpAllowedDomain' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.28 NAME ( 'mgrpMsgRejectAction' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' ) +-attributeTypes: ( 1.3.6.1.4.1.42.2.27.10.1.79 NAME ( 'nsmsgDisallowAccess' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) ++attributeTypes: ( nsmsgDisallowAccess-oid NAME ( 'nsmsgDisallowAccess' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.17 NAME ( 'mailForwardingAddress' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.32 NAME ( 'mgrpMsgMaxSize' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Messaging Server 4.x' ) + attributeTypes: ( 2.16.840.1.113730.3.1.29 NAME ( 'mgrpMsgRejectText' ) DESC 'Netscape Messaging Server 4.x defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Messaging Server 4.x' ) +-- +2.21.0 + diff --git a/SOURCES/0007-Issue-50378-ACI-s-with-IPv4-and-IPv6-bind-rules-do-n.patch b/SOURCES/0007-Issue-50378-ACI-s-with-IPv4-and-IPv6-bind-rules-do-n.patch new file mode 100644 index 0000000..ef6b95b --- /dev/null +++ b/SOURCES/0007-Issue-50378-ACI-s-with-IPv4-and-IPv6-bind-rules-do-n.patch @@ -0,0 +1,72 @@ +From 76d8b45b71563d6158464f7a34bcb57d470993dc Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Fri, 21 Jun 2019 16:41:34 +0200 +Subject: [PATCH 03/12] Issue 50378 - ACI's with IPv4 and IPv6 bind rules do + not work for IPv6 clients + +Description: + +Add a new test case for #50378 instead of the older one that was testing +an unsupported corner case (ip=*). + +Relates: https://pagure.io/389-ds-base/issue/50378 + +Reviewed by: mreynolds (Thanks!) +--- + dirsrvtests/tests/suites/acl/keywords_test.py | 29 ++++++++++--------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +diff --git a/dirsrvtests/tests/suites/acl/keywords_test.py b/dirsrvtests/tests/suites/acl/keywords_test.py +index c8c19127b..6a494a4b6 100644 +--- a/dirsrvtests/tests/suites/acl/keywords_test.py ++++ b/dirsrvtests/tests/suites/acl/keywords_test.py +@@ -430,30 +430,33 @@ def test_dnsalias_keyword_test_nodns_cannot(topo, add_user, aci_of_user): + with pytest.raises(ldap.INSUFFICIENT_ACCESS): + org.replace("seeAlso", "cn=1") + +- +-def test_user_can_access_the_data_when_connecting_from_any_machine_2(topo, add_user, aci_of_user): ++@pytest.mark.ds50378 ++@pytest.mark.bz1710848 ++@pytest.mark.parametrize("ip_addr", ['127.0.0.1', "[::1]"]) ++def test_user_can_access_from_ipv4_or_ipv6_address(topo, add_user, aci_of_user, ip_addr): + """ +- User can access the data when connecting from any machine as per the ACI. ++ User can modify the data when accessing the server from the allowed IPv4 and IPv6 addresses + + :id:461e761e-7ac5-11e8-9ae4-8c16451d917b + :setup: Standalone Server + :steps: +- 1. Add test entry +- 2. Add ACI +- 3. User should follow ACI role ++ 1. Add ACI that has both IPv4 and IPv6 ++ 2. Connect from one of the IPs allowed in ACI ++ 3. Modify an attribute + :expectedresults: +- 1. Entry should be added +- 2. Operation should succeed +- 3. Operation should succeed ++ 1. ACI should be added ++ 2. Conection should be successful ++ 3. Operation should be successful + """ +- # Add ACI ++ # Add ACI that contains both IPv4 and IPv6 + Domain(topo.standalone, DEFAULT_SUFFIX).\ +- add("aci", f'(target ="ldap:///{IP_OU_KEY}")(targetattr=*)' ++ add("aci", f'(target ="ldap:///{IP_OU_KEY}")(targetattr=*) ' + f'(version 3.0; aci "IP aci"; allow(all) ' +- f'userdn = "ldap:///{FULLIP_KEY}" and ip = "*" ;)') ++ f'userdn = "ldap:///{FULLIP_KEY}" and (ip = "127.0.0.1" or ip = "::1");)') + + # Create a new connection for this test. +- conn = UserAccount(topo.standalone, FULLIP_KEY).bind(PW_DM) ++ conn = UserAccount(topo.standalone, FULLIP_KEY).bind(PW_DM, uri=f'ldap://{ip_addr}:{topo.standalone.port}') ++ + # Perform Operation + OrganizationalUnit(conn, IP_OU_KEY).replace("seeAlso", "cn=1") + +-- +2.21.0 + diff --git a/SOURCES/0008-Issue-50177-Add-a-new-CI-test-case-also-added-fixes-.patch b/SOURCES/0008-Issue-50177-Add-a-new-CI-test-case-also-added-fixes-.patch new file mode 100644 index 0000000..edfa32f --- /dev/null +++ b/SOURCES/0008-Issue-50177-Add-a-new-CI-test-case-also-added-fixes-.patch @@ -0,0 +1,70 @@ +From 96e4ad85a6fce9e140658b57146830b85c951415 Mon Sep 17 00:00:00 2001 +From: Akshay Adhikari +Date: Fri, 28 Jun 2019 17:27:08 +0530 +Subject: [PATCH 04/12] Issue 50177 - Add a new CI test case, also added fixes + in lib389 + +Bug Description: Import task should not be deleted too rapidely after import finishes +to be able to query the status. + +Fix Description: A new attribute 'ttl' is order to tune the life time of the task. +The default value is increased to '86400'. Added a test to check that and added it +to ImportTask & ExportTask classes in lib389 so it will create ttl attribute by default. + +Fixes: https://pagure.io/389-ds-base/issue/50177 + +Review by: mreynolds (Thanks!) +--- + dirsrvtests/tests/suites/basic/basic_test.py | 1 + + src/lib389/lib389/_constants.py | 2 ++ + src/lib389/lib389/tasks.py | 2 ++ + 3 files changed, 5 insertions(+) + +diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py +index 1e8662642..d2f8262fb 100644 +--- a/dirsrvtests/tests/suites/basic/basic_test.py ++++ b/dirsrvtests/tests/suites/basic/basic_test.py +@@ -274,6 +274,7 @@ def test_basic_import_export(topology_st, import_example_ldif): + assert r.present('nstasklog') + assert r.present('nstaskcurrentitem') + assert r.present('nstasktotalitems') ++ assert r.present('ttl') + + r.wait() + +diff --git a/src/lib389/lib389/_constants.py b/src/lib389/lib389/_constants.py +index ee5ed9e3e..e65613128 100644 +--- a/src/lib389/lib389/_constants.py ++++ b/src/lib389/lib389/_constants.py +@@ -20,6 +20,8 @@ INSTALL_LATEST_CONFIG = '999999999' + + REPLICA_FLAGS_CON = 0 + ++TTL_DEFAULT_VAL = '86400' ++ + # The structure is convenient for replica promote/demote methods + ReplicaRole = Enum("Replica role", "CONSUMER HUB MASTER STANDALONE") + +diff --git a/src/lib389/lib389/tasks.py b/src/lib389/lib389/tasks.py +index 6a86a422a..f12943fed 100644 +--- a/src/lib389/lib389/tasks.py ++++ b/src/lib389/lib389/tasks.py +@@ -275,6 +275,7 @@ class ImportTask(Task): + _properties = { + 'nsFilename': ldiffile, + 'nsIncludeSuffix': suffix, ++ 'ttl': TTL_DEFAULT_VAL, + } + self.create(properties=_properties) + +@@ -300,6 +301,7 @@ class ExportTask(Task): + _properties = { + 'nsFilename': ldiffile, + 'nsIncludeSuffix': suffix, ++ 'ttl': TTL_DEFAULT_VAL, + } + self.create(properties=_properties) + +-- +2.21.0 + diff --git a/SOURCES/0009-Ticket-50217-Implement-dsconf-security-section.patch b/SOURCES/0009-Ticket-50217-Implement-dsconf-security-section.patch new file mode 100644 index 0000000..0de98fd --- /dev/null +++ b/SOURCES/0009-Ticket-50217-Implement-dsconf-security-section.patch @@ -0,0 +1,457 @@ +From 2307e77efb6a75091b9152f81a52c83b8282d61a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mat=C3=BA=C5=A1=20Hon=C4=9Bk?= +Date: Thu, 31 Jan 2019 10:44:55 +0100 +Subject: [PATCH 05/12] Ticket 50217 - Implement dsconf security section + +Bug Description: +dsconf lacks options to configure security options + +Fix Description: +Implementing options to configure security related attributes and handle ciphers +configuration. + +Fixes: https://pagure.io/389-ds-base/issue/50217 + +Author: Matus Honek + +Review by: firstyear, mreynolds (Thanks!) +--- + src/lib389/cli/dsconf | 2 + + src/lib389/lib389/cli_conf/security.py | 244 +++++++++++++++++++++++++ + src/lib389/lib389/config.py | 97 +++++++++- + src/lib389/lib389/nss_ssl.py | 7 +- + 4 files changed, 343 insertions(+), 7 deletions(-) + create mode 100644 src/lib389/lib389/cli_conf/security.py + +diff --git a/src/lib389/cli/dsconf b/src/lib389/cli/dsconf +index f81516290..c0c0b4dfe 100755 +--- a/src/lib389/cli/dsconf ++++ b/src/lib389/cli/dsconf +@@ -32,6 +32,7 @@ from lib389.cli_conf import backup as cli_backup + from lib389.cli_conf import replication as cli_replication + from lib389.cli_conf import chaining as cli_chaining + from lib389.cli_conf import conflicts as cli_repl_conflicts ++from lib389.cli_conf import security as cli_security + from lib389.cli_base import disconnect_instance, connect_instance + from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat + from lib389.cli_base import setup_script_logger +@@ -87,6 +88,7 @@ cli_plugin.create_parser(subparsers) + cli_pwpolicy.create_parser(subparsers) + cli_replication.create_parser(subparsers) + cli_sasl.create_parser(subparsers) ++cli_security.create_parser(subparsers) + cli_schema.create_parser(subparsers) + cli_repl_conflicts.create_parser(subparsers) + +diff --git a/src/lib389/lib389/cli_conf/security.py b/src/lib389/lib389/cli_conf/security.py +new file mode 100644 +index 000000000..6d8c1ae0f +--- /dev/null ++++ b/src/lib389/lib389/cli_conf/security.py +@@ -0,0 +1,244 @@ ++# --- BEGIN COPYRIGHT BLOCK --- ++# Copyright (C) 2019 Red Hat, Inc. ++# All rights reserved. ++# ++# License: GPL (version 3 or any later version). ++# See LICENSE for details. ++# --- END COPYRIGHT BLOCK --- ++ ++from collections import OrderedDict, namedtuple ++import json ++ ++from lib389.config import Config, Encryption, RSA ++from lib389.nss_ssl import NssSsl ++ ++ ++Props = namedtuple('Props', ['cls', 'attr', 'help', 'values']) ++ ++onoff = ('on', 'off') ++protocol_versions = ('SSLv3', 'TLS1.0', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3', '') ++SECURITY_ATTRS_MAP = OrderedDict([ ++ ('security', Props(Config, 'nsslapd-security', ++ 'Enable or disable security', ++ onoff)), ++ ('listen-host', Props(Config, 'nsslapd-securelistenhost', ++ 'Host/address to listen on for LDAPS', ++ str)), ++ ('secure-port', Props(Config, 'nsslapd-securePort', ++ 'Port for LDAPS to listen on', ++ range(1, 65536))), ++ ('tls-client-auth', Props(Config, 'nsSSLClientAuth', ++ 'Client authentication requirement', ++ ('off', 'allowed', 'required'))), ++ ('require-secure-authentication', Props(Config, 'nsslapd-require-secure-binds', ++ 'Require binds over LDAPS, StartTLS, or SASL', ++ onoff)), ++ ('check-hostname', Props(Config, 'nsslapd-ssl-check-hostname', ++ 'Check Subject of remote certificate against the hostname', ++ onoff)), ++ ('verify-cert-chain-on-startup', Props(Config, 'nsslapd-validate-cert', ++ 'Validate server certificate during startup', ++ ('warn', *onoff))), ++ ('session-timeout', Props(Encryption, 'nsSSLSessionTimeout', ++ 'Secure session timeout', ++ int)), ++ ('tls-protocol-min', Props(Encryption, 'sslVersionMin', ++ 'Secure protocol minimal allowed version', ++ protocol_versions)), ++ ('tls-protocol-max', Props(Encryption, 'sslVersionMax', ++ 'Secure protocol maximal allowed version', ++ protocol_versions)), ++ ('allow-insecure-ciphers', Props(Encryption, 'allowWeakCipher', ++ 'Allow weak ciphers for legacy use', ++ onoff)), ++ ('allow-weak-dh-param', Props(Encryption, 'allowWeakDHParam', ++ 'Allow short DH params for legacy use', ++ onoff)), ++]) ++ ++RSA_ATTRS_MAP = OrderedDict([ ++ ('tls-allow-rsa-certificates', Props(RSA, 'nsSSLActivation', ++ 'Activate use of RSA certificates', ++ onoff)), ++ ('nss-cert-name', Props(RSA, 'nsSSLPersonalitySSL', ++ 'Server certificate name in NSS DB', ++ str)), ++ ('nss-token', Props(RSA, 'nsSSLToken', ++ 'Security token name (module of NSS DB)', ++ str)) ++]) ++ ++ ++def _security_generic_get(inst, basedn, logs, args, attrs_map): ++ result = {} ++ for attr, props in attrs_map.items(): ++ val = props.cls(inst).get_attr_val_utf8(props.attr) ++ result[props.attr] = val ++ if args.json: ++ print(json.dumps({'type': 'list', 'items': result})) ++ else: ++ print('\n'.join([f'{attr}: {value or ""}' for attr, value in result.items()])) ++ ++ ++def _security_generic_set(inst, basedn, logs, args, attrs_map): ++ for attr, props in attrs_map.items(): ++ arg = getattr(args, attr.replace('-', '_')) ++ if arg is None: ++ continue ++ dsobj = props.cls(inst) ++ dsobj.replace(props.attr, arg) ++ ++ ++def _security_generic_get_parser(parent, attrs_map, help): ++ p = parent.add_parser('get', help=help) ++ p.set_defaults(func=lambda *args: _security_generic_get(*args, attrs_map)) ++ return p ++ ++ ++def _security_generic_set_parser(parent, attrs_map, help, description): ++ p = parent.add_parser('set', help=help, description=description) ++ p.set_defaults(func=lambda *args: _security_generic_set(*args, attrs_map)) ++ for opt, params in attrs_map.items(): ++ p.add_argument(f'--{opt}', help=f'{params[2]} ({params[1]})') ++ return p ++ ++ ++def _security_ciphers_change(mode, ciphers, inst, log): ++ log = log.getChild('_security_ciphers_change') ++ if ('default' in ciphers) or ('all' in ciphers): ++ log.error(('Use ciphers\' names only. Keywords "default" and "all" are ignored. ' ++ 'Please, instead specify them manually using \'set\' command.')) ++ return ++ enc = Encryption(inst) ++ if enc.change_ciphers(mode, ciphers) is False: ++ log.error('Setting new ciphers failed.') ++ ++ ++def _security_generic_toggle(inst, basedn, log, args, cls, attr, value, thing): ++ cls(inst).set(attr, value) ++ ++ ++def _security_generic_toggle_parsers(parent, cls, attr, help_pattern): ++ def add_parser(action, value): ++ p = parent.add_parser(action.lower(), help=help_pattern.format(action)) ++ p.set_defaults(func=lambda *args: _security_generic_toggle(*args, cls, attr, value, action)) ++ return p ++ ++ return list(map(add_parser, ('Enable', 'Disable'), ('on', 'off'))) ++ ++ ++def security_enable(inst, basedn, log, args): ++ dbpath = inst.get_cert_dir() ++ tlsdb = NssSsl(dbpath=dbpath) ++ if not tlsdb._db_exists(even_partial=True): # we want to be very careful ++ log.info(f'Secure database does not exist. Creating a new one in {dbpath}.') ++ tlsdb.reinit() ++ ++ Config(inst).set('nsslapd-security', 'on') ++ ++ ++def security_disable(inst, basedn, log, args): ++ Config(inst).set('nsslapd-security', 'off') ++ ++ ++def security_ciphers_enable(inst, basedn, log, args): ++ _security_ciphers_change('+', args.cipher, inst, log) ++ ++ ++def security_ciphers_disable(inst, basedn, log, args): ++ _security_ciphers_change('-', args.cipher, inst, log) ++ ++ ++def security_ciphers_set(inst, basedn, log, args): ++ enc = Encryption(inst) ++ enc.ciphers = args.cipher_string.split(',') ++ ++ ++def security_ciphers_get(inst, basedn, log, args): ++ enc = Encryption(inst) ++ if args.json: ++ print({'type': 'list', 'items': enc.ciphers}) ++ else: ++ val = ','.join(enc.ciphers) ++ print(val if val != '' else '') ++ ++ ++def security_ciphers_list(inst, basedn, log, args): ++ enc = Encryption(inst) ++ ++ if args.enabled: ++ lst = enc.enabled_ciphers ++ elif args.supported: ++ lst = enc.supported_ciphers ++ elif args.disabled: ++ lst = set(enc.supported_ciphers) - set(enc.enabled_ciphers) ++ else: ++ lst = enc.ciphers ++ ++ if args.json: ++ print(json.dumps({'type': 'list', 'items': lst})) ++ else: ++ if lst == []: ++ log.getChild('security').warn('List of ciphers is empty') ++ else: ++ print(*lst, sep='\n') ++ ++ ++def create_parser(subparsers): ++ security = subparsers.add_parser('security', help='Query and manipulate security options') ++ security_sub = security.add_subparsers(help='security') ++ security_set = _security_generic_set_parser(security_sub, SECURITY_ATTRS_MAP, 'Set general security options', ++ ('Use this command for setting security related options located in cn=config and cn=encryption,cn=config.' ++ '\n\nTo enable/disable security you can use enable and disable commands instead.')) ++ security_get = _security_generic_get_parser(security_sub, SECURITY_ATTRS_MAP, 'Get general security options') ++ security_enable_p = security_sub.add_parser('enable', help='Enable security', description=( ++ 'If missing, create security database, then turn on security functionality. Please note this is usually not' ++ ' enought for TLS connections to work - proper setup of CA and server certificate is necessary.')) ++ security_enable_p.set_defaults(func=security_enable) ++ security_disable_p = security_sub.add_parser('disable', help='Disable security', description=( ++ 'Turn off security functionality. The rest of the configuration will be left untouched.')) ++ security_disable_p.set_defaults(func=security_disable) ++ ++ rsa = security_sub.add_parser('rsa', help='Query and mainpulate RSA security options') ++ rsa_sub = rsa.add_subparsers(help='rsa') ++ rsa_set = _security_generic_set_parser(rsa_sub, RSA_ATTRS_MAP, 'Set RSA security options', ++ ('Use this command for setting RSA (private key) related options located in cn=RSA,cn=encryption,cn=config.' ++ '\n\nTo enable/disable RSA you can use enable and disable commands instead.')) ++ rsa_get = _security_generic_get_parser(rsa_sub, RSA_ATTRS_MAP, 'Get RSA security options') ++ rsa_toggles = _security_generic_toggle_parsers(rsa_sub, RSA, 'nsSSLActivation', '{} RSA') ++ ++ ciphers = security_sub.add_parser('ciphers', help='Manage secure ciphers') ++ ciphers_sub = ciphers.add_subparsers(help='ciphers') ++ ++ ciphers_enable = ciphers_sub.add_parser('enable', help='Enable ciphers', description=( ++ 'Use this command to enable specific ciphers.')) ++ ciphers_enable.set_defaults(func=security_ciphers_enable) ++ ciphers_enable.add_argument('cipher', nargs='+') ++ ++ ciphers_disable = ciphers_sub.add_parser('disable', help='Disable ciphers', description=( ++ 'Use this command to disable specific ciphers.')) ++ ciphers_disable.set_defaults(func=security_ciphers_disable) ++ ciphers_disable.add_argument('cipher', nargs='+') ++ ++ ciphers_get = ciphers_sub.add_parser('get', help='Get ciphers attribute', description=( ++ 'Use this command to get contents of nsSSL3Ciphers attribute.')) ++ ciphers_get.set_defaults(func=security_ciphers_get) ++ ++ ciphers_set = ciphers_sub.add_parser('set', help='Set ciphers attribute', description=( ++ 'Use this command to directly set nsSSL3Ciphers attribute. It is a comma separated list ' ++ 'of cipher names (prefixed with + or -), optionaly including +all or -all. The attribute ' ++ 'may optionally be prefixed by keyword default. Please refer to documentation of ' ++ 'the attribute for a more detailed description.')) ++ ciphers_set.set_defaults(func=security_ciphers_set) ++ ciphers_set.add_argument('cipher_string', metavar='cipher-string') ++ ++ ciphers_list = ciphers_sub.add_parser('list', help='List ciphers', description=( ++ 'List secure ciphers. Without arguments, list ciphers as configured in nsSSL3Ciphers attribute.')) ++ ciphers_list.set_defaults(func=security_ciphers_list) ++ ciphers_list_group = ciphers_list.add_mutually_exclusive_group() ++ ciphers_list_group.add_argument('--enabled', action='store_true', ++ help='Only enabled ciphers') ++ ciphers_list_group.add_argument('--supported', action='store_true', ++ help='Only supported ciphers') ++ ciphers_list_group.add_argument('--disabled', action='store_true', ++ help='Only supported ciphers without enabled ciphers') +diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py +index b462585df..c2a34fa07 100644 +--- a/src/lib389/lib389/config.py ++++ b/src/lib389/lib389/config.py +@@ -1,5 +1,5 @@ + # --- BEGIN COPYRIGHT BLOCK --- +-# Copyright (C) 2015 Red Hat, Inc. ++# Copyright (C) 2019 Red Hat, Inc. + # All rights reserved. + # + # License: GPL (version 3 or any later version). +@@ -202,14 +202,16 @@ class Config(DSLdapObject): + return DSCLE0002 + return None + ++ + class Encryption(DSLdapObject): + """ + Manage "cn=encryption,cn=config" tree, including: + - ssl ciphers + - ssl / tls levels + """ +- def __init__(self, conn): ++ def __init__(self, conn, dn=None): + """@param conn - a DirSrv instance """ ++ assert dn is None # compatibility with Config class + super(Encryption, self).__init__(instance=conn) + self._dn = 'cn=encryption,%s' % DN_CONFIG + self._create_objectclasses = ['top', 'nsEncryptionConfig'] +@@ -225,11 +227,97 @@ class Encryption(DSLdapObject): + super(Encryption, self).create(properties=properties) + + def _lint_check_tls_version(self): +- tls_min = self.get_attr_val('sslVersionMin'); ++ tls_min = self.get_attr_val('sslVersionMin') + if tls_min < ensure_bytes('TLS1.1'): + return DSELE0001 + return None + ++ @property ++ def ciphers(self): ++ """List of requested ciphers. ++ ++ Each is represented by a string, either of: ++ - "+all" or "-all" ++ - TLS cipher RFC name, prefixed with either "+" or "-" ++ ++ Optionally, first element may be a string "default". ++ ++ :returns: list of str ++ """ ++ val = self.get_attr_val_utf8('nsSSL3Ciphers') ++ return val.split(',') if val else [] ++ ++ @ciphers.setter ++ def ciphers(self, ciphers): ++ """List of requested ciphers. ++ ++ :param ciphers: Ciphers to enable ++ :type ciphers: list of str ++ """ ++ self.set('nsSSL3Ciphers', ','.join(ciphers)) ++ self._log.info('Remeber to restart the server to apply the new cipher set.') ++ self._log.info('Some ciphers may be disabled anyway due to allowWeakCipher attribute.') ++ ++ def _get_listed_ciphers(self, attr): ++ """Remove features of ciphers that come after first :: occurence.""" ++ return [c[:c.index('::')] for c in self.get_attr_vals_utf8(attr)] ++ ++ @property ++ def enabled_ciphers(self): ++ """List currently enabled ciphers. ++ ++ :returns: list of str ++ """ ++ return self._get_listed_ciphers('nsSSLEnabledCiphers') ++ ++ @property ++ def supported_ciphers(self): ++ """List currently supported ciphers. ++ ++ :returns: list of str ++ """ ++ return self._get_listed_ciphers('nsSSLSupportedCiphers') ++ ++ def _check_ciphers_supported(self, ciphers): ++ good = True ++ for c in ciphers: ++ if c not in self.supported_ciphers: ++ self._log.warn(f'Cipher {c} is not supported.') ++ good = False ++ return good ++ ++ def change_ciphers(self, mode, ciphers): ++ """Enable or disable ciphers of the nsSSL3Ciphers attribute. ++ ++ :param mode: '+'/'-' string to enable/disable the ciphers ++ :type mode: str ++ :param ciphers: List of ciphers to enable/disable ++ :type ciphers: list of string ++ ++ :returns: False if some cipher is not supported ++ """ ++ if ('default' in ciphers) or 'all' in ciphers: ++ raise NotImplementedError('Processing "default" and "all" is not implemented.') ++ if not self._check_ciphers_supported(ciphers): ++ return False ++ ++ if mode == '+': ++ to_change = [c for c in ciphers if c not in self.enabled_ciphers] ++ elif mode == '-': ++ to_change = [c for c in ciphers if c in self.enabled_ciphers] ++ else: ++ raise ValueError('Incorrect mode. Use - or + sign.') ++ if len(to_change) != len(ciphers): ++ self._log.info( ++ ('Applying changes only for the following ciphers, the rest is up to date. ' ++ 'If this does not seem to be correct, please make sure the effective ' ++ 'set of enabled ciphers is up to date with configured ciphers ' ++ '- a server restart is needed for these to be applied.\n' ++ f'... {to_change}')) ++ cleaned = [c for c in self.ciphers if c[1:] not in to_change] ++ self.ciphers = cleaned + list(map(lambda c: mode + c, to_change)) ++ ++ + class RSA(DSLdapObject): + """ + Manage the "cn=RSA,cn=encryption,cn=config" object +@@ -237,8 +325,9 @@ class RSA(DSLdapObject): + - Database path + - ssl token name + """ +- def __init__(self, conn): ++ def __init__(self, conn, dn=None): + """@param conn - a DirSrv instance """ ++ assert dn is None # compatibility with Config class + super(RSA, self).__init__(instance=conn) + self._dn = 'cn=RSA,cn=encryption,%s' % DN_CONFIG + self._create_objectclasses = ['top', 'nsEncryptionModule'] +diff --git a/src/lib389/lib389/nss_ssl.py b/src/lib389/lib389/nss_ssl.py +index 7a8f2a5bd..a54095cd4 100644 +--- a/src/lib389/lib389/nss_ssl.py ++++ b/src/lib389/lib389/nss_ssl.py +@@ -162,11 +162,12 @@ only. + self.log.debug("nss output: %s", result) + return True + +- def _db_exists(self): ++ def _db_exists(self, even_partial=False): + """Check that a nss db exists at the certpath""" + +- if all(map(os.path.exists, self.db_files["dbm_backend"])) or \ +- all(map(os.path.exists, self.db_files["sql_backend"])): ++ fn = any if even_partial else all ++ if fn(map(os.path.exists, self.db_files["dbm_backend"])) or \ ++ fn(map(os.path.exists, self.db_files["sql_backend"])): + return True + return False + +-- +2.21.0 + diff --git a/SOURCES/0010-Issue-50431-Fix-regression-from-coverity-fix.patch b/SOURCES/0010-Issue-50431-Fix-regression-from-coverity-fix.patch new file mode 100644 index 0000000..0f60f04 --- /dev/null +++ b/SOURCES/0010-Issue-50431-Fix-regression-from-coverity-fix.patch @@ -0,0 +1,35 @@ +From ae86b58838fc3cc5978312b61613c10ce7fb6aa0 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 8 Jul 2019 14:00:28 -0400 +Subject: [PATCH 06/12] Issue 50431 - Fix regression from coverity fix + +Description: Fix a regression from the initial coverity commit that + caused the memebrOf groupattrs to become corrupted and + crash the server. + +https://pagure.io/389-ds-base/issue/50431 + +Reviewed by: vashirov(Thanks!) +--- + ldap/servers/plugins/memberof/memberof_config.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c +index 124217ee0..6729c3a7e 100644 +--- a/ldap/servers/plugins/memberof/memberof_config.c ++++ b/ldap/servers/plugins/memberof/memberof_config.c +@@ -550,8 +550,9 @@ memberof_apply_config(Slapi_PBlock *pb __attribute__((unused)), + } + + /* Build the new list */ +- for (i = 0; theConfig.group_slapiattrs && theConfig.group_slapiattrs[i] && +- theConfig.groupattrs && theConfig.groupattrs[i]; i++) ++ for (i = 0; theConfig.group_slapiattrs && ++ theConfig.groupattrs && ++ theConfig.groupattrs[i]; i++) + { + theConfig.group_slapiattrs[i] = slapi_attr_new(); + slapi_attr_init(theConfig.group_slapiattrs[i], theConfig.groupattrs[i]); +-- +2.21.0 + diff --git a/SOURCES/0011-Ticket-50413-ds-replcheck-Always-display-the-Result-.patch b/SOURCES/0011-Ticket-50413-ds-replcheck-Always-display-the-Result-.patch new file mode 100644 index 0000000..661493f --- /dev/null +++ b/SOURCES/0011-Ticket-50413-ds-replcheck-Always-display-the-Result-.patch @@ -0,0 +1,98 @@ +From e064b0b340936756e5d35180eb68d121ae828de4 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 30 May 2019 15:38:27 -0400 +Subject: [PATCH 07/12] Ticket 50413 - ds-replcheck - Always display the Result + Summary + +Description: Previously we only printed a "Result Summary" if there + were no inconsistencies and the entry counts matched. + However, the entry counts do not need to match. So + this made the "Result Summary" checks too strict, and + if things were out of sync there was no Result Summary + printed at all. This fix just always prints a result + summary and it removes the entry count check. + +https://pagure.io/389-ds-base/issue/50413 + +Reviewed by: ? +--- + ldap/admin/src/scripts/ds-replcheck | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck +index 5d7295e50..4abb417af 100755 +--- a/ldap/admin/src/scripts/ds-replcheck ++++ b/ldap/admin/src/scripts/ds-replcheck +@@ -661,14 +661,14 @@ def do_offline_report(opts, output_file=None): + MLDIF = open(opts['mldif'], "r") + except Exception as e: + print('Failed to open Master LDIF: ' + str(e)) +- return None ++ return + + try: + RLDIF = open(opts['rldif'], "r") + except Exception as e: + print('Failed to open Replica LDIF: ' + str(e)) + MLDIF.close() +- return None ++ return + + # Verify LDIF Files + try: +@@ -679,7 +679,7 @@ def do_offline_report(opts, output_file=None): + print('Master LDIF file in invalid, aborting...') + MLDIF.close() + RLDIF.close() +- return None ++ return + try: + if opts['verbose']: + print("Validating Replica ldif file ({})...".format(opts['rldif'])) +@@ -688,7 +688,7 @@ def do_offline_report(opts, output_file=None): + print('Replica LDIF file is invalid, aborting...') + MLDIF.close() + RLDIF.close() +- return None ++ return + + # Get all the dn's, and entry counts + if opts['verbose']: +@@ -845,10 +845,13 @@ def do_offline_report(opts, output_file=None): + final_report += ('=====================================================\n\n') + for diff in diff_report: + final_report += ('%s\n' % (diff)) +- if missing_report == "" and len(diff_report) == 0 and m_count == r_count: +- final_report += ('\nResult\n') +- final_report += ('=====================================================\n\n') +- final_report += ('No differences between Master and Replica\n') ++ ++ final_report += ('\nResult\n') ++ final_report += ('=====================================================\n\n') ++ if missing_report == "" and len(diff_report) == 0: ++ final_report += ('No replication differences between Master and Replica\n') ++ else: ++ final_report += ('There are replication differences between Master and Replica\n') + + if output_file: + output_file.write(final_report) +@@ -1130,10 +1133,12 @@ def print_online_report(report, opts, output_file): + for diff in report['diff']: + final_report += ('%s\n' % (diff)) + +- if not missing and len(report['diff']) == 0 and report['m_count'] == report['r_count']: +- final_report += ('\nResult\n') +- final_report += ('=====================================================\n\n') +- final_report += ('No differences between Master and Replica\n') ++ final_report += ('\nResult\n') ++ final_report += ('=====================================================\n\n') ++ if not missing and len(report['diff']) == 0: ++ final_report += ('No replication differences between Master and Replica\n') ++ else: ++ final_report += ('There are replication differences between Master and Replica\n') + + if output_file: + output_file.write(final_report) +-- +2.21.0 + diff --git a/SOURCES/0012-Issue-49239-Add-a-new-CI-test-case.patch b/SOURCES/0012-Issue-49239-Add-a-new-CI-test-case.patch new file mode 100644 index 0000000..81eab76 --- /dev/null +++ b/SOURCES/0012-Issue-49239-Add-a-new-CI-test-case.patch @@ -0,0 +1,34 @@ +From 2f42d3575b9dd781e7d351853df984db367507af Mon Sep 17 00:00:00 2001 +From: Akshay Adhikari +Date: Wed, 26 Jun 2019 13:56:05 +0530 +Subject: [PATCH 08/12] Issue 49239 - Add a new CI test case + +Bug Description: ds-replcheck unreliable, showing false positives, showing missing tombstone entries +in the report. + +Fix Description: Added a test case to check missing tombstone entries is not reported, also fixed +py3 issue in ds-replcheck by explicitly adding bytes. + +Relates: https://pagure.io/389-ds-base/issue/49239 + +Review by: vashirov, mreynolds (Thanks!) +--- + ldap/admin/src/scripts/ds-replcheck | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck +index 4abb417af..30bcfd65d 100755 +--- a/ldap/admin/src/scripts/ds-replcheck ++++ b/ldap/admin/src/scripts/ds-replcheck +@@ -142,7 +142,7 @@ def convert_entries(entries): + continue + + # lowercase all the objectclass values (easier for tombstone checking) +- oc_vals = new_entry.data['objectclass'] ++ oc_vals = ensure_list_str(new_entry.data['objectclass']) + new_oc_vals = [] + for val in oc_vals: + new_oc_vals.append(val.lower()) +-- +2.21.0 + diff --git a/SOURCES/0013-Ticket-50428-Log-the-actual-base-DN-when-the-search-.patch b/SOURCES/0013-Ticket-50428-Log-the-actual-base-DN-when-the-search-.patch new file mode 100644 index 0000000..c06d4f2 --- /dev/null +++ b/SOURCES/0013-Ticket-50428-Log-the-actual-base-DN-when-the-search-.patch @@ -0,0 +1,43 @@ +From a4f09a83a8899b52e1cf6a96b75483c576dd5bb2 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 7 Jun 2019 11:35:46 +0200 +Subject: [PATCH] Ticket 50428 - Log the actual base DN when the search fails + with "invalid attribute request" + +Bug Description: + When a search request contains invalid parameters (attribute list with empty attribute + name, unknown scope, invalid filter..) the search is rejected but the access log + contains a wrong base search: ... SRCH base="(null)"... + This is because it does not use for logging the variable that gather the actual base ('rawbase') + +Fix Description: + Use 'rawbase' value for logging + +https://pagure.io/389-ds-base/issue/50428 + +Reviewed by: Mark Reynolds + +Platforms tested: F28 + +Flag Day: no + +Doc impact: no +--- + ldap/servers/slapd/search.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c +index 953227ba0..75accbba6 100644 +--- a/ldap/servers/slapd/search.c ++++ b/ldap/servers/slapd/search.c +@@ -154,6 +154,7 @@ do_search(Slapi_PBlock *pb) + goto free_and_return; + } + } ++ base = rawbase; + + /* + * ignore negative time and size limits since they make no sense +-- +2.21.0 + diff --git a/SOURCES/0014-Issue-50474-Unify-result-codes-for-add-and-modify-of.patch b/SOURCES/0014-Issue-50474-Unify-result-codes-for-add-and-modify-of.patch new file mode 100644 index 0000000..618e688 --- /dev/null +++ b/SOURCES/0014-Issue-50474-Unify-result-codes-for-add-and-modify-of.patch @@ -0,0 +1,382 @@ +From 62af3beb9b2a3137a76456f534db7be1b172210c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mat=C3=BA=C5=A1=20Hon=C4=9Bk?= +Date: Wed, 16 Jan 2019 09:49:28 +0100 +Subject: [PATCH] Issue 50474 - Unify result codes for add and modify of repl5 + config + +Bug Description: +Same constraints resulting in error are reported as different LDAP +result codes when using different operation for adjusting these. + +Fix Description: +A part of the code had not conveyed the error reason down the stack, +therefore adding this information and returning the proper code. + +Fixes: https://pagure.io/389-ds-base/issue/50474 + +Author: Matus Honek + +Review by: mreynolds, spichugi (thanks!) +--- + .../suites/replication/replica_config_test.py | 25 +++++-- + ldap/servers/plugins/replication/repl5.h | 2 +- + .../plugins/replication/repl5_replica.c | 71 +++++++++++-------- + .../replication/repl5_replica_config.c | 3 +- + 4 files changed, 63 insertions(+), 38 deletions(-) + +diff --git a/dirsrvtests/tests/suites/replication/replica_config_test.py b/dirsrvtests/tests/suites/replication/replica_config_test.py +index 9a0e1b41f..3dc03713a 100644 +--- a/dirsrvtests/tests/suites/replication/replica_config_test.py ++++ b/dirsrvtests/tests/suites/replication/replica_config_test.py +@@ -4,7 +4,6 @@ import copy + import os + import ldap + from lib389._constants import * +-from lib389 import Entry + from lib389.topologies import topology_st as topo + + from lib389.replica import Replicas +@@ -104,12 +103,14 @@ def agmt_setup(topo): + def perform_invalid_create(many, properties, attr, value): + my_properties = copy.deepcopy(properties) + my_properties[attr] = value +- with pytest.raises(ldap.LDAPError): ++ with pytest.raises(ldap.LDAPError) as ei: + many.create(properties=my_properties) ++ return ei.value + + def perform_invalid_modify(o, attr, value): +- with pytest.raises(ldap.LDAPError): ++ with pytest.raises(ldap.LDAPError) as ei: + o.replace(attr, value) ++ return ei.value + + @pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", repl_add_attrs) + def test_replica_num_add(topo, attr, too_small, too_big, overflow, notnum, valid): +@@ -254,9 +255,25 @@ def test_agmt_num_modify(topo, attr, too_small, too_big, overflow, notnum, valid + # Value is valid + agmt.replace(attr, valid) + ++ ++@pytest.mark.bz1546739 ++def test_same_attr_yields_same_return_code(topo): ++ """Test that various operations with same incorrect attribute value yield same return code ++ """ ++ attr = 'nsDS5ReplicaId' ++ ++ replica_reset(topo) ++ replicas = Replicas(topo.standalone) ++ e = perform_invalid_create(replicas, replica_dict, attr, too_big) ++ assert type(e) is ldap.UNWILLING_TO_PERFORM ++ ++ replica = replica_setup(topo) ++ e = perform_invalid_modify(replica, attr, too_big) ++ assert type(e) is ldap.UNWILLING_TO_PERFORM ++ ++ + 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/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 138578d5f..1801a333e 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -662,7 +662,7 @@ Replica *replica_new(const Slapi_DN *root); + Replica *windows_replica_new(const Slapi_DN *root); + /* this function should be called to construct the replica object + during addition of the replica over LDAP */ +-Replica *replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation); ++int replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation, Replica **r); + 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); +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 6a5363e43..b3f03d5c0 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -128,8 +128,9 @@ replica_new(const Slapi_DN *root) + e = _replica_get_config_entry(root, NULL); + if (e) { + errorbuf[0] = '\0'; +- r = replica_new_from_entry(e, errorbuf, +- PR_FALSE /* not a newly added entry */); ++ replica_new_from_entry(e, errorbuf, ++ PR_FALSE, /* not a newly added entry */ ++ &r); + + if (NULL == r) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_new - " +@@ -143,17 +144,17 @@ replica_new(const Slapi_DN *root) + } + + /* constructs the replica object from the newly added entry */ +-Replica * +-replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) ++int ++replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation, Replica **rp) + { +- int rc = 0; + Replica *r; ++ int rc = LDAP_SUCCESS; + + if (e == NULL) { + if (NULL != errortext) { + PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry"); + } +- return NULL; ++ return LDAP_OTHER; + } + + r = (Replica *)slapi_ch_calloc(1, sizeof(Replica)); +@@ -162,7 +163,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) + if (NULL != errortext) { + PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory"); + } +- rc = -1; ++ rc = LDAP_OTHER; + goto done; + } + +@@ -170,7 +171,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) + if (NULL != errortext) { + PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "failed to create replica lock"); + } +- rc = -1; ++ rc = LDAP_OTHER; + goto done; + } + +@@ -178,7 +179,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) + if (NULL != errortext) { + PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "failed to create replica lock"); + } +- rc = -1; ++ rc = LDAP_OTHER; + goto done; + } + +@@ -191,14 +192,17 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) + + /* read parameters from the replica config entry */ + rc = _replica_init_from_config(r, e, errortext); +- if (rc != 0) { ++ if (rc != LDAP_SUCCESS) { + goto done; + } + + /* configure ruv */ + rc = _replica_configure_ruv(r, PR_FALSE); + if (rc != 0) { ++ rc = LDAP_OTHER; + goto done; ++ } else { ++ rc = LDAP_SUCCESS; + } + + /* If smallest csn exists in RUV for our local replica, it's ok to begin iteration */ +@@ -217,8 +221,12 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) + * (done by the update state event scheduled below) + */ + } +- if (rc != 0) ++ if (rc != 0) { ++ rc = LDAP_OTHER; + goto done; ++ } else { ++ rc = LDAP_SUCCESS; ++ } + + /* ONREPL - the state update can occur before the entry is added to the DIT. + In that case the updated would fail but nothing bad would happen. The next +@@ -237,11 +245,12 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation) + } + + done: +- if (rc != 0 && r) { ++ if (rc != LDAP_SUCCESS && r) { + replica_destroy((void **)&r); + } + +- return r; ++ *rp = r; ++ return rc; + } + + +@@ -1789,9 +1798,9 @@ _replica_check_validity(const Replica *r) + + if (r->repl_root == NULL || r->repl_type == 0 || r->repl_rid == 0 || + r->repl_csngen == NULL || r->repl_name == NULL) { +- return -1; ++ return LDAP_OTHER; + } else { +- return 0; ++ return LDAP_SUCCESS; + } + } + +@@ -1841,7 +1850,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + (char *)slapi_entry_get_dn((Slapi_Entry *)e)); + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - %s\n", + errormsg); +- return -1; ++ return LDAP_OTHER; + } + + r->repl_root = slapi_sdn_new_dn_passin(val); +@@ -1851,7 +1860,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, attr_replicaType))) { + if (repl_config_valid_num(attr_replicaType, val, 0, REPLICA_TYPE_UPDATABLE, &rc, errormsg, &rtype) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + r->repl_type = rtype; + slapi_ch_free_string(&val); +@@ -1867,7 +1876,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, type_replicaBackoffMin))) { + if (repl_config_valid_num(type_replicaBackoffMin, val, 1, INT_MAX, &rc, errormsg, &backoff_min) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + slapi_ch_free_string(&val); + } else { +@@ -1882,7 +1891,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, type_replicaBackoffMax))) { + if (repl_config_valid_num(type_replicaBackoffMax, val, 1, INT_MAX, &rc, errormsg, &backoff_max) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + slapi_ch_free_string(&val); + } else { +@@ -1899,7 +1908,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + backoff_min, backoff_max); + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - " + "%s\n", errormsg); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } else { + slapi_counter_set_value(r->backoff_min, backoff_min); + slapi_counter_set_value(r->backoff_max, backoff_max); +@@ -1910,7 +1919,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, type_replicaProtocolTimeout))) { + if (repl_config_valid_num(type_replicaProtocolTimeout, val, 0, INT_MAX, &rc, errormsg, &ptimeout) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + slapi_ch_free_string(&val); + slapi_counter_set_value(r->protocol_timeout, ptimeout); +@@ -1926,7 +1935,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, type_replicaReleaseTimeout))) { + if (repl_config_valid_num(type_replicaReleaseTimeout, val, 0, INT_MAX, &rc, errortext, &release_timeout) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + slapi_counter_set_value(r->release_timeout, release_timeout); + slapi_ch_free_string(&val); +@@ -1950,7 +1959,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + type_replicaPrecisePurge, precise_purging); + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - " + "%s\n", errormsg); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + slapi_ch_free_string(&precise_purging); + } else { +@@ -1963,7 +1972,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if((val = slapi_entry_attr_get_charptr(e, attr_flags))) { + if (repl_config_valid_num(attr_flags, val, 0, 1, &rc, errortext, &rflags) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + r->repl_flags = (uint32_t)rflags; + slapi_ch_free_string(&val); +@@ -1990,7 +1999,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + int64_t rid; + if (repl_config_valid_num(attr_replicaId, val, 1, 65534, &rc, errormsg, &rid) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + r->repl_rid = (ReplicaId)rid; + slapi_ch_free_string(&val); +@@ -2000,7 +2009,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + attr_replicaId, (char *)slapi_entry_get_dn((Slapi_Entry *)e)); + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "_replica_init_from_config - %s\n", errormsg); +- return -1; ++ return LDAP_OTHER; + } + } + +@@ -2013,7 +2022,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + (char *)slapi_entry_get_dn((Slapi_Entry *)e)); + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "_replica_init_from_config - %s\n", errormsg); +- return -1; ++ return LDAP_OTHER; + } + r->repl_csngen = object_new((void *)gen, (FNFree)csngen_free); + +@@ -2031,7 +2040,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, attr_replicaBindDnGroupCheckInterval))) { + if (repl_config_valid_num(attr_replicaBindDnGroupCheckInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + r->updatedn_group_check_interval = interval; + slapi_ch_free_string(&val); +@@ -2051,7 +2060,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + (char *)slapi_entry_get_dn((Slapi_Entry *)e), rc); + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - %s\n", + errormsg); +- return -1; ++ return LDAP_OTHER; + } else + r->new_name = PR_TRUE; + } +@@ -2072,7 +2081,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, type_replicaPurgeDelay))) { + if (repl_config_valid_num(type_replicaPurgeDelay, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + r->repl_purge_delay = interval; + slapi_ch_free_string(&val); +@@ -2083,7 +2092,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) + if ((val = slapi_entry_attr_get_charptr(e, type_replicaTombstonePurgeInterval))) { + if (repl_config_valid_num(type_replicaTombstonePurgeInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) { + slapi_ch_free_string(&val); +- return -1; ++ return LDAP_UNWILLING_TO_PERFORM; + } + r->tombstone_reap_interval = interval; + slapi_ch_free_string(&val); +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 7649aa14e..749e90936 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -267,9 +267,8 @@ replica_config_add(Slapi_PBlock *pb __attribute__((unused)), + } + + /* create replica object */ +- r = replica_new_from_entry(e, errortext, PR_TRUE /* is a newly added entry */); ++ *returncode = replica_new_from_entry(e, errortext, PR_TRUE /* is a newly added entry */, &r); + if (r == NULL) { +- *returncode = LDAP_OPERATIONS_ERROR; + goto done; + } + +-- +2.21.0 + diff --git a/SOURCES/0015-Ticket-49789-By-default-do-not-manage-unhashed-passw.patch b/SOURCES/0015-Ticket-49789-By-default-do-not-manage-unhashed-passw.patch new file mode 100644 index 0000000..03e5d35 --- /dev/null +++ b/SOURCES/0015-Ticket-49789-By-default-do-not-manage-unhashed-passw.patch @@ -0,0 +1,192 @@ +From d9e895e928c39ca66e272a61a431fa3bfc3d8f5c Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 13 Jul 2018 17:55:27 +0200 +Subject: [PATCH] Ticket 49789 - By default, do not manage unhashed password + +Bug Description: + By default, unhashed#user#password is recorded into changelog database. + It is a specific use when some plugin need to know the clear text password on update. + This should be disabled ('off') by default + +Fix Description: + Switch the default value from 'on' to 'off' + +https://pagure.io/389-ds-base/issue/49789 + +Reviewed by: Viktor Ashirov, Simon Pichugi, Mark Reynolds + +Platforms tested: F28 + +Flag Day: no + +Doc impact: no +--- + .../tests/suites/password/regression_test.py | 121 +++++++++++++++++- + ldap/servers/slapd/slap.h | 4 +- + 2 files changed, 122 insertions(+), 3 deletions(-) + +diff --git a/dirsrvtests/tests/suites/password/regression_test.py b/dirsrvtests/tests/suites/password/regression_test.py +index b01b73e2e..c239799e4 100644 +--- a/dirsrvtests/tests/suites/password/regression_test.py ++++ b/dirsrvtests/tests/suites/password/regression_test.py +@@ -8,8 +8,11 @@ + import pytest + import time + from lib389._constants import PASSWORD, DN_DM, DEFAULT_SUFFIX ++from lib389._constants import SUFFIX, PASSWORD, DN_DM, DN_CONFIG, PLUGIN_RETRO_CHANGELOG, DEFAULT_SUFFIX, DEFAULT_CHANGELOG_DB ++from lib389 import Entry ++from lib389.topologies import topology_m1 as topo_master + from lib389.idm.user import UserAccounts +-from lib389.utils import ldap, os, logging ++from lib389.utils import ldap, os, logging, ensure_bytes + from lib389.topologies import topology_st as topo + from lib389.idm.organizationalunit import OrganizationalUnits + +@@ -36,6 +39,23 @@ TEST_PASSWORDS += ['CNpwtest1ZZZZ', 'ZZZZZCNpwtest1', + TEST_PASSWORDS2 = ( + 'CN12pwtest31', 'SN3pwtest231', 'UID1pwtest123', 'MAIL2pwtest12@redhat.com', '2GN1pwtest123', 'People123') + ++def _check_unhashed_userpw(inst, user_dn, is_present=False): ++ """Check if unhashed#user#password attribute is present of not in the changelog""" ++ unhashed_pwd_attribute = 'unhashed#user#password' ++ ++ changelog_dbdir = os.path.join(os.path.dirname(inst.dbdir), DEFAULT_CHANGELOG_DB) ++ for dbfile in os.listdir(changelog_dbdir): ++ if dbfile.endswith('.db'): ++ changelog_dbfile = os.path.join(changelog_dbdir, dbfile) ++ log.info('Changelog dbfile file exist: {}'.format(changelog_dbfile)) ++ log.info('Running dbscan -f to check {} attr'.format(unhashed_pwd_attribute)) ++ dbscanOut = inst.dbscan(DEFAULT_CHANGELOG_DB, changelog_dbfile) ++ for entry in dbscanOut.split(b'dbid: '): ++ if ensure_bytes('operation: modify') in entry and ensure_bytes(user_dn) in entry and ensure_bytes('userPassword') in entry: ++ if is_present: ++ assert ensure_bytes(unhashed_pwd_attribute) in entry ++ else: ++ assert ensure_bytes(unhashed_pwd_attribute) not in entry + + @pytest.fixture(scope="module") + def passw_policy(topo, request): +@@ -193,6 +213,105 @@ def test_global_vs_local(topo, passw_policy, create_user, user_pasw): + # reset password + create_user.set('userPassword', PASSWORD) + ++@pytest.mark.ds49789 ++def test_unhashed_pw_switch(topo_master): ++ """Check that nsslapd-unhashed-pw-switch works corrently ++ ++ :id: e5aba180-d174-424d-92b0-14fe7bb0b92a ++ :setup: Master Instance ++ :steps: ++ 1. A Master is created, enable retrocl (not used here) ++ 2. create a set of users ++ 3. update userpassword of user1 and check that unhashed#user#password is not logged (default) ++ 4. udpate userpassword of user2 and check that unhashed#user#password is not logged ('nolog') ++ 5. udpate userpassword of user3 and check that unhashed#user#password is logged ('on') ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3 Success (unhashed#user#password is not logged in the replication changelog) ++ 4. Success (unhashed#user#password is not logged in the replication changelog) ++ 5. Success (unhashed#user#password is logged in the replication changelog) ++ """ ++ MAX_USERS = 10 ++ PEOPLE_DN = ("ou=people," + DEFAULT_SUFFIX) ++ ++ inst = topo_master.ms["master1"] ++ inst.modify_s("cn=Retro Changelog Plugin,cn=plugins,cn=config", ++ [(ldap.MOD_REPLACE, 'nsslapd-changelogmaxage', b'2m'), ++ (ldap.MOD_REPLACE, 'nsslapd-changelog-trim-interval', b"5s"), ++ (ldap.MOD_REPLACE, 'nsslapd-logAccess', b'on')]) ++ inst.config.loglevel(vals=[256 + 4], service='access') ++ inst.restart() ++ # If you need any test suite initialization, ++ # please, write additional fixture for that (including finalizer). ++ # Topology for suites are predefined in lib389/topologies.py. ++ ++ # enable dynamic plugins, memberof and retro cl plugin ++ # ++ log.info('Enable plugins...') ++ try: ++ inst.modify_s(DN_CONFIG, ++ [(ldap.MOD_REPLACE, ++ 'nsslapd-dynamic-plugins', ++ b'on')]) ++ except ldap.LDAPError as e: ++ ldap.error('Failed to enable dynamic plugins! ' + e.message['desc']) ++ assert False ++ ++ #topology_st.standalone.plugins.enable(name=PLUGIN_MEMBER_OF) ++ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG) ++ #topology_st.standalone.modify_s("cn=changelog,cn=ldbm database,cn=plugins,cn=config", [(ldap.MOD_REPLACE, 'nsslapd-cachememsize', str(100000))]) ++ inst.restart() ++ ++ log.info('create users and group...') ++ for idx in range(1, MAX_USERS): ++ try: ++ USER_DN = ("uid=member%d,%s" % (idx, PEOPLE_DN)) ++ inst.add_s(Entry((USER_DN, ++ {'objectclass': 'top extensibleObject'.split(), ++ 'uid': 'member%d' % (idx)}))) ++ except ldap.LDAPError as e: ++ log.fatal('Failed to add user (%s): error %s' % (USER_DN, e.message['desc'])) ++ assert False ++ ++ # Check default is that unhashed#user#password is not logged ++ user = "uid=member1,%s" % (PEOPLE_DN) ++ inst.modify_s(user, [(ldap.MOD_REPLACE, ++ 'userpassword', ++ PASSWORD.encode())]) ++ inst.stop() ++ _check_unhashed_userpw(inst, user, is_present=False) ++ ++ # Check with nolog that unhashed#user#password is not logged ++ inst.modify_s(DN_CONFIG, ++ [(ldap.MOD_REPLACE, ++ 'nsslapd-unhashed-pw-switch', ++ b'nolog')]) ++ inst.restart() ++ user = "uid=member2,%s" % (PEOPLE_DN) ++ inst.modify_s(user, [(ldap.MOD_REPLACE, ++ 'userpassword', ++ PASSWORD.encode())]) ++ inst.stop() ++ _check_unhashed_userpw(inst, user, is_present=False) ++ ++ # Check with value 'on' that unhashed#user#password is logged ++ inst.modify_s(DN_CONFIG, ++ [(ldap.MOD_REPLACE, ++ 'nsslapd-unhashed-pw-switch', ++ b'on')]) ++ inst.restart() ++ user = "uid=member3,%s" % (PEOPLE_DN) ++ inst.modify_s(user, [(ldap.MOD_REPLACE, ++ 'userpassword', ++ PASSWORD.encode())]) ++ inst.stop() ++ _check_unhashed_userpw(inst, user, is_present=True) ++ ++ if DEBUGGING: ++ # Add debugging steps(if any)... ++ pass ++ + + if __name__ == '__main__': + # Run isolated +diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h +index b3ede6f7c..a1b68b7b6 100644 +--- a/ldap/servers/slapd/slap.h ++++ b/ldap/servers/slapd/slap.h +@@ -295,8 +295,8 @@ typedef void (*VFPV)(); /* takes undefined arguments */ + #define SLAPD_DEFAULT_VALIDATE_CERT SLAPD_VALIDATE_CERT_WARN + #define SLAPD_DEFAULT_VALIDATE_CERT_STR "warn" + +-#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH SLAPD_UNHASHED_PW_ON +-#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH_STR "on" ++#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH SLAPD_UNHASHED_PW_OFF ++#define SLAPD_DEFAULT_UNHASHED_PW_SWITCH_STR "off" + + #define SLAPD_DEFAULT_LDAPI_SEARCH_BASE "dc=example,dc=com" + #define SLAPD_DEFAULT_LDAPI_AUTO_DN "cn=peercred,cn=external,cn=auth" +-- +2.21.0 + diff --git a/SOURCES/0016-Ticket-50329-2nd-Possible-Security-Issue-DOS-due-to-.patch b/SOURCES/0016-Ticket-50329-2nd-Possible-Security-Issue-DOS-due-to-.patch new file mode 100644 index 0000000..11bbfa5 --- /dev/null +++ b/SOURCES/0016-Ticket-50329-2nd-Possible-Security-Issue-DOS-due-to-.patch @@ -0,0 +1,46 @@ +From 5da265eb9a023964f00d3ff6b54bcc64107dcf5a Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Wed, 15 May 2019 17:46:14 +0200 +Subject: [PATCH] Ticket 50329 - (2nd) Possible Security Issue: DOS due to + ioblocktimeout not applying to TLS + +Bug Description: + A secure socket is configured in blocking mode. If an event + is detected on a secure socket a worker tries to receive the request. + If handshake occurs during the read, it can hang longer than + ioblocktimeout because it takes into account the socket option + rather than the timeout used for the ssl_Recv + +Fix Description: + The fix is specific to secure socket and set this socket option + to do non blocking IO. + +https://pagure.io/389-ds-base/issue/50329 + +Reviewed by: ? + +Platforms tested: F28, RHEL7.6 + +Flag Day: no + +Doc impact: no +--- + ldap/servers/slapd/daemon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c +index 2daa21034..519fd2f86 100644 +--- a/ldap/servers/slapd/daemon.c ++++ b/ldap/servers/slapd/daemon.c +@@ -3174,7 +3174,7 @@ configure_pr_socket(PRFileDesc **pr_socket, int secure, int local) + + if (secure) { + pr_socketoption.option = PR_SockOpt_Nonblocking; +- pr_socketoption.value.non_blocking = 0; ++ pr_socketoption.value.non_blocking = 1; + if (PR_SetSocketOption(*pr_socket, &pr_socketoption) == PR_FAILURE) { + PRErrorCode prerr = PR_GetError(); + slapi_log_err(SLAPI_LOG_ERR, +-- +2.21.0 + diff --git a/SOURCES/0017-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch b/SOURCES/0017-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch new file mode 100644 index 0000000..49e24f3 --- /dev/null +++ b/SOURCES/0017-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch @@ -0,0 +1,779 @@ +From bc438614f71d18e337a56b49a67627299658b649 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 7 Aug 2019 20:36:53 -0400 +Subject: [PATCH 1/4] Issue 50538 - cleanAllRUV task limit is not enforced for + replicated tasks + +Bug Description: + +There is a hard limit of 64 concurrent cleanAllRUV tasks, but this limit is +only enforced when creating "new" tasks. It was not enforced when a task was +received via an extended operation. There were also race conditions in the +existing logic that allowed the array of cleaned rids to get corrupted . This +allowed for a very large number of task threads to be created. + +Fix Description: + +Maintain a new counter to keep track of the number of clean and abort threads +to make sure it never over runs the rid array buffers. + +relates: https://pagure.io/389-ds-base/issue/50538 + +Reviewed by: lkrispenz(Thanks!) +--- + .../suites/replication/cleanallruv_test.py | 144 +++++++++- + ldap/servers/plugins/replication/repl5.h | 7 +- + .../replication/repl5_replica_config.c | 247 ++++++++++-------- + ldap/servers/plugins/replication/repl_extop.c | 19 +- + 4 files changed, 299 insertions(+), 118 deletions(-) + +diff --git a/dirsrvtests/tests/suites/replication/cleanallruv_test.py b/dirsrvtests/tests/suites/replication/cleanallruv_test.py +index 09805d6b2..4893b81fe 100644 +--- a/dirsrvtests/tests/suites/replication/cleanallruv_test.py ++++ b/dirsrvtests/tests/suites/replication/cleanallruv_test.py +@@ -1,5 +1,5 @@ + # --- BEGIN COPYRIGHT BLOCK --- +-# Copyright (C) 2016 Red Hat, Inc. ++# Copyright (C) 2019 Red Hat, Inc. + # All rights reserved. + # + # License: GPL (version 3 or any later version). +@@ -7,7 +7,6 @@ + # --- END COPYRIGHT BLOCK --- + # + import threading +- + import pytest + import random + from lib389 import DirSrv +@@ -721,6 +720,147 @@ def test_multiple_tasks_with_force(topology_m4, m4rid): + log.fatal('test_abort: CleanAllRUV task was not aborted') + assert False + ++ ++@pytest.mark.bz1466441 ++@pytest.mark.ds50370 ++def test_clean_shutdown_crash(topology_m2): ++ """Check that server didn't crash after shutdown when running CleanAllRUV task ++ ++ :id: c34d0b40-3c3e-4f53-8656-5e4c2a310aaf ++ :setup: Replication setup with two masters ++ :steps: ++ 1. Enable TLS on both masters ++ 2. Reconfigure both agreements to use TLS Client auth ++ 3. Stop master2 ++ 4. Run the CleanAllRUV task ++ 5. Restart master1 ++ 6. Check if master1 didn't crash ++ 7. Restart master1 again ++ 8. Check if master1 didn't crash ++ ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ 4. Success ++ 5. Success ++ 6. Success ++ 7. Success ++ 8. Success ++ """ ++ ++ m1 = topology_m2.ms["master1"] ++ m2 = topology_m2.ms["master2"] ++ ++ repl = ReplicationManager(DEFAULT_SUFFIX) ++ ++ cm_m1 = CertmapLegacy(m1) ++ cm_m2 = CertmapLegacy(m2) ++ ++ certmaps = cm_m1.list() ++ certmaps['default']['DNComps'] = None ++ certmaps['default']['CmapLdapAttr'] = 'nsCertSubjectDN' ++ ++ cm_m1.set(certmaps) ++ cm_m2.set(certmaps) ++ ++ log.info('Enabling TLS') ++ [i.enable_tls() for i in topology_m2] ++ ++ log.info('Creating replication dns') ++ services = ServiceAccounts(m1, DEFAULT_SUFFIX) ++ repl_m1 = services.get('%s:%s' % (m1.host, m1.sslport)) ++ repl_m1.set('nsCertSubjectDN', m1.get_server_tls_subject()) ++ ++ repl_m2 = services.get('%s:%s' % (m2.host, m2.sslport)) ++ repl_m2.set('nsCertSubjectDN', m2.get_server_tls_subject()) ++ ++ log.info('Changing auth type') ++ replica_m1 = Replicas(m1).get(DEFAULT_SUFFIX) ++ agmt_m1 = replica_m1.get_agreements().list()[0] ++ agmt_m1.replace_many( ++ ('nsDS5ReplicaBindMethod', 'SSLCLIENTAUTH'), ++ ('nsDS5ReplicaTransportInfo', 'SSL'), ++ ('nsDS5ReplicaPort', '%s' % m2.sslport), ++ ) ++ ++ agmt_m1.remove_all('nsDS5ReplicaBindDN') ++ ++ replica_m2 = Replicas(m2).get(DEFAULT_SUFFIX) ++ agmt_m2 = replica_m2.get_agreements().list()[0] ++ ++ agmt_m2.replace_many( ++ ('nsDS5ReplicaBindMethod', 'SSLCLIENTAUTH'), ++ ('nsDS5ReplicaTransportInfo', 'SSL'), ++ ('nsDS5ReplicaPort', '%s' % m1.sslport), ++ ) ++ agmt_m2.remove_all('nsDS5ReplicaBindDN') ++ ++ log.info('Stopping master2') ++ m2.stop() ++ ++ log.info('Run the cleanAllRUV task') ++ cruv_task = CleanAllRUVTask(m1) ++ cruv_task.create(properties={ ++ 'replica-id': repl.get_rid(m1), ++ 'replica-base-dn': DEFAULT_SUFFIX, ++ 'replica-force-cleaning': 'no', ++ 'replica-certify-all': 'yes' ++ }) ++ ++ m1.restart() ++ ++ log.info('Check if master1 crashed') ++ assert not m1.detectDisorderlyShutdown() ++ ++ log.info('Repeat') ++ m1.restart() ++ assert not m1.detectDisorderlyShutdown() ++ ++ ++def test_max_tasks(topology_m4): ++ """Test we can not create more than 64 cleaning tasks ++ ++ :id: c34d0b40-3c3e-4f53-8656-5e4c2a310a1f ++ :setup: Replication setup with four masters ++ :steps: ++ 1. Stop masters 3 & 4 ++ 2. Create over 64 tasks between m1 and m2 ++ 3. Check logs to see if (>65) tasks were rejected ++ ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ """ ++ ++ # Stop masters 3 & 4 ++ m1 = topology_m4.ms["master1"] ++ m2 = topology_m4.ms["master2"] ++ m3 = topology_m4.ms["master3"] ++ m4 = topology_m4.ms["master4"] ++ m3.stop() ++ m4.stop() ++ ++ # Add over 64 tasks between master1 & 2 to try to exceed the 64 task limit ++ for i in range(1, 64): ++ cruv_task = CleanAllRUVTask(m1) ++ cruv_task.create(properties={ ++ 'replica-id': str(i), ++ 'replica-base-dn': DEFAULT_SUFFIX, ++ 'replica-force-cleaning': 'no', # This forces these tasks to stick around ++ }) ++ cruv_task = CleanAllRUVTask(m2) ++ cruv_task.create(properties={ ++ 'replica-id': "10" + str(i), ++ 'replica-base-dn': DEFAULT_SUFFIX, ++ 'replica-force-cleaning': 'yes', # This allows the tasks to propagate ++ }) ++ ++ # Check the errors log for our error message in master 1 ++ assert m1.searchErrorsLog('Exceeded maximum number of active CLEANALLRUV tasks') ++ ++ + if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode +diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 1801a333e..9d25f2305 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -80,6 +80,8 @@ + #define CLEANRUV_FINISHED "finished" + #define CLEANRUV_CLEANING "cleaning" + #define CLEANRUV_NO_MAXCSN "no maxcsn" ++#define CLEANALLRUV_ID "CleanAllRUV Task" ++#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task" + + /* DS 5.0 replication protocol error codes */ + #define NSDS50_REPL_REPLICA_READY 0x00 /* Replica ready, go ahead */ +@@ -784,6 +786,7 @@ void multimaster_mtnode_construct_replicas(void); + void multimaster_be_state_change(void *handle, char *be_name, int old_be_state, int new_be_state); + + #define CLEANRIDSIZ 64 /* maximum number for concurrent CLEANALLRUV tasks */ ++#define CLEANRID_BUFSIZ 128 + + typedef struct _cleanruv_data + { +@@ -815,6 +818,8 @@ int get_replica_type(Replica *r); + int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid); + void add_cleaned_rid(cleanruv_data *data); + int is_cleaned_rid(ReplicaId rid); ++int32_t check_and_set_cleanruv_task_count(ReplicaId rid); ++int32_t check_and_set_abort_cleanruv_task_count(void); + int replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg); + void replica_cleanallruv_thread_ext(void *arg); + void stop_ruv_cleaning(void); +@@ -833,8 +838,6 @@ void set_cleaned_rid(ReplicaId rid); + void cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fmt, ...); + char *replica_cleanallruv_get_local_maxcsn(ReplicaId rid, char *base_dn); + +- +- + /* replutil.c */ + LDAPControl *create_managedsait_control(void); + LDAPControl *create_backend_control(Slapi_DN *sdn); +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 749e90936..c66a1c81d 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -30,17 +30,18 @@ + #define CLEANALLRUV "CLEANALLRUV" + #define CLEANALLRUVLEN 11 + #define REPLICA_RDN "cn=replica" +-#define CLEANALLRUV_ID "CleanAllRUV Task" +-#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task" + + int slapi_log_urp = SLAPI_LOG_REPL; +-static ReplicaId cleaned_rids[CLEANRIDSIZ + 1] = {0}; +-static ReplicaId pre_cleaned_rids[CLEANRIDSIZ + 1] = {0}; +-static ReplicaId aborted_rids[CLEANRIDSIZ + 1] = {0}; +-static Slapi_RWLock *rid_lock = NULL; +-static Slapi_RWLock *abort_rid_lock = NULL; ++static ReplicaId cleaned_rids[CLEANRID_BUFSIZ] = {0}; ++static ReplicaId pre_cleaned_rids[CLEANRID_BUFSIZ] = {0}; ++static ReplicaId aborted_rids[CLEANRID_BUFSIZ] = {0}; ++static PRLock *rid_lock = NULL; ++static PRLock *abort_rid_lock = NULL; + static PRLock *notify_lock = NULL; + static PRCondVar *notify_cvar = NULL; ++static PRLock *task_count_lock = NULL; ++static int32_t clean_task_count = 0; ++static int32_t abort_task_count = 0; + + /* Forward Declartions */ + static int replica_config_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg); +@@ -67,8 +68,6 @@ static int replica_cleanallruv_send_abort_extop(Repl_Agmt *ra, Slapi_Task *task, + static int replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *basedn, char *rid_text, char *maxcsn, Slapi_Task *task); + static int replica_cleanallruv_replica_alive(Repl_Agmt *agmt); + static int replica_cleanallruv_check_ruv(char *repl_root, Repl_Agmt *ra, char *rid_text, Slapi_Task *task, char *force); +-static int get_cleanruv_task_count(void); +-static int get_abort_cleanruv_task_count(void); + static int replica_cleanup_task(Object *r, const char *task_name, char *returntext, int apply_mods); + static int replica_task_done(Replica *replica); + static void delete_cleaned_rid_config(cleanruv_data *data); +@@ -114,20 +113,27 @@ replica_config_init() + PR_GetError()); + return -1; + } +- rid_lock = slapi_new_rwlock(); ++ rid_lock = PR_NewLock(); + if (rid_lock == NULL) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - " + "Failed to create rid_lock; NSPR error - %d\n", + PR_GetError()); + return -1; + } +- abort_rid_lock = slapi_new_rwlock(); ++ abort_rid_lock = PR_NewLock(); + if (abort_rid_lock == NULL) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - " + "Failed to create abort_rid_lock; NSPR error - %d\n", + PR_GetError()); + return -1; + } ++ task_count_lock = PR_NewLock(); ++ if (task_count_lock == NULL) { ++ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - " ++ "Failed to create task_count_lock; NSPR error - %d\n", ++ PR_GetError()); ++ return -1; ++ } + if ((notify_lock = PR_NewLock()) == NULL) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - " + "Failed to create notify lock; NSPR error - %d\n", +@@ -1533,12 +1539,6 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co + + cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Initiating CleanAllRUV Task..."); + +- if (get_cleanruv_task_count() >= CLEANRIDSIZ) { +- /* we are already running the maximum number of tasks */ +- cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, +- "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ); +- return LDAP_UNWILLING_TO_PERFORM; +- } + /* + * Grab the replica + */ +@@ -1590,6 +1590,13 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co + goto fail; + } + ++ if (check_and_set_cleanruv_task_count(rid) != LDAP_SUCCESS) { ++ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, ++ "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ); ++ rc = LDAP_UNWILLING_TO_PERFORM; ++ goto fail; ++ } ++ + /* + * Launch the cleanallruv thread. Once all the replicas are cleaned it will release the rid + */ +@@ -1597,6 +1604,9 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co + if (data == NULL) { + cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Failed to allocate cleanruv_data. Aborting task."); + rc = -1; ++ PR_Lock(task_count_lock); ++ clean_task_count--; ++ PR_Unlock(task_count_lock); + goto fail; + } + data->repl_obj = r; +@@ -1679,13 +1689,13 @@ replica_cleanallruv_thread(void *arg) + int aborted = 0; + int rc = 0; + +- if (!data || slapi_is_shutting_down()) { +- return; /* no data */ +- } +- + /* Increase active thread count to prevent a race condition at server shutdown */ + g_incr_active_threadcnt(); + ++ if (!data || slapi_is_shutting_down()) { ++ goto done; ++ } ++ + if (data->task) { + slapi_task_inc_refcount(data->task); + slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name, +@@ -1732,16 +1742,13 @@ replica_cleanallruv_thread(void *arg) + slapi_task_begin(data->task, 1); + } + /* +- * Presetting the rid prevents duplicate thread creation, but allows the db and changelog to still +- * process updates from the rid. +- * set_cleaned_rid() blocks updates, so we don't want to do that... yet unless we are in force mode. +- * If we are forcing a clean independent of state of other servers for this RID we can set_cleaned_rid() ++ * We have already preset this rid, but if we are forcing a clean independent of state ++ * of other servers for this RID we can set_cleaned_rid() + */ + if (data->force) { + set_cleaned_rid(data->rid); +- } else { +- preset_cleaned_rid(data->rid); + } ++ + rid_text = slapi_ch_smprintf("%d", data->rid); + csn_as_string(data->maxcsn, PR_FALSE, csnstr); + /* +@@ -1911,6 +1918,9 @@ done: + /* + * If the replicas are cleaned, release the rid + */ ++ if (slapi_is_shutting_down()) { ++ stop_ruv_cleaning(); ++ } + if (!aborted && !slapi_is_shutting_down()) { + /* + * Success - the rid has been cleaned! +@@ -1929,10 +1939,9 @@ done: + } else { + cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Propagated task does not delete Keep alive entry (%d).", data->rid); + } +- + clean_agmts(data); + remove_cleaned_rid(data->rid); +- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d).", data->rid); ++ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d)", data->rid); + } else { + /* + * Shutdown or abort +@@ -1965,6 +1974,10 @@ done: + slapi_ch_free_string(&data->force); + slapi_ch_free_string(&rid_text); + slapi_ch_free((void **)&data); ++ /* decrement task count */ ++ PR_Lock(task_count_lock); ++ clean_task_count--; ++ PR_Unlock(task_count_lock); + g_decr_active_threadcnt(); + } + +@@ -2462,16 +2475,14 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, cleanruv_data *clean_data) + int + is_cleaned_rid(ReplicaId rid) + { +- int i; +- +- slapi_rwlock_rdlock(rid_lock); +- for (i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != 0; i++) { ++ PR_Lock(rid_lock); ++ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) { + if (rid == cleaned_rids[i]) { +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + return 1; + } + } +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + + return 0; + } +@@ -2479,16 +2490,14 @@ is_cleaned_rid(ReplicaId rid) + int + is_pre_cleaned_rid(ReplicaId rid) + { +- int i; +- +- slapi_rwlock_rdlock(rid_lock); +- for (i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != 0; i++) { ++ PR_Lock(rid_lock); ++ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) { + if (rid == pre_cleaned_rids[i]) { +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + return 1; + } + } +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + + return 0; + } +@@ -2501,14 +2510,14 @@ is_task_aborted(ReplicaId rid) + if (rid == 0) { + return 0; + } +- slapi_rwlock_rdlock(abort_rid_lock); +- for (i = 0; i < CLEANRIDSIZ && aborted_rids[i] != 0; i++) { ++ PR_Lock(abort_rid_lock); ++ for (i = 0; i < CLEANRID_BUFSIZ && aborted_rids[i] != 0; i++) { + if (rid == aborted_rids[i]) { +- slapi_rwlock_unlock(abort_rid_lock); ++ PR_Unlock(abort_rid_lock); + return 1; + } + } +- slapi_rwlock_unlock(abort_rid_lock); ++ PR_Unlock(abort_rid_lock); + return 0; + } + +@@ -2517,15 +2526,14 @@ preset_cleaned_rid(ReplicaId rid) + { + int i; + +- slapi_rwlock_wrlock(rid_lock); +- for (i = 0; i < CLEANRIDSIZ; i++) { ++ PR_Lock(rid_lock); ++ for (i = 0; i < CLEANRID_BUFSIZ && pre_cleaned_rids[i] != rid; i++) { + if (pre_cleaned_rids[i] == 0) { + pre_cleaned_rids[i] = rid; +- pre_cleaned_rids[i + 1] = 0; + break; + } + } +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + } + + /* +@@ -2538,14 +2546,13 @@ set_cleaned_rid(ReplicaId rid) + { + int i; + +- slapi_rwlock_wrlock(rid_lock); +- for (i = 0; i < CLEANRIDSIZ; i++) { ++ PR_Lock(rid_lock); ++ for (i = 0; i < CLEANRID_BUFSIZ && cleaned_rids[i] != rid; i++) { + if (cleaned_rids[i] == 0) { + cleaned_rids[i] = rid; +- cleaned_rids[i + 1] = 0; + } + } +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + } + + /* +@@ -2621,15 +2628,14 @@ add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root, char *certify_all, P + int rc; + int i; + +- slapi_rwlock_wrlock(abort_rid_lock); +- for (i = 0; i < CLEANRIDSIZ; i++) { ++ PR_Lock(abort_rid_lock); ++ for (i = 0; i < CLEANRID_BUFSIZ; i++) { + if (aborted_rids[i] == 0) { + aborted_rids[i] = rid; +- aborted_rids[i + 1] = 0; + break; + } + } +- slapi_rwlock_unlock(abort_rid_lock); ++ PR_Unlock(abort_rid_lock); + /* + * Write the rid to the config entry + */ +@@ -2672,21 +2678,24 @@ delete_aborted_rid(Replica *r, ReplicaId rid, char *repl_root, char *certify_all + char *data; + char *dn; + int rc; +- int i; + + if (r == NULL) + return; + + if (skip) { + /* skip the deleting of the config, and just remove the in memory rid */ +- slapi_rwlock_wrlock(abort_rid_lock); +- for (i = 0; i < CLEANRIDSIZ && aborted_rids[i] != rid; i++) +- ; /* found rid, stop */ +- for (; i < CLEANRIDSIZ; i++) { +- /* rewrite entire array */ +- aborted_rids[i] = aborted_rids[i + 1]; +- } +- slapi_rwlock_unlock(abort_rid_lock); ++ ReplicaId new_abort_rids[CLEANRID_BUFSIZ] = {0}; ++ int32_t idx = 0; ++ ++ PR_Lock(abort_rid_lock); ++ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) { ++ if (aborted_rids[i] != rid) { ++ new_abort_rids[idx] = aborted_rids[i]; ++ idx++; ++ } ++ } ++ memcpy(aborted_rids, new_abort_rids, sizeof(new_abort_rids)); ++ PR_Unlock(abort_rid_lock); + } else { + /* only remove the config, leave the in-memory rid */ + dn = replica_get_dn(r); +@@ -2832,27 +2841,31 @@ bail: + void + remove_cleaned_rid(ReplicaId rid) + { +- int i; +- /* +- * Remove this rid, and optimize the array +- */ +- slapi_rwlock_wrlock(rid_lock); ++ ReplicaId new_cleaned_rids[CLEANRID_BUFSIZ] = {0}; ++ ReplicaId new_pre_cleaned_rids[CLEANRID_BUFSIZ] = {0}; ++ size_t idx = 0; ++ ++ PR_Lock(rid_lock); + +- for (i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != rid; i++) +- ; /* found rid, stop */ +- for (; i < CLEANRIDSIZ; i++) { +- /* rewrite entire array */ +- cleaned_rids[i] = cleaned_rids[i + 1]; ++ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) { ++ if (cleaned_rids[i] != rid) { ++ new_cleaned_rids[idx] = cleaned_rids[i]; ++ idx++; ++ } + } ++ memcpy(cleaned_rids, new_cleaned_rids, sizeof(new_cleaned_rids)); ++ + /* now do the preset cleaned rids */ +- for (i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != rid; i++) +- ; /* found rid, stop */ +- for (; i < CLEANRIDSIZ; i++) { +- /* rewrite entire array */ +- pre_cleaned_rids[i] = pre_cleaned_rids[i + 1]; ++ idx = 0; ++ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) { ++ if (pre_cleaned_rids[i] != rid) { ++ new_pre_cleaned_rids[idx] = pre_cleaned_rids[i]; ++ idx++; ++ } + } ++ memcpy(pre_cleaned_rids, new_pre_cleaned_rids, sizeof(new_pre_cleaned_rids)); + +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(rid_lock); + } + + /* +@@ -2882,16 +2895,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), + char *ridstr = NULL; + int rc = SLAPI_DSE_CALLBACK_OK; + +- if (get_abort_cleanruv_task_count() >= CLEANRIDSIZ) { +- /* we are already running the maximum number of tasks */ +- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, +- "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)", +- CLEANRIDSIZ); +- cleanruv_log(task, -1, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext); +- *returncode = LDAP_OPERATIONS_ERROR; +- return SLAPI_DSE_CALLBACK_ERROR; +- } +- + /* allocate new task now */ + task = slapi_new_task(slapi_entry_get_ndn(e)); + +@@ -2976,6 +2979,16 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), + */ + certify_all = "no"; + } ++ ++ if (check_and_set_abort_cleanruv_task_count() != LDAP_SUCCESS) { ++ /* we are already running the maximum number of tasks */ ++ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, ++ "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)", ++ CLEANRIDSIZ); ++ cleanruv_log(task, -1, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext); ++ *returncode = LDAP_UNWILLING_TO_PERFORM; ++ goto out; ++ } + /* + * Create payload + */ +@@ -3190,6 +3203,9 @@ done: + slapi_ch_free_string(&data->certify); + slapi_sdn_free(&data->sdn); + slapi_ch_free((void **)&data); ++ PR_Lock(task_count_lock); ++ abort_task_count--; ++ PR_Unlock(task_count_lock); + g_decr_active_threadcnt(); + } + +@@ -3541,36 +3557,43 @@ replica_cleanallruv_check_ruv(char *repl_root, Repl_Agmt *agmt, char *rid_text, + return rc; + } + +-static int +-get_cleanruv_task_count(void) ++/* ++ * Before starting a cleanAllRUV task make sure there are not ++ * too many task threads already running. If everything is okay ++ * also pre-set the RID now so rebounding extended ops do not ++ * try to clean it over and over. ++ */ ++int32_t ++check_and_set_cleanruv_task_count(ReplicaId rid) + { +- int i, count = 0; ++ int32_t rc = 0; + +- slapi_rwlock_wrlock(rid_lock); +- for (i = 0; i < CLEANRIDSIZ; i++) { +- if (pre_cleaned_rids[i] != 0) { +- count++; +- } ++ PR_Lock(task_count_lock); ++ if (clean_task_count >= CLEANRIDSIZ) { ++ rc = -1; ++ } else { ++ clean_task_count++; ++ preset_cleaned_rid(rid); + } +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(task_count_lock); + +- return count; ++ return rc; + } + +-static int +-get_abort_cleanruv_task_count(void) ++int32_t ++check_and_set_abort_cleanruv_task_count(void) + { +- int i, count = 0; ++ int32_t rc = 0; + +- slapi_rwlock_wrlock(rid_lock); +- for (i = 0; i < CLEANRIDSIZ; i++) { +- if (aborted_rids[i] != 0) { +- count++; ++ PR_Lock(task_count_lock); ++ if (abort_task_count > CLEANRIDSIZ) { ++ rc = -1; ++ } else { ++ abort_task_count++; + } +- } +- slapi_rwlock_unlock(rid_lock); ++ PR_Unlock(task_count_lock); + +- return count; ++ return rc; + } + + /* +diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c +index b49cb8cd5..5bed84958 100644 +--- a/ldap/servers/plugins/replication/repl_extop.c ++++ b/ldap/servers/plugins/replication/repl_extop.c +@@ -1393,6 +1393,12 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) + rc = LDAP_OPERATIONS_ERROR; + goto out; + } ++ if (check_and_set_abort_cleanruv_task_count() != LDAP_SUCCESS) { ++ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, ++ "Exceeded maximum number of active abort CLEANALLRUV tasks(%d)", CLEANRIDSIZ); ++ rc = LDAP_UNWILLING_TO_PERFORM; ++ goto out; ++ } + /* + * Prepare the abort data + */ +@@ -1499,6 +1505,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) + if (force == NULL) { + force = "no"; + } ++ + maxcsn = csn_new(); + csn_init_by_string(maxcsn, csnstr); + /* +@@ -1535,13 +1542,21 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) + goto free_and_return; + } + ++ if (check_and_set_cleanruv_task_count((ReplicaId)rid) != LDAP_SUCCESS) { ++ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, ++ "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ); ++ rc = LDAP_UNWILLING_TO_PERFORM; ++ goto free_and_return; ++ } ++ + if (replica_get_type(r) != REPLICA_TYPE_READONLY) { + /* + * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid + * + * This will also release mtnode_ext->replica + */ +- slapi_log_err(SLAPI_LOG_INFO, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Launching cleanAllRUV thread...\n"); ++ ++ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Launching cleanAllRUV thread...\n"); + data = (cleanruv_data *)slapi_ch_calloc(1, sizeof(cleanruv_data)); + if (data == NULL) { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Failed to allocate " +@@ -1635,7 +1650,7 @@ free_and_return: + ber_printf(resp_bere, "{s}", CLEANRUV_ACCEPTED); + ber_flatten(resp_bere, &resp_bval); + slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval); +- slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL); ++ slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); + /* resp_bere */ + if (NULL != resp_bere) { + ber_free(resp_bere, 1); +-- +2.21.0 + diff --git a/SOURCES/0018-CVE-2019-14824-BZ-1748201-deref-plugin-displays-rest.patch b/SOURCES/0018-CVE-2019-14824-BZ-1748201-deref-plugin-displays-rest.patch new file mode 100644 index 0000000..e213cc1 --- /dev/null +++ b/SOURCES/0018-CVE-2019-14824-BZ-1748201-deref-plugin-displays-rest.patch @@ -0,0 +1,53 @@ +From 9e244c9344a73af93cc79dd1176ce78971747027 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 3 Sep 2019 14:53:09 -0400 +Subject: [PATCH] CVE-2019-14824 (BZ#1748201) - deref plugin displays + restricted attributes + +Bug Description: If there is an ACI that allows "search" access to an attribute, + the deref plugin access control checks sees this is a "read" + privilege and returns the attribute's value. + +Fix description: For deref plugin we are only concerned with "read" access, not + "search" access. Removed the SLAPI_ACL_SEARCH right flag when + checking access for an attribute. + +Reviewed by: lkrispen & tbordaz(Thanks!) +--- + ldap/servers/plugins/deref/deref.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c +index cb5ebb830..ec1884ba3 100644 +--- a/ldap/servers/plugins/deref/deref.c ++++ b/ldap/servers/plugins/deref/deref.c +@@ -573,7 +573,7 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, + Slapi_Entry **entries = NULL; + int rc; + +- /* If the access check on the attributes is done without retrieveing the entry ++ /* If the access check on the attributes is done without retrieving the entry + * it cannot handle acis which need teh entry, eg to apply a targetfilter rule + * So the determination of attrs which can be dereferenced is delayed + */ +@@ -596,7 +596,7 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn, + int ii; + int needattrvals = 1; /* need attrvals sequence? */ + if (deref_check_access(pb, entries[0], derefdn, attrs, &retattrs, +- (SLAPI_ACL_SEARCH | SLAPI_ACL_READ))) { ++ SLAPI_ACL_READ)) { + slapi_log_err(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM, + "deref_do_deref_attr - The client does not have permission to read the requested " + "attributes in entry %s\n", +@@ -714,7 +714,7 @@ deref_pre_entry(Slapi_PBlock *pb) + attrs[1] = NULL; + + if (deref_check_access(pb, ent, NULL, attrs, &retattrs, +- (SLAPI_ACL_SEARCH | SLAPI_ACL_READ))) { ++ SLAPI_ACL_READ)) { + slapi_log_err(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM, + "deref_pre_entry - The client does not have permission to read attribute %s in entry %s\n", + spec->derefattr, slapi_entry_get_dn_const(ent)); +-- +2.21.0 + diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index a199d91..661afc1 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -25,7 +25,7 @@ ExcludeArch: i686 %if %{bundle_jemalloc} %global jemalloc_name jemalloc -%global jemalloc_ver 5.1.0 +%global jemalloc_ver 5.2.0 %global __provides_exclude ^libjemalloc\\.so.*$ %endif @@ -42,13 +42,10 @@ ExcludeArch: i686 # set PIE flag %global _hardened_build 1 -# RHEL minor version -%global minor 10 - Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 1.4.0.20 -Release: %{?relprefix}%{minor}%{?prerel}%{?dist} +Version: 1.4.1.3 +Release: %{?relprefix}7%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Group: System Environment/Daemons @@ -94,6 +91,7 @@ BuildRequires: rust %endif BuildRequires: pkgconfig BuildRequires: pkgconfig(systemd) +BuildRequires: pkgconfig(krb5) # Needed to support regeneration of the autotool artifacts. BuildRequires: autoconf @@ -160,18 +158,40 @@ Requires: perl-Errno >= 1.23-360 Requires: perl-DB_File Requires: perl-Archive-Tar +# Needed for password dictionary checks +Requires: cracklib-dicts + # Picks up our systemd deps. %{?systemd_requires} Obsoletes: %{name} <= 1.3.5.4 -Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}-%{minor}.tar.bz2 +Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}.tar.bz2 # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README %if %{bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif +Patch00: 0000-Issue-49602-Revise-replication-status-messages.patch +Patch01: 0001-Issue-49875-Move-SystemD-service-config-to-a-drop-in.patch +Patch02: 0002-Ticket-50355-NSS-can-change-the-requested-SSL-min-an.patch +Patch03: 0003-Ticket-49361-Use-IPv6-friendly-network-functions.patch +Patch04: 0004-Ticket-50431-Fix-covscan-warnings.patch +Patch05: 0005-Issue-50431-Fix-regression-from-coverity-fix.patch +Patch06: 0006-Revert-Issue-49960-Core-schema-contains-strings-inst.patch +Patch07: 0007-Issue-50378-ACI-s-with-IPv4-and-IPv6-bind-rules-do-n.patch +Patch08: 0008-Issue-50177-Add-a-new-CI-test-case-also-added-fixes-.patch +Patch09: 0009-Ticket-50217-Implement-dsconf-security-section.patch +Patch10: 0010-Issue-50431-Fix-regression-from-coverity-fix.patch +Patch11: 0011-Ticket-50413-ds-replcheck-Always-display-the-Result-.patch +Patch12: 0012-Issue-49239-Add-a-new-CI-test-case.patch +Patch13: 0013-Ticket-50428-Log-the-actual-base-DN-when-the-search-.patch +Patch14: 0014-Issue-50474-Unify-result-codes-for-add-and-modify-of.patch +Patch15: 0015-Ticket-49789-By-default-do-not-manage-unhashed-passw.patch +Patch16: 0016-Ticket-50329-2nd-Possible-Security-Issue-DOS-due-to-.patch +Patch17: 0017-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch +Patch18: 0018-CVE-2019-14824-BZ-1748201-deref-plugin-displays-rest.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -211,7 +231,7 @@ package to be installed with just the -libs package and without the main package Summary: Legacy utilities for 389 Directory Server (%{variant}) Group: System Environment/Daemons Obsoletes: %{name} <= 1.4.0.9 -Requires: %{name} = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} %if %{use_perl} # for setup-ds.pl to support ipv6 %if %{use_Socket6} @@ -269,7 +289,6 @@ Group: Development/Libraries Requires: openssl Requires: iproute Requires: platform-python -Requires: python%{python3_pkgversion}-pytest Requires: python%{python3_pkgversion}-ldap Requires: python%{python3_pkgversion}-six Requires: python%{python3_pkgversion}-pyasn1 @@ -294,9 +313,9 @@ Requires: python%{python3_pkgversion}-lib389 A cockpit UI Plugin for configuring and administering the 389 Directory Server %prep -%autosetup -p1 -v -n %{name}-%{version}-%{minor}%{?prerel} +%autosetup -p1 -v -n %{name}-%{version}%{?prerel} %if %{bundle_jemalloc} -%setup -q -n %{name}-%{version}-%{minor}%{?prerel} -T -D -b 3 +%setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3 %endif cp %{SOURCE2} README.devel @@ -317,6 +336,8 @@ RUST_FLAGS="--enable-rust" %if !%{use_perl} PERL_FLAGS="--disable-perl" +%else +PERL_FLAGS="--enable-perl" %endif %if %{use_clang} @@ -356,10 +377,10 @@ pushd ./src/lib389 popd # argparse-manpage dynamic man pages have hardcoded man v1 in header, # need to change it to v8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}-%{minor}%{?prerel}/src/lib389/man/dsconf.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}-%{minor}%{?prerel}/src/lib389/man/dsctl.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}-%{minor}%{?prerel}/src/lib389/man/dsidm.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}-%{minor}%{?prerel}/src/lib389/man/dscreate.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dsconf.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dsctl.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dsidm.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dscreate.8 # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS @@ -379,7 +400,7 @@ find %{buildroot}%{_datadir}/cockpit/389-console -type d | sed -e "s@%{buildroot find %{buildroot}%{_datadir}/cockpit/389-console -type f | sed -e "s@%{buildroot}@@" >> cockpit.list # Copy in our docs from doxygen. -cp -r %{_builddir}/%{name}-%{version}-%{minor}%{?prerel}/man/man3 $RPM_BUILD_ROOT/%{_mandir}/man3 +cp -r %{_builddir}/%{name}-%{version}%{?prerel}/man/man3 $RPM_BUILD_ROOT/%{_mandir}/man3 # lib389 pushd src/lib389 @@ -405,8 +426,8 @@ sed -i -e 's|#{{PERL-EXEC}}|#!/usr/bin/perl|' $RPM_BUILD_ROOT%{_datadir}/%{pkgna %if %{bundle_jemalloc} pushd ../%{jemalloc_name}-%{jemalloc_ver} make DESTDIR="$RPM_BUILD_ROOT" install_lib install_bin -cp -pa COPYING ../%{name}-%{version}-%{minor}%{?prerel}/COPYING.jemalloc -cp -pa README ../%{name}-%{version}-%{minor}%{?prerel}/README.jemalloc +cp -pa COPYING ../%{name}-%{version}%{?prerel}/COPYING.jemalloc +cp -pa README ../%{name}-%{version}%{?prerel}/README.jemalloc popd %endif @@ -550,8 +571,6 @@ exit 0 %config(noreplace)%{_sysconfdir}/%{pkgname}/config/slapd-collations.conf %config(noreplace)%{_sysconfdir}/%{pkgname}/config/certmap.conf %config(noreplace)%{_sysconfdir}/%{pkgname}/config/template-initconfig -%config(noreplace)%{_sysconfdir}/sysconfig/%{pkgname} -%config(noreplace)%{_sysconfdir}/sysconfig/%{pkgname}.systemd %{_datadir}/%{pkgname} %exclude %{_datadir}/%{pkgname}/script-templates %exclude %{_datadir}/%{pkgname}/updates @@ -590,14 +609,6 @@ exit 0 %{_mandir}/man8/dbverify.8.gz %{_sbindir}/ldif2db %{_mandir}/man8/ldif2db.8.gz -%{_sbindir}/restart-dirsrv -%{_mandir}/man8/restart-dirsrv.8.gz -%{_sbindir}/start-dirsrv -%{_mandir}/man8/start-dirsrv.8.gz -%{_sbindir}/status-dirsrv -%{_mandir}/man8/status-dirsrv.8.gz -%{_sbindir}/stop-dirsrv -%{_mandir}/man8/stop-dirsrv.8.gz %{_sbindir}/upgradedb %{_mandir}/man8/upgradedb.8.gz %{_sbindir}/vlvindex @@ -689,6 +700,14 @@ exit 0 %{_mandir}/man8/suffix2instance.8.gz %{_sbindir}/upgradednformat %{_mandir}/man8/upgradednformat.8.gz +%{_sbindir}/restart-dirsrv +%{_mandir}/man8/restart-dirsrv.8.gz +%{_sbindir}/start-dirsrv +%{_mandir}/man8/start-dirsrv.8.gz +%{_sbindir}/status-dirsrv +%{_mandir}/man8/status-dirsrv.8.gz +%{_sbindir}/stop-dirsrv +%{_mandir}/man8/stop-dirsrv.8.gz %if %{use_perl} %{_datadir}/%{pkgname}/properties/*.res %{_datadir}/%{pkgname}/script-templates @@ -764,23 +783,49 @@ exit 0 %{_mandir}/man8/dsctl.8.gz %{_sbindir}/dsidm %{_mandir}/man8/dsidm.8.gz +%{_sbindir}/dscontainer %files -n cockpit-389-ds -f cockpit.list -%{_datarootdir}/metainfo/389-console/org.cockpit-project.389-console.metainfo.xml +%{_datarootdir}/metainfo/389-console/org.port389.cockpit_console.metainfo.xml %doc README.md %changelog -* Wed Apr 24 2019 Mark Reynolds - 1.4.0.20-10 -- Bump version to 1.4.0.20-10 -- Resolves: Bug 1690024 - rebase lib389 to pull in all the dscreate fixes - -* Wed Apr 10 2019 Mark Reynolds - 1.4.0.20-9 -- Bump version to 1.4.0.20-9 -- Resolves: Bug 1690024 - ipa role-mod DatabaseError changing cn (missing commit from last release) - -* Tue Mar 19 2019 Mark Reynolds - 1.4.0.20-8 -- Bump version to 1.4.0.20-8 -- Resolves: Bug 1690024 - ipa role-mod DatabaseError changing cn (entry cache corruption) +* Tue Sep 3 2019 Mark Reynolds - 1.4.1.3-7 +- Bump version to 1.4.1.3-7 +- Resolves: Bug 1748201 - EMBARGOED CVE-2019-14824 389-ds:1.4/389-ds-base: 389-ds and IDM: allows authenticated unprivileged user to retrieve content of userPassword field for any user + +* Thu Aug 22 2019 Mark Reynolds - 1.4.1.3-6 +- Bump version to 1.4.1.3-6 +- Resolves: Bug 1739183 - CleanAllRUV task limit not enforced + +* Fri Jul 26 2019 Mark Reynolds - 1.4.1.3-5 +- Bump verison to 1.4.1.3-5 +- Resolves: Bug 1720331 - Log the actual base DN when the search fails with "invalid attribute request" +- Resolves: Bug 1725815 - consistency in the replication error codes while setting nsds5replicaid=65535 +- Resolves: Bug 1592228 - CVE-2018-10871 389-ds-base: replication and the Retro Changelog plugin store plaintext password by default +- Resolves: Bug 1699043 - CVE-2019-3883 389-ds-base: DoS via hanging secured connections +- Resolves: Bug 1444876 - Add new keyword to access logging when buffer capacity is exceeded + +* Fri Jul 12 2019 Mark Reynolds - 1.4.1.3-4 +- Bump verison to 1.4.1.3-4 +- Resolves: Bug 1712467 - Fix schema OID issue that came over from rebase + +* Fri Jun 28 2019 Mark Reynolds - 1.4.1.3-3 +- Bump verison to 1.4.1.3-3 +- Resolves: Bug 1654056 - /usr/lib/systemd/system/dirsrv@.service:40: .include directives are deprecated +- Resolves: Bug 1706224 - Protocol setting is inconsistent in FIPS mode +- Resolves: Bug 1715675 - Fix potential ipv6 issues +- Resolves: Bug 1717540 - Address covscan warnings + +* Fri May 24 2019 Mark Reynolds - 1.4.1.3-2 +- Bump version to 1.4.1.3-2 +- Resolves: Bug 1544973 - [RFE] IPA replica stuck at last update status: Error (18) Replication error acquiring replica: Incremental update transient error. + +* Fri May 24 2019 Mark Reynolds - 1.4.1.3-1 +- Bump version to 1.4.1.3-1 +- Resolves: Bug 1633718 - 389-ds module: Switched Requires from "python3" to "platform-python" +- Resolves: Bug 1654059 - 389-ds-base: dscreate and dsconf print DM's password in verbose mode +- Resolves: Bug 1712467 - Rebase 389-ds-base on RHEL 8.1 * Fri Feb 01 2019 Mark Reynolds - 1.4.0.20-7 - Bump version to 1.4.0.20-7