mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
add more semantics to the "type" field; fix a bug in anonymous operations; treat children aci_mask() as internal searches
This commit is contained in:
parent
e79fbb88cf
commit
1e650374c2
@ -48,6 +48,7 @@
|
||||
static struct berval
|
||||
aci_bv_entry = BER_BVC("entry"),
|
||||
aci_bv_children = BER_BVC("children"),
|
||||
aci_bv_onelevel = BER_BVC("onelevel"),
|
||||
aci_bv_subtree = BER_BVC("subtree"),
|
||||
aci_bv_br_entry = BER_BVC("[entry]"),
|
||||
aci_bv_br_all = BER_BVC("[all]"),
|
||||
@ -2412,15 +2413,20 @@ aci_mask(
|
||||
assert( !BER_BVISNULL( &desc->ad_cname ) );
|
||||
|
||||
/* parse an aci of the form:
|
||||
oid#scope#action;rights;attr;rights;attr$action;rights;attr;rights;attr#dnType#subjectDN
|
||||
oid # scope # action;rights;attr;rights;attr
|
||||
$ action;rights;attr;rights;attr # type # subject
|
||||
|
||||
See draft-ietf-ldapext-aci-model-04.txt section 9.1 for
|
||||
a full description of the format for this attribute.
|
||||
Differences: "this" in the draft is "self" here, and
|
||||
"self" and "public" is in the position of dnType.
|
||||
"self" and "public" is in the position of type.
|
||||
|
||||
For now, this routine only supports scope=entry.
|
||||
This routine now supports scope={ENTRY,CHILDREN}
|
||||
with the semantics:
|
||||
- ENTRY applies to "entry" and "subtree";
|
||||
- CHILDREN aplies to "children" and "subtree"
|
||||
*/
|
||||
|
||||
/* check that the aci has all 5 components */
|
||||
if ( aci_get_part( aci, 4, '#', NULL ) < 0 ) {
|
||||
return 0;
|
||||
@ -2475,6 +2481,17 @@ aci_mask(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* see if we have a public (i.e. anonymous) access */
|
||||
if ( ber_bvstrcasecmp( &aci_bv_public, &type ) == 0 ) {
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* otherwise require an identity */
|
||||
if ( BER_BVISNULL( &op->o_ndn ) || BER_BVISEMPTY( &op->o_ndn ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( aci_get_part( aci, 4, '#', &sdn ) < 0 ) {
|
||||
return 0;
|
||||
}
|
||||
@ -2482,18 +2499,66 @@ aci_mask(
|
||||
if ( ber_bvstrcasecmp( &aci_bv_access_id, &type ) == 0 ) {
|
||||
struct berval ndn;
|
||||
|
||||
rc = 0;
|
||||
if ( dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx ) == LDAP_SUCCESS )
|
||||
{
|
||||
if ( dn_match( &op->o_ndn, &ndn ) ) {
|
||||
rc = 1;
|
||||
}
|
||||
slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
|
||||
rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( dn_match( &op->o_ndn, &ndn ) ) {
|
||||
rc = 1;
|
||||
}
|
||||
slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
|
||||
|
||||
return rc;
|
||||
|
||||
} else if ( ber_bvstrcasecmp( &aci_bv_public, &type ) == 0 ) {
|
||||
return 1;
|
||||
} else if ( ber_bvstrcasecmp( &aci_bv_subtree, &type ) == 0 ) {
|
||||
struct berval ndn;
|
||||
|
||||
rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( dnIsSuffix( &op->o_ndn, &ndn ) ) {
|
||||
rc = 1;
|
||||
}
|
||||
slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
|
||||
|
||||
return rc;
|
||||
|
||||
} else if ( ber_bvstrcasecmp( &aci_bv_onelevel, &type ) == 0 ) {
|
||||
struct berval ndn, pndn;
|
||||
|
||||
rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dnParent( &ndn, &pndn );
|
||||
|
||||
if ( dn_match( &op->o_ndn, &pndn ) ) {
|
||||
rc = 1;
|
||||
}
|
||||
slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
|
||||
|
||||
return rc;
|
||||
|
||||
} else if ( ber_bvstrcasecmp( &aci_bv_children, &type ) == 0 ) {
|
||||
struct berval ndn;
|
||||
|
||||
rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !dn_match( &op->o_ndn, &ndn )
|
||||
&& dnIsSuffix( &op->o_ndn, &ndn ) )
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
|
||||
|
||||
return rc;
|
||||
|
||||
} else if ( ber_bvstrcasecmp( &aci_bv_self, &type ) == 0 ) {
|
||||
if ( dn_match( &op->o_ndn, &e->e_nname ) ) {
|
||||
@ -2513,8 +2578,6 @@ aci_mask(
|
||||
|
||||
rc = 0;
|
||||
|
||||
bv = op->o_ndn;
|
||||
|
||||
for ( at = attrs_find( e->e_attrs, ad );
|
||||
at != NULL;
|
||||
at = attrs_find( at->a_next, ad ) )
|
||||
@ -2523,7 +2586,7 @@ aci_mask(
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
|
||||
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
|
||||
at->a_nvals,
|
||||
&bv, op->o_tmpmemctx ) == 0 )
|
||||
&op->o_ndn, op->o_tmpmemctx ) == 0 )
|
||||
{
|
||||
rc = 1;
|
||||
break;
|
||||
@ -2532,7 +2595,6 @@ aci_mask(
|
||||
|
||||
return rc;
|
||||
|
||||
|
||||
} else if ( ber_bvstrcasecmp( &aci_bv_group, &type ) == 0 ) {
|
||||
if ( aci_group_member( &sdn, &aci_bv_group_class,
|
||||
&aci_bv_group_attr, op, e, nmatch, matches ) )
|
||||
@ -2671,6 +2733,27 @@ dynacl_aci_mask(
|
||||
struct berval parent_ndn;
|
||||
struct berval old_parent_ndn = BER_BVNULL;
|
||||
|
||||
#if 1
|
||||
/* to solve the chicken'n'egg problem of accessing
|
||||
* the OpenLDAPaci attribute, the direct access
|
||||
* to the entry's attribute is unchecked; however,
|
||||
* further accesses to OpenLDAPaci values in the
|
||||
* ancestors occur through backend_attribute(), i.e.
|
||||
* with the identity of the operation, requiring
|
||||
* further access checking. For uniformity, this
|
||||
* makes further requests occur as the rootdn, if
|
||||
* any, i.e. searching for the OpenLDAPaci attribute
|
||||
* is considered an internal search. If this is not
|
||||
* acceptable, then the same check needs be performed
|
||||
* when accessing the entry's attribute. */
|
||||
Operation op2 = *op;
|
||||
|
||||
if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
|
||||
op2.o_dn = op->o_bd->be_rootdn;
|
||||
op2.o_ndn = op->o_bd->be_rootndn;
|
||||
}
|
||||
#endif
|
||||
|
||||
dnParent( &e->e_nname, &parent_ndn );
|
||||
while ( parent_ndn.bv_val != old_parent_ndn.bv_val ){
|
||||
int i;
|
||||
@ -2679,7 +2762,7 @@ dynacl_aci_mask(
|
||||
|
||||
old_parent_ndn = parent_ndn;
|
||||
Debug( LDAP_DEBUG_ACL, "checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 );
|
||||
ret = backend_attribute( op, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
|
||||
ret = backend_attribute( &op2, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
|
||||
|
||||
switch ( ret ) {
|
||||
case LDAP_SUCCESS :
|
||||
|
Loading…
Reference in New Issue
Block a user