mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
honor attributeType inheritance as well
This commit is contained in:
parent
d65f402058
commit
c4a8f58a0d
@ -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
|
||||
|
@ -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__ */
|
||||
|
@ -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 : "<NULL>", 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 );
|
||||
/*
|
||||
* attribute inheritance:
|
||||
*/
|
||||
if ( backsql_supad2at( bsi->bsi_oc, ad, &vat ) ) {
|
||||
bsi->bsi_status = LDAP_OTHER;
|
||||
rc = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
#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 " );
|
||||
at = at->bam_next;
|
||||
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 " );
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user