]> git.sur5r.net Git - openldap/commitdiff
improved filter mapping/rewrite; improved result rewriting; improved attribute/object...
authorPierangelo Masarati <ando@openldap.org>
Sat, 1 Mar 2003 11:08:53 +0000 (11:08 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 1 Mar 2003 11:08:53 +0000 (11:08 +0000)
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/map.c
servers/slapd/back-ldap/search.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/search.c
servers/slapd/filter.c
servers/slapd/proto-slap.h

index 921d7be53e87e935e51942e758c66893d1822b29..ffe616e24b564c3111efc854fde66193c14c7487 100644 (file)
@@ -106,6 +106,7 @@ extern int ldap_back_conn_cmp( const void *c1, const void *c2);
 extern int ldap_back_conn_dup( void *c1, void *c2 );
 extern void ldap_back_conn_free( void *c );
 
+/* attributeType/objectClass mapping */
 int mapping_cmp (const void *, const void *);
 int mapping_dup (void *, void *);
 
@@ -130,6 +131,27 @@ ldap_back_map_attrs(
 
 extern void mapping_free ( void *mapping );
 
+extern int ldap_back_map_config(
+               struct ldapmap  *oc_map,
+               struct ldapmap  *at_map,
+               const char      *fname,
+               int             lineno,
+               int             argc,
+               char            **argv );
+
+extern int
+ldap_back_filter_map_rewrite_(
+#ifdef ENABLE_REWRITE
+               struct rewrite_info     *info,
+               void                    *cookie,
+#endif /* ENABLE_REWRITE */
+               struct ldapmap          *at_map,
+               struct ldapmap          *oc_map,
+               Filter                  *f,
+               struct berval           *fstr,
+               int                     remap );
+
+/* suffix massaging by means of librewrite */
 #ifdef ENABLE_REWRITE
 extern int suffix_massage_config( struct rewrite_info *info,
                struct berval *pvnc, struct berval *nvnc,
index 8dbed1b1aa5f8b69ce132276b42b358ac43da320..bba917a4cc94558bc0a7f18616c7975718343b96 100644 (file)
@@ -239,88 +239,172 @@ ldap_back_db_config(
                
        /* objectclass/attribute mapping */
        } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
-               struct ldapmap *map;
-               struct ldapmapping *mapping;
-               char *src, *dst;
+               return ldap_back_map_config( &li->oc_map, &li->at_map,
+                               fname, lineno, argc, argv );
 
-               if ( argc < 3 || argc > 4 ) {
-                       fprintf( stderr,
+       /* anything else */
+       } else {
+               fprintf( stderr, "%s: line %d: unknown directive \"%s\" "
+                       "in ldap database definition (ignored)\n",
+                   fname, lineno, argv[0] );
+       }
+       return 0;
+}
+
+int
+ldap_back_map_config(
+               struct ldapmap  *oc_map,
+               struct ldapmap  *at_map,
+               const char      *fname,
+               int             lineno,
+               int             argc,
+               char            **argv )
+{
+       struct ldapmap          *map;
+       struct ldapmapping      *mapping;
+       char                    *src, *dst;
+       int                     is_oc = 0;
+
+       if ( argc < 3 || argc > 4 ) {
+               fprintf( stderr,
        "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
-                               fname, lineno );
-                       return( 1 );
-               }
+                       fname, lineno );
+               return 1;
+       }
 
-               if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
-                       map = &li->oc_map;
-               } else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
-                       map = &li->at_map;
-               } else {
-                       fprintf( stderr, "%s: line %d: syntax is "
-                               "\"map {objectclass | attribute} [<local> | *] "
-                               "{<foreign> | *}\"\n",
-                               fname, lineno );
-                       return( 1 );
+       if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
+               map = oc_map;
+               is_oc = 1;
+
+       } else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
+               map = at_map;
+
+       } else {
+               fprintf( stderr, "%s: line %d: syntax is "
+                       "\"map {objectclass | attribute} [<local> | *] "
+                       "{<foreign> | *}\"\n",
+                       fname, lineno );
+               return 1;
+       }
+
+       if ( strcmp( argv[2], "*" ) == 0 ) {
+               if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) {
+                       map->drop_missing = ( argc < 4 );
+                       return 0;
                }
+               src = dst = argv[3];
+
+       } else if ( argc < 4 ) {
+               src = "";
+               dst = argv[2];
+
+       } else {
+               src = argv[2];
+               dst = ( strcmp( argv[3], "*" ) == 0 ? src : argv[3] );
+       }
+
+       if ( ( map == at_map )
+                       && ( strcasecmp( src, "objectclass" ) == 0
+                       || strcasecmp( dst, "objectclass" ) == 0 ) )
+       {
+               fprintf( stderr,
+                       "%s: line %d: objectclass attribute cannot be mapped\n",
+                       fname, lineno );
+       }
 
