Commit b816c6d8 authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

ITS#5572

parent 13e0b0e0
......@@ -8,6 +8,7 @@ OpenLDAP 2.4.13 Engineering
Fixed libldap interaction with GnuTLS CN IP-based matches (ITS#5789)
Fixed libldap Ipv6 detection (ITS#5739)
Fixed slapd acl checks on ADD (ITS#4556,ITS#5723)
Fixed slapd acl application to newly created backends (ITS#5572)
Added slapd keyword add_content_acl for add checks (ITS#4556,ITS#5723)
Fixed slapd config backend olcLogFile support (ITS#5765)
Fixed slapd contextCSN pending list (ITS#5709)
......
......@@ -138,6 +138,7 @@ slap_access_allowed(
slap_access_t access_level;
const char *attr;
regmatch_t matches[MAXREMATCHES];
AccessControlState acl_state = ACL_STATE_INIT;
assert( op != NULL );
assert( e != NULL );
......@@ -179,7 +180,7 @@ slap_access_allowed(
}
/* use backend default access if no backend acls */
if ( op->o_bd->be_acl == NULL ) {
if ( op->o_bd->be_acl == NULL && frontendDB->be_acl == NULL ) {
int i;
Debug( LDAP_DEBUG_ACL,
......@@ -201,15 +202,22 @@ slap_access_allowed(
ret = 0;
control = ACL_BREAK;
if ( state && state->as_vd_ad == desc ) {
if ( state == NULL )
state = &acl_state;
if ( state->as_vd_ad == desc ) {
a = state->as_vd_acl;
count = state->as_vd_acl_count;
if ( state->as_fe_done )
state->as_fe_done--;
} else {
if ( state ) state->as_vi_acl = NULL;
state->as_vi_acl = NULL;
a = NULL;
count = 0;
}
if ( a == NULL )
state->as_fe_done = 0;
ACL_PRIV_ASSIGN( mask, *maskp );
memset( matches, '\0', sizeof( matches ) );
......@@ -476,13 +484,14 @@ slap_acl_get(
assert( e != NULL );
assert( count != NULL );
assert( desc != NULL );
assert( state != NULL );
attr = desc->ad_cname.bv_val;
assert( attr != NULL );
if( a == NULL ) {
if( op->o_bd == NULL ) {
if( op->o_bd == NULL || op->o_bd->be_acl == NULL ) {
a = frontendDB->be_acl;
} else {
a = op->o_bd->be_acl;
......@@ -490,7 +499,8 @@ slap_acl_get(
prev = NULL;
assert( a != NULL );
if ( a == frontendDB->be_acl )
state->as_fe_done = 1;
} else {
prev = a;
a = a->acl_next;
......@@ -498,9 +508,13 @@ slap_acl_get(
dnlen = e->e_nname.bv_len;
retry:
for ( ; a != NULL; prev = a, a = a->acl_next ) {
(*count) ++;
if ( a != frontendDB->be_acl && state->as_fe_done )
state->as_fe_done++;
if ( a->acl_dn_pat.bv_len || ( a->acl_dn_style != ACL_STYLE_REGEX )) {
if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n",
......@@ -567,7 +581,7 @@ slap_acl_get(
continue;
}
if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
if( !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
state->as_recorded |= ACL_STATE_RECORDED_VD;
state->as_vd_acl = prev;
state->as_vd_acl_count = *count - 1;
......@@ -649,6 +663,12 @@ slap_acl_get(
return a;
}
if ( !state->as_fe_done ) {
state->as_fe_done = 1;
a = frontendDB->be_acl;
goto retry;
}
Debug( LDAP_DEBUG_ACL, "<= acl_get: done.\n", 0, 0, 0 );
return( NULL );
}
......@@ -1856,7 +1876,7 @@ acl_check_modlist(
}
/* use backend default access if no backend acls */
if( op->o_bd != NULL && op->o_bd->be_acl == NULL ) {
if( op->o_bd != NULL && op->o_bd->be_acl == NULL && frontendDB->be_acl == NULL ) {
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: backend default %s access %s to \"%s\"\n",
access2str( ACL_WRITE ),
......
......@@ -2449,19 +2449,12 @@ acl_free( AccessControl *a )
free( a );
}
/* Because backend_startup uses acl_append to tack on the global_acl to
* the end of each backend's acl, we cannot just take one argument and
* merrily free our way to the end of the list. backend_destroy calls us
* with the be_acl in arg1, and global_acl in arg2 to give us a stopping
* point. config_destroy calls us with global_acl in arg1 and NULL in
* arg2, so we then proceed to polish off the global_acl.
*/
void
acl_destroy( AccessControl *a, AccessControl *end )
acl_destroy( AccessControl *a )
{
AccessControl *n;
for ( ; a && a != end; a = n ) {
for ( ; a; a = n ) {
n = a->acl_next;
acl_free( a );
}
......
......@@ -261,8 +261,6 @@ int backend_startup(Backend *be)
return rc;
}
}
/* append global access controls */
acl_append( &be->be_acl, frontendDB->be_acl, -1 );
return backend_startup_one( be, &cr );
}
......@@ -310,8 +308,6 @@ int backend_startup(Backend *be)
"has no suffix\n",
i, be->bd_info->bi_type, 0 );
}
/* append global access controls */
acl_append( &be->be_acl, frontendDB->be_acl, -1 );
rc = backend_startup_one( be, &cr );
......@@ -453,7 +449,7 @@ void backend_destroy_one( BackendDB *bd, int dynamic )
if ( !BER_BVISNULL( &bd->be_rootpw ) ) {
free( bd->be_rootpw.bv_val );
}
acl_destroy( bd->be_acl, frontendDB->be_acl );
acl_destroy( bd->be_acl );
limits_destroy( bd->be_limits );
if ( !BER_BVISNULL( &bd->be_update_ndn ) ) {
ch_free( bd->be_update_ndn.bv_val );
......@@ -504,7 +500,8 @@ int backend_destroy(void)
if ( !BER_BVISNULL( &bd->be_rootpw ) ) {
free( bd->be_rootpw.bv_val );
}
acl_destroy( bd->be_acl, frontendDB->be_acl );
acl_destroy( bd->be_acl );
frontendDB = NULL;
}
return 0;
......
......@@ -979,12 +979,7 @@ config_generic(ConfigArgs *c) {
AccessControl *a;
char *src, *dst, ibuf[11];
struct berval bv, abv;
AccessControl *end;
if ( c->be == frontendDB )
end = NULL;
else
end = frontendDB->be_acl;
for (i=0, a=c->be->be_acl; a && a != end; i++,a=a->acl_next) {
for (i=0, a=c->be->be_acl; a; i++,a=a->acl_next) {
abv.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
if ( abv.bv_len >= sizeof( ibuf ) ) {
ber_bvarray_free_x( c->rvalue_vals, NULL );
......@@ -1220,13 +1215,8 @@ config_generic(ConfigArgs *c) {
case CFG_ACL:
if ( c->valx < 0 ) {
AccessControl *end;
if ( c->be == frontendDB )
end = NULL;
else
end = frontendDB->be_acl;
acl_destroy( c->be->be_acl, end );
c->be->be_acl = end;
acl_destroy( c->be->be_acl );
c->be->be_acl = NULL;
} else {
AccessControl **prev, *a;
......@@ -1691,11 +1681,10 @@ sortval_reject:
case CFG_ACL:
/* Don't append to the global ACL if we're on a specific DB */
i = c->valx;
if ( c->be != frontendDB && frontendDB->be_acl && c->valx == -1 ) {
if ( c->valx == -1 ) {
AccessControl *a;
i = 0;
for ( a=c->be->be_acl; a && a != frontendDB->be_acl;
a = a->acl_next )
for ( a=c->be->be_acl; a; a = a->acl_next )
i++;
}
if ( parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, i ) ) {
......@@ -5920,7 +5909,7 @@ config_back_db_open( BackendDB *be, ConfigReply *cr )
/* If we have no explicitly configured ACLs, don't just use
* the global ACLs. Explicitly deny access to everything.
*/
if ( frontendDB->be_acl && be->be_acl == frontendDB->be_acl ) {
if ( !be->be_acl ) {
parse_acl(be, "config_back_db_open", 0, 6, (char **)defacl, 0 );
}
......
......@@ -1984,7 +1984,7 @@ config_destroy( )
if ( frontendDB->be_schemadn.bv_val )
free( frontendDB->be_schemadn.bv_val );
if ( frontendDB->be_acl )
acl_destroy( frontendDB->be_acl, NULL );
acl_destroy( frontendDB->be_acl );
}
free( line );
if ( slapd_args_file )
......
......@@ -111,7 +111,7 @@ LDAP_SLAPD_F (slap_access_t) str2access LDAP_P(( const char *str ));
LDAP_SLAPD_F (char *) accessmask2str LDAP_P(( slap_mask_t mask, char*, int debug ));
LDAP_SLAPD_F (slap_mask_t) str2accessmask LDAP_P(( const char *str ));
LDAP_SLAPD_F (void) acl_unparse LDAP_P(( AccessControl*, struct berval* ));
LDAP_SLAPD_F (void) acl_destroy LDAP_P(( AccessControl*, AccessControl* ));
LDAP_SLAPD_F (void) acl_destroy LDAP_P(( AccessControl* ));
LDAP_SLAPD_F (void) acl_free LDAP_P(( AccessControl *a ));
......
......@@ -1542,9 +1542,10 @@ typedef struct AccessControlState {
slap_acl_state_t as_recorded;
int as_vd_acl_count;
int as_result;
int as_fe_done;
} AccessControlState;
#define ACL_STATE_INIT { NULL, NULL, NULL, \
ACL_STATE_NOT_RECORDED, 0, 0 }
ACL_STATE_NOT_RECORDED, 0, 0, 0 }
/*
* Backend-info
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment