From 07576218515e4089933984d348290f19592af0c0 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sun, 1 Sep 2002 06:01:22 +0000 Subject: [PATCH] match rule uses and other misc stuff from HEAD --- servers/slapd/at.c | 36 +++++ servers/slapd/filter.c | 49 +------ servers/slapd/filterentry.c | 16 +-- servers/slapd/matchedValues.c | 10 +- servers/slapd/modify.c | 6 +- servers/slapd/mr.c | 246 +++++++++++++++++++++++++++++++--- servers/slapd/mra.c | 57 +------- servers/slapd/proto-slap.h | 14 +- servers/slapd/result.c | 17 +-- servers/slapd/schema.c | 32 +++++ servers/slapd/schema_init.c | 94 +++++++------ servers/slapd/schema_prep.c | 17 ++- servers/slapd/slap.h | 53 +++++++- servers/slapd/syntax.c | 5 + 14 files changed, 453 insertions(+), 199 deletions(-) diff --git a/servers/slapd/at.c b/servers/slapd/at.c index ef73fe7b45..1abda507ac 100644 --- a/servers/slapd/at.c +++ b/servers/slapd/at.c @@ -208,6 +208,42 @@ at_destroy( void ) ad_destroy(slap_schema.si_at_undefined->sat_ad); } +int +at_start( AttributeType **at ) +{ + assert( at ); + + *at = attr_list; + + return (*at != NULL); +} + +int +at_next( AttributeType **at ) +{ + assert( at ); + +#if 1 /* pedantic check */ + { + AttributeType *tmp; + + for ( tmp = attr_list; tmp; tmp = tmp->sat_next ) { + if ( tmp == *at ) { + break; + } + } + + assert( tmp ); + } +#endif + + *at = (*at)->sat_next; + + return (*at != NULL); +} + + + static int at_insert( AttributeType *sat, diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 608b732c84..4582be62bb 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -70,7 +70,7 @@ get_filter( * lessOrEqual [6] AttributeValueAssertion, * present [7] AttributeType,, * approxMatch [8] AttributeValueAssertion - * extensibleMatch [9] MatchingRuleAssertion + * extensibleMatch [9] MatchingRuleAssertion * } * * SubstringFilter ::= SEQUENCE { @@ -742,24 +742,9 @@ filter2bv( Filter *f, struct berval *fstr ) break; - case LDAP_FILTER_EXT: - filter_escape_value( &f->f_mr_value, &tmp ); -#ifndef SLAP_X_MRA_MATCH_DNATTRS - fstr->bv_len = f->f_mr_desc->ad_cname.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 ) + - tmp.bv_len + ( sizeof("(:=)") - 1 ); - fstr->bv_val = malloc( fstr->bv_len + 1 ); - - snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)", - f->f_mr_desc->ad_cname.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 : "", - tmp.bv_val ); -#else /* SLAP_X_MRA_MATCH_DNATTRS */ - { + case LDAP_FILTER_EXT: { struct berval ad; + filter_escape_value( &f->f_mr_value, &tmp ); if ( f->f_mr_desc ) { ad = f->f_mr_desc->ad_cname; @@ -780,10 +765,8 @@ filter2bv( Filter *f, struct berval *fstr ) f->f_mr_rule_text.bv_len ? ":" : "", f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "", tmp.bv_val ); - } -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ ber_memfree( tmp.bv_val ); - break; + } break; case SLAPD_FILTER_COMPUTED: ber_str2bv( @@ -1308,25 +1291,9 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr ) f->f_desc->ad_cname.bv_val ); break; - case LDAP_FILTER_EXT: - filter_escape_value( &f->f_mr_value, &tmp ); - -#ifndef SLAP_X_MRA_MATCH_DNATTRS - fstr->bv_len = f->f_mr_desc->ad_cname.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 ) + - tmp.bv_len + ( sizeof("(:=)") - 1 ); - fstr->bv_val = malloc( fstr->bv_len + 1 ); - - snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)", - f->f_mr_desc->ad_cname.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 : "", - tmp.bv_val ); -#else /* SLAP_X_MRA_MATCH_DNATTRS */ - { + case LDAP_FILTER_EXT: { struct berval ad; + filter_escape_value( &f->f_mr_value, &tmp ); if ( f->f_mr_desc ) { ad = f->f_mr_desc->ad_cname; @@ -1347,11 +1314,9 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr ) f->f_mr_rule_text.bv_len ? ":" : "", f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "", tmp.bv_val ); - } -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ ber_memfree( tmp.bv_val ); - break; + } break; case SLAPD_FILTER_COMPUTED: ber_str2bv( diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index 111e258e61..82cd8cd327 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -215,13 +215,6 @@ static int test_mra_filter( { Attribute *a; -#ifndef SLAP_X_MRA_MATCH_DNATTRS - if( !access_allowed( be, conn, op, e, - mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) ) - { - return LDAP_INSUFFICIENT_ACCESS; - } -#else /* SLAP_X_MRA_MATCH_DNATTRS */ if ( mra->ma_desc ) { /* * if ma_desc is available, then we're filtering for @@ -233,7 +226,6 @@ static int test_mra_filter( { return LDAP_INSUFFICIENT_ACCESS; } -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ for(a = attrs_find( e->e_attrs, mra->ma_desc ); a != NULL; @@ -258,7 +250,6 @@ static int test_mra_filter( } } } -#ifdef SLAP_X_MRA_MATCH_DNATTRS } else { /* @@ -270,8 +261,7 @@ static int test_mra_filter( int rc; /* check if matching is appropriate */ - if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid, - a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) { + if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type )) { continue; } @@ -346,8 +336,7 @@ static int test_mra_filter( const char *text = NULL; /* check if matching is appropriate */ - if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid, - ad->ad_type->sat_syntax->ssyn_oid ) != 0 ) { + if ( !mr_usable_with_at( mra->ma_rule, ad->ad_type )) { continue; } @@ -382,7 +371,6 @@ static int test_mra_filter( } } } -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ return LDAP_COMPARE_FALSE; } diff --git a/servers/slapd/matchedValues.c b/servers/slapd/matchedValues.c index 51c223e97d..0d3986ae2b 100644 --- a/servers/slapd/matchedValues.c +++ b/servers/slapd/matchedValues.c @@ -358,16 +358,9 @@ test_mra_vrFilter( for ( i=0; a != NULL; a = a->a_next, i++ ) { struct berval *bv, value; -#ifndef SLAP_X_MRA_MATCH_DNATTRS - if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) { - return( LDAP_SUCCESS ); - } - value = mra->ma_value; - -#else /* SLAP_X_MRA_MATCH_DNATTRS */ if ( mra->ma_desc ) { if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) { - return( LDAP_SUCCESS ); + continue; } value = mra->ma_value; @@ -389,7 +382,6 @@ test_mra_vrFilter( } } -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) { int ret; diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index d0b81b15c7..799aefee93 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -547,8 +547,8 @@ int slap_mods_opattrs( char *textbuf, size_t textlen ) { struct berval name, timestamp, csn; - char timebuf[22]; - char csnbuf[64]; + char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; Modifications *mod; int mop = op->o_tag == LDAP_REQ_ADD @@ -603,7 +603,7 @@ int slap_mods_opattrs( } if( SLAP_LASTMOD(be) ) { - char uuidbuf[40]; + char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) ); tmpval.bv_val = uuidbuf; diff --git a/servers/slapd/mr.c b/servers/slapd/mr.c index ee69d0b535..701c646c18 100644 --- a/servers/slapd/mr.c +++ b/servers/slapd/mr.c @@ -23,6 +23,7 @@ struct mindexrec { static Avlnode *mr_index = NULL; static MatchingRule *mr_list = NULL; +static MatchingRuleUse *mru_list = NULL; static int mr_index_cmp( @@ -76,6 +77,7 @@ mr_destroy( void ) avl_free(mr_index, ldap_memfree); for (m=mr_list; m; m=n) { n = m->smr_next; + ch_free( m->smr_str.bv_val ); ldap_matchingrule_free((LDAPMatchingRule *)m); } } @@ -144,13 +146,38 @@ mr_add( { MatchingRule *smr; Syntax *syn; + Syntax **compat_syn = NULL; int code; + if( def->mrd_compat_syntaxes ) { + int i; + for( i=0; def->mrd_compat_syntaxes[i]; i++ ) { + /* just count em */ + } + + compat_syn = ch_malloc( sizeof(Syntax *) * (i+1) ); + + for( i=0; def->mrd_compat_syntaxes[i]; i++ ) { + compat_syn[i] = syn_find( def->mrd_compat_syntaxes[i] ); + if( compat_syn[i] == NULL ) { + return SLAP_SCHERR_SYN_NOT_FOUND; + } + } + + compat_syn[i] = NULL; + } + smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) ); AC_MEMCPY( &smr->smr_mrule, mr, sizeof(LDAPMatchingRule)); + /* + * note: smr_bvoid uses the same memory of smr_mrule.mr_oid; + * smr_oidlen is #defined as smr_bvoid.bv_len + */ + smr->smr_bvoid.bv_val = smr->smr_mrule.mr_oid; smr->smr_oidlen = strlen( mr->mr_oid ); smr->smr_usage = def->mrd_usage; + smr->smr_compat_syntaxes = compat_syn; smr->smr_convert = def->mrd_convert; smr->smr_normalize = def->mrd_normalize; smr->smr_match = def->mrd_match; @@ -173,7 +200,6 @@ mr_add( return code; } - int register_matching_rule( slap_mrule_defs_rec *def ) @@ -183,7 +209,9 @@ register_matching_rule( int code; const char *err; - if( def->mrd_usage == SLAP_MR_NONE ) { + if( def->mrd_usage == SLAP_MR_NONE && + def->mrd_compat_syntaxes == NULL ) + { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "register_matching_rule: %s not usable\n", def->mrd_desc, 0, 0 ); @@ -205,7 +233,8 @@ register_matching_rule( #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "register_matching_rule: could not locate associated " - "matching rule %s for %s\n", def->mrd_associated, def->mrd_desc, 0 ); + "matching rule %s for %s\n", + def->mrd_associated, def->mrd_desc, 0 ); #else Debug( LDAP_DEBUG_ANY, "register_matching_rule: could not locate " "associated matching rule %s for %s\n", @@ -215,17 +244,18 @@ register_matching_rule( return -1; } #endif - } - mr = ldap_str2matchingrule( def->mrd_desc, &code, &err, LDAP_SCHEMA_ALLOW_ALL); + mr = ldap_str2matchingrule( def->mrd_desc, &code, &err, + LDAP_SCHEMA_ALLOW_ALL ); if ( !mr ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "register_matching_rule: %s before %s in %s.\n", ldap_scherr2str(code), err, def->mrd_desc ); #else - Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n", + Debug( LDAP_DEBUG_ANY, + "Error in register_matching_rule: %s before %s in %s\n", ldap_scherr2str(code), err, def->mrd_desc ); #endif @@ -242,7 +272,8 @@ register_matching_rule( "register_matching_rule: %s for %s in %s.\n", scherr2str(code), err, def->mrd_desc ); #else - Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s for %s in %s\n", + Debug( LDAP_DEBUG_ANY, + "Error in register_matching_rule: %s for %s in %s\n", scherr2str(code), err, def->mrd_desc ); #endif @@ -252,18 +283,178 @@ register_matching_rule( return( 0 ); } +void +mru_destroy( void ) +{ + MatchingRuleUse *m, *n; + + for (m=mru_list; m; m=n) { + n = m->smru_next; + if ( m->smru_str.bv_val ) { + ch_free( m->smru_str.bv_val ); + } + /* memory borrowed from m->smru_mr */ + m->smru_oid = NULL; + m->smru_names = NULL; + m->smru_desc = NULL; + + /* free what's left (basically + * smru_mruleuse.mru_applies_oids) */ + ldap_matchingruleuse_free((LDAPMatchingRuleUse *)m); + } +} + +int +matching_rule_use_init( void ) +{ + MatchingRule *mr; + MatchingRuleUse **mru_ptr = &mru_list; + +#define MR_TYPE_MASK ( SLAP_MR_TYPE_MASK & ~SLAP_MR_EXT ) +#define MR_TYPE_SUBTYPE_MASK ( MR_TYPE_MASK | SLAP_MR_SUBTYPE_MASK ) +#if 0 /* all types regardless of EXT */ +#define MR_TYPE(x) ( (x) & MR_TYPE_MASK ) +#define MR_TYPE_SUBTYPE(x) ( (x) & MR_TYPE_SUBTYPE_MASK ) +#else /* only those marked as EXT (as per RFC 2252) */ +#define MR_TYPE(x) ( ( (x) & SLAP_MR_EXT ) ? ( (x) & MR_TYPE_MASK ) : SLAP_MR_NONE ) +#define MR_TYPE_SUBTYPE(x) ( ( (x) & SLAP_MR_EXT ) ? ( (x) & MR_TYPE_SUBTYPE_MASK ) : SLAP_MR_NONE ) +#endif + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, "matching_rule_use_init\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "matching_rule_use_init\n", 0, 0, 0 ); +#endif + + for ( mr = mr_list; mr; mr = mr->smr_next ) { + slap_mask_t um = MR_TYPE( mr->smr_usage ); + slap_mask_t usm = MR_TYPE_SUBTYPE( mr->smr_usage ); + + AttributeType *at; + MatchingRuleUse _mru, *mru = &_mru; + + char **applies_oids = NULL; + + mr->smr_mru = NULL; + + /* hide rules marked as HIDE */ + if ( mr->smr_usage & SLAP_MR_HIDE ) { + continue; + } + + /* hide rules not marked as designed for extensibility */ + /* MR_EXT means can be used any attribute type whose + * syntax is same as the assertion syntax. + * Another mechanism is needed where rule can be used + * with attribute of other syntaxes. + * Framework doesn't support this (yet). + */ + + if (!( ( mr->smr_usage & SLAP_MR_EXT ) + || mr->smr_compat_syntaxes ) ) + { + continue; + } + + memset( mru, 0, sizeof( MatchingRuleUse ) ); + + /* + * Note: we're using the same values of the corresponding + * MatchingRule structure; maybe we'd copy them ... + */ + mru->smru_mr = mr; + mru->smru_obsolete = mr->smr_obsolete; + mru->smru_applies_oids = NULL; + mru->smru_next = NULL; + mru->smru_oid = mr->smr_oid; + mru->smru_names = mr->smr_names; + mru->smru_desc = mr->smr_desc; + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, " %s (%s): ", + mru->smru_oid, + mru->smru_names ? mru->smru_names[ 0 ] : "", 0 ); +#else + Debug( LDAP_DEBUG_TRACE, " %s (%s): ", + mru->smru_oid, + mru->smru_names ? mru->smru_names[ 0 ] : "", 0 ); +#endif + + at = NULL; + for ( at_start( &at ); at; at_next( &at ) ) { + if( at->sat_flags & SLAP_AT_HIDE ) continue; + + if( mr_usable_with_at( mr, at )) { + ldap_charray_add( &applies_oids, at->sat_cname.bv_val ); + } + } + + /* + * Note: the matchingRules that are not used + * by any attributeType are not listed as + * matchingRuleUse + */ + if ( applies_oids != NULL ) { + mru->smru_applies_oids = applies_oids; +#ifdef NEW_LOGGING + { + char *str = ldap_matchingruleuse2str( &mru->smru_mruleuse ); + LDAP_LOG( OPERATION, INFO, "matchingRuleUse: %s\n", str, 0, 0 ); + ldap_memfree( str ); + } +#else + { + char *str = ldap_matchingruleuse2str( &mru->smru_mruleuse ); + Debug( LDAP_DEBUG_TRACE, "matchingRuleUse: %s\n", str, 0, 0 ); + ldap_memfree( str ); + } +#endif + + mru = (MatchingRuleUse *)ber_memalloc( sizeof( MatchingRuleUse ) ); + /* call-forward from MatchingRule to MatchingRuleUse */ + mr->smr_mru = mru; + /* copy static data to newly allocated struct */ + *mru = _mru; + /* append the struct pointer to the end of the list */ + *mru_ptr = mru; + /* update the list head pointer */ + mru_ptr = &mru->smru_next; + } + } + + return( 0 ); +} + +int mr_usable_with_at( + MatchingRule *mr, + AttributeType *at ) +{ + if( mr->smr_usage & SLAP_MR_EXT && ( + mr->smr_syntax == at->sat_syntax || + mr == at->sat_equality || mr == at->sat_approx ) ) + { + return 1; + } + + if ( mr->smr_compat_syntaxes ) { + int i; + for( i=0; mr->smr_compat_syntaxes[i]; i++ ) { + if( at->sat_syntax == mr->smr_compat_syntaxes[i] ) { + return 1; + } + } + } + return 0; +} #if defined( SLAPD_SCHEMA_DN ) int mr_schema_info( Entry *e ) { - struct berval vals[2]; MatchingRule *mr; AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules; - vals[1].bv_val = NULL; - for ( mr = mr_list; mr; mr = mr->smr_next ) { if ( mr->smr_usage & SLAP_MR_HIDE ) { /* skip hidden rules */ @@ -275,21 +466,44 @@ int mr_schema_info( Entry *e ) continue; } - if ( ldap_matchingrule2bv( &mr->smr_mrule, vals ) == NULL ) { - return -1; + if ( mr->smr_str.bv_val == NULL ) { + if ( ldap_matchingrule2bv( &mr->smr_mrule, &mr->smr_str ) == NULL ) { + return -1; + } } #if 0 - Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n", - (long) vals[0].bv_len, vals[0].bv_val, 0 ); + Debug( LDAP_DEBUG_TRACE, "Merging mr [%lu] %s\n", + mr->smr_str.bv_len, mr->smr_str.bv_val, 0 ); #endif - attr_merge( e, ad_matchingRules, vals ); - ldap_memfree( vals[0].bv_val ); + attr_merge_one( e, ad_matchingRules, &mr->smr_str ); } return 0; } int mru_schema_info( Entry *e ) { + MatchingRuleUse *mru; + + AttributeDescription *ad_matchingRuleUse + = slap_schema.si_ad_matchingRuleUse; + + for ( mru = mru_list; mru; mru = mru->smru_next ) { + + assert( !( mru->smru_usage & SLAP_MR_HIDE ) ); + + if ( mru->smru_str.bv_val == NULL ) { + if ( ldap_matchingruleuse2bv( &mru->smru_mruleuse, &mru->smru_str ) + == NULL ) { + return -1; + } + } + +#if 0 + Debug( LDAP_DEBUG_TRACE, "Merging mru [%lu] %s\n", + mru->smru_str.bv_len, mru->smru_str.bv_val, 0 ); +#endif + attr_merge_one( e, ad_matchingRuleUse, &mru->smru_str ); + } return 0; } diff --git a/servers/slapd/mra.c b/servers/slapd/mra.c index fbd3a6afa9..5276c546e6 100644 --- a/servers/slapd/mra.c +++ b/servers/slapd/mra.c @@ -170,28 +170,12 @@ get_mra( return SLAPD_DISCONNECT; } -#ifndef SLAP_X_MRA_MATCH_DNATTRS - /* - * Let's try to implement it - */ - if( ma->ma_dnattrs ) { - *text = "matching with \":dn\" not supported"; - return LDAP_INAPPROPRIATE_MATCHING; - } -#endif /* !SLAP_X_MRA_MATCH_DNATTRS */ - if( type.bv_val != NULL ) { rc = slap_bv2ad( &type, &ma->ma_desc, text ); if( rc != LDAP_SUCCESS ) { mra_free( ma, 1 ); return rc; } - -#ifndef SLAP_X_MRA_MATCH_DNATTRS - } else { - *text = "matching without attribute description rule not supported"; - return LDAP_INAPPROPRIATE_MATCHING; -#endif /* !SLAP_X_MRA_MATCH_DNATTRS */ } if( ma->ma_rule_text.bv_val != NULL ) { @@ -203,26 +187,15 @@ get_mra( } } - /* - * FIXME: is it correct that ma->ma_rule_text, if present, - * is looked-up, checked, and then replaced by the sat_equality - * of the given attribute? I'd rather do smtg like use - * the attribute's equality rule only if no matching rule - * was given, otherwise I don't see any extension ... - */ - -#if 1 if ( ma->ma_rule == NULL ) { -#ifdef SLAP_X_MRA_MATCH_DNATTRS /* * Need either type or rule ... */ if ( ma->ma_desc == NULL ) { mra_free( ma, 1 ); - *text = "matching rule not recognized"; + *text = "no matching rule or type"; return LDAP_INAPPROPRIATE_MATCHING; } -#endif /* !SLAP_X_MRA_MATCH_DNATTRS */ if ( ma->ma_desc->ad_type->sat_equality != NULL && ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT ) @@ -232,36 +205,16 @@ get_mra( ma->ma_rule = ma->ma_desc->ad_type->sat_equality; } else { + *text = "no appropriate rule to use for type"; mra_free( ma, 1 ); return LDAP_INAPPROPRIATE_MATCHING; } } -#else - if( ma->ma_desc != NULL && - ma->ma_desc->ad_type->sat_equality != NULL && - ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT ) - { - /* no matching rule was provided, use the attribute's - equality rule if it supports extensible matching. */ - ma->ma_rule = ma->ma_desc->ad_type->sat_equality; - } else { - mra_free( ma, 1 ); - return LDAP_INAPPROPRIATE_MATCHING; - } -#endif - -#ifdef SLAP_X_MRA_MATCH_DNATTRS if ( ma->ma_desc != NULL ) { -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ - /* check to see if the matching rule is appropriate for - the syntax of the attribute. This check will need - to be extended to support other kinds of extensible - matching rules */ - if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid, - ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) - { + if( !mr_usable_with_at( ma->ma_rule, ma->ma_desc->ad_type ) ) { mra_free( ma, 1 ); + *text = "matching rule use with this attribute not appropriate"; return LDAP_INAPPROPRIATE_MATCHING; } @@ -271,7 +224,6 @@ get_mra( */ rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY, &value, &ma->ma_value, text ); -#ifdef SLAP_X_MRA_MATCH_DNATTRS } else { /* * Need to normalize, but how? @@ -282,7 +234,6 @@ get_mra( } } -#endif /* SLAP_X_MRA_MATCH_DNATTRS */ if( rc != LDAP_SUCCESS ) { mra_free( ma, 1 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index f51f24a18b..db7d7ba9fa 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -115,6 +115,9 @@ LDAP_SLAPD_F (int) is_at_syntax LDAP_P(( AttributeType *at, const char *oid )); +LDAP_SLAPD_F (int) at_start LDAP_P(( AttributeType **at )); +LDAP_SLAPD_F (int) at_next LDAP_P(( AttributeType **at )); + /* * attr.c */ @@ -478,11 +481,6 @@ LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter )); * filterentry.c */ -/* - * define to enable dn components match in extended filter matching - */ -#define SLAP_X_MRA_MATCH_DNATTRS - LDAP_SLAPD_F (int) test_filter LDAP_P(( Backend *be, Connection *conn, Operation *op, Entry *e, Filter *f )); @@ -621,9 +619,15 @@ LDAP_SLAPD_F (void) mr_destroy LDAP_P(( void )); LDAP_SLAPD_F (int) register_matching_rule LDAP_P(( slap_mrule_defs_rec *def )); +LDAP_SLAPD_F (void) mru_destroy LDAP_P(( void )); +LDAP_SLAPD_F (int) matching_rule_use_init LDAP_P(( void )); + LDAP_SLAPD_F (int) mr_schema_info( Entry *e ); LDAP_SLAPD_F (int) mru_schema_info( Entry *e ); +LDAP_SLAPD_F (int) mr_usable_with_at( MatchingRule *mr, + AttributeType *at ); + /* * mra.c */ diff --git a/servers/slapd/result.c b/servers/slapd/result.c index ed5f85f782..863547f206 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -1207,21 +1207,22 @@ send_search_reference( #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "send_search_reference: conn %lu dn=\"%s\"\n", - op->o_connid, e->e_dn, 0 ); + op->o_connid, e ? e->e_dn : "(null)", 0 ); #else Debug( LDAP_DEBUG_TRACE, "=> send_search_reference: dn=\"%s\"\n", - e->e_dn, 0, 0 ); + e ? e->e_dn : "(null)", 0, 0 ); #endif - if ( ! access_allowed( be, conn, op, e, + if ( e && ! access_allowed( be, conn, op, e, ad_entry, NULL, ACL_READ, NULL ) ) { #ifdef NEW_LOGGING LDAP_LOG( ACL, INFO, "send_search_reference: conn %lu " - "access to entry %s not allowed\n", op->o_connid, e->e_dn, 0 ); + "access to entry %s not allowed\n", + op->o_connid, e->e_dn, 0 ); #else Debug( LDAP_DEBUG_ACL, "send_search_reference: access to entry not allowed\n", @@ -1231,7 +1232,7 @@ send_search_reference( return( 1 ); } - if ( ! access_allowed( be, conn, op, e, + if ( e && ! access_allowed( be, conn, op, e, ad_ref, NULL, ACL_READ, NULL ) ) { #ifdef NEW_LOGGING @@ -1252,11 +1253,11 @@ send_search_reference( #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "send_search_reference: conn %lu null ref in (%s).\n", - op->o_connid, e->e_dn, 0 ); + op->o_connid, e ? e->e_dn : "(null)", 0 ); #else Debug( LDAP_DEBUG_ANY, "send_search_reference: null ref in (%s)\n", - e->e_dn, 0, 0 ); + e ? e->e_dn : "(null)", 0, 0 ); #endif return( 1 ); @@ -1310,7 +1311,7 @@ send_search_reference( ldap_pvt_thread_mutex_unlock( &num_sent_mutex ); Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu REF dn=\"%s\"\n", - conn->c_connid, op->o_opid, e->e_dn, 0, 0 ); + conn->c_connid, op->o_opid, e ? e->e_dn : "(null)", 0, 0 ); #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index 874ace374c..452a679ff2 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -15,6 +15,7 @@ #include "slap.h" #include "ldap_pvt.h" +#include "lutil.h" #if defined( SLAPD_SCHEMA_DN ) @@ -26,6 +27,10 @@ schema_info( Entry **entry, const char **text ) = slap_schema.si_ad_structuralObjectClass; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; + AttributeDescription *ad_createTimestamp + = slap_schema.si_ad_createTimestamp; + AttributeDescription *ad_modifyTimestamp + = slap_schema.si_ad_modifyTimestamp; Entry *e; struct berval vals[5]; @@ -81,6 +86,33 @@ schema_info( Entry **entry, const char **text ) attr_merge_one( e, desc, vals ); } + { + struct tm *ltm; + char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + + /* + * According to RFC 2251: + + Servers SHOULD provide the attributes createTimestamp and + modifyTimestamp in subschema entries, in order to allow clients to + maintain their caches of schema information. + + * to be conservative, we declare schema created + * AND modified at server startup time ... + */ + + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); + ltm = gmtime( &starttime ); + lutil_gentime( timebuf, sizeof(timebuf), ltm ); + ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); + + vals[0].bv_val = timebuf; + vals[0].bv_len = strlen( timebuf ); + + attr_merge_one( e, ad_createTimestamp, vals ); + attr_merge_one( e, ad_modifyTimestamp, vals ); + } + if ( syn_schema_info( e ) || mr_schema_info( e ) || mru_schema_info( e ) diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 93427a0b2c..6ced09a12b 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -513,7 +513,7 @@ Directory String - In later versions, more CHOICEs were added. In all cases the string must be non-empty. - In LDPAv3, a directory string is a UTF-8 encoded UCS string. + In LDAPv3, a directory string is a UTF-8 encoded UCS string. For matching, there are both case ignore and exact rules. Both also require that "insignificant" spaces be ignored. @@ -3545,7 +3545,7 @@ integerBitAndMatch( if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE ) return LDAP_CONSTRAINT_VIOLATION; - *matchp = (lValue & lAssertedValue); + *matchp = (lValue & lAssertedValue) ? 0 : 1; return LDAP_SUCCESS; } @@ -3569,7 +3569,7 @@ integerBitOrMatch( if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE ) return LDAP_CONSTRAINT_VIOLATION; - *matchp = (lValue | lAssertedValue); + *matchp = (lValue | lAssertedValue) ? 0 : -1; return LDAP_SUCCESS; } @@ -4427,6 +4427,11 @@ static slap_syntax_defs_rec syntax_defs[] = { {NULL, 0, NULL, NULL, NULL} }; +#ifdef HAVE_TLS +char *certificateExactMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.8", NULL }; +#endif + /* * Other matching rules in X.520 that we do not use (yet): * @@ -4456,7 +4461,7 @@ static slap_mrule_defs_rec mrule_defs[] = { */ {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, NULL, NULL, directoryStringApproxMatch, directoryStringApproxIndexer, @@ -4465,7 +4470,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, NULL, NULL, IA5StringApproxMatch, IA5StringApproxIndexer, @@ -4478,35 +4483,35 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.0 NAME 'objectIdentifierMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter, NULL}, {"( 2.5.13.1 NAME 'distinguishedNameMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, dnMatch, dnIndexer, dnFilter, NULL}, {"( 2.5.13.2 NAME 'caseIgnoreMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter, directoryStringApproxMatchOID }, {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, NULL, NULL, caseIgnoreOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseExactIgnoreSubstringsMatch, caseExactIgnoreSubstringsIndexer, @@ -4515,21 +4520,21 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.5 NAME 'caseExactMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter, directoryStringApproxMatchOID }, {"( 2.5.13.6 NAME 'caseExactOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, NULL, NULL, caseExactOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseExactIgnoreSubstringsMatch, caseExactIgnoreSubstringsIndexer, @@ -4538,7 +4543,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.8 NAME 'numericStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreIA5Match, caseIgnoreIA5Indexer, @@ -4547,7 +4552,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseIgnoreIA5SubstringsMatch, caseIgnoreIA5SubstringsIndexer, @@ -4556,56 +4561,56 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.11 NAME 'caseIgnoreListMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreListMatch, NULL, NULL, NULL}, {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseIgnoreListSubstringsMatch, NULL, NULL, NULL}, {"( 2.5.13.13 NAME 'booleanMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, booleanMatch, NULL, NULL, NULL}, {"( 2.5.13.14 NAME 'integerMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, integerMatch, integerIndexer, integerFilter, NULL}, {"( 2.5.13.15 NAME 'integerOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, NULL, NULL, integerOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.16 NAME 'bitStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, bitStringMatch, bitStringIndexer, bitStringFilter, NULL}, {"( 2.5.13.17 NAME 'octetStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, octetStringMatch, octetStringIndexer, octetStringFilter, NULL}, {"( 2.5.13.20 NAME 'telephoneNumberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, telephoneNumberMatch, telephoneNumberIndexer, @@ -4614,7 +4619,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, telephoneNumberSubstringsMatch, telephoneNumberSubstringsIndexer, @@ -4623,49 +4628,49 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.22 NAME 'presentationAddressMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, {"( 2.5.13.23 NAME 'uniqueMemberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, uniqueMemberMatch, NULL, NULL, NULL}, {"( 2.5.13.24 NAME 'protocolInformationMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, protocolInformationMatch, NULL, NULL, NULL}, {"( 2.5.13.27 NAME 'generalizedTimeMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, generalizedTimeMatch, NULL, NULL, NULL}, {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.29 NAME 'integerFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, integerFirstComponentMatch, NULL, NULL, NULL}, {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL, NULL}, @@ -4673,7 +4678,7 @@ static slap_mrule_defs_rec mrule_defs[] = { #ifdef HAVE_TLS {"( 2.5.13.34 NAME 'certificateExactMatch' " "SYNTAX 1.2.826.0.1.3344810.7.1 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes, certificateExactConvert, NULL, certificateExactMatch, certificateExactIndexer, certificateExactFilter, @@ -4682,21 +4687,21 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter, IA5StringApproxMatchOID }, {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter, IA5StringApproxMatchOID }, {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_SUBSTR, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseIgnoreIA5SubstringsMatch, caseIgnoreIA5SubstringsIndexer, @@ -4705,7 +4710,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_SUBSTR, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseExactIA5SubstringsMatch, caseExactIA5SubstringsIndexer, @@ -4716,7 +4721,7 @@ static slap_mrule_defs_rec mrule_defs[] = { /* needs updating */ {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY, NULL, NULL, NULL, authPasswordMatch, NULL, NULL, NULL}, @@ -4725,7 +4730,7 @@ static slap_mrule_defs_rec mrule_defs[] = { #ifdef SLAPD_ACI_ENABLED {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' " "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )", - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY, NULL, NULL, NULL, OpenLDAPaciMatch, NULL, NULL, NULL}, @@ -4733,19 +4738,21 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EXT, + SLAP_MR_EXT, NULL, NULL, NULL, integerBitAndMatch, NULL, NULL, NULL}, {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EXT, + SLAP_MR_EXT, NULL, NULL, NULL, integerBitOrMatch, NULL, NULL, NULL}, - {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL} + {NULL, SLAP_MR_NONE, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL } }; int @@ -4768,7 +4775,9 @@ slap_schema_init( void ) } for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { - if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) { + if( mrule_defs[i].mrd_usage == SLAP_MR_NONE && + mrule_defs[i].mrd_compat_syntaxes == NULL ) + { fprintf( stderr, "slap_schema_init: Ingoring unusable matching rule %s\n", mrule_defs[i].mrd_desc ); @@ -4803,5 +4812,6 @@ schema_destroy( void ) for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ ) *mr_ptr[i].mr = NULL; mr_destroy(); + mru_destroy(); syn_destroy(); } diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c index c940d3f857..1a759cdde7 100644 --- a/servers/slapd/schema_prep.c +++ b/servers/slapd/schema_prep.c @@ -573,7 +573,7 @@ static struct slap_schema_ad_map { "DESC 'RFC2252: matching rule uses' " "EQUALITY objectIdentifierFirstComponentMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )", - subentryAttribute, SLAP_AT_HIDE, + subentryAttribute, 0, NULL, NULL, NULL, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) }, @@ -768,7 +768,7 @@ slap_schema_load( void ) *synp = syn_find( syn_map[i].sssm_name ); if( *synp == NULL ) { - fprintf( stderr, "slap_schema_check: " + fprintf( stderr, "slap_schema_load: " "No syntax \"%s\" defined in schema\n", syn_map[i].sssm_name ); return LDAP_INVALID_SYNTAX; @@ -784,7 +784,7 @@ slap_schema_load( void ) *mrp = mr_find( mr_map[i].ssmm_name ); if( *mrp == NULL ) { - fprintf( stderr, "slap_schema_check: " + fprintf( stderr, "slap_schema_load: " "No matching rule \"%s\" defined in schema\n", mr_map[i].ssmm_name ); return LDAP_INAPPROPRIATE_MATCHING; @@ -834,7 +834,7 @@ slap_schema_load( void ) rc = slap_str2ad( ad_map[i].ssam_name, adp, &text ); if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "slap_schema_check: " + fprintf( stderr, "slap_schema_load: " "No attribute \"%s\" defined in schema\n", ad_map[i].ssam_name ); return rc; @@ -918,7 +918,7 @@ slap_schema_load( void ) *ocp = oc_find( oc_map[i].ssom_name ); if( *ocp == NULL ) { - fprintf( stderr, "slap_schema_check: " + fprintf( stderr, "slap_schema_load: " "No objectClass \"%s\" defined in schema\n", oc_map[i].ssom_name ); return LDAP_OBJECT_CLASS_VIOLATION; @@ -945,6 +945,13 @@ slap_schema_check( void ) /* we should only be called once after schema_init() was called */ assert( schema_init_done == 1 ); + /* + * cycle thru attributeTypes to build matchingRuleUse + */ + if ( matching_rule_use_init() ) { + return LDAP_OTHER; + } + ++schema_init_done; return LDAP_SUCCESS; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index e64d7e87b9..e0f796eaa9 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -278,7 +278,16 @@ typedef struct slap_syntax { #define ssyn_oid ssyn_syn.syn_oid #define ssyn_desc ssyn_syn.syn_desc #define ssyn_extensions ssyn_syn.syn_extensions + /* + * Note: the former ber_len_t ssyn_oidlen; + * has been replaced by a struct berval that uses the value + * provided by ssyn_syn.syn_oid; a macro that expands to + * the bv_len field of the berval is provided for backward + * compatibility. CAUTION: NEVER FREE THE BERVAL + */ + struct berval ssyn_bvoid; +#define ssyn_oidlen ssyn_bvoid.bv_len unsigned int ssyn_flags; @@ -361,9 +370,24 @@ typedef int slap_mr_filter_func LDAP_P(( void * assertValue, BerVarray *keys )); +typedef struct slap_matching_rule_use MatchingRuleUse; + typedef struct slap_matching_rule { LDAPMatchingRule smr_mrule; - ber_len_t smr_oidlen; + MatchingRuleUse *smr_mru; + /* RFC2252 string representation */ + struct berval smr_str; + /* + * Note: the former + ber_len_t smr_oidlen; + * has been replaced by a struct berval that uses the value + * provided by smr_mrule.mr_oid; a macro that expands to + * the bv_len field of the berval is provided for backward + * compatibility. CAUTION: NEVER FREE THE BERVAL + */ + struct berval smr_bvoid; +#define smr_oidlen smr_bvoid.bv_len + slap_mask_t smr_usage; #define SLAP_MR_HIDE 0x8000U @@ -376,7 +400,7 @@ typedef struct slap_matching_rule { #define SLAP_MR_EQUALITY 0x0100U #define SLAP_MR_ORDERING 0x0200U #define SLAP_MR_SUBSTR 0x0400U -#define SLAP_MR_EXT 0x0800U +#define SLAP_MR_EXT 0x0800U /* implicitly extensible */ #define SLAP_MR_EQUALITY_APPROX ( SLAP_MR_EQUALITY | 0x0010U ) #define SLAP_MR_DN_FOLD 0x0008U @@ -415,6 +439,13 @@ typedef struct slap_matching_rule { slap_mr_indexer_func *smr_indexer; slap_mr_filter_func *smr_filter; + /* + * null terminated list of syntaxes compatible with this syntax + * note: when MS_EXT is set, this MUST NOT contain the assertion + * syntax of the rule. When MS_EXT is not set, it MAY. + */ + Syntax **smr_compat_syntaxes; + struct slap_matching_rule *smr_associated; struct slap_matching_rule *smr_next; @@ -426,9 +457,27 @@ typedef struct slap_matching_rule { #define smr_extensions smr_mrule.mr_extensions } MatchingRule; +struct slap_matching_rule_use { + LDAPMatchingRuleUse smru_mruleuse; + MatchingRule *smru_mr; + /* RFC2252 string representation */ + struct berval smru_str; + + struct slap_matching_rule_use *smru_next; + +#define smru_oid smru_mruleuse.mru_oid +#define smru_names smru_mruleuse.mru_names +#define smru_desc smru_mruleuse.mru_desc +#define smru_obsolete smru_mruleuse.mru_obsolete +#define smru_applies_oids smru_mruleuse.mru_applies_oids + +#define smru_usage smru_mr->smr_usage +} /* MatchingRuleUse */ ; + typedef struct slap_mrule_defs_rec { char * mrd_desc; slap_mask_t mrd_usage; + char ** mrd_compat_syntaxes; slap_mr_convert_func * mrd_convert; slap_mr_normalize_func * mrd_normalize; slap_mr_match_func * mrd_match; diff --git a/servers/slapd/syntax.c b/servers/slapd/syntax.c index 21fef110ea..994761b92c 100644 --- a/servers/slapd/syntax.c +++ b/servers/slapd/syntax.c @@ -126,6 +126,11 @@ syn_add( ssyn->ssyn_next = NULL; + /* + * note: ssyn_bvoid uses the same memory of ssyn_syn.syn_oid; + * ssyn_oidlen is #defined as ssyn_bvoid.bv_len + */ + ssyn->ssyn_bvoid.bv_val = ssyn->ssyn_syn.syn_oid; ssyn->ssyn_oidlen = strlen(syn->syn_oid); ssyn->ssyn_flags = def->sd_flags; ssyn->ssyn_validate = def->sd_validate; -- 2.39.5