From bf35f8e37fa2516daa02a8c607dd2326b2be40e9 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 1 Mar 2003 11:08:53 +0000 Subject: [PATCH] improved filter mapping/rewrite; improved result rewriting; improved attribute/objectclass mapping configuration --- servers/slapd/back-ldap/back-ldap.h | 22 ++ servers/slapd/back-ldap/config.c | 222 +++++++++++----- servers/slapd/back-ldap/map.c | 393 ++++++++++++++++++++++++++++ servers/slapd/back-ldap/search.c | 108 +++----- servers/slapd/back-meta/config.c | 82 +----- servers/slapd/back-meta/search.c | 45 +++- servers/slapd/filter.c | 7 +- servers/slapd/proto-slap.h | 2 + 8 files changed, 652 insertions(+), 229 deletions(-) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 921d7be53e..ffe616e24b 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -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, diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 8dbed1b1aa..bba917a4cc 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -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} [ | *] { | *}\"\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} [ | *] " - "{ | *}\"\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} [ | *] " + "{ | *}\"\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"; diff --git a/servers/slapd/back-ldap/map.c b/servers/slapd/back-ldap/map.c index 9a5fb497da..ff7a48b71d 100644 --- a/servers/slapd/back-ldap/map.c +++ b/servers/slapd/back-ldap/map.c @@ -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; +} diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 404f9e37e2..07e0f30a95 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -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; } diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index e02adc8df6..04fc7d9fac 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -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} [ | *] { | *}\"\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} [ | *] { | *}\"\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, diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 39e2114ae5..98ebbafbaa 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -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; } diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 9c07d2d6ac..f8a6649232 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -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 ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index d2c5dbae10..258b13a3da 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 -- 2.39.5