X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-meta%2Fmap.c;h=87ca4b903175cdae6c7750b8098848d40bea291b;hb=52165180f7713b5fdebef933a9dca8842daa2e2a;hp=a76c5f0f856f92ddc1418dbaa69fd2937966ff12;hpb=ba6ac023ad20c1a37e2ec8d796e86ef73571a7de;p=openldap diff --git a/servers/slapd/back-meta/map.c b/servers/slapd/back-meta/map.c index a76c5f0f85..87ca4b9031 100644 --- a/servers/slapd/back-meta/map.c +++ b/servers/slapd/back-meta/map.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2003 The OpenLDAP Foundation. + * Copyright 1998-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,7 +70,7 @@ mapping_cmp ( const void *c1, const void *c2 ) struct ldapmapping *map2 = (struct ldapmapping *)c2; int rc = map1->src.bv_len - map2->src.bv_len; if (rc) return rc; - return ( strcasecmp(map1->src.bv_val, map2->src.bv_val) ); + return ( strcasecmp( map1->src.bv_val, map2->src.bv_val ) ); } int @@ -79,7 +79,7 @@ mapping_dup ( void *c1, void *c2 ) struct ldapmapping *map1 = (struct ldapmapping *)c1; struct ldapmapping *map2 = (struct ldapmapping *)c2; - return( ( strcasecmp(map1->src.bv_val, map2->src.bv_val) == 0 ) ? -1 : 0 ); + return ( ( strcasecmp( map1->src.bv_val, map2->src.bv_val ) == 0 ) ? -1 : 0 ); } void @@ -109,32 +109,48 @@ ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping **m ) *m = mapping; } -void -ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv, +int +ldap_back_mapping ( struct ldapmap *map, struct berval *s, struct ldapmapping **m, int remap ) { Avlnode *tree; - struct ldapmapping *mapping, fmapping; + struct ldapmapping fmapping; - if (remap == BACKLDAP_REMAP) + assert( m ); + + if ( remap == BACKLDAP_REMAP ) { tree = map->remap; - else + } else { tree = map->map; + } - bv->bv_len = 0; - bv->bv_val = NULL; fmapping.src = *s; - mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp ); - if (mapping != NULL) { - if ( mapping->dst.bv_val ) + *m = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp ); + if ( *m == NULL ) { + return map->drop_missing; + } + + return 0; +} + +void +ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv, + int remap ) +{ + struct ldapmapping *mapping; + + BER_BVZERO( bv ); + ( void )ldap_back_mapping( map, s, &mapping, remap ); + if ( mapping != NULL ) { + if ( !BER_BVISNULL( &mapping->dst ) ) { *bv = mapping->dst; + } return; } - if (!map->drop_missing) + if ( !map->drop_missing ) { *bv = *s; - - return; + } } int @@ -149,28 +165,29 @@ ldap_back_map_attrs( char **na; struct berval mapped; - if (an == NULL) { + if ( an == NULL ) { *mapped_attrs = NULL; return LDAP_SUCCESS; } - for (i = 0; an[i].an_name.bv_val; i++) { - /* */ - } + for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) + /* */ ; na = (char **)ch_calloc( i + 1, sizeof(char *) ); - if (na == NULL) { + if ( na == NULL ) { *mapped_attrs = NULL; return LDAP_NO_MEMORY; } - for (i = j = 0; an[i].an_name.bv_val; i++) { - ldap_back_map(at_map, &an[i].an_name, &mapped, remap); - if (mapped.bv_val != NULL && mapped.bv_val != '\0') + for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) { + ldap_back_map( at_map, &an[i].an_name, &mapped, remap ); + if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) { na[j++] = mapped.bv_val; + } } - if (j == 0 && i != 0) + if ( j == 0 && i != 0 ) { na[j++] = LDAP_NO_ATTRS; + } na[j] = NULL; *mapped_attrs = na; @@ -189,13 +206,13 @@ map_attr_value( struct berval vtmp; int freeval = 0; - ldap_back_map( &dc->rwmap->rwm_at, &ad->ad_cname, mapped_attr, remap ); - if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0') { + ldap_back_map( &dc->target->mt_rwmap.rwm_at, &ad->ad_cname, mapped_attr, remap ); + if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) { /* * FIXME: are we sure we need to search oc_map if at_map fails? */ - ldap_back_map( &dc->rwmap->rwm_oc, &ad->ad_cname, mapped_attr, remap ); - if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0' ) { + ldap_back_map( &dc->target->mt_rwmap.rwm_oc, &ad->ad_cname, mapped_attr, remap ); + if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) { *mapped_attr = ad->ad_cname; } } @@ -227,8 +244,8 @@ map_attr_value( } } else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) { - ldap_back_map( &dc->rwmap->rwm_oc, value, &vtmp, remap ); - if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) { + ldap_back_map( &dc->target->mt_rwmap.rwm_oc, value, &vtmp, remap ); + if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) { vtmp = *value; } @@ -259,7 +276,7 @@ ldap_back_int_filter_map_rewrite( ber_len_t len; if ( f == NULL ) { - ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr ); + ber_str2bv( "No filter!", STRLENOF( "No filter!" ), 1, fstr ); return -1; } @@ -341,13 +358,13 @@ ldap_back_int_filter_map_rewrite( /* cannot be a DN ... */ - fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 ); - fstr->bv_val = malloc( fstr->bv_len + 128 ); + fstr->bv_len = atmp.bv_len + ( STRLENOF( "(=*)" ) ); + fstr->bv_val = malloc( fstr->bv_len + 128 ); /* FIXME: why 128 ? */ snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)", atmp.bv_val ); - if ( f->f_sub_initial.bv_val != NULL ) { + if ( !BER_BVISNULL( &f->f_sub_initial ) ) { len = fstr->bv_len; filter_escape_value( &f->f_sub_initial, &vtmp ); @@ -363,7 +380,7 @@ ldap_back_int_filter_map_rewrite( } if ( f->f_sub_any != NULL ) { - for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) { + for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) { len = fstr->bv_len; filter_escape_value( &f->f_sub_any[i], &vtmp ); @@ -377,7 +394,7 @@ ldap_back_int_filter_map_rewrite( } } - if ( f->f_sub_final.bv_val != NULL ) { + if ( !BER_BVISNULL( &f->f_sub_final ) ) { len = fstr->bv_len; filter_escape_value( &f->f_sub_final, &vtmp ); @@ -401,7 +418,7 @@ ldap_back_int_filter_map_rewrite( return -1; } - fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 ); + fstr->bv_len = atmp.bv_len + ( STRLENOF( "(=*)" ) ); fstr->bv_val = malloc( fstr->bv_len + 1 ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)", @@ -411,8 +428,8 @@ ldap_back_int_filter_map_rewrite( 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 ); + fstr->bv_len = STRLENOF( "(%)" ); + fstr->bv_val = malloc( fstr->bv_len + 128 ); /* FIXME: why 128? */ snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)", f->f_choice == LDAP_FILTER_AND ? '&' : @@ -437,7 +454,7 @@ ldap_back_int_filter_map_rewrite( break; - case LDAP_FILTER_EXT: { + case LDAP_FILTER_EXT: if ( f->f_mr_desc ) { if ( map_attr_value( dc, f->f_mr_desc, &atmp, &f->f_mr_value, &vtmp, remap ) ) @@ -446,44 +463,60 @@ ldap_back_int_filter_map_rewrite( } } else { - atmp.bv_len = 0; - atmp.bv_val = ""; - + BER_BVSTR( &atmp, "" ); filter_escape_value( &f->f_mr_value, &vtmp ); } - + /* FIXME: cleanup (less ?: operators...) */ 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 ); + ( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) + + ( !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_len + 1 : 0 ) + + vtmp.bv_len + ( STRLENOF( "(:=)" ) ); 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 : "", + !BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "", + !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "", vtmp.bv_val ); ber_memfree( vtmp.bv_val ); - } break; + break; + + case SLAPD_FILTER_COMPUTED: { + struct berval bv; - case SLAPD_FILTER_COMPUTED: switch ( f->f_result ) { case LDAP_COMPARE_FALSE: - ber_str2bv( "(?=false)", STRLENOF( "(?=false)" ), 1, fstr ); + if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) { + BER_BVSTR( &bv, "(|)" ); + break; + } + /* fallthru */ + + /* FIXME: treat UNDEFINED as FALSE */ + case SLAPD_COMPARE_UNDEFINED: + /* better than nothing... */ + BER_BVSTR( &bv, "(!(objectClass=*))" ); break; + case LDAP_COMPARE_TRUE: - ber_str2bv( "(?=true)", STRLENOF( "(?=true)" ), 1, fstr ); - break; - case SLAPD_COMPARE_UNDEFINED: - ber_str2bv( "(?=undefined)", STRLENOF( "(?=undefined)" ), 1, fstr ); + if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) { + BER_BVSTR( &bv, "(&)" ); + break; + } + + /* better than nothing... */ + BER_BVSTR( &bv, "(objectClass=*)" ); break; + default: - ber_str2bv( "(?=error)", STRLENOF( "(?=error)" ), 1, fstr ); + BER_BVSTR( &bv, "(?=error)" ); break; } - break; + + ber_dupbv( fstr, &bv ); + } break; default: ber_str2bv( "(?=unknown)", STRLENOF( "(?=unknown)" ), 1, fstr ); @@ -503,6 +536,7 @@ ldap_back_filter_map_rewrite( int rc; dncookie fdc; struct berval ftmp; + static char *dmy = ""; rc = ldap_back_int_filter_map_rewrite( dc, f, fstr, remap ); @@ -516,19 +550,21 @@ ldap_back_filter_map_rewrite( fdc.ctx = "searchFilter"; - switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx, - ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ), + switch ( rewrite_session( fdc.target->mt_rwmap.rwm_rw, fdc.ctx, + ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : dmy ), fdc.conn, &fstr->bv_val ) ) { case REWRITE_REGEXEC_OK: if ( !BER_BVISNULL( fstr ) ) { fstr->bv_len = strlen( fstr->bv_val ); + } else { *fstr = ftmp; } Debug( LDAP_DEBUG_ARGS, "[rw] %s: \"%s\" -> \"%s\"\n", - fdc.ctx, ftmp.bv_val, fstr->bv_val ); + fdc.ctx, BER_BVISNULL( &ftmp ) ? "" : ftmp.bv_val, + BER_BVISNULL( fstr ) ? "" : fstr->bv_val ); rc = LDAP_SUCCESS; break; @@ -548,6 +584,10 @@ ldap_back_filter_map_rewrite( rc = LDAP_OTHER; break; } + + if ( fstr->bv_val == dmy ) { + BER_BVZERO( fstr ); + } #endif /* ENABLE_REWRITE */ return rc; @@ -569,7 +609,8 @@ ldap_back_referral_result_rewrite( last--; for ( i = 0; !BER_BVISNULL( &a_vals[ i ] ); i++ ) { - struct berval dn, olddn; + struct berval dn, + olddn = BER_BVNULL; int rc; LDAPURLDesc *ludp; @@ -579,6 +620,14 @@ ldap_back_referral_result_rewrite( continue; } + /* FIXME: URLs like "ldap:///dc=suffix" if passed + * thru ldap_url_parse() and ldap_url_desc2str() + * get rewritten as "ldap:///dc=suffix??base"; + * we don't want this to occur... */ + if ( ludp->lud_scope == LDAP_SCOPE_BASE ) { + ludp->lud_scope = LDAP_SCOPE_DEFAULT; + } + ber_str2bv( ludp->lud_dn, 0, 0, &olddn ); rc = ldap_back_dn_massage( dc, &olddn, &dn ); @@ -608,7 +657,8 @@ ldap_back_referral_result_rewrite( newurl = ldap_url_desc2str( ludp ); if ( newurl == NULL ) { /* FIXME: leave attr untouched - * even if ldap_url_desc2str failed... */ + * even if ldap_url_desc2str failed... + */ break; } @@ -642,10 +692,13 @@ ldap_dnattr_rewrite( struct berval bv; int i, last; - for ( last = 0; a_vals[last].bv_val != NULL; last++ ); + assert( a_vals != NULL ); + + for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ ) + ; last--; - for ( i = 0; a_vals[i].bv_val != NULL; i++ ) { + for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) { switch ( ldap_back_dn_massage( dc, &a_vals[i], &bv ) ) { case LDAP_UNWILLING_TO_PERFORM: /* @@ -654,17 +707,16 @@ ldap_dnattr_rewrite( * it should be when searching (e.g. ACLs). */ ch_free( a_vals[i].bv_val ); - if (last > i ) { + if ( last > i ) { a_vals[i] = a_vals[last]; } - a_vals[last].bv_len = 0; - a_vals[last].bv_val = NULL; + BER_BVZERO( &a_vals[last] ); last--; break; default: /* leave attr untouched if massage failed */ - if ( bv.bv_val && bv.bv_val != a_vals[i].bv_val ) { + if ( !BER_BVISNULL( &bv ) && bv.bv_val != a_vals[i].bv_val ) { ch_free( a_vals[i].bv_val ); a_vals[i] = bv; } @@ -684,10 +736,13 @@ ldap_dnattr_result_rewrite( struct berval bv; int i, last; - for ( last = 0; a_vals[last].bv_val; last++ ); + assert( a_vals != NULL ); + + for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ ) + ; last--; - for ( i = 0; a_vals[i].bv_val; i++ ) { + for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) { switch ( ldap_back_dn_massage( dc, &a_vals[i], &bv ) ) { case LDAP_UNWILLING_TO_PERFORM: /* @@ -705,7 +760,7 @@ ldap_dnattr_result_rewrite( default: /* leave attr untouched if massage failed */ - if ( bv.bv_val && a_vals[i].bv_val != bv.bv_val ) { + if ( !BER_BVISNULL( &bv ) && a_vals[i].bv_val != bv.bv_val ) { LBER_FREE( a_vals[i].bv_val ); a_vals[i] = bv; }