-               if ( strcmp( argv[2], "*" ) == 0 ) {
-                       if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) {
-                               map->drop_missing = ( argc < 4 );
-                               return 0;
+       mapping = (struct ldapmapping *)ch_calloc( 2,
+               sizeof(struct ldapmapping) );
+       if ( mapping == NULL ) {
+               fprintf( stderr,
+                       "%s: line %d: out of memory\n",
+                       fname, lineno );
+               return 1;
+       }
+       ber_str2bv( src, 0, 1, &mapping->src );
+       ber_str2bv( dst, 0, 1, &mapping->dst );
+       mapping[1].src = mapping->dst;
+       mapping[1].dst = mapping->src;
+
+       /*
+        * schema check
+        */
+       if ( is_oc ) {
+               if ( src[0] != '\0' ) {
+                       if ( oc_bvfind( &mapping->src ) == NULL ) {
+                               fprintf( stderr,
+       "%s: line %d: warning, source objectClass '%s' "
+       "should be defined in schema\n",
+                                       fname, lineno, src );
+
+                               /*
+                                * FIXME: this should become an err
+                                */
                        }
-                       src = dst = argv[3];
-               } else if ( argc < 4 ) {
-                       src = "";
-                       dst = argv[2];
-               } else {
-                       src = argv[2];
-                       dst = ( strcmp( argv[3], "*" ) == 0 ? src : argv[3] );
                }
 
-               if ( ( map == &li->at_map )
-                       && ( strcasecmp( src, "objectclass" ) == 0
-                               || strcasecmp( dst, "objectclass" ) == 0 ) )
-               {
+               if ( oc_bvfind( &mapping->dst ) == NULL ) {
                        fprintf( stderr,
-                               "%s: line %d: objectclass attribute cannot be mapped\n",
-                               fname, lineno );
+       "%s: line %d: warning, destination objectClass '%s' "
+       "is not defined in schema\n",
+                               fname, lineno, dst );
                }
+       } else {
+               int                     rc;
+               const char              *text = NULL;
+               AttributeDescription    *ad = NULL;
+
+               if ( src[0] != '\0' ) {
+                       rc = slap_bv2ad( &mapping->src, &ad, &text );
+                       if ( rc != LDAP_SUCCESS ) {
+                               fprintf( stderr,
+       "%s: line %d: warning, source attributeType '%s' "
+       "should be defined in schema\n",
+                                       fname, lineno, src );
+
+                               /*
+                                * FIXME: this should become an err
+                                */
+                       }
 
-               mapping = (struct ldapmapping *)ch_calloc( 2,
-                       sizeof(struct ldapmapping) );
-               if ( mapping == NULL ) {
-                       fprintf( stderr,
-                               "%s: line %d: out of memory\n",
-                               fname, lineno );
-                       return( 1 );
+                       ad = NULL;
                }
-               ber_str2bv( src, 0, 1, &mapping->src );
-               ber_str2bv( dst, 0, 1, &mapping->dst );
-               mapping[1].src = mapping->dst;
-               mapping[1].dst = mapping->src;
-
-               if ( (*src != '\0' &&
-                         avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL) ||
-                       avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
-               {
+
+               rc = slap_bv2ad( &mapping->dst, &ad, &text );
+               if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr,
-                               "%s: line %d: duplicate mapping found (ignored)\n",
-                               fname, lineno );
-                       return 0;
+       "%s: line %d: warning, destination attributeType '%s' "
+       "is not defined in schema\n",
+                               fname, lineno, dst );
                }
+       }
 
-               if ( *src != '\0' )
-                       avl_insert( &map->map, (caddr_t)mapping,
-                                               mapping_cmp, mapping_dup );
-               avl_insert( &map->remap, (caddr_t)&mapping[1],
-                                       mapping_cmp, mapping_dup );
+       if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
+                       || avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
+       {
+               fprintf( stderr,
+                       "%s: line %d: duplicate mapping found (ignored)\n",
+                       fname, lineno );
+               /* FIXME: free stuff */
+               goto error_return;
+       }
 
-       /* anything else */
-       } else {
-               fprintf( stderr, "%s: line %d: unknown directive \"%s\" "
-                       "in ldap database definition (ignored)\n",
-                   fname, lineno, argv[0] );
+       if ( src[0] != '\0' ) {
+               avl_insert( &map->map, (caddr_t)mapping,
+                                       mapping_cmp, mapping_dup );
        }
+       avl_insert( &map->remap, (caddr_t)&mapping[1],
+                               mapping_cmp, mapping_dup );
+
        return 0;
+
+error_return:;
+       if ( mapping ) {
+               ch_free( mapping->src.bv_val );
+               ch_free( mapping->dst.bv_val );
+               ch_free( mapping );
+       }
+
+       return 1;
 }
 
 static int
@@ -504,6 +588,15 @@ 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
         * 
@@ -580,6 +673,7 @@ suffix_massage_config(
                }
        }
 #endif /* rewrite filters */
+#endif
 
 #if 0 /*  "matched" is not normalized */
        rargv[ 0 ] = "rewriteContext";
index 9a5fb497da48dbe9b5eb77b12904c13795e3a4af..ff7a48b71dab81a76128d334d15eb302fd1d0f40 100644 (file)
@@ -175,6 +175,10 @@ ldap_back_map_filter(
                                tmp.bv_val = q;
                                ldap_back_map(at_map, &tmp, &m, remap);
                                if (m.bv_val == NULL || m.bv_val[0] == '\0') {
+                                       /*
+                                        * FIXME: are we sure we need to search 
+                                        * oc_map if at_map fails?
+                                        */
                                        ldap_back_map(oc_map, &tmp, &m, remap);
                                        if (m.bv_val == NULL || m.bv_val[0] == '\0') {
                                                m = tmp;
@@ -244,3 +248,392 @@ ldap_back_map_attrs(
        return(na);
 }
 
+#ifdef ENABLE_REWRITE
+
+static int
+map_attr_value_(
+               struct rewrite_info     *info,
+               void                    *cookie,
+               struct ldapmap          *at_map,
+               struct ldapmap          *oc_map,
+               AttributeDescription    *ad,
+               struct berval           *mapped_attr,
+               struct berval           *value,
+               struct berval           *mapped_value,
+               int                     remap )
+{
+       struct berval           vtmp;
+       int                     freeval = 0;
+
+       ldap_back_map( at_map, &ad->ad_cname, mapped_attr, remap );
+       if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0') {
+               /*
+                * FIXME: are we sure we need to search oc_map if at_map fails?
+                */
+               ldap_back_map( oc_map, &ad->ad_cname, mapped_attr, remap );
+               if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0' ) {
+                       *mapped_attr = ad->ad_cname;
+               }
+       }
+
+       if ( value == NULL ) {
+               return 0;
+       }
+
+       if ( strcmp( ad->ad_type->sat_syntax->ssyn_oid, SLAPD_DN_SYNTAX ) == 0 )
+       {
+               switch ( rewrite_session( info, "searchFilter",
+                                       value->bv_val, cookie, &vtmp.bv_val ) ) {
+               case REWRITE_REGEXEC_OK:
+                       if ( vtmp.bv_val == NULL ) {
+                               vtmp = *value;
+                       } else {
+                               vtmp.bv_len = strlen( vtmp.bv_val );
+                               freeval = 1;
+                       }
+#ifdef NEW_LOGGING
+                       LDAP_LOG( BACK_LDAP, DETAIL1, 
+                               "[rw] searchFilter: \"%s\" -> \"%s\"\n", 
+                               value->bv_val, vtmp.bv_val, 0 );
+#else /* !NEW_LOGGING */
+                       Debug( LDAP_DEBUG_ARGS, "rw> searchFilter: \"%s\" -> \"%s\"\n%s",
+                                       value->bv_val, vtmp.bv_val, "" );
+#endif /* !NEW_LOGGING */
+                       break;
+
+               
+               case REWRITE_REGEXEC_UNWILLING:
+                       return -1;
+
+               case REWRITE_REGEXEC_ERR:
+                       return -1;
+               }
+
+       } else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) {
+               ldap_back_map( oc_map, value, &vtmp, remap );
+               if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) {
+                       vtmp = *value;
+               }
+               
+       } else {
+               vtmp = *value;
+       }
+
+       filter_escape_value( &vtmp, mapped_value );
+
+       if ( freeval ) {
+               ber_memfree( vtmp.bv_val );
+       }
+       
+       return 0;
+}
+
+#define map_attr_value(at_map, oc_map, ad, mapped_attr, value, mapped_value, remap) \
+       map_attr_value_(info, cookie, (at_map), (oc_map), (ad), (mapped_attr), (value), (mapped_value), (remap))
+#define ldap_back_filter_map_rewrite(at_map, oc_map, f, fstr, remap) \
+       ldap_back_filter_map_rewrite_(info, cookie, (at_map), (oc_map), (f), (fstr), (remap))
+
+#else /* ! ENABLE_REWRITE */
+
+static int
+map_attr_value_(
+               struct ldapmap          *at_map,
+               struct ldapmap          *oc_map,
+               AttributeDescription    *ad,
+               struct berval           *mapped_attr,
+               struct berval           *value,
+               struct berval           *mapped_value,
+               int                     remap )
+{
+       struct berval           vtmp;
+
+       ldap_back_map( at_map, &ad->ad_cname, mapped_attr, remap );
+       if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0') {
+               /*
+                * FIXME: are we sure we need to search oc_map if at_map fails?
+                */
+               ldap_back_map( oc_map, &ad->ad_cname, mapped_attr, remap );
+               if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0' ) {
+                       *mapped_attr = ad->ad_cname;
+               }
+       }
+
+       if ( value == NULL ) {
+               return 0;
+       }
+
+       if ( strcmp( ad->ad_type->sat_syntax->ssyn_oid, SLAPD_DN_SYNTAX ) == 0 )
+       {
+               /* FIXME: use suffix massage capabilities */
+               vtmp = *value;
+
+       } else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) {
+               ldap_back_map( oc_map, value, &vtmp, remap );
+               if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) {
+                       vtmp = *value;
+               }
+               
+       } else {
+               vtmp = *value;
+       }
+
+       filter_escape_value( &vtmp, mapped_value );
+
+       return 0;
+}
+
+#define map_attr_value(at_map, oc_map, ad, mapped_attr, value, mapped_value, remap) \
+       map_attr_value_((at_map), (oc_map), (ad), (mapped_attr), (value), (mapped_value), (remap))
+#define ldap_back_filter_map_rewrite(at_map, oc_map, f, fstr, remap) \
+       ldap_back_filter_map_rewrite_((at_map), (oc_map), (f), (fstr), (remap))
+
+#endif /* ! ENABLE_REWRITE */
+
+int
+ldap_back_filter_map_rewrite_(
+#ifdef ENABLE_REWRITE
+               struct rewrite_info     *info,
+               void                    *cookie,
+#endif /* ENABLE_REWRITE */
+               struct ldapmap          *at_map,
+               struct ldapmap          *oc_map,
+               Filter                  *f,
+               struct berval           *fstr,
+               int                     remap )
+{
+       int             i;
+       Filter          *p;
+       struct berval   atmp;
+       struct berval   vtmp;
+       ber_len_t       len;
+
+       if ( f == NULL ) {
+               ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
+               return -1;
+       }
+
+       switch ( f->f_choice ) {
+       case LDAP_FILTER_EQUALITY:
+               if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
+                                       &f->f_av_value, &vtmp, remap ) )
+               {
+                       return -1;
+               }
+
+               fstr->bv_len = atmp.bv_len + vtmp.bv_len
+                       + ( sizeof("(=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
+                       atmp.bv_val, vtmp.bv_val );
+
+               ber_memfree( vtmp.bv_val );
+               break;
+
+       case LDAP_FILTER_GE:
+               if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
+                               &f->f_av_value, &vtmp, remap ) )
+               {
+                       return -1;
+               }
+
+               fstr->bv_len = atmp.bv_len + vtmp.bv_len
+                       + ( sizeof("(>=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
+                       atmp.bv_val, vtmp.bv_val );
+
+               ber_memfree( vtmp.bv_val );
+               break;
+
+       case LDAP_FILTER_LE:
+               if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
+                                       &f->f_av_value, &vtmp, remap ) )
+               {
+                       return -1;
+               }
+
+               fstr->bv_len = atmp.bv_len + vtmp.bv_len
+                       + ( sizeof("(<=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
+                       atmp.bv_val, vtmp.bv_val );
+
+               ber_memfree( vtmp.bv_val );
+               break;
+
+       case LDAP_FILTER_APPROX:
+               if ( map_attr_value( at_map, oc_map, f->f_av_desc, &atmp,
+                                       &f->f_av_value, &vtmp, remap ) )
+               {
+                       return -1;
+               }
+
+               fstr->bv_len = atmp.bv_len + vtmp.bv_len
+                       + ( sizeof("(~=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
+                       atmp.bv_val, vtmp.bv_val );
+
+               ber_memfree( vtmp.bv_val );
+               break;
+
+       case LDAP_FILTER_SUBSTRINGS:
+               if ( map_attr_value( at_map, oc_map, f->f_sub_desc, &atmp,
+                                       NULL, NULL, remap ) )
+               {
+                       return -1;
+               }
+
+               /* cannot be a DN ... */
+
+               fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 128 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
+                       atmp.bv_val );
+
+               if ( f->f_sub_initial.bv_val != NULL ) {
+                       len = fstr->bv_len;
+
+                       filter_escape_value( &f->f_sub_initial, &vtmp );
+
+                       fstr->bv_len += vtmp.bv_len;
+                       fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
+
+                       snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3,
+                               /* "(attr=" */ "%s*)",
+                               vtmp.bv_val );
+
+                       ber_memfree( vtmp.bv_val );
+               }
+
+               if ( f->f_sub_any != NULL ) {
+                       for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
+                               len = fstr->bv_len;
+                               filter_escape_value( &f->f_sub_any[i], &vtmp );
+
+                               fstr->bv_len += vtmp.bv_len + 1;
+                               fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
+
+                               snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
+                                       /* "(attr=[init]*[any*]" */ "%s*)",
+                                       vtmp.bv_val );
+                               ber_memfree( vtmp.bv_val );
+                       }
+               }
+
+               if ( f->f_sub_final.bv_val != NULL ) {
+                       len = fstr->bv_len;
+
+                       filter_escape_value( &f->f_sub_final, &vtmp );
+
+                       fstr->bv_len += vtmp.bv_len;
+                       fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
+
+                       snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
+                               /* "(attr=[init*][any*]" */ "%s)",
+                               vtmp.bv_val );
+
+                       ber_memfree( vtmp.bv_val );
+               }
+
+               break;
+
+       case LDAP_FILTER_PRESENT:
+               if ( map_attr_value( at_map, oc_map, f->f_desc, &atmp,
+                                       NULL, NULL, remap ) )
+               {
+                       return -1;
+               }
+
+               fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
+                       atmp.bv_val );
+               break;
+
+       case LDAP_FILTER_AND:
+       case LDAP_FILTER_OR:
+       case LDAP_FILTER_NOT:
+               fstr->bv_len = sizeof("(%)") - 1;
+               fstr->bv_val = malloc( fstr->bv_len + 128 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
+                       f->f_choice == LDAP_FILTER_AND ? '&' :
+                       f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
+
+               for ( p = f->f_list; p != NULL; p = p->f_next ) {
+                       len = fstr->bv_len;
+
+                       if ( ldap_back_filter_map_rewrite( at_map, oc_map, p, &vtmp, remap ) )
+                       {
+                               return -1;
+                       }
+                       
+                       fstr->bv_len += vtmp.bv_len;
+                       fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
+
+                       snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2, 
+                               /*"("*/ "%s)", vtmp.bv_val );
+
+                       ch_free( vtmp.bv_val );
+               }
+
+               break;
+
+       case LDAP_FILTER_EXT: {
+               if ( f->f_mr_desc ) {
+                       if ( map_attr_value( at_map, oc_map, f->f_mr_desc, &atmp,
+                                               &f->f_mr_value, &vtmp, remap ) )
+                       {
+                               return -1;
+                       }
+
+               } else {
+                       atmp.bv_len = 0;
+                       atmp.bv_val = "";
+                       
+                       filter_escape_value( &f->f_mr_value, &vtmp );
+               }
+                       
+
+               fstr->bv_len = atmp.bv_len +
+                       ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
+                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
+                       vtmp.bv_len + ( sizeof("(:=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
+                       atmp.bv_val,
+                       f->f_mr_dnattrs ? ":dn" : "",
+                       f->f_mr_rule_text.bv_len ? ":" : "",
+                       f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+                       vtmp.bv_val );
+               ber_memfree( vtmp.bv_val );
+               } break;
+
+       case SLAPD_FILTER_COMPUTED:
+               ber_str2bv(
+                       f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
+                       f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
+                       f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
+                       "(?=error)",
+                       f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
+                       f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
+                       f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
+                       sizeof("(?=error)")-1,
+                       1, fstr );
+               break;
+
+       default:
+               ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
+               break;
+       }
+
+       return 0;
+}
index 404f9e37e2da6cdac5e63f45d9fc8a7983eed3a5..07e0f30a95d1214706e4684f4aad6d403e2026cf 100644 (file)
@@ -74,12 +74,12 @@ ldap_back_search(
        LDAPMessage             *res, *e;
        int     count, rc = 0, msgid, sres = LDAP_SUCCESS; 
        char *match = NULL, *err = NULL;
-       char *mapped_filter = NULL, **mapped_attrs = NULL;
+       char **mapped_attrs = NULL;
        struct berval mbase;
 #ifdef ENABLE_REWRITE
        char *mmatch = NULL;
-       struct berval mfilter = { 0, NULL };
 #endif /* ENABLE_REWRITE */
+       struct berval mfilter = { 0, NULL };
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
        BerVarray v2refs = NULL;
@@ -186,69 +186,24 @@ ldap_back_search(
                rc = -1;
                goto finish;
        }
-       
-       /*
-        * Rewrite the search filter, if required
-        */
-       switch ( rewrite_session( li->rwinfo, "searchFilter",
-                               filterstr->bv_val, conn, &mfilter.bv_val ) ) {
-       case REWRITE_REGEXEC_OK:
-               if ( mfilter.bv_val == NULL || mfilter.bv_val[0] == '\0') {
-                       if ( mfilter.bv_val != NULL ) {
-                               free( mfilter.bv_val );
-                       }
-                       mfilter = *filterstr;
-               } else {
-                       mfilter.bv_len = strlen( mfilter.bv_val );
-               }
 
-#ifdef NEW_LOGGING
-               LDAP_LOG( BACK_LDAP, DETAIL1, 
-                       "[rw] searchFilter: \"%s\" -> \"%s\"\n",
-                       filterstr->bv_val, mfilter.bv_val, 0 );
-#else /* !NEW_LOGGING */
-               Debug( LDAP_DEBUG_ARGS,
-                               "rw> searchFilter: \"%s\" -> \"%s\"\n%s",
-                               filterstr->bv_val, mfilter.bv_val, "" );
-#endif /* !NEW_LOGGING */
-               break;
-               
-       case REWRITE_REGEXEC_UNWILLING:
-               send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
-                               NULL, "Operation not allowed", NULL, NULL );
-               rc = -1;
-               goto finish;
-
-       case REWRITE_REGEXEC_ERR:
-               send_ldap_result( conn, op, LDAP_OTHER,
-                               NULL, "Rewrite error", NULL, NULL );
-               rc = -1;
-               goto finish;
-       }
 #else /* !ENABLE_REWRITE */
        ldap_back_dn_massage( li, base, &mbase, 0, 1 );
 #endif /* !ENABLE_REWRITE */
 
