- if ( level > 0 && !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) )
- {
- goto dn_match_cleanup;
- }
-
- level = b->a_level;
- ndn = *opndn;
- for ( ; level > 0; level-- ) {
- if ( BER_BVISEMPTY( &ndn ) ) {
- goto dn_match_cleanup;
- }
- dnParent( &ndn, &ndn );
- if ( ndn.bv_len < patlen ) {
- goto dn_match_cleanup;
- }
- }
-
- if ( ndn.bv_len != patlen ) {
- goto dn_match_cleanup;
- }
- }
-
- got_match = !strcmp( pat.bv_val, &opndn->bv_val[ odnlen - patlen ] );
-
-dn_match_cleanup:;
- if ( pat.bv_val != b->a_pat.bv_val ) {
- slap_sl_free( pat.bv_val, op->o_tmpmemctx );
- }
-
- if ( !got_match ) {
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
- * Record value-dependent access control state
- */
-#define ACL_RECORD_VALUE_STATE do { \
- if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \
- state->as_recorded |= ACL_STATE_RECORDED_VD; \
- state->as_vd_acl = a; \
- AC_MEMCPY( state->as_vd_acl_matches, matches, \
- sizeof( state->as_vd_acl_matches )) ; \
- state->as_vd_acl_count = count; \
- state->as_vd_access = b; \
- state->as_vd_access_count = i; \
- } \
- } while( 0 )
-
-static int
-acl_mask_dnattr(
- Operation *op,
- Entry *e,
- struct berval *val,
- AccessControl *a,
- Access *b,
- int i,
- regmatch_t *matches,
- int count,
- AccessControlState *state,
- slap_dn_access *bdn,
- struct berval *opndn )
-{
- Attribute *at;
- struct berval bv;
- int rc, match = 0;
- const char *text;
- const char *attr = bdn->a_at->ad_cname.bv_val;
-
- assert( attr != NULL );
-
- if ( BER_BVISEMPTY( opndn ) ) {
- return 1;
- }
-
- Debug( LDAP_DEBUG_ACL, "<= check a_dn_at: %s\n", attr, 0, 0 );
- bv = *opndn;
-
- /* see if asker is listed in dnattr */
- for ( at = attrs_find( e->e_attrs, bdn->a_at );
- at != NULL;
- at = attrs_find( at->a_next, bdn->a_at ) )
- {
- if ( value_find_ex( bdn->a_at,
- SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
- SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
- at->a_nvals,
- &bv, op->o_tmpmemctx ) == 0 )
- {
- /* found it */
- match = 1;
- break;
- }
- }
-
- if ( match ) {
- /* have a dnattr match. if this is a self clause then
- * the target must also match the op dn.
- */
- if ( bdn->a_self ) {
- /* check if the target is an attribute. */
- if ( val == NULL ) return 1;
-
- /* target is attribute, check if the attribute value
- * is the op dn.
- */
- rc = value_match( &match, bdn->a_at,
- bdn->a_at->ad_type->sat_equality, 0,
- val, &bv, &text );
- /* on match error or no match, fail the ACL clause */
- if ( rc != LDAP_SUCCESS || match != 0 )
- return 1;
- }
-
- } else {
- /* no dnattr match, check if this is a self clause */
- if ( ! bdn->a_self )
- return 1;
-
- ACL_RECORD_VALUE_STATE;
-
- /* this is a self clause, check if the target is an
- * attribute.
- */
- if ( val == NULL )
- return 1;
-
- /* target is attribute, check if the attribute value
- * is the op dn.
- */
- rc = value_match( &match, bdn->a_at,
- bdn->a_at->ad_type->sat_equality, 0,
- val, &bv, &text );
-
- /* on match error or no match, fail the ACL clause */
- if ( rc != LDAP_SUCCESS || match != 0 )
- return 1;
- }
-
- return 0;
-}
-
-
-/*
- * acl_mask - modifies mask based upon the given acl and the
- * requested access to entry e, attribute attr, value val. if val
- * is null, access to the whole attribute is assumed (all values).
- *
- * returns 0 access NOT allowed
- * 1 access allowed
- */
-
-static slap_control_t
-acl_mask(
- AccessControl *a,
- slap_mask_t *mask,
- Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,