From 9fec1299971d03f0c1d0cd2462d530685e1c7861 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 25 Jan 2000 21:13:31 +0000 Subject: [PATCH] Second round of schema changes Revert normalization to matching rule per discussions with Julio. May need separate normalization routines for stored value and asserted value. Currently rely on passed in syntax/mr to allow "special" behavior. Reworked filters to pass struct berval * instead of char *. (needs work) Validation, normalization and matching needed. --- servers/slapd/back-ldbm/filterindex.c | 47 +++--- servers/slapd/filter.c | 102 ++++++++---- servers/slapd/filterentry.c | 12 +- servers/slapd/proto-slap.h | 8 +- servers/slapd/schema.c | 214 +++++++++++++++----------- servers/slapd/schemaparse.c | 35 +++-- servers/slapd/slap.h | 61 ++++++-- servers/slapd/str2filter.c | 14 +- 8 files changed, 301 insertions(+), 192 deletions(-) diff --git a/servers/slapd/back-ldbm/filterindex.c b/servers/slapd/back-ldbm/filterindex.c index 97b2c87866..c3c92a3954 100644 --- a/servers/slapd/back-ldbm/filterindex.c +++ b/servers/slapd/back-ldbm/filterindex.c @@ -20,7 +20,8 @@ static ID_BLOCK *presence_candidates( Backend *be, char *type ); static ID_BLOCK *approx_candidates( Backend *be, Ava *ava ); static ID_BLOCK *list_candidates( Backend *be, Filter *flist, int ftype ); static ID_BLOCK *substring_candidates( Backend *be, Filter *f ); -static ID_BLOCK *substring_comp_candidates( Backend *be, char *type, char *val, int prepost ); +static ID_BLOCK *substring_comp_candidates( Backend *be, char *type, + struct berval *val, int prepost ); /* * test_filter - test a filter against a single entry. @@ -247,7 +248,7 @@ substring_candidates( /* initial */ if ( f->f_sub_initial != NULL ) { - if ( (int) strlen( f->f_sub_initial ) < SUBLEN - 1 ) { + if ( f->f_sub_initial->bv_len < SUBLEN - 1 ) { idl = idl_allids( be ); } else if ( (idl = substring_comp_candidates( be, f->f_sub_type, f->f_sub_initial, '^' )) == NULL ) { @@ -257,7 +258,7 @@ substring_candidates( /* final */ if ( f->f_sub_final != NULL ) { - if ( (int) strlen( f->f_sub_final ) < SUBLEN - 1 ) { + if ( f->f_sub_final->bv_len < SUBLEN - 1 ) { tmp = idl_allids( be ); } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, f->f_sub_final, '$' )) == NULL ) { @@ -275,22 +276,24 @@ substring_candidates( } } - for ( i = 0; f->f_sub_any != NULL && f->f_sub_any[i] != NULL; i++ ) { - if ( (int) strlen( f->f_sub_any[i] ) < SUBLEN ) { - tmp = idl_allids( be ); - } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_any[i], 0 )) == NULL ) { - idl_free( idl ); - return( NULL ); - } - - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); + if( f->f_sub_any != NULL ) { + for ( i = 0; f->f_sub_any[i] != NULL; i++ ) { + if ( f->f_sub_any[i]->bv_len < SUBLEN ) { + tmp = idl_allids( be ); + } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, + f->f_sub_any[i], 0 )) == NULL ) { + idl_free( idl ); + return( NULL ); + } + + if ( idl == NULL ) { + idl = tmp; + } else { + tmp2 = idl; + idl = idl_intersection( be, idl, tmp ); + idl_free( tmp ); + idl_free( tmp2 ); + } } } @@ -303,7 +306,7 @@ static ID_BLOCK * substring_comp_candidates( Backend *be, char *type, - char *val, + struct berval *bv, int prepost ) { @@ -311,10 +314,12 @@ substring_comp_candidates( ID_BLOCK *idl, *tmp, *tmp2; char *p; char buf[SUBLEN + 1]; + char *val; Debug( LDAP_DEBUG_TRACE, "=> substring_comp_candidates\n", 0, 0, 0 ); - len = strlen( val ); + val = bv->bv_val; + len = bv->bv_len; idl = NULL; /* prepend ^ for initial substring */ diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 35604cf6b9..ad0aed6461 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -229,7 +229,8 @@ get_substring_filter( ber_tag_t tag; ber_len_t len; ber_tag_t rc; - char *val, *last; + struct berval *val; + char *last; int syntax; Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 ); @@ -237,73 +238,107 @@ get_substring_filter( if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) { return( -1 ); } + attr_normalize( f->f_sub_type ); + + /* should get real syntax and see if we have a substring matching rule */ syntax = attr_syntax( f->f_sub_type ); + f->f_sub_initial = NULL; f->f_sub_any = NULL; f->f_sub_final = NULL; - *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 ); - sprintf( *fstr, "(%s=", f->f_sub_type ); + if( fstr ) { + *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 ); + sprintf( *fstr, "(%s=", f->f_sub_type ); + } + for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { - rc = ber_scanf( ber, "a", &val ); + rc = ber_scanf( ber, "O", &val ); if ( rc == LBER_ERROR ) { return( -1 ); } - if ( val == NULL || *val == '\0' ) { - if ( val != NULL ) { - free( val ); - } + if ( val == NULL || val->bv_len == 0 ) { + ber_bvfree( val ); return( LDAP_INVALID_SYNTAX ); } - value_normalize( val, syntax ); + + /* we should call a substring syntax normalization routine */ + value_normalize( val->bv_val, syntax ); + + /* this is bogus, value_normalize should take a berval */ + val->bv_len = strlen( val->bv_val ); switch ( tag ) { case LDAP_SUBSTRING_INITIAL: Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 ); if ( f->f_sub_initial != NULL ) { - return( LDAP_PROTOCOL_ERROR ); + ber_bvfree( val ); + goto return_error; } f->f_sub_initial = val; - *fstr = ch_realloc( *fstr, strlen( *fstr ) + - strlen( val ) + 1 ); - strcat( *fstr, val ); + + if( fstr ) { + *fstr = ch_realloc( *fstr, + strlen( *fstr ) + val->bv_len + 1 ); + strcat( *fstr, val->bv_val ); + } break; case LDAP_SUBSTRING_ANY: Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 ); - charray_add( &f->f_sub_any, val ); - *fstr = ch_realloc( *fstr, strlen( *fstr ) + - strlen( val ) + 2 ); - strcat( *fstr, "*" ); - strcat( *fstr, val ); + charray_add( (char ***) &f->f_sub_any, (char *) val ); + + if( fstr ) { + *fstr = ch_realloc( *fstr, + strlen( *fstr ) + val->bv_len + 2 ); + strcat( *fstr, "*" ); + strcat( *fstr, val->bv_val ); + } break; case LDAP_SUBSTRING_FINAL: Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 ); if ( f->f_sub_final != NULL ) { - return( LDAP_PROTOCOL_ERROR ); + ber_bvfree( val ); + goto return_error; } f->f_sub_final = val; - *fstr = ch_realloc( *fstr, strlen( *fstr ) + - strlen( val ) + 2 ); - strcat( *fstr, "*" ); - strcat( *fstr, val ); + + if( fstr ) { + *fstr = ch_realloc( *fstr, + strlen( *fstr ) + val->bv_len + 2 ); + strcat( *fstr, "*" ); + strcat( *fstr, val->bv_val ); + } break; default: Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0, 0 ); +return_error: + if( fstr ) { + free( *fstr ); + *fstr = NULL; + } + + ch_free( f->f_sub_type ); + ber_bvfree( f->f_sub_initial ); + ber_bvecfree( f->f_sub_any ); + ber_bvfree( f->f_sub_final ); return( LDAP_PROTOCOL_ERROR ); } } - *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 ); - if ( f->f_sub_final == NULL ) { - strcat( *fstr, "*" ); + + if( fstr ) { + *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 ); + if ( f->f_sub_final == NULL ) { + strcat( *fstr, "*" ); + } + strcat( *fstr, ")" ); } - strcat( *fstr, ")" ); Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 ); return( LDAP_SUCCESS ); @@ -331,11 +366,11 @@ filter_free( Filter *f ) free( f->f_sub_type ); } if ( f->f_sub_initial != NULL ) { - free( f->f_sub_initial ); + ber_bvfree( f->f_sub_initial ); } - charray_free( f->f_sub_any ); + ber_bvecfree( f->f_sub_any ); if ( f->f_sub_final != NULL ) { - free( f->f_sub_final ); + ber_bvfree( f->f_sub_final ); } break; @@ -398,16 +433,15 @@ filter_print( Filter *f ) case LDAP_FILTER_SUBSTRINGS: fprintf( stderr, "(%s=", f->f_sub_type ); if ( f->f_sub_initial != NULL ) { - fprintf( stderr, "%s", f->f_sub_initial ); + fprintf( stderr, "%s", f->f_sub_initial->bv_val ); } if ( f->f_sub_any != NULL ) { for ( i = 0; f->f_sub_any[i] != NULL; i++ ) { - fprintf( stderr, "*%s", f->f_sub_any[i] ); + fprintf( stderr, "*%s", f->f_sub_any[i]->bv_val ); } } - charray_free( f->f_sub_any ); if ( f->f_sub_final != NULL ) { - fprintf( stderr, "*%s", f->f_sub_final ); + fprintf( stderr, "*%s", f->f_sub_final->bv_val ); } break; diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index c1abb4555d..f1c54dbbfc 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -358,38 +358,38 @@ test_substring_filter( strcpy( p, "^" ); p = strchr( p, '\0' ); /* 2 * in case every char is special */ - if ( p + 2 * strlen( f->f_sub_initial ) > end ) { + if ( p + 2 * f->f_sub_initial->bv_len > end ) { Debug( LDAP_DEBUG_ANY, "not enough pattern space\n", 0, 0, 0 ); return( -1 ); } - strcpy_regex( p, f->f_sub_initial ); + strcpy_regex( p, f->f_sub_initial->bv_val ); p = strchr( p, '\0' ); } if ( f->f_sub_any != NULL ) { for ( i = 0; f->f_sub_any[i] != NULL; i++ ) { /* ".*" + value */ - if ( p + 2 * strlen( f->f_sub_any[i] ) + 2 > end ) { + if ( p + 2 * f->f_sub_any[i]->bv_len + 2 > end ) { Debug( LDAP_DEBUG_ANY, "not enough pattern space\n", 0, 0, 0 ); return( -1 ); } strcpy( p, ".*" ); p = strchr( p, '\0' ); - strcpy_regex( p, f->f_sub_any[i] ); + strcpy_regex( p, f->f_sub_any[i]->bv_val ); p = strchr( p, '\0' ); } } if ( f->f_sub_final != NULL ) { /* ".*" + value */ - if ( p + 2 * strlen( f->f_sub_final ) + 2 > end ) { + if ( p + 2 * f->f_sub_final->bv_len + 2 > end ) { Debug( LDAP_DEBUG_ANY, "not enough pattern space\n", 0, 0, 0 ); return( -1 ); } strcpy( p, ".*" ); p = strchr( p, '\0' ); - strcpy_regex( p, f->f_sub_final ); + strcpy_regex( p, f->f_sub_final->bv_val ); p = strchr( p, '\0' ); strcpy( p, "$" ); } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 2b5150f79b..d6f8023f1b 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -449,18 +449,22 @@ LIBSLAPD_F (Syntax *) syn_find LDAP_P((const char *synname)); LIBSLAPD_F (Syntax *) syn_find_desc LDAP_P((const char *syndesc, int *slen)); LIBSLAPD_F (int) syn_add LDAP_P((LDAP_SYNTAX *syn, slap_syntax_validate_func *validate, - slap_syntax_normalize_func *normalize, + slap_syntax_transform_func *ber2str, + slap_syntax_transform_func *str2ber, const char **err)); LIBSLAPD_F (MatchingRule *) mr_find LDAP_P((const char *mrname)); LIBSLAPD_F (int) mr_add LDAP_P((LDAP_MATCHING_RULE *mr, + slap_mr_normalize_func *normalize, slap_mr_match_func *match, const char **err)); LIBSLAPD_F (int) register_syntax LDAP_P((char *desc, slap_syntax_validate_func *validate, - slap_syntax_normalize_func *normalize )); + slap_syntax_transform_func *ber2str, + slap_syntax_transform_func *str2ber )); LIBSLAPD_F (int) register_matching_rule LDAP_P((char * desc, + slap_mr_normalize_func *normalize, slap_mr_match_func *match )); LIBSLAPD_F (void) schema_info LDAP_P((Connection *conn, Operation *op, diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index 12c30af94e..515dc35d26 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -651,7 +651,8 @@ int syn_add( LDAP_SYNTAX *syn, slap_syntax_validate_func *validate, - slap_syntax_normalize_func *normalize, + slap_syntax_transform_func *ber2str, + slap_syntax_transform_func *str2ber, const char **err ) { @@ -660,8 +661,11 @@ syn_add( ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) ); memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX)); + ssyn->ssyn_validate = validate; - ssyn->ssyn_normalize = normalize; + ssyn->ssyn_ber2str = ber2str; + ssyn->ssyn_str2ber = str2ber; + code = syn_insert(ssyn,err); return code; } @@ -759,6 +763,7 @@ mr_insert( int mr_add( LDAP_MATCHING_RULE *mr, + slap_mr_normalize_func *normalize, slap_mr_match_func *match, const char **err ) @@ -769,7 +774,10 @@ mr_add( smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) ); memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE)); + + smr->smr_normalize = normalize; smr->smr_match = match; + if ( smr->smr_syntax_oid ) { if ( (syn = syn_find(smr->smr_syntax_oid)) ) { smr->smr_syntax = syn; @@ -786,20 +794,24 @@ mr_add( } static int -octetStringValidate( struct berval *val ) +octetStringValidate( + Syntax *syntax, + struct berval *in ) { /* any value allowed */ return 0; } static int -UTF8StringValidate( struct berval *val ) +UTF8StringValidate( + Syntax *syntax, + struct berval *in ) { ber_len_t count; int len; - unsigned char *u = val->bv_val; + unsigned char *u = in->bv_val; - for( count = val->bv_len; count > 0; count+=len, u+=len ) { + for( count = in->bv_len; count > 0; count+=len, u+=len ) { /* get the length indicated by the first byte */ len = LDAP_UTF8_CHARLEN( u ); @@ -818,9 +830,10 @@ UTF8StringValidate( struct berval *val ) static int UTF8StringNormalize( + Syntax *syntax, + MatchingRule *mr, struct berval *val, - struct berval **normalized -) + struct berval **normalized ) { struct berval *newval; char *p, *q, *s; @@ -894,9 +907,11 @@ UTF8StringNormalize( } static int -IA5StringValidate( struct berval *val ) +IA5StringValidate( + Syntax *syntax, + struct berval *val ) { - int i; + ber_len_t i; for(i=0; i < val->bv_len; i++) { if( !isascii(val->bv_val[i]) ) return -1; @@ -907,9 +922,10 @@ IA5StringValidate( struct berval *val ) static int IA5StringNormalize( + Syntax *syntax, + MatchingRule *mr, struct berval *val, - struct berval **normalized -) + struct berval **normalized ) { struct berval *newval; char *p, *q; @@ -975,27 +991,30 @@ IA5StringNormalize( static int caseExactIA5Match( - struct berval *val1, - struct berval *val2 -) + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + struct berval *assertedValue ) { - return strcmp( val1->bv_val, val2->bv_val ); + return strcmp( value->bv_val, assertedValue->bv_val ); } static int caseIgnoreIA5Match( - struct berval *val1, - struct berval *val2 -) + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + struct berval *assertedValue ) { - return strcasecmp( val1->bv_val, val2->bv_val ); + return strcasecmp( value->bv_val, assertedValue->bv_val ); } int register_syntax( char * desc, slap_syntax_validate_func *validate, - slap_syntax_normalize_func *normalize ) + slap_syntax_transform_func *ber2str, + slap_syntax_transform_func *str2ber ) { LDAP_SYNTAX *syn; int code; @@ -1007,18 +1026,21 @@ register_syntax( ldap_scherr2str(code), err, desc ); return( -1 ); } - code = syn_add( syn, validate, normalize, &err ); + + code = syn_add( syn, validate, ber2str, str2ber, &err ); if ( code ) { Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n", scherr2str(code), err, desc ); return( -1 ); } + return( 0 ); } int register_matching_rule( char * desc, + slap_mr_normalize_func *normalize, slap_mr_match_func *match ) { LDAP_MATCHING_RULE *mr; @@ -1031,7 +1053,8 @@ register_matching_rule( ldap_scherr2str(code), err, desc ); return( -1 ); } - code = mr_add( mr, match, &err ); + + code = mr_add( mr, normalize, match, &err ); if ( code ) { Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n", scherr2str(code), err, desc ); @@ -1043,98 +1066,100 @@ register_matching_rule( struct syntax_defs_rec { char *sd_desc; slap_syntax_validate_func *sd_validate; - slap_syntax_normalize_func *sd_normalize; + slap_syntax_transform_func *sd_ber2str; + slap_syntax_transform_func *sd_str2ber; }; struct syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )", - UTF8StringValidate, UTF8StringNormalize}, + UTF8StringValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )", - IA5StringValidate, IA5StringNormalize}, + IA5StringValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )", - octetStringValidate, NULL}, + octetStringValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )", - NULL, NULL}, + NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )", - NULL, NULL}, + NULL, NULL, NULL}, {NULL, NULL, NULL} }; struct mrule_defs_rec { char *mrd_desc; + slap_mr_normalize_func *mrd_normalize; slap_mr_match_func *mrd_match; }; @@ -1166,6 +1191,7 @@ struct mrule_defs_rec { */ /* recycled matching functions */ +#define stringNormalize IA5StringNormalize #define caseIgnoreMatch caseIgnoreIA5Match #define caseExactMatch caseExactIA5Match @@ -1196,110 +1222,110 @@ struct mrule_defs_rec { struct mrule_defs_rec mrule_defs[] = { {"( 2.5.13.0 NAME 'objectIdentifierMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", - objectIdentifierMatch}, + NULL, objectIdentifierMatch}, {"( 2.5.13.1 NAME 'distinguishedNameMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", - distinguishedNameMatch}, + NULL, distinguishedNameMatch}, {"( 2.5.13.2 NAME 'caseIgnoreMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - caseIgnoreMatch}, + stringNormalize, caseIgnoreMatch}, {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - caseIgnoreOrderingMatch}, + stringNormalize, caseIgnoreOrderingMatch}, {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - caseIgnoreSubstringsMatch}, + stringNormalize, caseIgnoreSubstringsMatch}, /* Next three are not in the RFC's, but are needed for compatibility */ {"( 2.5.13.5 NAME 'caseExactMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - caseExactMatch}, + stringNormalize, caseExactMatch}, {"( 2.5.13.6 NAME 'caseExactOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - caseExactOrderingMatch}, + stringNormalize, caseExactOrderingMatch}, {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - caseExactSubstringsMatch}, + stringNormalize, caseExactSubstringsMatch}, {"( 2.5.13.8 NAME 'numericStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", - numericStringMatch}, + NULL, numericStringMatch}, {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - numericStringSubstringsMatch}, + NULL, numericStringSubstringsMatch}, {"( 2.5.13.11 NAME 'caseIgnoreListMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", - caseIgnoreListMatch}, + NULL, caseIgnoreListMatch}, {"( 2.5.13.14 NAME 'integerMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - integerMatch}, + NULL, integerMatch}, {"( 2.5.13.16 NAME 'bitStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", - bitStringMatch}, + NULL, bitStringMatch}, {"( 2.5.13.17 NAME 'octetStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", - octetStringMatch}, + NULL, octetStringMatch}, {"( 2.5.13.20 NAME 'telephoneNumberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", - telephoneNumberMatch}, + NULL, telephoneNumberMatch}, {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - telephoneNumberSubstringsMatch}, + NULL, telephoneNumberSubstringsMatch}, {"( 2.5.13.22 NAME 'presentationAddressMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )", - presentationAddressMatch}, + NULL, presentationAddressMatch}, {"( 2.5.13.23 NAME 'uniqueMemberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", - uniqueMemberMatch}, + NULL, uniqueMemberMatch}, {"( 2.5.13.24 NAME 'protocolInformationMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", - protocolInformationMatch}, + NULL, protocolInformationMatch}, {"( 2.5.13.27 NAME 'generalizedTimeMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - generalizedTimeMatch}, + NULL, generalizedTimeMatch}, {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - generalizedTimeOrderingMatch}, + NULL, generalizedTimeOrderingMatch}, {"( 2.5.13.29 NAME 'integerFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - integerFirstComponentMatch}, + NULL, integerFirstComponentMatch}, {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", - objectIdentifierFirstComponentMatch}, + NULL, objectIdentifierFirstComponentMatch}, {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - caseExactIA5Match}, + IA5StringNormalize, caseExactIA5Match}, {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - caseIgnoreIA5Match}, + IA5StringNormalize, caseIgnoreIA5Match}, {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - caseIgnoreIA5SubstringsMatch}, + IA5StringNormalize, caseIgnoreIA5SubstringsMatch}, - {NULL, NULL} + {NULL, NULL, NULL} }; int @@ -1316,7 +1342,8 @@ schema_init( void ) for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) { res = register_syntax( syntax_defs[i].sd_desc, syntax_defs[i].sd_validate, - syntax_defs[i].sd_normalize ); + syntax_defs[i].sd_ber2str, + syntax_defs[i].sd_str2ber ); if ( res ) { fprintf( stderr, "schema_init: Error registering syntax %s\n", @@ -1327,6 +1354,7 @@ schema_init( void ) for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { res = register_matching_rule( mrule_defs[i].mrd_desc, + mrule_defs[i].mrd_normalize, mrule_defs[i].mrd_match ); if ( res ) { diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c index 48249d3f75..848456cf3c 100644 --- a/servers/slapd/schemaparse.c +++ b/servers/slapd/schemaparse.c @@ -187,16 +187,16 @@ find_oidm(char *oid) /* OID macros must start alpha */ if ( !isdigit( *oid ) ) { - for (om = om_list; om; om=om->next) + for (om = om_list; om; om=om->som_next) { - if ((pos = dscompare(om->name, oid, ':'))) + if ((pos = dscompare(om->som_name, oid, ':'))) { suflen = strlen(oid + pos); - new = ch_calloc(1, om->oidlen + suflen + 1); - strcpy(new, om->oid); + new = ch_calloc(1, om->som_oidlen + suflen + 1); + strcpy(new, om->som_oid); if (suflen) { - suflen = om->oidlen; + suflen = om->som_oidlen; new[suflen++] = '.'; strcpy(new+suflen, oid+pos+1); } @@ -218,24 +218,27 @@ parse_oidm( { OidMacro *om; - if (argc != 3) - { -usage: fprintf( stderr, "ObjectIdentifier \n"); + if (argc != 3) { +usage: fprintf( stderr, "ObjectIdentifier \n"); exit( EXIT_FAILURE ); } + om = (OidMacro *) ch_malloc( sizeof(OidMacro) ); - om->name = ch_strdup( argv[1] ); - om->oid = find_oidm( argv[2] ); - if (!om->oid) - { + om->som_name = ch_strdup( argv[1] ); + om->som_oid = find_oidm( argv[2] ); + + if (!om->som_oid) { fprintf( stderr, "%s: line %d: OID %s not recognized\n", fname, lineno, argv[2] ); goto usage; } - if (om->oid == argv[2]) - om->oid = ch_strdup( argv[2] ); - om->oidlen = strlen( om->oid ); - om->next = om_list; + + if (om->som_oid == argv[2]) { + om->som_oid = ch_strdup( argv[2] ); + } + + om->som_oidlen = strlen( om->som_oid ); + om->som_next = om_list; om_list = om; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index f96e38d787..632adfa193 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -109,42 +109,67 @@ LIBSLAPD_F (int) slap_debug; #define SLAP_SCHERR_MR_INCOMPLETE 12 typedef struct slap_oid_macro { - struct slap_oid_macro *next; - char *name; - char *oid; - int oidlen; + char *som_name; + char *som_oid; + int som_oidlen; + struct slap_oid_macro *som_next; } OidMacro; +/* forward declarations */ +struct slap_syntax; +struct slap_matching_rule; + + typedef int slap_syntax_validate_func LDAP_P(( + struct slap_syntax *syntax, struct berval * in)); -typedef int slap_syntax_normalize_func LDAP_P(( +typedef int slap_syntax_transform_func LDAP_P(( + struct slap_syntax *syntax, struct berval * in, struct berval ** out)); typedef struct slap_syntax { LDAP_SYNTAX ssyn_syn; + int ssyn_flags; + slap_syntax_validate_func *ssyn_validate; - slap_syntax_normalize_func *ssyn_normalize; + + /* convert to and from binary */ + slap_syntax_transform_func *ssyn_ber2str; + slap_syntax_transform_func *ssyn_str2ber; + struct slap_syntax *ssyn_next; #define ssyn_oid ssyn_syn.syn_oid #define ssyn_desc ssyn_syn.syn_desc } Syntax; + +/* Normalizer */ +typedef int slap_mr_normalize_func LDAP_P(( + struct slap_syntax *syntax, /* NULL if in is asserted value */ + struct slap_matching_rule *mr, + struct berval * in, + struct berval ** out )); + +/* Match (compare) function */ typedef int slap_mr_match_func LDAP_P(( - struct berval * atval, - struct berval * matchval)); + struct slap_syntax *syntax, /* syntax of stored value */ + struct slap_matching_rule *mr, + struct berval * value, + struct berval * assertValue )); typedef struct slap_matching_rule { LDAP_MATCHING_RULE smr_mrule; + slap_mr_normalize_func *smr_normalize; slap_mr_match_func *smr_match; - Syntax *smr_syntax; + Syntax *smr_syntax; struct slap_matching_rule *smr_next; #define smr_oid smr_mrule.mr_oid #define smr_names smr_mrule.mr_names #define smr_desc smr_mrule.mr_desc -#define smr_obsolete smr_mrule.mr_obsolete -#define smr_syntax_oid smr_mrule.mr_syntax_oid +#define smr_obsolete smr_mrule.mr_obsolete +#define smr_syntax_oid smr_mrule.mr_syntax_oid } MatchingRule; typedef struct slap_attribute_type { @@ -200,18 +225,21 @@ struct replog_moddn { }; /* - * represents an attribute value assertion (i.e., attr=value) + * represents an attribute value assertion (i.e., attr;option=value) */ typedef struct slap_ava { char *ava_type; /* attribute description */ struct berval ava_value; } Ava; +/* + * represents an matching rule assertion + */ typedef struct slap_mra { char *mra_rule; char *mra_type; /* attribute description */ - char *mra_value; int mra_dnattrs; + struct berval *mra_value; } Mra; /* @@ -236,9 +264,10 @@ typedef struct slap_filter { /* substrings */ struct sub { char *f_un_sub_type; - char *f_un_sub_initial; - char **f_un_sub_any; - char *f_un_sub_final; + + struct berval *f_un_sub_initial; + struct berval **f_un_sub_any; + struct berval *f_un_sub_final; } f_un_sub; } f_un; diff --git a/servers/slapd/str2filter.c b/servers/slapd/str2filter.c index cc98593519..f0e332b4c8 100644 --- a/servers/slapd/str2filter.c +++ b/servers/slapd/str2filter.c @@ -211,19 +211,25 @@ str2subvals( char *val, Filter *f ) Debug( LDAP_DEBUG_FILTER, "str2subvals \"%s\"\n", val, 0, 0 ); + if( val == NULL ) return 0; + val = freeme = ch_strdup( val ); gotstar = 0; - while ( val != NULL && *val ) { + + while ( *val ) { if ( (nextstar = ldap_pvt_find_wildcard( val )) != NULL ) *nextstar++ = '\0'; ldap_pvt_filter_value_unescape( val ); + if ( gotstar == 0 ) { - f->f_sub_initial = ch_strdup( val ); + f->f_sub_initial = ber_bvstrdup( val ); + } else if ( nextstar == NULL ) { - f->f_sub_final = ch_strdup( val ); + f->f_sub_final = ber_bvstrdup( val ); + } else { - charray_add( &f->f_sub_any, val ); + charray_add( (char ***) &f->f_sub_any, (char *) ber_bvstrdup( val ) ); } gotstar = 1; -- 2.39.5