]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Preliminary checkin for new access_allowed() signature. Still need
authorHoward Chu <hyc@openldap.org>
Fri, 11 Dec 2009 05:09:40 +0000 (05:09 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 11 Dec 2009 05:09:40 +0000 (05:09 +0000)
to update backends and overlays.

12 files changed:
servers/slapd/acl.c
servers/slapd/backend.c
servers/slapd/backover.c
servers/slapd/bconfig.c
servers/slapd/compare.c
servers/slapd/filterentry.c
servers/slapd/passwd.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/sasl.c
servers/slapd/slap.h
servers/slapd/slapacl.c

index bbd89fbd3812edaddc6b3c644ae21bb4d33d7f73..558d10218e4fb549d4912706cbcb68453ac8e883 100644 (file)
@@ -48,23 +48,16 @@ static const struct berval  acl_bv_path_eq = BER_BVC("PATH=");
 #endif /* LDAP_PF_LOCAL */
 
 static AccessControl * slap_acl_get(
-       AccessControl *ac, int *count,
-       Operation *op, Entry *e,
-       AttributeDescription *desc,
-       struct berval *val,
+       Operation *op, AclCheck *ak,
+       AccessControl *ac,
        AclRegexMatches *matches,
-       slap_mask_t *mask,
-       AccessControlState *state );
+       int *count );
 
 static slap_control_t slap_acl_mask(
-       AccessControl *ac, slap_mask_t *mask,
-       Operation *op, Entry *e,
-       AttributeDescription *desc,
-       struct berval *val,
+       Operation *op, AclCheck *ak, 
+       AccessControl *ac,
        AclRegexMatches *matches,
-       int count,
-       AccessControlState *state,
-       slap_access_t access );
+       int count );
 
 static int     regex_matches(
        struct berval *pat, char *str,
@@ -103,17 +96,10 @@ SLAP_SET_GATHER acl_set_gather2;
 int
 slap_access_always_allowed(
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp )
+       AclCheck                *ak )
 {
-       assert( maskp != NULL );
-
        /* assign all */
-       ACL_LVL_ASSIGN_MANAGE( *maskp );
+       ACL_LVL_ASSIGN_MANAGE( ak->ak_mask );
 
        return 1;
 }
