]> git.sur5r.net Git - openldap/commitdiff
Deleted BackendInfo->bi_acl_attribute, bi_acl_group.
authorHoward Chu <hyc@openldap.org>
Wed, 26 Mar 2003 11:50:03 +0000 (11:50 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 26 Mar 2003 11:50:03 +0000 (11:50 +0000)
Replaced with bi_entry_get_rw.
Implemented for back-bdb, back-ldbm, back-ldap.

22 files changed:
servers/slapd/back-bdb/id2entry.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-dnssrv/init.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/external.h
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldbm/entry.c
servers/slapd/back-ldbm/external.h
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-meta/external.h
servers/slapd/back-meta/init.c
servers/slapd/back-monitor/init.c
servers/slapd/back-passwd/init.c
servers/slapd/back-perl/init.c
servers/slapd/back-shell/init.c
servers/slapd/back-sql/init.c
servers/slapd/backend.c
servers/slapd/proto-slap.h
servers/slapd/slap.h

index 6065491faa7d15934d296d7315a76f2661bb90f3..598ee76ce878549889127b977fa9519bed407da0 100644 (file)
@@ -267,3 +267,169 @@ int bdb_entry_release(
  
        return 0;
 }
+
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int bdb_entry_get(
+       BackendDB *be,
+       Connection *c,
+       Operation *op,
+       struct berval *ndn,
+       ObjectClass *oc,
+       AttributeDescription *at,
+       int rw,
+       Entry **ent )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       struct bdb_op_info *boi = NULL;
+       DB_TXN *txn = NULL;
+       Entry *e;
+       int     rc;
+       const char *at_name = at->ad_cname.bv_val;
+
+       u_int32_t       locker = 0;
+       DB_LOCK         lock;
+       int             free_lock_id = 0;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, ARGS, 
+               "bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 );
+       LDAP_LOG( BACK_BDB, ARGS, 
+               "bdb_entry_get: oc: \"%s\", at: \"%s\"\n",
+               oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#else
+       Debug( LDAP_DEBUG_ARGS,
+               "=> bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 ); 
+       Debug( LDAP_DEBUG_ARGS,
+               "=> bdb_entry_get: oc: \"%s\", at: \"%s\"\n",
+               oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#endif
+
+       if( op ) boi = (struct bdb_op_info *) op->o_private;
+       if( boi != NULL && be == boi->boi_bdb ) {
+               txn = boi->boi_txn;
+               locker = boi->boi_locker;
+       }
+
+       if ( txn != NULL ) {
+               locker = TXN_ID ( txn );
+       } else if ( !locker ) {
+               rc = LOCK_ID ( bdb->bi_dbenv, &locker );
+               free_lock_id = 1;
+               switch(rc) {
+               case 0:
+                       break;
+               default:
+                       return LDAP_OTHER;
+               }
+       }
+
+dn2entry_retry:
+       /* can we find entry */
+       rc = bdb_dn2entry_rw( be, txn, ndn, &e, NULL, 0, rw, locker, &lock );
+       switch( rc ) {
+       case DB_NOTFOUND:
+       case 0:
+               break;
+       case DB_LOCK_DEADLOCK:
+       case DB_LOCK_NOTGRANTED:
+               /* the txn must abort and retry */
+               if ( txn ) {
+                       boi->boi_err = rc;
+                       return LDAP_BUSY;
+               }
+               ldap_pvt_thread_yield();
+               goto dn2entry_retry;
+       default:
+               boi->boi_err = rc;
+               if ( free_lock_id ) {
+                       LOCK_ID_FREE( bdb->bi_dbenv, locker );
+               }
+               return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
+       }
+       if (e == NULL) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "bdb_entry_get: cannot find entry (%s)\n", 
+                       ndn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "=> bdb_entry_get: cannot find entry: \"%s\"\n",
+                               ndn->bv_val, 0, 0 ); 
+#endif
+               if ( free_lock_id ) {
+                       LOCK_ID_FREE( bdb->bi_dbenv, locker );
+               }
+               return LDAP_NO_SUCH_OBJECT; 
+       }
+       
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, DETAIL1, "bdb_entry_get: found entry (%s)\n",
+               ndn->bv_val, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_ACL,
+               "=> bdb_entry_get: found entry: \"%s\"\n",
+               ndn->bv_val, 0, 0 ); 
+#endif
+
+#ifdef BDB_ALIASES
+       /* find attribute values */
+       if( is_entry_alias( e ) ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "bdb_entry_get: entry (%s) is an alias\n", e->e_name.bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "<= bdb_entry_get: entry is an alias\n", 0, 0, 0 );
+#endif
+               rc = LDAP_ALIAS_PROBLEM;
+               goto return_results;
+       }
+#endif
+
+       if( is_entry_referral( e ) ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "bdb_entry_get: entry (%s) is a referral.\n", e->e_name.bv_val, 0, 0);
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "<= bdb_entry_get: entry is a referral\n", 0, 0, 0 );
+#endif
+               rc = LDAP_REFERRAL;
+               goto return_results;
+       }
+
+       if ( oc && !is_entry_objectclass( e, oc, 0 )) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "bdb_entry_get: failed to find objectClass.\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "<= bdb_entry_get: failed to find objectClass\n",
+                       0, 0, 0 ); 
+#endif
+               rc = LDAP_NO_SUCH_ATTRIBUTE;
+               goto return_results;
+       }
+
+return_results:
+       if( rc != LDAP_SUCCESS ) {
+               /* free entry */
+               bdb_cache_return_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, rw, &lock);
+       } else {
+               *ent = e;
+       }
+
+       if ( free_lock_id ) {
+               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, ENTRY, "bdb_entry_get: rc=%d\n", rc, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "bdb_entry_get: rc=%d\n",
+               rc, 0, 0 ); 
+#endif
+       return(rc);
+}
index 039934c474f5f1e9ae015add97a882a53fb202ad..c99c70a7bbfbafaf4e2194cc0a39d331deeb9ff6 100644 (file)
@@ -665,22 +665,11 @@ bdb_initialize(
 
        bi->bi_extended = bdb_extended;
 
-#if 1
-       /*
-        * these routines (and their callers) are not yet designed
-        * to work with transaction.  Using them may cause deadlock.
-        */
-       bi->bi_acl_group = bdb_group;
-       bi->bi_acl_attribute = bdb_attribute;
-#else
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
-#endif
-
        bi->bi_chk_referrals = bdb_referrals;
        bi->bi_operational = bdb_operational;
        bi->bi_has_subordinates = bdb_hasSubordinates;
        bi->bi_entry_release_rw = bdb_entry_release;
+       bi->bi_entry_get_rw = bdb_entry_get;
 
        /*
         * hooks for slap tools
index 8cb1ed580892a01d3cc4b1da07e3e72628cda732..87e6d414b872bf6f8b4ca4404e3613af485d7f68 100644 (file)
@@ -39,12 +39,6 @@ int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
 
 void bdb_attr_index_destroy LDAP_P(( Avlnode *tree ));
 
-/*
- * attribute.c
- */
-
-BI_acl_attribute bdb_attribute;
-
 /*
  * dbcache.c
  */
@@ -114,6 +108,7 @@ bdb_dn2idl(
  */
 int bdb_entry_return( Entry *e );
 BI_entry_release_rw bdb_entry_release;
+BI_entry_get_rw bdb_entry_get;
 
 /*
  * error.c
@@ -130,12 +125,6 @@ int bdb_filter_candidates(
        ID *tmp,
        ID *stack );
 
-/*
- * group.c
- */
-
-BI_acl_group bdb_group;
-
 /*
  * id2entry.c
  */
index 52bcd6658d2e6fab335f05e88e049e2d3f821732..adb99fc28254f1970e7c0f7dbcdabf3c0e394af0 100644 (file)
@@ -66,8 +66,6 @@ dnssrv_back_initialize(
        bi->bi_op_unbind = 0;
 
        bi->bi_extended = 0;
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
 
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = 0;
index ffe616e24b564c3111efc854fde66193c14c7487..68c4e2eeec9122828db0d22b4b3c2b801aa27454 100644 (file)
@@ -159,6 +159,9 @@ extern int suffix_massage_config( struct rewrite_info *info,
 extern int ldap_dnattr_rewrite( struct rewrite_info *rwinfo, BerVarray a_vals, void *cookie );
 #endif /* ENABLE_REWRITE */
 
+int ldap_build_entry( Backend *be, Connection *c, LDAPMessage *e, Entry *ent,
+        struct berval *bdn, int private );
+
 LDAP_END_DECL
 
 #endif /* SLAPD_LDAP_H */
index e12b6b5ecbdcca88003c32d65a9571913bd6be39..dd883376589099f54428bb3de5b9ebf0d345fc24 100644 (file)
@@ -39,9 +39,7 @@ extern BI_op_abandon  ldap_back_abandon;
 
 extern BI_op_extended  ldap_back_extended;
 
-extern BI_acl_group    ldap_back_group;
-
-extern BI_acl_attribute        ldap_back_attribute;
+extern BI_entry_get_rw ldap_back_entry_get;
 
 LDAP_END_DECL
 
index 5cffa2f67fcda0737d2d4368feb9310ae0d0e5b6..765660806ebd7953a4821e488f98fd350f5e785d 100644 (file)
@@ -89,9 +89,8 @@ ldap_back_initialize(
 
        bi->bi_extended = ldap_back_extended;
 
-       bi->bi_acl_group = ldap_back_group;
-       bi->bi_acl_attribute = ldap_back_attribute;
        bi->bi_chk_referrals = 0;
+       bi->bi_entry_get_rw = ldap_back_entry_get;
 
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = ldap_back_conn_destroy;
index 60232de30a34bc84497e48d6cf60e64617f2c09b..c68cb2469c9a01ebbdafcfb5bdfe539d923d56ee 100644 (file)
@@ -48,8 +48,9 @@
 #undef ldap_debug      /* silence a warning in ldap-int.h */
 #include "../../../libraries/libldap/ldap-int.h"
 
-static int ldap_send_entry( Backend *be, Operation *op, Connection *conn,
-                             LDAPMessage *e, AttributeName *attrs, int attrsonly );
+#include "lutil.h"
+
+static struct berval dummy = { 0, NULL };
 
 int
 ldap_back_search(
@@ -244,10 +245,26 @@ fail:;
                        ldap_pvt_thread_yield();
 
                } else if (rc == LDAP_RES_SEARCH_ENTRY) {
+                       Entry ent;
+                       struct berval bdn;
                        e = ldap_first_entry(lc->ld,res);
-                       if ( ldap_send_entry(be, op, conn, e, attrs, attrsonly) 
-                                       == LDAP_SUCCESS ) {
+                       if ( ldap_build_entry(be, conn, e, &ent, &bdn, 1) == LDAP_SUCCESS ) {
+                               Attribute *a;
                                count++;
+                               send_search_entry( be, conn, op, &ent, attrs,
+                                        attrsonly, NULL );
+                               while (ent.e_attrs) {
+                                       a = ent.e_attrs;
+                                       ent.e_attrs = a->a_next;
+                                       if (a->a_vals != &dummy)
+                                               ber_bvarray_free(a->a_vals);
+                                       ch_free(a);
+                               }
+                               
+                               if ( ent.e_dn && ( ent.e_dn != bdn.bv_val ) )
+                                       free( ent.e_dn );
+                               if ( ent.e_ndn )
+                                       free( ent.e_ndn );
                        }
                        ldap_msgfree(res);
 
@@ -381,26 +398,24 @@ finish:;
        return rc;
 }
 
-static int
-ldap_send_entry(
+int
+ldap_build_entry(
        Backend *be,
-       Operation *op,
        Connection *conn,
        LDAPMessage *e,
-       AttributeName *attrs,
-       int attrsonly
+       Entry *ent,
+       struct berval *bdn,
+       int private
 )
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
        struct berval a, mapped;
-       Entry ent;
        BerElement ber = *e->lm_ber;
        Attribute *attr, **attrp;
-       struct berval dummy = { 0, NULL };
-       struct berval *bv, bdn;
+       struct berval *bv;
        const char *text;
 
-       if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
+       if ( ber_scanf( &ber, "{m{", bdn ) == LBER_ERROR ) {
                return LDAP_DECODING_ERROR;
        }
 #ifdef ENABLE_REWRITE
@@ -409,20 +424,20 @@ ldap_send_entry(
         * Rewrite the dn of the result, if needed
         */
        switch ( rewrite_session( li->rwinfo, "searchResult",
-                               bdn.bv_val, conn, &ent.e_name.bv_val ) ) {
+                               bdn->bv_val, conn, &ent->e_name.bv_val ) ) {
        case REWRITE_REGEXEC_OK:
-               if ( ent.e_name.bv_val == NULL ) {
-                       ent.e_name = bdn;
+               if ( ent->e_name.bv_val == NULL ) {
+                       ent->e_name = *bdn;
                } else {
 #ifdef NEW_LOGGING
                        LDAP_LOG( BACK_LDAP, DETAIL1, 
                                "[rw] searchResult: \"%s\"" " -> \"%s\"\n", 
-                               bdn.bv_val, ent.e_dn, 0 );
+                               bdn->bv_val, ent->e_dn, 0 );
 #else /* !NEW_LOGGING */
                        Debug( LDAP_DEBUG_ARGS, "rw> searchResult: \"%s\""
-                                       " -> \"%s\"\n%s", bdn.bv_val, ent.e_dn, "" );
+                                       " -> \"%s\"\n%s", bdn->bv_val, ent->e_dn, "" );
 #endif /* !NEW_LOGGING */
-                       ent.e_name.bv_len = strlen( ent.e_name.bv_val );
+                       ent->e_name.bv_len = strlen( ent->e_name.bv_val );
                }
                break;
                
@@ -431,7 +446,7 @@ ldap_send_entry(
                return LDAP_OTHER;
        }
 #else /* !ENABLE_REWRITE */
-       ldap_back_dn_massage( li, &bdn, &ent.e_name, 0, 0 );
+       ldap_back_dn_massage( li, bdn, &ent->e_name, 0, 0 );
 #endif /* !ENABLE_REWRITE */
 
        /*
@@ -441,14 +456,14 @@ ldap_send_entry(
         * 
         * FIXME: should we log anything, or delegate to dnNormalize2?
         */
-       if ( dnNormalize2( NULL, &ent.e_name, &ent.e_nname ) != LDAP_SUCCESS ) {
+       if ( dnNormalize2( NULL, &ent->e_name, &ent->e_nname ) != LDAP_SUCCESS ) {
                return LDAP_INVALID_DN_SYNTAX;
        }
        
-       ent.e_id = 0;
-       ent.e_attrs = 0;
-       ent.e_private = 0;
-       attrp = &ent.e_attrs;
+       ent->e_id = 0;
+       ent->e_attrs = 0;
+       ent->e_private = 0;
+       attrp = &ent->e_attrs;
 
        while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
                ldap_back_map(&li->at_map, &a, &mapped, BACKLDAP_REMAP);
@@ -488,8 +503,13 @@ ldap_send_entry(
                         * Note: attr->a_vals can be null when using
                         * values result filter
                         */
-                       attr->a_vals = &dummy;
-
+                       if (private) {
+                               attr->a_vals = &dummy;
+                       } else {
+                               attr->a_vals = ch_malloc(sizeof(struct berval));
+                               attr->a_vals->bv_val = NULL;
+                               attr->a_vals->bv_len = 0;
+                       }
                } else if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
                        int             last;
@@ -602,19 +622,94 @@ next_attr:;
                *attrp = attr;
                attrp = &attr->a_next;
        }
-       send_search_entry( be, conn, op, &ent, attrs, attrsonly, NULL );
-       while (ent.e_attrs) {
-               attr = ent.e_attrs;
-               ent.e_attrs = attr->a_next;
-               if (attr->a_vals != &dummy)
-                       ber_bvarray_free(attr->a_vals);
-               ch_free(attr);
+       /* make sure it's free'able */
+       if (!private && ent->e_name.bv_val == bdn->bv_val)
+               ber_dupbv( &ent->e_name, bdn );
+       return LDAP_SUCCESS;
+}
+
+/* return 0 IFF we can retrieve the entry with ndn
+ */
+int
+ldap_back_entry_get(
+       Backend *be,
+       Connection *conn,
+       Operation *op,
+       struct berval   *ndn,
+       ObjectClass *oc,
+       AttributeDescription *at,
+       int rw,
+       Entry **ent
+)
+{
+       struct ldapinfo *li = (struct ldapinfo *) be->be_private;    
+       struct ldapconn *lc;
+       int rc = 1, is_oc;
+       struct berval mapped = { 0, NULL }, bdn;
+       LDAPMessage     *result = NULL, *e = NULL;
+       char *gattr[3];
+       char *filter;
+
+       ldap_back_map(&li->at_map, &at->ad_cname, &mapped, BACKLDAP_MAP);
+       if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
+               return 1;
        }
-       
-       if ( ent.e_dn && ( ent.e_dn != bdn.bv_val ) )
-               free( ent.e_dn );
-       if ( ent.e_ndn )
-               free( ent.e_ndn );
 
-       return LDAP_SUCCESS;
+       /* Tell getconn this is a privileged op */
+       is_oc = op->o_do_not_cache;
+       op->o_do_not_cache = 1;
+       lc = ldap_back_getconn(li, conn, op);
+       if ( !lc || !ldap_back_dobind(li, lc, NULL, op) ) {
+               op->o_do_not_cache = is_oc;
+               return 1;
+       }
+       op->o_do_not_cache = is_oc;
+
+       is_oc = (strcasecmp("objectclass", mapped.bv_val) == 0);
+       if (oc && !is_oc) {
+               gattr[0] = "objectclass";
+               gattr[1] = mapped.bv_val;
+               gattr[2] = NULL;
+       } else {
+               gattr[0] = mapped.bv_val;
+               gattr[1] = NULL;
+       }
+       if (oc) {
+               char *ptr;
+               filter = ch_malloc(sizeof("(objectclass=)" + oc->soc_cname.bv_len));
+               ptr = lutil_strcopy(filter, "(objectclass=");
+               ptr = lutil_strcopy(ptr, oc->soc_cname.bv_val);
+               *ptr++ = ')';
+               *ptr++ = '\0';
+       } else {
+               filter = "(objectclass=*)";
+       }
+               
+       if (ldap_search_ext_s(lc->ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
+                               gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+                               LDAP_NO_LIMIT, &result) != LDAP_SUCCESS)
+       {
+               goto cleanup;
+       }
+
+       if ((e = ldap_first_entry(lc->ld, result)) == NULL) {
+               goto cleanup;
+       }
+
+       *ent = ch_malloc(sizeof(Entry));
+
+       rc = ldap_build_entry(be, conn, e, *ent, &bdn, 0);
+
+       if (rc != LDAP_SUCCESS) {
+               ch_free(*ent);
+               *ent = NULL;
+       }
+
+cleanup:
+       if (result) {
+               ldap_msgfree(result);
+       }
+
+       return(rc);
 }
+
index 4c87512b32f52f9daa3523d44166e04db327274c..8ebf0ab2c5a089281fd74559661457a3d9573ba6 100644 (file)
@@ -43,3 +43,118 @@ ldbm_back_entry_release_rw(
 
        return 0;
 }
+
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int ldbm_back_entry_get(
+       BackendDB *be,
+       Connection *c,
+       Operation *op,
+       struct berval *ndn,
+       ObjectClass *oc,
+       AttributeDescription *at,
+       int rw,
+       Entry **ent )
+{
+       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+       Entry *e;
+       int     rc;
+       const char *at_name = at->ad_cname.bv_val;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, ARGS, 
+               "ldbm_back_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 );
+       LDAP_LOG( BACK_BDB, ARGS, 
+               "ldbm_back_entry_get: oc: \"%s\", at: \"%s\"\n",
+               oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#else
+       Debug( LDAP_DEBUG_ARGS,
+               "=> ldbm_back_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 ); 
+       Debug( LDAP_DEBUG_ARGS,
+               "=> ldbm_back_entry_get: oc: \"%s\", at: \"%s\"\n",
+               oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#endif
+
+       /* can we find entry */
+       e = dn2entry_rw( be, ndn, NULL, rw );
+       if (e == NULL) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "ldbm_back_entry_get: cannot find entry (%s)\n", 
+                       ndn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "=> ldbm_back_entry_get: cannot find entry: \"%s\"\n",
+                               ndn->bv_val, 0, 0 ); 
+#endif
+               return LDAP_NO_SUCH_OBJECT; 
+       }
+       
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, DETAIL1, "ldbm_back_entry_get: found entry (%s)\n",
+               ndn->bv_val, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_ACL,
+               "=> ldbm_back_entry_get: found entry: \"%s\"\n",
+               ndn->bv_val, 0, 0 ); 
+#endif
+
+#ifdef BDB_ALIASES
+       /* find attribute values */
+       if( is_entry_alias( e ) ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "ldbm_back_entry_get: entry (%s) is an alias\n", e->e_name.bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "<= ldbm_back_entry_get: entry is an alias\n", 0, 0, 0 );
+#endif
+               rc = LDAP_ALIAS_PROBLEM;
+               goto return_results;
+       }
+#endif
+
+       if( is_entry_referral( e ) ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "ldbm_back_entry_get: entry (%s) is a referral.\n", e->e_name.bv_val, 0, 0);
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "<= ldbm_back_entry_get: entry is a referral\n", 0, 0, 0 );
+#endif
+               rc = LDAP_REFERRAL;
+               goto return_results;
+       }
+
+       if ( oc && !is_entry_objectclass( e, oc, 0 )) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_BDB, INFO, 
+                       "ldbm_back_entry_get: failed to find objectClass.\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ACL,
+                       "<= ldbm_back_entry_get: failed to find objectClass\n",
+                       0, 0, 0 ); 
+#endif
+               rc = LDAP_NO_SUCH_ATTRIBUTE;
+               goto return_results;
+       }
+
+       rc = LDAP_SUCCESS;
+
+return_results:
+       if( rc != LDAP_SUCCESS ) {
+               /* free entry */
+               cache_return_entry_rw(&li->li_cache, e, rw);
+       } else {
+               *ent = e;
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, ENTRY, "ldbm_back_entry_get: rc=%d\n", rc, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "ldbm_back_entry_get: rc=%d\n",
+               rc, 0, 0 ); 
+#endif
+       return(rc);
+}
index 0f3107d85b8c7604bc4ef71851f6a3b89db9c5a7..d26999e4d090ecffb44bfcd41bca1b966070267f 100644 (file)
@@ -37,10 +37,6 @@ extern BI_op_add     ldbm_back_add;
 
 extern BI_op_delete    ldbm_back_delete;
 
-extern BI_acl_group    ldbm_back_group;
-
-extern BI_acl_attribute        ldbm_back_attribute;
-
 extern BI_operational  ldbm_back_operational;
 
 extern BI_has_subordinates     ldbm_back_hasSubordinates;
index cc023e8e18ece2f72b9f1c04073b6dfd19f897bd..26c411d1710dc25022c11842b995f19b7de073a9 100644 (file)
@@ -67,8 +67,7 @@ ldbm_back_initialize(
        bi->bi_extended = ldbm_back_extended;
 
        bi->bi_entry_release_rw = ldbm_back_entry_release_rw;
-       bi->bi_acl_group = ldbm_back_group;
-       bi->bi_acl_attribute = ldbm_back_attribute;
+       bi->bi_entry_get_rw = ldbm_back_entry_get;
        bi->bi_chk_referrals = ldbm_back_referrals;
        bi->bi_operational = ldbm_back_operational;
        bi->bi_has_subordinates = ldbm_back_hasSubordinates;
index dfd531629d3cf260a24f5b1dc597e8a462f6d8e1..de1709ad36d625aab948febf0688c1cf29469438 100644 (file)
@@ -97,6 +97,8 @@ int ldbm_back_entry_release_rw LDAP_P(( Backend *be,
        Connection *conn, Operation *op,
        Entry *e, int rw ));
 
+BI_entry_get_rw ldbm_back_entry_get;
+
 /*
  * filterindex.c
  */
index e37d552b8c6a61f51b2d3fcd8975bb6ea6e4273a..b9d3517ddbfd6ea317eccb592369e03b9701cc82 100644 (file)
@@ -88,9 +88,6 @@ extern BI_op_add      meta_back_add;
 extern BI_op_delete    meta_back_delete;
 extern BI_op_abandon   meta_back_abandon;
 
-extern BI_acl_group    meta_back_group;
-extern BI_acl_attribute        meta_back_attribute;
-
 LDAP_END_DECL
 
 #endif /* META_EXTERNAL_H */
index 1aa4054ed5fbc8124ffbbfb99e0d29e7ade342df..a0f7b4d943553c74da20d2e0b2cec529d7c1d363 100644 (file)
@@ -120,8 +120,6 @@ meta_back_initialize(
 
        bi->bi_extended = 0;
 
-       bi->bi_acl_group = meta_back_group;
-       bi->bi_acl_attribute = meta_back_attribute;
        bi->bi_chk_referrals = 0;
 
        bi->bi_connection_init = 0;
index 4c68e7491b76d12b5269bf8222703b4d1aa11593..770f8e0bf86fbc57fee39de6680c8b1a122dd3df 100644 (file)
@@ -211,8 +211,6 @@ monitor_back_initialize(
        bi->bi_extended = 0;
 
        bi->bi_entry_release_rw = 0;
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
        bi->bi_chk_referrals = 0;
        bi->bi_operational = monitor_back_operational;
 
index 1bb6ad284dfc5d9c0a6e99a9c8095cde519ef1e7..d0405b4143dd3e14c6f1fd47ee9184de117539a9 100644 (file)
@@ -57,8 +57,6 @@ passwd_back_initialize(
 
        bi->bi_extended = 0;
 
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
        bi->bi_chk_referrals = 0;
 
        bi->bi_connection_init = 0;
index 648ae715a90f507def5895c40b2e7d59e04c8b2f..e0f29ba3d48ba604c8498595c92967d8fc287ef8 100644 (file)
@@ -97,8 +97,6 @@ perl_back_initialize(
 
        bi->bi_extended = 0;
 
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
        bi->bi_chk_referrals = 0;
 
        bi->bi_connection_init = 0;
index cfbd8811c57ed517c80b1dc7f2920c676d7dbecf..cfb5357dd0ab17a2c51f2e7f695e5b1472755601 100644 (file)
@@ -57,8 +57,6 @@ shell_back_initialize(
 
        bi->bi_extended = 0;
 
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
        bi->bi_chk_referrals = 0;
 
        bi->bi_connection_init = 0;
index 826e5dd92a6524036fb7e31241f9d7e5ff690c89..a5402355f26dd6ba349e58f08d5336f34ef617ed 100644 (file)
@@ -83,8 +83,6 @@ sql_back_initialize(
        bi->bi_op_add = backsql_add;
        bi->bi_op_delete = backsql_delete;
        
-       bi->bi_acl_group = 0;
-       bi->bi_acl_attribute = 0;
        bi->bi_chk_referrals = 0;
        bi->bi_operational = backsql_operational;
  
index 637a1dfc31559ca78458fdecac31221459512ff0..c187574072cd90b33fdee6d7a2b62a334a441517 100644 (file)
@@ -1080,6 +1080,31 @@ int backend_check_referrals(
        return rc;
 }
 
+int
+be_entry_get_rw(
+       Backend *be,
+       Connection *conn,
+       Operation *op,
+       struct berval *ndn,
+       ObjectClass *oc,
+       AttributeDescription *at,
+       int rw,
+       Entry **e )
+{
+       be = select_backend( ndn, 0, 0 );
+
+       if (be == NULL) {
+                       return LDAP_NO_SUCH_OBJECT;
+       }
+
+       if ( be->be_fetch ) {
+               return be->be_fetch( be, conn, op, ndn,
+                       oc, at, rw, e );
+       }
+
+       return LDAP_UNWILLING_TO_PERFORM;
+}
+
 int 
 backend_group(
        Backend *be,
@@ -1092,20 +1117,13 @@ backend_group(
        AttributeDescription *group_at
 )
 {
+       Entry *e;
+       Attribute *a;
+       int i, j, rc;
        GroupAssertion *g;
 
        if ( op->o_abandon ) return SLAPD_ABANDON;
 
-       if ( !dn_match( &target->e_nname, gr_ndn ) ) {
-               /* we won't attempt to send it to a different backend */
-               
-               be = select_backend( gr_ndn, 0, 0 );
-
-               if (be == NULL) {
-                       return LDAP_NO_SUCH_OBJECT;
-               }
-       } 
-
        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
        for (g = conn->c_groups; g; g=g->ga_next) {
@@ -1122,29 +1140,48 @@ backend_group(
                return g->ga_res;
        }
 
-       if( be->be_group ) {
-               int res = be->be_group( be, conn, op,
-                       target, gr_ndn, op_ndn,
-                       group_oc, group_at );
-               
-               if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) {
-                       g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len);
-                       g->ga_be = be;
-                       g->ga_oc = group_oc;
-                       g->ga_at = group_at;
-                       g->ga_res = res;
-                       g->ga_len = gr_ndn->bv_len;
-                       strcpy(g->ga_ndn, gr_ndn->bv_val);
-                       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
-                       g->ga_next = conn->c_groups;
-                       conn->c_groups = g;
-                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+       if ( target && dn_match( &target->e_nname, gr_ndn ) ) {
+               e = target;
+       } else {
+               rc = be_entry_get_rw(be, conn, op, gr_ndn, group_oc, group_at,
+                       0, &e );
+       }
+       if ( e ) {
+               a = attr_find( e->e_attrs, group_at );
+               if ( a ) {
+#ifdef SLAP_NVALUES
+                       rc = value_find_ex( group_at,
+                               SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+                               SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+                               a->a_nvals, op_ndn );
+#else
+                       rc = value_find_ex( group_at, 0, a->a_vals, op_ndn );
+#endif
+               } else {
+                       rc = LDAP_NO_SUCH_ATTRIBUTE;
                }
+               if (e != target ) {
+                       be_entry_release_r( be, conn, op, e );
+               }
+       } else {
+               rc = LDAP_NO_SUCH_OBJECT;
+       }
 
-               return res;
+       if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) {
+               g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len);
+               g->ga_be = be;
+               g->ga_oc = group_oc;
+               g->ga_at = group_at;
+               g->ga_res = rc;
+               g->ga_len = gr_ndn->bv_len;
+               strcpy(g->ga_ndn, gr_ndn->bv_val);
+               ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+               g->ga_next = conn->c_groups;
+               conn->c_groups = g;
+               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
        }
 
-       return LDAP_UNWILLING_TO_PERFORM;
+       return rc;
 }
 
 int 
@@ -1158,22 +1195,71 @@ backend_attribute(
        BerVarray *vals
 )
 {
-       if ( target == NULL || !dn_match( &target->e_nname, edn ) ) {
-               /* we won't attempt to send it to a different backend */
-               
-               be = select_backend( edn, 0, 0 );
+       Entry *e;
+       Attribute *a;
+       int i, j, rc;
+       AccessControlState acl_state = ACL_STATE_INIT;
 
-               if (be == NULL) {
-                       return LDAP_NO_SUCH_OBJECT;
-               }
+       if ( target && dn_match( &target->e_nname, edn ) ) {
+               e = target;
+       } else {
+               rc = be_entry_get_rw(be, conn, op, edn, NULL, entry_at,
+                       0, &e );
+               if ( rc != LDAP_SUCCESS ) return rc;
        } 
 
-       if( be->be_attribute ) {
-               return be->be_attribute( be, conn, op, target, edn,
-                       entry_at, vals );
+       if ( e ) {
+               a = attr_find( e->e_attrs, entry_at );
+               if ( a ) {
+                       BerVarray v;
+
+                       if ( conn && op && access_allowed( be,
+                               conn, op, e, entry_at, NULL, ACL_AUTH,
+                               &acl_state ) == 0 ) {
+                               rc = LDAP_INSUFFICIENT_ACCESS;
+                               goto freeit;
+                       }
+
+                       for ( i=0; a->a_vals[i].bv_val; i++ ) ;
+                       
+                       v = ch_malloc( sizeof(struct berval) * (i+1) );
+                       for ( i=0,j=0; a->a_vals[i].bv_val; i++ ) {
+                               if ( conn && op && access_allowed( be,
+                                       conn, op, e, entry_at,
+#ifdef SLAP_NVALUES
+                                       &a->a_nvals[i],
+#else
+                                       &a->a_vals[i],
+#endif
+                                       ACL_AUTH, &acl_state ) == 0 ) {
+                                       continue;
+                               }
+                               ber_dupbv( &v[j],
+#ifdef SLAP_NVALUES
+                                       &a->a_nvals[i]
+#else
+                                       &a->a_vals[i]
+#endif
+                                       );
+                               if (v[j].bv_val ) j++;
+                       }
+                       if (j == 0) {
+                               ch_free( v );
+                               *vals = NULL;
+                               rc = LDAP_INSUFFICIENT_ACCESS;
+                       } else {
+                               v[j].bv_val = NULL;
+                               v[j].bv_len = 0;
+                               *vals = v;
+                               rc = LDAP_SUCCESS;
+                       }
+               }
+freeit:                if (e != target ) {
+                       be_entry_release_r( be, conn, op, e );
+               }
        }
 
-       return LDAP_UNWILLING_TO_PERFORM;
+       return rc;
 }
 
 Attribute *backend_operational(
index a3b75fd30570cba0e3965ba4a2ac3dc4b4ffcebe..94e0606ce5f0df85d35ee18c6bd0046b0e30d34a 100644 (file)
@@ -208,6 +208,10 @@ LDAP_SLAPD_F (int) be_isroot_pw LDAP_P(( Backend *be,
        Connection *conn, struct berval *ndn, struct berval *cred ));
 LDAP_SLAPD_F (int) be_isupdate LDAP_P(( Backend *be, struct berval *ndn ));
 LDAP_SLAPD_F (struct berval *) be_root_dn LDAP_P(( Backend *be ));
+LDAP_SLAPD_F (int) be_entry_get_rw LDAP_P(( BackendDB *bd,
+               struct slap_conn *c, struct slap_op *o,
+               struct berval *ndn, ObjectClass *oc,
+               AttributeDescription *at, int rw, Entry **e ));
 LDAP_SLAPD_F (int) be_entry_release_rw LDAP_P((
        BackendDB *be, Connection *c, Operation *o, Entry *e, int rw ));
 #define be_entry_release_r( be, c, o, e ) be_entry_release_rw( be, c, o, e, 0 )
index 7aa3353bd4d8cd37fa6a942e867971f86b644e13..76c3989071c1803acb504e53a14eac3502924f0a 100644 (file)
@@ -1301,6 +1301,7 @@ struct slap_backend_db {
 
 #define                be_extended     bd_info->bi_extended
 
+#define                be_fetch        bd_info->bi_entry_get_rw
 #define                be_release      bd_info->bi_entry_release_rw
 #define                be_chk_referrals        bd_info->bi_chk_referrals
 #define                be_group        bd_info->bi_acl_group
@@ -1542,6 +1543,12 @@ typedef int (BI_op_extended) LDAP_P((
        const char **   text,
        BerVarray *refs ));
 
+typedef int (BI_entry_get_rw) LDAP_P((BackendDB *bd,
+               struct slap_conn *c, struct slap_op *o,
+               struct berval *ndn, ObjectClass *oc,
+               AttributeDescription *at, int rw,
+               Entry **e ));
+
 typedef int (BI_entry_release_rw) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
                Entry *e, int rw));
@@ -1550,21 +1557,7 @@ typedef int (BI_chk_referrals) LDAP_P((BackendDB *bd,
                struct slap_conn *c, struct slap_op *o,
                struct berval *dn, struct berval *ndn,
                const char **text ));
-
-typedef int (BI_acl_group)  LDAP_P((Backend *bd,
-               struct slap_conn *c, struct slap_op *o,
-               Entry *e,
-               struct berval *bdn,
-               struct berval *edn,
-               ObjectClass *group_oc,
-               AttributeDescription *group_at ));
-
-typedef int (BI_acl_attribute)  LDAP_P((Backend *bd,
-               struct slap_conn *c, struct slap_op *o,
-               Entry *e, struct berval *edn,
-               AttributeDescription *entry_at,
-               BerVarray *vals ));
-
+               
 typedef int (BI_operational)  LDAP_P((Backend *bd,
                struct slap_conn *c, struct slap_op *o,
                Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
@@ -1660,12 +1653,10 @@ struct slap_backend_info {
        BI_op_extended  *bi_extended;
 
        /* Auxilary Functions */
+       BI_entry_get_rw         *bi_entry_get_rw;
        BI_entry_release_rw     *bi_entry_release_rw;
        BI_chk_referrals        *bi_chk_referrals;
 
-       BI_acl_group    *bi_acl_group;
-       BI_acl_attribute        *bi_acl_attribute;
-
        BI_operational  *bi_operational;
        BI_has_subordinates     *bi_has_subordinates;