further isolation and cleanup of ACI code

This commit is contained in:
Pierangelo Masarati 2005-11-10 00:52:43 +00:00
parent cbdaf8058f
commit 4537065ffc
4 changed files with 150 additions and 144 deletions

View file

@ -42,6 +42,75 @@
#define ACI_BUF_SIZE 1024 /* use most appropriate size */
enum {
ACI_BV_ENTRY,
ACI_BV_CHILDREN,
ACI_BV_ONELEVEL,
ACI_BV_SUBTREE,
ACI_BV_BR_ENTRY,
ACI_BV_BR_ALL,
ACI_BV_ACCESS_ID,
ACI_BV_PUBLIC,
ACI_BV_USERS,
ACI_BV_SELF,
ACI_BV_DNATTR,
ACI_BV_GROUP,
ACI_BV_ROLE,
ACI_BV_SET,
ACI_BV_SET_REF,
ACI_BV_GRANT,
ACI_BV_DENY,
ACI_BV_GROUP_CLASS,
ACI_BV_GROUP_ATTR,
ACI_BV_ROLE_CLASS,
ACI_BV_ROLE_ATTR,
ACI_BV_SET_ATTR,
ACI_BV_LAST
};
static const struct berval aci_bv[] = {
/* scope */
BER_BVC("entry"),
BER_BVC("children"),
BER_BVC("onelevel"),
BER_BVC("subtree"),
/* */
BER_BVC("[entry]"),
BER_BVC("[all]"),
/* type */
BER_BVC("access-id"),
BER_BVC("public"),
BER_BVC("users"),
BER_BVC("self"),
BER_BVC("dnattr"),
BER_BVC("group"),
BER_BVC("role"),
BER_BVC("set"),
BER_BVC("set-ref"),
/* actions */
BER_BVC("grant"),
BER_BVC("deny"),
/* schema */
BER_BVC(SLAPD_GROUP_CLASS),
BER_BVC(SLAPD_GROUP_ATTR),
BER_BVC(SLAPD_ROLE_CLASS),
BER_BVC(SLAPD_ROLE_ATTR),
BER_BVC(SLAPD_ACI_SET_ATTR),
BER_BVNULL
};
#ifdef SLAP_DYNACL
static
#endif /* SLAP_DYNACL */
@ -554,12 +623,12 @@ aci_mask(
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) {
if ( acl_match_set( &sdn, op, e, 0 ) ) {
if ( acl_match_set( &sdn, op, e, NULL ) ) {
return 1;
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) {
if ( acl_match_set( &sdn, op, e, 1 ) ) {
if ( acl_match_set( &sdn, op, e, (struct berval *)&aci_bv[ ACI_BV_SET_ATTR ] ) ) {
return 1;
}
@ -574,7 +643,7 @@ aci_mask(
int
aci_init( void )
{
/* OpenLDAP Experimental Syntax */
/* OpenLDAP eXperimental Syntax */
static slap_syntax_defs_rec aci_syntax_def = {
"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
SLAP_SYNTAX_HIDE,
@ -659,11 +728,6 @@ aci_init( void )
}
#ifdef SLAP_DYNACL
/*
* FIXME: there is a silly dependence that makes it difficult
* to move ACIs in a run-time loadable module under the "dynacl"
* umbrella, because sets share some helpers with ACIs.
*/
static int
dynacl_aci_parse(
const char *fname,
@ -744,6 +808,11 @@ dynacl_aci_mask(
char accessmaskbuf1[ACCESSMASK_MAXLEN];
#endif /* LDAP_DEBUG */
if ( BER_BVISEMPTY( &e->e_nname ) ) {
/* no ACIs in the root DSE */
return -1;
}
/* start out with nothing granted, nothing denied */
ACL_INIT(tgrant);
ACL_INIT(tdeny);
@ -767,7 +836,7 @@ dynacl_aci_mask(
}
}
Debug( LDAP_DEBUG_ACL, "<= aci_mask grant %s deny %s\n",
Debug( LDAP_DEBUG_ACL, " <= aci_mask grant %s deny %s\n",
accessmask2str( tgrant, accessmaskbuf, 1 ),
accessmask2str( tdeny, accessmaskbuf1, 1 ), 0 );
}
@ -779,35 +848,41 @@ dynacl_aci_mask(
if ( tgrant == ACL_PRIV_NONE && tdeny == ACL_PRIV_NONE ) {
struct berval parent_ndn;
#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 ( !BER_BVISEMPTY( &parent_ndn ) ){
int i;
BerVarray bvals = NULL;
int ret, stop;
Debug( LDAP_DEBUG_ACL, "checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 );
ret = backend_attribute( &op2, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
/* 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. */
struct berval save_o_dn, save_o_ndn;
if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
save_o_dn = op->o_dn;
save_o_ndn = op->o_ndn;
op->o_dn = op->o_bd->be_rootdn;
op->o_ndn = op->o_bd->be_rootndn;
}
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 );
if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
op->o_dn = save_o_dn;
op->o_ndn = save_o_ndn;
}
switch ( ret ) {
case LDAP_SUCCESS :

View file

@ -39,46 +39,10 @@
#define ACL_BUF_SIZE 1024 /* use most appropriate size */
/*
* speed up compares
*/
const struct berval aci_bv[] = {
BER_BVC("entry"),
BER_BVC("children"),
BER_BVC("onelevel"),
BER_BVC("subtree"),
BER_BVC("[entry]"),
BER_BVC("[all]"),
BER_BVC("access-id"),
#if 0
BER_BVC("anonymous"),
#endif
BER_BVC("public"),
BER_BVC("users"),
BER_BVC("self"),
BER_BVC("dnattr"),
BER_BVC("group"),
BER_BVC("role"),
BER_BVC("set"),
BER_BVC("set-ref"),
BER_BVC("grant"),
BER_BVC("deny"),
BER_BVC("IP="),
static const struct berval acl_bv_ip_eq = BER_BVC( "IP=" );
#ifdef LDAP_PF_LOCAL
BER_BVC("PATH="),
#if 0
BER_BVC(LDAP_DIRSEP),
#endif
static const struct berval acl_bv_path_eq = BER_BVC("PATH=");
#endif /* LDAP_PF_LOCAL */
BER_BVC(SLAPD_GROUP_CLASS),
BER_BVC(SLAPD_GROUP_ATTR),
BER_BVC(SLAPD_ROLE_CLASS),
BER_BVC(SLAPD_ROLE_ATTR),
BER_BVC(SLAPD_ACI_SET_ATTR)
};
static AccessControl * slap_acl_get(
AccessControl *ac, int *count,
@ -1395,9 +1359,6 @@ slap_acl_mask(
Access *b;
#ifdef LDAP_DEBUG
char accessmaskbuf[ACCESSMASK_MAXLEN];
#if !defined( SLAP_DYNACL ) && defined( SLAPD_ACI_ENABLED )
char accessmaskbuf1[ACCESSMASK_MAXLEN];
#endif /* !SLAP_DYNACL && SLAPD_ACI_ENABLED */
#endif /* DEBUG */
const char *attr;
slap_mask_t a2pmask = ACL_ACCESS2PRIV( *mask );
@ -1633,12 +1594,12 @@ slap_acl_mask(
int port_number = -1;
if ( strncasecmp( op->o_conn->c_peer_name.bv_val,
aci_bv[ ACI_BV_IP_EQ ].bv_val,
aci_bv[ ACI_BV_IP_EQ ].bv_len ) != 0 )
acl_bv_ip_eq.bv_val,
acl_bv_ip_eq.bv_len ) != 0 )
continue;
ip.bv_val = op->o_conn->c_peer_name.bv_val + aci_bv[ ACI_BV_IP_EQ ].bv_len;
ip.bv_len = op->o_conn->c_peer_name.bv_len - aci_bv[ ACI_BV_IP_EQ ].bv_len;
ip.bv_val = op->o_conn->c_peer_name.bv_val + acl_bv_ip_eq.bv_len;
ip.bv_len = op->o_conn->c_peer_name.bv_len - acl_bv_ip_eq.bv_len;
port = strrchr( ip.bv_val, ':' );
if ( port ) {
@ -1677,14 +1638,14 @@ slap_acl_mask(
struct berval path;
if ( strncmp( op->o_conn->c_peer_name.bv_val,
aci_bv[ ACI_BV_PATH_EQ ].bv_val,
aci_bv[ ACI_BV_PATH_EQ ].bv_len ) != 0 )
acl_bv_path_eq.bv_val,
acl_bv_path_eq.bv_len ) != 0 )
continue;
path.bv_val = op->o_conn->c_peer_name.bv_val
+ aci_bv[ ACI_BV_PATH_EQ ].bv_len;
+ acl_bv_path_eq.bv_len;
path.bv_len = op->o_conn->c_peer_name.bv_len
- aci_bv[ ACI_BV_PATH_EQ ].bv_len;
- acl_bv_path_eq.bv_len;
if ( ber_bvcmp( &b->a_peername_pat, &path ) != 0 )
continue;
@ -1923,7 +1884,7 @@ slap_acl_mask(
bv = b->a_set_pat;
}
if ( acl_match_set( &bv, op, e, 0 ) == 0 ) {
if ( acl_match_set( &bv, op, e, NULL ) == 0 ) {
continue;
}
}
@ -1972,14 +1933,9 @@ slap_acl_mask(
0, 0, 0 );
/* this case works different from the others above.
* since aci's themselves give permissions, we need
* since dynamic ACL's themselves give permissions, we need
* to first check b->a_access_mask, the ACL's access level.
*/
if ( BER_BVISEMPTY( &e->e_nname ) ) {
/* no ACIs in the root DSE */
continue;
}
/* first check if the right being requested
* is allowed by the ACL clause.
*/
@ -2037,6 +1993,8 @@ slap_acl_mask(
} else
#else /* !SLAP_DYNACL */
/* NOTE: this entire block can be eliminated when SLAP_DYNACL
* moves outside of LDAP_DEVEL */
#ifdef SLAPD_ACI_ENABLED
if ( b->a_aci_at != NULL ) {
Attribute *at;
@ -2044,6 +2002,9 @@ slap_acl_mask(
struct berval parent_ndn;
BerVarray bvals = NULL;
int ret, stop;
#ifdef LDAP_DEBUG
char accessmaskbuf1[ACCESSMASK_MAXLEN];
#endif /* DEBUG */
Debug( LDAP_DEBUG_ACL, " <= check a_aci_at: %s\n",
b->a_aci_at->ad_cname.bv_val, 0, 0 );
@ -2679,13 +2640,13 @@ acl_match_set (
struct berval *subj,
Operation *op,
Entry *e,
int setref )
struct berval *default_set_attribute )
{
struct berval set = BER_BVNULL;
int rc = 0;
AclSetCookie cookie;
if ( setref == 0 ) {
if ( default_set_attribute == NULL ) {
ber_dupbv_x( &set, subj, op->o_tmpmemctx );
} else {
@ -2701,7 +2662,7 @@ acl_match_set (
}
if ( acl_get_part( subj, 1, '/', &setat ) < 0 ) {
setat = aci_bv[ ACI_BV_SET_ATTR ];
setat = *default_set_attribute;
}
/*
@ -2798,23 +2759,34 @@ slap_dynacl_get( const char *name )
}
#endif /* SLAP_DYNACL */
/*
* statically built-in dynamic ACL initialization
*/
static int (*acl_init_func[])( void ) = {
#ifdef SLAPD_ACI_ENABLED
#ifdef SLAP_DYNACL
dynacl_aci_init,
#else /* !SLAP_DYNACL */
aci_init,
#endif /* !SLAP_DYNACL */
#endif /* SLAPD_ACI_ENABLED */
NULL
};
int
acl_init( void )
{
int rc = 0;
int i, rc;
#ifdef SLAPD_ACI_ENABLED
#ifdef SLAP_DYNACL
rc = dynacl_aci_init();
#else /* !SLAP_DYNACL */
rc = aci_init();
#endif /* !SLAP_DYNACL */
if ( rc != 0 ) {
return rc;
for ( i = 0; acl_init_func[ i ] != NULL; i++ ) {
rc = (*(acl_init_func[ i ]))();
if ( rc != 0 ) {
return rc;
}
}
#endif /* SLAPD_ACI_ENABLED */
return rc;
return 0;
}
int

View file

@ -93,8 +93,6 @@ LDAP_SLAPD_F (slap_dynacl_t *) slap_dynacl_get LDAP_P(( const char *name ));
#endif /* SLAP_DYNACL */
LDAP_SLAPD_F (int) acl_init LDAP_P(( void ));
LDAP_SLAPD_V (const struct berval) aci_bv[];
LDAP_SLAPD_F (int) acl_get_part LDAP_P((
struct berval *list,
int ix,
@ -104,7 +102,7 @@ LDAP_SLAPD_F (int) acl_match_set LDAP_P((
struct berval *subj,
Operation *op,
Entry *e,
int setref ));
struct berval *default_set_attribute ));
LDAP_SLAPD_F (int) acl_string_expand LDAP_P((
struct berval *newbuf, struct berval *pattern,
char *match, int nmatch, regmatch_t *matches ));

View file

@ -1510,45 +1510,6 @@ typedef enum slap_aci_scope_t {
} slap_aci_scope_t;
#endif /* SLAPD_ACI_ENABLED */
enum {
ACI_BV_ENTRY,
ACI_BV_CHILDREN,
ACI_BV_ONELEVEL,
ACI_BV_SUBTREE,
ACI_BV_BR_ENTRY,
ACI_BV_BR_ALL,
ACI_BV_ACCESS_ID,
#if 0
ACI_BV_ANONYMOUS = BER_BVC("anonymous"),
#endif
ACI_BV_PUBLIC,
ACI_BV_USERS,
ACI_BV_SELF,
ACI_BV_DNATTR,
ACI_BV_GROUP,
ACI_BV_ROLE,
ACI_BV_SET,
ACI_BV_SET_REF,
ACI_BV_GRANT,
ACI_BV_DENY,
ACI_BV_IP_EQ,
#ifdef LDAP_PF_LOCAL
ACI_BV_PATH_EQ,
#if 0
ACI_BV_DIRSEP,
#endif
#endif /* LDAP_PF_LOCAL */
ACI_BV_GROUP_CLASS,
ACI_BV_GROUP_ATTR,
ACI_BV_ROLE_CLASS,
ACI_BV_ROLE_ATTR,
ACI_BV_SET_ATTR,
ACI_BV_LAST
};
/*
* Backend-info
* represents a backend