]> git.sur5r.net Git - openldap/commitdiff
add "searchFilterAttrDN" rewrite context, and allow filterstring rewrite
authorPierangelo Masarati <ando@openldap.org>
Wed, 10 Mar 2004 21:11:14 +0000 (21:11 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 10 Mar 2004 21:11:14 +0000 (21:11 +0000)
21 files changed:
doc/man/man5/slapd-meta.5
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/delete.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/map.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldap/suffixmassage.c
servers/slapd/back-meta/add.c
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/data/setup.sh
servers/slapd/back-meta/delete.c
servers/slapd/back-meta/modify.c
servers/slapd/back-meta/search.c

index 4f37eef4a56b6b667eac4e68f2e237acfdcbc812..a7e3228df637dd45ec3af1429183b898372644ba 100644 (file)
@@ -513,20 +513,22 @@ client -> server:
 .LP
 .RS
 .nf
-(default)      if defined and no specific context 
-               is available
-bindDN         bind
-searchBase     search
-searchFilter   search
-compareDN      compare
-compareAttrDN  compare AVA
-addDN          add
-addAttrDN      add AVA
-modifyDN       modify
-modifyAttrDN   modify AVA
-modrDN         modrdn
-newSuperiorDN  modrdn
-deleteDN       delete
+(default)            if defined and no specific context 
+                     is available
+bindDN               bind
+searchBase           search
+searchFilter         search
+searchFilterAttrDN   search
+compareDN            compare
+compareAttrDN        compare AVA
+addDN                add
+addAttrDN            add AVA
+modifyDN             modify
+modifyAttrDN         modify AVA
+modrDN               modrdn
+newSuperiorDN        modrdn
+deleteDN             delete
+exopPasswdDN         passwd exop DN if proxy
 .fi
 .RE
 .LP
@@ -534,11 +536,11 @@ server -> client:
 .LP
 .RS
 .nf
-searchResult   search (only if defined; no default;
-               acts on DN and DN-syntax attributes 
-               of search results)
-searchAttrDN   search AVA
-matchedDN      all ops (only if applicable)
+searchResult         search (only if defined; no default;
+                     acts on DN and DN-syntax attributes 
+                     of search results)
+searchAttrDN         search AVA
+matchedDN            all ops (only if applicable)
 .fi
 .RE
 .LP
@@ -627,10 +629,10 @@ rewriteRule     ".*" "%{>addBlanks(%0)}" ":"
 .\" 
 .\" # Finally, in a bind, if one uses a `uid=username' DN,
 .\" # it is rewritten in `cn=name surname' if possible.
-.\" rewriteContext  bindDn
+.\" rewriteContext  bindDN
 .\" rewriteRule     ".*" "%{>addBlanks(%{>uid2Gecos(%0)})}" ":"
 .\" 
-# Rewrite the search base  according to `default' rules.
+# Rewrite the search base according to `default' rules.
 rewriteContext  searchBase alias default
 
 # Search results with OpenLDAP DN are rewritten back with
@@ -652,7 +654,7 @@ rewriteMap ldap attr2dn "ldap://host/dc=my,dc=org?dn?sub"
 # to real naming contexts, we also need to rewrite
 # regular DNs, because the definition of a bindDn
 # rewrite context overrides the default definition.
-rewriteContext bindDn
+rewriteContext bindDN
 rewriteRule "^mail=[^,]+@[^,]+$" "%{attr2dn(%0)}" ":@I"
 
 # This is a rather sophisticated example. It massages a
@@ -661,7 +663,7 @@ rewriteRule "^mail=[^,]+@[^,]+$" "%{attr2dn(%0)}" ":@I"
 # track of the bind DN of the incoming request, which is
 # stored in a variable called `binddn' with session scope,
 # and left in place to allow regular binding:
-rewriteContext  bindDn
+rewriteContext  bindDN
 rewriteRule     ".+" "%{&&binddn(%0)}%0" ":"
 
 # A search filter containing `uid=' is rewritten only
index adf80638185f9d177f7e89177f9877160324cd27..a6d3d1fa3aec04bcc96b89f45ad9870898267b88 100644 (file)
@@ -69,7 +69,7 @@ ldap_back_add(
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "addDn";
+       dc.ctx = "addDN";
 #else
        dc.tofrom = 1;
        dc.normalized = 0;
@@ -87,7 +87,7 @@ ldap_back_add(
        attrs = (LDAPMod **)ch_malloc(sizeof(LDAPMod *)*i);
 
 #ifdef ENABLE_REWRITE
-       dc.ctx = "addDnAttr";
+       dc.ctx = "addAttrDN";
 #endif
 
        isupdate = be_isupdate( op->o_bd, &op->o_ndn );
index cfecc0362f26c71747460936b1696b54065b7c02..29bc8b24ab2c511f017d13642ad122b37c846efc 100644 (file)
@@ -62,7 +62,7 @@ ldap_back_bind(
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "bindDn";
+       dc.ctx = "bindDN";
 #else
        dc.tofrom = 1;
        dc.normalized = 0;
@@ -303,7 +303,7 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
 #ifdef ENABLE_REWRITE
                                dc.conn = op->o_conn;
                                dc.rs = rs;
-                               dc.ctx = "bindDn";
+                               dc.ctx = "bindDN";
 #else
                                dc.tofrom = 1;
                                dc.normalized = 0;
@@ -532,7 +532,7 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
 #ifdef ENABLE_REWRITE
                        dc.conn = op->o_conn;
                        dc.rs = rs;
-                       dc.ctx = "matchedDn";
+                       dc.ctx = "matchedDN";
 #else
                        dc.tofrom = 0;
                        dc.normalized = 0;
index 3bed65a348d190458f09891434a491ee2eeaae9e..8af11742f5d3ccdb5642964ccc4953ab0761376a 100644 (file)
@@ -60,7 +60,7 @@ ldap_back_compare(
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "compareDn";
+       dc.ctx = "compareDN";
 #else
        dc.tofrom = 1;
        dc.normalized = 0;
index ab35c0cb5d257ccd58bf67e0b1bc3fb81b488530..5baef7722d7a1b77bbeb7730d1fb2929af90f900 100644 (file)
@@ -586,96 +586,9 @@ suffix_massage_config(
        ch_free( rargv[ 1 ] );
        ch_free( rargv[ 2 ] );
 
-#if 0
-       /*
-        * FIXME: this is no longer required since now we map filters
-        * based on the parsed filter structure, so we can deal directly
-        * with attribute types and values.  The rewriteContext 
-        * "searchFilter" now refers to the value of attrbutes
-        * with DN syntax.
-        */
-
-       /*
-        * the filter should be rewritten as
-        * 
-        * rewriteRule
-        *      "(.*)member=([^)]+),o=Foo Bar,[ ]?c=US(.*)"
-        *      "%1member=%2,dc=example,dc=com%3"
-        *
-        * where "o=Foo Bar, c=US" is the virtual naming context,
-        * and "dc=example, dc=com" is the real naming context
-        */
-       rargv[ 0 ] = "rewriteContext";
-       rargv[ 1 ] = "searchFilter";
-       rargv[ 2 ] = NULL;
-       rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
-
-#if 1 /* rewrite filters */
-       {
-               /*
-                * Note: this is far more optimistic than desirable:
-                * for any AVA value ending with the virtual naming
-                * context the terminal part will be replaced by the
-                * real naming context; a better solution would be to
-                * walk the filter looking for DN-valued attributes,
-                * and only rewrite those that require rewriting
-                */
-               char    vbuf_[BUFSIZ], *vbuf = vbuf_,
-                       rbuf_[BUFSIZ], *rbuf = rbuf_;
-               int     len;
-
-               len = snprintf( vbuf, sizeof( vbuf_ ), 
-                               "(.*)%s\\)(.*)", nvnc->bv_val );
-               if ( len == -1 ) {
-                       /* 
-                        * traditional behavior: snprintf returns -1 
-                        * if buffer is insufficient
-                        */
-                       return -1;
-
-               } else if ( len >= (int)sizeof( vbuf_ ) ) {
-                       /* 
-                        * C99: snprintf returns the required size 
-                        */
-                       vbuf = ch_malloc( len + 1 );
-                       len = snprintf( vbuf, len,
-                                       "(.*)%s\\)(.*)", nvnc->bv_val );
-                       assert( len > 0 );
-               }
-
-               len = snprintf( rbuf, sizeof( rbuf_ ), "%%1%s)%%2", 
-                               nrnc->bv_val );
-               if ( len == -1 ) {
-                       return -1;
-
-               } else if ( len >= (int)sizeof( rbuf_ ) ) {
-                       rbuf = ch_malloc( len + 1 );
-                       len = snprintf( rbuf, sizeof( rbuf_ ), "%%1%s)%%2", 
-                                       nrnc->bv_val );
-                       assert( len > 0 );
-               }
-               
-               rargv[ 0 ] = "rewriteRule";
-               rargv[ 1 ] = vbuf;
-               rargv[ 2 ] = rbuf;
-               rargv[ 3 ] = ":";
-               rargv[ 4 ] = NULL;
-               rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
-
-               if ( vbuf != vbuf_ ) {
-                       ch_free( vbuf );
-               }
-
-               if ( rbuf != rbuf_ ) {
-                       ch_free( rbuf );
-               }
-       }
-#endif /* rewrite filters */
-#endif
-
 #if 0 /*  "matched" is not normalized */
        rargv[ 0 ] = "rewriteContext";
-       rargv[ 1 ] = "matchedDn";
+       rargv[ 1 ] = "matchedDN";
        rargv[ 2 ] = "alias";
        rargv[ 3 ] = "searchResult";
        rargv[ 4 ] = NULL;
index 0027f573844578978393072a11ef664f3036243d..91a7b53f2c5ae92a74babad98640991c562b8801 100644 (file)
@@ -60,7 +60,7 @@ ldap_back_delete(
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "deleteDn";
+       dc.ctx = "deleteDN";
 #else
        dc.tofrom = 1;
        dc.normalized = 0;
index 0223a0cebb46e66954f9df1bdf31a99a030a6ce2..4403fbaaf51dcc831385f385148284100b083002 100644 (file)
@@ -117,12 +117,12 @@ ldap_back_exop_passwd(
                op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 );
 #endif
 
-       if (isproxy) {
+       if ( isproxy ) {
                dc.rwmap = &li->rwmap;
 #ifdef ENABLE_REWRITE
                dc.conn = op->o_conn;
                dc.rs = rs;
-               dc.ctx = "modifyPwd";
+               dc.ctx = "exopPasswdDN";
 #else
                dc.tofrom = 1;
                dc.normalized = 0;
index a36c77cfe62eebacb995c80a6652a9180d533450..2cbf10a99835f803eba2b2ec261a101d20550fed 100644 (file)
@@ -118,6 +118,21 @@ ldap_back_db_init(
                ch_free( li );
                return -1;
        }
+
+       {
+               char    *rargv[3];
+
+               /*
+                * the filter rewrite as a string must be disabled
+                * by default; it can be re-enabled by adding rules;
+                * this creates an empty rewriteContext
+                */
+               rargv[ 0 ] = "rewriteContext";
+               rargv[ 1 ] = "searchFilter";
+               rargv[ 2 ] = NULL;
+               rewrite_parse( li->rwmap.rwm_rw, "<suffix massage>", 
+                               1, 2, rargv );
+       }
 #endif /* ENABLE_REWRITE */
 
        ldap_pvt_thread_mutex_init( &li->conn_mutex );
index 3f38ce6b4b698d71522603572ae9aa416da5c97b..1d91a21bbab9d407490c5f08b30e5cbda3564199 100644 (file)
@@ -180,7 +180,7 @@ map_attr_value(
                dncookie fdc = *dc;
 
 #ifdef ENABLE_REWRITE
-               fdc.ctx = "searchFilter";
+               fdc.ctx = "searchFilterAttrDN";
 #endif
 
                switch ( ldap_back_dn_massage( &fdc, value, &vtmp ) ) {
@@ -214,8 +214,8 @@ map_attr_value(
        return LDAP_SUCCESS;
 }
 
-int
-ldap_back_filter_map_rewrite(
+static int
+ldap_int_back_filter_map_rewrite(
                dncookie                *dc,
                Filter                  *f,
                struct berval           *fstr,
@@ -390,7 +390,7 @@ ldap_back_filter_map_rewrite(
                for ( p = f->f_list; p != NULL; p = p->f_next ) {
                        len = fstr->bv_len;
 
-                       rc = ldap_back_filter_map_rewrite( dc, p, &vtmp, remap );
+                       rc = ldap_int_back_filter_map_rewrite( dc, p, &vtmp, remap );
                        if ( rc != LDAP_SUCCESS ) {
                                return rc;
                        }
@@ -458,6 +458,73 @@ ldap_back_filter_map_rewrite(
        return LDAP_SUCCESS;
 }
 
+int
+ldap_back_filter_map_rewrite(
+               dncookie                *dc,
+               Filter                  *f,
+               struct berval           *fstr,
+               int                     remap )
+{
+       int             rc;
+       dncookie        fdc;
+       struct berval   ftmp;
+
+       rc = ldap_int_back_filter_map_rewrite( dc, f, fstr, remap );
+
+#ifdef ENABLE_REWRITE
+       if ( rc != LDAP_SUCCESS ) {
+               return rc;
+       }
+
+       fdc = *dc;
+       ftmp = *fstr;
+
+       fdc.ctx = "searchFilter";
+
+       switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx, 
+                               ( ftmp.bv_len ? ftmp.bv_val : "" ), 
+                               fdc.conn, &fstr->bv_val )) {
+       case REWRITE_REGEXEC_OK:
+               if ( fstr->bv_val != NULL ) {
+                       fstr->bv_len = strlen( fstr->bv_val );
+                       free( ftmp.bv_val );
+               } else {
+                       *fstr = ftmp;
+               }
+
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_LDAP, DETAIL1, 
+                       "[rw] %s: \"%s\" -> \"%s\"\n",
+                       dc->ctx, ftmp.bv_val, fstr->bv_val );           
+#else /* !NEW_LOGGING */
+               Debug( LDAP_DEBUG_ARGS,
+                       "[rw] %s: \"%s\" -> \"%s\"\n",
+                       dc->ctx, ftmp.bv_val, fstr->bv_val );           
+#endif /* !NEW_LOGGING */
+               rc = LDAP_SUCCESS;
+               break;
+               
+       case REWRITE_REGEXEC_UNWILLING:
+               if ( fdc.rs ) {
+                       fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+                       fdc.rs->sr_text = "Operation not allowed";
+               }
+               rc = LDAP_UNWILLING_TO_PERFORM;
+               break;
+               
+       case REWRITE_REGEXEC_ERR:
+               if ( fdc.rs ) {
+                       fdc.rs->sr_err = LDAP_OTHER;
+                       fdc.rs->sr_text = "Rewrite error";
+               }
+               rc = LDAP_OTHER;
+               break;
+       }
+
+#endif /* ENABLE_REWRITE */
+       return rc;
+}
+
 /*
  * I don't like this much, but we need two different
  * functions because different heap managers may be
index 541e41047da6726081328bef19218f6fdac4813d..6da70a1536c77668915115435a7756a7b1a57e65 100644 (file)
@@ -63,7 +63,7 @@ ldap_back_modify(
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "modifyDn";
+       dc.ctx = "modifyDN";
 #else
        dc.tofrom = 1;
        dc.normalized = 0;
index 13ab0ba7b028ce125b1e4e83177e680dfc1888ee..a479131c86034cdca21a9890a27bfd22070b3e90 100644 (file)
@@ -68,7 +68,7 @@ ldap_back_modrdn(
                 * Rewrite the new superior, if defined and required
                 */
 #ifdef ENABLE_REWRITE
-               dc.ctx = "newSuperiorDn";
+               dc.ctx = "newSuperiorDN";
 #endif
                if ( ldap_back_dn_massage( &dc, op->orr_newSup,
                        &mnewSuperior ) ) {
@@ -81,7 +81,7 @@ ldap_back_modrdn(
         * Rewrite the modrdn dn, if required
         */
 #ifdef ENABLE_REWRITE
-       dc.ctx = "modrDn";
+       dc.ctx = "modrDN";
 #endif
        if ( ldap_back_dn_massage( &dc, &op->o_req_ndn, &mdn ) ) {
                send_ldap_result( op, rs );
index d3b45d6532d105cc65927e0177a57737b19788fa..986e4c5c7064ba6ad32493945458a76de22a939f 100644 (file)
@@ -275,7 +275,7 @@ fail:;
                struct berval mdn;
 
 #ifdef ENABLE_REWRITE
-               dc.ctx = "matchedDn";
+               dc.ctx = "matchedDN";
 #else
                dc.tofrom = 0;
                dc.normalized = 0;
index 2cee6844516cddb1541d74be2ee36511328276bb..2ad3bafdf8a05fa50baa1d77b46f811596e4db75 100644 (file)
@@ -42,8 +42,11 @@ ldap_back_dn_massage(
 {
        int rc = 0;
 
-       switch (rewrite_session( dc->rwmap->rwm_rw, dc->ctx, (dn->bv_len ? dn->bv_val : ""), dc->conn, 
-                               &res->bv_val )) {
+       rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
+                       ( dn->bv_len ? dn->bv_val : "" ), dc->conn,
+                       &res->bv_val );
+
+       switch ( rc ) {
        case REWRITE_REGEXEC_OK:
                if ( res->bv_val != NULL ) {
                        res->bv_len = strlen( res->bv_val );
@@ -52,10 +55,12 @@ ldap_back_dn_massage(
                }
 #ifdef NEW_LOGGING
                LDAP_LOG( BACK_LDAP, DETAIL1, 
-                       "[rw] %s: \"%s\" -> \"%s\"\n", dc->ctx, dn->bv_val, res->bv_val );              
+                       "[rw] %s: \"%s\" -> \"%s\"\n",
+                       dc->ctx, dn->bv_val, res->bv_val );             
 #else /* !NEW_LOGGING */
                Debug( LDAP_DEBUG_ARGS,
-                       "[rw] %s: \"%s\" -> \"%s\"\n", dc->ctx, dn->bv_val, res->bv_val );              
+                       "[rw] %s: \"%s\" -> \"%s\"\n",
+                       dc->ctx, dn->bv_val, res->bv_val );             
 #endif /* !NEW_LOGGING */
                rc = LDAP_SUCCESS;
                break;
index fa959ce8b24cc4e21dcf5e3fc32a9555bc6dfa1d..a65a38081212ac6d18f2cd71c96d01abe9dcee44 100644 (file)
@@ -73,7 +73,7 @@ meta_back_add( Operation *op, SlapReply *rs )
        dc.rwmap = &li->targets[ candidate ]->rwmap;
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "addDn";
+       dc.ctx = "addDN";
 
        if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                send_ldap_result( op, rs );
index 3eb5f0db6c5007ad69446be291526f7791d1c385..25430df987f7a5cfddeb8543b78715c97c65abf9 100644 (file)
@@ -203,7 +203,7 @@ meta_back_do_single_bind(
        dc.rwmap = &li->targets[ candidate ]->rwmap;
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "bindDn";
+       dc.ctx = "bindDN";
 
        if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                send_ldap_result( op, rs );
index 3e0d8fd5d53c523ee30a3214ebccd68ea7f13fde..4f0d06548f7d9ee3e28280817c0f5a4d6dd35905 100644 (file)
@@ -67,7 +67,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
         */
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "compareDn";
+       dc.ctx = "compareDN";
 
        for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
                struct berval mdn = { 0, NULL };
@@ -254,7 +254,7 @@ finish:;
                matched.bv_val = match;
                matched.bv_len = strlen( match );
 
-               dc.ctx = "matchedDn";
+               dc.ctx = "matchedDN";
                ldap_back_dn_massage( &dc, &matched, &mmatch );
        }
 
index 8af403d2ab539491b60e8e5e8388c028f0c85704..0d3a4839ea23f001c0cc6d2df4dfc4de8476e9f0 100644 (file)
@@ -243,7 +243,7 @@ init_one_conn(
                dc.rwmap = &lt->rwmap;
                dc.conn = op->o_conn;
                dc.rs = rs;
-               dc.ctx = "bindDn";
+               dc.ctx = "bindDN";
                
                /*
                 * Rewrite the bind dn if needed
index 178644a55cbb3495cdd9fd12b6dd259b420a209c..1bb507cfc3a9497536efec6fac69e3cc4ceb8528 100644 (file)
@@ -46,7 +46,7 @@ $SRCDIR/servers/slapd/slapd -f $CONF -h "ldap://:$PORT/" -d $DEBUG
 echo "Waiting 2 secs for everything to shut down ..."
 sleep 2
 
-#exit
+exit
 
 rm -rf $METADBDIR
 rm -f schema ucdata $CONF $LDAPCONF
index dd28e40279e5a8b2b86d0d0044de2f1fa3749fdf..c3c8ea8f5ff02f42d6e68521843b68b4ec743a9d 100644 (file)
@@ -60,7 +60,7 @@ meta_back_delete( Operation *op, SlapReply *rs )
        dc.rwmap = &li->targets[ candidate ]->rwmap;
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "deleteDn";
+       dc.ctx = "deleteDN";
 
        if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                send_ldap_result( op, rs );
index d00c0f5e17312d411acedfa077aa20f3e3fc452d..c44a1f214cc036faa5800d9877647970e6688015 100644 (file)
@@ -65,7 +65,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
        dc.rwmap = &li->targets[ candidate ]->rwmap;
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "modifyDn";
+       dc.ctx = "modifyDN";
 
        if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                rc = -1;
index d6c2798dc57c22d7d07da6f563fdcfa4cdb6a3b5..ecb5fcdafb44c6d17562d92297fba2bbd07e18e5 100644 (file)
@@ -495,7 +495,7 @@ new_candidate:;
         */
        if ( candidate_match == initial_candidates
                        && match.bv_val != NULL && *match.bv_val ) {
-               dc.ctx = "matchedDn";
+               dc.ctx = "matchedDN";
                dc.rwmap = &li->targets[ last ]->rwmap;
 
                if ( ldap_back_dn_massage( &dc, &match, &mmatch ) ) {