mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-28 10:39:34 -05:00
further isolation and cleanup of ACI code
This commit is contained in:
parent
cbdaf8058f
commit
4537065ffc
4 changed files with 150 additions and 144 deletions
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue