]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/acl.c
more cleanup; add the frontend to the set of monitored databases; handle exceptional...
[openldap] / servers / slapd / acl.c
index 62593991f6d23c03f51decbc9b84ab428cde6555..7b1c4a0854556da8466b02fd5dc56ff02ec7528a 100644 (file)
@@ -94,7 +94,6 @@ SLAP_SET_GATHER acl_set_gather2;
  * - can be legally called with op->o_bd == NULL
  */
 
-#ifdef SLAP_OVERLAY_ACCESS
 int
 slap_access_always_allowed(
        Operation               *op,
@@ -135,7 +134,6 @@ slap_access_allowed(
        slap_access_t                   access_level;
        const char                      *attr;
        regmatch_t                      matches[MAXREMATCHES];
-       int                             st_same_attr = 0;
 
        assert( op != NULL );
        assert( e != NULL );
@@ -199,24 +197,17 @@ slap_access_allowed(
        ret = 0;
        control = ACL_BREAK;
 
-       if ( st_same_attr ) {
-               assert( state->as_vd_acl != NULL );
-
+       if ( state && state->as_vd_ad == desc ) {
                a = state->as_vd_acl;
                count = state->as_vd_acl_count;
-               if ( !ACL_IS_INVALID( state->as_vd_acl_mask ) ) {
-                       mask = state->as_vd_acl_mask;
-                       AC_MEMCPY( matches, state->as_vd_acl_matches, sizeof(matches) );
-                       goto vd_access;
-               }
 
        } else {
                if ( state ) state->as_vi_acl = NULL;
                a = NULL;
-               ACL_PRIV_ASSIGN( mask, *maskp );
                count = 0;
-               memset( matches, '\0', sizeof( matches ) );
        }
+       ACL_PRIV_ASSIGN( mask, *maskp );
+       memset( matches, '\0', sizeof( matches ) );
 
        while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
                MAXREMATCHES, matches, state ) ) != NULL )
@@ -341,7 +332,6 @@ access_allowed_mask(
        slap_mask_t                     mask;
        slap_access_t                   access_level;
        const char                      *attr;
-       int                             st_same_attr = 0;
        static AccessControlState       state_init = ACL_STATE_INIT;
 
        assert( e != NULL );
@@ -364,7 +354,7 @@ access_allowed_mask(
                {
                        access = ACL_AUTH;
 
-               } else if ( get_manageDIT( op ) && access_level == ACL_WRITE &&
+               } else if ( get_relax( op ) && access_level == ACL_WRITE &&
                        desc == slap_schema.si_ad_entry )
                {
                        access = ACL_MANAGE;
@@ -378,17 +368,10 @@ access_allowed_mask(
                        {
                                return state->as_result;
 
-                       } else if ( ( state->as_recorded & ACL_STATE_RECORDED_VD ) &&
-                               val != NULL && state->as_vd_acl == NULL )
-                       {
-                               return state->as_result;
                        }
-                       st_same_attr = 1;
                } else {
                        *state = state_init;
                }
-
-               state->as_vd_ad = desc;
        }
 
        Debug( LDAP_DEBUG_ACL,
@@ -404,14 +387,12 @@ access_allowed_mask(
                op->o_bd = LDAP_STAILQ_FIRST( &backendDB );
                be_null = 1;
 
-#ifdef LDAP_DEVEL
-               /*
-                * FIXME: experimental; use first backend rules
-                * iff there is no global_acl (ITS#3100) */
+               /* FIXME: experimental; use first backend rules
+                * iff there is no global_acl (ITS#3100)
+                */
                if ( frontendDB->be_acl != NULL ) {
                        op->o_bd = frontendDB;
                }
-#endif /* LDAP_DEVEL */
        }
        assert( op->o_bd != NULL );
 
@@ -456,287 +437,13 @@ done:
                        state->as_result = ret;
                }
                state->as_recorded |= ACL_STATE_RECORDED;
-       }
-       if ( be_null ) op->o_bd = NULL;
-       if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
-       return ret;
-}
-
-#else /* !SLAP_OVERLAY_ACCESS */
-
-int
-access_allowed_mask(
-       Operation               *op,
-       Entry                   *e,
-       AttributeDescription    *desc,
-       struct berval           *val,
-       slap_access_t           access,
-       AccessControlState      *state,
-       slap_mask_t             *maskp )
-{
-       int                             ret = 1;
-       int                             count;
-       AccessControl                   *a = NULL;
-       Backend                         *be;
-       int                             be_null = 0;
-
-#ifdef LDAP_DEBUG
-       char                            accessmaskbuf[ACCESSMASK_MAXLEN];
-#endif
-       slap_mask_t                     mask;
-       slap_control_t                  control;
-       slap_access_t                   access_level;
-       const char                      *attr;
-       regmatch_t                      matches[MAXREMATCHES];
-       int                             st_same_attr = 0;
-       static AccessControlState       state_init = ACL_STATE_INIT;
-
-       assert( e != NULL );
-       assert( desc != NULL );
-
-       access_level = ACL_LEVEL( access );
-
-       assert( access_level > ACL_NONE );
-       if ( maskp ) ACL_INVALIDATE( *maskp );
-
-       attr = desc->ad_cname.bv_val;
-
-       assert( attr != NULL );
-
-       if ( op ) {
-               if ( op->o_is_auth_check &&
-                       ( access_level == ACL_SEARCH || access_level == ACL_READ ) )
-               {
-                       access = ACL_AUTH;
-
-               } else if ( get_manageDIT( op ) && access_level == ACL_WRITE &&
-                       desc == slap_schema.si_ad_entry )
-               {
-                       access = ACL_MANAGE;
-               }
-       }
-
-       if ( state ) {
-               if ( state->as_vd_ad == desc ) {
-                       if ( ( state->as_recorded & ACL_STATE_RECORDED_NV ) &&
-                               val == NULL )
-                       {
-                               return state->as_result;
-
-                       } else if ( ( state->as_recorded & ACL_STATE_RECORDED_VD ) &&
-                               val != NULL && state->as_vd_acl == NULL )
-                       {
-                               return state->as_result;
-                       }
-                       st_same_attr = 1;
-               } else {
-                       *state = state_init;
-               }
-
                state->as_vd_ad = desc;
        }
-
-       Debug( LDAP_DEBUG_ACL,
-               "=> access_allowed: %s access to \"%s\" \"%s\" requested\n",
-               access2str( access ), e->e_dn, attr );
-
-       if ( op == NULL ) {
-               /* no-op call */
-               goto done;
-       }
-
-       be = op->o_bd;
-       if ( be == NULL ) {
-               be = LDAP_STAILQ_FIRST(&backendDB);
-               be_null = 1;
-#ifdef LDAP_DEVEL
-               /*
-                * FIXME: experimental; use first backend rules
-                * iff there is no global_acl (ITS#3100) */
-               if ( frontendDB->be_acl == NULL ) 
-#endif
-               {
-                       op->o_bd = be;
-               }
-       }
-       assert( be != NULL );
-
-       /* grant database root access */
-       if ( be_isroot( op ) ) {
-               Debug( LDAP_DEBUG_ACL, "<= root access granted\n", 0, 0, 0 );
-               if ( maskp ) {
-                       mask = ACL_LVL_MANAGE;
-               }
-
-               goto done;
-       }
-
-       /*
-        * no-user-modification operational attributes are ignored
-        * by ACL_WRITE checking as any found here are not provided
-        * by the user
-        *
-        * NOTE: but they are not ignored for ACL_MANAGE, because
-        * if we get here it means a non-root user is trying to 
-        * 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 )
-       {
-               Debug( LDAP_DEBUG_ACL, "NoUserMod Operational attribute:"
-                       " %s access granted\n",
-                       attr, 0, 0 );
-               goto done;
-       }
-
-       /* use backend default access if no backend acls */
-       if ( be->be_acl == NULL ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "=> access_allowed: backend default %s "
-                       "access %s to \"%s\"\n",
-                       access2str( access ),
-                       be->be_dfltaccess >= access_level ? "granted" : "denied",
-                       op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" );
-               ret = be->be_dfltaccess >= access_level;
-
-               if ( maskp ) {
-                       int     i;
-
-                       mask = ACL_PRIV_LEVEL;
-                       for ( i = ACL_NONE; i <= be->be_dfltaccess; i++ ) {
-                               mask |= ACL_ACCESS2PRIV( i );
-                       }
-               }
-
-               goto done;
-
-#ifdef notdef
-       /* be is always non-NULL */
-       /* use global default access if no global acls */
-       } else if ( be == NULL && frontendDB->be_acl == NULL ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "=> access_allowed: global default %s access %s to \"%s\"\n",
-                       access2str( access ),
-                       frontendDB->be_dfltaccess >= access_level ?
-                               "granted" : "denied", op->o_dn.bv_val );
-               ret = frontendDB->be_dfltaccess >= access_level;
-
-               if ( maskp ) {
-                       int     i;
-
-                       mask = ACL_PRIV_LEVEL;
-                       for ( i = ACL_NONE; i <= global_default_access; i++ ) {
-                               mask |= ACL_ACCESS2PRIV( i );
-                       }
-               }
-
-               goto done;
-#endif
-       }
-
-       ret = 0;
-       control = ACL_BREAK;
-
-       if ( st_same_attr ) {
-               assert( state->as_vd_acl != NULL );
-
-               a = state->as_vd_acl;
-               count = state->as_vd_acl_count;
-               if ( !ACL_IS_INVALID( state->as_vd_acl_mask ) ) {
-                       mask = state->as_vd_acl_mask;
-                       AC_MEMCPY( matches, state->as_vd_acl_matches, sizeof(matches) );
-                       goto vd_access;
-               }
-
-       } else {
-               if ( state ) state->as_vi_acl = NULL;
-               a = NULL;
-               ACL_INIT(mask);
-               count = 0;
-               memset( matches, '\0', sizeof(matches) );
-       }
-
-       while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
-               MAXREMATCHES, matches, state ) ) != NULL )
-       {
-               int i;
-
-               for ( i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++ ) {
-                       Debug( LDAP_DEBUG_ACL, "=> match[%d]: %d %d ", i,
-                               (int)matches[i].rm_so, (int)matches[i].rm_eo );
-                       if ( matches[i].rm_so <= matches[0].rm_eo ) {
-                               int n;
-                               for ( n = matches[i].rm_so; n < matches[i].rm_eo; n++ ) {
-                                       Debug( LDAP_DEBUG_ACL, "%c", e->e_ndn[n], 0, 0 );
-                               }
-                       }
-                       Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
-               }
-
-               if ( state ) {
-                       if ( state->as_vi_acl == a &&
-                               ( state->as_recorded & ACL_STATE_RECORDED_NV ) )
-                       {
-                               Debug( LDAP_DEBUG_ACL,
-                                       "access_allowed: result from state (%s)\n",
-                                       attr, 0, 0 );
-                               ret = state->as_result;
-                               goto done;
-                       } else {
-                               Debug( LDAP_DEBUG_ACL,
-                                       "access_allowed: no res from state (%s)\n",
-                                       attr, 0, 0 );
-                       }
-               }
-
-vd_access:
-               control = slap_acl_mask( a, &mask, op,
-                       e, desc, val, MAXREMATCHES, matches, count, state );
-
-               if ( control != ACL_BREAK ) {
-                       break;
-               }
-
-               memset( matches, '\0', sizeof(matches) );
-       }
-
-       if ( ACL_IS_INVALID( mask ) ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "=> access_allowed: \"%s\" (%s) invalid!\n",
-                       e->e_dn, attr, 0 );
-               ACL_INIT(mask);
-
-       } else if ( control == ACL_BREAK ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "=> access_allowed: no more rules\n", 0, 0, 0 );
-
-               goto done;
-       }
-
-       Debug( LDAP_DEBUG_ACL,
-               "=> access_allowed: %s access %s by %s\n",
-               access2str( access ),
-               ACL_GRANT(mask, access) ? "granted" : "denied",
-               accessmask2str( mask, accessmaskbuf, 1 ) );
-
-       ret = ACL_GRANT(mask, access);
-
-done:
-       if ( state != NULL ) {
-               /* If not value-dependent, save ACL in case of more attrs */
-               if ( !( state->as_recorded & ACL_STATE_RECORDED_VD ) ) {
-                       state->as_vi_acl = a;
-                       state->as_result = ret;
-               }
-               state->as_recorded |= ACL_STATE_RECORDED;
-       }
        if ( be_null ) op->o_bd = NULL;
-       if ( maskp ) *maskp = mask;
+       if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
        return ret;
 }
 
-#endif /* !SLAP_OVERLAY_ACCESS */
 
 /*
  * slap_acl_get - return the acl applicable to entry e, attribute
@@ -785,7 +492,7 @@ slap_acl_get(
 
        dnlen = e->e_nname.bv_len;
 
-       for ( ; a != NULL; a = a->acl_next ) {
+       for ( ; a != NULL; prev = a, a = a->acl_next ) {
                (*count) ++;
 
                if ( a->acl_dn_pat.bv_len || ( a->acl_dn_style != ACL_STYLE_REGEX )) {
@@ -856,11 +563,8 @@ slap_acl_get(
 
                        if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
                                state->as_recorded |= ACL_STATE_RECORDED_VD;
-                               state->as_vd_acl = a;
-                               state->as_vd_acl_count = *count;
-                               state->as_vd_access = a->acl_access;
-                               state->as_vd_access_count = 1;
-                               ACL_INVALIDATE( state->as_vd_acl_mask );
+                               state->as_vd_acl = prev;
+                               state->as_vd_acl_count = *count - 1;
                        }
 
                        if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
@@ -943,6 +647,17 @@ slap_acl_get(
        return( NULL );
 }
 
+/*
+ * Record value-dependent access control state
+ */
+#define ACL_RECORD_VALUE_STATE do { \
+               if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \
+                       state->as_recorded |= ACL_STATE_RECORDED_VD; \
+                       state->as_vd_acl = a; \
+                       state->as_vd_acl_count = count; \
+               } \
+       } while( 0 )
+
 static int
 acl_mask_dn(
        Operation               *op,
@@ -952,7 +667,7 @@ acl_mask_dn(
        AccessControl           *a,
        int                     nmatch,
        regmatch_t              *matches,
-       slap_dn_access          *b,
+       slap_dn_access          *bdn,
        struct berval           *opndn )
 {
        /*
@@ -964,40 +679,20 @@ acl_mask_dn(
         * NOTE: styles "anonymous", "users" and "self" 
         * have been moved to enum slap_style_t, whose 
         * value is set in a_dn_style; however, the string
-        * is maintaned in a_dn_pat.
+        * is maintained in a_dn_pat.
         */
-       if ( b->a_style == ACL_STYLE_ANONYMOUS ) {
+
+       if ( bdn->a_style == ACL_STYLE_ANONYMOUS ) {
                if ( !BER_BVISEMPTY( opndn ) ) {
                        return 1;
                }
 
-       } else if ( b->a_style == ACL_STYLE_USERS ) {
+       } else if ( bdn->a_style == ACL_STYLE_USERS ) {
                if ( BER_BVISEMPTY( opndn ) ) {
                        return 1;
                }
 
-               if ( b->a_self ) {
-                       const char *dummy;
-                       int rc, match = 0;
-
-                       /* must have DN syntax */
-                       if ( desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) return 1;
-
-                       /* check if the target is an attribute. */
-                       if ( val == NULL ) return 1;
-
-                       /* target is attribute, check if the attribute value
-                        * is the op dn.
-                        */
-                       rc = value_match( &match, desc,
-                               desc->ad_type->sat_equality, 0,
-                               val, opndn, &dummy );
-                       /* on match error or no match, fail the ACL clause */
-                       if ( rc != LDAP_SUCCESS || match != 0 )
-                               return 1;
-               }
-
-       } else if ( b->a_style == ACL_STYLE_SELF ) {
+       } else if ( bdn->a_style == ACL_STYLE_SELF ) {
                struct berval   ndn, selfndn;
                int             level;
 
@@ -1005,7 +700,7 @@ acl_mask_dn(
                        return 1;
                }
 
-               level = b->a_self_level;
+               level = bdn->a_self_level;
                if ( level < 0 ) {
                        selfndn = *opndn;
                        ndn = e->e_nname;
@@ -1028,8 +723,8 @@ acl_mask_dn(
                        return 1;
                }
 
-       } else if ( b->a_style == ACL_STYLE_REGEX ) {
-               if ( !ber_bvccmp( &b->a_pat, '*' ) ) {
+       } else if ( bdn->a_style == ACL_STYLE_REGEX ) {
+               if ( !ber_bvccmp( &bdn->a_pat, '*' ) ) {
                        int             tmp_nmatch;
                        regmatch_t      tmp_matches[2],
                                        *tmp_matchesp = tmp_matches;
@@ -1071,7 +766,7 @@ acl_mask_dn(
                                return 1;
                        }
 
-                       if ( !regex_matches( &b->a_pat, opndn->bv_val,
+                       if ( !regex_matches( &bdn->a_pat, opndn->bv_val,
                                e->e_ndn, tmp_nmatch, tmp_matchesp ) )
                        {
                                return 1;
@@ -1086,7 +781,7 @@ acl_mask_dn(
                if ( e->e_dn == NULL )
                        return 1;
 
-               if ( b->a_expand ) {
+               if ( bdn->a_expand ) {
                        struct berval   bv;
                        char            buf[ACL_BUF_SIZE];
                        
@@ -1134,7 +829,7 @@ acl_mask_dn(
                                return 1;
                        }
 
-                       if ( acl_string_expand( &bv, &b->a_pat, 
+                       if ( acl_string_expand( &bv, &bdn->a_pat, 
                                        e->e_nname.bv_val,
                                        tmp_nmatch, tmp_matchesp ) )
                        {
@@ -1150,7 +845,7 @@ acl_mask_dn(
                        }
 
                } else {
-                       pat = b->a_pat;
+                       pat = bdn->a_pat;
                }
 
                patlen = pat.bv_len;
@@ -1160,13 +855,13 @@ acl_mask_dn(
 
                }
 
-               if ( b->a_style == ACL_STYLE_BASE ) {
+               if ( bdn->a_style == ACL_STYLE_BASE ) {
                        /* base dn -- entire object DN must match */
                        if ( odnlen != patlen ) {
                                goto dn_match_cleanup;
                        }
 
-               } else if ( b->a_style == ACL_STYLE_ONE ) {
+               } else if ( bdn->a_style == ACL_STYLE_ONE ) {
                        ber_len_t       rdnlen = 0;
 
                        if ( odnlen <= patlen ) {
@@ -1182,12 +877,12 @@ acl_mask_dn(
                                goto dn_match_cleanup;
                        }
 
-               } else if ( b->a_style == ACL_STYLE_SUBTREE ) {
+               } else if ( bdn->a_style == ACL_STYLE_SUBTREE ) {
                        if ( odnlen > patlen && !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) ) {
                                goto dn_match_cleanup;
                        }
 
-               } else if ( b->a_style == ACL_STYLE_CHILDREN ) {
+               } else if ( bdn->a_style == ACL_STYLE_CHILDREN ) {
                        if ( odnlen <= patlen ) {
                                goto dn_match_cleanup;
                        }
@@ -1196,8 +891,8 @@ acl_mask_dn(
                                goto dn_match_cleanup;
                        }
 
-               } else if ( b->a_style == ACL_STYLE_LEVEL ) {
-                       int             level = b->a_level;
+               } else if ( bdn->a_style == ACL_STYLE_LEVEL ) {
+                       int             level = bdn->a_level;
                        struct berval   ndn;
 
                        if ( odnlen <= patlen ) {
@@ -1228,7 +923,7 @@ acl_mask_dn(
                got_match = !strcmp( pat.bv_val, &opndn->bv_val[ odnlen - patlen ] );
 
 dn_match_cleanup:;
-               if ( pat.bv_val != b->a_pat.bv_val ) {
+               if ( pat.bv_val != bdn->a_pat.bv_val ) {
                        slap_sl_free( pat.bv_val, op->o_tmpmemctx );
                }
 
@@ -1240,21 +935,6 @@ dn_match_cleanup:;
        return 0;
 }
 
-/*
- * Record value-dependent access control state
- */
-#define ACL_RECORD_VALUE_STATE do { \
-               if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \
-                       state->as_recorded |= ACL_STATE_RECORDED_VD; \
-                       state->as_vd_acl = a; \
-                       AC_MEMCPY( state->as_vd_acl_matches, matches, \
-                               sizeof( state->as_vd_acl_matches )) ; \
-                       state->as_vd_acl_count = count; \
-                       state->as_vd_access = b; \
-                       state->as_vd_access_count = i; \
-               } \
-       } while( 0 )
-
 static int
 acl_mask_dnattr(
        Operation               *op,
@@ -1326,7 +1006,7 @@ acl_mask_dnattr(
                        return 1;
 
                ACL_RECORD_VALUE_STATE;
-               
+
                /* this is a self clause, check if the target is an
                 * attribute.
                 */
@@ -1398,16 +1078,8 @@ slap_acl_mask(
                accessmask2str( *mask, accessmaskbuf, 1 ) );
 
 
-       if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )
-               && state->as_vd_acl == a )
-       {
-               b = state->as_vd_access;
-               i = state->as_vd_access_count;
-
-       } else {
-               b = a->acl_access;
-               i = 1;
-       }
+       b = a->acl_access;
+       i = 1;
 
        for ( ; b != NULL; b = b->a_next, i++ ) {
                slap_mask_t oldmask, modmask;
@@ -1427,7 +1099,7 @@ slap_acl_mask(
                         * NOTE: styles "anonymous", "users" and "self" 
                         * have been moved to enum slap_style_t, whose 
                         * value is set in a_dn_style; however, the string
-                        * is maintaned in a_dn_pat.
+                        * is maintained in a_dn_pat.
                         */
 
                        if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
@@ -1451,7 +1123,7 @@ slap_acl_mask(
                         * NOTE: styles "anonymous", "users" and "self" 
                         * have been moved to enum slap_style_t, whose 
                         * value is set in a_dn_style; however, the string
-                        * is maintaned in a_dn_pat.
+                        * is maintained in a_dn_pat.
                         */
 
                        if ( op->o_conn && !BER_BVISNULL( &op->o_conn->c_ndn ) )
@@ -1937,6 +1609,36 @@ slap_acl_mask(
                        }
                }
 
+               /* check for the "self" modifier in the <access> field */
+               if ( b->a_dn.a_self ) {
+                       const char *dummy;
+                       int rc, match = 0;
+
+                       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;
+
+                       /* check if the target is an attribute. */
+                       if ( val == NULL ) continue;
+
+                       /* a DN must be present */
+                       if ( BER_BVISEMPTY( &op->o_ndn ) ) {
+                               continue;
+                       }
+
+                       /* 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 );
+                       /* on match error or no match, fail the ACL clause */
+                       if ( rc != LDAP_SUCCESS || match != 0 )
+                               continue;
+               }
+
 #ifdef SLAP_DYNACL
                if ( b->a_dynacl ) {
                        slap_dynacl_t   *da;
@@ -1957,15 +1659,15 @@ slap_acl_mask(
                        }
 
                        /* start out with nothing granted, nothing denied */
-                       ACL_INIT(tgrant);
-                       ACL_INIT(tdeny);
+                       ACL_INVALIDATE(tgrant);
+                       ACL_INVALIDATE(tdeny);
 
                        for ( da = b->a_dynacl; da; da = da->da_next ) {
                                slap_access_t   grant,
                                                deny;
 
-                               ACL_INIT(grant);
-                               ACL_INIT(deny);
+                               ACL_INVALIDATE(grant);
+                               ACL_INVALIDATE(deny);
 
                                Debug( LDAP_DEBUG_ACL, "    <= check a_dynacl: %s\n",
                                        da->da_name, 0, 0 );
@@ -2504,7 +2206,7 @@ acl_match_set (
        } else {
                struct berval           subjdn, ndn = BER_BVNULL;
                struct berval           setat;
-               BerVarray               bvals;
+               BerVarray               bvals = NULL;
                const char              *text;
                AttributeDescription    *desc = NULL;