[389-commits] Branch 'Directory_Server_8_2_Branch' - ldap/servers

Noriko Hosoi nhosoi at fedoraproject.org
Thu Mar 11 19:17:32 UTC 2010


 ldap/servers/plugins/syntaxes/validate.c |    1 
 ldap/servers/slapd/back-ldbm/ldbm_add.c  |    9 +
 ldap/servers/slapd/dn.c                  |  153 +++++++++++++++++++------------
 3 files changed, 102 insertions(+), 61 deletions(-)

New commits:
commit b46d314292ae186a64692e550e7e1fa289596f08
Author: Noriko Hosoi <nhosoi at redhat.com>
Date:   Thu Mar 11 11:10:48 2010 -0800

    199923 - subtree search fails to find items under a db
             containing special characters
    
    https://bugzilla.redhat.com/show_bug.cgi?id=199923
    
    Description: regression observed in the tests.
    > as of March 04, 2010, this is happening again.
    
    Fix Description:
    dn.c: Based upon RFC 4514, the following characters in the RDN
    values need to be escaped:
      '+', ';', '<', '>', and '=' for the intermediate characters
      '+', ';', '<', '>', '=', '#' and ' ' for leading characters
      '+', ';', '<', '>', '=', and ' ' for trailing characters
    
    validate.c: If an escaped character followed by another escaped
    character, e.g., \#\<,  the pointer was moved twice skipping '\'
    before '<' and it makes the validation fail.
    
    ldbm_add.c: a local variable addr was not initialized.

diff --git a/ldap/servers/plugins/syntaxes/validate.c b/ldap/servers/plugins/syntaxes/validate.c
index d0da4be..aab6d9c 100644
--- a/ldap/servers/plugins/syntaxes/validate.c
+++ b/ldap/servers/plugins/syntaxes/validate.c
@@ -535,7 +535,6 @@ int rdn_validate( const char *begin, const char *end, const char **last )
 						}
 						p++;
 					}
-					p++;
 				/* Only allow 'SUTF1' chars now. */
 				} else if (!IS_SUTF1(*p)) {
 					rc = 1;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 3bd6eae..76cc6bb 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -112,7 +112,7 @@ ldbm_back_add( Slapi_PBlock *pb )
 	int is_fixup_operation= 0;
 	int is_ruv = 0;				 /* True if the current entry is RUV */
 	CSN *opcsn = NULL;
-	entry_address addr;
+	entry_address addr = {0};
 
 	slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
 	slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e );
@@ -188,7 +188,7 @@ ldbm_back_add( Slapi_PBlock *pb )
 		{
 			/* Check if an entry with the intended uniqueid already exists. */
 			done_with_pblock_entry(pb,SLAPI_ADD_EXISTING_UNIQUEID_ENTRY); /* Could be through this multiple times */
-			addr.dn = NULL;
+			addr.dn = addr.udn = NULL;
 			addr.uniqueid = (char*)slapi_entry_get_uniqueid(e); /* jcm -  cast away const */
 			ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_EXISTING_UNIQUEID_ENTRY, !is_replicated_operation);
 		}
@@ -211,6 +211,7 @@ ldbm_back_add( Slapi_PBlock *pb )
 			/* Check if an entry with the intended DN already exists. */
 			done_with_pblock_entry(pb,SLAPI_ADD_EXISTING_DN_ENTRY); /* Could be through this multiple times */
 			addr.dn = dn;
