]> 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 68f10d2f1d4939b90615213606758c470275d9d0..7b1c4a0854556da8466b02fd5dc56ff02ec7528a 100644 (file)
@@ -134,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 );
@@ -198,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 )
@@ -340,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 );
@@ -363,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;
@@ -377,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,
@@ -403,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 );
 
@@ -455,6 +437,7 @@ done:
                        state->as_result = ret;
                }
                state->as_recorded |= ACL_STATE_RECORDED;
+               state->as_vd_ad = desc;
        }
        if ( be_null ) op->o_bd = NULL;
        if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
@@ -509,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 )) {
@@ -580,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 ) {
@@ -674,11 +654,7 @@ slap_acl_get(
                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 )
 
@@ -689,12 +665,8 @@ acl_mask_dn(
        AttributeDescription    *desc,
        struct berval           *val,
        AccessControl           *a,
-       Access                  *b,
-       int                     i,
        int                     nmatch,
        regmatch_t              *matches,
-       int                     count,
-       AccessControlState      *state,
        slap_dn_access          *bdn,
        struct berval           *opndn )
 {
@@ -707,35 +679,8 @@ 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 ( bdn->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 ) return 1;
-
-               /* check if the target is an attribute. */
-               if ( val == NULL ) return 1;
-
-               /* a DN must be present */
-               if ( BER_BVISEMPTY( opndn ) ) {
-                       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;
-       }
 
        if ( bdn->a_style == ACL_STYLE_ANONYMOUS ) {
                if ( !BER_BVISEMPTY( opndn ) ) {
@@ -1061,7 +1006,7 @@ acl_mask_dnattr(
                        return 1;
 
                ACL_RECORD_VALUE_STATE;
-               
+
                /* this is a self clause, check if the target is an
                 * attribute.
                 */
@@ -1133,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;
@@ -1162,11 +1099,11 @@ 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, b, i, nmatch, matches,
-                               count, state, &b->a_dn, &op->o_ndn ) )
+                       if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
+                               &b->a_dn, &op->o_ndn ) )
                        {
                                continue;
                        }
@@ -1186,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 ) )
@@ -1196,8 +1133,8 @@ slap_acl_mask(
                                ndn = op->o_ndn;
                        }
 
-                       if ( acl_mask_dn( op, e, desc, val, a, b, i, nmatch, matches,
-                               count, state, &b->a_realdn, &ndn ) )
+                       if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
+                               &b->a_realdn, &ndn ) )
                        {
                                continue;
                        }
@@ -1672,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;