oprofile shows quite a bit more overhead in 2.4's ACL processing vs 2.3's. I'm thinking of streamlining things a bit, along these lines. Any thoughts?

This acl.c compiles, but a fair amount of slapd code needs to be altered to use it. I guess if we commit and move forward on it it will have to be for 2.5.
--
  -- Howard Chu
  CTO, Symas Corp.           http://www.symas.com
  Director, Highland Sun     http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/
Index: proto-slap.h
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.796
diff -u -w -u -r1.796 proto-slap.h
--- proto-slap.h        9 Dec 2009 23:07:35 -0000       1.796
+++ proto-slap.h        10 Dec 2009 22:29:42 -0000
@@ -47,28 +47,12 @@
  * 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 ));
+       Operation *op, AclCheck *ak ));
 #define access_allowed(op,e,desc,val,access,state) 
access_allowed_mask(op,e,desc,val,access,state,NULL)
 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 ));
@@ -2043,12 +2027,7 @@
        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: slap.h
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/slap.h,v
retrieving revision 1.887
diff -u -w -u -r1.887 slap.h
--- slap.h      10 Dec 2009 18:54:57 -0000      1.887
+++ slap.h      10 Dec 2009 22:29:42 -0000
@@ -1298,38 +1298,6 @@
        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 @@
 } 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 @@
         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_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: acl.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/acl.c,v
retrieving revision 1.351
diff -u -w -u -r1.351 acl.c
--- acl.c       8 Sep 2009 19:06:15 -0000       1.351
+++ acl.c       10 Dec 2009 22:29:42 -0000
@@ -48,23 +48,16 @@
 #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 @@
 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 @@
 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 @@
 #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 @@
         * 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 @@
                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 @@
        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 )
-       {
-               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 );
+       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 = 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 @@
 
                /* 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 @@
 
                /* 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 @@
                        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 @@
                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 @@
                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,7 +321,7 @@
                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;
@@ -354,12 +330,7 @@
 int
 access_allowed_mask(
        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 @@
 #ifdef LDAP_DEBUG
        char                            accessmaskbuf[ACCESSMASK_MAXLEN];
 #endif
-       slap_mask_t                     mask;
        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 @@
                }
        }
 
+       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 @@
        /* 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 @@
 
        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 @@
 
 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 @@
 
                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 @@
                                                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 @@
                                *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 @@
 
                /* 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 @@
                                        "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 @@
                                        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 @@
                                        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 @@
                                        } 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 @@
                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 @@
  * 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 @@
                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 @@
 
                        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 @@
                        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 @@
                        }
 
                        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 @@
                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 @@
 
                        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 @@
                        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 @@
                        }
 
                        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 @@
 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 @@
        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 @@
                 */
                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 @@
                /* 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 @@
                 */
                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 @@
 
 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 @@
 #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 @@
                         * 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 @@
                                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 @@
                        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 @@
 
                                        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 @@
                        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 @@
                                                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 @@
                        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 @@
 
                                                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 @@
                        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 @@
 
                                        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 @@
                }
 
                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 @@
                                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 @@
                                /* 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 @@
                                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 @@
                                }
                                
                                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 @@
                                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 @@
                                /* 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 @@
                                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 @@
                                }
                                
                                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 @@
                                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 @@
                        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 @@
                        /* 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 @@
                                 * 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 @@
                                        ? "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 @@
        }
 
        /* 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 @@
        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 @@
                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 @@
                        continue;
                }
 
+               ak.ak_desc = mlist->sml_desc;
                switch ( mlist->sml_op ) {
                case LDAP_MOD_REPLACE:
                case LDAP_MOD_INCREMENT:
@@ -1971,10 +1929,9 @@
                         * 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_mask( op, &ak ))
                        {
                                ret = 0;
                                goto done;
@@ -1986,15 +1943,13 @@
 
                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_mask( op, &ak ))
                                {
                                        ret = 0;
                                        goto done;
@@ -2004,24 +1959,20 @@
 
                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_mask( 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_mask( op, &ak ))
                                {
                                        ret = 0;
                                        goto done;

Reply via email to