+			addr.udn = NULL;
 			addr.uniqueid = NULL;
 			ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_EXISTING_DN_ENTRY, !is_replicated_operation);
 			if(ldap_result_code==LDAP_OPERATIONS_ERROR ||
@@ -226,6 +227,7 @@ ldbm_back_add( Slapi_PBlock *pb )
 		{
 			done_with_pblock_entry(pb,SLAPI_ADD_PARENT_ENTRY); /* Could be through this multiple times */
 			addr.dn = (char*)slapi_sdn_get_dn (&parentsdn); /* get_copy_of_entry assumes the DN is not normalized */
+			addr.udn = NULL;
 			addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
 			ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_PARENT_ENTRY, !is_replicated_operation);
 			/* need to set parentsdn or parentuniqueid if either is not set? */
@@ -265,6 +267,7 @@ ldbm_back_add( Slapi_PBlock *pb )
 	if(have_parent_address(&parentsdn, operation->o_params.p.p_add.parentuniqueid))
 	{
 		addr.dn = (char*)slapi_sdn_get_dn (&parentsdn);
+		addr.udn = NULL;
 		addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
 		parententry = find_entry2modify_only(pb,be,&addr,&txn);
 		if (parententry && parententry->ep_entry) {
@@ -345,7 +348,7 @@ ldbm_back_add( Slapi_PBlock *pb )
 		 * When we resurect a tombstone we must use its UniqueID
 		 * to find the tombstone entry and lock it down in the cache.
 		 */
-		addr.dn = NULL;
+		addr.dn = addr.udn = NULL;
 		addr.uniqueid = (char *)slapi_entry_get_uniqueid(e); /* jcm - cast away const */
 		tombstoneentry = find_entry2modify( pb, be, &addr, NULL );
 		if ( tombstoneentry==NULL )
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 6aa7ae7..3ab9327 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -77,10 +77,16 @@ hexchar2int( char c )
     return( -1 );
 }
 
-#define DNSEPARATOR(c)	(c == ',' || c == ';')
-#define SEPARATOR(c)	(c == ',' || c == ';' || c == '+')
-#define SPACE(c)	(c == ' ' || c == '\n')   /* XXX 518524 */
-#define NEEDSESCAPE(c)	(c == '\\' || c == '"')
+#define DNSEPARATOR(c)	(((c) == ',') || ((c) == ';'))
+#define SEPARATOR(c)	(((c) == ',') || ((c) == ';') || ((c) == '+'))
+#define SPACE(c)	(((c) == ' ') || ((c) == '\n'))   /* XXX 518524 */
+#define NEEDSESCAPE(c)	(((c) == '\\') || ((c) == '"') || ((c) == '+') || \
+  ((c) == ',') || ((c) == ';') || ((c) == '<') || ((c) == '>') || ((c) == '='))
+#define LEADNEEDSESCAPE(c)	(((c) == ' ') || ((c) == '#') || NEEDSESCAPE(c))
+#if 0 /* not used */
+#define ONLYTRAILNEEDSESCAPE(c)	((c) == ' ') 
+#define TRAILNEEDSESCAPE(c)	(ONLYTRAILNEEDSESCAPE(c) || NEEDSESCAPE(c))
+#endif
 #define B4TYPE		0
 #define INTYPE		1
 #define B4EQUAL		2
@@ -88,6 +94,7 @@ hexchar2int( char c )
 #define INVALUE		4
 #define INQUOTEDVALUE	5
 #define B4SEPARATOR	6
+#define INVALUE1ST	7
 
 #define SLAPI_DNNORM_INITIAL_RDN_AVS	10
 #define SLAPI_DNNORM_SMALL_RDN_AV	512
@@ -148,6 +155,8 @@ substr_dn_normalize( char *dn, char *end )
 	char		*d = NULL;
 	char 		*s = NULL;
 	char		*typestart = NULL;
+	char		*rdnbegin = NULL;
+	char		*lastesc = NULL;
 	int		gotesc = 0;
 	int		state = B4TYPE;
 	int		rdn_av_count = 0;
@@ -186,75 +195,104 @@ substr_dn_normalize( char *dn, char *end )
 			if ( *s == '"' || ! SPACE( *s ) ) {
 				value_separator = NULL;
 				value = d;
-				state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE;
+				state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE1ST;
+				rdnbegin = d;
+				lastesc = NULL;
 				*d++ = *s;
 			}
 			break;
+		case INVALUE1ST:
 		case INVALUE:
 			if ( gotesc ) {
 				if ( SEPARATOR( *s ) ) {
 					value_separator = d;
-				} else if ( ! NEEDSESCAPE( *s ) ) {
+				}
+				if ( INVALUE1ST == state ) {
+					if ( !LEADNEEDSESCAPE( *s )) {
+						/* checking the leading char + special chars */
+						--d; /* eliminate the \ */
+					}
+				} else if ( !NEEDSESCAPE( *s ) ) {
 					--d; /* eliminate the \ */
+					lastesc = d;
 				}
 			} else if ( SEPARATOR( *s ) ) {
-				while ( SPACE( *(d - 1) ) )
-					d--;
+				/* 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 ( SPACE( *(d - 1) ) && d > lastesc ) {
+						d--;
+					}
+					if ( d == lastesc ) {
+						*d++ = '\\';
+						*d++ = ' '; /* escaped trailing space */
+					}
+				} else {
+					while ( SPACE( *(d - 1) ) ) {
+						d--;
+					}
+				}
 				if ( value_separator == dn ) { /* 2 or more separators */
-				/* convert to quoted value: */
-				char *L = NULL; /* char after last seperator */
-				char *R; /* value character iterator */
-				int escape_skips = 0; /* number of escapes we have seen after the first */
-
-				for ( R = value; (R = strchr( R, '\\' )) && (R < d); L = ++R ) {
-					if ( SEPARATOR( R[1] )) {
-						if ( L == NULL ) {
-							/* executes once, at first escape, adds opening quote */
-							const size_t len = R - value;
+					/* convert to quoted value: */
+					char *L = NULL; /* char after last seperator */
+					char *R; /* value character iterator */
+					int escape_skips = 0; /* number of escapes we have seen after the first */
+
+					for ( R = value; (R = strchr( R, '\\' )) && (R < d); L = ++R ) {
+						if ( SEPARATOR( R[1] )) {
+							if ( L == NULL ) {
+								/* executes once, at first escape, adds opening quote */
+								const size_t len = R - value;
 							
-							/* make room for quote by covering escape */
-							if ( len > 0 ) {
-								memmove( value+1, value, len );
+								/* make room for quote by covering escape */
+								if ( len > 0 ) {
+									memmove( value+1, value, len );
+								}
+
+								*value = '"'; /* opening quote */
+								value = R + 1; /* move passed what has been parsed */
+							} else {
+								const size_t len = R - L;
+								if ( len > 0 ) {
+									/* remove the seperator */
+									memmove( value, L, len );
+									value += len; /* move passed what has been parsed */
+								}
+								--d;
+								++escape_skips;
 							}
+						} /* if ( SEPARATOR( R[1] )) */
+					} /* for */
+					memmove( value, L, d - L + escape_skips );
+					*d++ = '"'; /* closing quote */
+				} /* if (value_separator == dn) */
+				state = B4TYPE;
 
-							*value = '"'; /* opening quote */
-							value = R + 1; /* move passed what has been parsed */
-						} else {
-							const size_t len = R - L;
-							if ( len > 0 ) {
-								/* remove the seperator */
-								memmove( value, L, len );
-								value += len; /* move passed what has been parsed */
-							}
-							--d;
-							++escape_skips;
-						}
-					}
-				}
-				memmove( value, L, d - L + escape_skips );
-				*d++ = '"'; /* closing quote */
-			}
-			state = B4TYPE;
-
-			/*
-			 * Track and sort attribute values within
-			 * multivalued RDNs.
-			 */
-			if ( *s == '+' || rdn_av_count > 0 ) {
-				add_rdn_av( typestart, d, &rdn_av_count,
-					&rdn_avs, initial_rdn_av_stack );
-			}
-			if ( *s != '+' ) {	/* at end of this RDN */
-				if ( rdn_av_count > 1 ) {
-					sort_rdn_avs( rdn_avs, rdn_av_count );
+				/*
+				 * Track and sort attribute values within
+				 * multivalued RDNs.
+				 */
+				if ( *s == '+' || rdn_av_count > 0 ) {
+					add_rdn_av( typestart, d, &rdn_av_count,
+								&rdn_avs, initial_rdn_av_stack );
 				}
-				if ( rdn_av_count > 0 ) {
-					reset_rdn_avs( &rdn_avs, &rdn_av_count );
+				if ( *s != '+' ) {	/* at end of this RDN */
+					if ( rdn_av_count > 1 ) {
+						sort_rdn_avs( rdn_avs, rdn_av_count );
+					}
+					if ( rdn_av_count > 0 ) {
+						reset_rdn_avs( &rdn_avs, &rdn_av_count );
+					}
 				}
-			}
 
-			*d++ = (*s == '+') ? '+' : ',';
-			break;
+				*d++ = (*s == '+') ? '+' : ',';
+				break;
+			} /* else if ( SEPARATOR( *s ) ) */
+			if ( INVALUE1ST == state ) {
+				state = INVALUE;
 			}
 			*d++ = *s;
 			break;
@@ -355,7 +393,8 @@ substr_dn_normalize( char *dn, char *end )
 	 * 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 ((rdn_av_count > 0) && ((state == INVALUE) || (state == B4SEPARATOR))) {
+	if ((rdn_av_count > 0) && ((state == INVALUE1ST) || 
+		(state == INVALUE) || (state == B4SEPARATOR))) {
 		add_rdn_av( typestart, d, &rdn_av_count,
 			&rdn_avs, initial_rdn_av_stack );
 	}




More information about the 389-commits mailing list