/* 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
*/
{
int ret = 1;
int count;
- AccessControl *a;
+ AccessControl *a = NULL;
#ifdef LDAP_DEBUG
char accessmaskbuf[ACCESSMASK_MAXLEN];
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 );
assert( attr != NULL );
- if( state && state->as_recorded ) {
+ if( op && op->o_is_auth_check && (access == ACL_SEARCH || access == ACL_READ)) {
+ access = ACL_AUTH;
+ }
+ if( state && state->as_recorded && state->as_vd_ad==desc) {
if( state->as_recorded & ACL_STATE_RECORDED_NV &&
val == NULL )
{
{
return state->as_result;
}
+ st_same_attr = 1;
+ } if (state) {
+ state->as_vd_ad=desc;
}
#ifdef NEW_LOGGING
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;
#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 );
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;
}
* 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;
}
}
if ( b->a_sockurl_pat.bv_len ) {
+ if ( !conn->c_listener_url.bv_val ) {
+ continue;
+ }
#ifdef NEW_LOGGING
LDAP_LOG( ACL, DETAIL1,
"acl_mask: conn %lu check a_sockurl_pat: %s\n",
}
if ( b->a_domain_pat.bv_len ) {
+ if ( !conn->c_peer_domain.bv_val ) {
+ continue;
+ }
#ifdef NEW_LOGGING
LDAP_LOG( ACL, DETAIL1,
"acl_mask: conn %lu check a_domain_pat: %s\n",
if ( b->a_domain_expand ) {
struct berval bv;
- bv.bv_len = sizeof(buf);
+ bv.bv_len = sizeof(buf) - 1;
bv.bv_val = buf;
string_expand(&bv, &b->a_domain_pat, e->e_ndn, matches);
}
if ( b->a_peername_pat.bv_len ) {
+ if ( !conn->c_peer_name.bv_val ) {
+ continue;
+ }
#ifdef NEW_LOGGING
LDAP_LOG( ACL, DETAIL1,
- "acl_mask: conn %lu check a_perrname_path: %s\n",
+ "acl_mask: conn %lu check a_peername_path: %s\n",
conn->c_connid, b->a_peername_pat.bv_val , 0 );
#else
Debug( LDAP_DEBUG_ACL, "<= check a_peername_path: %s\n",
}
if ( b->a_sockname_pat.bv_len ) {
+ if ( !conn->c_sock_name.bv_val ) {
+ continue;
+ }
#ifdef NEW_LOGGING
LDAP_LOG( ACL, DETAIL1,
"acl_mask: conn %lu check a_sockname_path: %s\n",
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_ASSERTED_VALUE_NORMALIZED_MATCH,
+ at->a_vals, &bv ) == 0 )
+ {
/* found it */
match = 1;
break;
*/
if ( b->a_dn_self ) {
/* check if the target is an attribute. */
- if ( val == NULL )
- continue;
+ if ( val == NULL ) continue;
+
/* target is attribute, check if the attribute value
* is the op dn.
*/
}
if ( b->a_group_pat.bv_len ) {
- char buf[ACL_BUF_SIZE];
struct berval bv;
struct berval ndn = { 0, NULL };
int rc;
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;
}
}
if ( b->a_set_pat.bv_len != 0 ) {
- if (aci_match_set( &b->a_set_pat, be, e, conn, op, 0 ) == 0) {
+ struct berval bv;
+ char buf[ACL_BUF_SIZE];
+ if( b->a_set_style == ACL_STYLE_REGEX ){
+ bv.bv_len = sizeof(buf) - 1;
+ bv.bv_val = buf;
+ string_expand( &bv, &b->a_set_pat, e->e_ndn, matches );
+ }else{
+ bv = b->a_set_pat;
+ }
+ if (aci_match_set( &bv, be, e, conn, op, 0 ) == 0) {
continue;
}
}
)
{
struct berval *bv;
+ AccessControlState state = ACL_STATE_INIT;
assert( be != NULL );
}
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
continue;
}
- state = state_init;
-
switch ( mlist->sml_op ) {
case LDAP_MOD_REPLACE:
/*
const char *text;
AttributeDescription *desc = NULL;
if (slap_bv2ad(attr, &desc, &text) == LDAP_SUCCESS) {
- backend_attribute(cp->be, NULL, NULL,
+ backend_attribute(cp->be, NULL, cp->op,
cp->e, &ndn, desc, &bvals);
}
free(ndn.bv_val);
if ( dnNormalize2(NULL, &subjdn, &ndn) == LDAP_SUCCESS
&& slap_bv2ad(&setat, &desc, &text) == LDAP_SUCCESS )
{
- backend_attribute(be, NULL, NULL, e,
+ backend_attribute(be, NULL, op, e,
&ndn, desc, &bvals);
if ( bvals != NULL ) {
if ( bvals[0].bv_val != NULL ) {
if (grp_oc != NULL && grp_ad != NULL ) {
char buf[ACL_BUF_SIZE];
struct berval bv, ndn;
- bv.bv_len = sizeof( buf );
+ bv.bv_len = sizeof( buf ) - 1;
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 );
}
}
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_ASSERTED_VALUE_NORMALIZED_MATCH, at->a_vals, &bv) == 0 ) {
rc = 1;
break;
}
struct berval bv;
int rc;
- bv.bv_len = sizeof(newbuf);
+ bv.bv_len = sizeof(newbuf) - 1;
bv.bv_val = newbuf;
if(str == NULL) str = "";