mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-25 00:59:45 -05:00
Add ACL state recording to avoid multiple evaluation of
value-independent access controls.
This commit is contained in:
parent
ffa4b26343
commit
32fb8b0bff
19 changed files with 216 additions and 102 deletions
|
|
@ -50,7 +50,9 @@ static slap_control_t acl_mask(
|
|||
Entry *e,
|
||||
AttributeDescription *desc,
|
||||
struct berval *val,
|
||||
regmatch_t *matches );
|
||||
regmatch_t *matches,
|
||||
int count,
|
||||
AccessControlState *state );
|
||||
|
||||
#ifdef SLAPD_ACI_ENABLED
|
||||
static int aci_mask(
|
||||
|
|
@ -106,8 +108,10 @@ access_allowed(
|
|||
Entry *e,
|
||||
AttributeDescription *desc,
|
||||
struct berval *val,
|
||||
slap_access_t access )
|
||||
slap_access_t access,
|
||||
AccessControlState *state )
|
||||
{
|
||||
int ret = 1;
|
||||
int count;
|
||||
AccessControl *a;
|
||||
#ifdef LDAP_DEBUG
|
||||
|
|
@ -126,6 +130,19 @@ access_allowed(
|
|||
|
||||
assert( attr != NULL );
|
||||
|
||||
if( state && state->as_recorded ) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_ENTRY,
|
||||
"access_allowed: conn %d %s access to \"%s\" \"%s\" requested\n",
|
||||
|
|
@ -138,7 +155,7 @@ access_allowed(
|
|||
|
||||
if ( op == NULL ) {
|
||||
/* no-op call */
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( be == NULL ) be = &backends[0];
|
||||
|
|
@ -155,7 +172,7 @@ access_allowed(
|
|||
"<= root access granted\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -176,7 +193,7 @@ access_allowed(
|
|||
" %s access granted\n",
|
||||
attr, 0, 0 );
|
||||
#endif
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* use backend default access if no backend acls */
|
||||
|
|
@ -192,7 +209,8 @@ access_allowed(
|
|||
access2str( access ),
|
||||
be->be_dfltaccess >= access ? "granted" : "denied", op->o_dn.bv_val );
|
||||
#endif
|
||||
return be->be_dfltaccess >= access;
|
||||
ret = be->be_dfltaccess >= access;
|
||||
goto done;
|
||||
|
||||
#ifdef notdef
|
||||
/* be is always non-NULL */
|
||||
|
|
@ -209,29 +227,45 @@ access_allowed(
|
|||
access2str( access ),
|
||||
global_default_access >= access ? "granted" : "denied", op->o_dn.bv_val );
|
||||
#endif
|
||||
return global_default_access >= access;
|
||||
ret = global_default_access >= access;
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
|
||||
ACL_INIT(mask);
|
||||
memset(matches, '\0', sizeof(matches));
|
||||
|
||||
ret = 0;
|
||||
control = ACL_BREAK;
|
||||
a = NULL;
|
||||
count = 0;
|
||||
|
||||
while((a = acl_get( a, &count, be, op, e, desc, MAXREMATCHES, matches )) != NULL)
|
||||
if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )) {
|
||||
assert( state->as_vd_acl != NULL );
|
||||
|
||||
a = state->as_vd_acl;
|
||||
mask = state->as_vd_acl_mask;
|
||||
count = state->as_vd_acl_count;
|
||||
AC_MEMCPY( matches, state->as_vd_acl_matches,
|
||||
sizeof(matches) );
|
||||
goto vd_access;
|
||||
|
||||
} else {
|
||||
a = NULL;
|
||||
ACL_INIT(mask);
|
||||
count = 0;
|
||||
memset(matches, '\0', sizeof(matches));
|
||||
}
|
||||
|
||||
while((a = acl_get( a, &count, be, op, e, desc,
|
||||
MAXREMATCHES, matches )) != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_DETAIL1,
|
||||
"access_allowed: conn %d match[%d]: %d %d ",
|
||||
conn->c_connid, i, (int)matches[i].rm_so, (int)matches[i].rm_eo ));
|
||||
"access_allowed: conn %d match[%d]: %d %d ",
|
||||
conn->c_connid, i,
|
||||
(int)matches[i].rm_so, (int)matches[i].rm_eo ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ACL, "=> match[%d]: %d %d ", i,
|
||||
(int)matches[i].rm_so, (int)matches[i].rm_eo );
|
||||
(int)matches[i].rm_so, (int)matches[i].rm_eo );
|
||||
#endif
|
||||
if( matches[i].rm_so <= matches[0].rm_eo ) {
|
||||
int n;
|
||||
|
|
@ -246,8 +280,9 @@ access_allowed(
|
|||
#endif
|
||||
}
|
||||
|
||||
vd_access:
|
||||
control = acl_mask( a, &mask, be, conn, op,
|
||||
e, desc, val, matches );
|
||||
e, desc, val, matches, count, state );
|
||||
|
||||
if ( control != ACL_BREAK ) {
|
||||
break;
|
||||
|
|
@ -259,14 +294,14 @@ access_allowed(
|
|||
if ( ACL_IS_INVALID( mask ) ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_DETAIL1,
|
||||
"access_allowed: conn %d \"%s\" (%s) invalid!\n",
|
||||
conn->c_connid, e->e_dn, attr ));
|
||||
"access_allowed: conn %d \"%s\" (%s) invalid!\n",
|
||||
conn->c_connid, e->e_dn, attr ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"=> access_allowed: \"%s\" (%s) invalid!\n",
|
||||
e->e_dn, attr, 0 );
|
||||
#endif
|
||||
ACL_INIT( mask );
|
||||
ACL_INIT(mask);
|
||||
|
||||
} else if ( control == ACL_BREAK ) {
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -276,16 +311,17 @@ access_allowed(
|
|||
Debug( LDAP_DEBUG_ACL,
|
||||
"=> access_allowed: no more rules\n", 0, 0, 0);
|
||||
#endif
|
||||
ACL_INIT( mask );
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_ENTRY,
|
||||
"access_allowed: conn %d %s access %s by %s\n",
|
||||
conn->c_connid,
|
||||
access2str( access ),
|
||||
ACL_GRANT( mask, access ) ? "granted" : "denied",
|
||||
accessmask2str( mask, accessmaskbuf ) ));
|
||||
"access_allowed: conn %d %s access %s by %s\n",
|
||||
conn->c_connid,
|
||||
access2str( access ),
|
||||
ACL_GRANT( mask, access ) ? "granted" : "denied",
|
||||
accessmask2str( mask, accessmaskbuf ) ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"=> access_allowed: %s access %s by %s\n",
|
||||
|
|
@ -293,7 +329,15 @@ access_allowed(
|
|||
ACL_GRANT(mask, access) ? "granted" : "denied",
|
||||
accessmask2str( mask, accessmaskbuf ) );
|
||||
#endif
|
||||
return ACL_GRANT(mask, access);
|
||||
|
||||
ret = ACL_GRANT(mask, access);
|
||||
|
||||
done:
|
||||
if( state != NULL ) {
|
||||
state->as_recorded |= ACL_STATE_RECORDED;
|
||||
state->as_result = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -452,6 +496,20 @@ 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; \
|
||||
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 )
|
||||
|
||||
/*
|
||||
* acl_mask - modifies mask based upon the given acl and the
|
||||
|
|
@ -472,10 +530,12 @@ acl_mask(
|
|||
Entry *e,
|
||||
AttributeDescription *desc,
|
||||
struct berval *val,
|
||||
regmatch_t *matches
|
||||
)
|
||||
regmatch_t *matches,
|
||||
int count,
|
||||
AccessControlState *state )
|
||||
{
|
||||
int i, odnlen, patlen;
|
||||
int vd_recorded = 0;
|
||||
Access *b;
|
||||
#ifdef LDAP_DEBUG
|
||||
char accessmaskbuf[ACCESSMASK_MAXLEN];
|
||||
|
|
@ -512,7 +572,18 @@ acl_mask(
|
|||
accessmask2str( *mask, accessmaskbuf ) );
|
||||
#endif
|
||||
|
||||
for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
|
||||
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;
|
||||
}
|
||||
|
||||
for ( ; b != NULL; b = b->a_next, i++ ) {
|
||||
slap_mask_t oldmask, modmask;
|
||||
|
||||
ACL_INVALIDATE( modmask );
|
||||
|
|
@ -750,11 +821,15 @@ acl_mask(
|
|||
/* no dnattr match, check if this is a self clause */
|
||||
if ( ! b->a_dn_self )
|
||||
continue;
|
||||
|
||||
ACL_RECORD_VALUE_STATE;
|
||||
|
||||
/* this is a self clause, check if the target is an
|
||||
* attribute.
|
||||
*/
|
||||
if ( val == NULL )
|
||||
continue;
|
||||
|
||||
/* target is attribute, check if the attribute value
|
||||
* is the op dn.
|
||||
*/
|
||||
|
|
@ -892,6 +967,8 @@ acl_mask(
|
|||
continue;
|
||||
}
|
||||
|
||||
ACL_RECORD_VALUE_STATE;
|
||||
|
||||
/* start out with nothing granted, nothing denied */
|
||||
ACL_INIT(tgrant);
|
||||
ACL_INIT(tdeny);
|
||||
|
|
@ -1086,6 +1163,9 @@ 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
|
||||
|
|
@ -1104,6 +1184,8 @@ acl_check_modlist(
|
|||
continue;
|
||||
}
|
||||
|
||||
state = state_init;
|
||||
|
||||
switch ( mlist->sml_op ) {
|
||||
case LDAP_MOD_REPLACE:
|
||||
/*
|
||||
|
|
@ -1112,7 +1194,7 @@ acl_check_modlist(
|
|||
* This prevents abuse from selfwriters.
|
||||
*/
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
mlist->sml_desc, NULL, ACL_WRITE ) )
|
||||
mlist->sml_desc, NULL, ACL_WRITE, &state ) )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
|
@ -1126,7 +1208,7 @@ acl_check_modlist(
|
|||
|
||||
for ( bv = mlist->sml_bvalues; bv->bv_val != NULL; bv++ ) {
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
mlist->sml_desc, bv, ACL_WRITE ) )
|
||||
mlist->sml_desc, bv, ACL_WRITE, &state ) )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
|
@ -1136,7 +1218,7 @@ acl_check_modlist(
|
|||
case LDAP_MOD_DELETE:
|
||||
if ( mlist->sml_bvalues == NULL ) {
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
mlist->sml_desc, NULL, ACL_WRITE ) )
|
||||
mlist->sml_desc, NULL, ACL_WRITE, NULL ) )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
|
@ -1144,7 +1226,7 @@ acl_check_modlist(
|
|||
}
|
||||
for ( bv = mlist->sml_bvalues; bv->bv_val != NULL; bv++ ) {
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
mlist->sml_desc, bv, ACL_WRITE ) )
|
||||
mlist->sml_desc, bv, ACL_WRITE, &state ) )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
|
||||
switch( opinfo.boi_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -253,7 +253,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* check parent for "children" acl */
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
p = NULL;
|
||||
|
||||
switch( opinfo.boi_err ) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ bdb_attribute(
|
|||
Attribute *attr;
|
||||
BerVarray v;
|
||||
const char *entry_at_name = entry_at->ad_cname.bv_val;
|
||||
AccessControlState acl_state = ACL_STATE_INIT;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_ARGS,
|
||||
|
|
@ -142,8 +143,8 @@ bdb_attribute(
|
|||
}
|
||||
|
||||
if (conn != NULL && op != NULL
|
||||
&& access_allowed(be, conn, op, e, slap_schema.si_ad_entry,
|
||||
NULL, ACL_READ) == 0)
|
||||
&& access_allowed( be, conn, op, e, slap_schema.si_ad_entry,
|
||||
NULL, ACL_READ, &acl_state ) == 0 )
|
||||
{
|
||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
|
|
@ -163,7 +164,8 @@ bdb_attribute(
|
|||
}
|
||||
|
||||
if (conn != NULL && op != NULL
|
||||
&& access_allowed(be, conn, op, e, entry_at, NULL, ACL_READ) == 0)
|
||||
&& access_allowed( be, conn, op, e, entry_at, NULL, ACL_READ,
|
||||
&acl_state ) == 0 )
|
||||
{
|
||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
|
|
@ -179,7 +181,7 @@ bdb_attribute(
|
|||
if( conn != NULL
|
||||
&& op != NULL
|
||||
&& access_allowed(be, conn, op, e, entry_at,
|
||||
&attr->a_vals[i], ACL_READ) == 0)
|
||||
&attr->a_vals[i], ACL_READ, &acl_state ) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ bdb_bind(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
password, NULL, ACL_AUTH ) )
|
||||
password, NULL, ACL_AUTH, NULL ) )
|
||||
{
|
||||
send_ldap_result( conn, op, rc = LDAP_INSUFFICIENT_ACCESS,
|
||||
NULL, NULL, NULL, NULL );
|
||||
|
|
@ -200,7 +200,7 @@ bdb_bind(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
krbattr, NULL, ACL_AUTH ) )
|
||||
krbattr, NULL, ACL_AUTH, NULL ) )
|
||||
{
|
||||
send_ldap_result( conn, op, rc = LDAP_INSUFFICIENT_ACCESS,
|
||||
NULL, NULL, NULL, NULL );
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ bdb_compare(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
ava->aa_desc, &ava->aa_value, ACL_COMPARE ) )
|
||||
ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
|
||||
{
|
||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* check parent for "children" acl */
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, p);
|
||||
p = NULL;
|
||||
|
|
@ -148,7 +148,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* check parent for "children" acl */
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
p = NULL;
|
||||
|
||||
switch( opinfo.boi_err ) {
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* check parent for "children" acl */
|
||||
if ( ! access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE ) )
|
||||
children, NULL, ACL_WRITE, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
|
||||
0, 0 );
|
||||
|
|
@ -237,7 +237,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* check parent for "children" acl */
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
|
||||
p = NULL;
|
||||
|
||||
|
|
@ -317,7 +317,7 @@ retry: /* transaction retry */
|
|||
np, (long) np->e_id, 0 );
|
||||
|
||||
/* check newSuperior for "children" acl */
|
||||
if ( !access_allowed( be, conn, op, np, children, NULL, ACL_WRITE ) ) {
|
||||
if ( !access_allowed( be, conn, op, np, children, NULL, ACL_WRITE, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_modrdn: no wr to newSup children\n",
|
||||
0, 0, 0 );
|
||||
|
|
@ -360,7 +360,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* check parent for "children" acl */
|
||||
rc = access_allowed( be, conn, op, np,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
|
||||
np = NULL;
|
||||
|
||||
|
|
@ -487,7 +487,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* ACL check of newly added attrs */
|
||||
if ( !access_allowed( be, conn, op, e, desc,
|
||||
&new_rdn[0][ a_cnt ]->la_value, ACL_WRITE ) ) {
|
||||
&new_rdn[0][ a_cnt ]->la_value, ACL_WRITE, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_modrdn: access to attr \"%s\" "
|
||||
"(new) not allowed\n",
|
||||
|
|
@ -537,7 +537,7 @@ retry: /* transaction retry */
|
|||
|
||||
/* ACL check of newly added attrs */
|
||||
if ( !access_allowed( be, conn, op, e, desc,
|
||||
&old_rdn[0][d_cnt]->la_value, ACL_WRITE ) ) {
|
||||
&old_rdn[0][d_cnt]->la_value, ACL_WRITE, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_modrdn: access to attr \"%s\" "
|
||||
"(old) not allowed\n",
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ ldbm_back_add(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE ) )
|
||||
children, NULL, ACL_WRITE, NULL ) )
|
||||
{
|
||||
/* free parent and writer lock */
|
||||
cache_return_entry_w( &li->li_cache, p );
|
||||
|
|
@ -207,7 +207,7 @@ ldbm_back_add(
|
|||
p = (Entry *)&slap_entry_root;
|
||||
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
p = NULL;
|
||||
|
||||
if ( ! rc ) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ ldbm_back_attribute(
|
|||
BerVarray v;
|
||||
const char *entry_at_name = entry_at->ad_cname.bv_val;
|
||||
struct berval *iv, *jv;
|
||||
AccessControlState acl_state = ACL_STATE_INIT;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_ARGS,
|
||||
|
|
@ -102,7 +103,7 @@ ldbm_back_attribute(
|
|||
}
|
||||
|
||||
/* find attribute values */
|
||||
|
||||
|
||||
if( is_entry_alias( e ) ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
|
||||
|
|
@ -130,8 +131,8 @@ ldbm_back_attribute(
|
|||
}
|
||||
|
||||
if (conn != NULL && op != NULL
|
||||
&& access_allowed(be, conn, op, e, slap_schema.si_ad_entry,
|
||||
NULL, ACL_READ) == 0)
|
||||
&& access_allowed( be, conn, op, e, slap_schema.si_ad_entry,
|
||||
NULL, ACL_READ, NULL ) == 0)
|
||||
{
|
||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
|
|
@ -152,7 +153,8 @@ ldbm_back_attribute(
|
|||
}
|
||||
|
||||
if (conn != NULL && op != NULL
|
||||
&& access_allowed(be, conn, op, e, entry_at, NULL, ACL_READ) == 0)
|
||||
&& access_allowed( be, conn, op, e, entry_at, NULL,
|
||||
ACL_READ, &acl_state ) == 0)
|
||||
{
|
||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
|
|
@ -167,8 +169,8 @@ ldbm_back_attribute(
|
|||
for ( iv=attr->a_vals, jv=v; iv->bv_val; iv++ ) {
|
||||
if( conn != NULL
|
||||
&& op != NULL
|
||||
&& access_allowed(be, conn, op, e, entry_at,
|
||||
iv, ACL_READ) == 0)
|
||||
&& access_allowed( be, conn, op, e, entry_at,
|
||||
iv, ACL_READ, &acl_state ) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ ldbm_back_bind(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
password, NULL, ACL_AUTH ) )
|
||||
password, NULL, ACL_AUTH, NULL ) )
|
||||
{
|
||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
||||
NULL, NULL, NULL, NULL );
|
||||
|
|
@ -207,7 +207,7 @@ ldbm_back_bind(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
krbattr, NULL, ACL_AUTH ) )
|
||||
krbattr, NULL, ACL_AUTH, NULL ) )
|
||||
{
|
||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
||||
NULL, NULL, NULL, NULL );
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ ldbm_back_compare(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
ava->aa_desc, &ava->aa_value, ACL_COMPARE ) )
|
||||
ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
|
||||
{
|
||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
||||
NULL, NULL, NULL, NULL );
|
||||
|
|
@ -107,7 +107,6 @@ ldbm_back_compare(
|
|||
rc = LDAP_COMPARE_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
send_ldap_result( conn, op, rc,
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ ldbm_back_delete(
|
|||
|
||||
/* check parent for "children" acl */
|
||||
if ( ! access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE ) )
|
||||
children, NULL, ACL_WRITE, NULL ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
|
||||
|
|
@ -162,7 +162,7 @@ ldbm_back_delete(
|
|||
p = (Entry *)&slap_entry_root;
|
||||
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
p = NULL;
|
||||
|
||||
/* check parent for "children" acl */
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ ldbm_back_modrdn(
|
|||
|
||||
/* check parent for "children" acl */
|
||||
if ( ! access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE ) )
|
||||
children, NULL, ACL_WRITE, NULL ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
|
||||
|
|
@ -228,7 +228,7 @@ ldbm_back_modrdn(
|
|||
p = (Entry *)&slap_entry_root;
|
||||
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
p = NULL;
|
||||
|
||||
/* check parent for "children" acl */
|
||||
|
|
@ -342,7 +342,7 @@ ldbm_back_modrdn(
|
|||
|
||||
/* check newSuperior for "children" acl */
|
||||
if ( !access_allowed( be, conn, op, np, children, NULL,
|
||||
ACL_WRITE ) )
|
||||
ACL_WRITE, NULL ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
|
||||
|
|
@ -403,7 +403,7 @@ ldbm_back_modrdn(
|
|||
np = (Entry *)&slap_entry_root;
|
||||
|
||||
rc = access_allowed( be, conn, op, np,
|
||||
children, NULL, ACL_WRITE );
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
np = NULL;
|
||||
|
||||
/* check parent for "children" acl */
|
||||
|
|
@ -593,7 +593,7 @@ ldbm_back_modrdn(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
desc, &new_rdn[0][a_cnt]->la_value, ACL_WRITE ) ) {
|
||||
desc, &new_rdn[0][a_cnt]->la_value, ACL_WRITE, NULL ) ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
|
||||
"ldbm_back_modrdn: access "
|
||||
|
|
@ -666,7 +666,7 @@ ldbm_back_modrdn(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
desc, &old_rdn[0][d_cnt]->la_value, ACL_WRITE ) ) {
|
||||
desc, &old_rdn[0][d_cnt]->la_value, ACL_WRITE, NULL ) ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
|
||||
"ldbm_back_modrdn: access "
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ static int compare_entry(
|
|||
Attribute *a;
|
||||
|
||||
if ( ! access_allowed( NULL, conn, op, e,
|
||||
ava->aa_desc, &ava->aa_value, ACL_COMPARE ) )
|
||||
ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1963,7 +1963,7 @@ read_config( const char *fname )
|
|||
}
|
||||
|
||||
/* file from which to read additional rootdse attrs */
|
||||
} else if ( strcasecmp( cargv[0], "rootdse" ) == 0) {
|
||||
} else if ( strcasecmp( cargv[0], "rootDSE" ) == 0) {
|
||||
if ( cargc < 2 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ static int test_mra_filter(
|
|||
Attribute *a;
|
||||
|
||||
if( !access_allowed( be, conn, op, e,
|
||||
mra->ma_desc, &mra->ma_value, ACL_SEARCH ) )
|
||||
mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
|
@ -285,7 +285,7 @@ test_ava_filter(
|
|||
Attribute *a;
|
||||
|
||||
if ( !access_allowed( be, conn, op, e,
|
||||
ava->aa_desc, &ava->aa_value, ACL_SEARCH ) )
|
||||
ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
|
@ -370,7 +370,7 @@ test_presence_filter(
|
|||
AttributeDescription *desc
|
||||
)
|
||||
{
|
||||
if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH ) )
|
||||
if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ test_substrings_filter(
|
|||
|
||||
|
||||
if ( !access_allowed( be, conn, op, e,
|
||||
f->f_sub_desc, NULL, ACL_SEARCH ) )
|
||||
f->f_sub_desc, NULL, ACL_SEARCH, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ LDAP_BEGIN_DECL
|
|||
LDAP_SLAPD_F (int) access_allowed LDAP_P((
|
||||
Backend *be, Connection *conn, Operation *op,
|
||||
Entry *e, AttributeDescription *desc, struct berval *val,
|
||||
slap_access_t access ));
|
||||
slap_access_t access,
|
||||
AccessControlState *state ));
|
||||
LDAP_SLAPD_F (int) acl_check_modlist LDAP_P((
|
||||
Backend *be, Connection *conn, Operation *op,
|
||||
Entry *e, Modifications *ml ));
|
||||
|
|
|
|||
|
|
@ -628,6 +628,8 @@ send_search_entry(
|
|||
char *edn;
|
||||
int userattrs;
|
||||
int opattrs;
|
||||
static AccessControlState acl_state_init = ACL_STATE_INIT;
|
||||
AccessControlState acl_state;
|
||||
|
||||
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
|
||||
|
||||
|
|
@ -647,9 +649,8 @@ send_search_entry(
|
|||
e->e_dn, attrsonly ? " (attrsOnly)" : "", 0 );
|
||||
#endif
|
||||
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
ad_entry, NULL, ACL_READ ) )
|
||||
ad_entry, NULL, ACL_READ, NULL ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
|
||||
|
|
@ -739,7 +740,11 @@ send_search_entry(
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
|
||||
acl_state = acl_state_init;
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e, desc, NULL,
|
||||
ACL_READ, &acl_state ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO, "send_search_entry: "
|
||||
"conn %d access to attribute %s not allowed\n",
|
||||
|
|
@ -749,7 +754,6 @@ send_search_entry(
|
|||
"access to attribute %s not allowed\n",
|
||||
desc->ad_cname.bv_val, 0, 0 );
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -771,12 +775,13 @@ send_search_entry(
|
|||
if ( ! attrsonly ) {
|
||||
for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
desc, &a->a_vals[i], ACL_READ ) )
|
||||
desc, &a->a_vals[i], ACL_READ, &acl_state ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
|
||||
"send_search_entry: conn %d access to attribute %s, value %d not allowed\n",
|
||||
op->o_connid, desc->ad_cname.bv_val, i ));
|
||||
"send_search_entry: conn %d "
|
||||
"access to attribute %s, value %d not allowed\n",
|
||||
op->o_connid, desc->ad_cname.bv_val, i ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"acl: access to attribute %s, value %d not allowed\n",
|
||||
|
|
@ -789,8 +794,8 @@ send_search_entry(
|
|||
if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
|
||||
"send_search_entry: conn %d ber_printf failed.\n",
|
||||
op->o_connid ));
|
||||
"send_search_entry: conn %d ber_printf failed.\n",
|
||||
op->o_connid ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"ber_printf failed\n", 0, 0, 0 );
|
||||
|
|
@ -807,8 +812,8 @@ send_search_entry(
|
|||
if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
|
||||
"send_search_entry: conn %d ber_printf failed\n",
|
||||
op->o_connid ));
|
||||
"send_search_entry: conn %d ber_printf failed\n",
|
||||
op->o_connid ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
|
||||
#endif
|
||||
|
|
@ -847,11 +852,16 @@ send_search_entry(
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
|
||||
acl_state = acl_state_init;
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e, desc, NULL,
|
||||
ACL_READ, &acl_state ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
|
||||
"send_search_entry: conn %s access to attribute %s not allowed\n",
|
||||
op->o_connid, desc->ad_cname.bv_val ));
|
||||
"send_search_entry: conn %s "
|
||||
"access to attribute %s not allowed\n",
|
||||
op->o_connid, desc->ad_cname.bv_val ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
|
||||
desc->ad_cname.bv_val, 0, 0 );
|
||||
|
|
@ -864,8 +874,8 @@ send_search_entry(
|
|||
if ( rc == -1 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
|
||||
"send_search_entry: conn %d ber_printf failed\n",
|
||||
op->o_connid ));
|
||||
"send_search_entry: conn %d ber_printf failed\n",
|
||||
op->o_connid ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
|
||||
#endif
|
||||
|
|
@ -880,12 +890,13 @@ send_search_entry(
|
|||
if ( ! attrsonly ) {
|
||||
for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
desc, &a->a_vals[i], ACL_READ ) )
|
||||
desc, &a->a_vals[i], ACL_READ, &acl_state ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
|
||||
"send_search_entry: conn %d access to %s, value %d not allowed\n",
|
||||
op->o_connid, desc->ad_cname.bv_val, i ));
|
||||
"send_search_entry: conn %d "
|
||||
"access to %s, value %d not allowed\n",
|
||||
op->o_connid, desc->ad_cname.bv_val, i ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"acl: access to attribute %s, value %d not allowed\n",
|
||||
|
|
@ -895,7 +906,6 @@ send_search_entry(
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
|
||||
|
|
@ -989,7 +999,6 @@ send_search_entry(
|
|||
Debug( LDAP_DEBUG_TRACE, "<= send_search_entry\n", 0, 0, 0 );
|
||||
#endif
|
||||
|
||||
|
||||
rc = 0;
|
||||
|
||||
error_return:;
|
||||
|
|
@ -1027,7 +1036,7 @@ send_search_reference(
|
|||
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
ad_entry, NULL, ACL_READ ) )
|
||||
ad_entry, NULL, ACL_READ, NULL ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
|
||||
|
|
@ -1043,7 +1052,7 @@ send_search_reference(
|
|||
}
|
||||
|
||||
if ( ! access_allowed( be, conn, op, e,
|
||||
ad_ref, NULL, ACL_READ ) )
|
||||
ad_ref, NULL, ACL_READ, NULL ) )
|
||||
{
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
|
||||
|
|
|
|||
|
|
@ -948,6 +948,26 @@ typedef struct slap_acl {
|
|||
struct slap_acl *acl_next;
|
||||
} AccessControl;
|
||||
|
||||
typedef struct slap_acl_state {
|
||||
unsigned as_recorded;
|
||||
#define ACL_STATE_NOT_RECORDED 0x0
|
||||
#define ACL_STATE_RECORDED_VD 0x1
|
||||
#define ACL_STATE_RECORDED_NV 0x2
|
||||
#define ACL_STATE_RECORDED 0x3
|
||||
|
||||
/* Access state */
|
||||
AccessControl *as_vd_acl;
|
||||
slap_mask_t as_vd_acl_mask;
|
||||
regmatch_t as_vd_acl_matches[MAXREMATCHES];
|
||||
int as_vd_acl_count;
|
||||
|
||||
Access *as_vd_access;
|
||||
int as_vd_access_count;
|
||||
|
||||
int as_result;
|
||||
} AccessControlState;
|
||||
#define ACL_STATE_INIT { ACL_STATE_NOT_RECORDED, NULL, 0UL, { 0 }, 0, NULL, 0 }
|
||||
|
||||
/*
|
||||
* replog moddn param structure
|
||||
*/
|
||||
|
|
@ -1138,7 +1158,6 @@ struct slap_backend_db {
|
|||
struct berval be_update_ndn; /* allowed to make changes (in replicas) */
|
||||
BerVarray be_update_refs; /* where to refer modifying clients to */
|
||||
char *be_realm;
|
||||
|
||||
void *be_private; /* anything the backend database needs */
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue