Skip to content
Snippets Groups Projects
Commit 5a5373ff authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

ITS#6287

parent 46d73bce
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,7 @@ OpenLDAP 2.4 Change Log ...@@ -3,6 +3,7 @@ OpenLDAP 2.4 Change Log
OpenLDAP 2.4.19 Engineering OpenLDAP 2.4.19 Engineering
Fixed client tools with null timeouts (ITS#6282) Fixed client tools with null timeouts (ITS#6282)
Fixed slapadd to warn about missing attrs for replicas (ITS#6281) Fixed slapadd to warn about missing attrs for replicas (ITS#6281)
Fixed slapd acl cache (ITS#6287)
Fixed slapd tools to allow -n for conversion (ITS#6258) Fixed slapd tools to allow -n for conversion (ITS#6258)
Fixed slapd-ldap with null timeouts (ITS#6282) Fixed slapd-ldap with null timeouts (ITS#6282)
Fixed slapd-ldif buffer overflow (ITS#6303) Fixed slapd-ldif buffer overflow (ITS#6303)
......
...@@ -53,6 +53,7 @@ static AccessControl * slap_acl_get( ...@@ -53,6 +53,7 @@ static AccessControl * slap_acl_get(
AttributeDescription *desc, AttributeDescription *desc,
struct berval *val, struct berval *val,
AclRegexMatches *matches, AclRegexMatches *matches,
slap_mask_t *mask,
AccessControlState *state ); AccessControlState *state );
static slap_control_t slap_acl_mask( static slap_control_t slap_acl_mask(
...@@ -151,6 +152,7 @@ slap_access_allowed( ...@@ -151,6 +152,7 @@ slap_access_allowed(
const char *attr; const char *attr;
AclRegexMatches matches; AclRegexMatches matches;
AccessControlState acl_state = ACL_STATE_INIT; AccessControlState acl_state = ACL_STATE_INIT;
static AccessControlState state_init = ACL_STATE_INIT;
assert( op != NULL ); assert( op != NULL );
assert( e != NULL ); assert( e != NULL );
...@@ -216,25 +218,27 @@ slap_access_allowed( ...@@ -216,25 +218,27 @@ slap_access_allowed(
if ( state == NULL ) if ( state == NULL )
state = &acl_state; state = &acl_state;
if ( state->as_vd_ad == desc ) { if ( state->as_desc == desc &&
state->as_access == access &&
state->as_vd_acl != NULL )
{
a = state->as_vd_acl; a = state->as_vd_acl;
count = state->as_vd_acl_count; count = state->as_vd_acl_count;
if ( state->as_fe_done ) if ( state->as_fe_done )
state->as_fe_done--; state->as_fe_done--;
ACL_PRIV_ASSIGN( mask, state->as_vd_mask );
} else { } else {
state->as_vi_acl = NULL; *state = state_init;
a = NULL; a = NULL;
count = 0; count = 0;
ACL_PRIV_ASSIGN( mask, *maskp );
} }
if ( a == NULL )
state->as_fe_done = 0;
ACL_PRIV_ASSIGN( mask, *maskp );
MATCHES_MEMSET( &matches ); MATCHES_MEMSET( &matches );
while ( ( a = slap_acl_get( a, &count, op, e, desc, val, while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
&matches, state ) ) != NULL ) &matches, &mask, state ) ) != NULL )
{ {
int i; int i;
int dnmaxcount = MATCHES_DNMAXCOUNT( &matches ); int dnmaxcount = MATCHES_DNMAXCOUNT( &matches );
...@@ -278,22 +282,6 @@ slap_access_allowed( ...@@ -278,22 +282,6 @@ slap_access_allowed(
Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 ); Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
} }
if ( state ) {
if ( state->as_vi_acl == a &&
( state->as_recorded & ACL_STATE_RECORDED_NV ) )
{
Debug( LDAP_DEBUG_ACL,
"=> slap_access_allowed: result was in cache (%s)\n",
attr, 0, 0 );
ret = state->as_result;
goto done;
} else {
Debug( LDAP_DEBUG_ACL,
"=> slap_access_allowed: result not in cache (%s)\n",
attr, 0, 0 );
}
}
control = slap_acl_mask( a, &mask, op, control = slap_acl_mask( a, &mask, op,
e, desc, val, &matches, count, state, access ); e, desc, val, &matches, count, state, access );
...@@ -374,7 +362,6 @@ access_allowed_mask( ...@@ -374,7 +362,6 @@ access_allowed_mask(
slap_mask_t *maskp ) slap_mask_t *maskp )
{ {
int ret = 1; int ret = 1;
AccessControl *a = NULL;
int be_null = 0; int be_null = 0;
#ifdef LDAP_DEBUG #ifdef LDAP_DEBUG
...@@ -383,7 +370,6 @@ access_allowed_mask( ...@@ -383,7 +370,6 @@ access_allowed_mask(
slap_mask_t mask; slap_mask_t mask;
slap_access_t access_level; slap_access_t access_level;
const char *attr; const char *attr;
static AccessControlState state_init = ACL_STATE_INIT;
assert( e != NULL ); assert( e != NULL );
assert( desc != NULL ); assert( desc != NULL );
...@@ -415,16 +401,20 @@ access_allowed_mask( ...@@ -415,16 +401,20 @@ access_allowed_mask(
} }
} }
if ( state ) { if ( state != NULL ) {
if ( state->as_vd_ad == desc ) { if ( state->as_desc == desc &&
if ( ( state->as_recorded & ACL_STATE_RECORDED_NV ) && state->as_access == access &&
val == NULL ) state->as_result != -1 &&
state->as_vd_acl == NULL )
{ {
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: result was in cache (%s)\n",
attr, 0, 0 );
return state->as_result; return state->as_result;
}
} else { } else {
*state = state_init; Debug( LDAP_DEBUG_ACL,
"=> access_allowed: result not in cache (%s)\n",
attr, 0, 0 );
} }
} }
...@@ -485,13 +475,9 @@ access_allowed_mask( ...@@ -485,13 +475,9 @@ access_allowed_mask(
done: done:
if ( state != NULL ) { if ( state != NULL ) {
/* If not value-dependent, save ACL in case of more attrs */ state->as_access = access;
if ( !( state->as_recorded & ACL_STATE_RECORDED_VD ) ) {
state->as_vi_acl = a;
state->as_result = ret; state->as_result = ret;
} state->as_desc = desc;
state->as_recorded |= ACL_STATE_RECORDED;
state->as_vd_ad = desc;
} }
if ( be_null ) op->o_bd = NULL; if ( be_null ) op->o_bd = NULL;
if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask ); if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
...@@ -514,6 +500,7 @@ slap_acl_get( ...@@ -514,6 +500,7 @@ slap_acl_get(
AttributeDescription *desc, AttributeDescription *desc,
struct berval *val, struct berval *val,
AclRegexMatches *matches, AclRegexMatches *matches,
slap_mask_t *mask,
AccessControlState *state ) AccessControlState *state )
{ {
const char *attr; const char *attr;
...@@ -628,10 +615,10 @@ slap_acl_get( ...@@ -628,10 +615,10 @@ slap_acl_get(
continue; continue;
} }
if( !( state->as_recorded & ACL_STATE_RECORDED_VD )) { if ( state->as_vd_acl == NULL ) {
state->as_recorded |= ACL_STATE_RECORDED_VD;
state->as_vd_acl = prev; state->as_vd_acl = prev;
state->as_vd_acl_count = *count - 1; state->as_vd_acl_count = *count - 1;
ACL_PRIV_ASSIGN ( state->as_vd_mask, *mask );
} }
if ( a->acl_attrval_style == ACL_STYLE_REGEX ) { if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
...@@ -727,10 +714,10 @@ slap_acl_get( ...@@ -727,10 +714,10 @@ slap_acl_get(
* Record value-dependent access control state * Record value-dependent access control state
*/ */
#define ACL_RECORD_VALUE_STATE do { \ #define ACL_RECORD_VALUE_STATE do { \
if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \ if( state && state->as_vd_acl == NULL ) { \
state->as_recorded |= ACL_STATE_RECORDED_VD; \
state->as_vd_acl = a; \ state->as_vd_acl = a; \
state->as_vd_acl_count = count; \ state->as_vd_acl_count = count; \
ACL_PRIV_ASSIGN( state->as_vd_mask, *mask ); \
} \ } \
} while( 0 ) } while( 0 )
...@@ -1024,6 +1011,7 @@ acl_mask_dnattr( ...@@ -1024,6 +1011,7 @@ acl_mask_dnattr(
AccessControl *a, AccessControl *a,
int count, int count,
AccessControlState *state, AccessControlState *state,
slap_mask_t *mask,
slap_dn_access *bdn, slap_dn_access *bdn,
struct berval *opndn ) struct berval *opndn )
{ {
...@@ -1504,7 +1492,7 @@ slap_acl_mask( ...@@ -1504,7 +1492,7 @@ slap_acl_mask(
if ( b->a_dn_at != NULL ) { if ( b->a_dn_at != NULL ) {
if ( acl_mask_dnattr( op, e, val, a, if ( acl_mask_dnattr( op, e, val, a,
count, state, count, state, mask,
&b->a_dn, &op->o_ndn ) ) &b->a_dn, &op->o_ndn ) )
{ {
continue; continue;
...@@ -1522,7 +1510,7 @@ slap_acl_mask( ...@@ -1522,7 +1510,7 @@ slap_acl_mask(
} }
if ( acl_mask_dnattr( op, e, val, a, if ( acl_mask_dnattr( op, e, val, a,
count, state, count, state, mask,
&b->a_realdn, &ndn ) ) &b->a_realdn, &ndn ) )
{ {
continue; continue;
...@@ -2019,7 +2007,7 @@ acl_check_modlist( ...@@ -2019,7 +2007,7 @@ acl_check_modlist(
if ( ! access_allowed( op, e, if ( ! access_allowed( op, e,
mlist->sml_desc, NULL, mlist->sml_desc, NULL,
( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL, ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
NULL ) ) &state ) )
{ {
ret = 0; ret = 0;
goto done; goto done;
......
...@@ -1527,27 +1527,27 @@ typedef struct AccessControl { ...@@ -1527,27 +1527,27 @@ typedef struct AccessControl {
struct AccessControl *acl_next; struct AccessControl *acl_next;
} AccessControl; } AccessControl;
typedef enum {
ACL_STATE_NOT_RECORDED = 0x0,
ACL_STATE_RECORDED_VD = 0x1,
ACL_STATE_RECORDED_NV = 0x2,
ACL_STATE_RECORDED = ( ACL_STATE_RECORDED_VD | ACL_STATE_RECORDED_NV )
} slap_acl_state_t;
typedef struct AccessControlState { typedef struct AccessControlState {
/* Access state */ /* Access state */
AccessControl *as_vi_acl;
AccessControl *as_vd_acl;
AttributeDescription *as_vd_ad;
/* The stored state is valid when requesting as_access access
* to the as_desc attributes. */
AttributeDescription *as_desc;
slap_access_t as_access;
slap_acl_state_t as_recorded; /* Value dependent acl where processing can restart */
AccessControl *as_vd_acl;
int as_vd_acl_count; int as_vd_acl_count;
slap_mask_t as_vd_mask;
/* The cached result after evaluating a value independent attr.
* Only valid when != -1 and as_vd_acl == NULL */
int as_result; int as_result;
/* True if started to process frontend ACLs */
int as_fe_done; int as_fe_done;
} AccessControlState; } AccessControlState;
#define ACL_STATE_INIT { NULL, NULL, NULL, \ #define ACL_STATE_INIT { NULL, ACL_NONE, NULL, 0, ACL_PRIV_NONE, -1, 0 }
ACL_STATE_NOT_RECORDED, 0, 0, 0 }
typedef struct AclRegexMatches { typedef struct AclRegexMatches {
int dn_count; int dn_count;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment