X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fvalue.c;h=cf46e7765b54e065eec42880711326fdfe681052;hb=7dc5a0bb831df990ecad4ffd60c06b952c1a0bce;hp=3cc7ba54a3bfbe22f1b89761cfe25f59ba1946a2;hpb=439c0c796ded2be4d3236b981eb20eb2992402df;p=openldap diff --git a/servers/slapd/value.c b/servers/slapd/value.c index 3cc7ba54a3..cf46e7765b 100644 --- a/servers/slapd/value.c +++ b/servers/slapd/value.c @@ -1,8 +1,28 @@ /* value.c - routines for dealing with values */ /* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2004 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + * Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ #include "portable.h" @@ -20,295 +40,220 @@ int value_add( - struct berval ***vals, - struct berval **addvals -) + BerVarray *vals, + BerVarray addvals ) { - int n, nn, i, j; + int n, nn = 0; + BerVarray v2; - for ( nn = 0; addvals != NULL && addvals[nn] != NULL; nn++ ) - ; /* NULL */ + if ( addvals != NULL ) { + for ( ; !BER_BVISNULL( &addvals[nn] ); nn++ ) + ; /* NULL */ + } if ( *vals == NULL ) { - *vals = (struct berval **) ch_malloc( (nn + 1) - * sizeof(struct berval *) ); + *vals = (BerVarray) SLAP_MALLOC( (nn + 1) + * sizeof(struct berval) ); + if( *vals == NULL ) { + Debug(LDAP_DEBUG_TRACE, + "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 ); + return LBER_ERROR_MEMORY; + } n = 0; + } else { - for ( n = 0; (*vals)[n] != NULL; n++ ) - ; /* NULL */ - *vals = (struct berval **) ch_realloc( (char *) *vals, - (n + nn + 1) * sizeof(struct berval *) ); + for ( n = 0; !BER_BVISNULL( &(*vals)[n] ); n++ ) { + ; /* Empty */ + } + *vals = (BerVarray) SLAP_REALLOC( (char *) *vals, + (n + nn + 1) * sizeof(struct berval) ); + if( *vals == NULL ) { + Debug(LDAP_DEBUG_TRACE, + "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 ); + return LBER_ERROR_MEMORY; + } } - for ( i = 0, j = 0; i < nn; i++ ) { - if ( addvals[i]->bv_len > 0 ) { - (*vals)[n + j] = ber_bvdup( addvals[i] ); - if( (*vals)[n + j++] == NULL ) break; - } + v2 = &(*vals)[n]; + for ( ; !BER_BVISNULL( addvals ); v2++, addvals++ ) { + ber_dupbv( v2, addvals ); + if ( BER_BVISNULL( v2 ) ) break; } - (*vals)[n + j] = NULL; + BER_BVZERO( v2 ); - return( 0 ); + return LDAP_SUCCESS; } -#ifdef SLAPD_SCHEMA_NOT_COMPAT - /* not used */ -#else int -value_add_fast( - struct berval ***vals, - struct berval **addvals, - int nvals, - int naddvals, - int *maxvals -) +value_add_one( + BerVarray *vals, + struct berval *addval ) { - int need, i, j; + int n; + BerVarray v2; - 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 *) ); - } + if ( *vals == NULL ) { + *vals = (BerVarray) SLAP_MALLOC( 2 * sizeof(struct berval) ); + if( *vals == NULL ) { + Debug(LDAP_DEBUG_TRACE, + "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 ); + return LBER_ERROR_MEMORY; + } + n = 0; - for ( i = 0, j = 0; i < naddvals; i++ ) { - if ( addvals[i]->bv_len > 0 ) { - (*vals)[nvals + j] = ber_bvdup( addvals[i] ); - if( (*vals)[nvals + j] != NULL ) j++; + } else { + for ( n = 0; !BER_BVISNULL( &(*vals)[n] ); n++ ) { + ; /* Empty */ + } + *vals = (BerVarray) SLAP_REALLOC( (char *) *vals, + (n + 2) * sizeof(struct berval) ); + if( *vals == NULL ) { + Debug(LDAP_DEBUG_TRACE, + "value_add_one: SLAP_MALLOC failed.\n", 0, 0, 0 ); + return LBER_ERROR_MEMORY; } } - (*vals)[nvals + j] = NULL; - return( 0 ); + v2 = &(*vals)[n]; + ber_dupbv(v2, addval); + + v2++; + BER_BVZERO( v2 ); + + return LDAP_SUCCESS; } -#endif -#ifdef SLAPD_SCHEMA_NOT_COMPAT -int -value_normalize( +int asserted_value_validate_normalize( AttributeDescription *ad, + MatchingRule *mr, unsigned usage, struct berval *in, - struct berval **out, - const char **text ) + struct berval *out, + const char ** text, + void *ctx ) { int rc; - MatchingRule *mr; - - 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; - } + struct berval pval; + pval.bv_val = NULL; + + /* we expect the value to be in the assertion syntax */ + assert( !SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) ); if( mr == NULL ) { *text = "inappropriate matching request"; return LDAP_INAPPROPRIATE_MATCHING; } - /* we only support equality matching of binary attributes */ - if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) { - *text = "inappropriate binary matching"; + if( !mr->smr_match ) { + *text = "requested matching rule not supported"; return LDAP_INAPPROPRIATE_MATCHING; } - if( mr->smr_normalize ) { - rc = (mr->smr_normalize)( usage, - ad->ad_type->sat_syntax, - mr, in, out ); + if( mr->smr_syntax->ssyn_pretty ) { + rc = (mr->smr_syntax->ssyn_pretty)( mr->smr_syntax, in, &pval, ctx ); + in = &pval; - if( rc != LDAP_SUCCESS ) { - *text = "unable to normalize value"; - return LDAP_INVALID_SYNTAX; - } + } else { + rc = (mr->smr_syntax->ssyn_validate)( mr->smr_syntax, in ); + } - } 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 = "value does not conform to assertion syntax"; + return LDAP_INVALID_SYNTAX; + } + + if( mr->smr_normalize ) { + rc = (mr->smr_normalize)( + usage|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, + ad ? ad->ad_type->sat_syntax : NULL, + mr, in, out, ctx ); + + if( pval.bv_val ) ber_memfree_x( pval.bv_val, ctx ); if( rc != LDAP_SUCCESS ) { - *text = "unable to normalize value"; + *text = "unable to normalize value for matching"; return LDAP_INVALID_SYNTAX; } + } else if ( pval.bv_val != NULL ) { + *out = pval; + } else { - *out = ber_bvdup( in ); + ber_dupbv_x( out, in, ctx ); } return LDAP_SUCCESS; } -#else -void -value_normalize( - char *s, - int syntax -) -{ - char *d, *save; - - if ( ! (syntax & SYNTAX_CIS) ) { - return; - } - - if ( syntax & SYNTAX_DN ) { - (void) dn_normalize( s ); - return; - } - - save = s; - for ( d = s; *s; s++ ) { - if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) { - continue; - } - *d++ = TOUPPER( (unsigned char) *s ); - } - *d = '\0'; -} -#endif -#ifdef SLAPD_SCHEMA_NOT_COMPAT int value_match( int *match, AttributeDescription *ad, MatchingRule *mr, + unsigned flags, struct berval *v1, /* stored value */ void *v2, /* assertion */ const char ** text ) { int rc; - int usage = 0; - struct berval *nv1 = NULL; - if( ad->ad_type->sat_syntax->ssyn_normalize ) { - rc = ad->ad_type->sat_syntax->ssyn_normalize( - ad->ad_type->sat_syntax, v1, &nv1 ); - - if( rc != LDAP_SUCCESS ) { - return LDAP_INAPPROPRIATE_MATCHING; - } - } + assert( mr != NULL ); if( !mr->smr_match ) { return LDAP_INAPPROPRIATE_MATCHING; } - rc = (mr->smr_match)( match, usage, - ad->ad_type->sat_syntax, - mr, - nv1 != NULL ? nv1 : v1, - v2 ); + rc = (mr->smr_match)( match, flags, + ad->ad_type->sat_syntax, mr, v1, v2 ); - ber_bvfree( nv1 ); return rc; } -#else -int -value_cmp( - struct berval *v1, - struct berval *v2, - int syntax, - int normalize /* 1 => arg 1; 2 => arg 2; 3 => both */ -) -{ - int rc; - - 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 ); - } - - 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; - - default: /* Unknown syntax */ - 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 ( normalize & 1 ) { - ber_bvfree( v1 ); - } - if ( normalize & 2 ) { - ber_bvfree( v2 ); - } - - return( rc ); -} -#endif - -#ifdef SLAPD_SCHEMA_NOT_COMPAT -int value_find( +int value_find_ex( AttributeDescription *ad, - struct berval **vals, - struct berval *val ) -#else -int -value_find( - struct berval **vals, - struct berval *v, - int syntax, - int normalize ) -#endif + unsigned flags, + BerVarray vals, + struct berval *val, + void *ctx ) { int i; -#ifdef SLAPD_SCHEMA_NOT_COMPAT + int rc; + struct berval nval = BER_BVNULL; MatchingRule *mr = ad->ad_type->sat_equality; - if( mr == NULL ) { + if( mr == NULL || !mr->smr_match ) { return LDAP_INAPPROPRIATE_MATCHING; } -#endif - for ( i = 0; vals[i] != NULL; i++ ) { -#ifdef SLAPD_SCHEMA_NOT_COMPAT - int rc; + assert(SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags )); + + if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) && + mr->smr_normalize ) + { + rc = (mr->smr_normalize)( + flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX), + ad ? ad->ad_type->sat_syntax : NULL, + mr, val, &nval, ctx ); + + if( rc != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; + } + } + + for ( i = 0; vals[i].bv_val != NULL; i++ ) { int match; const char *text; - rc = value_match( &match, ad, mr, vals[i], val, &text ); - - if( rc == LDAP_SUCCESS && match == 0 ) -#else - if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) -#endif - { - return LDAP_SUCCESS; + + rc = value_match( &match, ad, mr, flags, + &vals[i], nval.bv_val == NULL ? val : &nval, &text ); + + if( rc == LDAP_SUCCESS && match == 0 ) { + slap_sl_free( nval.bv_val, ctx ); + return rc; } } + slap_sl_free( nval.bv_val, ctx ); return LDAP_NO_SUCH_ATTRIBUTE; }