-       mapped_filter = ldap_back_map_filter(&li->at_map, &li->oc_map,
 #ifdef ENABLE_REWRITE
-                       &mfilter,
-#else /* !ENABLE_REWRITE */
-                       filterstr,
-#endif /* !ENABLE_REWRITE */
-                       BACKLDAP_MAP);
-       if ( mapped_filter == NULL ) {
-#ifdef ENABLE_REWRITE
-               mapped_filter = mfilter.bv_val;
-#else /* !ENABLE_REWRITE */
-               mapped_filter = filterstr->bv_val;
-#endif /* !ENABLE_REWRITE */
-       }
-
-#ifdef ENABLE_REWRITE
-       if ( mfilter.bv_val != filterstr->bv_val ) {
-               free( mfilter.bv_val );
+       rc = ldap_back_filter_map_rewrite_( li->rwinfo, conn,
+                       &li->at_map, &li->oc_map, filter, &mfilter, 
+                       BACKLDAP_MAP );
+#else /* ! ENABLE_REWRITE */
+       rc = ldap_back_filter_map_rewrite_( &li->at_map, &li->oc_map, 
+                       filter, &mfilter, BACKLDAP_MAP );
+#endif /* ! ENABLE_REWRITE */
+
+       if ( rc ) {
+               rc = -1;
+               goto finish;
        }
-#endif /* ENABLE_REWRITE */
 
        mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, BACKLDAP_MAP);
        if ( mapped_attrs == NULL && attrs) {
@@ -260,7 +215,7 @@ ldap_back_search(
                mapped_attrs[count] = NULL;
        }
 
-       rc = ldap_search_ext(lc->ld, mbase.bv_val, scope, mapped_filter,
+       rc = ldap_search_ext(lc->ld, mbase.bv_val, scope, mfilter.bv_val,
                        mapped_attrs, attrsonly, op->o_ctrls, NULL, tv.tv_sec ? &tv
                        : NULL, slimit, &msgid);
        if ( rc != LDAP_SUCCESS ) {
@@ -412,8 +367,8 @@ finish:;
        if ( mapped_attrs ) {
                ch_free( mapped_attrs );
        }
-       if ( mapped_filter != filterstr->bv_val ) {
-               ch_free( mapped_filter );
+       if ( mfilter.bv_val != filterstr->bv_val ) {
+               ch_free( mfilter.bv_val );
        }
        if ( mbase.bv_val != base->bv_val ) {
                free( mbase.bv_val );
@@ -533,10 +488,11 @@ ldap_send_entry(
 
                } else if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
-                       int i, last;
+                       int             last;
 
-                       for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
-                       for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
+                       for ( last = 0; attr->a_vals[last].bv_val; last++ );
+
+                       for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
                                ldap_back_map(&li->oc_map, bv, &mapped,
                                                BACKLDAP_REMAP);
                                if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
@@ -546,7 +502,8 @@ ldap_send_entry(
                                                break;
                                        *bv = attr->a_vals[last];
                                        attr->a_vals[last].bv_val = NULL;
-                                       i--;
+                                       bv--;
+
                                } else if ( mapped.bv_val != bv->bv_val ) {
                                        /*
                                         * FIXME: after LBER_FREEing
@@ -571,9 +528,12 @@ ldap_send_entry(
                 */
                } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
                                        SLAPD_DN_SYNTAX ) == 0 ) {
-                       int i;
-                       for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
-                               struct berval newval;
+                       int             last;
+
+                       for ( last = 0; attr->a_vals[last].bv_val; last++ );
+
+                       for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
+                               struct berval   newval;
                                
 #ifdef ENABLE_REWRITE
                                switch ( rewrite_session( li->rwinfo,
@@ -603,7 +563,15 @@ ldap_send_entry(
                                        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,
@@ -619,6 +587,8 @@ ldap_send_entry(
                        }
                }
 
+next_attr:;
+
                *attrp = attr;
                attrp = &attr->a_next;
        }
index e02adc8df63d0ed9df7c672e5ba1605bd109a03c..04fc7d9facfa2f59e236807f5472ea7619600553 100644 (file)
@@ -512,87 +512,11 @@ meta_back_db_config(
 
        /* objectclass/attribute mapping */
        } else if ( strcasecmp( argv[ 0 ], "map" ) == 0 ) {
-               struct ldapmap *map;
-               struct ldapmapping *mapping;
-               char *src, *dst;
                int             i = li->ntargets-1;
 
-               if ( i < 0 ) {
-                       fprintf( stderr,
-       "%s: line %d: need \"uri\" directive first\n",
-                               fname, lineno );
-               }
-               
-
-               if ( argc < 3 || argc > 4 ) {
-                       fprintf( stderr,
-       "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
-                               fname, lineno );
-                       return 1;
-               }
-
-               if ( strcasecmp( argv[ 1 ], "objectClass" ) == 0 ) {
-                       map = &li->targets[ i ]->oc_map;
-               } else if ( strcasecmp( argv[ 1 ], "attribute" ) == 0 ) {
-                       map = &li->targets[ i ]->at_map;
-               } else {
-                       fprintf( stderr,
-       "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
-                               fname, lineno );
-                       return 1;
-               }
-
-               if ( strcmp( argv[ 2 ], "*" ) == 0 ) {
-                       if ( argc < 4 || strcmp( argv[ 3 ], "*" ) == 0 ) {
-                               map->drop_missing = ( argc < 4 );
-                               return 0;
-                       }
-                       src = dst = argv[ 3 ];
-               } else if ( argc < 4 ) {
-                       src = "";
-                       dst = argv[ 2 ];
-               } else {
-                       src = argv[ 2 ];
-                       dst = ( strcmp( argv[ 3 ], "*" ) == 0 ? src : argv[ 3 ] );
-               }
-
-               if ( ( map == &li->targets[ i ]->at_map )
-                       && ( strcasecmp( src, "objectclass" ) == 0
-                               || strcasecmp( dst, "objectclass" ) == 0 ) ) {
-                       fprintf( stderr,
-       "%s: line %d: objectclass attribute cannot be mapped\n",
-                               fname, lineno );
-               }
-
-               mapping = ch_calloc( 2, sizeof( struct ldapmapping ) );
-               if ( mapping == NULL ) {
-                       fprintf( stderr,
-                               "%s: line %d: out of memory\n",
-                               fname, lineno );
-                       return 1;
-               }
-               ber_str2bv( src, 0, 1, &mapping->src );
-               ber_str2bv( dst, 0, 1, &mapping->dst );
-               mapping[ 1 ].src = mapping->dst;
-               mapping[ 1 ].dst = mapping->src;
-
-               if ( (*src != '\0' &&
-                         avl_find( map->map, ( caddr_t )mapping,
-                               mapping_cmp ) != NULL)
-                       || avl_find( map->remap, ( caddr_t )&mapping[ 1 ],
-                               mapping_cmp ) != NULL) {
-                       fprintf( stderr,
-       "%s: line %d: duplicate mapping found (ignored)\n",
-                               fname, lineno );
-                       return 0;
-               }
-
-               if ( *src != '\0' )
-                       avl_insert( &map->map, ( caddr_t )mapping,
-                                               mapping_cmp, mapping_dup );
-               avl_insert( &map->remap, ( caddr_t )&mapping[ 1 ],
-                                       mapping_cmp, mapping_dup );
-
+               return ldap_back_map_config( &li->targets[ i ]->oc_map, 
+                               &li->targets[ i ]->at_map,
+                               fname, lineno, argc, argv );
        /* anything else */
        } else {
                fprintf( stderr,
index 39e2114ae5c4aa9353c68d6aeb5ebdbfd97ca7a8..98ebbafbaacd62c0a1b26f2687c030063a457227 100644 (file)
@@ -207,7 +207,7 @@ meta_back_search(
                char    *realbase = ( char * )base->bv_val;
                int     realscope = scope;
                ber_len_t suffixlen;
-               char    *mapped_filter, **mapped_attrs;
+               char    **mapped_attrs;
 
                if ( lsc->candidate != META_CANDIDATE ) {
                        msgid[ i ] = -1;
@@ -311,7 +311,8 @@ meta_back_search(
                        rc = -1;
                        goto finish;
                }
-       
+
+#if 0
                /*
                 * Rewrite the search filter, if required
                 */
@@ -367,7 +368,12 @@ meta_back_search(
                }
                mfilter.bv_val = NULL;
                mfilter.bv_len = 0;
+#endif
        
+               rc = ldap_back_filter_map_rewrite_( li->targets[ i ]->rwinfo, conn,
+                       &li->targets[ i ]->at_map, &li->targets[ i ]->oc_map, 
+                       filter, &mfilter, BACKLDAP_MAP );
+
                /*
                 * Maps required attributes
                 */
@@ -386,14 +392,14 @@ meta_back_search(
                 * Starts the search
                 */
                msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
-                               mapped_filter, mapped_attrs, attrsonly ); 
+                               mfilter.bv_val, mapped_attrs, attrsonly ); 
                if ( mapped_attrs ) {
                        free( mapped_attrs );
                        mapped_attrs = NULL;
                }
-               if ( mapped_filter != filterstr->bv_val ) {
-                       free( mapped_filter );
-                       mapped_filter = NULL;
+               if ( mfilter.bv_val != filterstr->bv_val ) {
+                       free( mfilter.bv_val );
+                       mfilter.bv_val = NULL;
                }
                if ( mbase != realbase ) {
                        free( mbase );
@@ -782,9 +788,11 @@ meta_send_entry(
 
                } else if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
-                       int i, last;
+                       int             last;
+
                        for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
-                       for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
+
+                       for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
                                ldap_back_map( &li->targets[ target]->oc_map,
                                                bv, &mapped, BACKLDAP_REMAP );
                                if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
@@ -795,7 +803,7 @@ meta_send_entry(
                                        }
                                        *bv = attr->a_vals[ last ];
                                        attr->a_vals[ last ].bv_val = NULL;
-                                       i--;
+                                       bv--;
 
                                } else if ( mapped.bv_val != bv->bv_val ) {
                                        free( bv->bv_val );
@@ -815,8 +823,11 @@ meta_send_entry(
                 */
                } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
                                        SLAPD_DN_SYNTAX ) == 0 ) {
-                       int i;
-                       for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
+                       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 ]->rwinfo,
@@ -847,7 +858,15 @@ meta_send_entry(
                                        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,
@@ -858,6 +877,8 @@ meta_send_entry(
                                }
                        }
                }
+next_attr:;
+
                *attrp = attr;
                attrp = &attr->a_next;
        }
index 9c07d2d6acf4e102897893f578b185a5c4182c13..f8a6649232309d6c39251cdfc4c1f3d56f877d7e 100644 (file)
@@ -26,10 +26,6 @@ static int   get_substring_filter(
        Filter *f,
        const char **text );
 
-static int filter_escape_value(
-       struct berval *in,
-       struct berval *out );
-
 static void simple_vrFilter2bv(
        ValuesReturnFilter *f,
        struct berval *fstr );
@@ -797,7 +793,8 @@ filter2bv( Filter *f, struct berval *fstr )
        }
 }
 
-static int filter_escape_value(
+int
+filter_escape_value(
        struct berval *in,
        struct berval *out )
 {
index d2c5dbae10a5cad3f8ad07d3f23a173eb87106ed..258b13a3da3ea65a1c00791ab554d13bcb88ebbf 100644 (file)
@@ -537,6 +537,8 @@ LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
 LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
 
 LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
+LDAP_SLAPD_F (int) filter_escape_value LDAP_P(( struct berval *in, 
+       struct berval *out ));
 
 /*
  * filterentry.c