X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fvalue.c;h=e4b9ee0ed6c4ea05ae9e61947c6f629cf385febd;hb=b44cc963c2b021821ccac582054e2ffa04f4f1e1;hp=6988e6cec6860f4e705a85f7c94bd9f94d981521;hpb=387186fc339338fe9c2c5f674a73db071711c848;p=openldap diff --git a/servers/slapd/value.c b/servers/slapd/value.c index 6988e6cec6..e4b9ee0ed6 100644 --- a/servers/slapd/value.c +++ b/servers/slapd/value.c @@ -1,6 +1,7 @@ /* value.c - routines for dealing with values */ +/* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -17,38 +18,6 @@ #include "slap.h" -int -value_add_fast( - struct berval ***vals, - struct berval **addvals, - int nvals, - int naddvals, - int *maxvals -) -{ - int need, i, j; - - if ( *maxvals == 0 ) { - *maxvals = 1; - } - need = nvals + naddvals + 1; - while ( *maxvals < need ) { - *maxvals *= 2; - *vals = (struct berval **) ch_realloc( (char *) *vals, - *maxvals * sizeof(struct berval *) ); - } - - for ( i = 0, j = 0; i < naddvals; i++, j++ ) { - if ( addvals[i]->bv_len > 0 ) { - (*vals)[nvals + j] = ber_bvdup( addvals[i] ); - if( (*vals)[nvals + j] == NULL ) break; - } - } - (*vals)[nvals + j] = NULL; - - return( 0 ); -} - int value_add( struct berval ***vals, @@ -79,98 +48,151 @@ value_add( } (*vals)[n + j] = NULL; - return( 0 ); + return LDAP_SUCCESS; } -void + +int value_normalize( - char *s, - int syntax -) + AttributeDescription *ad, + unsigned usage, + struct berval *in, + struct berval **out, + const char **text ) { - char *d, *save; + int rc; + MatchingRule *mr; - if ( ! (syntax & SYNTAX_CIS) ) { - return; + switch( usage & SLAP_MR_TYPE_MASK ) { + case SLAP_MR_NONE: + case SLAP_MR_EQUALITY: + mr = ad->ad_type->sat_equality; + break; + case SLAP_MR_ORDERING: + mr = ad->ad_type->sat_ordering; + break; + case SLAP_MR_SUBSTR: + mr = ad->ad_type->sat_substr; + break; + case SLAP_MR_EXT: + default: + assert( 0 ); + *text = "internal error"; + return LDAP_OTHER; + } + + if( mr == NULL ) { + *text = "inappropriate matching request"; + return LDAP_INAPPROPRIATE_MATCHING; } - if ( syntax & SYNTAX_DN ) { - (void) dn_normalize_case( s ); - return; + /* we only support equality matching of binary attributes */ + if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) { + *text = "inappropriate binary matching"; + return LDAP_INAPPROPRIATE_MATCHING; } - save = s; - for ( d = s; *s; s++ ) { - if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) { - continue; + if( mr->smr_normalize ) { + rc = (mr->smr_normalize)( usage, + ad->ad_type->sat_syntax, + mr, in, out ); + + if( rc != LDAP_SUCCESS ) { + *text = "unable to normalize value"; + return LDAP_INVALID_SYNTAX; + } + + } else if ( mr->smr_syntax->ssyn_normalize ) { + rc = (mr->smr_syntax->ssyn_normalize)( + ad->ad_type->sat_syntax, + in, out ); + + if( rc != LDAP_SUCCESS ) { + *text = "unable to normalize value"; + return LDAP_INVALID_SYNTAX; } - *d++ = TOUPPER( (unsigned char) *s ); + + } else { + *out = ber_bvdup( in ); } - *d = '\0'; + + return LDAP_SUCCESS; } + int -value_cmp( - struct berval *v1, - struct berval *v2, - int syntax, - int normalize /* 1 => arg 1; 2 => arg 2; 3 => both */ -) +value_match( + int *match, + AttributeDescription *ad, + MatchingRule *mr, + unsigned flags, + struct berval *v1, /* stored value */ + void *v2, /* assertion */ + const char ** text ) { - int rc; + int rc; + struct berval *nv1 = NULL; - if ( normalize & 1 ) { - v1 = ber_bvdup( v1 ); - value_normalize( v1->bv_val, syntax ); - } - if ( normalize & 2 ) { - v2 = ber_bvdup( v2 ); - value_normalize( v2->bv_val, syntax ); + if( !mr->smr_match ) { + return LDAP_INAPPROPRIATE_MATCHING; } - switch ( syntax ) { - case SYNTAX_CIS: - case (SYNTAX_CIS | SYNTAX_TEL): - case (SYNTAX_CIS | SYNTAX_DN): - rc = strcasecmp( v1->bv_val, v2->bv_val ); - break; - - case SYNTAX_CES: - rc = strcmp( v1->bv_val, v2->bv_val ); - break; - - case SYNTAX_BIN: - rc = (v1->bv_len == v2->bv_len - ? memcmp( v1->bv_val, v2->bv_val, v1->bv_len ) - : v1->bv_len > v2->bv_len ? 1 : -1); - break; - } + if( ad->ad_type->sat_syntax->ssyn_normalize ) { + rc = ad->ad_type->sat_syntax->ssyn_normalize( + ad->ad_type->sat_syntax, v1, &nv1 ); - if ( normalize & 1 ) { - ber_bvfree( v1 ); - } - if ( normalize & 2 ) { - ber_bvfree( v2 ); + if( rc != LDAP_SUCCESS ) { + return LDAP_INAPPROPRIATE_MATCHING; + } } - return( rc ); + rc = (mr->smr_match)( match, flags, + ad->ad_type->sat_syntax, + mr, + nv1 != NULL ? nv1 : v1, + v2 ); + + ber_bvfree( nv1 ); + return rc; } -int -value_find( - struct berval **vals, - struct berval *v, - int syntax, - int normalize -) + +int value_find( + AttributeDescription *ad, + struct berval **vals, + struct berval *val ) { int i; + int rc; + struct berval *nval = NULL; + MatchingRule *mr = ad->ad_type->sat_equality; + + if( mr == NULL || !mr->smr_match ) { + return LDAP_INAPPROPRIATE_MATCHING; + } + + if( mr->smr_syntax->ssyn_normalize ) { + rc = mr->smr_syntax->ssyn_normalize( + mr->smr_syntax, val, &nval ); + + if( rc != LDAP_SUCCESS ) { + return LDAP_INAPPROPRIATE_MATCHING; + } + } for ( i = 0; vals[i] != NULL; i++ ) { - if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) { - return( 0 ); + int match; + const char *text; + + rc = value_match( &match, ad, mr, 0, + vals[i], nval == NULL ? val : nval, &text ); + + if( rc == LDAP_SUCCESS && match == 0 ) { + ber_bvfree( nval ); + return LDAP_SUCCESS; } } - return( 1 ); + ber_bvfree( nval ); + return LDAP_NO_SUCH_ATTRIBUTE; }