Preliminary checkin for new access_allowed() signature. Still need

to update backends and overlays.
This commit is contained in:
Howard Chu 2009-12-11 05:09:40 +00:00
parent 198634e945
commit 1cb6c19603
12 changed files with 528 additions and 519 deletions

File diff suppressed because it is too large Load diff

View file

@ -1625,11 +1625,11 @@ fe_acl_attribute(
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;
@ -1645,30 +1645,34 @@ fe_acl_attribute(
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 ];
@ -1681,7 +1685,7 @@ fe_acl_attribute(
/* 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;
@ -1700,8 +1704,7 @@ fe_acl_attribute(
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;
@ -1712,11 +1715,9 @@ fe_acl_attribute(
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;
}
@ -1737,9 +1738,9 @@ fe_acl_attribute(
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 ) {
@ -1781,50 +1782,43 @@ backend_attribute(
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;
@ -1833,13 +1827,13 @@ backend_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;
@ -1848,7 +1842,7 @@ backend_access(
/* 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;
@ -1864,8 +1858,7 @@ backend_access(
}
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;
@ -1873,9 +1866,9 @@ backend_access(
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 ) {

View file

@ -250,12 +250,7 @@ over_back_response ( Operation *op, SlapReply *rs )
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;
@ -286,8 +281,7 @@ over_access_allowed(
}
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;
}
}
@ -307,8 +301,7 @@ over_access_allowed(
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 ) {

View file

@ -4796,13 +4796,18 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
}
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",
@ -5168,9 +5173,10 @@ config_back_add( Operation *op, SlapReply *rs )
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;
}
@ -5711,6 +5717,7 @@ config_back_modrdn( Operation *op, SlapReply *rs )
CfEntryInfo *ce, *last;
struct berval rdn;
int ixold, ixnew;
AclCheck ak;
cfb = (CfBackInfo *)op->o_bd->be_private;
@ -5721,18 +5728,22 @@ config_back_modrdn( Operation *op, SlapReply *rs )
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;
}
@ -6014,7 +6025,7 @@ config_back_search( Operation *op, SlapReply *rs )
{
CfBackInfo *cfb;
CfEntryInfo *ce, *last;
slap_mask_t mask;
AclCheck ak;
cfb = (CfBackInfo *)op->o_bd->be_private;
@ -6025,10 +6036,14 @@ config_back_search( Operation *op, SlapReply *rs )
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;

View file

@ -33,8 +33,7 @@
static int compare_entry(
Operation *op,
Entry *e,
AttributeAssertion *ava );
AclCheck *ak );
int
do_compare(
@ -144,9 +143,9 @@ cleanup:;
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 ) {
@ -154,7 +153,7 @@ fe_op_compare( Operation *op, SlapReply *rs )
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;
@ -167,7 +166,7 @@ fe_op_compare( Operation *op, SlapReply *rs )
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;
@ -175,9 +174,13 @@ fe_op_compare( Operation *op, SlapReply *rs )
}
}
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 );
@ -240,17 +243,19 @@ fe_op_compare( Operation *op, SlapReply *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 );
}
}
@ -269,13 +274,17 @@ fe_op_compare( Operation *op, SlapReply *rs )
} 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 );
@ -307,13 +316,17 @@ fe_op_compare( Operation *op, SlapReply *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;
@ -354,40 +367,45 @@ cleanup:;
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;
@ -396,8 +414,10 @@ static int compare_entry(
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;
}

View file

@ -163,6 +163,7 @@ static int test_mra_filter(
Attribute *a;
void *memctx;
BER_MEMFREE_FN *memfree;
AclCheck ak;
#ifdef LDAP_COMP_MATCH
int i, num_attr_vals = 0;
#endif
@ -175,14 +176,19 @@ static int test_mra_filter(
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;
}
@ -345,8 +351,9 @@ static int test_mra_filter(
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;
@ -470,8 +477,9 @@ static int test_mra_filter(
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;
@ -532,13 +540,13 @@ test_ava_filter(
{
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;
}
@ -620,11 +628,17 @@ test_ava_filter(
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;
@ -817,8 +831,9 @@ test_presence_filter(
{
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;
}
@ -849,11 +864,17 @@ test_presence_filter(
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;
@ -934,11 +955,11 @@ test_substrings_filter(
{
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;
}
@ -952,11 +973,17 @@ test_substrings_filter(
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;

View file

@ -505,9 +505,9 @@ slap_passwd_check(
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;
@ -518,15 +518,19 @@ slap_passwd_check(
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;
}

View file

@ -46,29 +46,15 @@ LDAP_SLAPD_F (int) dynacl_aci_init LDAP_P(( void ));
/*
* 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 ));
@ -416,12 +402,8 @@ LDAP_SLAPD_F (int) backend_attribute LDAP_P((
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,
@ -2043,12 +2025,7 @@ LDAP_SLAPD_F (int) fe_acl_attribute LDAP_P((
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 } */

View file

@ -847,6 +847,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
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
@ -896,7 +897,12 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
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 );
@ -999,6 +1005,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
}
}
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;
@ -1029,9 +1036,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
}
}
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",
@ -1055,8 +1062,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
} 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 "
@ -1190,8 +1197,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
}
}
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 "
@ -1216,8 +1223,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
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 "
@ -1383,25 +1390,29 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
"=> 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 ) {

View file

@ -178,9 +178,15 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
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;
@ -215,7 +221,8 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
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 ) ) {

View file

@ -1298,38 +1298,6 @@ typedef struct AuthorizationInformation {
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 */
@ -1549,6 +1517,15 @@ typedef struct AccessControlState {
} 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];
@ -1556,6 +1533,38 @@ typedef struct AclRegexMatches {
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
@ -2145,9 +2154,7 @@ typedef int (BI_entry_get_rw) LDAP_P(( Operation *op, struct berval *ndn,
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 ));

View file

@ -38,24 +38,21 @@
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;
}
@ -74,6 +71,7 @@ slapacl( int argc, char **argv )
int doclose = 0;
BackendDB *bd;
void *thrctx;
AclCheck ak;
slap_tool_init( progname, SLAPACL, argc, argv );
@ -277,33 +275,36 @@ slapacl( int argc, char **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 ];
@ -314,17 +315,20 @@ slapacl( int argc, char **argv )
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 );
@ -349,7 +353,8 @@ slapacl( int argc, char **argv )
}
}
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 ) );
@ -359,23 +364,22 @@ slapacl( int argc, char **argv )
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;