diff --git a/SOURCES/0019-Ticket-49543-fix-certmap-dn-comparison.patch b/SOURCES/0019-Ticket-49543-fix-certmap-dn-comparison.patch new file mode 100644 index 0000000..3ee748e --- /dev/null +++ b/SOURCES/0019-Ticket-49543-fix-certmap-dn-comparison.patch @@ -0,0 +1,435 @@ +From 66c96b915dd4a82ebd4228cba61d7c4bae96cbca Mon Sep 17 00:00:00 2001 +From: Fraser Tweedale +Date: Fri, 16 Mar 2018 15:16:56 +1000 +Subject: [PATCH] Ticket 49543 - fix certmap dn comparison + +Bug Description: Differences in DN string representations between +the value included in certmap.conf, and the stringified value of the +Issuer DN produced by NSS, as well as buggy DN normalisation code in +389 itself, cause 389 to wrongly reject the correct certmap +configuration to use. Authentication fails. This behaviour was +observed when there is an escaped comma in an attribute value. + +Fix Description: Instead of comparing stringified DNs, parse the DN +represented in certmap.conf into an NSS CertNAME. Use the NSS DN +comparison routine when comparing certificate Issuer DNs against the +certmap configurations. Remove the buggy DN normalisation routine. + +https://pagure.io/389-ds-base/issue/49543 + +Author: Fraser Tweedale + +Review by: ??? +--- + include/ldaputil/certmap.h | 20 +++-- + include/ldaputil/ldaputil.h | 2 +- + lib/ldaputil/cert.c | 27 ++++-- + lib/ldaputil/certmap.c | 162 ++++++----------------------------- + lib/ldaputil/examples/init.c | 3 +- + 5 files changed, 62 insertions(+), 152 deletions(-) + +diff --git a/include/ldaputil/certmap.h b/include/ldaputil/certmap.h +index fec2dd931..50fd4d158 100644 +--- a/include/ldaputil/certmap.h ++++ b/include/ldaputil/certmap.h +@@ -16,6 +16,7 @@ + /* What was extcmap.h begins ... */ + + #include ++#include + + #ifndef NSAPI_PUBLIC + #define NSAPI_PUBLIC +@@ -156,7 +157,7 @@ typedef int (*CertVerifyFn_t)(void *cert, LDAP *ld, void *certmap_info, LDAPMess + * otherwise return LDAPU_CERT_MAP_INITFN_FAILED. The server startup will be + * aborted if the return value is not LDAPU_SUCCESS. + */ +-typedef int (*CertMapInitFn_t)(void *certmap_info, const char *issuerName, const char *issuerDN, const char *libname); ++typedef int (*CertMapInitFn_t)(void *certmap_info, const char *issuerName, const CERTName *issuerDN, const char *libname); + + /* + * Refer to the description of the function ldapu_get_cert_ava_val +@@ -209,27 +210,30 @@ extern "C" { + + NSAPI_PUBLIC int ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage **res); + +-NSAPI_PUBLIC int ldapu_set_cert_mapfn(const char *issuerDN, ++NSAPI_PUBLIC int ldapu_set_cert_mapfn(const CERTName *issuerDN, + CertMapFn_t mapfn); + + +-NSAPI_PUBLIC CertMapFn_t ldapu_get_cert_mapfn(const char *issuerDN); ++NSAPI_PUBLIC CertMapFn_t ldapu_get_cert_mapfn(const CERTName *issuerDN); + +-NSAPI_PUBLIC int ldapu_set_cert_searchfn(const char *issuerDN, ++NSAPI_PUBLIC int ldapu_set_cert_searchfn(const CERTName *issuerDN, + CertSearchFn_t searchfn); + + +-NSAPI_PUBLIC CertSearchFn_t ldapu_get_cert_searchfn(const char *issuerDN); ++NSAPI_PUBLIC CertSearchFn_t ldapu_get_cert_searchfn(const CERTName *issuerDN); + +-NSAPI_PUBLIC int ldapu_set_cert_verifyfn(const char *issuerDN, ++NSAPI_PUBLIC int ldapu_set_cert_verifyfn(const CERTName *issuerDN, + CertVerifyFn_t verifyFn); + +-NSAPI_PUBLIC CertVerifyFn_t ldapu_get_cert_verifyfn(const char *issuerDN); ++NSAPI_PUBLIC CertVerifyFn_t ldapu_get_cert_verifyfn(const CERTName *issuerDN); + + + NSAPI_PUBLIC int ldapu_get_cert_subject_dn(void *cert, char **subjectDN); + + ++NSAPI_PUBLIC CERTName *ldapu_get_cert_issuer_dn_as_CERTName(CERTCertificate *cert); ++ ++ + NSAPI_PUBLIC int ldapu_get_cert_issuer_dn(void *cert, char **issuerDN); + + +@@ -242,7 +246,7 @@ NSAPI_PUBLIC int ldapu_free_cert_ava_val(char **val); + NSAPI_PUBLIC int ldapu_get_cert_der(void *cert, unsigned char **derCert, unsigned int *len); + + +-NSAPI_PUBLIC int ldapu_issuer_certinfo(const char *issuerDN, ++NSAPI_PUBLIC int ldapu_issuer_certinfo(const CERTName *issuerDN, + void **certmap_info); + + +diff --git a/include/ldaputil/ldaputil.h b/include/ldaputil/ldaputil.h +index e0e028c5c..b172819b0 100644 +--- a/include/ldaputil/ldaputil.h ++++ b/include/ldaputil/ldaputil.h +@@ -48,7 +48,7 @@ enum + typedef struct + { + char *issuerName; /* issuer (symbolic/short) name */ +- char *issuerDN; /* cert issuer's DN */ ++ CERTName *issuerDN; /* cert issuer's DN */ + LDAPUPropValList_t *propval; /* pointer to the prop-val pairs list */ + CertMapFn_t mapfn; /* cert to ldapdn & filter mapping func */ + CertVerifyFn_t verifyfn; /* verify cert function */ +diff --git a/lib/ldaputil/cert.c b/lib/ldaputil/cert.c +index 65a481541..73abba12a 100644 +--- a/lib/ldaputil/cert.c ++++ b/lib/ldaputil/cert.c +@@ -54,15 +54,30 @@ ldapu_get_cert_subject_dn(void *cert_in, char **subjectDN) + return *subjectDN ? LDAPU_SUCCESS : LDAPU_ERR_EXTRACT_SUBJECTDN_FAILED; + } + ++/* ++ * Return the Issuer DN as a CERTName. ++ * The CERTName is owned by the CERTCertificate. ++ */ ++NSAPI_PUBLIC CERTName * ++ldapu_get_cert_issuer_dn_as_CERTName(CERTCertificate *cert_in) ++{ ++ return &cert_in->issuer; ++} ++ ++/* ++ * Return the Issuer DN as a string. ++ * The string should be freed by the caller. ++ */ + NSAPI_PUBLIC int + ldapu_get_cert_issuer_dn(void *cert_in, char **issuerDN) + { +- CERTCertificate *cert = (CERTCertificate *)cert_in; +- char *cert_issuer = CERT_NameToAscii(&cert->issuer); +- +- *issuerDN = strdup(cert_issuer); +- PR_Free(cert_issuer); +- ++ *issuerDN = NULL; ++ CERTName *dn = ldapu_get_cert_issuer_dn_as_CERTName((CERTCertificate *)cert_in); ++ if (dn != NULL) { ++ char *cert_issuer = CERT_NameToAscii(dn); ++ *issuerDN = strdup(cert_issuer); ++ PR_Free(cert_issuer); ++ } + return *issuerDN ? LDAPU_SUCCESS : LDAPU_ERR_EXTRACT_ISSUERDN_FAILED; + } + +diff --git a/lib/ldaputil/certmap.c b/lib/ldaputil/certmap.c +index 78bb3635b..0db2de12b 100644 +--- a/lib/ldaputil/certmap.c ++++ b/lib/ldaputil/certmap.c +@@ -52,7 +52,6 @@ static char this_dllname[256]; + static const char *LIB_DIRECTIVE = "certmap"; + static const int LIB_DIRECTIVE_LEN = 7; /* strlen("LIB_DIRECTIVE") */ + +-static char *ldapu_dn_normalize(char *dn); + static void *ldapu_propval_free(void *propval_in, void *arg); + + typedef struct +@@ -337,8 +336,13 @@ dbinfo_to_certinfo(DBConfDBInfo_t *db_info, + certinfo->issuerName = db_info->dbname; + db_info->dbname = 0; + +- certinfo->issuerDN = ldapu_dn_normalize(db_info->url); +- db_info->url = 0; ++ /* Parse the Issuer DN. */ ++ certinfo->issuerDN = CERT_AsciiToName(db_info->url); ++ if (NULL == certinfo->issuerDN /* invalid DN */ ++ && ldapu_strcasecmp(db_info->url, "default") != 0 /* not "default" */) { ++ rv = LDAPU_ERR_MALFORMED_SUBJECT_DN; ++ goto error; ++ } + + /* hijack actual prop-vals from dbinfo -- to avoid strdup calls */ + if (db_info->firstprop) { +@@ -890,24 +894,26 @@ ldapu_cert_searchfn_default(void *cert, LDAP *ld, void *certmap_info_in, const c + } + + NSAPI_PUBLIC int +-ldapu_issuer_certinfo(const char *issuerDN, void **certmap_info) ++ldapu_issuer_certinfo(const CERTName *issuerDN, void **certmap_info) + { + *certmap_info = 0; + +- if (!issuerDN || !*issuerDN || !ldapu_strcasecmp(issuerDN, "default")) { +- *certmap_info = default_certmap_info; +- } else if (certmap_listinfo) { +- char *n_issuerDN = ldapu_dn_normalize(ldapu_strdup(issuerDN)); ++ if (certmap_listinfo) { + LDAPUListNode_t *cur = certmap_listinfo->head; + while (cur) { +- if (!ldapu_strcasecmp(n_issuerDN, ((LDAPUCertMapInfo_t *)cur->info)->issuerDN)) { ++ LDAPUCertMapInfo_t *info = (LDAPUCertMapInfo_t *)cur->info; ++ ++ if (NULL == info->issuerDN) { ++ /* no DN to compare to (probably the default certmap info) */ ++ continue; ++ } ++ ++ if (CERT_CompareName(issuerDN, info->issuerDN) == SECEqual) { + *certmap_info = cur->info; + break; + } + cur = cur->next; + } +- if (n_issuerDN) +- ldapu_free(n_issuerDN); + } + return *certmap_info ? LDAPU_SUCCESS : LDAPU_FAILED; + } +@@ -1128,7 +1134,7 @@ ldapu_cert_mapfn_default(void *cert_in, LDAP *ld __attribute__((unused)), void * + } + + NSAPI_PUBLIC int +-ldapu_set_cert_mapfn(const char *issuerDN, ++ldapu_set_cert_mapfn(const CERTName *issuerDN, + CertMapFn_t mapfn) + { + LDAPUCertMapInfo_t *certmap_info; +@@ -1161,7 +1167,7 @@ ldapu_get_cert_mapfn_sub(LDAPUCertMapInfo_t *certmap_info) + } + + NSAPI_PUBLIC CertMapFn_t +-ldapu_get_cert_mapfn(const char *issuerDN) ++ldapu_get_cert_mapfn(const CERTName *issuerDN) + { + LDAPUCertMapInfo_t *certmap_info = 0; + +@@ -1173,7 +1179,7 @@ ldapu_get_cert_mapfn(const char *issuerDN) + } + + NSAPI_PUBLIC int +-ldapu_set_cert_searchfn(const char *issuerDN, ++ldapu_set_cert_searchfn(const CERTName *issuerDN, + CertSearchFn_t searchfn) + { + LDAPUCertMapInfo_t *certmap_info; +@@ -1206,7 +1212,7 @@ ldapu_get_cert_searchfn_sub(LDAPUCertMapInfo_t *certmap_info) + } + + NSAPI_PUBLIC CertSearchFn_t +-ldapu_get_cert_searchfn(const char *issuerDN) ++ldapu_get_cert_searchfn(const CERTName *issuerDN) + { + LDAPUCertMapInfo_t *certmap_info = 0; + +@@ -1218,7 +1224,7 @@ ldapu_get_cert_searchfn(const char *issuerDN) + } + + NSAPI_PUBLIC int +-ldapu_set_cert_verifyfn(const char *issuerDN, ++ldapu_set_cert_verifyfn(const CERTName *issuerDN, + CertVerifyFn_t verifyfn) + { + LDAPUCertMapInfo_t *certmap_info; +@@ -1251,7 +1257,7 @@ ldapu_get_cert_verifyfn_sub(LDAPUCertMapInfo_t *certmap_info) + } + + NSAPI_PUBLIC CertVerifyFn_t +-ldapu_get_cert_verifyfn(const char *issuerDN) ++ldapu_get_cert_verifyfn(const CERTName *issuerDN) + { + LDAPUCertMapInfo_t *certmap_info = 0; + +@@ -1288,7 +1294,6 @@ static int ldapu_certinfo_copy (const LDAPUCertMapInfo_t *from, + NSAPI_PUBLIC int + ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage **res) + { +- char *issuerDN = 0; + char *ldapDN = 0; + char *filter = 0; + LDAPUCertMapInfo_t *certmap_info; +@@ -1308,14 +1313,14 @@ ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage * + certmap_attrs[3] = 0; + } + +- rv = ldapu_get_cert_issuer_dn(cert, &issuerDN); ++ CERTName *issuerDN = ldapu_get_cert_issuer_dn_as_CERTName(cert); ++ /* ^ don't need to free this; it will be freed with ^ the cert */ + +- if (rv != LDAPU_SUCCESS) ++ if (NULL == issuerDN) + return LDAPU_ERR_NO_ISSUERDN_IN_CERT; + + /* don't free the certmap_info -- its a pointer to an internal structure */ + rv = ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); +- free(issuerDN); + + if (!certmap_info) + certmap_info = default_certmap_info; +@@ -1604,118 +1609,3 @@ ldapu_realloc(void *ptr, int size) + { + return realloc(ptr, size); + } +- +-#define DNSEPARATOR(c) (c == ',' || c == ';') +-#define SEPARATOR(c) (c == ',' || c == ';' || c == '+') +-#define SPACE(c) (c == ' ' || c == '\n') +-#define NEEDSESCAPE(c) (c == '\\' || c == '"') +-#define B4TYPE 0 +-#define INTYPE 1 +-#define B4EQUAL 2 +-#define B4VALUE 3 +-#define INVALUE 4 +-#define INQUOTEDVALUE 5 +-#define B4SEPARATOR 6 +- +-static char * +-ldapu_dn_normalize(char *dn) +-{ +- char *d, *s; +- int state, gotesc; +- +- gotesc = 0; +- state = B4TYPE; +- for (d = s = dn; *s; s++) { +- switch (state) { +- case B4TYPE: +- if (!SPACE(*s)) { +- state = INTYPE; +- *d++ = *s; +- } +- break; +- case INTYPE: +- if (*s == '=') { +- state = B4VALUE; +- *d++ = *s; +- } else if (SPACE(*s)) { +- state = B4EQUAL; +- } else { +- *d++ = *s; +- } +- break; +- case B4EQUAL: +- if (*s == '=') { +- state = B4VALUE; +- *d++ = *s; +- } else if (!SPACE(*s)) { +- /* not a valid dn - but what can we do here? */ +- *d++ = *s; +- } +- break; +- case B4VALUE: +- if (*s == '"') { +- state = INQUOTEDVALUE; +- *d++ = *s; +- } else if (!SPACE(*s)) { +- state = INVALUE; +- *d++ = *s; +- } +- break; +- case INVALUE: +- if (!gotesc && SEPARATOR(*s)) { +- while (SPACE(*(d - 1))) +- d--; +- state = B4TYPE; +- if (*s == '+') { +- *d++ = *s; +- } else { +- *d++ = ','; +- } +- } else if (gotesc && !NEEDSESCAPE(*s) && +- !SEPARATOR(*s)) { +- *--d = *s; +- d++; +- } else { +- *d++ = *s; +- } +- break; +- case INQUOTEDVALUE: +- if (!gotesc && *s == '"') { +- state = B4SEPARATOR; +- *d++ = *s; +- } else if (gotesc && !NEEDSESCAPE(*s)) { +- *--d = *s; +- d++; +- } else { +- *d++ = *s; +- } +- break; +- case B4SEPARATOR: +- if (SEPARATOR(*s)) { +- state = B4TYPE; +- if (*s == '+') { +- *d++ = *s; +- } else { +- *d++ = ','; +- } +- } +- break; +- default: +- break; +- } +- if (*s == '\\') { +- gotesc = 1; +- } else { +- gotesc = 0; +- } +- } +- *d = '\0'; +- +- /* Trim trailing spaces */ +- d--; +- while (d >= dn && *d == ' ') { +- *d-- = '\0'; +- } +- +- return (dn); +-} +diff --git a/lib/ldaputil/examples/init.c b/lib/ldaputil/examples/init.c +index 74db9775c..fd1edc97e 100644 +--- a/lib/ldaputil/examples/init.c ++++ b/lib/ldaputil/examples/init.c +@@ -15,12 +15,13 @@ + #include + #include + #include ++#include + #include "certmap.h" /* Public Certmap API */ + #include "plugin.h" /* must define extern "C" functions */ + + + NSAPI_PUBLIC int +-plugin_init_fn(void *certmap_info, const char *issuerName, const char *issuerDN, const char *libname) ++plugin_init_fn(void *certmap_info, const char *issuerName, const CERTName *issuerDN, const char *libname) + { + static int initialized = 0; + int rv; +-- +2.17.2 + diff --git a/SOURCES/0020-Ticket-50117-after-certain-failed-import-operation-i.patch b/SOURCES/0020-Ticket-50117-after-certain-failed-import-operation-i.patch new file mode 100644 index 0000000..a178a31 --- /dev/null +++ b/SOURCES/0020-Ticket-50117-after-certain-failed-import-operation-i.patch @@ -0,0 +1,63 @@ +From 90ba52ac8f655cb5d6cfd3f201c15f8004eb8414 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 4 Jan 2019 12:24:56 +0100 +Subject: [PATCH] Ticket 50117 - after certain failed import operation, + impossible to replay an import operation + +Bug Description: + At the beginning of an import, a flag is set to mark the target backend is busy. + Then import tests if there are pending operations. If such operations exist the import can not proceed and fails. + The problem is that in such case of pending operations, the import fails without resetting the busy flag. + It let the backend busy (until next reboot) and prevent new import. + +Fix Description: + It needs to reset the busy flag if there are pending operations + +https://pagure.io/389-ds-base/issue/50117 + +Reviewed by: Mark Reynolds, William Brown + +Platforms tested: F27 + +Flag Day: no + +Doc impact: no + +(cherry picked from commit ff00b07402747aac403478a157adab75e306d7d1) +(cherry picked from commit 630940ec119a90c3bbfc7cd3464eb02ab779b474) +--- + ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +index 16b87ee6b..69a2af9cf 100644 +--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c ++++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +@@ -704,12 +704,22 @@ ldbm_back_ldif2ldbm(Slapi_PBlock *pb) + } + + /* check if an import/restore is already ongoing... */ +- if ((instance_set_busy(inst) != 0) || +- (slapi_counter_get_value(inst->inst_ref_count) > 0)) { ++ if ((instance_set_busy(inst) != 0)) { + slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' is already in the middle of " + "another task and cannot be disturbed.\n", + inst->inst_name); + return -1; ++ } else { ++ uint64_t refcnt; ++ refcnt = slapi_counter_get_value(inst->inst_ref_count); ++ if (refcnt > 0) { ++ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %d pending operation(s)." ++ " Import can not proceed until they are completed.\n", ++ inst->inst_name, ++ refcnt); ++ instance_set_not_busy(inst); ++ return -1; ++ } + } + + if ((task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE)) { +-- +2.17.2 + diff --git a/SOURCES/0021-Ticket-49540-Fix-compiler-warning-in-ldif2ldbm.patch b/SOURCES/0021-Ticket-49540-Fix-compiler-warning-in-ldif2ldbm.patch new file mode 100644 index 0000000..d212998 --- /dev/null +++ b/SOURCES/0021-Ticket-49540-Fix-compiler-warning-in-ldif2ldbm.patch @@ -0,0 +1,31 @@ +From 9ab11ef54c378772982ef65cba3ea6718942899c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 15 Jan 2019 13:55:18 -0500 +Subject: [PATCH] Ticket 49540 - FIx compiler warning in ldif2ldbm + +https://pagure.io/389-ds-base/issue/49540 + +Reviewed by: mreynolds(one line commit rule) + +(cherry picked from commit 58be90b8bf96a7a0e10740b122035ea03fa13e0f) +(cherry picked from commit c9580477ffe22a08c0094378e81a6927d0dc4ffc) +--- + ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +index 69a2af9cf..11c020af0 100644 +--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c ++++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +@@ -713,7 +713,7 @@ ldbm_back_ldif2ldbm(Slapi_PBlock *pb) + uint64_t refcnt; + refcnt = slapi_counter_get_value(inst->inst_ref_count); + if (refcnt > 0) { +- slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %d pending operation(s)." ++ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %" PRIu64 " pending operation(s)." + " Import can not proceed until they are completed.\n", + inst->inst_name, + refcnt); +-- +2.17.2 + diff --git a/SOURCES/0022-Ticket-50078-cannot-add-cenotaph-in-read-only-consum.patch b/SOURCES/0022-Ticket-50078-cannot-add-cenotaph-in-read-only-consum.patch new file mode 100644 index 0000000..6a80c19 --- /dev/null +++ b/SOURCES/0022-Ticket-50078-cannot-add-cenotaph-in-read-only-consum.patch @@ -0,0 +1,108 @@ +From 7b4cb7aebdf5264e12e4ffad96fd21b3d7d2a14f Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +Date: Tue, 11 Dec 2018 11:06:44 +0100 +Subject: [PATCH] Ticket 50078 - cannot add cenotaph in read only consumer + +Bug: For modrdn operations a cenotaph entry is created to be used in later conflict + resolution procedures, this is done by an internal add operation and + fails on hubs and consumers + +Fix: Add the "bypass referral" flag to the internal add operation to allow it + +Reviewed by: Thierry, thanks +--- + dirsrvtests/tests/tickets/ticket50078_test.py | 68 +++++++++++++++++++ + ldap/servers/plugins/replication/urp.c | 2 +- + 2 files changed, 69 insertions(+), 1 deletion(-) + create mode 100644 dirsrvtests/tests/tickets/ticket50078_test.py + +diff --git a/dirsrvtests/tests/tickets/ticket50078_test.py b/dirsrvtests/tests/tickets/ticket50078_test.py +new file mode 100644 +index 000000000..3f6c5ec2d +--- /dev/null ++++ b/dirsrvtests/tests/tickets/ticket50078_test.py +@@ -0,0 +1,68 @@ ++import pytest ++from lib389.utils import * ++from lib389.topologies import topology_m1h1c1 ++from lib389.idm.user import UserAccounts ++ ++from lib389._constants import (DEFAULT_SUFFIX, REPLICA_RUV_FILTER, defaultProperties, ++ REPLICATION_BIND_DN, REPLICATION_BIND_PW, REPLICATION_BIND_METHOD, ++ REPLICATION_TRANSPORT, SUFFIX, RA_NAME, RA_BINDDN, RA_BINDPW, ++ RA_METHOD, RA_TRANSPORT_PROT, SUFFIX) ++ ++logging.getLogger(__name__).setLevel(logging.DEBUG) ++log = logging.getLogger(__name__) ++ ++TEST_USER = "test_user" ++ ++def test_ticket50078(topology_m1h1c1): ++ """ ++ Test that for a MODRDN operation the cenotaph entry is created on ++ a hub or consumer. ++ """ ++ ++ M1 = topology_m1h1c1.ms["master1"] ++ H1 = topology_m1h1c1.hs["hub1"] ++ C1 = topology_m1h1c1.cs["consumer1"] ++ # ++ # Test replication is working ++ # ++ if M1.testReplication(DEFAULT_SUFFIX, topology_m1h1c1.cs["consumer1"]): ++ log.info('Replication is working.') ++ else: ++ log.fatal('Replication is not working.') ++ assert False ++ ++ ua = UserAccounts(M1, DEFAULT_SUFFIX) ++ ua.create(properties={ ++ 'uid': "%s%d" % (TEST_USER, 1), ++ 'cn' : "%s%d" % (TEST_USER, 1), ++ 'sn' : 'user', ++ 'uidNumber' : '1000', ++ 'gidNumber' : '2000', ++ 'homeDirectory' : '/home/testuser' ++ }) ++ ++ user = ua.get('%s1' % TEST_USER) ++ log.info(" Rename the test entry %s..." % user) ++ user.rename('uid=test_user_new') ++ ++ # wait until replication is in sync ++ if M1.testReplication(DEFAULT_SUFFIX, topology_m1h1c1.cs["consumer1"]): ++ log.info('Replication is working.') ++ else: ++ log.fatal('Replication is not working.') ++ assert False ++ ++ # check if cenotaph was created on hub and consumer ++ ents = H1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, filterstr="(&(objectclass=nstombstone)(cenotaphid=*))") ++ assert len(ents) == 1 ++ ++ ents = C1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, filterstr="(&(objectclass=nstombstone)(cenotaphid=*))") ++ assert len(ents) == 1 ++ ++ ++ ++if __name__ == '__main__': ++ # Run isolated ++ # -s for DEBUG mode ++ CURRENT_FILE = os.path.realpath(__file__) ++ pytest.main("-s %s" % CURRENT_FILE) +diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c +index 11c5da7cf..37fe77379 100644 +--- a/ldap/servers/plugins/replication/urp.c ++++ b/ldap/servers/plugins/replication/urp.c +@@ -911,7 +911,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) + cenotaph, + NULL, + repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), +- OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP|OP_FLAG_CENOTAPH_ENTRY); ++ OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP|OP_FLAG_CENOTAPH_ENTRY|SLAPI_OP_FLAG_BYPASS_REFERRALS); + slapi_add_internal_pb(add_pb); + slapi_pblock_get(add_pb, SLAPI_PLUGIN_INTOP_RESULT, &ret); + +-- +2.17.2 + diff --git a/SOURCES/0023-Ticket-50177-import-task-should-not-be-deleted-too-r.patch b/SOURCES/0023-Ticket-50177-import-task-should-not-be-deleted-too-r.patch new file mode 100644 index 0000000..ab57e52 --- /dev/null +++ b/SOURCES/0023-Ticket-50177-import-task-should-not-be-deleted-too-r.patch @@ -0,0 +1,85 @@ +From aea4494eeb5351bcc26bf5e15411c28b96648445 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 1 Feb 2019 15:36:01 +0100 +Subject: [PATCH] Ticket 50177 - import task should not be deleted too rapidely + after import finishes to be able to query the status + +Bug Description: + scripts that create online import and export tasks do not define a Time To Life of the tasks. + As a consequence the task entry is cleared 2min (default value) after task completion. + This is too rapid and some admin scripts may miss the final task status. + +Fix Description: + The fix is to keep the entry of completed online import and export tasks for 1 day. + It also allows defines a default TTL to 1h (instead of 2min) + +https://pagure.io/389-ds-base/issue/50177 + +Reviewed by: Mark Reynolds + +Platforms tested: F27 + +Flag Day: no + +Doc impact: no +--- + ldap/admin/src/scripts/db2ldif.pl.in | 3 ++- + ldap/admin/src/scripts/ldif2db.pl.in | 3 ++- + ldap/servers/slapd/task.c | 6 +++--- + 3 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/ldap/admin/src/scripts/db2ldif.pl.in b/ldap/admin/src/scripts/db2ldif.pl.in +index 0d220f00a..f7d12b48a 100644 +--- a/ldap/admin/src/scripts/db2ldif.pl.in ++++ b/ldap/admin/src/scripts/db2ldif.pl.in +@@ -241,7 +241,8 @@ if ($decrypt_on_export != 0) { $nsexportdecrypt = "nsExportDecrypt: true\n"; } + $nsprintkey = ""; + if ($printkey == 0) { $nsprintkey = "nsPrintKey: false\n"; } + $nsldiffile = "nsFilename: ${ldiffile}\n"; +-$entry = "${dn}${misc}${cn}${nsinstance}${nsincluded}${nsexcluded}${nsreplica}${nsnobase64}${nsnowrap}${nsnoversion}${nsnouniqueid}${nsuseid2entry}${nsonefile}${nsexportdecrypt}${nsprintkey}${nsldiffile}"; ++$ttl = "ttl: 86400"; ++$entry = "${dn}${misc}${cn}${nsinstance}${nsincluded}${nsexcluded}${nsreplica}${nsnobase64}${nsnowrap}${nsnoversion}${nsnouniqueid}${nsuseid2entry}${nsonefile}${nsexportdecrypt}${nsprintkey}${nsldiffile}${ttl}"; + + print("Exporting to ldif file: ${ldiffile}\n"); + $rc = DSUtil::ldapmod($entry, %info); +diff --git a/ldap/admin/src/scripts/ldif2db.pl.in b/ldap/admin/src/scripts/ldif2db.pl.in +index a5d834f8e..486dcd053 100644 +--- a/ldap/admin/src/scripts/ldif2db.pl.in ++++ b/ldap/admin/src/scripts/ldif2db.pl.in +@@ -192,7 +192,8 @@ $nsmergechunksiz = "nsImportChunkSize: ${mergechunksiz}\n"; + $nsgenuniqid = "nsUniqueIdGenerator: ${genuniqid}\n"; + $nsuniqidname = ""; + if ($uniqidname ne "") { $nsuniqidname = "nsUniqueIdGeneratorNamespace: ${uniqidname}\n"; } +-$entry = "${dn}${misc}${cn}${nsinstance}${nsincluded}${nsexcluded}${nsldiffiles}${nsnoattrindexes}${nsimportencrypt}${nsmergechunksiz}${nsgenuniqid}${nsuniqidname}"; ++$ttl = "ttl: 86400"; ++$entry = "${dn}${misc}${cn}${nsinstance}${nsincluded}${nsexcluded}${nsldiffiles}${nsnoattrindexes}${nsimportencrypt}${nsmergechunksiz}${nsgenuniqid}${nsuniqidname}${ttl}"; + + $rc = DSUtil::ldapmod($entry, %info); + +diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c +index 698ee19b9..8c48c05b8 100644 +--- a/ldap/servers/slapd/task.c ++++ b/ldap/servers/slapd/task.c +@@ -46,7 +46,7 @@ static int shutting_down = 0; + #define TASK_PROGRESS_NAME "nsTaskCurrentItem" + #define TASK_WORK_NAME "nsTaskTotalItems" + +-#define DEFAULT_TTL "120" /* seconds */ ++#define DEFAULT_TTL "3600" /* seconds */ + #define TASK_SYSCONFIG_FILE_ATTR "sysconfigfile" /* sysconfig reload task file attr */ + #define TASK_SYSCONFIG_LOGCHANGES_ATTR "logchanges" + #define TASK_TOMBSTONE_FIXUP "fixup tombstones task" +@@ -387,8 +387,8 @@ slapi_task_status_changed(Slapi_Task *task) + if (e == NULL) + return; + ttl = atoi(fetch_attr(e, "ttl", DEFAULT_TTL)); +- if (ttl > 3600) +- ttl = 3600; /* be reasonable. */ ++ if (ttl > (24*3600)) ++ ttl = (24*3600); /* be reasonable, allow to check task status not longer than one day */ + expire = time(NULL) + ttl; + task->task_flags |= SLAPI_TASK_DESTROYING; + /* queue an event to destroy the state info */ +-- +2.17.2 + diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index 200a9de..6c2b417 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -39,7 +39,7 @@ Summary: 389 Directory Server (%{variant}) Name: 389-ds-base Version: 1.3.8.4 -Release: %{?relprefix}22%{?prerel}%{?dist} +Release: %{?relprefix}23%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org/ Group: System Environment/Daemons @@ -164,8 +164,12 @@ Patch14: 0014-Ticket-49950-PassSync-not-setting-pwdLastSet-attribu.patc Patch15: 0015-Ticket-49915-fix-compiler-warnings.patch Patch16: 0016-Ticket-49915-fix-compiler-warnings-2nd.patch Patch17: 0017-Ticket-49618-Increase-cachememsize-and-dncachememsize.patch -Patch21: 0018-Ticket-50020-during-MODRDN-referential-integrity-can.patch - +Patch18: 0018-Ticket-50020-during-MODRDN-referential-integrity-can.patch +Patch19: 0019-Ticket-49543-fix-certmap-dn-comparison.patch +Patch20: 0020-Ticket-50117-after-certain-failed-import-operation-i.patch +Patch21: 0021-Ticket-49540-Fix-compiler-warning-in-ldif2ldbm.patch +Patch22: 0022-Ticket-50078-cannot-add-cenotaph-in-read-only-consum.patch +Patch23: 0023-Ticket-50177-import-task-should-not-be-deleted-too-r.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -394,7 +398,6 @@ if [ $1 -eq 0 ]; then # Final removal fi %postun -/sbin/ldconfig if [ $1 = 0 ]; then # Final removal rm -rf /var/run/%{pkgname} fi @@ -514,6 +517,12 @@ fi %{_sysconfdir}/%{pkgname}/dirsrvtests %changelog +* Wed Feb 6 2019 Mark Reynolds - 1.3.8.4-23 +- Bump version to 1.3.8.4-23 +- Resolves: Bug 1672173 - import task should not be deleted after import finishes to be able to query the status +- Resolves: Bug 1672177 - after certain failed import operation, impossible to replay an import operation. +- Resolves: Bug 1672179 - cannot add cenotaph in read only consumer + * Mon Dec 17 2018 Mark Reynolds - 1.3.8.4-22 - Bump version to 1.3.8.4-22 - Resolves: Bug 1660120 - certmap fails when Issuer DN has comma in name