From: Pierangelo Masarati Date: Thu, 10 Nov 2005 00:52:43 +0000 (+0000) Subject: further isolation and cleanup of ACI code X-Git-Tag: OPENLDAP_REL_ENG_2_2_MP~49 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4537065ffc6fcf717175dd8355af8ee95a96c47b;p=openldap further isolation and cleanup of ACI code --- diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c index 7f23b4363b..e9e24985fe 100644 --- a/servers/slapd/aci.c +++ b/servers/slapd/aci.c @@ -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 : diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 8bff33752d..5b84f9e304 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -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 */ -int -acl_init( void ) -{ - int rc = 0; - +/* + * statically built-in dynamic ACL initialization + */ +static int (*acl_init_func[])( void ) = { #ifdef SLAPD_ACI_ENABLED #ifdef SLAP_DYNACL - rc = dynacl_aci_init(); + dynacl_aci_init, #else /* !SLAP_DYNACL */ - rc = aci_init(); + aci_init, #endif /* !SLAP_DYNACL */ - if ( rc != 0 ) { - return rc; - } #endif /* SLAPD_ACI_ENABLED */ - return rc; + NULL +}; + +int +acl_init( void ) +{ + int i, rc; + + for ( i = 0; acl_init_func[ i ] != NULL; i++ ) { + rc = (*(acl_init_func[ i ]))(); + if ( rc != 0 ) { + return rc; + } + } + + return 0; } int diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 533badad67..e8259a0959 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 )); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 489eb130b5..1d81e8abaa 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -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