From 81c616fdb22d73badde56d018ffe95ce263a8a25 Mon Sep 17 00:00:00 2001
From: Pierangelo Masarati <ando@openldap.org>
Date: Mon, 7 Apr 2003 19:01:48 +0000
Subject: [PATCH] works fine now

---
 servers/slapd/back-meta/compare.c |   2 +-
 servers/slapd/back-meta/conn.c    |  48 ++----------
 servers/slapd/back-meta/modrdn.c  |  87 +++++----------------
 servers/slapd/back-meta/search.c  | 124 ++++++++----------------------
 4 files changed, 61 insertions(+), 200 deletions(-)

diff --git a/servers/slapd/back-meta/compare.c b/servers/slapd/back-meta/compare.c
index 6633d1ddc1..8679e42384 100644
--- a/servers/slapd/back-meta/compare.c
+++ b/servers/slapd/back-meta/compare.c
@@ -83,7 +83,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
 	struct metasingleconn *lsc;
 	char *match = NULL, *err = NULL;
 	struct berval mmatch = { 0, NULL };
-	int candidates = 0, last = 0, i, count, rc;
+	int candidates = 0, last = 0, i, count = 0, rc;
        	int cres = LDAP_SUCCESS, rres = LDAP_SUCCESS;
 	int *msgid;
 	dncookie dc;
diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c
index ba4d50fc93..f13352e7bb 100644
--- a/servers/slapd/back-meta/conn.c
+++ b/servers/slapd/back-meta/conn.c
@@ -228,6 +228,7 @@ init_one_conn(
 		)
 {
 	int		vers;
+	dncookie	dc;
 
 	/*
 	 * Already init'ed
@@ -262,51 +263,16 @@ init_one_conn(
 	 * If the connection dn is not null, an attempt to rewrite it is made
 	 */
 	if ( op->o_conn->c_dn.bv_len != 0 ) {
+		dc.rwmap = &lt->rwmap;
+		dc.conn = op->o_conn;
+		dc.rs = rs;
+		dc.ctx = "bindDn";
 		
 		/*
 		 * Rewrite the bind dn if needed
 		 */
-		lsc->bound_dn.bv_val = NULL;
-		switch ( rewrite_session( lt->rwmap.rwm_rw, "bindDn",
-					op->o_conn->c_dn.bv_val, op->o_conn, 
-					&lsc->bound_dn.bv_val ) ) {
-		case REWRITE_REGEXEC_OK:
-			if ( lsc->bound_dn.bv_val == NULL ) {
-				ber_dupbv( &lsc->bound_dn, &op->o_conn->c_dn );
-			}
-#ifdef NEW_LOGGING
-			LDAP_LOG( BACK_META, DETAIL1,
-				"[rw] bindDn: \"%s\" -> \"%s\"\n",
-				op->o_conn->c_dn.bv_val,
-				lsc->bound_dn.bv_val, 0 );
-#else /* !NEW_LOGGING */
-			Debug( LDAP_DEBUG_ARGS,
-				       	"rw> bindDn: \"%s\" -> \"%s\"\n",
-					op->o_conn->c_dn.bv_val,
-					lsc->bound_dn.bv_val, 0 );
-#endif /* !NEW_LOGGING */
-			break;
-			
-		case REWRITE_REGEXEC_UNWILLING:
-			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-			rs->sr_text = "Operation not allowed";
-#if 0
-			send_ldap_result( conn, op,
-					LDAP_UNWILLING_TO_PERFORM,
-					NULL, "Operation not allowed",
-					NULL, NULL );
-#endif
-			return rs->sr_err;
-			
-		case REWRITE_REGEXEC_ERR:
-			rs->sr_err = LDAP_OTHER;
-			rs->sr_text = "Rewrite error";
-#if 0
-			send_ldap_result( conn, op,
-					LDAP_OTHER,
-					NULL, "Rewrite error",
-					NULL, NULL );
-#endif
+		if ( ldap_back_dn_massage( &dc, &op->o_conn->c_dn, &lsc->bound_dn) ) {
+			send_ldap_result( op, rs );
 			return rs->sr_err;
 		}
 
diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c
index d7b3068ef2..2d94b0a470 100644
--- a/servers/slapd/back-meta/modrdn.c
+++ b/servers/slapd/back-meta/modrdn.c
@@ -94,8 +94,9 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
 	struct metaconn		*lc;
 	int			rc = 0;
 	int			candidate = -1;
-	char			*mdn = NULL,
-				*mnewSuperior = NULL;
+	struct berval		mdn = { 0, NULL },
+				mnewSuperior = { 0, NULL };
+	dncookie		dc;
 
 	lc = meta_back_getconn( op, rs, META_OP_REQUIRE_SINGLE,
 			&op->o_req_ndn, &candidate );
@@ -111,6 +112,9 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
 		goto cleanup;
 	}
 
+	dc.conn = op->o_conn;
+	dc.rs = rs;
+
 	if ( op->oq_modrdn.rs_newSup ) {
 		int nsCandidate, version = LDAP_VERSION3;
 
@@ -137,40 +141,13 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
 
 		ldap_set_option( lc->conns[ nsCandidate ].ld,
 				LDAP_OPT_PROTOCOL_VERSION, &version );
-		
+
 		/*
 		 * Rewrite the new superior, if defined and required
 	 	 */
-		switch ( rewrite_session( li->targets[ nsCandidate ]->rwmap.rwm_rw,
-					"newSuperiorDn",
-					op->oq_modrdn.rs_newSup->bv_val, 
-					op->o_conn, 
-					&mnewSuperior ) ) {
-		case REWRITE_REGEXEC_OK:
-			if ( mnewSuperior == NULL ) {
-				mnewSuperior = ( char * )op->oq_modrdn.rs_newSup;
-			}
-#ifdef NEW_LOGGING
-			LDAP_LOG( BACK_META, DETAIL1,
-				"[rw] newSuperiorDn: \"%s\" -> \"%s\"\n",
-				op->oq_modrdn.rs_newSup, mnewSuperior, 0 );
-#else /* !NEW_LOGGING */
-			Debug( LDAP_DEBUG_ARGS, "rw> newSuperiorDn:"
-					" \"%s\" -> \"%s\"\n",
-					op->oq_modrdn.rs_newSup->bv_val,
-					mnewSuperior, 0 );
-#endif /* !NEW_LOGGING */
-			break;
-
-		case REWRITE_REGEXEC_UNWILLING:
-			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-			rs->sr_text = "Operation not allowed";
-			rc = -1;
-			goto cleanup;
-
-		case REWRITE_REGEXEC_ERR:
-			rs->sr_err = LDAP_OTHER;
-			rs->sr_text = "Rewrite error";
+		dc.rwmap = &li->targets[ nsCandidate ]->rwmap;
+		dc.ctx = "newSuperiorDN";
+		if ( ldap_back_dn_massage( &dc, op->oq_modrdn.rs_newSup, &mnewSuperior ) ) {
 			rc = -1;
 			goto cleanup;
 		}
@@ -179,48 +156,26 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
 	/*
 	 * Rewrite the modrdn dn, if required
 	 */
-	switch ( rewrite_session( li->targets[ candidate ]->rwmap.rwm_rw,
-				"modrDn", op->o_req_dn.bv_val,
-				op->o_conn, &mdn ) ) {
-	case REWRITE_REGEXEC_OK:
-		if ( mdn == NULL ) {
-			mdn = ( char * )op->o_req_dn.bv_val;
-		}
-#ifdef NEW_LOGGING
-		LDAP_LOG( BACK_META, DETAIL1,
-				"[rw] modrDn: \"%s\" -> \"%s\"\n",
-				op->o_req_dn.bv_val, mdn, 0 );
-#else /* !NEW_LOGGING */
-		Debug( LDAP_DEBUG_ARGS, "rw> modrDn: \"%s\" -> \"%s\"\n",
-				op->o_req_dn.bv_val, mdn, 0 );
-#endif /* !NEW_LOGGING */
-		break;
-		
-	case REWRITE_REGEXEC_UNWILLING:
-		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-		rs->sr_text = "Operation not allowed";
-		rc = -1;
-		goto cleanup;
-
-	case REWRITE_REGEXEC_ERR:
-		rs->sr_err = LDAP_OTHER;
-		rs->sr_text = "Rewrite error";
+	dc.rwmap = &li->targets[ candidate ]->rwmap;
+	dc.ctx = "modrDN";
+	if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
 		rc = -1;
 		goto cleanup;
 	}
 
-	ldap_rename2_s( lc->conns[ candidate ].ld, mdn,
+	ldap_rename2_s( lc->conns[ candidate ].ld, mdn.bv_val,
 			op->oq_modrdn.rs_newrdn.bv_val,
-			mnewSuperior, op->oq_modrdn.rs_deleteoldrdn );
+			mnewSuperior.bv_val,
+			op->oq_modrdn.rs_deleteoldrdn );
 
 cleanup:;
-	if ( mdn != op->o_req_dn.bv_val ) {
-		free( mdn );
+	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
+		free( mdn.bv_val );
 	}
 	
-	if ( mnewSuperior != NULL 
-			&& mnewSuperior != op->oq_modrdn.rs_newSup->bv_val ) {
-		free( mnewSuperior );
+	if ( mnewSuperior.bv_val != NULL 
+			&& mnewSuperior.bv_val != op->oq_modrdn.rs_newSup->bv_val ) {
+		free( mnewSuperior.bv_val );
 	}
 
 	if ( rc == 0 ) {
diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c
index 52f366feef..7d17b68fbf 100644
--- a/servers/slapd/back-meta/search.c
+++ b/servers/slapd/back-meta/search.c
@@ -104,8 +104,8 @@ meta_back_search( Operation *op, SlapReply *rs )
 	struct timeval	tv = { 0, 0 };
 	LDAPMessage	*res, *e;
 	int	rc = 0, *msgid, sres = LDAP_NO_SUCH_OBJECT;
-	char *match = NULL, *err = NULL;
-	char *mmatch = NULL;
+	char *err = NULL;
+	struct berval match = { 0, NULL }, mmatch = { 0, NULL };
 	BerVarray v2refs = NULL;
 		
 	int i, last = 0, candidates = 0;
@@ -513,22 +513,22 @@ new_candidate:;
 				}
 				ldap_get_option( lsc->ld,
 						LDAP_OPT_ERROR_STRING, &err );
-				if ( match != NULL ) {
-					free( match );
+				if ( match.bv_val != NULL ) {
+					free( match.bv_val );
 				}
 				ldap_get_option( lsc->ld,
-						LDAP_OPT_MATCHED_DN, &match );
+						LDAP_OPT_MATCHED_DN, &match.bv_val );
 
 #ifdef NEW_LOGGING
 				LDAP_LOG( BACK_META, ERR,
 					"meta_back_search [%d] "
 					"match=\"%s\" err=\"%s\"\n",
-					i, match, err );
+					i, match.bv_val, err );
 #else /* !NEW_LOGGING */
 				Debug( LDAP_DEBUG_ANY,
 					"=>meta_back_search [%d] "
 					"match=\"%s\" err=\"%s\"\n",
-     					i, match, err );	
+     					i, match.bv_val, err );	
 #endif /* !NEW_LOGGING */
 				
 				last = i;
@@ -570,31 +570,12 @@ new_candidate:;
 	 * 
 	 * FIXME: only the last one gets caught!
 	 */
-	if ( match != NULL ) {
-		switch ( rewrite_session( li->targets[ last ]->rwmap.rwm_rw,
-					"matchedDn", match, op->o_conn,
-					&mmatch ) ) {
-		case REWRITE_REGEXEC_OK:
-			if ( mmatch == NULL ) {
-				mmatch = ( char * )match;
-			}
-#ifdef NEW_LOGGING
-			LDAP_LOG( BACK_META, DETAIL1,
-				"[rw] matchedDn: \"%s\" -> \"%s\"\n",
-				match, mmatch, 0 );
-#else /* !NEW_LOGGING */
-			Debug( LDAP_DEBUG_ARGS,
-				"rw> matchedDn: \"%s\" -> \"%s\"\n",
-				match, mmatch, 0 );
-#endif /* !NEW_LOGGING */
-			break;
-			
-		case REWRITE_REGEXEC_UNWILLING:
-			
-		case REWRITE_REGEXEC_ERR:
-			/* FIXME: no error, but no matched ... */
-			mmatch = NULL;
-			break;
+	if ( match.bv_val != NULL && *match.bv_val ) {
+		dc.ctx = "matchedDn";
+		dc.rwmap = &li->targets[ last ]->rwmap;
+
+		if ( ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
+			mmatch.bv_val = NULL;
 		}
 	}
 
@@ -609,7 +590,7 @@ new_candidate:;
 		sres = LDAP_REFERRAL;
 	}
 	rs->sr_err = sres;
-	rs->sr_matched = mmatch;
+	rs->sr_matched = mmatch.bv_val;
 	rs->sr_v2ref = v2refs;
 	send_ldap_result( op, rs );
 	rs->sr_matched = NULL;
@@ -617,11 +598,11 @@ new_candidate:;
 
 
 finish:;
-	if ( match ) {
-		if ( mmatch != match ) {
-			free( mmatch );
+	if ( match.bv_val ) {
+		if ( mmatch.bv_val != match.bv_val ) {
+			free( mmatch.bv_val );
 		}
-		free(match);
+		free( match.bv_val );
 	}
 	
 	if ( err ) {
@@ -695,6 +676,7 @@ meta_send_entry(
 	ent.e_private = 0;
 	attrp = &ent.e_attrs;
 
+	dc.ctx = "searchAttrDN";
 	while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
 		ldap_back_map( &li->targets[ target ]->rwmap.rwm_at, 
 				&a, &mapped, BACKLDAP_REMAP );
@@ -727,6 +709,16 @@ meta_send_entry(
 
 		/* no subschemaSubentry */
 		if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
+
+			/* 
+			 * We eat target's subschemaSubentry because
+			 * a search for this value is likely not
+			 * to resolve to the appropriate backend;
+			 * later, the local subschemaSubentry is
+			 * added.
+			 */
+			( void )ber_scanf( &ber, "x" /* [W] */ );
+
 			ch_free(attr);
 			continue;
 		}
@@ -770,61 +762,9 @@ meta_send_entry(
 		 * ACLs to the target directory server, and letting
 		 * everything pass thru the ldap backend.
 		 */
-		} else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
-					SLAPD_DN_SYNTAX ) == 0 ) {
-			int		last;
-
-			for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
-
-			for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
-				char *newval;
-
-				switch ( rewrite_session( li->targets[ target ]->rwmap.rwm_rw,
-							"searchResult",
-							bv->bv_val,
-							lc->conn, &newval )) {
-				case REWRITE_REGEXEC_OK:
-					/* left as is */
-					if ( newval == NULL ) {
-						break;
-					}
-#ifdef NEW_LOGGING
-					LDAP_LOG( BACK_META, DETAIL1,
-						"[rw] searchResult on attr=%s: \"%s\" -> \"%s\"\n",
-						attr->a_desc->ad_type->sat_cname.bv_val,
-						bv->bv_val, newval );
-#else /* !NEW_LOGGING */
-					Debug( LDAP_DEBUG_ARGS,
-						"rw> searchResult on attr=%s:"
-						" \"%s\" -> \"%s\"\n",
-					attr->a_desc->ad_type->sat_cname.bv_val,
-						bv->bv_val, newval );
-#endif /* !NEW_LOGGING */
-					free( bv->bv_val );
-					bv->bv_val = newval;
-					bv->bv_len = strlen( newval );
-
-					break;
-
-				case REWRITE_REGEXEC_UNWILLING:
-					LBER_FREE(bv->bv_val);
-					bv->bv_val = NULL;
-					if (--last < 0)
-						goto next_attr;
-					*bv = attr->a_vals[last];
-					attr->a_vals[last].bv_val = NULL;
-					bv--;
-					break;
-
-				case REWRITE_REGEXEC_ERR:
-					/*
-					 * FIXME: better give up,
-					 * skip the attribute
-					 * or leave it untouched?
-					 */
-					break;
-				}
-			}
+		} else if ( attr->a_desc->ad_type->sat_syntax ==
+				slap_schema.si_syn_distinguishedName ) {
+			ldap_dnattr_result_rewrite( &dc, attr->a_vals );
 		}
 next_attr:;
 
-- 
GitLab