ldap/servers/plugins/acl/acl.c | 3
ldap/servers/plugins/acl/acl.h | 2
ldap/servers/plugins/acl/aclplugin.c | 8
ldap/servers/plugins/replication/repl5.h | 2
ldap/servers/plugins/replication/repl5_connection.c | 10
ldap/servers/plugins/replication/repl5_inc_protocol.c | 2
ldap/servers/plugins/replication/repl5_protocol_util.c | 7
ldap/servers/plugins/replication/repl5_tot_protocol.c | 2
ldap/servers/slapd/abandon.c | 7
ldap/servers/slapd/attrsyntax.c | 22
ldap/servers/slapd/connection.c | 14
ldap/servers/slapd/csnset.c | 4
ldap/servers/slapd/dn.c | 495 ++++++++++++++++-
ldap/servers/slapd/entrywsi.c | 18
ldap/servers/slapd/libglobs.c | 33 +
ldap/servers/slapd/opshared.c | 42 +
ldap/servers/slapd/pagedresults.c | 33 +
ldap/servers/slapd/proto-slap.h | 3
ldap/servers/slapd/sasl_map.c | 4
ldap/servers/slapd/slap.h | 2
ldap/servers/slapd/slapi-plugin.h | 59 ++
ldap/servers/slapd/slapi2nspr.c | 83 ++
ldap/servers/slapd/ssl.c | 73 ++
23 files changed, 850 insertions(+), 78 deletions(-)
New commits:
commit 04a60122c0c506cf6ec5797c7e36aa24960de3b1
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Tue Dec 13 15:46:43 2011 -0700
Bug 767273 - add switch to disable DN normalization of nested DNs
https://bugzilla.redhat.com/show_bug.cgi?id=767273
Resolves: bug 767273
Bug Description: add switch to disable DN normalization of nested DNs
Reviewed by: nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: Fix compiler error and warning
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 998f731..efb5868 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -511,7 +511,6 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t
*dest_len)
struct berval *subrdn_avs = NULL;
struct berval subinitial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
int chkblank = 0;
- int avstat = 0;
int is_dn_syntax = 0;
int normalize_nested_dn = config_get_normalize_nested_dn();
@@ -2605,8 +2604,8 @@ old_slapi_dn_normalize_ext(char *src, size_t src_len, char **dest,
size_t *dest_
} else if (s + 2 < ends &&
isxdigit(*(s+1)) && isxdigit(*(s+2))) {
/* esc hexpair ==> real character */
- int n = slapi_hexchar2int(*(s+1));
- int n2 = slapi_hexchar2int(*(s+2));
+ int n = hexchar2int(*(s+1));
+ int n2 = hexchar2int(*(s+2));
n = (n << 4) + n2;
if (n == 0) { /* don't change \00 */
*d++ = *++s;
commit 049b8eb771a44cc26b8178af4bce1a9d2f44aaec
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Nov 21 15:58:56 2011 -0700
Bug 730387 - attrsyntax - Add slapi_rwlock API and use POSIX rwlocks
This adds a new slapi_rwlock API and uses it throughout the server.
Internally, this API can allow either NSPR or POSIX rwlocks to be
used for different platforms. This patch makes it use the POSIX
implementation on Linux platforms since the NSPR implementation
does not safely allow re-entrant reader locks to be used.
backported from
commit f9b199ec05f4fd0d3054f05ce6cd6ba4a820d246
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Aug 17 09:20:26 2011 -0700
this patch only addresses the attrsyntax rwlocks, not all of the other
rwlocks in the server
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 6d3fe8c..0b8111f 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -55,7 +55,7 @@
*/
static PLHashTable *oid2asi = NULL;
/* read/write lock to protect table */
-static PRRWLock *oid2asi_lock = NULL;
+static Slapi_RWLock *oid2asi_lock = NULL;
/*
* This hashtable maps the name or alias of the attribute to the
@@ -65,12 +65,12 @@ static PRRWLock *oid2asi_lock = NULL;
*/
static PLHashTable *name2asi = NULL;
/* read/write lock to protect table */
-static PRRWLock *name2asi_lock = NULL;
+static Slapi_RWLock *name2asi_lock = NULL;
-#define AS_LOCK_READ(l) PR_RWLock_Rlock(l)
-#define AS_LOCK_WRITE(l) PR_RWLock_Wlock(l)
-#define AS_UNLOCK_READ(l) PR_RWLock_Unlock(l)
-#define AS_UNLOCK_WRITE(l) PR_RWLock_Unlock(l)
+#define AS_LOCK_READ(l) slapi_rwlock_rdlock(l)
+#define AS_LOCK_WRITE(l) slapi_rwlock_wrlock(l)
+#define AS_UNLOCK_READ(l) slapi_rwlock_unlock(l)
+#define AS_UNLOCK_WRITE(l) slapi_rwlock_unlock(l)
@@ -994,13 +994,12 @@ attr_syntax_init(void)
oid2asi = PL_NewHashTable(2047, hashNocaseString,
hashNocaseCompare,
PL_CompareValues, 0, 0);
- if ( NULL == ( oid2asi_lock = PR_NewRWLock( PR_RWLOCK_RANK_NONE,
- "attrsyntax oid rwlock" ))) {
+ if ( NULL == ( oid2asi_lock = slapi_new_rwlock())) {
if(oid2asi) PL_HashTableDestroy(oid2asi);
oid2asi = NULL;
slapi_log_error( SLAPI_LOG_FATAL, "attr_syntax_init",
- "PR_NewRWLock() for oid2asi lock failed\n" );
+ "slapi_new_rwlock() for oid2asi lock failed\n" );
return 1;
}
}
@@ -1010,13 +1009,12 @@ attr_syntax_init(void)
name2asi = PL_NewHashTable(2047, hashNocaseString,
hashNocaseCompare,
PL_CompareValues, 0, 0);
- if ( NULL == ( name2asi_lock = PR_NewRWLock( PR_RWLOCK_RANK_NONE,
- "attrsyntax name2asi rwlock"))) {
+ if ( NULL == ( name2asi_lock = slapi_new_rwlock())) {
if(name2asi) PL_HashTableDestroy(name2asi);
name2asi = NULL;
slapi_log_error( SLAPI_LOG_FATAL, "attr_syntax_init",
- "PR_NewRWLock() for oid2asi lock failed\n" );
+ "slapi_new_rwlock() for oid2asi lock failed\n" );
return 1;
}
}
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index ff14108..79f1e60 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -4739,6 +4739,7 @@ int slapi_is_loglevel_set( const int loglevel );
*/
typedef struct slapi_mutex Slapi_Mutex;
typedef struct slapi_condvar Slapi_CondVar;
+typedef struct slapi_rwlock Slapi_RWLock;
Slapi_Mutex *slapi_new_mutex( void );
void slapi_destroy_mutex( Slapi_Mutex *mutex );
void slapi_lock_mutex( Slapi_Mutex *mutex );
@@ -4748,6 +4749,64 @@ void slapi_destroy_condvar( Slapi_CondVar *cvar );
int slapi_wait_condvar( Slapi_CondVar *cvar, struct timeval *timeout );
int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all );
+/**
+ * Creates a new read/write lock.
+ *
+ * \return A pointer to a \c Slapi_RWLock
+ *
+ * \note Free the returned lock by calling slapi_destroy_rwlock() when finished
+ *
+ * \see slapi_destroy_rwlock()
+ * \see slapi_rwlock_rdlock()
+ * \see slapi_rwlock_wrlock()
+ * \see slapi_rwlock_unlock()
+ */
+Slapi_RWLock *slapi_new_rwlock( void );
+
+/**
+ * Free a read/write lock
+ *
+ * \see slapi_new_rwlock()
+ */
+void slapi_destroy_rwlock( Slapi_RWLock *rwlock );
+
+/**
+ * Acquires a reader lock
+ *
+ * \return 0 if successful
+ * \return Non-zero if an error occurred
+ *
+ * \note Release the acquired lock by calling slapi_rwlock_unlock()
+ * \note It is safe for a thread to hold multiple reader locks, but
+ * you must call slapi_rwlock_unlock() for each aquired lock.
+ *
+ * \see slapi_rwlock_unlock()
+ */
+int slapi_rwlock_rdlock( Slapi_RWLock *rwlock );
+
+/**
+ * Acquires a writer lock
+ *
+ * \return 0 if successful
+ * \return Non-zero if an error occurred
+ *
+ * \note Release the acquired lock by calling slapi_rwlock_unlock()
+ *
+ * \see slapi_rwlock_unlock()
+ */
+int slapi_rwlock_wrlock( Slapi_RWLock *rwlock );
+
+/**
+ * Releases a reader or writer lock
+ *
+ * \return 0 if successful
+ * \return Non-zero if an error occurred
+ *
+ * \see slapi_rwlock_rdlock()
+ * \see slapi_rwlock_wrlock()
+ */
+int slapi_rwlock_unlock( Slapi_RWLock *rwlock );
+
/*
* thread-safe LDAP connections
diff --git a/ldap/servers/slapd/slapi2nspr.c b/ldap/servers/slapd/slapi2nspr.c
index 18eebfb..c6d1d97 100644
--- a/ldap/servers/slapd/slapi2nspr.c
+++ b/ldap/servers/slapd/slapi2nspr.c
@@ -210,3 +210,86 @@ slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
return( prrc == PR_SUCCESS ? 1 : 0 );
}
+
+#ifndef USE_POSIX_RWLOCKS
+#define USE_POSIX_RWLOCKS 1
+#endif
+
+Slapi_RWLock *
+slapi_new_rwlock(void)
+{
+#ifdef USE_POSIX_RWLOCKS
+ pthread_rwlock_t *rwlock = NULL;
+
+ rwlock = (pthread_rwlock_t *)slapi_ch_malloc(sizeof(pthread_rwlock_t));
+ if (rwlock) {
+ pthread_rwlock_init(rwlock, NULL);
+ }
+
+ return((Slapi_RWLock *)rwlock);
+#else
+ return((Slapi_RWLock *)PR_NewRWLock(PR_RWLOCK_RANK_NONE, "slapi_rwlock"));
+#endif
+}
+
+void
+slapi_destroy_rwlock(Slapi_RWLock *rwlock)
+{
+ if (rwlock != NULL) {
+#ifdef USE_POSIX_RWLOCKS
+ pthread_rwlock_destroy((pthread_rwlock_t *)rwlock);
+ slapi_ch_free((void **)&rwlock);
+#else
+ PR_DestroyLock((PRRWLock *)rwlock);
+#endif
+ }
+}
+
+int
+slapi_rwlock_rdlock( Slapi_RWLock *rwlock )
+{
+ int ret = 0;
+
+ if (rwlock != NULL) {
+#ifdef USE_POSIX_RWLOCKS
+ ret = pthread_rwlock_rdlock((pthread_rwlock_t *)rwlock);
+#else
+ PR_RWLock_Rlock((PRRWLock *)rwlock);
+#endif
+ }
+
+ return ret;
+}
+
+int
+slapi_rwlock_wrlock( Slapi_RWLock *rwlock )
+{
+ int ret = 0;
+
+ if (rwlock != NULL) {
+#ifdef USE_POSIX_RWLOCKS
+ ret = pthread_rwlock_wrlock((pthread_rwlock_t *)rwlock);
+#else
+ PR_RWLock_Wlock((PRRWLock *)rwlock);
+#endif
+ }
+
+ return ret;
+}
+
+int
+slapi_rwlock_unlock( Slapi_RWLock *rwlock )
+{
+ int ret = 0;
+
+ if (rwlock != NULL) {
+#ifdef USE_POSIX_RWLOCKS
+ ret = pthread_rwlock_unlock((pthread_rwlock_t *)rwlock);
+#else
+ PR_RWLock_Unlock((PRRWLock *)rwlock);
+#endif
+ }
+
+ return ret;
+}
+
commit 1719004585a0ef439c116d63bff5a3d9c96d347e
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Tue Dec 13 11:48:38 2011 -0700
Bug 767273 - add switch to disable DN normalization of nested DNs
https://bugzilla.redhat.com/show_bug.cgi?id=767273
Resolves: bug 767273
Bug Description: add switch to disable DN normalization of nested DNs
Reviewed by: nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: Added a new cn=config attribute nsslapd-normalize-nested-dn
This is set to "on" by default. If this is set to off, the old (8.2.2)
version of slapi_normalize_dn_ext() will be used instead of the new one.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
cherry-picked from 45623ad410327af106eaf5a50a1149d3c01fc54d and rebased for 8.2
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 8e0d0fa..998f731 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -60,6 +60,7 @@ static void reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp
);
static void sort_rdn_avs( struct berval *avs, int count, int escape );
static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape );
+static int old_slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t
*dest_len);
int
@@ -512,6 +513,11 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t
*dest_len)
int chkblank = 0;
int avstat = 0;
int is_dn_syntax = 0;
+ int normalize_nested_dn = config_get_normalize_nested_dn();
+
+ if (!normalize_nested_dn) {
+ return old_slapi_dn_normalize_ext(src, src_len, dest, dest_len);
+ }
if (NULL == dest) {
goto bail;
@@ -2324,3 +2330,491 @@ sdn_dump( const Slapi_DN *sdn, const char *text)
LDAPDebug( LDAP_DEBUG_ANY, "SDN %s ptr=%lx dn=%s\n", text, sdn,
(sdn->dn==NULL?"NULL":sdn->dn));
}
#endif
+
+/*
+ * This is the old version of slapi_dn_normalize_ext that does not correctly
+ * handle DNs nested within other DNs in all cases, but is required for
+ * backwards compatability
+ * set nsslapd-normalize-nested-dn: off to use this function
+ */
+static int
+old_slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
+{
+ int rc = -1;
+ int state = B4TYPE;
+ char *s = NULL; /* work pointer for src */
+ char *d = NULL; /* work pointer for dest */
+ char *ends = NULL;
+ char *endd = NULL;
+ char *lastesc = NULL;
+ /* rdn avs for the main DN */
+ char *typestart = NULL;
+ int rdn_av_count = 0;
+ struct berval *rdn_avs = NULL;
+ struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
+ /* rdn avs for the nested DN */
+ char *subtypestart = NULL; /* used for nested rdn avs */
+ int subrdn_av_count = 0;
+ struct berval *subrdn_avs = NULL;
+ struct berval subinitial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
+ int chkblank = 0;
+
+ if (NULL == dest) {
+ goto bail;
+ }
+ if (NULL == src) {
+ *dest = NULL;
+ *dest_len = 0;
+ goto bail;
+ }
+ if (0 == src_len) {
+ src_len = strlen(src);
+ }
+ s = PL_strnchr(src, '\\', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ s = PL_strnchr(src, '"', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ *dest_len = src_len;
+ *dest = src; /* just removing spaces around separators */
+ rc = 0;
+ }
+ }
+
+ ends = src + src_len;
+ endd = *dest + *dest_len;
+ for (s = src, d = *dest; s < ends && d < endd; ) {
+ switch (state) {
+ case B4TYPE: /* before type; cn=... */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++; /* skip leading spaces */
+ } else {
+ state = INTYPE;
+ typestart = d;
+ *d++ = *s++;
+ }
+ break;
+ case INTYPE: /* in type; cn=... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
+ state = INVALUE; /* skip a trailing space */
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ state = B4EQUAL; /* skip a trailing space */
+ } else {
+ *d++ = *s++;
+ }
+ break;
+ case B4EQUAL: /* before equal; cn =... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ s++; /* skip trailing spaces */
+ } else {
+ /* type includes spaces; not a valid dn */
+ rc = -1;
+ goto bail;
+ }
+ break;
+ case B4VALUE: /* before value; cn= ABC */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++;
+ } else {
+ if (ISQUOTE(*s)) {
+ s++; /* start with the first char in quotes */
+ state = INQUOTEDVALUE1ST;
+ } else {
+ state = INVALUE1ST;
+ }
+ lastesc = NULL;
+ /* process *s in INVALUE or INQUOTEDVALUE */
+ }
+ break;
+ case INVALUE1ST: /* 1st char in value; cn=ABC */
+ /* ^ */
+ if (ISSPACE(*s)) { /* skip leading spaces */
+ s++;
+ continue;
+ } else if (SEPARATOR(*s)) {
+ /* 1st char in value is separator; invalid dn */
+ rc = -1;
+ goto bail;
+ } /* otherwise, go through */
+ if (ISESCAPE(*s)) {
+ subtypestart = NULL; /* if escaped, can't be multivalued dn */
+ } else {
+ subtypestart = d; /* prepare for '+' in the nested DN, if any */
+ }
+ subrdn_av_count = 0;
+ case INVALUE: /* in value; cn=ABC */
+ /* ^ */
+ if (ISESCAPE(*s)) {
+ if (s + 1 >= ends) {
+ /* DN ends with '\'; invalid dn */
+ rc = -1;
+ goto bail;
+ }
+ if (((state == INVALUE1ST) && LEADNEEDSESCAPE(*(s+1))) ||
+ ((state == INVALUE) && NEEDSESCAPE(*(s+1)))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*(s+1))) {
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*(s+1))) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) &&
ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUS(*(s+1)) || subrdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &subrdn_av_count,
+ &subrdn_avs, subinitial_rdn_av_stack);
+ }
+ if (!ISPLUS(*(s+1))) { /* at end of this RDN */
+ if (subrdn_av_count > 1) {
+ sort_rdn_avs( subrdn_avs,
+ subrdn_av_count, 1 );
+ }
+ if (subrdn_av_count > 0) {
+ reset_rdn_avs( &subrdn_avs,
+ &subrdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+ /* dn: cn=x\=x\,... -> dn: cn=x\3Dx\2C,... */
+ *d++ = *s++; /* '\\' */
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s)) {
+ /* next type start of multi values */
+ /* should not be a escape char AND should be
+ * followed by \\= or \\3D */
+ if (!ISESCAPE(*s) &&
+ (PL_strnstr(s, "\\=", ends - s) ||
+ PL_strncaserstr(s, "\\3D", ends - s))) {
+ subtypestart = d;
+ } else {
+ subtypestart = NULL;
+ }
+ }
+ if (SEPARATOR(*s) || ISEQUAL(*s)) {
+ while (ISSPACE(*(s+1)))
+ s++; /* remove leading spaces */
+ s++;
+ } else {
+ s++;
+ }
+ }
+ } else if (((state == INVALUE1ST) &&
+ (s+2 < ends) && LEADNEEDSESCAPESTR(s+1)) ||
+ ((state == INVALUE) &&
+ (((s+2 < ends) && NEEDSESCAPESTR(s+1)) ||
+ (ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) {
+ /* e.g., cn=abc\20 ,... */
+ /* ^ */
+ if (ISEQUALSTR(s+1)) {
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATORSTR(s+1)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d))
{
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUSSTR(s+1) || subrdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &subrdn_av_count,
+ &subrdn_avs, subinitial_rdn_av_stack);
+ }
+ if (!ISPLUSSTR(s+1)) { /* at end of this RDN */
+ if (subrdn_av_count > 1) {
+ sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 );
+ }
+ if (subrdn_av_count > 0) {
+ reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+ *d++ = *s++; /* '\\' */
+ *d++ = *s++; /* HEX */
+ *d++ = *s++; /* HEX */
+ if (ISPLUSSTR(s-2)) {
+ /* next type start of multi values */
+ /* should not be a escape char AND should be followed
+ * by \\= or \\3D */
+ if (!ISESCAPE(*s) && (PL_strnstr(s, "\\=", ends
- s) ||
+ PL_strncaserstr(s, "\\3D", ends - s))) {
+ subtypestart = d;
+ } else {
+ subtypestart = NULL;
+ }
+ }
+ if (SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ } else if (s + 2 < ends &&
+ isxdigit(*(s+1)) && isxdigit(*(s+2))) {
+ /* esc hexpair ==> real character */
+ int n = slapi_hexchar2int(*(s+1));
+ int n2 = slapi_hexchar2int(*(s+2));
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ *d++ = *++s;
+ *d++ = *++s;
+ } else {
+ *d++ = n;
+ s += 3;
+ }
+ } else {
+ /* ignore an escape for now */
+ lastesc = d; /* position of the previous escape */
+ s++;
+ }
+ } else if (SEPARATOR(*s)) { /* cn=ABC , ... */
+ /* ^ */
+ /* handling a trailing escaped space */
+ /* assuming a space is the only an extra character which
+ * is not escaped if it appears in the middle, but should
+ * be if it does at the end of the RDN value */
+ /* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
+ if (lastesc) {
+ while (ISSPACE(*(d-1)) && d > lastesc ) {
+ d--;
+ }
+ if (d == lastesc) {
+ /* esc hexpair of space: \20 */
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = '0';
+ }
+ } else {
+ while (ISSPACE(*(d-1))) {
+ d--;
+ }
+ }
+ state = B4SEPARATOR;
+ break;
+ } else { /* else if (SEPARATOR(*s)) */
+ *d++ = *s++;
+ }
+ if (state == INVALUE1ST) {
+ state = INVALUE;
+ }
+ break;
+ case INQUOTEDVALUE1ST:
+ if (ISSPACE(*s) && (s+1 < ends && ISSPACE(*(s+1)))) {
+ /* skip leading spaces but need to leave one */
+ s++;
+ continue;
+ }
+ subtypestart = d; /* prepare for '+' in the quoted value, if any */
+ subrdn_av_count = 0;
+ case INQUOTEDVALUE:
+ if (ISQUOTE(*s)) {
+ if (ISESCAPE(*(d-1))) { /* the quote is escaped */
+ PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
+ } else { /* end of INQUOTEVALUE */
+ while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A,ou=B " */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ state = B4SEPARATOR;
+ s++;
+ }
+ } else if (((state == INQUOTEDVALUE1ST) && LEADNEEDSESCAPE(*s)) ||
+ (state == INQUOTEDVALUE && NEEDSESCAPE(*s))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*s)) {
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*s)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A\ ,ou=..." */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUS(*s) || subrdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &subrdn_av_count,
+ &subrdn_avs, subinitial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (subrdn_av_count > 1) {
+ sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 );
+ }
+ if (subrdn_av_count > 0) {
+ reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+
+ /* dn: cn="x=x,..",... -> dn: cn=x\3Dx\2C,... */
+ *d++ = '\\';
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s++)) {
+ subtypestart = d; /* next type start of multi values */
+ }
+ if (SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ }
+ } else {
+ *d++ = *s++;
+ }
+ if (state == INQUOTEDVALUE1ST) {
+ state = INQUOTEDVALUE;
+ }
+ break;
+ case B4SEPARATOR:
+ if (SEPARATOR(*s)) {
+ state = B4TYPE;
+
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (typestart &&
+ (ISPLUS(*s) || rdn_av_count > 0)) {
+ add_rdn_av(typestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ typestart = NULL;
+ }
+ }
+
+ *d++ = (ISPLUS(*s++)) ? '+' : ',';
+ } else {
+ s++;
+ }
+ break;
+ default:
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "slapi_dn_normalize - unknown state %d\n", state, 0, 0 );
+ break;
+ }
+ }
+
+ /*
+ * Track and sort attribute values within multivalued RDNs.
+ */
+ /* We may still be in an unexpected state, such as B4TYPE if
+ * we encountered something odd like a '+' at the end of the
+ * rdn. If this is the case, we don't want to add this bogus
+ * rdn to our list to sort. We should only be in the INVALUE
+ * or B4SEPARATOR state if we have a valid rdn component to
+ * be added. */
+ if (typestart && (rdn_av_count > 0) && ((state == INVALUE1ST) ||
+ (state == INVALUE) || (state == B4SEPARATOR))) {
+ add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack);
+ }
+ if ( rdn_av_count > 1 ) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if ( rdn_av_count > 0 ) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ /* Trim trailing spaces */
+ while (d > *dest && ISBLANK(*(d-1))) {
+ --d; /* XXX 518524 */
+ }
+ *dest_len = d - *dest;
+bail:
+ if (rc < 0) {
+ if (*dest != src) {
+ slapi_ch_free_string(dest);
+ } else {
+ *dest = NULL;
+ }
+ *dest_len = 0;
+ } else if (rc > 0) {
+ /* We terminate the str with NULL only when we allocate the str */
+ *d = '\0';
+ }
+ return rc;
+}
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index b8e26d1..945ebca 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -624,7 +624,11 @@ static struct config_get_and_set {
{CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE, config_set_force_sasl_external,
NULL, 0,
(void**)&global_slapdFrontendConfig.force_sasl_external, CONFIG_ON_OFF,
- (ConfigGetFunc)config_get_force_sasl_external}
+ (ConfigGetFunc)config_get_force_sasl_external},
+ {CONFIG_NORMALIZE_NESTED_DN, config_set_normalize_nested_dn,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.normalize_nested_dn, CONFIG_ON_OFF,
+ (ConfigGetFunc)config_get_normalize_nested_dn}
#ifdef MEMPOOL_EXPERIMENTAL
,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
NULL, 0,
@@ -1002,6 +1006,7 @@ FrontendConfig_init () {
cfg->auditlog_exptime = 1;
cfg->auditlog_exptimeunit = slapi_ch_strdup("month");
+ cfg->normalize_nested_dn = LDAP_ON; /* normalize_nested_dn is on by default */
#ifdef MEMPOOL_EXPERIMENTAL
cfg->mempool_switch = LDAP_ON;
cfg->mempool_maxfreelist = 1024;
@@ -5526,6 +5531,32 @@ config_set_force_sasl_external( const char *attrname, char *value,
}
+int
+config_get_normalize_nested_dn(void)
+{
+ int retVal;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ /* disable locking for this value for performance */
+ /*CFG_LOCK_READ(slapdFrontendConfig);*/
+ retVal = slapdFrontendConfig->normalize_nested_dn;
+ /*CFG_UNLOCK_READ(slapdFrontendConfig);*/
+
+ return retVal;
+}
+
+int
+config_set_normalize_nested_dn( const char *attrname, char *value,
+ char *errorbuf, int apply )
+{
+ int retVal = LDAP_SUCCESS;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ retVal = config_set_onoff(attrname, value,
+ &(slapdFrontendConfig->normalize_nested_dn),
+ errorbuf, apply);
+ return retVal;
+}
+
/*
* This function is intended to be used from the dse code modify callback. It
* is "optimized" for that case because it takes a berval** of values, which
is
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 2c85b20..3392025 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -351,6 +351,7 @@ int config_set_minssf(const char *attrname, char *value, char
*errorbuf, int app
int config_set_accesslogbuffering(const char *attrname, char *value, char *errorbuf, int
apply);
int config_set_csnlogging(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_force_sasl_external(const char *attrname, char *value, char *errorbuf, int
apply );
+int config_set_normalize_nested_dn( const char *attrname, char *value, char *errorbuf,
int apply );
#if !defined(_WIN32) && !defined(AIX)
int config_set_maxdescriptors( const char *attrname, char *value, char *errorbuf, int
apply );
@@ -489,6 +490,7 @@ long config_get_system_page_size();
int config_get_system_page_bits();
#endif
int config_get_force_sasl_external();
+int config_get_normalize_nested_dn(void);
int is_abspath(const char *);
char* rel2abspath( char * );
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 1ec7224..e55fb1f 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1857,6 +1857,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters"
#define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE
"nsslapd-outbound-ldap-io-timeout"
#define CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE "nsslapd-force-sasl-external"
+#define CONFIG_NORMALIZE_NESTED_DN "nsslapd-normalize-nested-dn"
#ifdef MEMPOOL_EXPERIMENTAL
#define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
@@ -2073,6 +2074,7 @@ typedef struct _slapdFrontendConfig {
int system_page_bits; /* bit count to shift the system page size */
#endif /* MEMPOOL_EXPERIMENTAL */
int force_sasl_external; /* force SIMPLE bind to be SASL/EXTERNAL if client cert
credentials were supplied */
+ int normalize_nested_dn; /* if true, attempt to normalize DNs nested within a DN
*/
} slapdFrontendConfig_t;
/* possible values for slapdFrontendConfig_t.schemareplace */
commit 7c1124804a8b63d55827d1e3cb2f23261847559b
Author: Noriko Hosoi <nhosoi(a)jiji.usersys.redhat.com>
Date: Tue Nov 1 16:03:57 2011 -0700
Bug 750622 - Fix Coverity (11104) Resource leak:
ids_sasl_user_to_entry (slapd/saslbind.c)
https://bugzilla.redhat.com/show_bug.cgi?id=750622
Bug Description: sasl_map_domap allocates strings for "base" and
"filter" in it; the caller ids_sasl_user_to_entry releases them
only when the function returns non-0 regexmatch (matched), but
even if the return value is 0 (did not match), the strings are
allocated.
Fix Description: underlying function sasl_map_check frees "base"
and "filter" if mapping did not match.
(cherry picked from commit 6af5ece3ca029271f2b2180c24bad546e2d64c45)
diff --git a/ldap/servers/slapd/sasl_map.c b/ldap/servers/slapd/sasl_map.c
index d6a84a7..3cdabac 100644
--- a/ldap/servers/slapd/sasl_map.c
+++ b/ldap/servers/slapd/sasl_map.c
@@ -517,6 +517,8 @@ sasl_map_check(sasl_map_data *dp, char *sasl_user_and_realm, char
**ldap_search_
"sasl_map_check: slapi_re_subs failed: "
"subject: %s, subst str: %s (%d)\n",
sasl_user_and_realm, dp->template_base_dn, rc);
+ slapi_ch_free_string(ldap_search_base);
+ slapi_ch_free_string(ldap_search_filter);
} else {
/* Substitutes '&' and/or "\#" in template_search_filter */
rc = slapi_re_subs(re, sasl_user_and_realm,
@@ -527,6 +529,8 @@ sasl_map_check(sasl_map_data *dp, char *sasl_user_and_realm, char
**ldap_search_
"sasl_map_check: slapi_re_subs failed: "
"subject: %s, subst str: %s (%d)\n",
sasl_user_and_realm, dp->template_search_filter, rc);
+ slapi_ch_free_string(ldap_search_base);
+ slapi_ch_free_string(ldap_search_filter);
} else {
/* these values are internal regex representations with
* lots of unprintable control chars - escape for logging */
commit 4bdaacd5b1c06cd1ecbd1788d37f067db38957ac
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Oct 28 12:51:08 2011 -0600
Bug 748575 - part 2 - rhds81 modrdn operation and 100% cpu use in replication
https://bugzilla.redhat.com/show_bug.cgi?id=748575
Resolves: bug 748575
Bug Description: rhds81 modrdn operation and 100% cpu use in replication
Reviewed by: nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: The entry code takes great pains to add or insert in
ascending order the dncsn to the e_dncsnset. But the only place this is
ever used is in the call to entry_get_dncsn, which just calls
csnset_get_last_csn, which just gets the last one in the list. Since the
last one in the list is the one with the greatest csn, and the function
csnset_update_csn already stores the greatest csn, we can just use that
function, rather than using csnset_add and insert and building a potentially
very large list. This should also have the effect of making importing
a replica init LDIF faster.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit c07717326879119f321512d87e558b69045a86fd)
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 83a9c2a..4959047 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -184,10 +184,7 @@ int
entry_add_dncsn(Slapi_Entry *entry, const CSN *csn)
{
PR_ASSERT(entry!=NULL);
- if(!csnset_contains(entry->e_dncsnset,csn))
- {
- csnset_add_csn(&entry->e_dncsnset, CSN_TYPE_VALUE_DISTINGUISHED, csn);
- }
+ csnset_update_csn(&entry->e_dncsnset, CSN_TYPE_VALUE_DISTINGUISHED, csn);
return 0;
}
@@ -204,17 +201,7 @@ int
entry_add_dncsn_ext(Slapi_Entry *entry, const CSN *csn, PRUint32 flags)
{
PR_ASSERT(entry!=NULL);
- if(!csnset_contains(entry->e_dncsnset,csn))
- {
- if (flags & ENTRY_DNCSN_INCREASING)
- {
- csnset_insert_csn(&entry->e_dncsnset, CSN_TYPE_VALUE_DISTINGUISHED, csn);
- }
- else
- {
- csnset_add_csn(&entry->e_dncsnset, CSN_TYPE_VALUE_DISTINGUISHED, csn);
- }
- }
+ csnset_update_csn(&entry->e_dncsnset, CSN_TYPE_VALUE_DISTINGUISHED, csn);
return 0;
}
commit 7b6a831c344c33c128a15328ec0b8e46690248ec
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Oct 26 17:13:28 2011 -0600
Bug 748575 - rhds81 modrn operation and 100% cpu use in replication
https://bugzilla.redhat.com/show_bug.cgi?id=748575
Resolves: bug 748575
Bug Description: rhds81 modrn operation and 100% cpu use in replication
Reviewed by: ???
Branch: Directory_Server_8_2_Branch
Fix Description: The modrdn operation causes the entry to be copied multiple
times by calling slapi_entry_dup. This in turn does a csnset_dup of the
e_dncsnset in the entry. This function was very inefficient. It would simply
call csnset_add_csn, which would iterate to the end of the linked list
for every addition. Once you get several thousand items in the list, it
has to iterate to the end of several thousand items each time. I changed it
to keep track of the last item in the list, and just add the new item to the
end of the list. This improves the performance quite a bit, but the cpu
still gets pegged at a high percentage eventually, it just takes longer to
reach that point.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 23467126c33a1f6004bb8357d87bc355a53eb25d)
diff --git a/ldap/servers/slapd/csnset.c b/ldap/servers/slapd/csnset.c
index 645c17e..d98cecf 100644
--- a/ldap/servers/slapd/csnset.c
+++ b/ldap/servers/slapd/csnset.c
@@ -374,11 +374,13 @@ CSNSet *
csnset_dup(const CSNSet *csnset)
{
CSNSet *newcsnset= NULL;
+ CSNSet **curnode = &newcsnset;
const CSNSet *n= csnset;
while(n!=NULL)
{
- csnset_add_csn(&newcsnset,n->type,&n->csn);
+ csnset_add_csn(curnode,n->type,&n->csn);
n= n->next;
+ curnode = &((*curnode)->next);
}
return newcsnset;
}
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 01c160c..83a9c2a 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -357,6 +357,7 @@ entry_purge_state_information(Slapi_Entry *e, const CSN *csnUpTo)
*/
attr_purge_state_information(e, a, csnUpTo);
}
+ csnset_purge(&e->e_dncsnset, csnUpTo);
}
/*
commit f5ed8e84a50b27135ed30e7662a29cf0a071244e
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Jul 7 11:38:00 2011 -0600
Bug 709468 - RSA Authentication Server timeouts when using simple paged results on
RHDS 8.2.
https://bugzilla.redhat.com/show_bug.cgi?id=709468
Resolves: bug 709468
Bug Description: RSA Authentication Server timeouts when using simple paged results on
RHDS 8.2.
Reviewed by: nkinder, nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: When returning the last page of the last result set, in the
searchResultDone message, the paged results cookie is set to NULL. This
means the client cannot issue another search using this result set/cookie,
which means the server can free/reset the simple paged resources
associated with this result set. Use pagedresults_cleanup() to do this.
Since before it was assumed pagedresults_cleanup was called with the
connection lock, a new parameter tells it if it needs to lock or not.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c
index 4e87a71..8870364 100644
--- a/ldap/servers/slapd/abandon.c
+++ b/ldap/servers/slapd/abandon.c
@@ -152,7 +152,12 @@ do_abandon( Slapi_PBlock *pb )
0 );
}
- if ( NULL == o ) {
+ if (pagedresults_cleanup(pb->pb_conn, 0 /* already locked */)) {
+ /* Cleaned up paged result connection */
+ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d
ABANDON"
+ " targetop=Simple Paged Results\n",
+ pb->pb_conn->c_connid, pb->pb_op->o_opid );
+ } else if ( NULL == o ) {
slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d
ABANDON"
" targetop=NOTFOUND msgid=%d\n",
pb->pb_conn->c_connid, pb->pb_op->o_opid, id );
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index 768f959..ec2b6bd 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -200,16 +200,7 @@ connection_cleanup(Connection *conn)
/* destroy any sasl context */
sasl_dispose((sasl_conn_t**)&conn->c_sasl_conn);
/* PAGED_RESULTS */
- if (conn->c_search_result_set) {
- if (conn->c_current_be->be_search_results_release) {
- conn->c_current_be->be_search_results_release(&(conn->c_search_result_set));
- }
- conn->c_search_result_set = NULL;
- }
- conn->c_current_be = NULL;
- conn->c_search_result_count = 0;
- conn->c_timelimit = 0;
- /* PAGED_RESULTS ENDS */
+ pagedresults_cleanup(conn, 0 /* do not need to lock inside */);
/* free the connection socket buffer */
connection_free_private_buffer(conn);
@@ -2723,6 +2714,9 @@ disconnect_server_nomutex( Connection *conn, PRUint64 opconnid, int
opid, PRErro
conn->c_gettingber = 0;
connection_abandon_operations( conn );
+ pagedresults_cleanup(conn, 0 /* already locked */); /* In case the connection is on
pagedresult.
+ Better to call it after the op is abandened. */
+
if (! config_check_referral_mode()) {
/*
* If any of the outstanding operations on this
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index 08243dd..2761886 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -587,6 +587,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
sort_make_sort_response_control(pb, CONN_GET_SORT_RESULT_CODE, NULL);
}
next_be = NULL; /* to break the loop */
+ if (curr_search_count == -1) {
+ pagedresults_cleanup(pb->pb_conn, 1 /* need to lock */);
+ }
} else {
/* be_suffix null means that we are searching the default backend
* -> don't change the search parameters in pblock
@@ -725,6 +728,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
pagesize, curr_search_count);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL );
next_be = NULL; /* to break the loop */
+ if (curr_search_count == -1) {
+ pagedresults_cleanup(pb->pb_conn, 1 /* need to lock */);
+ }
}
/* if rc != 0 an error occurred while sending back the entries
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 919dd4c..270a074 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -314,6 +314,39 @@ pagedresults_set_timelimit(Connection *conn, time_t timelimit)
}
/*
+ * must be called with conn->c_mutex held
+ * return values
+ * 0: not a simple paged result connection
+ * 1: simple paged result and successfully abandoned
+ */
+int
+pagedresults_cleanup(Connection *conn, int needlock)
+{
+ int rc = 0;
+
+ if (needlock) {
+ PR_Lock(conn->c_mutex);
+ }
+ if (conn->c_current_be) {
+ if (conn->c_search_result_set) {
+ if (conn->c_current_be->be_search_results_release) {
+
conn->c_current_be->be_search_results_release(&(conn->c_search_result_set));
+ }
+ conn->c_search_result_set = NULL;
+ }
+ conn->c_current_be = 0;
+ rc = 1;
+ }
+ conn->c_search_result_count = 0;
+ conn->c_timelimit = 0;
+ conn->c_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
+ if (needlock) {
+ PR_Unlock(conn->c_mutex);
+ }
+ return rc;
+}
+
+/*
* check to see if this connection is currently processing
* a pagedresults search - if it is, return True - if not,
* mark that it is processing, and return False
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index f11565c..2c85b20 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -1349,6 +1349,7 @@ int pagedresults_set_with_sort(Connection *conn, int flags);
int pagedresults_get_sort_result_code(Connection *conn);
int pagedresults_set_sort_result_code(Connection *conn, int code);
int pagedresults_set_timelimit(Connection *conn, time_t timelimit);
+int pagedresults_cleanup(Connection *conn, int needlock);
int pagedresults_check_or_set_processing(Connection *conn);
int pagedresults_reset_processing(Connection *conn);
commit b05d4f5b97db5662bb617b312818fb20b8433d28
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Jun 22 20:54:58 2011 -0600
Bug 697694 - rhds82 - incr update state stop_fatal_error "requires administrator
action", with extop_result: 9
https://bugzilla.redhat.com/show_bug.cgi?id=697694
Resolves: bug 697694
Bug Description: incr update state stop_fatal_error "requires administrator
action", with extop_result: 9
Reviewed by: nkinder, nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: Calling ldap_result with LDAP_RES_ANY will return the first
msgid available. Because the operation sending and receiving is async
done in separate threads, we may not get the msgid corresponding to the
request we sent. This is the cause of the "Bad parameter to an LDAP
routine"
errors. We call ldap_parse_result expecting an EXTENDED operation but we get
some other operation. This causes hard failures to eventually propagate up
and halt replication with fatal errors. The solution is to call
ldap_result with the actual msgid corresponding to the operation that was
sent, instead of LDAP_RES_ANY.
This is hard to reproduce. One way I have found to consistently reproduce
the error is to set up a 4-way MMR and run one of the masters in the
debugger. Break the debugger and let the server sit idle for several minutes
until you see errors in the errors logs of the other masters. Break and
continue like this several times, and you will eventually see "Bad parameter
to an LDAP routine" errors.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/plugins/replication/repl5.h
b/ldap/servers/plugins/replication/repl5.h
index 6be21ce..6c322c2 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -398,7 +398,7 @@ void conn_set_timeout(Repl_Connection *conn, long timeout);
long conn_get_timeout(Repl_Connection *conn);
void conn_set_agmt_changed(Repl_Connection *conn);
ConnResult conn_read_result(Repl_Connection *conn, int *message_id);
-ConnResult conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval
**retdatap, LDAPControl ***returned_controls, int *message_id, int noblock);
+ConnResult conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval
**retdatap, LDAPControl ***returned_controls, int send_msgid, int *resp_msgid, int
noblock);
/* In repl5_protocol.c */
typedef struct repl_protocol Repl_Protocol;
diff --git a/ldap/servers/plugins/replication/repl5_connection.c
b/ldap/servers/plugins/replication/repl5_connection.c
index 927fb20..11bf3f7 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -284,7 +284,7 @@ conn_get_error_ex(Repl_Connection *conn, int *operation, int *error,
char **erro
/* The _ex version handles a bunch of parameters (retoidp et al) that were present in the
original
* sync operation functions, but were never actually used) */
ConnResult
-conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retdatap,
LDAPControl ***returned_controls, int *message_id, int block)
+conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retdatap,
LDAPControl ***returned_controls, int send_msgid, int *resp_msgid, int block)
{
LDAPMessage *res = NULL;
int setlevel = 0;
@@ -323,7 +323,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct
berval **retda
break;
}
- rc = ldap_result(conn->ld, LDAP_RES_ANY , 1, &local_timeout, &res);
+ rc = ldap_result(conn->ld, send_msgid, 1, &local_timeout, &res);
PR_Unlock(conn->lock);
if (0 != rc)
@@ -412,9 +412,9 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct
berval **retda
char **referrals = NULL;
char *matched = NULL;
- if (message_id)
+ if (resp_msgid)
{
- *message_id = ldap_msgid(res);
+ *resp_msgid = ldap_msgid(res);
}
rc = ldap_parse_result(conn->ld, res, &err, &matched,
@@ -483,7 +483,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct
berval **retda
ConnResult
conn_read_result(Repl_Connection *conn, int *message_id)
{
- return conn_read_result_ex(conn,NULL,NULL,NULL,message_id,1);
+ return conn_read_result_ex(conn,NULL,NULL,NULL,LDAP_RES_ANY,message_id,1);
}
/* Because the SDK isn't really thread-safe (it can deadlock between
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c
b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index d999d3b..4de9fc7 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -293,7 +293,7 @@ static void repl5_inc_result_threadmain(void *param)
while (!finished)
{
- conres = conn_read_result_ex(conn, NULL, NULL, NULL, &message_id, 0);
+ conres = conn_read_result_ex(conn, NULL, NULL, NULL, LDAP_RES_ANY, &message_id,
0);
slapi_log_error(SLAPI_LOG_REPL, NULL, "repl5_inc_result_threadmain: read result
for message_id %d\n", message_id);
/* Timeout here means that we didn't block, not a real timeout */
if (CONN_TIMEOUT == conres)
diff --git a/ldap/servers/plugins/replication/repl5_protocol_util.c
b/ldap/servers/plugins/replication/repl5_protocol_util.c
index 3fbc978..54f2a22 100644
--- a/ldap/servers/plugins/replication/repl5_protocol_util.c
+++ b/ldap/servers/plugins/replication/repl5_protocol_util.c
@@ -212,6 +212,7 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV
**ruv)
current_csn = get_current_csn(replarea_sdn);
if (NULL != current_csn)
{
+ int send_msgid = 0;
struct berval *payload = NSDS50StartReplicationRequest_new(
prot_oid, slapi_sdn_get_ndn(replarea_sdn),
NULL /* XXXggood need to provide referral(s) */, current_csn);
@@ -219,7 +220,7 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV
**ruv)
csn_free(¤t_csn);
current_csn = NULL;
crc = conn_send_extended_operation(conn,
- REPL_START_NSDS50_REPLICATION_REQUEST_OID, payload, NULL /* update control */,
NULL /* Message ID */);
+ REPL_START_NSDS50_REPLICATION_REQUEST_OID, payload, NULL /* update control */,
&send_msgid /* Message ID */);
if (CONN_OPERATION_SUCCESS != crc)
{
int operation, error;
@@ -234,7 +235,7 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV
**ruv)
error ? ldap_err2string(error) : "unknown error");
}
/* Since the operation request is async, we need to wait for the response here */
- crc = conn_read_result_ex(conn,&retoid,&retdata,NULL,NULL,1);
+ crc = conn_read_result_ex(conn,&retoid,&retdata,NULL,send_msgid,NULL,1);
ber_bvfree(payload);
payload = NULL;
/* Look at the response we got. */
@@ -482,7 +483,7 @@ release_replica(Private_Repl_Protocol *prp)
goto error;
}
/* Since the operation request is async, we need to wait for the response here */
- conres =
conn_read_result_ex(prp->conn,&retoid,&retdata,NULL,&ret_message_id,1);
+ conres =
conn_read_result_ex(prp->conn,&retoid,&retdata,NULL,sent_message_id,&ret_message_id,1);
if (CONN_OPERATION_SUCCESS != conres)
{
int operation, error;
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c
b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index 7bd6e25..8ceee7a 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -153,7 +153,7 @@ static void repl5_tot_result_threadmain(void *param)
while (!finished)
{
- conres = conn_read_result_ex(conn, NULL, NULL, NULL, &message_id, 0);
+ conres = conn_read_result_ex(conn, NULL, NULL, NULL, LDAP_RES_ANY, &message_id,
0);
/* Timeout here means that we didn't block, not a real timeout */
if (CONN_TIMEOUT == conres)
{
commit eff49fc34104ffd0c0314eb02b2f92954566a4b2
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Tue May 24 11:38:32 2011 -0600
Bug 707015 - Cannot disable SSLv3 and use TLS only
https://bugzilla.redhat.com/show_bug.cgi?id=707015
Resolves: bug 707015
Bug Description: Cannot disable SSLv3 and use TLS only
Reviewed by: nkinder (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: We had attributes in the cn=encryption,cn=config entry
for nsSSL2 and nsSSL3 but they were not being used. The way it works now
is this:
If the nsSSL3 attribute is not present, and modutil -chkfips is disabled,
SSLv3 will be enabled.
If the nsSSL3 attribute is not present, and modutil -chkfips is enabled,
SSLv3 will be disabled.
If FIPS is enabled, SSLv3 will be disabled. If the user set nsSSL3 to
"on" or boolean true, the server will print a warning message to the error
log and disable SSLv3.
If FIPS is disabled, and the nsSSL3 attribute is present, and the value
is "on" or a boolean value that evaluates to true, SSLv3 will be enabled.
If FIPS is disabled, and the nsSSL3 attribute is present, and the value
is "off" or a boolean value that evaluates to false, SSLv3 will be
disabled.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: Yes - will need to document this behavior
(cherry picked from commit 63309e4c86bf30720b8213bd2f486cc19327be62)
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index 0866dc7..158ce21 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -754,6 +754,10 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
int slapd_SSLclientAuth;
char* tmpDir;
Slapi_Entry *e = NULL;
+ PRBool enableSSL2 = PR_FALSE;
+ PRBool enableSSL3 = PR_TRUE;
+ PRBool enableTLS1 = PR_TRUE;
+ PRBool fipsMode = PR_FALSE;
/* turn off the PKCS11 pin interactive mode */
#ifndef _WIN32
@@ -803,6 +807,9 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
errorCode, slapd_pr_strerror(errorCode));
return -1;
}
+ fipsMode = PR_TRUE;
+ /* FIPS does not like to use SSLv3 */
+ enableSSL3 = PR_FALSE;
}
slapd_pk11_setSlotPWValues(slot, 0, 0);
@@ -995,23 +1002,16 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
return -1;
}
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, PR_TRUE);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to enable SSLv3 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR "
error %d - %s)",
- errorCode, slapd_pr_strerror(errorCode));
- }
-
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, PR_TRUE);
+/* Explicitly disabling SSL2 - NGK */
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL2, enableSSL2);
if (sslStatus != SECSuccess) {
errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to enable TLS "
+ slapd_SSL_warn("Security Initialization: Failed to %s SSLv2 "
"on the imported socket (" SLAPI_COMPONENT_NAME_NSPR "
error %d - %s)",
+ enableSSL2 ? "enable" : "disable",
errorCode, slapd_pr_strerror(errorCode));
+ return -1;
}
-/* Explicitly disabling SSL2 - NGK */
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL2, PR_FALSE);
/* Retrieve the SSL Client Authentication status from cn=config */
/* Set a default value if no value found */
@@ -1056,6 +1056,55 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
slapi_ch_free_string(&val);
}
+ if ( e != NULL ) {
+ val = slapi_entry_attr_get_charptr( e, "nsSSL3" );
+ if ( val ) {
+ if ( !strcasecmp( val, "off" ) ) {
+ enableSSL3 = PR_FALSE;
+ } else if ( !strcasecmp( val, "on" ) ) {
+ enableSSL3 = PR_TRUE;
+ } else {
+ enableSSL3 = slapi_entry_attr_get_bool( e, "nsSSL3" );
+ }
+ if ( fipsMode && enableSSL3 ) {
+ slapd_SSL_warn("Security Initialization: FIPS mode is enabled and
"
+ "nsSSL3 explicitly set to on - SSLv3 is not approved
"
+ "for use in FIPS mode - SSLv3 will be disabled - if
"
+ "you want to use SSLv3, you must use modutil to
"
+ "disable FIPS in the internal token.\n");
+ enableSSL3 = PR_FALSE;
+ }
+ }
+ slapi_ch_free_string( &val );
+ val = slapi_entry_attr_get_charptr( e, "nsTLS1" );
+ if ( val ) {
+ if ( !strcasecmp( val, "off" ) ) {
+ enableTLS1 = PR_FALSE;
+ } else if ( !strcasecmp( val, "on" ) ) {
+ enableTLS1 = PR_TRUE;
+ } else {
+ enableTLS1 = slapi_entry_attr_get_bool( e, "nsTLS1" );
+ }
+ }
+ slapi_ch_free_string( &val );
+ }
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: 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("Security Initialization: Failed to %s TLSv1 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR "
error %d - %s)",
+ enableTLS1 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
freeConfigEntry( &e );
if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF )
{
commit d999fa991f1440735e5082fc0579d80d0148fd19
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Sat Mar 20 21:03:59 2010 -0500
Bug 520151 - Error when modifying userPassword with proxy user
https://bugzilla.redhat.com/show_bug.cgi?id=520151
Resolves: bug 520151
Bug description: Error when modifying userPassword with proxy user
Fix description: The acl_access_allowed() has been modified to
call aclplugin_preop_common() which will initialize the aclpb.
The aclplugin_preop_common() has been modified to check for the
ACLPB_INITIALIZED flag to avoid re-initializing aclpb.
Reviewed by: rmeggins (and pushed by)
(cherry picked from commit 742032c11f0dabbdc80ba204801c27c4cbe305a4)
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 9cb9229..3b9f057 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -323,6 +323,9 @@ acl_access_allowed(
/* Get the bindDN */
slapi_pblock_get ( pb, SLAPI_REQUESTOR_DN, &clientDn );
+ /* Initialize aclpb */
+ aclplugin_preop_common( pb );
+
/* get the right acl pblock to work with */
if ( access & SLAPI_ACL_PROXY )
aclpb = acl_get_aclpb ( pb, ACLPB_PROXYDN_PBLOCK );
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index cbfde48..3f4b4e6 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -932,4 +932,6 @@ acl_get_effective_rights ( Slapi_PBlock *pb, Slapi_Entry *e,
char* aclutil__access_str (int type , char str[]);
+int aclplugin_preop_common( Slapi_PBlock *pb );
+
#endif /* _ACL_H_ */
diff --git a/ldap/servers/plugins/acl/aclplugin.c b/ldap/servers/plugins/acl/aclplugin.c
index 881d0f1..12c435d 100644
--- a/ldap/servers/plugins/acl/aclplugin.c
+++ b/ldap/servers/plugins/acl/aclplugin.c
@@ -54,7 +54,7 @@ char *plugin_name = ACL_PLUGIN_NAME;
static int aclplugin_preop_search ( Slapi_PBlock *pb );
static int aclplugin_preop_modify ( Slapi_PBlock *pb );
-static int aclplugin_preop_common ( Slapi_PBlock *pb );
+int aclplugin_preop_common ( Slapi_PBlock *pb );
/*******************************************************************************
* ACL PLUGIN Architecture
@@ -192,7 +192,7 @@ aclplugin_preop_modify ( Slapi_PBlock *pb )
* 0 - all is well; proceed.
* 1 - fatal error; result has been sent to client.
*/
-static int
+int
aclplugin_preop_common( Slapi_PBlock *pb )
{
char *proxy_dn; /* id being assumed */
@@ -205,6 +205,9 @@ aclplugin_preop_common( Slapi_PBlock *pb )
aclpb = acl_get_aclpb ( pb, ACLPB_BINDDN_PBLOCK );
+ /* See if we have initialized already */
+ if ( aclpb->aclpb_state & ACLPB_INITIALIZED ) goto done;
+
/*
* The following mallocs memory for proxy_dn, but not the dn.
* The proxy_dn is the id being assumed, while dn
@@ -248,6 +251,7 @@ aclplugin_preop_common( Slapi_PBlock *pb )
}
+done:
TNF_PROBE_0_DEBUG(aclplugin_preop_common_end ,"ACL","");
return 0;
commit b116c808e854fb85f08651a00c5a452b4b1e5aa3
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Sep 22 16:28:59 2010 -0700
Bug 606920 - anonymous resource limit- nstimelimit -
also applied to "cn=directory manager"
https://bugzilla.redhat.com/show_bug.cgi?id=606920
Description: Client side sizelimit / timelimit request should
be honoured by the Directory Manager, too. Changing the time/
sizelimit evaluation so that if client side request exists,
the value is set even if the bind user is the directory manager.
(cherry picked from commit f980ff61da122b39d33bf83bc20f2b7a81b6be24)
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index 761d48a..08243dd 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -1380,12 +1380,18 @@ compute_limits (Slapi_PBlock *pb)
}
}
- if ( isroot ) {
- timelimit = max_timelimit = -1; /* no limit */
- } else if ( requested_timelimit == 0 ) {
- timelimit = ( max_timelimit == -1 ) ? -1 : max_timelimit;
- } else if ( max_timelimit == -1 || requested_timelimit < max_timelimit ) {
- timelimit = requested_timelimit;
+ if ( requested_timelimit ) {
+ /* requested limit should be applied to all (including root) */
+ if ( isroot ) {
+ timelimit = requested_timelimit;
+ } else if ( (max_timelimit == -1) ||
+ (requested_timelimit < max_timelimit) ) {
+ timelimit = requested_timelimit;
+ } else {
+ timelimit = max_timelimit;
+ }
+ } else if ( isroot ) {
+ timelimit = -1; /* no limit */
} else {
timelimit = max_timelimit;
}
@@ -1411,12 +1417,18 @@ compute_limits (Slapi_PBlock *pb)
}
}
- if ( isroot ) {
- sizelimit = max_sizelimit = -1;
- } else if ( requested_sizelimit == 0 ) {
- sizelimit = ( max_sizelimit == -1 ) ? -1 : max_sizelimit;
- } else if ( max_sizelimit == -1 || requested_sizelimit < max_sizelimit ) {
- sizelimit = requested_sizelimit;
+ if ( requested_sizelimit ) {
+ /* requested limit should be applied to all (including root) */
+ if ( isroot ) {
+ sizelimit = requested_sizelimit;
+ } else if ( (max_sizelimit == -1) ||
+ (requested_sizelimit < max_sizelimit) ) {
+ sizelimit = requested_sizelimit;
+ } else {
+ sizelimit = max_sizelimit;
+ }
+ } else if ( isroot ) {
+ sizelimit = -1; /* no limit */
} else {
sizelimit = max_sizelimit;
}