to update backends and overlays.
#endif /* LDAP_PF_LOCAL */
static AccessControl * slap_acl_get(
- AccessControl *ac, int *count,
- Operation *op, Entry *e,
- AttributeDescription *desc,
- struct berval *val,
+ Operation *op, AclCheck *ak,
+ AccessControl *ac,
AclRegexMatches *matches,
- slap_mask_t *mask,
- AccessControlState *state );
+ int *count );
static slap_control_t slap_acl_mask(
- AccessControl *ac, slap_mask_t *mask,
- Operation *op, Entry *e,
- AttributeDescription *desc,
- struct berval *val,
+ Operation *op, AclCheck *ak,
+ AccessControl *ac,
AclRegexMatches *matches,
- int count,
- AccessControlState *state,
- slap_access_t access );
+ int count );
static int regex_matches(
struct berval *pat, char *str,
int
slap_access_always_allowed(
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp )
+ AclCheck *ak )
{
- assert( maskp != NULL );
-
/* assign all */
- ACL_LVL_ASSIGN_MANAGE( *maskp );
+ ACL_LVL_ASSIGN_MANAGE( ak->ak_mask );
return 1;
}
int
slap_access_allowed(
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp )
+ AclCheck *ak )
{
int ret = 1;
int count;
#ifdef LDAP_DEBUG
char accessmaskbuf[ACCESSMASK_MAXLEN];
#endif
- slap_mask_t mask;
slap_control_t control;
slap_access_t access_level;
+ slap_mask_t oldmask;
const char *attr;
AclRegexMatches matches;
AccessControlState acl_state = ACL_STATE_INIT;
static AccessControlState state_init = ACL_STATE_INIT;
assert( op != NULL );
- assert( e != NULL );
- assert( desc != NULL );
- assert( maskp != NULL );
+ assert( ak != NULL );
+ assert( ak->ak_e != NULL );
+ assert( ak->ak_desc != NULL );
- access_level = ACL_LEVEL( access );
- attr = desc->ad_cname.bv_val;
+ access_level = ACL_LEVEL( ak->ak_access );
+ attr = ak->ak_desc->ad_cname.bv_val;
assert( attr != NULL );
- ACL_INIT( mask );
-
/* grant database root access */
if ( be_isroot( op ) ) {
Debug( LDAP_DEBUG_ACL, "<= root access granted\n", 0, 0, 0 );
- mask = ACL_LVL_MANAGE;
+ ak->ak_mask = ACL_LVL_MANAGE;
goto done;
}
+ oldmask = ak->ak_mask;
+ ACL_INIT( ak->ak_mask );
+
/*
* no-user-modification operational attributes are ignored
* by ACL_WRITE checking as any found here are not provided
* manage data, so we need to check its privileges.
*/
if ( access_level == ACL_WRITE
- && is_at_no_user_mod( desc->ad_type )
- && desc != slap_schema.si_ad_entry
- && desc != slap_schema.si_ad_children )
+ && is_at_no_user_mod( ak->ak_desc->ad_type )
+ && ak->ak_desc != slap_schema.si_ad_entry
+ && ak->ak_desc != slap_schema.si_ad_children )
{
Debug( LDAP_DEBUG_ACL, "NoUserMod Operational attribute:"
" %s access granted\n",
Debug( LDAP_DEBUG_ACL,
"=> slap_access_allowed: backend default %s "
"access %s to \"%s\"\n",
- access2str( access ),
+ access2str( ak->ak_access ),
op->o_bd->be_dfltaccess >= access_level ? "granted" : "denied",
op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" );
ret = op->o_bd->be_dfltaccess >= access_level;
- mask = ACL_PRIV_LEVEL;
+ ak->ak_mask = ACL_PRIV_LEVEL;
for ( i = ACL_NONE; i <= op->o_bd->be_dfltaccess; i++ ) {
- ACL_PRIV_SET( mask, ACL_ACCESS2PRIV( i ) );
+ ACL_PRIV_SET( ak->ak_mask, ACL_ACCESS2PRIV( i ) );
}
goto done;
ret = 0;
control = ACL_BREAK;
- if ( state == NULL )
- state = &acl_state;
- if ( state->as_desc == desc &&
- state->as_access == access &&
- state->as_vd_acl != NULL )
+ if ( ak->ak_state == NULL )
+ ak->ak_state = &acl_state;
+ if ( ak->ak_state->as_desc == ak->ak_desc &&
+ ak->ak_state->as_access == ak->ak_access &&
+ ak->ak_state->as_vd_acl != NULL )
{
- a = state->as_vd_acl;
- count = state->as_vd_acl_count;
- if ( state->as_fe_done )
- state->as_fe_done--;
- ACL_PRIV_ASSIGN( mask, state->as_vd_mask );
+ a = ak->ak_state->as_vd_acl;
+ count = ak->ak_state->as_vd_acl_count;
+ if ( ak->ak_state->as_fe_done )
+ ak->ak_state->as_fe_done--;
+ ACL_PRIV_ASSIGN( ak->ak_mask, ak->ak_state->as_vd_mask );
} else {
- *state = state_init;
+ *ak->ak_state = state_init;
a = NULL;
count = 0;
- ACL_PRIV_ASSIGN( mask, *maskp );
}
MATCHES_MEMSET( &matches );
- while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
- &matches, &mask, state ) ) != NULL )
+ while ( ( a = slap_acl_get( op, ak, a, &matches, &count ) ) != NULL )
{
int i;
int dnmaxcount = MATCHES_DNMAXCOUNT( &matches );
/* DN matches */
for ( i = 0; i < dnmaxcount && dn_data[i].rm_eo > 0; i++ ) {
- char *data = e->e_ndn;
+ char *data = ak->ak_e->e_ndn;
Debug( LDAP_DEBUG_ACL, "=> match[dn%d]: %d %d ", i,
(int)dn_data[i].rm_so,
/* val matches */
for ( i = 0; i < valmaxcount && val_data[i].rm_eo > 0; i++ ) {
- char *data = val->bv_val;
+ char *data = ak->ak_val->bv_val;
Debug( LDAP_DEBUG_ACL, "=> match[val%d]: %d %d ", i,
(int)val_data[i].rm_so,
Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
}
- control = slap_acl_mask( a, &mask, op,
- e, desc, val, &matches, count, state, access );
+ control = slap_acl_mask( op, ak, a,
+ &matches, count );
if ( control != ACL_BREAK ) {
break;
MATCHES_MEMSET( &matches );
}
- if ( ACL_IS_INVALID( mask ) ) {
+ if ( ACL_IS_INVALID( ak->ak_mask ) ) {
Debug( LDAP_DEBUG_ACL,
"=> slap_access_allowed: \"%s\" (%s) invalid!\n",
- e->e_dn, attr, 0 );
- ACL_PRIV_ASSIGN( mask, *maskp );
+ ak->ak_e->e_dn, attr, 0 );
+ ACL_PRIV_ASSIGN( ak->ak_mask, oldmask );
} else if ( control == ACL_BREAK ) {
Debug( LDAP_DEBUG_ACL,
goto done;
}
- ret = ACL_GRANT( mask, access );
+ ret = ACL_GRANT( ak->ak_mask, ak->ak_access );
Debug( LDAP_DEBUG_ACL,
"=> slap_access_allowed: %s access %s by %s\n",
- access2str( access ), ret ? "granted" : "denied",
- accessmask2str( mask, accessmaskbuf, 1 ) );
+ access2str( ak->ak_access ), ret ? "granted" : "denied",
+ accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
done:
- ACL_PRIV_ASSIGN( *maskp, mask );
+ if ( ak->ak_state == &acl_state )
+ ak->ak_state = NULL;
return ret;
}
int
fe_access_allowed(
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp )
+ AclCheck *ak )
{
BackendDB *be_orig;
int rc;
if ( op->o_bd == NULL )
op->o_bd = frontendDB;
}
- rc = slap_access_allowed( op, e, desc, val, access, state, maskp );
+ rc = slap_access_allowed( op, ak );
op->o_bd = be_orig;
return rc;
}
int
-access_allowed_mask(
+access_allowed(
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp )
+ AclCheck *ak )
{
int ret = 1;
int be_null = 0;
#ifdef LDAP_DEBUG
char accessmaskbuf[ACCESSMASK_MAXLEN];
#endif
- slap_mask_t mask;
- slap_access_t access_level;
+ slap_access_t access_level;
const char *attr;
- assert( e != NULL );
- assert( desc != NULL );
+ assert( ak != NULL );
+ assert( ak->ak_e != NULL );
+ assert( ak->ak_desc != NULL );
- access_level = ACL_LEVEL( access );
+ access_level = ACL_LEVEL( ak->ak_access );
assert( access_level > ACL_NONE );
- ACL_INIT( mask );
- if ( maskp ) ACL_INVALIDATE( *maskp );
+ ACL_INVALIDATE( ak->ak_mask );
- attr = desc->ad_cname.bv_val;
+ attr = ak->ak_desc->ad_cname.bv_val;
assert( attr != NULL );
if ( op ) {
if ( op->o_acl_priv != ACL_NONE ) {
- access = op->o_acl_priv;
+ ak->ak_access = op->o_acl_priv;
} else if ( op->o_is_auth_check &&
( access_level == ACL_SEARCH || access_level == ACL_READ ) )
{
- access = ACL_AUTH;
+ ak->ak_access = ACL_AUTH;
} else if ( get_relax( op ) && access_level == ACL_WRITE &&
- desc == slap_schema.si_ad_entry )
+ ak->ak_desc == slap_schema.si_ad_entry )
{
- access = ACL_MANAGE;
+ ak->ak_access = ACL_MANAGE;
}
}
- if ( state != NULL ) {
- if ( state->as_desc == desc &&
- state->as_access == access &&
- state->as_result != -1 &&
- state->as_vd_acl == NULL )
+ if ( ak->ak_state != NULL ) {
+ if ( ak->ak_state->as_desc == ak->ak_desc &&
+ ak->ak_state->as_access == ak->ak_access &&
+ ak->ak_state->as_result != -1 &&
+ ak->ak_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 ak->ak_state->as_result;
} else {
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: result not in cache (%s)\n",
}
}
+ ACL_INIT( ak->ak_mask );
+
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: %s access to \"%s\" \"%s\" requested\n",
- access2str( access ), e->e_dn, attr );
+ access2str( ak->ak_access ), ak->ak_e->e_dn, attr );
if ( op == NULL ) {
/* no-op call */
/* this is enforced in backend_add() */
if ( op->o_bd->bd_info->bi_access_allowed ) {
/* delegate to backend */
- ret = op->o_bd->bd_info->bi_access_allowed( op, e,
- desc, val, access, state, &mask );
+ ret = op->o_bd->bd_info->bi_access_allowed( op, ak );
} else {
/* use default (but pass through frontend
* for global ACL overlays) */
- ret = frontendDB->bd_info->bi_access_allowed( op, e,
- desc, val, access, state, &mask );
+ ret = frontendDB->bd_info->bi_access_allowed( op, ak );
}
if ( !ret ) {
- if ( ACL_IS_INVALID( mask ) ) {
+ if ( ACL_IS_INVALID( ak->ak_mask ) ) {
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: \"%s\" (%s) invalid!\n",
- e->e_dn, attr, 0 );
- ACL_INIT( mask );
+ ak->ak_e->e_dn, attr, 0 );
+ ACL_INIT( ak->ak_mask );
} else {
Debug( LDAP_DEBUG_ACL,
Debug( LDAP_DEBUG_ACL,
"=> access_allowed: %s access %s by %s\n",
- access2str( access ), ret ? "granted" : "denied",
- accessmask2str( mask, accessmaskbuf, 1 ) );
+ access2str( ak->ak_access ), ret ? "granted" : "denied",
+ accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
done:
- if ( state != NULL ) {
- state->as_access = access;
- state->as_result = ret;
- state->as_desc = desc;
+ if ( ak->ak_state != NULL ) {
+ ak->ak_state->as_access = ak->ak_access;
+ ak->ak_state->as_result = ret;
+ ak->ak_state->as_desc = ak->ak_desc;
}
if ( be_null ) op->o_bd = NULL;
- if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
return ret;
}
static AccessControl *
slap_acl_get(
- AccessControl *a,
- int *count,
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
+ AclCheck *ak,
+ AccessControl *a,
AclRegexMatches *matches,
- slap_mask_t *mask,
- AccessControlState *state )
+ int *count )
{
const char *attr;
ber_len_t dnlen;
AccessControl *prev;
- assert( e != NULL );
+ assert( ak->ak_e != NULL );
assert( count != NULL );
- assert( desc != NULL );
- assert( state != NULL );
+ assert( ak->ak_desc != NULL );
+ assert( ak->ak_state != NULL );
- attr = desc->ad_cname.bv_val;
+ attr = ak->ak_desc->ad_cname.bv_val;
assert( attr != NULL );
assert( a != NULL );
if ( a == frontendDB->be_acl )
- state->as_fe_done = 1;
+ ak->ak_state->as_fe_done = 1;
} else {
prev = a;
a = a->acl_next;
}
- dnlen = e->e_nname.bv_len;
+ dnlen = ak->ak_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 != frontendDB->be_acl && ak->ak_state->as_fe_done )
+ ak->ak_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",
*count, a->acl_dn_pat.bv_val, (int) a->acl_dn_re.re_nsub );
if ( regexec ( &a->acl_dn_re,
- e->e_ndn,
+ ak->ak_e->e_ndn,
matches->dn_count,
matches->dn_data, 0 ) )
continue;
continue;
if ( patlen > 0 ) {
- if ( !DN_SEPARATOR( e->e_ndn[dnlen - patlen - 1] ) )
+ if ( !DN_SEPARATOR( ak->ak_e->e_ndn[dnlen - patlen - 1] ) )
continue;
sep = 1;
}
- rdnlen = dn_rdnlen( NULL, &e->e_nname );
+ rdnlen = dn_rdnlen( NULL, &ak->ak_e->e_nname );
if ( rdnlen + patlen + sep != dnlen )
continue;
} else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
- if ( dnlen > patlen && !DN_SEPARATOR( e->e_ndn[dnlen - patlen - 1] ) )
+ if ( dnlen > patlen && !DN_SEPARATOR( ak->ak_e->e_ndn[dnlen - patlen - 1] ) )
continue;
} else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) {
if ( dnlen <= patlen )
continue;
- if ( !DN_SEPARATOR( e->e_ndn[dnlen - patlen - 1] ) )
+ if ( !DN_SEPARATOR( ak->ak_e->e_ndn[dnlen - patlen - 1] ) )
continue;
}
- if ( strcmp( a->acl_dn_pat.bv_val, e->e_ndn + dnlen - patlen ) != 0 )
+ if ( strcmp( a->acl_dn_pat.bv_val, ak->ak_e->e_ndn + dnlen - patlen ) != 0 )
continue;
}
*count, 0, 0 );
}
- if ( a->acl_attrs && !ad_inlist( desc, a->acl_attrs ) ) {
+ if ( a->acl_attrs && !ad_inlist( ak->ak_desc, a->acl_attrs ) ) {
matches->dn_data[0].rm_so = -1;
matches->dn_data[0].rm_eo = -1;
matches->val_data[0].rm_so = -1;
/* Is this ACL only for a specific value? */
if ( a->acl_attrval.bv_len ) {
- if ( val == NULL ) {
+ if ( ak->ak_val == NULL ) {
continue;
}
- if ( state->as_vd_acl == NULL ) {
- state->as_vd_acl = prev;
- state->as_vd_acl_count = *count - 1;
- ACL_PRIV_ASSIGN ( state->as_vd_mask, *mask );
+ if ( ak->ak_state->as_vd_acl == NULL ) {
+ ak->ak_state->as_vd_acl = prev;
+ ak->ak_state->as_vd_acl_count = *count - 1;
+ ACL_PRIV_ASSIGN ( ak->ak_state->as_vd_mask, ak->ak_mask );
}
if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
"acl_get: valpat %s\n",
a->acl_attrval.bv_val, 0, 0 );
if ( regexec ( &a->acl_attrval_re,
- val->bv_val,
+ ak->ak_val->bv_val,
matches->val_count,
matches->val_data, 0 ) )
{
a->acl_attrval.bv_val, 0, 0 );
if ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
- if (value_match( &match, desc,
+ if (value_match( &match, ak->ak_desc,
a->acl_attrval_mr, 0,
- val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
+ ak->ak_val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
match )
continue;
ber_len_t patlen, vdnlen;
patlen = a->acl_attrval.bv_len;
- vdnlen = val->bv_len;
+ vdnlen = ak->ak_val->bv_len;
if ( vdnlen < patlen )
continue;
} else if ( a->acl_attrval_style == ACL_STYLE_ONE ) {
ber_len_t rdnlen = 0;
- if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+ if ( !DN_SEPARATOR( ak->ak_val->bv_val[vdnlen - patlen - 1] ) )
continue;
- rdnlen = dn_rdnlen( NULL, val );
+ rdnlen = dn_rdnlen( NULL, ak->ak_val );
if ( rdnlen + patlen + 1 != vdnlen )
continue;
} else if ( a->acl_attrval_style == ACL_STYLE_SUBTREE ) {
- if ( vdnlen > patlen && !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+ if ( vdnlen > patlen && !DN_SEPARATOR( ak->ak_val->bv_val[vdnlen - patlen - 1] ) )
continue;
} else if ( a->acl_attrval_style == ACL_STYLE_CHILDREN ) {
if ( vdnlen <= patlen )
continue;
- if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
+ if ( !DN_SEPARATOR( ak->ak_val->bv_val[vdnlen - patlen - 1] ) )
continue;
}
- if ( strcmp( a->acl_attrval.bv_val, val->bv_val + vdnlen - patlen ) )
+ if ( strcmp( a->acl_attrval.bv_val, ak->ak_val->bv_val + vdnlen - patlen ) )
continue;
}
}
}
if ( a->acl_filter != NULL ) {
- ber_int_t rc = test_filter( NULL, e, a->acl_filter );
+ ber_int_t rc = test_filter( NULL, ak->ak_e, a->acl_filter );
if ( rc != LDAP_COMPARE_TRUE ) {
continue;
}
return a;
}
- if ( !state->as_fe_done ) {
- state->as_fe_done = 1;
+ if ( !ak->ak_state->as_fe_done ) {
+ ak->ak_state->as_fe_done = 1;
a = frontendDB->be_acl;
goto retry;
}
* Record value-dependent access control state
*/
#define ACL_RECORD_VALUE_STATE do { \
- if( state && state->as_vd_acl == NULL ) { \
- state->as_vd_acl = a; \
- state->as_vd_acl_count = count; \
- ACL_PRIV_ASSIGN( state->as_vd_mask, *mask ); \
+ if( ak->ak_state && ak->ak_state->as_vd_acl == NULL ) { \
+ ak->ak_state->as_vd_acl = a; \
+ ak->ak_state->as_vd_acl_count = count; \
+ ACL_PRIV_ASSIGN( ak->ak_state->as_vd_mask, ak->ak_mask ); \
} \
} while( 0 )
static int
acl_mask_dn(
Operation *op,
- Entry *e,
- struct berval *val,
+ AclCheck *ak,
AccessControl *a,
AclRegexMatches *matches,
slap_dn_access *bdn,
struct berval ndn, selfndn;
int level;
- if ( BER_BVISEMPTY( opndn ) || BER_BVISNULL( &e->e_nname ) ) {
+ if ( BER_BVISEMPTY( opndn ) || BER_BVISNULL( &ak->ak_e->e_nname ) ) {
return 1;
}
level = bdn->a_self_level;
if ( level < 0 ) {
selfndn = *opndn;
- ndn = e->e_nname;
+ ndn = ak->ak_e->e_nname;
level = -level;
} else {
ndn = *opndn;
- selfndn = e->e_nname;
+ selfndn = ak->ak_e->e_nname;
}
for ( ; level > 0; level-- ) {
case ACL_STYLE_BASE:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 1;
break;
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
- tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_data[1].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
+ tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 2;
break;
}
if ( !regex_matches( &bdn->a_pat, opndn->bv_val,
- &e->e_nname, NULL, tmp_matchesp ) )
+ &ak->ak_e->e_nname, NULL, tmp_matchesp ) )
{
return 1;
}
ber_len_t patlen, odnlen;
int got_match = 0;
- if ( e->e_dn == NULL )
+ if ( ak->ak_e->e_dn == NULL )
return 1;
if ( bdn->a_expand ) {
case ACL_STYLE_BASE:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 1;
break;
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
- tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_data[1].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
+ tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 2;
break;
}
if ( acl_string_expand( &bv, &bdn->a_pat,
- &e->e_nname,
- val, tmp_matchesp ) )
+ &ak->ak_e->e_nname,
+ ak->ak_val, tmp_matchesp ) )
{
return 1;
}
static int
acl_mask_dnattr(
Operation *op,
- Entry *e,
- struct berval *val,
+ AclCheck *ak,
AccessControl *a,
int count,
- AccessControlState *state,
- slap_mask_t *mask,
slap_dn_access *bdn,
struct berval *opndn )
{
bv = *opndn;
/* see if asker is listed in dnattr */
- for ( at = attrs_find( e->e_attrs, bdn->a_at );
+ for ( at = attrs_find( ak->ak_e->e_attrs, bdn->a_at );
at != NULL;
at = attrs_find( at->a_next, bdn->a_at ) )
{
*/
if ( bdn->a_self ) {
/* check if the target is an attribute. */
- if ( val == NULL ) return 1;
+ if ( ak->ak_val == NULL ) return 1;
/* target is attribute, check if the attribute value
* is the op dn.
*/
rc = value_match( &match, bdn->a_at,
bdn->a_at->ad_type->sat_equality, 0,
- val, &bv, &text );
+ ak->ak_val, &bv, &text );
/* on match error or no match, fail the ACL clause */
if ( rc != LDAP_SUCCESS || match != 0 )
return 1;
/* this is a self clause, check if the target is an
* attribute.
*/
- if ( val == NULL )
+ if ( ak->ak_val == NULL )
return 1;
/* target is attribute, check if the attribute value
*/
rc = value_match( &match, bdn->a_at,
bdn->a_at->ad_type->sat_equality, 0,
- val, &bv, &text );
+ ak->ak_val, &bv, &text );
/* on match error or no match, fail the ACL clause */
if ( rc != LDAP_SUCCESS || match != 0 )
static slap_control_t
slap_acl_mask(
- AccessControl *a,
- slap_mask_t *mask,
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
+ AclCheck *ak,
+ AccessControl *a,
AclRegexMatches *matches,
- int count,
- AccessControlState *state,
- slap_access_t access )
+ int count )
{
int i;
Access *b;
#endif /* SLAP_DYNACL */
assert( a != NULL );
- assert( mask != NULL );
- assert( desc != NULL );
+ assert( ak->ak_desc != NULL );
- attr = desc->ad_cname.bv_val;
+ attr = ak->ak_desc->ad_cname.bv_val;
assert( attr != NULL );
Debug( LDAP_DEBUG_ACL,
"=> acl_mask: access to entry \"%s\", attr \"%s\" requested\n",
- e->e_dn, attr, 0 );
+ ak->ak_e->e_dn, attr, 0 );
Debug( LDAP_DEBUG_ACL,
"=> acl_mask: to %s by \"%s\", (%s) \n",
- val ? "value" : "all values",
+ ak->ak_val ? "value" : "all values",
op->o_ndn.bv_val ? op->o_ndn.bv_val : "",
- accessmask2str( *mask, accessmaskbuf, 1 ) );
-
+ accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
b = a->acl_access;
i = 1;
* is maintained in a_dn_pat.
*/
- if ( acl_mask_dn( op, e, val, a, matches,
+ if ( acl_mask_dn( op, ak, a, matches,
&b->a_dn, &op->o_ndn ) )
{
continue;
ndn = op->o_ndn;
}
- if ( acl_mask_dn( op, e, val, a, matches,
+ if ( acl_mask_dn( op, ak, a, matches,
&b->a_realdn, &ndn ) )
{
continue;
if ( !ber_bvccmp( &b->a_sockurl_pat, '*' ) ) {
if ( b->a_sockurl_style == ACL_STYLE_REGEX) {
if ( !regex_matches( &b->a_sockurl_pat, op->o_conn->c_listener_url.bv_val,
- &e->e_nname, val, matches ) )
+ &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- if ( acl_string_expand( &bv, &b->a_sockurl_pat, &e->e_nname, val, matches ) )
+ if ( acl_string_expand( &bv, &b->a_sockurl_pat, &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
if ( !ber_bvccmp( &b->a_domain_pat, '*' ) ) {
if ( b->a_domain_style == ACL_STYLE_REGEX) {
if ( !regex_matches( &b->a_domain_pat, op->o_conn->c_peer_domain.bv_val,
- &e->e_nname, val, matches ) )
+ &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
bv.bv_len = sizeof(buf) - 1;
bv.bv_val = buf;
- if ( acl_string_expand(&bv, &b->a_domain_pat, &e->e_nname, val, matches) )
+ if ( acl_string_expand(&bv, &b->a_domain_pat, &ak->ak_e->e_nname, ak->ak_val, matches) )
{
continue;
}
if ( !ber_bvccmp( &b->a_peername_pat, '*' ) ) {
if ( b->a_peername_style == ACL_STYLE_REGEX ) {
if ( !regex_matches( &b->a_peername_pat, op->o_conn->c_peer_name.bv_val,
- &e->e_nname, val, matches ) )
+ &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- if ( acl_string_expand( &bv, &b->a_peername_pat, &e->e_nname, val, matches ) )
+ if ( acl_string_expand( &bv, &b->a_peername_pat, &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
if ( !ber_bvccmp( &b->a_sockname_pat, '*' ) ) {
if ( b->a_sockname_style == ACL_STYLE_REGEX) {
if ( !regex_matches( &b->a_sockname_pat, op->o_conn->c_sock_name.bv_val,
- &e->e_nname, val, matches ) )
+ &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- if ( acl_string_expand( &bv, &b->a_sockname_pat, &e->e_nname, val, matches ) )
+ if ( acl_string_expand( &bv, &b->a_sockname_pat, &ak->ak_e->e_nname, ak->ak_val, matches ) )
{
continue;
}
}
if ( b->a_dn_at != NULL ) {
- if ( acl_mask_dnattr( op, e, val, a,
- count, state, mask,
+ if ( acl_mask_dnattr( op, ak, a,
+ count,
&b->a_dn, &op->o_ndn ) )
{
continue;
ndn = op->o_ndn;
}
- if ( acl_mask_dnattr( op, e, val, a,
- count, state, mask,
+ if ( acl_mask_dnattr( op, ak, a,
+ count,
&b->a_realdn, &ndn ) )
{
continue;
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
case ACL_STYLE_BASE:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 1;
break;
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
- tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_data[1].rm_eo = e->e_nname.bv_len;
+ tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 2;
break;
}
if ( acl_string_expand( &bv, &b->a_group_pat,
- &e->e_nname, val,
+ &ak->ak_e->e_nname, ak->ak_val,
tmp_matchesp ) )
{
continue;
bv = b->a_group_pat;
}
- rc = backend_group( op, e, &bv, &op->o_ndn,
+ rc = backend_group( op, ak->ak_e, &bv, &op->o_ndn,
b->a_group_oc, b->a_group_at );
if ( ndn.bv_val ) {
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
case ACL_STYLE_BASE:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
tmp_matches.dn_count = 1;
break;
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
tmp_data[0].rm_so = 0;
- tmp_data[0].rm_eo = e->e_nname.bv_len;
- tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_data[1].rm_eo = e->e_nname.bv_len; tmp_matches.dn_count = 2;
+ tmp_data[0].rm_eo = ak->ak_e->e_nname.bv_len;
+ tmp_data[1].rm_so = ak->ak_e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = ak->ak_e->e_nname.bv_len; tmp_matches.dn_count = 2;
break;
default:
}
if ( acl_string_expand( &bv, &b->a_set_pat,
- &e->e_nname, val,
+ &ak->ak_e->e_nname, ak->ak_val,
tmp_matchesp ) )
{
continue;
bv = b->a_set_pat;
}
- if ( acl_match_set( &bv, op, e, NULL ) == 0 ) {
+ if ( acl_match_set( &bv, op, ak->ak_e, NULL ) == 0 ) {
continue;
}
}
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;
+ if ( ak->ak_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName &&
+ !is_at_syntax( ak->ak_desc->ad_type, SLAPD_NAMEUID_SYNTAX )) continue;
/* check if the target is an attribute. */
- if ( val == NULL ) continue;
+ if ( ak->ak_val == NULL ) continue;
/* a DN must be present */
if ( BER_BVISEMPTY( &op->o_ndn ) ) {
/* 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 );
+ rc = value_match( &match, ak->ak_desc,
+ ak->ak_desc->ad_type->sat_equality, 0,
+ ak->ak_val, &op->o_ndn, &dummy );
/* on match error or no match, fail the ACL clause */
if ( rc != LDAP_SUCCESS || match != 0 )
continue;
* sending attribute values matches require
* an API update
*/
- (void)da->da_mask( da->da_private, op, e, desc,
- val, matches->dn_count, matches->dn_data,
+ (void)da->da_mask( da->da_private, op, ak->ak_e, ak->ak_desc,
+ ak->ak_val, matches->dn_count, matches->dn_data,
&grant, &deny );
tgrant |= grant;
? "break"
: "stop" );
/* save old mask */
- oldmask = *mask;
+ oldmask = ak->ak_mask;
if( ACL_IS_ADDITIVE(modmask) ) {
/* add privs */
- ACL_PRIV_SET( *mask, modmask );
+ ACL_PRIV_SET( ak->ak_mask, modmask );
/* cleanup */
- ACL_PRIV_CLR( *mask, ~ACL_PRIV_MASK );
+ ACL_PRIV_CLR( ak->ak_mask, ~ACL_PRIV_MASK );
} else if( ACL_IS_SUBTRACTIVE(modmask) ) {
/* substract privs */
- ACL_PRIV_CLR( *mask, modmask );
+ ACL_PRIV_CLR( ak->ak_mask, modmask );
/* cleanup */
- ACL_PRIV_CLR( *mask, ~ACL_PRIV_MASK );
+ ACL_PRIV_CLR( ak->ak_mask, ~ACL_PRIV_MASK );
} else {
/* assign privs */
- *mask = modmask;
+ ak->ak_mask = modmask;
}
Debug( LDAP_DEBUG_ACL,
"<= acl_mask: [%d] mask: %s\n",
- i, accessmask2str(*mask, accessmaskbuf, 1), 0 );
+ i, accessmask2str(ak->ak_mask, accessmaskbuf, 1), 0 );
if( b->a_type == ACL_CONTINUE ) {
continue;
}
/* implicit "by * none" clause */
- ACL_INIT(*mask);
+ ACL_INIT(ak->ak_mask);
Debug( LDAP_DEBUG_ACL,
"<= acl_mask: no more <who> clauses, returning %s (stop)\n",
- accessmask2str(*mask, accessmaskbuf, 1), 0, 0 );
+ accessmask2str(ak->ak_mask, accessmaskbuf, 1), 0, 0 );
return ACL_STOP;
}
Entry *e,
Modifications *mlist )
{
- struct berval *bv;
AccessControlState state = ACL_STATE_INIT;
+ AclCheck ak;
Backend *be;
int be_null = 0;
int ret = 1; /* default is access allowed */
goto done;
}
+ ak.ak_e = e;
+ ak.ak_state = &state;
+
for ( ; mlist != NULL; mlist = mlist->sml_next ) {
/*
* Internal mods are ignored by ACL_WRITE checking
continue;
}
+ ak.ak_desc = mlist->sml_desc;
switch ( mlist->sml_op ) {
case LDAP_MOD_REPLACE:
case LDAP_MOD_INCREMENT:
* attribute and permission to add the specific attributes.
* This prevents abuse from selfwriters.
*/
- if ( ! access_allowed( op, e,
- mlist->sml_desc, NULL,
- ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
- &state ) )
+ ak.ak_val = NULL;
+ ak.ak_access = ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL;
+ if ( ! access_allowed( op, &ak ))
{
ret = 0;
goto done;
case LDAP_MOD_ADD:
assert( mlist->sml_values != NULL );
+ ak.ak_access = ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WADD;
- for ( bv = mlist->sml_nvalues
+ for ( ak.ak_val = mlist->sml_nvalues
? mlist->sml_nvalues : mlist->sml_values;
- bv->bv_val != NULL; bv++ )
+ ak.ak_val->bv_val != NULL; ak.ak_val++ )
{
- if ( ! access_allowed( op, e,
- mlist->sml_desc, bv,
- ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WADD,
- &state ) )
+ if ( ! access_allowed( op, &ak ))
{
ret = 0;
goto done;
case LDAP_MOD_DELETE:
if ( mlist->sml_values == NULL ) {
- if ( ! access_allowed( op, e,
- mlist->sml_desc, NULL,
- ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
- &state ) )
+ ak.ak_val = NULL;
+ ak.ak_access = ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL;
+ if ( ! access_allowed( op, &ak ))
{
ret = 0;
goto done;
}
break;
}
- for ( bv = mlist->sml_nvalues
+ for ( ak.ak_val = mlist->sml_nvalues
? mlist->sml_nvalues : mlist->sml_values;
- bv->bv_val != NULL; bv++ )
+ ak.ak_val->bv_val != NULL; ak.ak_val++ )
{
- if ( ! access_allowed( op, e,
- mlist->sml_desc, bv,
- ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
- &state ) )
+ if ( ! access_allowed( op, &ak ))
{
ret = 0;
goto done;
BerVarray *vals,
slap_access_t access )
{
- Entry *e = NULL;
void *o_priv = op->o_private, *e_priv = NULL;
Attribute *a = NULL;
int freeattr = 0, i, j, rc = LDAP_SUCCESS;
AccessControlState acl_state = ACL_STATE_INIT;
+ AclCheck ak;
Backend *be = op->o_bd;
OpExtra *oex;
op->o_bd = select_backend( edn, 0 );
if ( target && dn_match( &target->e_nname, edn ) ) {
- e = target;
+ ak.ak_e = target;
} else {
op->o_private = NULL;
- rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e );
+ ak.ak_e = NULL;
+ rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &ak.ak_e );
e_priv = op->o_private;
op->o_private = o_priv;
}
- if ( e ) {
+ if ( ak.ak_e ) {
+ ak.ak_state = &acl_state;
+ ak.ak_desc = entry_at;
+ ak.ak_access = access;
if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) {
assert( vals == NULL );
+ ak.ak_val = NULL;
rc = LDAP_SUCCESS;
if ( op->o_conn && access > ACL_NONE &&
- access_allowed( op, e, entry_at, NULL,
- access, &acl_state ) == 0 )
+ access_allowed( op, &ak ) == 0 )
{
rc = LDAP_INSUFFICIENT_ACCESS;
}
goto freeit;
}
- a = attr_find( e->e_attrs, entry_at );
+ a = attr_find( ak.ak_e->e_attrs, entry_at );
if ( a == NULL ) {
SlapReply rs = { 0 };
AttributeName anlist[ 2 ];
/* NOTE: backend_operational() is also called
* when returning results, so it's supposed
* to do no harm to entries */
- rs.sr_entry = e;
+ rs.sr_entry = ak.ak_e;
rc = backend_operational( op, &rs );
rs.sr_entry = NULL;
BerVarray v;
if ( op->o_conn && access > ACL_NONE &&
- access_allowed( op, e, entry_at, NULL,
- access, &acl_state ) == 0 )
+ access_allowed( op, &ak ) == 0 )
{
rc = LDAP_INSUFFICIENT_ACCESS;
goto freeit;
op->o_tmpmemctx );
for ( i = 0, j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
{
+ ak.ak_val = &a->a_nvals[i];
if ( op->o_conn && access > ACL_NONE &&
- access_allowed( op, e, entry_at,
- &a->a_nvals[i],
- access,
- &acl_state ) == 0 )
+ access_allowed( op, &ak ) == 0 )
{
continue;
}
rc = LDAP_SUCCESS;
}
}
-freeit: if ( e != target ) {
+freeit: if ( ak.ak_e != target ) {
op->o_private = e_priv;
- be_entry_release_r( op, e );
+ be_entry_release_r( op, ak.ak_e );
op->o_private = o_priv;
}
if ( freeattr ) {
int
backend_access(
Operation *op,
- Entry *target,
- struct berval *edn,
- AttributeDescription *entry_at,
- struct berval *nval,
- slap_access_t access,
- slap_mask_t *mask )
+ AclCheck *ak,
+ struct berval *edn )
{
- Entry *e = NULL;
void *o_priv = op->o_private, *e_priv = NULL;
int rc = LDAP_INSUFFICIENT_ACCESS;
Backend *be = op->o_bd;
+ int freeent = 0;
/* pedantic */
assert( op != NULL );
assert( op->o_conn != NULL );
assert( edn != NULL );
- assert( access > ACL_NONE );
+ assert( ak->ak_access > ACL_NONE );
if ( !op->o_bd ) {
op->o_bd = select_backend( edn, 0 );
}
- if ( target && dn_match( &target->e_nname, edn ) ) {
- e = target;
-
- } else {
+ if ( !ak->ak_e || !dn_match( &ak->ak_e->e_nname, edn ) ) {
op->o_private = NULL;
- rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e );
+ rc = be_entry_get_rw( op, edn, NULL, ak->ak_desc, 0, &ak->ak_e );
+ freeent = 1;
e_priv = op->o_private;
op->o_private = o_priv;
}
- if ( e ) {
+ if ( ak->ak_e ) {
Attribute *a = NULL;
int freeattr = 0;
- if ( entry_at == NULL ) {
- entry_at = slap_schema.si_ad_entry;
+ if ( ak->ak_desc == NULL ) {
+ ak->ak_desc = slap_schema.si_ad_entry;
}
- if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children )
+ if ( ak->ak_desc == slap_schema.si_ad_entry || ak->ak_desc == slap_schema.si_ad_children )
{
- if ( access_allowed_mask( op, e, entry_at,
- NULL, access, NULL, mask ) == 0 )
+ if ( access_allowed( op, ak ) == 0 )
{
rc = LDAP_INSUFFICIENT_ACCESS;
}
} else {
- a = attr_find( e->e_attrs, entry_at );
+ a = attr_find( ak->ak_e->e_attrs, ak->ak_desc );
if ( a == NULL ) {
SlapReply rs = { 0 };
AttributeName anlist[ 2 ];
- anlist[ 0 ].an_name = entry_at->ad_cname;
- anlist[ 0 ].an_desc = entry_at;
+ anlist[ 0 ].an_name = ak->ak_desc->ad_cname;
+ anlist[ 0 ].an_desc = ak->ak_desc;
BER_BVZERO( &anlist[ 1 ].an_name );
rs.sr_attrs = anlist;
/* NOTE: backend_operational() is also called
* when returning results, so it's supposed
* to do no harm to entries */
- rs.sr_entry = e;
+ rs.sr_entry = ak->ak_e;
rc = backend_operational( op, &rs );
rs.sr_entry = NULL;
}
if ( a ) {
- if ( access_allowed_mask( op, e, entry_at,
- nval, access, NULL, mask ) == 0 )
+ if ( access_allowed( op, ak ) == 0 )
{
rc = LDAP_INSUFFICIENT_ACCESS;
goto freeit;
rc = LDAP_SUCCESS;
}
}
-freeit: if ( e != target ) {
+freeit: if ( freeent ) {
op->o_private = e_priv;
- be_entry_release_r( op, e );
+ be_entry_release_r( op, ak->ak_e );
op->o_private = o_priv;
}
if ( freeattr ) {
static int
over_access_allowed(
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp )
+ AclCheck *ak )
{
slap_overinfo *oi;
slap_overinst *on;
}
op->o_bd->bd_info = (BackendInfo *)on;
- rc = on->on_bi.bi_access_allowed( op, e,
- desc, val, access, state, maskp );
+ rc = on->on_bi.bi_access_allowed( op, ak );
if ( rc != SLAP_CB_CONTINUE ) break;
}
}
bi_access_allowed = slap_access_allowed;
}
- rc = bi_access_allowed( op, e,
- desc, val, access, state, maskp );
+ rc = bi_access_allowed( op, ak );
}
/* should not fall thru this far without anything happening... */
if ( rc == SLAP_CB_CONTINUE ) {
}
if ( op ) {
+ AclCheck ak;
/* No parent, must be root. This will never happen... */
if ( !last && !be_isroot( op ) && !be_shadow_update( op ) ) {
return LDAP_NO_SUCH_OBJECT;
}
- if ( last && !access_allowed( op, last->ce_entry,
- slap_schema.si_ad_children, NULL, ACL_WADD, NULL ) )
+ ak.ak_e = last->ce_entry;
+ ak.ak_desc = slap_schema.si_ad_children;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_WADD;
+ ak.ak_state = NULL;
+ if ( last && !access_allowed( op, &ak ))
{
Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
"DN=\"%s\" no write access to \"children\" of parent\n",
CfBackInfo *cfb;
int renumber;
ConfigArgs ca;
+ AclCheck ak = { op->ora_e, slap_schema.si_ad_entry,
+ NULL, ACL_WADD, NULL };
- if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry,
- NULL, ACL_WADD, NULL )) {
+ if ( !access_allowed( op, &ak )) {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
goto out;
}
CfEntryInfo *ce, *last;
struct berval rdn;
int ixold, ixnew;
+ AclCheck ak;
cfb = (CfBackInfo *)op->o_bd->be_private;
rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto out;
}
- if ( !access_allowed( op, ce->ce_entry, slap_schema.si_ad_entry,
- NULL, ACL_WRITE, NULL )) {
+ ak.ak_e = ce->ce_entry;
+ ak.ak_desc = slap_schema.si_ad_entry;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_WRITE;
+ ak.ak_state = NULL;
+ if ( !access_allowed( op, &ak )) {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
goto out;
}
- { Entry *parent;
+ {
if ( ce->ce_parent )
- parent = ce->ce_parent->ce_entry;
+ ak.ak_e = ce->ce_parent->ce_entry;
else
- parent = (Entry *)&slap_entry_root;
- if ( !access_allowed( op, parent, slap_schema.si_ad_children,
- NULL, ACL_WRITE, NULL )) {
+ ak.ak_e = (Entry *)&slap_entry_root;
+ ak.ak_desc = slap_schema.si_ad_children;
+ if ( !access_allowed( op, &ak )) {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
goto out;
}
{
CfBackInfo *cfb;
CfEntryInfo *ce, *last;
- slap_mask_t mask;
+ AclCheck ak;
cfb = (CfBackInfo *)op->o_bd->be_private;
rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto out;
}
- if ( !access_allowed_mask( op, ce->ce_entry, slap_schema.si_ad_entry, NULL,
- ACL_SEARCH, NULL, &mask ))
+ ak.ak_e = ce->ce_entry;
+ ak.ak_desc = slap_schema.si_ad_entry;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_SEARCH;
+ ak.ak_state = NULL;
+ if ( !access_allowed_mask( op, &ak ))
{
- if ( !ACL_GRANT( mask, ACL_DISCLOSE )) {
+ if ( !ACL_GRANT( ak.ak_mask, ACL_DISCLOSE )) {
rs->sr_err = LDAP_NO_SUCH_OBJECT;
} else {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
static int compare_entry(
Operation *op,
- Entry *e,
- AttributeAssertion *ava );
+ AclCheck *ak );
int
do_compare(
int
fe_op_compare( Operation *op, SlapReply *rs )
{
- Entry *entry = NULL;
AttributeAssertion *ava = op->orc_ava;
BackendDB *bd = op->o_bd;
+ AclCheck ak = { NULL };
if( strcasecmp( op->o_req_ndn.bv_val, LDAP_ROOT_DSE ) == 0 ) {
if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
goto cleanup;
}
- rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text );
+ rs->sr_err = root_dse_info( op->o_conn, &ak.ak_e, &rs->sr_text );
if( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
goto cleanup;
goto cleanup;
}
- rs->sr_err = schema_info( &entry, &rs->sr_text );
+ rs->sr_err = schema_info( &ak.ak_e, &rs->sr_text );
if( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
rs->sr_err = 0;
}
}
- if( entry ) {
- rs->sr_err = compare_entry( op, entry, ava );
- entry_free( entry );
+ if( ak.ak_e ) {
+ ak.ak_desc = ava->aa_desc;
+ ak.ak_val = &ava->aa_value;
+ ak.ak_access = ACL_COMPARE;
+ ak.ak_state = NULL;
+ rs->sr_err = compare_entry( op, &ak );
+ entry_free( ak.ak_e );
send_ldap_result( op, rs );
{
int rc, hasSubordinates = LDAP_SUCCESS;
- rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &entry );
- if ( rc == 0 && entry ) {
- if ( ! access_allowed( op, entry,
- ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
+ rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &ak.ak_e );
+ if ( rc == 0 && ak.ak_e ) {
+ ak.ak_desc = ava->aa_desc;
+ ak.ak_val = &ava->aa_value;
+ ak.ak_access = ACL_COMPARE;
+ ak.ak_state = NULL;
+ if ( ! access_allowed( op, &ak ))
{
rc = rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
} else {
rc = rs->sr_err = op->o_bd->be_has_subordinates( op,
- entry, &hasSubordinates );
- be_entry_release_r( op, entry );
+ ak.ak_e, &hasSubordinates );
}
}
} else {
/* return error only if "disclose"
* is granted on the object */
- if ( backend_access( op, NULL, &op->o_req_ndn,
- slap_schema.si_ad_entry,
- NULL, ACL_DISCLOSE, NULL ) == LDAP_INSUFFICIENT_ACCESS )
+ ak.ak_desc = slap_schema.si_ad_entry;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_DISCLOSE;
+ ak.ak_state = NULL;
+ if ( backend_access( op, &ak, &op->o_req_ndn )
+ == LDAP_INSUFFICIENT_ACCESS )
{
rs->sr_err = LDAP_NO_SUCH_OBJECT;
}
}
+ be_entry_release_r( op, ak.ak_e );
send_ldap_result( op, rs );
rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn,
ava->aa_desc, &vals, ACL_COMPARE );
+
switch ( rs->sr_err ) {
default:
/* return error only if "disclose"
* is granted on the object */
- if ( backend_access( op, NULL, &op->o_req_ndn,
- slap_schema.si_ad_entry,
- NULL, ACL_DISCLOSE, NULL )
+ ak.ak_e = NULL;
+ ak.ak_desc = slap_schema.si_ad_entry;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_DISCLOSE;
+ ak.ak_state = NULL;
+ if ( backend_access( op, &ak, &op->o_req_ndn )
== LDAP_INSUFFICIENT_ACCESS )
{
rs->sr_err = LDAP_NO_SUCH_OBJECT;
static int compare_entry(
Operation *op,
- Entry *e,
- AttributeAssertion *ava )
+ AclCheck *ak )
{
int rc = LDAP_COMPARE_FALSE;
Attribute *a;
+ AttributeDescription *ad;
- if ( ! access_allowed( op, e,
- ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
+ if ( ! access_allowed( op, ak ))
{
rc = LDAP_INSUFFICIENT_ACCESS;
goto done;
}
- a = attrs_find( e->e_attrs, ava->aa_desc );
+ a = attrs_find( ak->ak_e->e_attrs, ak->ak_desc );
if( a == NULL ) {
rc = LDAP_NO_SUCH_ATTRIBUTE;
goto done;
}
- for(a = attrs_find( e->e_attrs, ava->aa_desc );
+ ad = ak->ak_desc;
+ for(a = attrs_find( ak->ak_e->e_attrs, ak->ak_desc );
a != NULL;
- a = attrs_find( a->a_next, ava->aa_desc ))
+ a = attrs_find( a->a_next, ak->ak_desc ))
{
- if (( ava->aa_desc != a->a_desc ) && ! access_allowed( op,
- e, a->a_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
- {
- rc = LDAP_INSUFFICIENT_ACCESS;
- break;
+ ak->ak_desc = a->a_desc;
+ if ( a->a_desc != ak->ak_desc )
+ {
+ ak->ak_desc = a->a_desc;
+ if ( !access_allowed( op, ak ))
+ {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ }
+ ak->ak_desc = ad;
}
if ( attr_valfind( a,
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
- &ava->aa_value, NULL, op->o_tmpmemctx ) == 0 )
+ ak->ak_val, NULL, op->o_tmpmemctx ) == 0 )
{
rc = LDAP_COMPARE_TRUE;
break;
done:
if( rc != LDAP_COMPARE_TRUE && rc != LDAP_COMPARE_FALSE ) {
- if ( ! access_allowed( op, e,
- slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) )
+ ak->ak_desc = slap_schema.si_ad_entry;
+ ak->ak_val = NULL;
+ ak->ak_access = ACL_DISCLOSE;
+ if ( ! access_allowed( op, ak ))
{
rc = LDAP_NO_SUCH_OBJECT;
}
Attribute *a;
void *memctx;
BER_MEMFREE_FN *memfree;
+ AclCheck ak;
#ifdef LDAP_COMP_MATCH
int i, num_attr_vals = 0;
#endif
memfree = op->o_tmpfree;
}
+ ak.ak_e = e;
+ ak.ak_access = ACL_SEARCH;
+ ak.ak_state = NULL;
+
if ( mra->ma_desc ) {
/*
* if ma_desc is available, then we're filtering for
* one attribute, and SEARCH permissions can be checked
* directly.
*/
- if ( !access_allowed( op, e,
- mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
+ ak.ak_desc = mra->ma_desc;
+ ak.ak_val = &mra->ma_value;
+ if ( !access_allowed( op, &ak ))
{
return LDAP_INSUFFICIENT_ACCESS;
}
if ( rc != LDAP_SUCCESS ) continue;
/* check search access */
- if ( !access_allowed( op, e,
- a->a_desc, &value, ACL_SEARCH, NULL ) )
+ ak.ak_desc = a->a_desc;
+ ak.ak_val = &value;
+ if ( !access_allowed( op, &ak ))
{
memfree( value.bv_val, memctx );
continue;
if ( rc != LDAP_SUCCESS ) continue;
/* check search access */
- if ( !access_allowed( op, e,
- ad, &value, ACL_SEARCH, NULL ) )
+ ak.ak_desc = ad;
+ ak.ak_val = &value;
+ if ( !access_allowed( op, &ak ))
{
memfree( value.bv_val, memctx );
continue;
{
int rc;
Attribute *a;
+ AclCheck ak = { e, ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL };
#ifdef LDAP_COMP_MATCH
int i, num_attr_vals = 0;
AttributeAliasing *a_alias = NULL;
#endif
- if ( !access_allowed( op, e,
- ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL ) )
+ if ( !access_allowed( op, &ak ))
{
return LDAP_INSUFFICIENT_ACCESS;
}
MatchingRule *mr;
struct berval *bv;
- if (( ava->aa_desc != a->a_desc ) && !access_allowed( op,
- e, a->a_desc, &ava->aa_value, ACL_SEARCH, NULL ))
+ if ( ava->aa_desc != a->a_desc )
{
- rc = LDAP_INSUFFICIENT_ACCESS;
- continue;
+ int ret;
+ ak.ak_desc = a->a_desc;
+ ret = access_allowed( op, &ak );
+ ak.ak_desc = ava->aa_desc;
+ if ( !ret )
+ {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ continue;
+ }
}
use = SLAP_MR_EQUALITY;
{
Attribute *a;
int rc;
+ AclCheck ak = { e, desc, NULL, ACL_SEARCH, NULL };
- if ( !access_allowed( op, e, desc, NULL, ACL_SEARCH, NULL ) ) {
+ if ( !access_allowed( op, &ak ) ) {
return LDAP_INSUFFICIENT_ACCESS;
}
a != NULL;
a = attrs_find( a->a_next, desc ) )
{
- if (( desc != a->a_desc ) && !access_allowed( op,
- e, a->a_desc, NULL, ACL_SEARCH, NULL ))
+ if ( desc != a->a_desc )
{
- rc = LDAP_INSUFFICIENT_ACCESS;
- continue;
+ int ret;
+ ak.ak_desc = a->a_desc;
+ ret = access_allowed( op, &ak );
+ ak.ak_desc = desc;
+ if ( !ret )
+ {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ continue;
+ }
}
rc = LDAP_COMPARE_TRUE;
{
Attribute *a;
int rc;
+ AclCheck ak = { e, f->f_sub_desc, NULL, ACL_SEARCH, NULL };
Debug( LDAP_DEBUG_FILTER, "begin test_substrings_filter\n", 0, 0, 0 );
- if ( !access_allowed( op, e,
- f->f_sub_desc, NULL, ACL_SEARCH, NULL ) )
+ if ( !access_allowed( op, &ak ))
{
return LDAP_INSUFFICIENT_ACCESS;
}
MatchingRule *mr;
struct berval *bv;
- if (( f->f_sub_desc != a->a_desc ) && !access_allowed( op,
- e, a->a_desc, NULL, ACL_SEARCH, NULL ))
+ if ( f->f_sub_desc != a->a_desc )
{
- rc = LDAP_INSUFFICIENT_ACCESS;
- continue;
+ int ret;
+ ak.ak_desc = a->a_desc;
+ ret = access_allowed( op, &ak );
+ ak.ak_desc = f->f_sub_desc;
+ if ( !ret )
+ {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ continue;
+ }
}
mr = a->a_desc->ad_type->sat_substr;
const char **text )
{
int result = 1;
- struct berval *bv;
AccessControlState acl_state = ACL_STATE_INIT;
char credNul = cred->bv_val[cred->bv_len];
+ AclCheck ak;
#ifdef SLAPD_SPASSWD
void *old_authctx = NULL;
if ( credNul ) cred->bv_val[cred->bv_len] = 0;
- for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
+ ak.ak_e = e;
+ ak.ak_desc = a->a_desc;
+ ak.ak_access = ACL_AUTH;
+ ak.ak_state = &acl_state;
+
+ for ( ak.ak_val = a->a_vals; ak.ak_val->bv_val != NULL; ak.ak_val++ ) {
/* if e is provided, check access */
- if ( e && access_allowed( op, e, a->a_desc, bv,
- ACL_AUTH, &acl_state ) == 0 )
+ if ( e && access_allowed( op, &ak ) == 0 )
{
continue;
}
- if ( !lutil_passwd( bv, cred, NULL, text ) ) {
+ if ( !lutil_passwd( ak.ak_val, cred, NULL, text ) ) {
result = 0;
break;
}
/*
* acl.c
*/
-LDAP_SLAPD_F (int) access_allowed_mask LDAP_P((
- Operation *op,
- Entry *e, AttributeDescription *desc, struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *mask ));
+LDAP_SLAPD_F (int) access_allowed LDAP_P((
+ Operation *op, AclCheck *ak ));
+#if 0
#define access_allowed(op,e,desc,val,access,state) access_allowed_mask(op,e,desc,val,access,state,NULL)
+#endif
LDAP_SLAPD_F (int) slap_access_allowed LDAP_P((
- Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp ));
+ Operation *op, AclCheck *ak ));
LDAP_SLAPD_F (int) slap_access_always_allowed LDAP_P((
- Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp ));
+ Operation *op, AclCheck *ak ));
LDAP_SLAPD_F (int) acl_check_modlist LDAP_P((
Operation *op, Entry *e, Modifications *ml ));
LDAP_SLAPD_F (int) backend_access LDAP_P((
Operation *op,
- Entry *target,
- struct berval *edn,
- AttributeDescription *entry_at,
- struct berval *nval,
- slap_access_t access,
- slap_mask_t *mask ));
+ AclCheck *ak,
+ struct berval *edn ));
LDAP_SLAPD_F (int) backend_operational LDAP_P((
Operation *op,
slap_access_t access ));
LDAP_SLAPD_F (int) fe_access_allowed LDAP_P((
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- slap_access_t access,
- AccessControlState *state,
- slap_mask_t *maskp ));
+ AclCheck *ak ));
/* NOTE: this macro assumes that bv has been allocated
* by ber_* malloc functions or is { 0L, NULL } */
AccessControlState acl_state = ACL_STATE_INIT;
int attrsonly;
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
+ AclCheck ak;
/* a_flags: array of flags telling if the i-th element will be
* returned or filtered out
attrsonly = op->ors_attrsonly;
- if ( !access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL )) {
+ ak.ak_e = rs->sr_entry;
+ ak.ak_desc = ad_entry;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_READ;
+ ak.ak_state = NULL;
+ if ( !access_allowed( op, &ak )) {
Debug( LDAP_DEBUG_ACL,
"send_search_entry: conn %lu access to entry (%s) not allowed\n",
op->o_connid, rs->sr_entry->e_name.bv_val, 0 );
}
}
+ ak.ak_state = &acl_state;
for ( a = rs->sr_entry->e_attrs, j = 0; a != NULL; a = a->a_next, j++ ) {
AttributeDescription *desc = a->a_desc;
int finish = 0;
}
}
+ ak.ak_desc = desc;
if ( attrsonly ) {
- if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
- ACL_READ, &acl_state ) )
+ if ( ! access_allowed( op, &ak ))
{
Debug( LDAP_DEBUG_ACL, "send_search_entry: "
"conn %lu access to attribute %s not allowed\n",
} else {
int first = 1;
for ( i = 0; a->a_nvals[i].bv_val != NULL; i++ ) {
- if ( ! access_allowed( op, rs->sr_entry,
- desc, &a->a_nvals[i], ACL_READ, &acl_state ) )
+ ak.ak_val = &a->a_nvals[i];
+ if ( ! access_allowed( op, &ak ))
{
Debug( LDAP_DEBUG_ACL,
"send_search_entry: conn %lu "
}
}
- if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
- ACL_READ, &acl_state ) )
+ ak.ak_desc = desc;
+ if ( ! access_allowed( op, &ak ))
{
Debug( LDAP_DEBUG_ACL,
"send_search_entry: conn %lu "
if ( ! attrsonly ) {
for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
- if ( ! access_allowed( op, rs->sr_entry,
- desc, &a->a_vals[i], ACL_READ, &acl_state ) )
+ ak.ak_val = &a->a_vals[i];
+ if ( ! access_allowed( op, &ak ))
{
Debug( LDAP_DEBUG_ACL,
"send_search_entry: conn %lu "
"=> send_search_reference: dn=\"%s\"\n",
edn, 0, 0 );
- if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
- ad_entry, NULL, ACL_READ, NULL ) )
+ if ( rs->sr_entry )
{
- Debug( LDAP_DEBUG_ACL,
- "send_search_reference: access to entry not allowed\n",
- 0, 0, 0 );
- rc = 1;
- goto rel;
- }
+ AclCheck ak = { rs->sr_entry, ad_entry, NULL, ACL_READ, NULL };
- if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
- ad_ref, NULL, ACL_READ, NULL ) )
- {
- Debug( LDAP_DEBUG_ACL,
- "send_search_reference: access "
- "to reference not allowed\n",
- 0, 0, 0 );
- rc = 1;
- goto rel;
+ if ( !access_allowed( op, &ak ))
+ {
+ Debug( LDAP_DEBUG_ACL,
+ "send_search_reference: access to entry not allowed\n",
+ 0, 0, 0 );
+ rc = 1;
+ goto rel;
+ }
+
+ ak.ak_desc = ad_ref;
+ if ( !access_allowed( op, &ak ))
+ {
+ Debug( LDAP_DEBUG_ACL,
+ "send_search_reference: access "
+ "to reference not allowed\n",
+ 0, 0, 0 );
+ rc = 1;
+ goto rel;
+ }
}
if( op->o_domain_scope ) {
const char *text;
int rc, i;
lookup_info *sl = (lookup_info *)op->o_callback->sc_private;
+ AclCheck ak;
if (rs->sr_type != REP_SEARCH) return 0;
+ ak.ak_e = rs->sr_entry;
+ ak.ak_val = NULL;
+ ak.ak_access = ACL_AUTH;
+ ak.ak_state = NULL;
+
for( i = 0; sl->list[i].name; i++ ) {
const char *name = sl->list[i].name;
a = attr_find( rs->sr_entry->e_attrs, ad );
if ( !a ) continue;
- if ( ! access_allowed( op, rs->sr_entry, ad, NULL, ACL_AUTH, NULL ) ) {
+ ak.ak_desc = ad;
+ if ( ! access_allowed( op, &ak ) ) {
continue;
}
if ( sl->list[i].values && ( sl->flags & SASL_AUXPROP_OVERRIDE ) ) {
slap_ssf_t sai_sasl_ssf; /* SASL SSF */
} AuthorizationInformation;
-#ifdef SLAP_DYNACL
-
-/*
- * "dynamic" ACL infrastructure (for ACIs and more)
- */
-typedef int (slap_dynacl_parse) LDAP_P(( const char *fname, int lineno,
- const char *opts, slap_style_t, const char *, void **privp ));
-typedef int (slap_dynacl_unparse) LDAP_P(( void *priv, struct berval *bv ));
-typedef int (slap_dynacl_mask) LDAP_P((
- void *priv,
- Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- int nmatch,
- regmatch_t *matches,
- slap_access_t *grant,
- slap_access_t *deny ));
-typedef int (slap_dynacl_destroy) LDAP_P(( void *priv ));
-
-typedef struct slap_dynacl_t {
- char *da_name;
- slap_dynacl_parse *da_parse;
- slap_dynacl_unparse *da_unparse;
- slap_dynacl_mask *da_mask;
- slap_dynacl_destroy *da_destroy;
-
- void *da_private;
- struct slap_dynacl_t *da_next;
-} slap_dynacl_t;
-#endif /* SLAP_DYNACL */
-
/* the DN portion of the "by" part */
typedef struct slap_dn_access {
/* DN pattern */
} AccessControlState;
#define ACL_STATE_INIT { NULL, ACL_NONE, NULL, 0, ACL_PRIV_NONE, -1, 0 }
+typedef struct AclCheck {
+ Entry *ak_e;
+ AttributeDescription *ak_desc;
+ struct berval *ak_val;
+ slap_access_t ak_access;
+ AccessControlState *ak_state;
+ slap_mask_t ak_mask;
+} AclCheck;
+
typedef struct AclRegexMatches {
int dn_count;
regmatch_t dn_data[MAXREMATCHES];
regmatch_t val_data[MAXREMATCHES];
} AclRegexMatches;
+#ifdef SLAP_DYNACL
+
+/*
+ * "dynamic" ACL infrastructure (for ACIs and more)
+ */
+typedef int (slap_dynacl_parse) LDAP_P(( const char *fname, int lineno,
+ const char *opts, slap_style_t, const char *, void **privp ));
+typedef int (slap_dynacl_unparse) LDAP_P(( void *priv, struct berval *bv ));
+typedef int (slap_dynacl_mask) LDAP_P((
+ void *priv,
+ Operation *op,
+ Entry *e,
+ AttributeDescription *desc,
+ struct berval *val,
+ int nmatch,
+ regmatch_t *matches,
+ slap_access_t *grant,
+ slap_access_t *deny ));
+typedef int (slap_dynacl_destroy) LDAP_P(( void *priv ));
+
+typedef struct slap_dynacl_t {
+ char *da_name;
+ slap_dynacl_parse *da_parse;
+ slap_dynacl_unparse *da_unparse;
+ slap_dynacl_mask *da_mask;
+ slap_dynacl_destroy *da_destroy;
+
+ void *da_private;
+ struct slap_dynacl_t *da_next;
+} slap_dynacl_t;
+#endif /* SLAP_DYNACL */
+
/*
* Backend-info
* represents a backend
typedef int (BI_operational) LDAP_P(( Operation *op, SlapReply *rs ));
typedef int (BI_has_subordinates) LDAP_P(( Operation *op,
Entry *e, int *hasSubs ));
-typedef int (BI_access_allowed) LDAP_P(( Operation *op, Entry *e,
- AttributeDescription *desc, struct berval *val, slap_access_t access,
- AccessControlState *state, slap_mask_t *maskp ));
+typedef int (BI_access_allowed) LDAP_P(( Operation *op, AclCheck *ak ));
typedef int (BI_acl_group) LDAP_P(( Operation *op, Entry *target,
struct berval *gr_ndn, struct berval *op_ndn,
ObjectClass *group_oc, AttributeDescription *group_at ));
static int
print_access(
Operation *op,
- Entry *e,
- AttributeDescription *desc,
- struct berval *val,
- struct berval *nval )
+ AclCheck *ak,
+ struct berval *val )
{
int rc;
- slap_mask_t mask;
char accessmaskbuf[ACCESSMASK_MAXLEN];
- rc = access_allowed_mask( op, e, desc, nval, ACL_AUTH, NULL, &mask );
+ rc = access_allowed( op, ak );
fprintf( stderr, "%s%s%s: %s\n",
- desc->ad_cname.bv_val,
- ( val && !BER_BVISNULL( val ) ) ? "=" : "",
- ( val && !BER_BVISNULL( val ) ) ?
- ( desc == slap_schema.si_ad_userPassword ?
- "****" : val->bv_val ) : "",
- accessmask2str( mask, accessmaskbuf, 1 ) );
+ ak->ak_desc->ad_cname.bv_val,
+ ( ak->ak_val && !BER_BVISNULL( ak->ak_val ) ) ? "=" : "",
+ ( ak->ak_val && !BER_BVISNULL( ak->ak_val ) ) ?
+ ( ak->ak_desc == slap_schema.si_ad_userPassword ?
+ "****" : ak->ak_val->bv_val ) : "",
+ accessmask2str( ak->ak_mask, accessmaskbuf, 1 ) );
return rc;
}
int doclose = 0;
BackendDB *bd;
void *thrctx;
+ AclCheck ak;
slap_tool_init( progname, SLAPACL, argc, argv );
}
+ ak.ak_e = ep;
+ ak.ak_access = ACL_AUTH;
+ ak.ak_state = NULL;
+
if ( argc == 0 ) {
Attribute *a;
- (void)print_access( op, ep, slap_schema.si_ad_entry, NULL, NULL );
- (void)print_access( op, ep, slap_schema.si_ad_children, NULL, NULL );
+ ak.ak_val = NULL;
+ ak.ak_desc = slap_schema.si_ad_entry;
+ (void)print_access( op, &ak, NULL );
+ ak.ak_desc = slap_schema.si_ad_children;
+ (void)print_access( op, &ak, NULL );
for ( a = ep->e_attrs; a; a = a->a_next ) {
int i;
for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ ) {
- (void)print_access( op, ep, a->a_desc,
- &a->a_vals[ i ],
- &a->a_nvals[ i ] );
+ ak.ak_desc = a->a_desc;
+ ak.ak_val = &a->a_nvals[i];
+ (void)print_access( op, &ak, &a->a_vals[ i ] );
}
}
}
}
for ( ; argc--; argv++ ) {
- slap_mask_t mask;
- AttributeDescription *desc = NULL;
- struct berval val = BER_BVNULL,
- *valp = NULL;
+ struct berval val = BER_BVNULL;
const char *text;
char accessmaskbuf[ACCESSMASK_MAXLEN];
char *accessstr;
- slap_access_t access = ACL_AUTH;
if ( attr == NULL ) {
attr = argv[ 0 ];
val.bv_val[0] = '\0';
val.bv_val++;
val.bv_len = strlen( val.bv_val );
- valp = &val;
+ ak.ak_val = &val;
+ } else {
+ ak.ak_val = NULL;
}
+ ak.ak_access = ACL_AUTH;
accessstr = strchr( attr, '/' );
if ( accessstr != NULL ) {
int invalid = 0;
accessstr[0] = '\0';
accessstr++;
- access = str2access( accessstr );
- switch ( access ) {
+ ak.ak_access = str2access( accessstr );
+ switch ( ak.ak_access ) {
case ACL_INVALID_ACCESS:
fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n",
accessstr, attr );
}
}
- rc = slap_str2ad( attr, &desc, &text );
+ ak.ak_desc = NULL;
+ rc = slap_str2ad( attr, &ak.ak_desc, &text );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "slap_str2ad(%s) failed %d (%s)\n",
attr, rc, ldap_err2string( rc ) );
break;
}
- rc = access_allowed_mask( op, ep, desc, valp, access,
- NULL, &mask );
+ rc = access_allowed( op, &ak );
if ( accessstr ) {
fprintf( stderr, "%s access to %s%s%s: %s\n",
accessstr,
- desc->ad_cname.bv_val,
+ ak.ak_desc->ad_cname.bv_val,
val.bv_val ? "=" : "",
val.bv_val ? val.bv_val : "",
rc ? "ALLOWED" : "DENIED" );
} else {
fprintf( stderr, "%s%s%s: %s\n",
- desc->ad_cname.bv_val,
+ ak.ak_desc->ad_cname.bv_val,
val.bv_val ? "=" : "",
val.bv_val ? val.bv_val : "",
- accessmask2str( mask, accessmaskbuf, 1 ) );
+ accessmask2str( ak.ak_mask, accessmaskbuf, 1 ) );
}
rc = 0;
attr = NULL;