]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/acl.c
added slapi_operation_set_pb
[openldap] / servers / slapd / acl.c
index fdb4cd1b6375ef892079f9eda457a4c10066b701..50511134b12f55537979035c1bc034cc1eae0c75 100644 (file)
@@ -1,7 +1,7 @@
 /* acl.c - routines to parse and check acl's */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -121,7 +121,7 @@ access_allowed(
 {
        int                             ret = 1;
        int                             count;
-       AccessControl   *a;
+       AccessControl                   *a = NULL;
 
 #ifdef LDAP_DEBUG
        char accessmaskbuf[ACCESSMASK_MAXLEN];
@@ -130,6 +130,9 @@ access_allowed(
        slap_control_t control;
        const char *attr;
        regmatch_t matches[MAXREMATCHES];
+       int        st_same_attr = 0;
+       int        st_initialized = 0;
+       static AccessControlState state_init = ACL_STATE_INIT;
 
        assert( e != NULL );
        assert( desc != NULL );
@@ -139,7 +142,7 @@ access_allowed(
 
        assert( attr != NULL );
 
-       if( state && state->as_recorded ) { 
+       if( state && state->as_recorded && state->as_vd_ad==desc) { 
                if( state->as_recorded & ACL_STATE_RECORDED_NV &&
                        val == NULL )
                {
@@ -150,6 +153,9 @@ access_allowed(
                {
                        return state->as_result;
                }
+               st_same_attr = 1;
+       } if (state) {
+               state->as_vd_ad=desc;
        }
 
 #ifdef NEW_LOGGING
@@ -246,7 +252,7 @@ access_allowed(
        ret = 0;
        control = ACL_BREAK;
 
-       if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )) {
+       if( st_same_attr ) {
                assert( state->as_vd_acl != NULL );
 
                a = state->as_vd_acl;
@@ -290,6 +296,18 @@ access_allowed(
 #endif
                }
 
+               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 );
+                               return state->as_result;
+                       } else if (!st_initialized) {
+                               Debug( LDAP_DEBUG_ACL, "access_allowed: no res from state (%s)\n", attr, 0, 0);
+                           *state = state_init;
+                               state->as_vd_ad=desc;
+                               st_initialized=1;
+                       }
+               }
+
 vd_access:
                control = acl_mask( a, &mask, be, conn, op,
                        e, desc, val, matches, count, state );
@@ -342,6 +360,9 @@ vd_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_recorded |= ACL_STATE_RECORDED;
                state->as_result = ret;
        }
@@ -605,17 +626,17 @@ acl_mask(
                         * user is bound as somebody in the same namespace as
                         * the entry, OR the given dn matches the dn pattern
                         */
-                       if ( ber_bvcmp( &b->a_dn_pat, &aci_bv_anonymous ) == 0 ) {
+                       if ( bvmatch( &b->a_dn_pat, &aci_bv_anonymous ) ) {
                                if ( op->o_ndn.bv_len != 0 ) {
                                        continue;
                                }
 
-                       } else if ( ber_bvcmp( &b->a_dn_pat, &aci_bv_users ) == 0 ) {
+                       } else if ( bvmatch( &b->a_dn_pat, &aci_bv_users ) ) {
                                if ( op->o_ndn.bv_len == 0 ) {
                                        continue;
                                }
 
-                       } else if ( ber_bvcmp( &b->a_dn_pat, &aci_bv_self ) == 0 ) {
+                       } else if ( bvmatch( &b->a_dn_pat, &aci_bv_self ) ) {
                                if ( op->o_ndn.bv_len == 0 ) {
                                        continue;
                                }
@@ -867,7 +888,8 @@ dn_match_cleanup:;
                                at != NULL;
                                at = attrs_find( at->a_next, b->a_dn_at ) )
                        {
-                               if( value_find( b->a_dn_at, at->a_vals, &bv ) == 0 ) {
+                               if( value_find_ex( b->a_dn_at,
+                                       SLAP_MR_VALUE_NORMALIZED_MATCH, at->a_vals, &bv ) == 0 ) {
                                        /* found it */
                                        match = 1;
                                        break;
@@ -919,7 +941,6 @@ dn_match_cleanup:;
                }
 
                if ( b->a_group_pat.bv_len ) {
-                       char buf[ACL_BUF_SIZE];
                        struct berval bv;
                        struct berval ndn = { 0, NULL };
                        int rc;
@@ -928,29 +949,33 @@ dn_match_cleanup:;
                                continue;
                        }
 
-                       bv.bv_len = sizeof(buf) - 1;
-                       bv.bv_val = buf; 
-
                        /* b->a_group is an unexpanded entry name, expanded it should be an 
                         * entry with objectclass group* and we test to see if odn is one of
                         * the values in the attribute group
                         */
                        /* see if asker is listed in dnattr */
                        if ( b->a_group_style == ACL_STYLE_REGEX ) {
-                               string_expand(&bv, &b->a_group_pat, e->e_ndn, matches);
-                               if ( dnNormalize2(NULL, &bv, &ndn) != LDAP_SUCCESS ) {
+                               char buf[ACL_BUF_SIZE];
+                               bv.bv_len = sizeof(buf) - 1;
+                               bv.bv_val = buf; 
+
+                               string_expand( &bv, &b->a_group_pat, e->e_ndn, matches );
+                               if ( dnNormalize2( NULL, &bv, &ndn ) != LDAP_SUCCESS ) {
                                        /* did not expand to a valid dn */
                                        continue;
                                }
+
                                bv = ndn;
+
                        } else {
                                bv = b->a_group_pat;
                        }
 
-                       rc = backend_group(be, conn, op, e, &bv, &op->o_ndn,
-                               b->a_group_oc, b->a_group_at);
-                       if ( ndn.bv_val )
-                               free( ndn.bv_val );
+                       rc = backend_group( be, conn, op, e, &bv, &op->o_ndn,
+                               b->a_group_oc, b->a_group_at );
+
+                       if ( ndn.bv_val ) free( ndn.bv_val );
+
                        if ( rc != 0 ) {
                                continue;
                        }
@@ -1197,6 +1222,7 @@ acl_check_modlist(
 )
 {
        struct berval *bv;
+       AccessControlState state = ACL_STATE_INIT;
 
        assert( be != NULL );
 
@@ -1251,9 +1277,6 @@ acl_check_modlist(
        }
 
        for ( ; mlist != NULL; mlist = mlist->sml_next ) {
-               static AccessControlState state_init = ACL_STATE_INIT;
-               AccessControlState state;
-
                /*
                 * no-user-modification operational attributes are ignored
                 * by ACL_WRITE checking as any found here are not provided
@@ -1272,8 +1295,6 @@ acl_check_modlist(
                        continue;
                }
 
-               state = state_init;
-
                switch ( mlist->sml_op ) {
                case LDAP_MOD_REPLACE:
                        /*
@@ -1674,7 +1695,8 @@ aci_group_member (
                bv.bv_val = (char *)&buf;
                string_expand(&bv, &subjdn, e->e_ndn, matches);
                if ( dnNormalize2(NULL, &bv, &ndn) == LDAP_SUCCESS ) {
-                       rc = (backend_group(be, conn, op, e, &ndn, &op->o_ndn, grp_oc, grp_ad) == 0);
+                       rc = (backend_group(be, conn, op, e, &ndn, &op->o_ndn,
+                               grp_oc, grp_ad) == 0);
                        free( ndn.bv_val );
                }
        }
@@ -1780,7 +1802,7 @@ aci_mask(
                        at != NULL;
                        at = attrs_find( at->a_next, ad ) )
                {
-                       if (value_find( ad, at->a_vals, &bv) == 0 ) {
+                       if (value_find_ex( ad, SLAP_MR_VALUE_NORMALIZED_MATCH, at->a_vals, &bv) == 0 ) {
                                rc = 1;
                                break;
                        }