mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-27 18:19:52 -05:00
implement "realdn" by clause in ACLs (ITS#3627; accounting for Howard's remarks)
This commit is contained in:
parent
fe1b73c712
commit
3eb87b2faa
5 changed files with 593 additions and 337 deletions
|
|
@ -618,6 +618,281 @@ acl_get(
|
|||
return( NULL );
|
||||
}
|
||||
|
||||
static int
|
||||
acl_mask_dn(
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
AccessControl *a,
|
||||
int nmatch,
|
||||
regmatch_t *matches,
|
||||
slap_dn_access *b,
|
||||
struct berval *opndn )
|
||||
{
|
||||
/*
|
||||
* if access applies to the entry itself, and the
|
||||
* user is bound as somebody in the same namespace as
|
||||
* the entry, OR the given dn matches the dn pattern
|
||||
*/
|
||||
/*
|
||||
* NOTE: styles "anonymous", "users" and "self"
|
||||
* have been moved to enum slap_style_t, whose
|
||||
* value is set in a_dn_style; however, the string
|
||||
* is maintaned in a_dn_pat.
|
||||
*/
|
||||
if ( b->a_style == ACL_STYLE_ANONYMOUS ) {
|
||||
if ( !BER_BVISEMPTY( opndn ) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_USERS ) {
|
||||
if ( BER_BVISEMPTY( opndn ) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_SELF ) {
|
||||
struct berval ndn, selfndn;
|
||||
int level;
|
||||
|
||||
if ( BER_BVISEMPTY( opndn ) || BER_BVISNULL( &e->e_nname ) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
level = b->a_self_level;
|
||||
if ( level < 0 ) {
|
||||
selfndn = *opndn;
|
||||
ndn = e->e_nname;
|
||||
level = -level;
|
||||
|
||||
} else {
|
||||
ndn = *opndn;
|
||||
selfndn = e->e_nname;
|
||||
}
|
||||
|
||||
for ( ; level > 0; level-- ) {
|
||||
if ( BER_BVISEMPTY( &ndn ) ) {
|
||||
break;
|
||||
}
|
||||
dnParent( &ndn, &ndn );
|
||||
}
|
||||
|
||||
if ( BER_BVISEMPTY( &ndn ) || !dn_match( &ndn, &selfndn ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_REGEX ) {
|
||||
if ( !ber_bvccmp( &b->a_pat, '*' ) ) {
|
||||
int tmp_nmatch;
|
||||
regmatch_t tmp_matches[2],
|
||||
*tmp_matchesp = tmp_matches;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
switch ( a->acl_dn_style ) {
|
||||
case ACL_STYLE_REGEX:
|
||||
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
|
||||
tmp_matchesp = matches;
|
||||
tmp_nmatch = nmatch;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
|
||||
|
||||
case ACL_STYLE_BASE:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 1;
|
||||
break;
|
||||
|
||||
case ACL_STYLE_ONE:
|
||||
case ACL_STYLE_SUBTREE:
|
||||
case ACL_STYLE_CHILDREN:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
|
||||
tmp_matches[1].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( !regex_matches( &b->a_pat, opndn->bv_val,
|
||||
e->e_ndn, tmp_nmatch, tmp_matchesp ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
struct berval pat;
|
||||
ber_len_t patlen, odnlen;
|
||||
int got_match = 0;
|
||||
|
||||
if ( e->e_dn == NULL )
|
||||
return 1;
|
||||
|
||||
if ( b->a_expand ) {
|
||||
struct berval bv;
|
||||
char buf[ACL_BUF_SIZE];
|
||||
|
||||
int tmp_nmatch;
|
||||
regmatch_t tmp_matches[2],
|
||||
*tmp_matchesp = tmp_matches;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
bv.bv_len = sizeof( buf ) - 1;
|
||||
bv.bv_val = buf;
|
||||
|
||||
switch ( a->acl_dn_style ) {
|
||||
case ACL_STYLE_REGEX:
|
||||
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
|
||||
tmp_matchesp = matches;
|
||||
tmp_nmatch = nmatch;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
|
||||
|
||||
case ACL_STYLE_BASE:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 1;
|
||||
break;
|
||||
|
||||
case ACL_STYLE_ONE:
|
||||
case ACL_STYLE_SUBTREE:
|
||||
case ACL_STYLE_CHILDREN:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
|
||||
tmp_matches[1].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( string_expand( &bv, &b->a_pat,
|
||||
e->e_nname.bv_val,
|
||||
tmp_nmatch, tmp_matchesp ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( dnNormalize(0, NULL, NULL, &bv,
|
||||
&pat, op->o_tmpmemctx )
|
||||
!= LDAP_SUCCESS )
|
||||
{
|
||||
/* did not expand to a valid dn */
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
pat = b->a_pat;
|
||||
}
|
||||
|
||||
patlen = pat.bv_len;
|
||||
odnlen = opndn->bv_len;
|
||||
if ( odnlen < patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
|
||||
}
|
||||
|
||||
if ( b->a_style == ACL_STYLE_BASE ) {
|
||||
/* base dn -- entire object DN must match */
|
||||
if ( odnlen != patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_ONE ) {
|
||||
int rdnlen = -1;
|
||||
|
||||
if ( odnlen <= patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
if ( !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
rdnlen = dn_rdnlen( NULL, opndn );
|
||||
if ( rdnlen != odnlen - patlen - 1 ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_SUBTREE ) {
|
||||
if ( odnlen > patlen && !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_CHILDREN ) {
|
||||
if ( odnlen <= patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
if ( !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_style == ACL_STYLE_LEVEL ) {
|
||||
int level;
|
||||
struct berval ndn;
|
||||
|
||||
if ( odnlen <= patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
if ( level > 0 && !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) )
|
||||
{
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
level = b->a_level;
|
||||
ndn = *opndn;
|
||||
for ( ; level > 0; level-- ) {
|
||||
if ( BER_BVISEMPTY( &ndn ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
dnParent( &ndn, &ndn );
|
||||
if ( ndn.bv_len < patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ndn.bv_len != patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
got_match = !strcmp( pat.bv_val, &opndn->bv_val[ odnlen - patlen ] );
|
||||
|
||||
dn_match_cleanup:;
|
||||
if ( pat.bv_val != b->a_pat.bv_val ) {
|
||||
slap_sl_free( pat.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
if ( !got_match ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record value-dependent access control state
|
||||
*/
|
||||
|
|
@ -633,6 +908,100 @@ acl_get(
|
|||
} \
|
||||
} while( 0 )
|
||||
|
||||
static int
|
||||
acl_mask_dnattr(
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
struct berval *val,
|
||||
AccessControl *a,
|
||||
Access *b,
|
||||
int i,
|
||||
regmatch_t *matches,
|
||||
int count,
|
||||
AccessControlState *state,
|
||||
slap_dn_access *bdn,
|
||||
struct berval *opndn )
|
||||
{
|
||||
Attribute *at;
|
||||
struct berval bv;
|
||||
int rc, match = 0;
|
||||
const char *text;
|
||||
const char *attr = bdn->a_at->ad_cname.bv_val;
|
||||
|
||||
assert( attr != NULL );
|
||||
|
||||
if ( BER_BVISEMPTY( opndn ) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_ACL, "<= check a_dn_at: %s\n", attr, 0, 0 );
|
||||
bv = *opndn;
|
||||
|
||||
/* see if asker is listed in dnattr */
|
||||
for ( at = attrs_find( e->e_attrs, bdn->a_at );
|
||||
at != NULL;
|
||||
at = attrs_find( at->a_next, bdn->a_at ) )
|
||||
{
|
||||
if ( value_find_ex( bdn->a_at,
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
|
||||
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
|
||||
at->a_nvals,
|
||||
&bv, op->o_tmpmemctx ) == 0 )
|
||||
{
|
||||
/* found it */
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( match ) {
|
||||
/* have a dnattr match. if this is a self clause then
|
||||
* the target must also match the op dn.
|
||||
*/
|
||||
if ( bdn->a_self ) {
|
||||
/* check if the target is an attribute. */
|
||||
if ( 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 );
|
||||
/* on match error or no match, fail the ACL clause */
|
||||
if ( rc != LDAP_SUCCESS || match != 0 )
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* no dnattr match, check if this is a self clause */
|
||||
if ( ! bdn->a_self )
|
||||
return 1;
|
||||
|
||||
ACL_RECORD_VALUE_STATE;
|
||||
|
||||
/* this is a self clause, check if the target is an
|
||||
* attribute.
|
||||
*/
|
||||
if ( 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 );
|
||||
|
||||
/* on match error or no match, fail the ACL clause */
|
||||
if ( rc != LDAP_SUCCESS || match != 0 )
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* acl_mask - modifies mask based upon the given acl and the
|
||||
* requested access to entry e, attribute attr, value val. if val
|
||||
|
|
@ -655,7 +1024,7 @@ acl_mask(
|
|||
int count,
|
||||
AccessControlState *state )
|
||||
{
|
||||
int i, odnlen, patlen;
|
||||
int i;
|
||||
Access *b;
|
||||
#ifdef LDAP_DEBUG
|
||||
char accessmaskbuf[ACCESSMASK_MAXLEN];
|
||||
|
|
@ -715,255 +1084,41 @@ acl_mask(
|
|||
* value is set in a_dn_style; however, the string
|
||||
* is maintaned in a_dn_pat.
|
||||
*/
|
||||
if ( b->a_dn_style == ACL_STYLE_ANONYMOUS ) {
|
||||
if ( !BER_BVISEMPTY( &op->o_ndn ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_USERS ) {
|
||||
if ( BER_BVISEMPTY( &op->o_ndn ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( acl_mask_dn( op, e, a, nmatch, matches,
|
||||
&b->a_dn, &op->o_ndn ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_SELF ) {
|
||||
struct berval ndn, selfndn;
|
||||
int level;
|
||||
if ( !BER_BVISEMPTY( &b->a_realdn_pat ) ) {
|
||||
struct berval ndn;
|
||||
|
||||
if ( BER_BVISEMPTY( &op->o_ndn ) || BER_BVISNULL( &e->e_nname ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
level = b->a_dn_self_level;
|
||||
if ( level < 0 ) {
|
||||
selfndn = op->o_ndn;
|
||||
ndn = e->e_nname;
|
||||
level = -level;
|
||||
|
||||
} else {
|
||||
ndn = op->o_ndn;
|
||||
selfndn = e->e_nname;
|
||||
}
|
||||
|
||||
for ( ; level > 0; level-- ) {
|
||||
if ( BER_BVISEMPTY( &ndn ) ) {
|
||||
break;
|
||||
}
|
||||
dnParent( &ndn, &ndn );
|
||||
}
|
||||
|
||||
if ( BER_BVISEMPTY( &ndn ) || !dn_match( &ndn, &selfndn ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_REGEX ) {
|
||||
if ( !ber_bvccmp( &b->a_dn_pat, '*' ) ) {
|
||||
int tmp_nmatch;
|
||||
regmatch_t tmp_matches[2],
|
||||
*tmp_matchesp = tmp_matches;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
switch ( a->acl_dn_style ) {
|
||||
case ACL_STYLE_REGEX:
|
||||
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
|
||||
tmp_matchesp = matches;
|
||||
tmp_nmatch = nmatch;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
|
||||
|
||||
case ACL_STYLE_BASE:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 1;
|
||||
break;
|
||||
|
||||
case ACL_STYLE_ONE:
|
||||
case ACL_STYLE_SUBTREE:
|
||||
case ACL_STYLE_CHILDREN:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
|
||||
tmp_matches[1].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !regex_matches( &b->a_dn_pat,
|
||||
op->o_ndn.bv_val, e->e_ndn,
|
||||
tmp_nmatch, tmp_matchesp ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Debug( LDAP_DEBUG_ACL, "<= check a_realdn_pat: %s\n",
|
||||
b->a_realdn_pat.bv_val, 0, 0);
|
||||
/*
|
||||
* if access applies to the entry itself, and the
|
||||
* user is bound as somebody in the same namespace as
|
||||
* the entry, OR the given dn matches the dn pattern
|
||||
*/
|
||||
/*
|
||||
* NOTE: styles "anonymous", "users" and "self"
|
||||
* have been moved to enum slap_style_t, whose
|
||||
* value is set in a_dn_style; however, the string
|
||||
* is maintaned in a_dn_pat.
|
||||
*/
|
||||
|
||||
if ( op->o_conn && !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
|
||||
ndn = op->o_conn->c_ndn;
|
||||
} else {
|
||||
struct berval pat;
|
||||
int got_match = 0;
|
||||
ndn = op->o_ndn;
|
||||
}
|
||||
|
||||
if ( e->e_dn == NULL )
|
||||
continue;
|
||||
|
||||
if ( b->a_dn_expand ) {
|
||||
struct berval bv;
|
||||
char buf[ACL_BUF_SIZE];
|
||||
|
||||
int tmp_nmatch;
|
||||
regmatch_t tmp_matches[2],
|
||||
*tmp_matchesp = tmp_matches;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
bv.bv_len = sizeof( buf ) - 1;
|
||||
bv.bv_val = buf;
|
||||
|
||||
switch ( a->acl_dn_style ) {
|
||||
case ACL_STYLE_REGEX:
|
||||
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
|
||||
tmp_matchesp = matches;
|
||||
tmp_nmatch = nmatch;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
|
||||
|
||||
case ACL_STYLE_BASE:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 1;
|
||||
break;
|
||||
|
||||
case ACL_STYLE_ONE:
|
||||
case ACL_STYLE_SUBTREE:
|
||||
case ACL_STYLE_CHILDREN:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
|
||||
tmp_matches[1].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( string_expand( &bv, &b->a_dn_pat,
|
||||
e->e_nname.bv_val,
|
||||
tmp_nmatch, tmp_matchesp ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( dnNormalize(0, NULL, NULL, &bv,
|
||||
&pat, op->o_tmpmemctx )
|
||||
!= LDAP_SUCCESS )
|
||||
{
|
||||
/* did not expand to a valid dn */
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
pat = b->a_dn_pat;
|
||||
}
|
||||
|
||||
patlen = pat.bv_len;
|
||||
odnlen = op->o_ndn.bv_len;
|
||||
if ( odnlen < patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
|
||||
}
|
||||
|
||||
if ( b->a_dn_style == ACL_STYLE_BASE ) {
|
||||
/* base dn -- entire object DN must match */
|
||||
if ( odnlen != patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_ONE ) {
|
||||
int rdnlen = -1;
|
||||
|
||||
if ( odnlen <= patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
if ( !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
rdnlen = dn_rdnlen( NULL, &op->o_ndn );
|
||||
if ( rdnlen != odnlen - patlen - 1 ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_SUBTREE ) {
|
||||
if ( odnlen > patlen && !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_CHILDREN ) {
|
||||
if ( odnlen <= patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
if ( !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
} else if ( b->a_dn_style == ACL_STYLE_LEVEL ) {
|
||||
int level;
|
||||
struct berval ndn;
|
||||
|
||||
if ( odnlen <= patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
if ( level > 0 && !DN_SEPARATOR( op->o_ndn.bv_val[odnlen - patlen - 1] ) )
|
||||
{
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
|
||||
level = b->a_dn_level;
|
||||
ndn = op->o_ndn;
|
||||
for ( ; level > 0; level-- ) {
|
||||
if ( BER_BVISEMPTY( &ndn ) ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
dnParent( &ndn, &ndn );
|
||||
if ( ndn.bv_len < patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ndn.bv_len != patlen ) {
|
||||
goto dn_match_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
got_match = !strcmp( pat.bv_val, &op->o_ndn.bv_val[ odnlen - patlen ] );
|
||||
|
||||
dn_match_cleanup:;
|
||||
if ( pat.bv_val != b->a_dn_pat.bv_val ) {
|
||||
slap_sl_free( pat.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
if ( !got_match ) {
|
||||
continue;
|
||||
}
|
||||
if ( acl_mask_dn( op, e, a, nmatch, matches,
|
||||
&b->a_realdn, &ndn ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1209,6 +1364,33 @@ dn_match_cleanup:;
|
|||
}
|
||||
}
|
||||
|
||||
if ( b->a_dn_at != NULL ) {
|
||||
if ( acl_mask_dnattr( op, e, val, a, b, i,
|
||||
matches, count, state,
|
||||
&b->a_dn, &op->o_ndn ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( b->a_realdn_at != NULL ) {
|
||||
struct berval ndn;
|
||||
|
||||
if ( op->o_conn && !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
|
||||
ndn = op->o_conn->c_ndn;
|
||||
} else {
|
||||
ndn = op->o_ndn;
|
||||
}
|
||||
|
||||
if ( acl_mask_dnattr( op, e, val, a, b, i,
|
||||
matches, count, state,
|
||||
&b->a_realdn, &ndn ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( b->a_dn_at != NULL ) {
|
||||
Attribute *at;
|
||||
struct berval bv;
|
||||
|
|
@ -1243,7 +1425,7 @@ dn_match_cleanup:;
|
|||
}
|
||||
}
|
||||
|
||||
if( match ) {
|
||||
if ( match ) {
|
||||
/* have a dnattr match. if this is a self clause then
|
||||
* the target must also match the op dn.
|
||||
*/
|
||||
|
|
@ -1261,6 +1443,7 @@ dn_match_cleanup:;
|
|||
if (rc != LDAP_SUCCESS || match != 0 )
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* no dnattr match, check if this is a self clause */
|
||||
if ( ! b->a_dn_self )
|
||||
|
|
@ -1286,6 +1469,7 @@ dn_match_cleanup:;
|
|||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
|
||||
struct berval bv;
|
||||
|
|
|
|||
|
|
@ -589,11 +589,13 @@ parse_acl(
|
|||
|
||||
/* get <who> */
|
||||
for ( ; i < argc; i++ ) {
|
||||
slap_style_t sty = ACL_STYLE_REGEX;
|
||||
char *style_modifier = NULL;
|
||||
char *style_level = NULL;
|
||||
int level = 0;
|
||||
int expand = 0;
|
||||
slap_style_t sty = ACL_STYLE_REGEX;
|
||||
char *style_modifier = NULL;
|
||||
char *style_level = NULL;
|
||||
int level = 0;
|
||||
int expand = 0;
|
||||
slap_dn_access *bdn = &b->a_dn;
|
||||
int is_realdn = 0;
|
||||
|
||||
split( argv[i], '=', &left, &right );
|
||||
split( left, '.', &left, &style );
|
||||
|
|
@ -721,38 +723,48 @@ parse_acl(
|
|||
fname, lineno );
|
||||
}
|
||||
|
||||
if ( strcasecmp( argv[i], "*" ) == 0 ) {
|
||||
if ( strncasecmp( left, "real", STRLENOF( "real" ) ) == 0 ) {
|
||||
is_realdn = 1;
|
||||
bdn = &b->a_realdn;
|
||||
left += STRLENOF( "real" );
|
||||
}
|
||||
|
||||
if ( strcasecmp( left, "*" ) == 0 ) {
|
||||
if ( is_realdn ) {
|
||||
acl_usage();
|
||||
}
|
||||
|
||||
ber_str2bv( "*", STRLENOF( "*" ), 1, &bv );
|
||||
sty = ACL_STYLE_REGEX;
|
||||
|
||||
} else if ( strcasecmp( argv[i], "anonymous" ) == 0 ) {
|
||||
} else if ( strcasecmp( left, "anonymous" ) == 0 ) {
|
||||
ber_str2bv("anonymous", STRLENOF( "anonymous" ), 1, &bv);
|
||||
sty = ACL_STYLE_ANONYMOUS;
|
||||
|
||||
} else if ( strcasecmp( argv[i], "users" ) == 0 ) {
|
||||
} else if ( strcasecmp( left, "users" ) == 0 ) {
|
||||
ber_str2bv("users", STRLENOF( "users" ), 1, &bv);
|
||||
sty = ACL_STYLE_USERS;
|
||||
|
||||
} else if ( strcasecmp( argv[i], "self" ) == 0 ) {
|
||||
} else if ( strcasecmp( left, "self" ) == 0 ) {
|
||||
ber_str2bv("self", STRLENOF( "self" ), 1, &bv);
|
||||
sty = ACL_STYLE_SELF;
|
||||
|
||||
} else if ( strcasecmp( left, "dn" ) == 0 ) {
|
||||
if ( sty == ACL_STYLE_REGEX ) {
|
||||
b->a_dn_style = ACL_STYLE_REGEX;
|
||||
bdn->a_style = ACL_STYLE_REGEX;
|
||||
if ( right == NULL ) {
|
||||
/* no '=' */
|
||||
ber_str2bv("users",
|
||||
STRLENOF( "users" ),
|
||||
1, &bv);
|
||||
b->a_dn_style = ACL_STYLE_USERS;
|
||||
bdn->a_style = ACL_STYLE_USERS;
|
||||
|
||||
} else if (*right == '\0' ) {
|
||||
/* dn="" */
|
||||
ber_str2bv("anonymous",
|
||||
STRLENOF( "anonymous" ),
|
||||
1, &bv);
|
||||
b->a_dn_style = ACL_STYLE_ANONYMOUS;
|
||||
bdn->a_style = ACL_STYLE_ANONYMOUS;
|
||||
|
||||
} else if ( strcmp( right, "*" ) == 0 ) {
|
||||
/* dn=* */
|
||||
|
|
@ -760,7 +772,7 @@ parse_acl(
|
|||
ber_str2bv("users",
|
||||
STRLENOF( "users" ),
|
||||
1, &bv);
|
||||
b->a_dn_style = ACL_STYLE_USERS;
|
||||
bdn->a_style = ACL_STYLE_USERS;
|
||||
|
||||
} else if ( strcmp( right, ".+" ) == 0
|
||||
|| strcmp( right, "^.+" ) == 0
|
||||
|
|
@ -772,7 +784,7 @@ parse_acl(
|
|||
ber_str2bv("users",
|
||||
STRLENOF( "users" ),
|
||||
1, &bv);
|
||||
b->a_dn_style = ACL_STYLE_USERS;
|
||||
bdn->a_style = ACL_STYLE_USERS;
|
||||
|
||||
} else if ( strcmp( right, ".*" ) == 0
|
||||
|| strcmp( right, "^.*" ) == 0
|
||||
|
|
@ -808,7 +820,7 @@ parse_acl(
|
|||
}
|
||||
|
||||
if ( !BER_BVISNULL( &bv ) ) {
|
||||
if ( !BER_BVISEMPTY( &b->a_dn_pat ) ) {
|
||||
if ( !BER_BVISEMPTY( &bdn->a_pat ) ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: dn pattern already specified.\n",
|
||||
fname, lineno );
|
||||
|
|
@ -822,7 +834,7 @@ parse_acl(
|
|||
expand == 0 )
|
||||
{
|
||||
rc = dnNormalize(0, NULL, NULL,
|
||||
&bv, &b->a_dn_pat, NULL);
|
||||
&bv, &bdn->a_pat, NULL);
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: bad DN \"%s\" in by DN clause\n",
|
||||
|
|
@ -832,12 +844,12 @@ parse_acl(
|
|||
free( bv.bv_val );
|
||||
|
||||
} else {
|
||||
b->a_dn_pat = bv;
|
||||
bdn->a_pat = bv;
|
||||
}
|
||||
b->a_dn_style = sty;
|
||||
b->a_dn_expand = expand;
|
||||
bdn->a_style = sty;
|
||||
bdn->a_expand = expand;
|
||||
if ( sty == ACL_STYLE_SELF ) {
|
||||
b->a_dn_self_level = level;
|
||||
bdn->a_self_level = level;
|
||||
|
||||
} else {
|
||||
if ( level < 0 ) {
|
||||
|
|
@ -858,7 +870,7 @@ parse_acl(
|
|||
fname, lineno, 0 );
|
||||
}
|
||||
|
||||
b->a_dn_level = level;
|
||||
bdn->a_level = level;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -872,14 +884,14 @@ parse_acl(
|
|||
acl_usage();
|
||||
}
|
||||
|
||||
if( b->a_dn_at != NULL ) {
|
||||
if( bdn->a_at != NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: dnattr already specified.\n",
|
||||
fname, lineno );
|
||||
acl_usage();
|
||||
}
|
||||
|
||||
rc = slap_str2ad( right, &b->a_dn_at, &text );
|
||||
rc = slap_str2ad( right, &bdn->a_at, &text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
|
|
@ -889,20 +901,20 @@ parse_acl(
|
|||
}
|
||||
|
||||
|
||||
if( !is_at_syntax( b->a_dn_at->ad_type,
|
||||
if( !is_at_syntax( bdn->a_at->ad_type,
|
||||
SLAPD_DN_SYNTAX ) &&
|
||||
!is_at_syntax( b->a_dn_at->ad_type,
|
||||
!is_at_syntax( bdn->a_at->ad_type,
|
||||
SLAPD_NAMEUID_SYNTAX ))
|
||||
{
|
||||
fprintf( stderr,
|
||||
"%s: line %d: dnattr \"%s\": "
|
||||
"inappropriate syntax: %s\n",
|
||||
fname, lineno, right,
|
||||
b->a_dn_at->ad_type->sat_syntax_oid );
|
||||
bdn->a_at->ad_type->sat_syntax_oid );
|
||||
acl_usage();
|
||||
}
|
||||
|
||||
if( b->a_dn_at->ad_type->sat_equality == NULL ) {
|
||||
if( bdn->a_at->ad_type->sat_equality == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: dnattr \"%s\": "
|
||||
"inappropriate matching (no EQUALITY)\n",
|
||||
|
|
@ -1650,9 +1662,13 @@ parse_acl(
|
|||
}
|
||||
|
||||
/* get <access> */
|
||||
if ( strncasecmp( left, "self", 4 ) == 0 ) {
|
||||
if ( strncasecmp( left, "self", STRLENOF( "self" ) ) == 0 ) {
|
||||
b->a_dn_self = 1;
|
||||
ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[4] ) );
|
||||
ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "self" ) ] ) );
|
||||
|
||||
} else if ( strncasecmp( left, "realself", STRLENOF( "realself" ) ) == 0 ) {
|
||||
b->a_realdn_self = 1;
|
||||
ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "realself" ) ] ) );
|
||||
|
||||
} else {
|
||||
ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( left ) );
|
||||
|
|
@ -2080,6 +2096,9 @@ access_free( Access *a )
|
|||
if ( !BER_BVISNULL( &a->a_dn_pat ) ) {
|
||||
free( a->a_dn_pat.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &a->a_realdn_pat ) ) {
|
||||
free( a->a_realdn_pat.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &a->a_peername_pat ) ) {
|
||||
free( a->a_peername_pat.bv_val );
|
||||
}
|
||||
|
|
@ -2211,6 +2230,62 @@ str2access( const char *str )
|
|||
|
||||
static char aclbuf[ACLBUF_MAXLEN];
|
||||
|
||||
static char *
|
||||
dnaccess2text( slap_dn_access *bdn, char *ptr, int is_realdn )
|
||||
{
|
||||
*ptr++ = ' ';
|
||||
|
||||
if ( is_realdn ) {
|
||||
ptr = lutil_strcopy( ptr, "real" );
|
||||
}
|
||||
|
||||
if ( ber_bvccmp( &bdn->a_pat, '*' ) ||
|
||||
bdn->a_style == ACL_STYLE_ANONYMOUS ||
|
||||
bdn->a_style == ACL_STYLE_USERS ||
|
||||
bdn->a_style == ACL_STYLE_SELF )
|
||||
{
|
||||
if ( is_realdn ) {
|
||||
assert( ! ber_bvccmp( &bdn->a_pat, '*' ) );
|
||||
}
|
||||
|
||||
ptr = lutil_strcopy( ptr, bdn->a_pat.bv_val );
|
||||
if ( bdn->a_style == ACL_STYLE_SELF && bdn->a_self_level != 0 ) {
|
||||
int n = sprintf( ptr, ".level{%d}", bdn->a_self_level );
|
||||
if ( n > 0 ) {
|
||||
ptr += n;
|
||||
} /* else ? */
|
||||
}
|
||||
|
||||
} else {
|
||||
ptr = lutil_strcopy( ptr, "dn." );
|
||||
ptr = lutil_strcopy( ptr, style_strings[bdn->a_style] );
|
||||
if ( bdn->a_style == ACL_STYLE_LEVEL ) {
|
||||
int n = sprintf( ptr, "{%d}", bdn->a_level );
|
||||
if ( n > 0 ) {
|
||||
ptr += n;
|
||||
} /* else ? */
|
||||
}
|
||||
if ( bdn->a_expand ) {
|
||||
ptr = lutil_strcopy( ptr, ",expand" );
|
||||
}
|
||||
*ptr++ = '=';
|
||||
*ptr++ = '"';
|
||||
ptr = lutil_strcopy( ptr, bdn->a_pat.bv_val );
|
||||
*ptr++ = '"';
|
||||
}
|
||||
|
||||
if ( bdn->a_at != NULL ) {
|
||||
*ptr++ = ' ';
|
||||
if ( is_realdn ) {
|
||||
ptr = lutil_strcopy( ptr, "real" );
|
||||
}
|
||||
ptr = lutil_strcopy( ptr, "dnattr=" );
|
||||
ptr = lutil_strcopy( ptr, bdn->a_at->ad_cname.bv_val );
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *
|
||||
access2text( Access *b, char *ptr )
|
||||
{
|
||||
|
|
@ -2219,42 +2294,11 @@ access2text( Access *b, char *ptr )
|
|||
ptr = lutil_strcopy( ptr, "\tby" );
|
||||
|
||||
if ( !BER_BVISEMPTY( &b->a_dn_pat ) ) {
|
||||
*ptr++ = ' ';
|
||||
if ( ber_bvccmp( &b->a_dn_pat, '*' ) ||
|
||||
b->a_dn_style == ACL_STYLE_ANONYMOUS ||
|
||||
b->a_dn_style == ACL_STYLE_USERS ||
|
||||
b->a_dn_style == ACL_STYLE_SELF )
|
||||
{
|
||||
ptr = lutil_strcopy( ptr, b->a_dn_pat.bv_val );
|
||||
if ( b->a_dn_style == ACL_STYLE_SELF && b->a_dn_self_level != 0 ) {
|
||||
int n = sprintf( ptr, ".level{%d}", b->a_dn_self_level );
|
||||
if ( n > 0 ) {
|
||||
ptr += n;
|
||||
} /* else ? */
|
||||
}
|
||||
|
||||
} else {
|
||||
ptr = lutil_strcopy( ptr, "dn." );
|
||||
ptr = lutil_strcopy( ptr, style_strings[b->a_dn_style] );
|
||||
if ( b->a_dn_style == ACL_STYLE_LEVEL ) {
|
||||
int n = sprintf( ptr, "{%d}", b->a_dn_level );
|
||||
if ( n > 0 ) {
|
||||
ptr += n;
|
||||
} /* else ? */
|
||||
}
|
||||
if ( b->a_dn_expand ) {
|
||||
ptr = lutil_strcopy( ptr, ",expand" );
|
||||
}
|
||||
*ptr++ = '=';
|
||||
*ptr++ = '"';
|
||||
ptr = lutil_strcopy( ptr, b->a_dn_pat.bv_val );
|
||||
*ptr++ = '"';
|
||||
}
|
||||
ptr = dnaccess2text( &b->a_dn, ptr, 0 );
|
||||
}
|
||||
|
||||
if ( b->a_dn_at != NULL ) {
|
||||
ptr = lutil_strcopy( ptr, " dnattr=" );
|
||||
ptr = lutil_strcopy( ptr, b->a_dn_at->ad_cname.bv_val );
|
||||
if ( !BER_BVISEMPTY( &b->a_realdn_pat ) ) {
|
||||
ptr = dnaccess2text( &b->a_realdn, ptr, 1 );
|
||||
}
|
||||
|
||||
if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
|
||||
|
|
@ -2342,7 +2386,11 @@ access2text( Access *b, char *ptr )
|
|||
}
|
||||
|
||||
*ptr++ = ' ';
|
||||
if ( b->a_dn_self ) ptr = lutil_strcopy( ptr, "self" );
|
||||
if ( b->a_dn_self ) {
|
||||
ptr = lutil_strcopy( ptr, "self" );
|
||||
} else if ( b->a_realdn_self ) {
|
||||
ptr = lutil_strcopy( ptr, "realself" );
|
||||
}
|
||||
ptr = lutil_strcopy( ptr, accessmask2str( b->a_access_mask, maskbuf, 0 ));
|
||||
if ( !maskbuf[0] ) ptr--;
|
||||
|
||||
|
|
|
|||
|
|
@ -755,19 +755,17 @@ static int parseProxyAuthz (
|
|||
ctrl->ldctl_value.bv_len ? ctrl->ldctl_value.bv_val : "anonymous",
|
||||
0 );
|
||||
|
||||
if( ctrl->ldctl_value.bv_len == 0 ) {
|
||||
if ( ctrl->ldctl_value.bv_len == 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"parseProxyAuthz: conn=%lu anonymous\n",
|
||||
op->o_connid, 0, 0 );
|
||||
|
||||
/* anonymous */
|
||||
free( op->o_dn.bv_val );
|
||||
op->o_dn.bv_len = 0;
|
||||
op->o_dn.bv_val = ch_strdup( "" );
|
||||
|
||||
free( op->o_ndn.bv_val );
|
||||
op->o_ndn.bv_val[ 0 ] = '\0';
|
||||
op->o_ndn.bv_len = 0;
|
||||
op->o_ndn.bv_val = ch_strdup( "" );
|
||||
|
||||
op->o_dn.bv_val[ 0 ] = '\0';
|
||||
op->o_dn.bv_len = 0;
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
|
@ -791,27 +789,26 @@ static int parseProxyAuthz (
|
|||
|
||||
rc = slap_sasl_authorized( op, &op->o_ndn, &dn );
|
||||
|
||||
if( rc ) {
|
||||
if ( rc ) {
|
||||
ch_free( dn.bv_val );
|
||||
rs->sr_text = "not authorized to assume identity";
|
||||
return LDAP_PROXY_AUTHZ_FAILURE;
|
||||
}
|
||||
|
||||
ch_free( op->o_dn.bv_val );
|
||||
ch_free( op->o_ndn.bv_val );
|
||||
|
||||
op->o_dn.bv_val = NULL;
|
||||
op->o_ndn = dn;
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS, "%s PROXYAUTHZ dn=\"%s\"\n",
|
||||
op->o_log_prefix, dn.bv_val, 0, 0, 0 );
|
||||
ch_free( op->o_dn.bv_val );
|
||||
|
||||
/*
|
||||
* NOTE: since slap_sasl_getdn() returns a normalized dn,
|
||||
* from now on op->o_dn is normalized
|
||||
*/
|
||||
op->o_ndn = dn;
|
||||
ber_dupbv( &op->o_dn, &dn );
|
||||
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS, "%s PROXYAUTHZ dn=\"%s\"\n",
|
||||
op->o_log_prefix, dn.bv_val, 0, 0, 0 );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,13 +68,13 @@ slap_op_free( Operation *op )
|
|||
if ( op->o_ber != NULL ) {
|
||||
ber_free( op->o_ber, 1 );
|
||||
}
|
||||
if ( op->o_dn.bv_val != NULL ) {
|
||||
if ( !BER_BVISNULL( &op->o_dn ) ) {
|
||||
free( op->o_dn.bv_val );
|
||||
}
|
||||
if ( op->o_ndn.bv_val != NULL ) {
|
||||
if ( !BER_BVISNULL( &op->o_ndn ) ) {
|
||||
free( op->o_ndn.bv_val );
|
||||
}
|
||||
if ( op->o_authmech.bv_val != NULL ) {
|
||||
if ( !BER_BVISNULL( &op->o_authmech ) ) {
|
||||
free( op->o_authmech.bv_val );
|
||||
}
|
||||
if ( op->o_ctrls != NULL ) {
|
||||
|
|
@ -89,9 +89,9 @@ slap_op_free( Operation *op )
|
|||
|
||||
{
|
||||
GroupAssertion *g, *n;
|
||||
for (g = op->o_groups; g; g=n) {
|
||||
for ( g = op->o_groups; g; g = n ) {
|
||||
n = g->ga_next;
|
||||
slap_sl_free(g, op->o_tmpmemctx);
|
||||
slap_sl_free( g, op->o_tmpmemctx );
|
||||
}
|
||||
op->o_groups = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1228,6 +1228,19 @@ typedef struct slap_dynacl_t {
|
|||
} slap_dynacl_t;
|
||||
#endif /* SLAP_DYNACL */
|
||||
|
||||
/* the DN portion of the "by" part */
|
||||
typedef struct slap_dn_access {
|
||||
/* DN pattern */
|
||||
AuthorizationInformation a_dnauthz;
|
||||
|
||||
slap_style_t a_style;
|
||||
int a_level;
|
||||
int a_self_level;
|
||||
AttributeDescription *a_at;
|
||||
int a_self;
|
||||
int a_expand;
|
||||
} slap_dn_access;
|
||||
|
||||
/* the "by" part */
|
||||
typedef struct slap_access {
|
||||
slap_control_t a_type;
|
||||
|
|
@ -1299,16 +1312,30 @@ typedef struct slap_access {
|
|||
|
||||
slap_mask_t a_access_mask;
|
||||
|
||||
AuthorizationInformation a_authz;
|
||||
#define a_dn_pat a_authz.sai_dn
|
||||
/* DN pattern */
|
||||
slap_dn_access a_dn;
|
||||
#define a_dn_pat a_dn.a_dnauthz.sai_dn
|
||||
#define a_dn_style a_dn.a_style
|
||||
#define a_dn_level a_dn.a_level
|
||||
#define a_dn_self_level a_dn.a_self_level
|
||||
#define a_dn_at a_dn.a_at
|
||||
#define a_dn_self a_dn.a_self
|
||||
#define a_dn_expand a_dn.a_expand
|
||||
|
||||
slap_style_t a_dn_style;
|
||||
int a_dn_level;
|
||||
int a_dn_self_level;
|
||||
AttributeDescription *a_dn_at;
|
||||
int a_dn_self;
|
||||
int a_dn_expand;
|
||||
/* real DN pattern */
|
||||
slap_dn_access a_realdn;
|
||||
#define a_realdn_pat a_realdn.a_dnauthz.sai_dn
|
||||
#define a_realdn_style a_realdn.a_style
|
||||
#define a_realdn_level a_realdn.a_level
|
||||
#define a_realdn_self_level a_realdn.a_self_level
|
||||
#define a_realdn_at a_realdn.a_at
|
||||
#define a_realdn_self a_realdn.a_self
|
||||
#define a_realdn_expand a_realdn.a_expand
|
||||
|
||||
#define a_authz a_dn.a_dnauthz
|
||||
#define a_pat a_dnauthz.sai_dn
|
||||
|
||||
/* connection related stuff */
|
||||
slap_style_t a_peername_style;
|
||||
struct berval a_peername_pat;
|
||||
unsigned long a_peername_addr,
|
||||
|
|
|
|||
Loading…
Reference in a new issue