]> git.sur5r.net Git - openldap/commitdiff
further isolation and cleanup of ACI code
authorPierangelo Masarati <ando@openldap.org>
Thu, 10 Nov 2005 00:52:43 +0000 (00:52 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 10 Nov 2005 00:52:43 +0000 (00:52 +0000)
servers/slapd/aci.c
servers/slapd/acl.c
servers/slapd/proto-slap.h
servers/slapd/slap.h

index 7f23b4363b3cc89f2d71d9636b5ae244efe0cef7..e9e24985fe6a669d394054a0c7903a9844cbf085 100644 (file)
 
 #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 :
index 8bff33752d108dea7ca3b293c0c40c5034bb33e9..5b84f9e3045225dffff4faf4f8a8c9fa63fdf41d 100644 (file)
 
 #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
index 533badad67379d19b9585f0f3d2214386910ae31..e8259a095959d80730b8340bbc43468e448637a5 100644 (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 ));
index 489eb130b53689bade2e2ffbe1c3eb4a930e4679..1d81e8abaa2c559b8fb37669f16a1359a3f197c8 100644 (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