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,
* lessOrEqual [6] AttributeValueAssertion,
* present [7] AttributeType,,
* approxMatch [8] AttributeValueAssertion
- * extensibleMatch [9] MatchingRuleAssertion
+ * extensibleMatch [9] MatchingRuleAssertion
* }
*
* SubstringFilter ::= SEQUENCE {
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;
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(
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;
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(
{
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
{
return LDAP_INSUFFICIENT_ACCESS;
}
-#endif /* SLAP_X_MRA_MATCH_DNATTRS */
for(a = attrs_find( e->e_attrs, mra->ma_desc );
a != NULL;
}
}
}
-#ifdef SLAP_X_MRA_MATCH_DNATTRS
} else {
/*
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;
}
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;
}
}
}
}
-#endif /* SLAP_X_MRA_MATCH_DNATTRS */
return LDAP_COMPARE_FALSE;
}
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;
}
}
-#endif /* SLAP_X_MRA_MATCH_DNATTRS */
for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
int ret;
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
}
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;
static Avlnode *mr_index = NULL;
static MatchingRule *mr_list = NULL;
+static MatchingRuleUse *mru_list = NULL;
static int
mr_index_cmp(
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);
}
}
{
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;
return code;
}
-
int
register_matching_rule(
slap_mrule_defs_rec *def )
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 );
#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",
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
"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
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 */
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;
}
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 ) {
}
}
- /*
- * 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 )
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;
}
*/
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?
}
}
-#endif /* SLAP_X_MRA_MATCH_DNATTRS */
if( rc != LDAP_SUCCESS ) {
mra_free( ma, 1 );
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
*/
* 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 ));
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
*/
#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",
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
#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 );
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,
#include "slap.h"
#include "ldap_pvt.h"
+#include "lutil.h"
#if defined( SLAPD_SCHEMA_DN )
= 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];
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 )
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.
if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
return LDAP_CONSTRAINT_VIOLATION;
- *matchp = (lValue & lAssertedValue);
+ *matchp = (lValue & lAssertedValue) ? 0 : 1;
return LDAP_SUCCESS;
}
if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
return LDAP_CONSTRAINT_VIOLATION;
- *matchp = (lValue | lAssertedValue);
+ *matchp = (lValue | lAssertedValue) ? 0 : -1;
return LDAP_SUCCESS;
}
{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):
*
*/
{"( " 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,
{"( " 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,
{"( 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,
{"( 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,
{"( 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,
{"( 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,
{"( 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,
{"( 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,
{"( 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},
#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,
{"( 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,
{"( 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,
/* 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},
#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},
{"( 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
}
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 );
for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
*mr_ptr[i].mr = NULL;
mr_destroy();
+ mru_destroy();
syn_destroy();
}
"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) },
*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;
*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;
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;
*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;
/* 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;
}
#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;
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
#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
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;
#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;
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;