From c4a8f58a0d8a16b573ac07f273181ed7fa8cbeec Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 17 Jan 2004 16:27:11 +0000 Subject: [PATCH] honor attributeType inheritance as well --- servers/slapd/back-sql/schema-map.c | 67 ++++++++++++++++ servers/slapd/back-sql/schema-map.h | 2 + servers/slapd/back-sql/search.c | 118 +++++++++++++++++----------- 3 files changed, 140 insertions(+), 47 deletions(-) diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index f73114b3ed..106d73e4ff 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -567,6 +567,73 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad ) return res; } +/* attributeType inheritance */ +struct supad2at_t { + backsql_at_map_rec **ret; + AttributeDescription *ad; + unsigned n; +}; + +#define SUPAD2AT_STOP (-1) + +static int +supad2at_f( void *v_at, void *v_arg ) +{ + backsql_at_map_rec *at = (backsql_at_map_rec *)v_at; + struct supad2at_t *va = (struct supad2at_t *)v_arg; + + if ( is_at_subtype( at->bam_ad->ad_type, va->ad->ad_type ) ) { + backsql_at_map_rec **ret; + + ret = ch_realloc( va->ret, sizeof( backsql_at_map_rec *) * ( va->n + 2 ) ); + if ( ret == NULL ) { + ch_free( va->ret ); + return SUPAD2AT_STOP; + } + + ret[ va->n ] = at; + va->n++; + ret[ va->n ] = NULL; + va->ret = ret; + } + + return 0; +} + +/* + * stores in *pret a NULL terminated array of pointers + * to backsql_at_map_rec whose attributeType is supad->ad_type + * or derived from it + */ +int +backsql_supad2at( backsql_oc_map_rec *objclass, AttributeDescription *supad, + backsql_at_map_rec ***pret ) +{ + struct supad2at_t va; + int rc; + + assert( objclass ); + assert( supad ); + assert( pret ); + + *pret = NULL; + + va.ret = NULL; + va.ad = supad; + va.n = 0; + + rc = avl_apply( objclass->bom_attrs, supad2at_f, &va, + SUPAD2AT_STOP, AVL_INORDER ); + if ( rc == SUPAD2AT_STOP ) { + return -1; + } + + *pret = va.ret; + + return 0; +} + + #if 0 /* * Deprecated diff --git a/servers/slapd/back-sql/schema-map.h b/servers/slapd/back-sql/schema-map.h index f9add2d7c8..cf7d388a3a 100644 --- a/servers/slapd/back-sql/schema-map.h +++ b/servers/slapd/back-sql/schema-map.h @@ -100,6 +100,8 @@ backsql_at_map_rec *backsql_name2at( backsql_oc_map_rec *objclass, struct berval *at_name ); backsql_at_map_rec *backsql_ad2at( backsql_oc_map_rec *objclass, AttributeDescription *ad ); +int backsql_supad2at( backsql_oc_map_rec *objclass, + AttributeDescription *supad, backsql_at_map_rec ***pret ); int backsql_destroy_schema_map( backsql_info *si ); #endif /* __BACKSQL_SCHEMA_MAP_H__ */ diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 56538aa4a1..342b79becf 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -215,10 +215,10 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op ) } static int -backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f ) +backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, + backsql_at_map_rec *at ) { int i; - backsql_at_map_rec *at; backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; int casefold = 0; @@ -234,10 +234,6 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f ) casefold = 1; } - at = backsql_ad2at( bsi->bsi_oc, f->f_sub_desc ); - - assert( at ); - /* * When dealing with case-sensitive strings * we may omit normalization; however, normalized @@ -247,8 +243,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f ) backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */ ); /* TimesTen */ - Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->bam_sel_expr.bv_val, - at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "", 0 ); + Debug( LDAP_DEBUG_TRACE, "expr: '%s%s%s'\n", at->bam_sel_expr.bv_val, + at->bam_sel_expr_u.bv_val ? "' '" : "", + at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "" ); if ( casefold && bi->upper_func.bv_val ) { /* * If a pre-upper-cased version of the column exists, use it @@ -294,9 +291,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, - "==>backsql_process_sub_filter(): " - "sub_any='%s'\n", f->f_sub_any[ i ].bv_val, - 0, 0 ); + "==>backsql_process_sub_filter(%s): " + "sub_any='%s'\n", at->bam_ad->ad_cname.bv_val, + f->f_sub_any[ i ].bv_val, 0 ); #endif /* BACKSQL_TRACE */ start = bsi->bsi_flt_where.bb_val.bv_len; @@ -333,8 +330,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f ) static int backsql_process_filter( backsql_srch_info *bsi, Filter *f ) { - backsql_at_map_rec *at; + backsql_at_map_rec **vat = NULL; AttributeDescription *ad = NULL; + unsigned i; int done = 0; int rc = 0; @@ -342,7 +340,8 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) if ( f->f_choice == SLAPD_FILTER_COMPUTED ) { Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): " "invalid filter\n", 0, 0, 0 ); - goto impossible; + rc = -1; + goto done; } switch( f->f_choice ) { @@ -381,10 +380,11 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) } if ( rc == -1 ) { - goto impossible; + goto done; } if ( done ) { + rc = 1; goto done; } @@ -410,12 +410,14 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) "in filter\n", f->f_av_value.bv_val, 0, 0 ); bsi->bsi_status = LDAP_OTHER; - goto impossible; + rc = -1; + goto done; } /* - * objectClass inheritance: - * - a search for "person" will also return "inetOrgPerson" + * "structural" objectClass inheritance: + * - a search for "person" will also return + * "inetOrgPerson" * - a search for "top" will return everything */ if ( is_object_subclass( oc, bsi->bsi_oc->bom_oc ) ) { @@ -430,6 +432,7 @@ filter_oc_success:; backsql_strfcat( &bsi->bsi_flt_where, "l", (ber_len_t)sizeof( "1=1" ) - 1, "1=1" ); bsi->bsi_status = LDAP_SUCCESS; + rc = 1; goto done; default: @@ -439,7 +442,8 @@ filter_oc_success:; "on objectClass attribute", 0, 0, 0 ); bsi->bsi_status = LDAP_OTHER; - goto impossible; + rc = -1; + goto done; } } else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) { @@ -474,60 +478,80 @@ filter_oc_success:; */ backsql_attrlist_add( bsi, NULL ); } + rc = 1; goto done; } - /* look for attribute (also if objectClass but not structural one) */ - at = backsql_ad2at( bsi->bsi_oc, ad ); - - if ( at == NULL ) { - Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): " - "attribute '%s' is not defined for objectclass '%s'\n", - ad->ad_cname.bv_val, BACKSQL_OC_NAME( bsi->bsi_oc ), 0 ); + /* + * attribute inheritance: + */ + if ( backsql_supad2at( bsi->bsi_oc, ad, &vat ) ) { + bsi->bsi_status = LDAP_OTHER; + rc = -1; + goto done; + } -#if 0 - backsql_strfcat( &bsi->bsi_flt_where, "l", - (ber_len_t)sizeof( "1=0" ) - 1, "1=0" ); - bsi->bsi_status = LDAP_UNDEFINED_TYPE; - goto impossible; -#else - /* search anyway; other parts of the filter may succeeed */ + if ( vat == NULL ) { + /* search anyway; other parts of the filter + * may succeeed */ backsql_strfcat( &bsi->bsi_flt_where, "l", (ber_len_t)sizeof( "1=1" ) - 1, "1=1" ); bsi->bsi_status = LDAP_SUCCESS; + rc = 1; goto done; -#endif } - /* apply extra level of parens only if required */ + /* if required, open extra level of parens */ done = 0; - if ( at->bam_next ) { + if ( vat[0]->bam_next || vat[1] ) { backsql_strfcat( &bsi->bsi_flt_where, "c", '(' ); done = 1; } + + i = 0; next:; - if ( backsql_process_filter_attr( bsi, f, at ) == -1 ) { + /* apply attr */ + if ( backsql_process_filter_attr( bsi, f, vat[i] ) == -1 ) { return -1; } - if ( at->bam_next ) { + /* if more definitions of the same attr, apply */ + if ( vat[i]->bam_next ) { + backsql_strfcat( &bsi->bsi_flt_where, "l", + sizeof( " OR " ) - 1, " OR " ); + vat[i] = vat[i]->bam_next; + goto next; + } + + /* if more descendants of the same attr, apply */ + i++; + if ( vat[i] ) { backsql_strfcat( &bsi->bsi_flt_where, "l", - sizeof( " OR " ) - 1, " OR " ); - at = at->bam_next; + sizeof( " OR " ) - 1, " OR " ); goto next; } + + /* if needed, close extra level of parens */ if ( done ) { backsql_strfcat( &bsi->bsi_flt_where, "c", ')' ); } -done:; - Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter()\n", 0, 0, 0 ); - return 1; + rc = 1; -impossible:; - Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() returns -1\n", - 0, 0, 0 ); - return -1; +done:; + if ( vat ) { + ch_free( vat ); + } + if ( rc == 1 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_process_filter() succeeded\n", + 0, 0, 0 ); + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_process_filter() failed\n", + 0, 0, 0 ); + } + return rc; } static int @@ -692,7 +716,7 @@ equality_match:; break; case LDAP_FILTER_SUBSTRINGS: - backsql_process_sub_filter( bsi, f ); + backsql_process_sub_filter( bsi, f, at ); break; case LDAP_FILTER_APPROX: -- 2.39.5