slap_access_t access_level;
const char *attr;
regmatch_t matches[MAXREMATCHES];
- int st_same_attr = 0;
assert( op != NULL );
assert( e != NULL );
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 )
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 );
{
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;
{
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,
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 );
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 );
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 )) {
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 ) {
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 )
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 )
{
* 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 ) ) {
return 1;
ACL_RECORD_VALUE_STATE;
-
+
/* this is a self clause, check if the target is an
* attribute.
*/
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;
* 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;
}
* 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 ) )
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;
}
}
}
+ /* 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;