@@ -132,12 +118,7 @@ slap_access_always_allowed(
 int
 slap_access_allowed(
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp )
+       AclCheck                *ak )
 {
        int                             ret = 1;
        int                             count;
@@ -146,33 +127,34 @@ slap_access_allowed(
 #ifdef LDAP_DEBUG
        char                            accessmaskbuf[ACCESSMASK_MAXLEN];
 #endif
-       slap_mask_t                     mask;
        slap_control_t                  control;
        slap_access_t                   access_level;
+       slap_mask_t                     oldmask;
        const char                      *attr;
        AclRegexMatches                 matches;
        AccessControlState              acl_state = ACL_STATE_INIT;
        static AccessControlState       state_init = ACL_STATE_INIT;
 
        assert( op != NULL );
-       assert( e != NULL );
-       assert( desc != NULL );
-       assert( maskp != NULL );
+       assert( ak != NULL );
+       assert( ak->ak_e != NULL );
+       assert( ak->ak_desc != NULL );
 
-       access_level = ACL_LEVEL( access );
-       attr = desc->ad_cname.bv_val;
+       access_level = ACL_LEVEL( ak->ak_access );
+       attr = ak->ak_desc->ad_cname.bv_val;
 
        assert( attr != NULL );
 
-       ACL_INIT( mask );
-
        /* grant database root access */
        if ( be_isroot( op ) ) {
                Debug( LDAP_DEBUG_ACL, "<= root access granted\n", 0, 0, 0 );
-               mask = ACL_LVL_MANAGE;
+               ak->ak_mask = ACL_LVL_MANAGE;
                goto done;
        }
 
+       oldmask = ak->ak_mask;
+       ACL_INIT( ak->ak_mask );
+
        /*
         * no-user-modification operational attributes are ignored
         * by ACL_WRITE checking as any found here are not provided
@@ -183,9 +165,9 @@ slap_access_allowed(
         * manage data, so we need to check its privileges.
         */
        if ( access_level == ACL_WRITE
-               && is_at_no_user_mod( desc->ad_type )
-               && desc != slap_schema.si_ad_entry
-               && desc != slap_schema.si_ad_children )
+               && is_at_no_user_mod( ak->ak_desc->ad_type )
+               && ak->ak_desc != slap_schema.si_ad_entry
+               && ak->ak_desc != slap_schema.si_ad_children )
        {
                Debug( LDAP_DEBUG_ACL, "NoUserMod Operational attribute:"
                        " %s access granted\n",
@@ -200,14 +182,14 @@ slap_access_allowed(
                Debug( LDAP_DEBUG_ACL,
                        "=> slap_access_allowed: backend default %s "
                        "access %s to \"%s\"\n",
-                       access2str( access ),
+                       access2str( ak->ak_access ),
                        op->o_bd->be_dfltaccess >= access_level ? "granted" : "denied",
                        op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" );
                ret = op->o_bd->be_dfltaccess >= access_level;
 
-               mask = ACL_PRIV_LEVEL;
+               ak->ak_mask = ACL_PRIV_LEVEL;
                for ( i = ACL_NONE; i <= op->o_bd->be_dfltaccess; i++ ) {
-                       ACL_PRIV_SET( mask, ACL_ACCESS2PRIV( i ) );
+                       ACL_PRIV_SET( ak->ak_mask, ACL_ACCESS2PRIV( i ) );
                }
 
                goto done;
@@ -216,29 +198,27 @@ slap_access_allowed(
        ret = 0;
        control = ACL_BREAK;
 
-       if ( state == NULL )
-               state = &acl_state;
-       if ( state->as_desc == desc &&
-               state->as_access == access &&
-               state->as_vd_acl != NULL )
+       if ( ak->ak_state == NULL )
+               ak->ak_state = &acl_state;
+       if ( ak->ak_state->as_desc == ak->ak_desc &&
+               ak->ak_state->as_access == ak->ak_access &&
+               ak->ak_state->as_vd_acl != NULL )
        {
-               a = state->as_vd_acl;
-               count = state->as_vd_acl_count;
-               if ( state->as_fe_done )
-                       state->as_fe_done--;
-               ACL_PRIV_ASSIGN( mask, state->as_vd_mask );
+               a = ak->ak_state->as_vd_acl;
+               count = ak->ak_state->as_vd_acl_count;
+               if ( ak->ak_state->as_fe_done )
+                       ak->ak_state->as_fe_done--;
+               ACL_PRIV_ASSIGN( ak->ak_mask, ak->ak_state->as_vd_mask );
        } else {
-               *state = state_init;
+               *ak->ak_state = state_init;
 
                a = NULL;
                count = 0;
-               ACL_PRIV_ASSIGN( mask, *maskp );
        }
 
        MATCHES_MEMSET( &matches );
 
-       while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
-               &matches, &mask, state ) ) != NULL )
+       while ( ( a = slap_acl_get( op, ak, a, &matches, &count ) ) != NULL )
        {
                int i; 
                int dnmaxcount = MATCHES_DNMAXCOUNT( &matches );
@@ -248,7 +228,7 @@ slap_access_allowed(
 
                /* DN matches */
                for ( i = 0; i < dnmaxcount && dn_data[i].rm_eo > 0; i++ ) {
-                       char *data = e->e_ndn;
+                       char *data = ak->ak_e->e_ndn;
 
                        Debug( LDAP_DEBUG_ACL, "=> match[dn%d]: %d %d ", i,
                                (int)dn_data[i].rm_so, 
@@ -266,7 +246,7 @@ slap_access_allowed(
 
                /* val matches */
                for ( i = 0; i < valmaxcount && val_data[i].rm_eo > 0; i++ ) {
-                       char *data = val->bv_val;
+                       char *data = ak->ak_val->bv_val;
 
                        Debug( LDAP_DEBUG_ACL, "=> match[val%d]: %d %d ", i,
                                (int)val_data[i].rm_so, 
@@ -282,8 +262,8 @@ slap_access_allowed(
                        Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
                }
 
-               control = slap_acl_mask( a, &mask, op,
-                       e, desc, val, &matches, count, state, access );
+               control = slap_acl_mask( op, ak, a,
+                       &matches, count );
 
                if ( control != ACL_BREAK ) {
                        break;
@@ -292,11 +272,11 @@ slap_access_allowed(
                MATCHES_MEMSET( &matches );
        }
 
-       if ( ACL_IS_INVALID( mask ) ) {
+       if ( ACL_IS_INVALID( ak->ak_mask ) ) {
                Debug( LDAP_DEBUG_ACL,
                        "=> slap_access_allowed: \"%s\" (%s) invalid!\n",
-                       e->e_dn, attr, 0 );
-               ACL_PRIV_ASSIGN( mask, *maskp );
+                       ak->ak_e->e_dn, attr, 0 );
+               ACL_PRIV_ASSIGN( ak->ak_mask, oldmask );
 
        } else if ( control == ACL_BREAK ) {
                Debug( LDAP_DEBUG_ACL,
@@ -305,27 +285,23 @@ slap_access_allowed(
                goto done;
        }
 
-       ret = ACL_GRANT( mask, access );
+       ret = ACL_GRANT( ak->ak_mask, ak->ak_access );
 
        Debug( LDAP_DEBUG_ACL,
                "=> slap_access_allowed: %s access %s by %s\n",
-               access2str( access ), ret ? "granted" : "denied",
-               accessmask2str( mask, accessmaskbuf, 1 ) );
+               access2str( ak->ak_access ), ret ? "granted" : "denied",
+               accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
 
 done:
-       ACL_PRIV_ASSIGN( *maskp, mask );
+       if ( ak->ak_state == &acl_state )
+               ak->ak_state = NULL;
        return ret;
 }
 
 int
 fe_access_allowed(
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp )
+       AclCheck                *ak )
 {
        BackendDB               *be_orig;
        int                     rc;
@@ -345,21 +321,16 @@ fe_access_allowed(
                if ( op->o_bd == NULL )
                        op->o_bd = frontendDB;
        }
-       rc = slap_access_allowed( op, e, desc, val, access, state, maskp );
+       rc = slap_access_allowed( op, ak );
        op->o_bd = be_orig;
 
        return rc;
 }
 
 int
-access_allowed_mask(
+access_allowed(
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp )
+       AclCheck                *ak )
 {
        int                             ret = 1;
        int                             be_null = 0;
@@ -367,50 +338,49 @@ access_allowed_mask(
 #ifdef LDAP_DEBUG
        char                            accessmaskbuf[ACCESSMASK_MAXLEN];
 #endif
-       slap_mask_t                     mask;
-       slap_access_t                   access_level;
+       slap_access_t           access_level;
        const char                      *attr;
 
-       assert( e != NULL );
-       assert( desc != NULL );
+       assert( ak != NULL );
+       assert( ak->ak_e != NULL );
+       assert( ak->ak_desc != NULL );
 
-       access_level = ACL_LEVEL( access );
+       access_level = ACL_LEVEL( ak->ak_access );
 
        assert( access_level > ACL_NONE );
 
-       ACL_INIT( mask );
-       if ( maskp ) ACL_INVALIDATE( *maskp );
+       ACL_INVALIDATE( ak->ak_mask );
 
-       attr = desc->ad_cname.bv_val;
+       attr = ak->ak_desc->ad_cname.bv_val;
 
        assert( attr != NULL );
 
        if ( op ) {
                if ( op->o_acl_priv != ACL_NONE ) {
-                       access = op->o_acl_priv;
+                       ak->ak_access = op->o_acl_priv;
 
                } else if ( op->o_is_auth_check &&
                        ( access_level == ACL_SEARCH || access_level == ACL_READ ) )
                {
-                       access = ACL_AUTH;
+                       ak->ak_access = ACL_AUTH;
 
                } else if ( get_relax( op ) && access_level == ACL_WRITE &&
-                       desc == slap_schema.si_ad_entry )
+                       ak->ak_desc == slap_schema.si_ad_entry )
                {
-                       access = ACL_MANAGE;
+                       ak->ak_access = ACL_MANAGE;
                }
        }
 
-       if ( state != NULL ) {
-               if ( state->as_desc == desc &&
-                       state->as_access == access &&
-                       state->as_result != -1 &&
-                       state->as_vd_acl == NULL )
+       if ( ak->ak_state != NULL ) {
+               if ( ak->ak_state->as_desc == ak->ak_desc &&
+                       ak->ak_state->as_access == ak->ak_access &&
+                       ak->ak_state->as_result != -1 &&
+                       ak->ak_state->as_vd_acl == NULL )
                        {
                        Debug( LDAP_DEBUG_ACL,
                                "=> access_allowed: result was in cache (%s)\n",
                                attr, 0, 0 );
-                               return state->as_result;
+                               return ak->ak_state->as_result;
                } else {
                        Debug( LDAP_DEBUG_ACL,
                                "=> access_allowed: result not in cache (%s)\n",
@@ -418,9 +388,11 @@ access_allowed_mask(
                }
        }
 
+       ACL_INIT( ak->ak_mask );
+       
        Debug( LDAP_DEBUG_ACL,
                "=> access_allowed: %s access to \"%s\" \"%s\" requested\n",
-               access2str( access ), e->e_dn, attr );
+               access2str( ak->ak_access ), ak->ak_e->e_dn, attr );
 
        if ( op == NULL ) {
                /* no-op call */
@@ -443,22 +415,20 @@ access_allowed_mask(
        /* this is enforced in backend_add() */
        if ( op->o_bd->bd_info->bi_access_allowed ) {
                /* delegate to backend */
-               ret = op->o_bd->bd_info->bi_access_allowed( op, e,
-                               desc, val, access, state, &mask );
+               ret = op->o_bd->bd_info->bi_access_allowed( op, ak );
 
        } else {
                /* use default (but pass through frontend
                 * for global ACL overlays) */
-               ret = frontendDB->bd_info->bi_access_allowed( op, e,
-                               desc, val, access, state, &mask );
+               ret = frontendDB->bd_info->bi_access_allowed( op, ak );
        }
 
        if ( !ret ) {
-               if ( ACL_IS_INVALID( mask ) ) {
+               if ( ACL_IS_INVALID( ak->ak_mask ) ) {
                        Debug( LDAP_DEBUG_ACL,
                                "=> access_allowed: \"%s\" (%s) invalid!\n",
-                               e->e_dn, attr, 0 );
-                       ACL_INIT( mask );
+                               ak->ak_e->e_dn, attr, 0 );
+                       ACL_INIT( ak->ak_mask );
 
                } else {
                        Debug( LDAP_DEBUG_ACL,
@@ -470,17 +440,16 @@ access_allowed_mask(
 
        Debug( LDAP_DEBUG_ACL,
                "=> access_allowed: %s access %s by %s\n",
-               access2str( access ), ret ? "granted" : "denied",
-               accessmask2str( mask, accessmaskbuf, 1 ) );
+               access2str( ak->ak_access ), ret ? "granted" : "denied",
+               accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
 
 done:
-       if ( state != NULL ) {
-               state->as_access = access;
-                       state->as_result = ret;
-               state->as_desc = desc;
+       if ( ak->ak_state != NULL ) {
+               ak->ak_state->as_access = ak->ak_access;
+               ak->ak_state->as_result = ret;
+               ak->ak_state->as_desc = ak->ak_desc;
        }
        if ( be_null ) op->o_bd = NULL;
-       if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
        return ret;
 }
 
@@ -493,26 +462,22 @@ done:
 
 static AccessControl *
 slap_acl_get(
-       AccessControl *a,
-       int                     *count,
        Operation       *op,
-       Entry           *e,
-       AttributeDescription *desc,
-       struct berval   *val,
+       AclCheck        *ak,
+       AccessControl *a,
        AclRegexMatches *matches,
-       slap_mask_t *mask,
-       AccessControlState *state )
+       int                     *count )
 {
        const char *attr;
        ber_len_t dnlen;
        AccessControl *prev;
 
-       assert( e != NULL );
+       assert( ak->ak_e != NULL );
        assert( count != NULL );
-       assert( desc != NULL );
-       assert( state != NULL );
+       assert( ak->ak_desc != NULL );
+       assert( ak->ak_state != NULL );
 
-       attr = desc->ad_cname.bv_val;
+       attr = ak->ak_desc->ad_cname.bv_val;
 
        assert( attr != NULL );
 
@@ -526,27 +491,27 @@ slap_acl_get(
 
                assert( a != NULL );
                if ( a == frontendDB->be_acl )
-                       state->as_fe_done = 1;
+                       ak->ak_state->as_fe_done = 1;
        } else {
                prev = a;
                a = a->acl_next;
        }
 
-       dnlen = e->e_nname.bv_len;
+       dnlen = ak->ak_e->e_nname.bv_len;
 
  retry:
        for ( ; a != NULL; prev = a, a = a->acl_next ) {
                (*count) ++;
 
-               if ( a != frontendDB->be_acl && state->as_fe_done )
-                       state->as_fe_done++;
+               if ( a != frontendDB->be_acl && ak->ak_state->as_fe_done )
+                       ak->ak_state->as_fe_done++;
 
                if ( a->acl_dn_pat.bv_len || ( a->acl_dn_style != ACL_STYLE_REGEX )) {
                        if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
                                Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n", 
                                        *count, a->acl_dn_pat.bv_val, (int) a->acl_dn_re.re_nsub );
                                if ( regexec ( &a->acl_dn_re, 
-                                              e->e_ndn, 
+                                              ak->ak_e->e_ndn, 
                                               matches->dn_count, 
                                               matches->dn_data, 0 ) )
                                        continue;
@@ -573,27 +538,27 @@ slap_acl_get(
                                                continue;
 
                                        if ( patlen > 0 ) {
-                                               if ( !DN_SEPARATOR( e->e_ndn[dnlen - patlen - 1] ) )
+                                               if ( !DN_SEPARATOR( ak->ak_e->e_ndn[dnlen - patlen - 1] ) )
                                                        continue;
                                                sep = 1;
                                        }
 
-                                       rdnlen = dn_rdnlen( NULL, &e->e_nname );
+                                       rdnlen = dn_rdnlen( NULL, &ak->ak_e->e_nname );
                                        if ( rdnlen + patlen + sep != dnlen )
                                                continue;
 
                                } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
-                                       if ( dnlen > patlen && !DN_SEPARATOR( e->e_ndn[dnlen - patlen - 1] ) )
+                                       if ( dnlen > patlen && !DN_SEPARATOR( ak->ak_e->e_ndn[dnlen - patlen - 1] ) )
                                                continue;
 
                                } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) {
                                        if ( dnlen <= patlen )
                                                continue;
-                                       if ( !DN_SEPARATOR( e->e_ndn[dnlen - patlen - 1] ) )
+                                       if ( !DN_SEPARATOR( ak->ak_e->e_ndn[dnlen - patlen - 1] ) )
                                                continue;
                                }
 
-                               if ( strcmp( a->acl_dn_pat.bv_val, e->e_ndn + dnlen - patlen ) != 0 )
+                               if ( strcmp( a->acl_dn_pat.bv_val, ak->ak_e->e_ndn + dnlen - patlen ) != 0 )
                                        continue;
                        }
 
@@ -601,7 +566,7 @@ slap_acl_get(
                                *count, 0, 0 );
                }
 
-               if ( a->acl_attrs && !ad_inlist( desc, a->acl_attrs ) ) {
+               if ( a->acl_attrs && !ad_inlist( ak->ak_desc, a->acl_attrs ) ) {
                        matches->dn_data[0].rm_so = -1;
                        matches->dn_data[0].rm_eo = -1;
                        matches->val_data[0].rm_so = -1;
@@ -611,14 +576,14 @@ slap_acl_get(
 
                /* Is this ACL only for a specific value? */
                if ( a->acl_attrval.bv_len ) {
-                       if ( val == NULL ) {
+                       if ( ak->ak_val == NULL ) {
                                continue;
                        }
 
-                       if ( state->as_vd_acl == NULL ) {
-                               state->as_vd_acl = prev;
-                               state->as_vd_acl_count = *count - 1;
-                               ACL_PRIV_ASSIGN ( state->as_vd_mask, *mask );
+                       if ( ak->ak_state->as_vd_acl == NULL ) {
+                               ak->ak_state->as_vd_acl = prev;
+                               ak->ak_state->as_vd_acl_count = *count - 1;
+                               ACL_PRIV_ASSIGN ( ak->ak_state->as_vd_mask, ak->ak_mask );
                        }
 
                        if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
@@ -626,7 +591,7 @@ slap_acl_get(
                                        "acl_get: valpat %s\n",
                                        a->acl_attrval.bv_val, 0, 0 );
                                if ( regexec ( &a->acl_attrval_re, 
-                                                   val->bv_val, 
+                                                   ak->ak_val->bv_val, 
                                                    matches->val_count, 
                                                    matches->val_data, 0 ) )
                                {
@@ -641,9 +606,9 @@ slap_acl_get(
                                        a->acl_attrval.bv_val, 0, 0 );
        
                                if ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
-                                       if (value_match( &match, desc,
+                                       if (value_match( &match, ak->ak_desc,
                                                a->acl_attrval_mr, 0,
-                                               val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
+                                               ak->ak_val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
                                                        match )
                                                continue;
                                        
@@ -651,7 +616,7 @@ slap_acl_get(
                                        ber_len_t       patlen, vdnlen;
        
                                        patlen = a->acl_attrval.bv_len;
-                                       vdnlen = val->bv_len;
+                                       vdnlen = ak->ak_val->bv_len;
        
                                        if ( vdnlen < patlen )
                                                continue;
@@ -663,33 +628,33 @@ slap_acl_get(
                                        } else if ( a->acl_attrval_style == ACL_STYLE_ONE ) {
                                                ber_len_t       rdnlen = 0;
        
-                                               if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+                                               if ( !DN_SEPARATOR( ak->ak_val->bv_val[vdnlen - patlen - 1] ) )
                                                        continue;
        
-                                               rdnlen = dn_rdnlen( NULL, val );
+                                               rdnlen = dn_rdnlen( NULL, ak->ak_val );
                                                if ( rdnlen + patlen + 1 != vdnlen )
                                                        continue;
        
                                        } else if ( a->acl_attrval_style == ACL_STYLE_SUBTREE ) {
-                                               if ( vdnlen > patlen && !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+                                               if ( vdnlen > patlen && !DN_SEPARATOR( ak->ak_val->bv_val[vdnlen - patlen - 1] ) )
                                                        continue;
        
                                        } else if ( a->acl_attrval_style == ACL_STYLE_CHILDREN ) {
                                                if ( vdnlen <= patlen )
                                                        continue;
        
-                                               if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+                                               if ( !DN_SEPARATOR( ak->ak_val->bv_val[vdnlen - patlen - 1] ) )
                                                        continue;
                                        }
        
-                                       if ( strcmp( a->acl_attrval.bv_val, val->bv_val + vdnlen - patlen ) )
+                                       if ( strcmp( a->acl_attrval.bv_val, ak->ak_val->bv_val + vdnlen - patlen ) )
                                                continue;
                                }
                        }
                }
 
                if ( a->acl_filter != NULL ) {
-                       ber_int_t rc = test_filter( NULL, e, a->acl_filter );
+                       ber_int_t rc = test_filter( NULL, ak->ak_e, a->acl_filter );
                        if ( rc != LDAP_COMPARE_TRUE ) {
                                continue;
                        }
@@ -700,8 +665,8 @@ slap_acl_get(
                return a;
        }
 
-       if ( !state->as_fe_done ) {
-               state->as_fe_done = 1;
+       if ( !ak->ak_state->as_fe_done ) {
+               ak->ak_state->as_fe_done = 1;
                a = frontendDB->be_acl;
                goto retry;
        }
@@ -714,18 +679,17 @@ slap_acl_get(
  * Record value-dependent access control state
  */
 #define ACL_RECORD_VALUE_STATE do { \
-               if( state && state->as_vd_acl == NULL ) { \
-                       state->as_vd_acl = a; \
-                       state->as_vd_acl_count = count; \
-                       ACL_PRIV_ASSIGN( state->as_vd_mask, *mask ); \
+               if( ak->ak_state && ak->ak_state->as_vd_acl == NULL ) { \
+                       ak->ak_state->as_vd_acl = a; \
+                       ak->ak_state->as_vd_acl_count = count; \
+                       ACL_PRIV_ASSIGN( ak->ak_state->as_vd_mask, ak->ak_mask ); \
                } \
        } while( 0 )
 
 static int
 acl_mask_dn(
        Operation               *op,
-       Entry                   *e,
-       struct berval           *val,
+       AclCheck                *ak,
        AccessControl           *a,
        AclRegexMatches         *matches,
        slap_dn_access          *bdn,
@@ -757,19 +721,19 @@ acl_mask_dn(
                struct berval   ndn, selfndn;
                int             level;
 
-               if ( BER_BVISEMPTY( opndn ) || BER_BVISNULL( &e->e_nname ) ) {
+               if ( BER_BVISEMPTY( opndn ) || BER_BVISNULL( &ak->ak_e->e_nname ) ) {
                        return 1;
                }
 
                level = bdn->a_self_level;
                if ( level < 0 ) {
                        selfndn = *opndn;
-                       ndn = e->e_nname;
+                       ndn = ak->ak_e->e_nname;
                        level = -level;
 
                } else {
                        ndn = *opndn;
-                       selfndn = e->e_nname;
+                       selfndn = ak->ak_e->e_nname;
                }
 
                for ( ; level > 0; level-- ) {
@@ -806,7 +770,7 @@ acl_mask_dn(
 
                        case ACL_STYLE_BASE:
                                tmp_data[0].rm_so = 0;
-                               tmp_data[0].rm_eo = e->e_nname.bv_len;
+                               tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
                                tmp_matches.dn_count = 1;
                                break;
 
@@ -814,9 +778,9 @@ acl_mask_dn(
                        case ACL_STYLE_SUBTREE:
                        case ACL_STYLE_CHILDREN:
                                tmp_data[0].rm_so = 0;
-                               tmp_data[0].rm_eo = e->e_nname.bv_len;
-                               tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
-                               tmp_data[1].rm_eo = e->e_nname.bv_len;
+                               tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
+                               tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+                               tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len;
                                tmp_matches.dn_count = 2;
                                break;
 
@@ -831,7 +795,7 @@ acl_mask_dn(
                        }
 
                        if ( !regex_matches( &bdn->a_pat, opndn->bv_val,
-                               &e->e_nname, NULL, tmp_matchesp ) )
+                               &ak->ak_e->e_nname, NULL, tmp_matchesp ) )
                        {
                                return 1;
                        }
@@ -842,7 +806,7 @@ acl_mask_dn(
                ber_len_t       patlen, odnlen;
                int             got_match = 0;
 
-               if ( e->e_dn == NULL )
+               if ( ak->ak_e->e_dn == NULL )
                        return 1;
 
                if ( bdn->a_expand ) {
@@ -873,7 +837,7 @@ acl_mask_dn(
 
                        case ACL_STYLE_BASE:
                                tmp_data[0].rm_so = 0;
-                               tmp_data[0].rm_eo = e->e_nname.bv_len;
+                               tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
                                tmp_matches.dn_count = 1;
                                break;
 
@@ -881,9 +845,9 @@ acl_mask_dn(
                        case ACL_STYLE_SUBTREE:
                        case ACL_STYLE_CHILDREN:
                                tmp_data[0].rm_so = 0;
-                               tmp_data[0].rm_eo = e->e_nname.bv_len;
-                               tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
-                               tmp_data[1].rm_eo = e->e_nname.bv_len;
+                               tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
+                               tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+                               tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len;
                                tmp_matches.dn_count = 2;
                                break;
 
@@ -898,8 +862,8 @@ acl_mask_dn(
                        }
 
                        if ( acl_string_expand( &bv, &bdn->a_pat, 
-                                               &e->e_nname, 
-                                               val, tmp_matchesp ) )
+                                               &ak->ak_e->e_nname, 
+                                               ak->ak_val, tmp_matchesp ) )
                        {
                                return 1;
                        }
@@ -1006,12 +970,9 @@ dn_match_cleanup:;
 static int
 acl_mask_dnattr(
        Operation               *op,
-       Entry                   *e,
-       struct berval           *val,
+       AclCheck                *ak,
        AccessControl           *a,
        int                     count,
-       AccessControlState      *state,
-       slap_mask_t                     *mask,
        slap_dn_access          *bdn,
        struct berval           *opndn )
 {
@@ -1031,7 +992,7 @@ acl_mask_dnattr(
        bv = *opndn;
 
        /* see if asker is listed in dnattr */
-       for ( at = attrs_find( e->e_attrs, bdn->a_at );
+       for ( at = attrs_find( ak->ak_e->e_attrs, bdn->a_at );
                at != NULL;
                at = attrs_find( at->a_next, bdn->a_at ) )
        {
@@ -1052,14 +1013,14 @@ acl_mask_dnattr(
                 */
                if ( bdn->a_self ) {
                        /* check if the target is an attribute. */
-                       if ( val == NULL ) return 1;
+                       if ( ak->ak_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 );
+                               ak->ak_val, &bv, &text );
                        /* on match error or no match, fail the ACL clause */
                        if ( rc != LDAP_SUCCESS || match != 0 )
                                return 1;
@@ -1075,7 +1036,7 @@ acl_mask_dnattr(
                /* this is a self clause, check if the target is an
                 * attribute.
                 */
-               if ( val == NULL )
+               if ( ak->ak_val == NULL )
                        return 1;
 
                /* target is attribute, check if the attribute value
@@ -1083,7 +1044,7 @@ acl_mask_dnattr(
                 */
                rc = value_match( &match, bdn->a_at,
                        bdn->a_at->ad_type->sat_equality, 0,
-                       val, &bv, &text );
+                       ak->ak_val, &bv, &text );
 
                /* on match error or no match, fail the ACL clause */
                if ( rc != LDAP_SUCCESS || match != 0 )
@@ -1105,16 +1066,11 @@ acl_mask_dnattr(
 
 static slap_control_t
 slap_acl_mask(
-       AccessControl           *a,
-       slap_mask_t             *mask,
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
+       AclCheck                        *ak,
+       AccessControl           *a,
        AclRegexMatches         *matches,
-       int                     count,
-       AccessControlState      *state,
-       slap_access_t   access )
+       int                     count )
 {
        int             i;
        Access          *b;
@@ -1127,23 +1083,21 @@ slap_acl_mask(
 #endif /* SLAP_DYNACL */
 
        assert( a != NULL );
-       assert( mask != NULL );
-       assert( desc != NULL );
+       assert( ak->ak_desc != NULL );
 
-       attr = desc->ad_cname.bv_val;
+       attr = ak->ak_desc->ad_cname.bv_val;
 
        assert( attr != NULL );
 
        Debug( LDAP_DEBUG_ACL,
                "=> acl_mask: access to entry \"%s\", attr \"%s\" requested\n",
-               e->e_dn, attr, 0 );
+               ak->ak_e->e_dn, attr, 0 );
 
        Debug( LDAP_DEBUG_ACL,
                "=> acl_mask: to %s by \"%s\", (%s) \n",
-               val ? "value" : "all values",
+               ak->ak_val ? "value" : "all values",
                op->o_ndn.bv_val ?  op->o_ndn.bv_val : "",
-               accessmask2str( *mask, accessmaskbuf, 1 ) );
-
+               accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
 
        b = a->acl_access;
        i = 1;
@@ -1169,7 +1123,7 @@ slap_acl_mask(
                         * is maintained in a_dn_pat.
                         */
 
-                       if ( acl_mask_dn( op, e, val, a, matches,
+                       if ( acl_mask_dn( op, ak, a, matches,
                                &b->a_dn, &op->o_ndn ) )
                        {
                                continue;
@@ -1200,7 +1154,7 @@ slap_acl_mask(
                                ndn = op->o_ndn;
                        }
 
-                       if ( acl_mask_dn( op, e, val, a, matches,
+                       if ( acl_mask_dn( op, ak, a, matches,
                                &b->a_realdn, &ndn ) )
                        {
                                continue;
@@ -1217,7 +1171,7 @@ slap_acl_mask(
                        if ( !ber_bvccmp( &b->a_sockurl_pat, '*' ) ) {
                                if ( b->a_sockurl_style == ACL_STYLE_REGEX) {
                                        if ( !regex_matches( &b->a_sockurl_pat, op->o_conn->c_listener_url.bv_val,
-                                                       &e->e_nname, val, matches ) ) 
+                                                       &ak->ak_e->e_nname, ak->ak_val, matches ) ) 
                                        {
                                                continue;
                                        }
@@ -1228,7 +1182,7 @@ slap_acl_mask(
 
                                        bv.bv_len = sizeof( buf ) - 1;
                                        bv.bv_val = buf;
-                                       if ( acl_string_expand( &bv, &b->a_sockurl_pat, &e->e_nname, val, matches ) )
+                                       if ( acl_string_expand( &bv, &b->a_sockurl_pat, &ak->ak_e->e_nname, ak->ak_val, matches ) )
                                        {
                                                continue;
                                        }
@@ -1256,7 +1210,7 @@ slap_acl_mask(
                        if ( !ber_bvccmp( &b->a_domain_pat, '*' ) ) {
                                if ( b->a_domain_style == ACL_STYLE_REGEX) {
                                        if ( !regex_matches( &b->a_domain_pat, op->o_conn->c_peer_domain.bv_val,
-                                                       &e->e_nname, val, matches ) ) 
+                                                       &ak->ak_e->e_nname, ak->ak_val, matches ) ) 
                                        {
                                                continue;
                                        }
@@ -1272,7 +1226,7 @@ slap_acl_mask(
                                                bv.bv_len = sizeof(buf) - 1;
                                                bv.bv_val = buf;
 
-                                               if ( acl_string_expand(&bv, &b->a_domain_pat, &e->e_nname, val, matches) )
+                                               if ( acl_string_expand(&bv, &b->a_domain_pat, &ak->ak_e->e_nname, ak->ak_val, matches) )
                                                {
                                                        continue;
                                                }
@@ -1310,7 +1264,7 @@ slap_acl_mask(
                        if ( !ber_bvccmp( &b->a_peername_pat, '*' ) ) {
                                if ( b->a_peername_style == ACL_STYLE_REGEX ) {
                                        if ( !regex_matches( &b->a_peername_pat, op->o_conn->c_peer_name.bv_val,
-                                                       &e->e_nname, val, matches ) ) 
+                                                       &ak->ak_e->e_nname, ak->ak_val, matches ) ) 
                                        {
                                                continue;
                                        }
@@ -1328,7 +1282,7 @@ slap_acl_mask(
 
                                                bv.bv_len = sizeof( buf ) - 1;
                                                bv.bv_val = buf;
-                                               if ( acl_string_expand( &bv, &b->a_peername_pat, &e->e_nname, val, matches ) )
+                                               if ( acl_string_expand( &bv, &b->a_peername_pat, &ak->ak_e->e_nname, ak->ak_val, matches ) )
                                                {
                                                        continue;
                                                }
@@ -1462,7 +1416,7 @@ slap_acl_mask(
                        if ( !ber_bvccmp( &b->a_sockname_pat, '*' ) ) {
                                if ( b->a_sockname_style == ACL_STYLE_REGEX) {
                                        if ( !regex_matches( &b->a_sockname_pat, op->o_conn->c_sock_name.bv_val,
-                                                       &e->e_nname, val, matches ) ) 
+                                                       &ak->ak_e->e_nname, ak->ak_val, matches ) ) 
                                        {
                                                continue;
                                        }
@@ -1473,7 +1427,7 @@ slap_acl_mask(
 
                                        bv.bv_len = sizeof( buf ) - 1;
                                        bv.bv_val = buf;
-                                       if ( acl_string_expand( &bv, &b->a_sockname_pat, &e->e_nname, val, matches ) )
+                                       if ( acl_string_expand( &bv, &b->a_sockname_pat, &ak->ak_e->e_nname, ak->ak_val, matches ) )
                                        {
                                                continue;
                                        }
@@ -1491,8 +1445,8 @@ slap_acl_mask(
                }
 
                if ( b->a_dn_at != NULL ) {
-                       if ( acl_mask_dnattr( op, e, val, a,
-                                       count, state, mask,
+                       if ( acl_mask_dnattr( op, ak, a,
+                                       count, 
                                        &b->a_dn, &op->o_ndn ) )
                        {
                                continue;
@@ -1509,8 +1463,8 @@ slap_acl_mask(
                                ndn = op->o_ndn;
                        }
 
-                       if ( acl_mask_dnattr( op, e, val, a,
-                                       count, state, mask,
+                       if ( acl_mask_dnattr( op, ak, a,
+                                       count,
                                        &b->a_realdn, &ndn ) )
                        {
                                continue;
@@ -1560,7 +1514,7 @@ slap_acl_mask(
                                /* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
                                case ACL_STYLE_BASE:
                                        tmp_data[0].rm_so = 0;
-                                       tmp_data[0].rm_eo = e->e_nname.bv_len;
+                                       tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
                                        tmp_matches.dn_count = 1;
                                        break;
 
@@ -1568,10 +1522,10 @@ slap_acl_mask(
                                case ACL_STYLE_SUBTREE:
                                case ACL_STYLE_CHILDREN:
                                        tmp_data[0].rm_so = 0;
-                                       tmp_data[0].rm_eo = e->e_nname.bv_len;
+                                       tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
 
-                                       tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
-                                       tmp_data[1].rm_eo = e->e_nname.bv_len;
+                                       tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+                                       tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len;
                                        tmp_matches.dn_count = 2;
                                        break;
 
@@ -1586,7 +1540,7 @@ slap_acl_mask(
                                }
                                
                                if ( acl_string_expand( &bv, &b->a_group_pat,
-                                               &e->e_nname, val,
+                                               &ak->ak_e->e_nname, ak->ak_val,
                                                tmp_matchesp ) )
                                {
                                        continue;
@@ -1605,7 +1559,7 @@ slap_acl_mask(
                                bv = b->a_group_pat;
                        }
 
-                       rc = backend_group( op, e, &bv, &op->o_ndn,
+                       rc = backend_group( op, ak->ak_e, &bv, &op->o_ndn,
                                b->a_group_oc, b->a_group_at );
 
                        if ( ndn.bv_val ) {
@@ -1650,7 +1604,7 @@ slap_acl_mask(
                                /* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
                                case ACL_STYLE_BASE:
                                        tmp_data[0].rm_so = 0;
-                                       tmp_data[0].rm_eo = e->e_nname.bv_len;
+                                       tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
                                        tmp_matches.dn_count = 1;
                                        break;
 
@@ -1658,9 +1612,9 @@ slap_acl_mask(
                                case ACL_STYLE_SUBTREE:
                                case ACL_STYLE_CHILDREN:
                                        tmp_data[0].rm_so = 0;
-                                       tmp_data[0].rm_eo = e->e_nname.bv_len;
-                                       tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
-                                       tmp_data[1].rm_eo = e->e_nname.bv_len; tmp_matches.dn_count = 2;
+                                       tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
+                                       tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+                                       tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len; tmp_matches.dn_count = 2;
                                        break;
 
                                default:
@@ -1674,7 +1628,7 @@ slap_acl_mask(
                                }
                                
                                if ( acl_string_expand( &bv, &b->a_set_pat,
-                                               &e->e_nname, val,
+                                               &ak->ak_e->e_nname, ak->ak_val,
                                                tmp_matchesp ) )
                                {
                                        continue;
@@ -1684,7 +1638,7 @@ slap_acl_mask(
                                bv = b->a_set_pat;
                        }
                        
-                       if ( acl_match_set( &bv, op, e, NULL ) == 0 ) {
+                       if ( acl_match_set( &bv, op, ak->ak_e, NULL ) == 0 ) {
                                continue;
                        }
                }
@@ -1732,11 +1686,11 @@ slap_acl_mask(
                        ACL_RECORD_VALUE_STATE;
 
                        /* must have DN syntax */
-                       if ( desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName &&
-                               !is_at_syntax( desc->ad_type, SLAPD_NAMEUID_SYNTAX )) continue;
+                       if ( ak->ak_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName &&
+                               !is_at_syntax( ak->ak_desc->ad_type, SLAPD_NAMEUID_SYNTAX )) continue;
 
                        /* check if the target is an attribute. */
-                       if ( val == NULL ) continue;
+                       if ( ak->ak_val == NULL ) continue;
 
                        /* a DN must be present */
                        if ( BER_BVISEMPTY( &op->o_ndn ) ) {
@@ -1746,9 +1700,9 @@ slap_acl_mask(
                        /* target is attribute, check if the attribute value
                         * is the op dn.
                         */
-                       rc = value_match( &match, desc,
-                               desc->ad_type->sat_equality, 0,
-                               val, &op->o_ndn, &dummy );
+                       rc = value_match( &match, ak->ak_desc,
+                               ak->ak_desc->ad_type->sat_equality, 0,
+                               ak->ak_val, &op->o_ndn, &dummy );
                        /* on match error or no match, fail the ACL clause */
                        if ( rc != LDAP_SUCCESS || match != 0 )
                                continue;
@@ -1792,8 +1746,8 @@ slap_acl_mask(
                                 * sending attribute values matches require
                                 * an API update
                                 */
-                               (void)da->da_mask( da->da_private, op, e, desc,
-                                       val, matches->dn_count, matches->dn_data, 
+                               (void)da->da_mask( da->da_private, op, ak->ak_e, ak->ak_desc,
+                                       ak->ak_val, matches->dn_count, matches->dn_data, 
                                        &grant, &deny ); 
 
                                tgrant |= grant;
@@ -1842,30 +1796,30 @@ slap_acl_mask(
                                        ? "break"
                                        : "stop" );
                /* save old mask */
-               oldmask = *mask;
+               oldmask = ak->ak_mask;
 
                if( ACL_IS_ADDITIVE(modmask) ) {
                        /* add privs */
-                       ACL_PRIV_SET( *mask, modmask );
+                       ACL_PRIV_SET( ak->ak_mask, modmask );
 
                        /* cleanup */
-                       ACL_PRIV_CLR( *mask, ~ACL_PRIV_MASK );
+                       ACL_PRIV_CLR( ak->ak_mask, ~ACL_PRIV_MASK );
 
                } else if( ACL_IS_SUBTRACTIVE(modmask) ) {
                        /* substract privs */
-                       ACL_PRIV_CLR( *mask, modmask );
+                       ACL_PRIV_CLR( ak->ak_mask, modmask );
 
                        /* cleanup */
-                       ACL_PRIV_CLR( *mask, ~ACL_PRIV_MASK );
+                       ACL_PRIV_CLR( ak->ak_mask, ~ACL_PRIV_MASK );
 
                } else {
                        /* assign privs */
-                       *mask = modmask;
+                       ak->ak_mask = modmask;
                }
 
                Debug( LDAP_DEBUG_ACL,
                        "<= acl_mask: [%d] mask: %s\n",
-                       i, accessmask2str(*mask, accessmaskbuf, 1), 0 );
+                       i, accessmask2str(ak->ak_mask, accessmaskbuf, 1), 0 );
 
                if( b->a_type == ACL_CONTINUE ) {
                        continue;
@@ -1879,11 +1833,11 @@ slap_acl_mask(
        }
 
        /* implicit "by * none" clause */
-       ACL_INIT(*mask);
+       ACL_INIT(ak->ak_mask);
 
        Debug( LDAP_DEBUG_ACL,
                "<= acl_mask: no more <who> clauses, returning %s (stop)\n",
-               accessmask2str(*mask, accessmaskbuf, 1), 0, 0 );
+               accessmask2str(ak->ak_mask, accessmaskbuf, 1), 0, 0 );
        return ACL_STOP;
 }
 
@@ -1900,8 +1854,8 @@ acl_check_modlist(
        Entry   *e,
        Modifications   *mlist )
 {
-       struct berval *bv;
        AccessControlState state = ACL_STATE_INIT;
+       AclCheck ak;
        Backend *be;
        int be_null = 0;
        int ret = 1; /* default is access allowed */
@@ -1938,6 +1892,9 @@ acl_check_modlist(
                goto done;
        }
 
+       ak.ak_e = e;
+       ak.ak_state = &state;
+
        for ( ; mlist != NULL; mlist = mlist->sml_next ) {
                /*
                 * Internal mods are ignored by ACL_WRITE checking
@@ -1963,6 +1920,7 @@ acl_check_modlist(
                        continue;
                }
 
+               ak.ak_desc = mlist->sml_desc;
                switch ( mlist->sml_op ) {
                case LDAP_MOD_REPLACE:
                case LDAP_MOD_INCREMENT:
@@ -1971,10 +1929,9 @@ acl_check_modlist(
                         * attribute and permission to add the specific attributes.
                         * This prevents abuse from selfwriters.
                         */
-                       if ( ! access_allowed( op, e,
-                               mlist->sml_desc, NULL,
-                               ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
-                               &state ) )
+                       ak.ak_val = NULL;
+                       ak.ak_access = ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL;
+                       if ( ! access_allowed( op, &ak ))
                        {
                                ret = 0;
                                goto done;
@@ -1986,15 +1943,13 @@ acl_check_modlist(
 
                case LDAP_MOD_ADD:
                        assert( mlist->sml_values != NULL );
+                       ak.ak_access = ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WADD;
 
-                       for ( bv = mlist->sml_nvalues
+                       for ( ak.ak_val = mlist->sml_nvalues
                                        ? mlist->sml_nvalues : mlist->sml_values;
-                               bv->bv_val != NULL; bv++ )
+                               ak.ak_val->bv_val != NULL; ak.ak_val++ )
                        {
-                               if ( ! access_allowed( op, e,
-                                       mlist->sml_desc, bv,
-                                       ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WADD,
-                                       &state ) )
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        ret = 0;
                                        goto done;
@@ -2004,24 +1959,20 @@ acl_check_modlist(
 
                case LDAP_MOD_DELETE:
                        if ( mlist->sml_values == NULL ) {
-                               if ( ! access_allowed( op, e,
-                                       mlist->sml_desc, NULL,
-                                       ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
-                                       &state ) )
+                               ak.ak_val = NULL;
+                               ak.ak_access = ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL;
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        ret = 0;
                                        goto done;
                                }
                                break;
                        }
-                       for ( bv = mlist->sml_nvalues
+                       for ( ak.ak_val = mlist->sml_nvalues
                                        ? mlist->sml_nvalues : mlist->sml_values;
-                               bv->bv_val != NULL; bv++ )
+                               ak.ak_val->bv_val != NULL; ak.ak_val++ )
                        {
-                               if ( ! access_allowed( op, e,
-                                       mlist->sml_desc, bv,
-                                       ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
-                                       &state ) )
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        ret = 0;
                                        goto done;
index 10320083539bce051c684869cd3659fb2bb649dc..4953724f4df08d570866cd4d06d5b3f98e306d40 100644 (file)
@@ -1625,11 +1625,11 @@ fe_acl_attribute(
        BerVarray *vals,
        slap_access_t access )
 {
-       Entry                   *e = NULL;
        void                    *o_priv = op->o_private, *e_priv = NULL;
        Attribute               *a = NULL;
        int                     freeattr = 0, i, j, rc = LDAP_SUCCESS;
        AccessControlState      acl_state = ACL_STATE_INIT;
+       AclCheck                ak;
        Backend                 *be = op->o_bd;
        OpExtra         *oex;
 
@@ -1645,30 +1645,34 @@ fe_acl_attribute(
                op->o_bd = select_backend( edn, 0 );
 
        if ( target && dn_match( &target->e_nname, edn ) ) {
-               e = target;
+               ak.ak_e = target;
 
        } else {
                op->o_private = NULL;
-               rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e );
+               ak.ak_e = NULL;
+               rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &ak.ak_e );
                e_priv = op->o_private;
                op->o_private = o_priv;
        } 
 
-       if ( e ) {
+       if ( ak.ak_e ) {
+               ak.ak_state = &acl_state;
+               ak.ak_desc = entry_at;
+               ak.ak_access = access;
                if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) {
                        assert( vals == NULL );
 
+                       ak.ak_val = NULL;
                        rc = LDAP_SUCCESS;
                        if ( op->o_conn && access > ACL_NONE &&
-                               access_allowed( op, e, entry_at, NULL,
-                                               access, &acl_state ) == 0 )
+                               access_allowed( op, &ak ) == 0 )
                        {
                                rc = LDAP_INSUFFICIENT_ACCESS;
                        }
                        goto freeit;
                }
 
-               a = attr_find( e->e_attrs, entry_at );
+               a = attr_find( ak.ak_e->e_attrs, entry_at );
                if ( a == NULL ) {
                        SlapReply       rs = { 0 };
                        AttributeName   anlist[ 2 ];
@@ -1681,7 +1685,7 @@ fe_acl_attribute(
                        /* NOTE: backend_operational() is also called
                         * when returning results, so it's supposed
                         * to do no harm to entries */
-                       rs.sr_entry = e;
+                       rs.sr_entry = ak.ak_e;
                        rc = backend_operational( op, &rs );
                        rs.sr_entry = NULL;
  
@@ -1700,8 +1704,7 @@ fe_acl_attribute(
                        BerVarray v;
 
                        if ( op->o_conn && access > ACL_NONE &&
-                               access_allowed( op, e, entry_at, NULL,
-                                               access, &acl_state ) == 0 )
+                               access_allowed( op, &ak ) == 0 )
                        {
                                rc = LDAP_INSUFFICIENT_ACCESS;
                                goto freeit;
@@ -1712,11 +1715,9 @@ fe_acl_attribute(
                                op->o_tmpmemctx );
                        for ( i = 0, j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
                        {
+                               ak.ak_val = &a->a_nvals[i];
                                if ( op->o_conn && access > ACL_NONE && 
-                                       access_allowed( op, e, entry_at,
-                                                       &a->a_nvals[i],
-                                                       access,
-                                                       &acl_state ) == 0 )
+                                       access_allowed( op, &ak ) == 0 )
                                {
                                        continue;
                                }
@@ -1737,9 +1738,9 @@ fe_acl_attribute(
                                rc = LDAP_SUCCESS;
                        }
                }
-freeit:                if ( e != target ) {
+freeit:                if ( ak.ak_e != target ) {
                        op->o_private = e_priv;
-                       be_entry_release_r( op, e );
+                       be_entry_release_r( op, ak.ak_e );
                        op->o_private = o_priv;
                }
                if ( freeattr ) {
@@ -1781,50 +1782,43 @@ backend_attribute(
 int 
 backend_access(
        Operation               *op,
-       Entry                   *target,
-       struct berval           *edn,
-       AttributeDescription    *entry_at,
-       struct berval           *nval,
-       slap_access_t           access,
-       slap_mask_t             *mask )
+       AclCheck                *ak,
+       struct berval           *edn )
 {
-       Entry           *e = NULL;
        void            *o_priv = op->o_private, *e_priv = NULL;
        int             rc = LDAP_INSUFFICIENT_ACCESS;
        Backend         *be = op->o_bd;
+       int freeent = 0;
 
        /* pedantic */
        assert( op != NULL );
        assert( op->o_conn != NULL );
        assert( edn != NULL );
-       assert( access > ACL_NONE );
+       assert( ak->ak_access > ACL_NONE );
 
        if ( !op->o_bd ) {
                op->o_bd = select_backend( edn, 0 );
        }
 
-       if ( target && dn_match( &target->e_nname, edn ) ) {
-               e = target;
-
-       } else {
+       if ( !ak->ak_e || !dn_match( &ak->ak_e->e_nname, edn ) ) {
                op->o_private = NULL;
-               rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e );
+               rc = be_entry_get_rw( op, edn, NULL, ak->ak_desc, 0, &ak->ak_e );
+               freeent = 1;
                e_priv = op->o_private;
                op->o_private = o_priv;
        } 
 
-       if ( e ) {
+       if ( ak->ak_e ) {
                Attribute       *a = NULL;
                int             freeattr = 0;
 
-               if ( entry_at == NULL ) {
-                       entry_at = slap_schema.si_ad_entry;
+               if ( ak->ak_desc == NULL ) {
+                       ak->ak_desc = slap_schema.si_ad_entry;
                }
 
-               if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children )
+               if ( ak->ak_desc == slap_schema.si_ad_entry || ak->ak_desc == slap_schema.si_ad_children )
                {
-                       if ( access_allowed_mask( op, e, entry_at,
-                                       NULL, access, NULL, mask ) == 0 )
+                       if ( access_allowed( op, ak ) == 0 )
                        {
                                rc = LDAP_INSUFFICIENT_ACCESS;
 
@@ -1833,13 +1827,13 @@ backend_access(
                        }
 
                } else {
-                       a = attr_find( e->e_attrs, entry_at );
+                       a = attr_find( ak->ak_e->e_attrs, ak->ak_desc );
                        if ( a == NULL ) {
                                SlapReply       rs = { 0 };
                                AttributeName   anlist[ 2 ];
 
-                               anlist[ 0 ].an_name = entry_at->ad_cname;
-                               anlist[ 0 ].an_desc = entry_at;
+                               anlist[ 0 ].an_name = ak->ak_desc->ad_cname;
+                               anlist[ 0 ].an_desc = ak->ak_desc;
                                BER_BVZERO( &anlist[ 1 ].an_name );
                                rs.sr_attrs = anlist;
                        
@@ -1848,7 +1842,7 @@ backend_access(
                                /* NOTE: backend_operational() is also called
                                 * when returning results, so it's supposed
                                 * to do no harm to entries */
-                               rs.sr_entry = e;
+                               rs.sr_entry = ak->ak_e;
                                rc = backend_operational( op, &rs );
                                rs.sr_entry = NULL;
 
@@ -1864,8 +1858,7 @@ backend_access(
                        }
 
                        if ( a ) {
-                               if ( access_allowed_mask( op, e, entry_at,
-                                               nval, access, NULL, mask ) == 0 )
+                               if ( access_allowed( op, ak ) == 0 )
                                {
                                        rc = LDAP_INSUFFICIENT_ACCESS;
                                        goto freeit;
@@ -1873,9 +1866,9 @@ backend_access(
                                rc = LDAP_SUCCESS;
                        }
                }
-freeit:                if ( e != target ) {
+freeit:                if ( freeent ) {
                        op->o_private = e_priv;
-                       be_entry_release_r( op, e );
+                       be_entry_release_r( op, ak->ak_e );
                        op->o_private = o_priv;
                }
                if ( freeattr ) {
index ffa0251293fe48fce9f68f74741974408f1ecb97..1c4f4e1a2346a26fe6df7af2001792ef9171278f 100644 (file)
@@ -250,12 +250,7 @@ over_back_response ( Operation *op, SlapReply *rs )
 static int
 over_access_allowed(
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp )
+       AclCheck                *ak )
 {
        slap_overinfo *oi;
        slap_overinst *on;
@@ -286,8 +281,7 @@ over_access_allowed(
                        }
 
                        op->o_bd->bd_info = (BackendInfo *)on;
-                       rc = on->on_bi.bi_access_allowed( op, e,
-                               desc, val, access, state, maskp );
+                       rc = on->on_bi.bi_access_allowed( op, ak );
                        if ( rc != SLAP_CB_CONTINUE ) break;
                }
        }
@@ -307,8 +301,7 @@ over_access_allowed(
                        bi_access_allowed = slap_access_allowed;
                }
 
-               rc = bi_access_allowed( op, e,
-                       desc, val, access, state, maskp );
+               rc = bi_access_allowed( op, ak );
        }
        /* should not fall thru this far without anything happening... */
        if ( rc == SLAP_CB_CONTINUE ) {
index a04a33ad6d99413defc35f2f7496d7e7c5cf25ac..6a67f3851d82cb6a696d8a8f606485fb6ce3ff89 100644 (file)
@@ -4796,13 +4796,18 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
        }
 
        if ( op ) {
+               AclCheck ak;
                /* No parent, must be root. This will never happen... */
                if ( !last && !be_isroot( op ) && !be_shadow_update( op ) ) {
                        return LDAP_NO_SUCH_OBJECT;
                }
 
-               if ( last && !access_allowed( op, last->ce_entry,
-                       slap_schema.si_ad_children, NULL, ACL_WADD, NULL ) )
+               ak.ak_e = last->ce_entry;
+               ak.ak_desc = slap_schema.si_ad_children;
+               ak.ak_val = NULL;
+               ak.ak_access = ACL_WADD;
+               ak.ak_state = NULL;
+               if ( last && !access_allowed( op, &ak ))
                {
                        Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
                                "DN=\"%s\" no write access to \"children\" of parent\n",
@@ -5168,9 +5173,10 @@ config_back_add( Operation *op, SlapReply *rs )
        CfBackInfo *cfb;
        int renumber;
        ConfigArgs ca;
+       AclCheck ak = { op->ora_e, slap_schema.si_ad_entry,
+               NULL, ACL_WADD, NULL };
 
-       if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry,
-               NULL, ACL_WADD, NULL )) {
+       if ( !access_allowed( op, &ak )) {
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
                goto out;
        }
@@ -5711,6 +5717,7 @@ config_back_modrdn( Operation *op, SlapReply *rs )
        CfEntryInfo *ce, *last;
        struct berval rdn;
        int ixold, ixnew;
+       AclCheck ak;
 
        cfb = (CfBackInfo *)op->o_bd->be_private;
 
@@ -5721,18 +5728,22 @@ config_back_modrdn( Operation *op, SlapReply *rs )
                rs->sr_err = LDAP_NO_SUCH_OBJECT;
                goto out;
        }
-       if ( !access_allowed( op, ce->ce_entry, slap_schema.si_ad_entry,
-               NULL, ACL_WRITE, NULL )) {
+       ak.ak_e = ce->ce_entry;
+       ak.ak_desc = slap_schema.si_ad_entry;
+       ak.ak_val = NULL;
+       ak.ak_access = ACL_WRITE;
+       ak.ak_state = NULL;
+       if ( !access_allowed( op, &ak )) {
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
                goto out;
        }
-       { Entry *parent;
+       {
                if ( ce->ce_parent )
-                       parent = ce->ce_parent->ce_entry;
+                       ak.ak_e = ce->ce_parent->ce_entry;
                else
-                       parent = (Entry *)&slap_entry_root;
-               if ( !access_allowed( op, parent, slap_schema.si_ad_children,
-                       NULL, ACL_WRITE, NULL )) {
+                       ak.ak_e = (Entry *)&slap_entry_root;
+               ak.ak_desc = slap_schema.si_ad_children;
+               if ( !access_allowed( op, &ak )) {
                        rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
                        goto out;
                }
@@ -6014,7 +6025,7 @@ config_back_search( Operation *op, SlapReply *rs )
 {
        CfBackInfo *cfb;
        CfEntryInfo *ce, *last;
-       slap_mask_t mask;
+       AclCheck ak;
 
        cfb = (CfBackInfo *)op->o_bd->be_private;
 
@@ -6025,10 +6036,14 @@ config_back_search( Operation *op, SlapReply *rs )
                rs->sr_err = LDAP_NO_SUCH_OBJECT;
                goto out;
        }
-       if ( !access_allowed_mask( op, ce->ce_entry, slap_schema.si_ad_entry, NULL,
-               ACL_SEARCH, NULL, &mask ))
+       ak.ak_e = ce->ce_entry;
+       ak.ak_desc = slap_schema.si_ad_entry;
+       ak.ak_val = NULL;
+       ak.ak_access = ACL_SEARCH;
+       ak.ak_state = NULL;
+       if ( !access_allowed_mask( op, &ak ))
        {
-               if ( !ACL_GRANT( mask, ACL_DISCLOSE )) {
+               if ( !ACL_GRANT( ak.ak_mask, ACL_DISCLOSE )) {
                        rs->sr_err = LDAP_NO_SUCH_OBJECT;
                } else {
                        rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
index 1e9376a701f9f13cfbac4ed8a049d0cbc0e0f824..4532987066339b2f085c649c0282f8189a1597ec 100644 (file)
@@ -33,8 +33,7 @@
 
 static int compare_entry(
        Operation *op,
-       Entry *e,
-       AttributeAssertion *ava );
+       AclCheck *ak );
 
 int
 do_compare(
@@ -144,9 +143,9 @@ cleanup:;
 int
 fe_op_compare( Operation *op, SlapReply *rs )
 {
-       Entry                   *entry = NULL;
        AttributeAssertion      *ava = op->orc_ava;
        BackendDB               *bd = op->o_bd;
+       AclCheck        ak = { NULL };
 
        if( strcasecmp( op->o_req_ndn.bv_val, LDAP_ROOT_DSE ) == 0 ) {
                if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
@@ -154,7 +153,7 @@ fe_op_compare( Operation *op, SlapReply *rs )
                        goto cleanup;
                }
 
-               rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text );
+               rs->sr_err = root_dse_info( op->o_conn, &ak.ak_e, &rs->sr_text );
                if( rs->sr_err != LDAP_SUCCESS ) {
                        send_ldap_result( op, rs );
                        goto cleanup;
@@ -167,7 +166,7 @@ fe_op_compare( Operation *op, SlapReply *rs )
                        goto cleanup;
                }
 
-               rs->sr_err = schema_info( &entry, &rs->sr_text );
+               rs->sr_err = schema_info( &ak.ak_e, &rs->sr_text );
                if( rs->sr_err != LDAP_SUCCESS ) {
                        send_ldap_result( op, rs );
                        rs->sr_err = 0;
@@ -175,9 +174,13 @@ fe_op_compare( Operation *op, SlapReply *rs )
                }
        }
 
-       if( entry ) {
-               rs->sr_err = compare_entry( op, entry, ava );
-               entry_free( entry );
+       if( ak.ak_e ) {
+               ak.ak_desc = ava->aa_desc;
+               ak.ak_val = &ava->aa_value;
+               ak.ak_access = ACL_COMPARE;
+               ak.ak_state = NULL;
+               rs->sr_err = compare_entry( op, &ak );
+               entry_free( ak.ak_e );
 
                send_ldap_result( op, rs );
 
@@ -240,17 +243,19 @@ fe_op_compare( Operation *op, SlapReply *rs )
        {
                int     rc, hasSubordinates = LDAP_SUCCESS;
 
-               rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &entry );
-               if ( rc == 0 && entry ) {
-                       if ( ! access_allowed( op, entry,
-                               ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
+               rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &ak.ak_e );
+               if ( rc == 0 && ak.ak_e ) {
+                       ak.ak_desc = ava->aa_desc;
+                       ak.ak_val = &ava->aa_value;
+                       ak.ak_access = ACL_COMPARE;
+                       ak.ak_state = NULL;
+                       if ( ! access_allowed( op, &ak ))
                        {       
                                rc = rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
                                
                        } else {
                                rc = rs->sr_err = op->o_bd->be_has_subordinates( op,
-                                               entry, &hasSubordinates );
-                               be_entry_release_r( op, entry );
+                                               ak.ak_e, &hasSubordinates );
                        }
                }
 
@@ -269,13 +274,17 @@ fe_op_compare( Operation *op, SlapReply *rs )
                } else {
                        /* return error only if "disclose"
                         * is granted on the object */
-                       if ( backend_access( op, NULL, &op->o_req_ndn,
-                                       slap_schema.si_ad_entry,
-                                       NULL, ACL_DISCLOSE, NULL ) == LDAP_INSUFFICIENT_ACCESS )
+                       ak.ak_desc = slap_schema.si_ad_entry;
+                       ak.ak_val = NULL;
+                       ak.ak_access = ACL_DISCLOSE;
+                       ak.ak_state = NULL;
+                       if ( backend_access( op, &ak, &op->o_req_ndn )
+                                        == LDAP_INSUFFICIENT_ACCESS )
                        {
                                rs->sr_err = LDAP_NO_SUCH_OBJECT;
                        }
                }
+               be_entry_release_r( op, ak.ak_e );
 
                send_ldap_result( op, rs );
 
@@ -307,13 +316,17 @@ fe_op_compare( Operation *op, SlapReply *rs )
 
                rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn,
                                ava->aa_desc, &vals, ACL_COMPARE );
+
                switch ( rs->sr_err ) {
                default:
                        /* return error only if "disclose"
                         * is granted on the object */
-                       if ( backend_access( op, NULL, &op->o_req_ndn,
-                                       slap_schema.si_ad_entry,
-                                       NULL, ACL_DISCLOSE, NULL )
+                       ak.ak_e = NULL;
+                       ak.ak_desc = slap_schema.si_ad_entry;
+                       ak.ak_val = NULL;
+                       ak.ak_access = ACL_DISCLOSE;
+                       ak.ak_state = NULL;
+                       if ( backend_access( op, &ak, &op->o_req_ndn )
                                        == LDAP_INSUFFICIENT_ACCESS )
                        {
                                rs->sr_err = LDAP_NO_SUCH_OBJECT;
@@ -354,40 +367,45 @@ cleanup:;
 
 static int compare_entry(
        Operation *op,
-       Entry *e,
-       AttributeAssertion *ava )
+       AclCheck *ak )
 {
        int rc = LDAP_COMPARE_FALSE;
        Attribute *a;
+       AttributeDescription *ad;
 
-       if ( ! access_allowed( op, e,
-               ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
+       if ( ! access_allowed( op, ak ))
        {       
                rc = LDAP_INSUFFICIENT_ACCESS;
                goto done;
        }
 
-       a = attrs_find( e->e_attrs, ava->aa_desc );
+       a = attrs_find( ak->ak_e->e_attrs, ak->ak_desc );
        if( a == NULL ) {
                rc = LDAP_NO_SUCH_ATTRIBUTE;
                goto done;
        }
 
-       for(a = attrs_find( e->e_attrs, ava->aa_desc );
+       ad = ak->ak_desc;
+       for(a = attrs_find( ak->ak_e->e_attrs, ak->ak_desc );
                a != NULL;
-               a = attrs_find( a->a_next, ava->aa_desc ))
+               a = attrs_find( a->a_next, ak->ak_desc ))
        {
-               if (( ava->aa_desc != a->a_desc ) && ! access_allowed( op,
-                       e, a->a_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
-               {       
-                       rc = LDAP_INSUFFICIENT_ACCESS;
-                       break;
+               ak->ak_desc = a->a_desc;
+               if ( a->a_desc != ak->ak_desc )
+               {
+                       ak->ak_desc = a->a_desc;
+                       if ( !access_allowed( op, ak ))
+                       {
+                               rc = LDAP_INSUFFICIENT_ACCESS;
+                               break;
+                       }
+                       ak->ak_desc = ad;
                }
 
                if ( attr_valfind( a, 
                        SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-                       &ava->aa_value, NULL, op->o_tmpmemctx ) == 0 )
+                       ak->ak_val, NULL, op->o_tmpmemctx ) == 0 )
                {
                        rc = LDAP_COMPARE_TRUE;
                        break;
@@ -396,8 +414,10 @@ static int compare_entry(
 
 done:
        if( rc != LDAP_COMPARE_TRUE && rc != LDAP_COMPARE_FALSE ) {
-               if ( ! access_allowed( op, e,
-                       slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) )
+               ak->ak_desc = slap_schema.si_ad_entry;
+               ak->ak_val = NULL;
+               ak->ak_access = ACL_DISCLOSE;
+               if ( ! access_allowed( op, ak ))
                {
                        rc = LDAP_NO_SUCH_OBJECT;
                }
index 82a36c33d2b8adb531807049d546384a184c5de7..1a0b56c93e5e0902279549ed49f752ff44b97840 100644 (file)
@@ -163,6 +163,7 @@ static int test_mra_filter(
        Attribute       *a;
        void            *memctx;
        BER_MEMFREE_FN  *memfree;
+       AclCheck        ak;
 #ifdef LDAP_COMP_MATCH
        int i, num_attr_vals = 0;
 #endif
@@ -175,14 +176,19 @@ static int test_mra_filter(
                memfree = op->o_tmpfree;
        }
 
+       ak.ak_e = e;
+       ak.ak_access = ACL_SEARCH;
+       ak.ak_state = NULL;
+
        if ( mra->ma_desc ) {
                /*
                 * if ma_desc is available, then we're filtering for
                 * one attribute, and SEARCH permissions can be checked
                 * directly.
                 */
-               if ( !access_allowed( op, e,
-                       mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
+               ak.ak_desc = mra->ma_desc;
+               ak.ak_val = &mra->ma_value;
+               if ( !access_allowed( op, &ak ))
                {
                        return LDAP_INSUFFICIENT_ACCESS;
                }
@@ -345,8 +351,9 @@ static int test_mra_filter(
                        if ( rc != LDAP_SUCCESS ) continue;
 
                        /* check search access */
-                       if ( !access_allowed( op, e,
-                               a->a_desc, &value, ACL_SEARCH, NULL ) )
+                       ak.ak_desc = a->a_desc;
+                       ak.ak_val = &value;
+                       if ( !access_allowed( op, &ak ))
                        {
                                memfree( value.bv_val, memctx );
                                continue;
@@ -470,8 +477,9 @@ static int test_mra_filter(
                                        if ( rc != LDAP_SUCCESS ) continue;
 
                                        /* check search access */
-                                       if ( !access_allowed( op, e,
-                                               ad, &value, ACL_SEARCH, NULL ) )
+                                       ak.ak_desc = ad;
+                                       ak.ak_val = &value;
+                                       if ( !access_allowed( op, &ak ))
                                        {
                                                memfree( value.bv_val, memctx );
                                                continue;
@@ -532,13 +540,13 @@ test_ava_filter(
 {
        int rc;
        Attribute       *a;
+       AclCheck ak = { e, ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL };
 #ifdef LDAP_COMP_MATCH
        int i, num_attr_vals = 0;
        AttributeAliasing *a_alias = NULL;
 #endif
 
-       if ( !access_allowed( op, e,
-               ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL ) )
+       if ( !access_allowed( op, &ak ))
        {
                return LDAP_INSUFFICIENT_ACCESS;
        }
@@ -620,11 +628,17 @@ test_ava_filter(
                MatchingRule *mr;
                struct berval *bv;
 
-               if (( ava->aa_desc != a->a_desc ) && !access_allowed( op,
-                       e, a->a_desc, &ava->aa_value, ACL_SEARCH, NULL ))
+               if ( ava->aa_desc != a->a_desc )
                {
-                       rc = LDAP_INSUFFICIENT_ACCESS;
-                       continue;
+                       int ret;
+                       ak.ak_desc = a->a_desc;
+                       ret = access_allowed( op, &ak );
+                       ak.ak_desc = ava->aa_desc;
+                       if ( !ret )
+                       {
+                               rc = LDAP_INSUFFICIENT_ACCESS;
+                               continue;
+                       }
                }
 
                use = SLAP_MR_EQUALITY;
@@ -817,8 +831,9 @@ test_presence_filter(
 {
        Attribute       *a;
        int rc;
+       AclCheck ak = { e, desc, NULL, ACL_SEARCH, NULL };
 
-       if ( !access_allowed( op, e, desc, NULL, ACL_SEARCH, NULL ) ) {
+       if ( !access_allowed( op, &ak ) ) {
                return LDAP_INSUFFICIENT_ACCESS;
        }
 
@@ -849,11 +864,17 @@ test_presence_filter(
                a != NULL;
                a = attrs_find( a->a_next, desc ) )
        {
-               if (( desc != a->a_desc ) && !access_allowed( op,
-                       e, a->a_desc, NULL, ACL_SEARCH, NULL ))
+               if ( desc != a->a_desc )
                {
-                       rc = LDAP_INSUFFICIENT_ACCESS;
-                       continue;
+                       int ret;
+                       ak.ak_desc = a->a_desc;
+                       ret = access_allowed( op, &ak );
+                       ak.ak_desc = desc;
+                       if ( !ret )
+                       {
+                               rc = LDAP_INSUFFICIENT_ACCESS;
+                               continue;
+                       }
                }
 
                rc = LDAP_COMPARE_TRUE;
@@ -934,11 +955,11 @@ test_substrings_filter(
 {
        Attribute       *a;
        int rc;
+       AclCheck ak = { e, f->f_sub_desc, NULL, ACL_SEARCH, NULL };
 
        Debug( LDAP_DEBUG_FILTER, "begin test_substrings_filter\n", 0, 0, 0 );
 
-       if ( !access_allowed( op, e,
-               f->f_sub_desc, NULL, ACL_SEARCH, NULL ) )
+       if ( !access_allowed( op, &ak ))
        {
                return LDAP_INSUFFICIENT_ACCESS;
        }
@@ -952,11 +973,17 @@ test_substrings_filter(
                MatchingRule *mr;
                struct berval *bv;
 
-               if (( f->f_sub_desc != a->a_desc ) && !access_allowed( op,
-                       e, a->a_desc, NULL, ACL_SEARCH, NULL ))
+               if ( f->f_sub_desc != a->a_desc )
                {
-                       rc = LDAP_INSUFFICIENT_ACCESS;
-                       continue;
+                       int ret;
+                       ak.ak_desc = a->a_desc;
+                       ret = access_allowed( op, &ak );
+                       ak.ak_desc = f->f_sub_desc;
+                       if ( !ret )
+                       {
+                               rc = LDAP_INSUFFICIENT_ACCESS;
+                               continue;
+                       }
                }
 
                mr = a->a_desc->ad_type->sat_substr;
index 15908cec84715e85c255a1b7f01a2336abb7c140..9dc82145b09a13b9cfef937997a9a144b624d2e8 100644 (file)
@@ -505,9 +505,9 @@ slap_passwd_check(
        const char      **text )
 {
        int                     result = 1;
-       struct berval           *bv;
        AccessControlState      acl_state = ACL_STATE_INIT;
        char            credNul = cred->bv_val[cred->bv_len];
+       AclCheck        ak;
 
 #ifdef SLAPD_SPASSWD
        void            *old_authctx = NULL;
@@ -518,15 +518,19 @@ slap_passwd_check(
 
        if ( credNul ) cred->bv_val[cred->bv_len] = 0;
 
-       for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
+       ak.ak_e = e;
+       ak.ak_desc = a->a_desc;
+       ak.ak_access = ACL_AUTH;
+       ak.ak_state = &acl_state;
+
+       for ( ak.ak_val = a->a_vals; ak.ak_val->bv_val != NULL; ak.ak_val++ ) {
                /* if e is provided, check access */
-               if ( e && access_allowed( op, e, a->a_desc, bv,
-                                       ACL_AUTH, &acl_state ) == 0 )
+               if ( e && access_allowed( op, &ak ) == 0 )
                {
                        continue;
                }
                
-               if ( !lutil_passwd( bv, cred, NULL, text ) ) {
+               if ( !lutil_passwd( ak.ak_val, cred, NULL, text ) ) {
                        result = 0;
                        break;
                }
index 62ea62815edd4979654a9191dc84e872c5f55f81..58e04e43e956660d79bd33e1cb8453af275687dc 100644 (file)
@@ -46,29 +46,15 @@ LDAP_SLAPD_F (int) dynacl_aci_init LDAP_P(( void ));
 /*
  * acl.c
  */
-LDAP_SLAPD_F (int) access_allowed_mask LDAP_P((
-       Operation *op,
-       Entry *e, AttributeDescription *desc, struct berval *val,
-       slap_access_t access,
-       AccessControlState *state,
-       slap_mask_t *mask ));
+LDAP_SLAPD_F (int) access_allowed LDAP_P((
+       Operation *op, AclCheck *ak ));
+#if 0
 #define access_allowed(op,e,desc,val,access,state) access_allowed_mask(op,e,desc,val,access,state,NULL)
+#endif
 LDAP_SLAPD_F (int) slap_access_allowed LDAP_P((
-       Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp ));
+       Operation *op, AclCheck *ak ));
 LDAP_SLAPD_F (int) slap_access_always_allowed LDAP_P((
-       Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp ));
+       Operation *op, AclCheck *ak ));
 
 LDAP_SLAPD_F (int) acl_check_modlist LDAP_P((
        Operation *op, Entry *e, Modifications *ml ));
@@ -416,12 +402,8 @@ LDAP_SLAPD_F (int) backend_attribute LDAP_P((
 
 LDAP_SLAPD_F (int) backend_access LDAP_P((
        Operation               *op,
-       Entry                   *target,
-       struct berval           *edn,
-       AttributeDescription    *entry_at,
-       struct berval           *nval,
-       slap_access_t           access,
-       slap_mask_t             *mask ));
+       AclCheck                *ak,
+       struct berval           *edn ));
 
 LDAP_SLAPD_F (int) backend_operational LDAP_P((
        Operation *op,
@@ -2043,12 +2025,7 @@ LDAP_SLAPD_F (int) fe_acl_attribute LDAP_P((
        slap_access_t access ));
 LDAP_SLAPD_F (int) fe_access_allowed LDAP_P((
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp ));
+       AclCheck                *ak ));
 
 /* NOTE: this macro assumes that bv has been allocated
  * by ber_* malloc functions or is { 0L, NULL } */
index e89090db148db22c007ba95ac7025a66ddc3f0f2..2014864e856dc945a2439af5667095bc7d568d21 100644 (file)
@@ -847,6 +847,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
        AccessControlState acl_state = ACL_STATE_INIT;
        int                      attrsonly;
        AttributeDescription *ad_entry = slap_schema.si_ad_entry;
+       AclCheck        ak;
 
        /* a_flags: array of flags telling if the i-th element will be
         *          returned or filtered out
@@ -896,7 +897,12 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
        attrsonly = op->ors_attrsonly;
 
-       if ( !access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL )) {
+       ak.ak_e = rs->sr_entry;
+       ak.ak_desc = ad_entry;
+       ak.ak_val = NULL;
+       ak.ak_access = ACL_READ;
+       ak.ak_state = NULL;
+       if ( !access_allowed( op, &ak )) {
                Debug( LDAP_DEBUG_ACL,
                        "send_search_entry: conn %lu access to entry (%s) not allowed\n", 
                        op->o_connid, rs->sr_entry->e_name.bv_val, 0 );
@@ -999,6 +1005,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                }
        }
 
+       ak.ak_state = &acl_state;
        for ( a = rs->sr_entry->e_attrs, j = 0; a != NULL; a = a->a_next, j++ ) {
                AttributeDescription *desc = a->a_desc;
                int finish = 0;
@@ -1029,9 +1036,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        }
                }
 
+               ak.ak_desc = desc;
                if ( attrsonly ) {
-                       if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
-                               ACL_READ, &acl_state ) )
+                       if ( ! access_allowed( op, &ak ))
                        {
                                Debug( LDAP_DEBUG_ACL, "send_search_entry: "
                                        "conn %lu access to attribute %s not allowed\n",
@@ -1055,8 +1062,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                } else {
                        int first = 1;
                        for ( i = 0; a->a_nvals[i].bv_val != NULL; i++ ) {
-                               if ( ! access_allowed( op, rs->sr_entry,
-                                       desc, &a->a_nvals[i], ACL_READ, &acl_state ) )
+                               ak.ak_val = &a->a_nvals[i];
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        Debug( LDAP_DEBUG_ACL,
                                                "send_search_entry: conn %lu "
@@ -1190,8 +1197,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
-                       ACL_READ, &acl_state ) )
+               ak.ak_desc = desc;
+               if ( ! access_allowed( op, &ak ))
                {
                        Debug( LDAP_DEBUG_ACL,
                                "send_search_entry: conn %lu "
@@ -1216,8 +1223,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
-                               if ( ! access_allowed( op, rs->sr_entry,
-                                       desc, &a->a_vals[i], ACL_READ, &acl_state ) )
+                               ak.ak_val = &a->a_vals[i];
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        Debug( LDAP_DEBUG_ACL,
                                                "send_search_entry: conn %lu "
@@ -1383,25 +1390,29 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
                "=> send_search_reference: dn=\"%s\"\n",
                edn, 0, 0 );
 
-       if (  rs->sr_entry && ! access_allowed( op, rs->sr_entry,
-               ad_entry, NULL, ACL_READ, NULL ) )
+       if ( rs->sr_entry )
        {
-               Debug( LDAP_DEBUG_ACL,
-                       "send_search_reference: access to entry not allowed\n",
-                   0, 0, 0 );
-               rc = 1;
-               goto rel;
-       }
+               AclCheck ak = { rs->sr_entry, ad_entry, NULL, ACL_READ, NULL };
 
-       if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
-               ad_ref, NULL, ACL_READ, NULL ) )
-       {
-               Debug( LDAP_DEBUG_ACL,
-                       "send_search_reference: access "
-                       "to reference not allowed\n",
-                   0, 0, 0 );
-               rc = 1;
-               goto rel;
+               if ( !access_allowed( op, &ak ))
+               {
+                       Debug( LDAP_DEBUG_ACL,
+                               "send_search_reference: access to entry not allowed\n",
+                               0, 0, 0 );
+                       rc = 1;
+                       goto rel;
+               }
+
+               ak.ak_desc = ad_ref;
+               if ( !access_allowed( op, &ak ))
+               {
+                       Debug( LDAP_DEBUG_ACL,
+                               "send_search_reference: access "
+                               "to reference not allowed\n",
+                               0, 0, 0 );
+                       rc = 1;
+                       goto rel;
+               }
        }
 
        if( op->o_domain_scope ) {
index 279731f40be27d3759c1fca6e005e1c0b3f705b7..820f2936b46f36ec6ec46bc519c9cf31d031fba6 100644 (file)
@@ -178,9 +178,15 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
        const char *text;
        int rc, i;
        lookup_info *sl = (lookup_info *)op->o_callback->sc_private;
+       AclCheck ak;
 
        if (rs->sr_type != REP_SEARCH) return 0;
 
+       ak.ak_e = rs->sr_entry;
+       ak.ak_val = NULL;
+       ak.ak_access = ACL_AUTH;
+       ak.ak_state = NULL;
+
        for( i = 0; sl->list[i].name; i++ ) {
                const char *name = sl->list[i].name;
 
@@ -215,7 +221,8 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
 
                a = attr_find( rs->sr_entry->e_attrs, ad );
                if ( !a ) continue;
-               if ( ! access_allowed( op, rs->sr_entry, ad, NULL, ACL_AUTH, NULL ) ) {
+               ak.ak_desc = ad;
+               if ( ! access_allowed( op, &ak ) ) {
                        continue;
                }
                if ( sl->list[i].values && ( sl->flags & SASL_AUXPROP_OVERRIDE ) ) {
index 567f35665447784b26cb92b9be109c0269f19b59..2babb3b5c69e78234b08b253c1474955598a1c31 100644 (file)
@@ -1298,38 +1298,6 @@ typedef struct AuthorizationInformation {
        slap_ssf_t      sai_sasl_ssf;           /* SASL SSF */
 } AuthorizationInformation;
 
-#ifdef SLAP_DYNACL
-
-/*
- * "dynamic" ACL infrastructure (for ACIs and more)
- */
-typedef int (slap_dynacl_parse) LDAP_P(( const char *fname, int lineno,
-       const char *opts, slap_style_t, const char *, void **privp ));
-typedef int (slap_dynacl_unparse) LDAP_P(( void *priv, struct berval *bv ));
-typedef int (slap_dynacl_mask) LDAP_P((
-               void                    *priv,
-               Operation               *op,
-               Entry                   *e,
-               AttributeDescription    *desc,
-               struct berval           *val,
-               int                     nmatch,
-               regmatch_t              *matches,
-               slap_access_t           *grant,
-               slap_access_t           *deny ));
-typedef int (slap_dynacl_destroy) LDAP_P(( void *priv ));
-
-typedef struct slap_dynacl_t {
-       char                    *da_name;
-       slap_dynacl_parse       *da_parse;
-       slap_dynacl_unparse     *da_unparse;
-       slap_dynacl_mask        *da_mask;
-       slap_dynacl_destroy     *da_destroy;
-       
-       void                    *da_private;
-       struct slap_dynacl_t    *da_next;
-} slap_dynacl_t;
-#endif /* SLAP_DYNACL */
-
 /* the DN portion of the "by" part */
 typedef struct slap_dn_access {
        /* DN pattern */
@@ -1549,6 +1517,15 @@ typedef struct AccessControlState {
 } AccessControlState;
 #define ACL_STATE_INIT { NULL, ACL_NONE, NULL, 0, ACL_PRIV_NONE, -1, 0 }
 
+typedef struct AclCheck {
+       Entry *ak_e;
+       AttributeDescription *ak_desc;
+       struct berval *ak_val;
+       slap_access_t ak_access;
+       AccessControlState *ak_state;
+       slap_mask_t ak_mask;
+} AclCheck;
+
 typedef struct AclRegexMatches {        
        int dn_count;
         regmatch_t dn_data[MAXREMATCHES];
@@ -1556,6 +1533,38 @@ typedef struct AclRegexMatches {
         regmatch_t val_data[MAXREMATCHES];
 } AclRegexMatches;
 
+#ifdef SLAP_DYNACL
+
+/*
+ * "dynamic" ACL infrastructure (for ACIs and more)
+ */
+typedef int (slap_dynacl_parse) LDAP_P(( const char *fname, int lineno,
+       const char *opts, slap_style_t, const char *, void **privp ));
+typedef int (slap_dynacl_unparse) LDAP_P(( void *priv, struct berval *bv ));
+typedef int (slap_dynacl_mask) LDAP_P((
+               void                    *priv,
+               Operation               *op,
+               Entry                   *e,
+               AttributeDescription    *desc,
+               struct berval           *val,
+               int                     nmatch,
+               regmatch_t              *matches,
+               slap_access_t           *grant,
+               slap_access_t           *deny ));
+typedef int (slap_dynacl_destroy) LDAP_P(( void *priv ));
+
+typedef struct slap_dynacl_t {
+       char                    *da_name;
+       slap_dynacl_parse       *da_parse;
+       slap_dynacl_unparse     *da_unparse;
+       slap_dynacl_mask        *da_mask;
+       slap_dynacl_destroy     *da_destroy;
+       
+       void                    *da_private;
+       struct slap_dynacl_t    *da_next;
+} slap_dynacl_t;
+#endif /* SLAP_DYNACL */
+
 /*
  * Backend-info
  * represents a backend 
@@ -2145,9 +2154,7 @@ typedef int (BI_entry_get_rw) LDAP_P(( Operation *op, struct berval *ndn,
 typedef int (BI_operational) LDAP_P(( Operation *op, SlapReply *rs ));
 typedef int (BI_has_subordinates) LDAP_P(( Operation *op,
        Entry *e, int *hasSubs ));
-typedef int (BI_access_allowed) LDAP_P(( Operation *op, Entry *e,
-       AttributeDescription *desc, struct berval *val, slap_access_t access,
-       AccessControlState *state, slap_mask_t *maskp ));
+typedef int (BI_access_allowed) LDAP_P(( Operation *op, AclCheck *ak ));
 typedef int (BI_acl_group) LDAP_P(( Operation *op, Entry *target,
        struct berval *gr_ndn, struct berval *op_ndn,
        ObjectClass *group_oc, AttributeDescription *group_at ));
index c02d5db3b14485e012a1b15e8453269746388447..7041bb28cbd897752f3f806f5f44b017fac0558b 100644 (file)
 static int
 print_access(
        Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       struct berval           *nval )
+       AclCheck                *ak,
+       struct berval           *val )
 {
        int                     rc;
-       slap_mask_t             mask;
        char                    accessmaskbuf[ACCESSMASK_MAXLEN];
 
-       rc = access_allowed_mask( op, e, desc, nval, ACL_AUTH, NULL, &mask );
+       rc = access_allowed( op, ak );
 
        fprintf( stderr, "%s%s%s: %s\n",
-                       desc->ad_cname.bv_val,
-                       ( val && !BER_BVISNULL( val ) ) ? "=" : "",
-                       ( val && !BER_BVISNULL( val ) ) ?
-                               ( desc == slap_schema.si_ad_userPassword ?
-                                       "****" : val->bv_val ) : "",
-                       accessmask2str( mask, accessmaskbuf, 1 ) );
+                       ak->ak_desc->ad_cname.bv_val,
+                       ( ak->ak_val && !BER_BVISNULL( ak->ak_val ) ) ? "=" : "",
+                       ( ak->ak_val && !BER_BVISNULL( ak->ak_val ) ) ?
+                               ( ak->ak_desc == slap_schema.si_ad_userPassword ?
+                                       "****" : ak->ak_val->bv_val ) : "",
+                       accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
 
        return rc;
 }
@@ -74,6 +71,7 @@ slapacl( int argc, char **argv )
        int                     doclose = 0;
        BackendDB               *bd;
        void                    *thrctx;
+       AclCheck                ak;
 
        slap_tool_init( progname, SLAPACL, argc, argv );
 
@@ -277,33 +275,36 @@ slapacl( int argc, char **argv )
 
                }
 
+               ak.ak_e = ep;
+               ak.ak_access = ACL_AUTH;
+               ak.ak_state = NULL;
+
                if ( argc == 0 ) {
                        Attribute       *a;
 
-                       (void)print_access( op, ep, slap_schema.si_ad_entry, NULL, NULL );
-                       (void)print_access( op, ep, slap_schema.si_ad_children, NULL, NULL );
+                       ak.ak_val = NULL;
+                       ak.ak_desc = slap_schema.si_ad_entry;
+                       (void)print_access( op, &ak, NULL );
+                       ak.ak_desc = slap_schema.si_ad_children;
+                       (void)print_access( op, &ak, NULL );
 
                        for ( a = ep->e_attrs; a; a = a->a_next ) {
                                int     i;
 
                                for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ ) {
-                                       (void)print_access( op, ep, a->a_desc,
-                                                       &a->a_vals[ i ],
-                                                       &a->a_nvals[ i ] );
+                                       ak.ak_desc = a->a_desc;
+                                       ak.ak_val = &a->a_nvals[i];
+                                       (void)print_access( op, &ak, &a->a_vals[ i ] );
                                }
                        }
                }
        }
 
        for ( ; argc--; argv++ ) {
-               slap_mask_t             mask;
-               AttributeDescription    *desc = NULL;
-               struct berval           val = BER_BVNULL,
-                                       *valp = NULL;
+               struct berval           val = BER_BVNULL;
                const char              *text;
                char                    accessmaskbuf[ACCESSMASK_MAXLEN];
                char                    *accessstr;
-               slap_access_t           access = ACL_AUTH;
 
                if ( attr == NULL ) {
                        attr = argv[ 0 ];
@@ -314,17 +315,20 @@ slapacl( int argc, char **argv )
                        val.bv_val[0] = '\0';
                        val.bv_val++;
                        val.bv_len = strlen( val.bv_val );
-                       valp = &val;
+                       ak.ak_val = &val;
+               } else {
+                       ak.ak_val = NULL;
                }
 
+               ak.ak_access = ACL_AUTH;
                accessstr = strchr( attr, '/' );
                if ( accessstr != NULL ) {
                        int     invalid = 0;
 
                        accessstr[0] = '\0';
                        accessstr++;
-                       access = str2access( accessstr );
-                       switch ( access ) {
+                       ak.ak_access = str2access( accessstr );
+                       switch ( ak.ak_access ) {
                        case ACL_INVALID_ACCESS:
                                fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n",
                                                accessstr, attr );
@@ -349,7 +353,8 @@ slapacl( int argc, char **argv )
                        }
                }
 
-               rc = slap_str2ad( attr, &desc, &text );
+               ak.ak_desc = NULL;
+               rc = slap_str2ad( attr, &ak.ak_desc, &text );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr, "slap_str2ad(%s) failed %d (%s)\n",
                                        attr, rc, ldap_err2string( rc ) );
@@ -359,23 +364,22 @@ slapacl( int argc, char **argv )
                        break;
                }
 
-               rc = access_allowed_mask( op, ep, desc, valp, access,
-                               NULL, &mask );
+               rc = access_allowed( op, &ak );
 
                if ( accessstr ) {
                        fprintf( stderr, "%s access to %s%s%s: %s\n",
                                        accessstr,
-                                       desc->ad_cname.bv_val,
+                                       ak.ak_desc->ad_cname.bv_val,
                                        val.bv_val ? "=" : "",
                                        val.bv_val ? val.bv_val : "",
                                        rc ? "ALLOWED" : "DENIED" );
 
                } else {
                        fprintf( stderr, "%s%s%s: %s\n",
-                                       desc->ad_cname.bv_val,
+                                       ak.ak_desc->ad_cname.bv_val,
                                        val.bv_val ? "=" : "",
                                        val.bv_val ? val.bv_val : "",
-                                       accessmask2str( mask, accessmaskbuf, 1 ) );
+                                       accessmask2str( ak.ak_mask, accessmaskbuf, 1 ) );
                }
                rc = 0;
                attr = NULL;