]> git.sur5r.net Git - openldap/commitdiff
Add bdb_add() and supporting routines
authorKurt Zeilenga <kurt@openldap.org>
Fri, 22 Sep 2000 06:46:32 +0000 (06:46 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 22 Sep 2000 06:46:32 +0000 (06:46 +0000)
servers/slapd/back-bdb/add.c [new file with mode: 0644]
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/backbdb.dsp
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/error.c
servers/slapd/back-bdb/id2entry.c [new file with mode: 0644]
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/nextid.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c

diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c
new file mode 100644 (file)
index 0000000..f59e5aa
--- /dev/null
@@ -0,0 +1,237 @@
+/* add.c - ldap BerkeleyDB back-end add routine */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+
+#include "back-bdb.h"
+
+int
+bdb_add(
+       Backend *be,
+       Connection      *conn,
+       Operation       *op,
+       Entry   *e )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       char            *pdn = NULL;
+       Entry           *p = NULL;
+       int                     rootlock = 0;
+       int                     rc; 
+       const char      *text = NULL;
+       AttributeDescription *children = slap_schema.si_ad_children;
+       DB_TXN          *ltid = NULL;
+
+
+       Debug(LDAP_DEBUG_ARGS, "==> bdb_add: %s\n", e->e_dn, 0, 0);
+
+       /* check entry's schema */
+       rc = entry_schema_check( e, NULL, &text );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_add: entry failed schema check: %s (%d)\n",
+                       text, rc, 0 );
+               goto return_results;
+       }
+
+       /*
+        * acquire an ID outside of the operation transaction
+        * to avoid serializing adds.
+        */
+       rc = bdb_next_id( be, NULL, &e->e_id );
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_add: next_id failed (%d)\n",
+                       rc, 0, 0 );
+               rc = LDAP_OTHER;
+               text = "internal error";
+               goto return_results;
+       }
+
+       /* begin transaction */
+       rc = txn_begin( bdb->bi_dbenv, NULL, &ltid, 0 );
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_add: txn_begin failed: %s (%d)\n",
+                       db_strerror(rc), rc, 0 );
+               rc = LDAP_OTHER;
+               text = "internal error";
+               goto return_results;
+       }
+       
+       /*
+        * Get the parent dn and see if the corresponding entry exists.
+        * If the parent does not exist, only allow the "root" user to
+        * add the entry.
+        */
+       pdn = dn_parent( be, e->e_ndn );
+
+       if( pdn != NULL && *pdn != '\0' ) {
+               Entry *matched = NULL;
+
+               /* get parent with reader lock */
+               p = dn2entry_r( be, ltid, pdn, &matched );
+               if ( p == NULL ) {
+                       char *matched_dn;
+                       struct berval **refs;
+
+                       ch_free( pdn );
+
+                       if ( matched != NULL ) {
+                               matched_dn = ch_strdup( matched->e_dn );
+                               refs = is_entry_referral( matched )
+                                       ? get_entry_referrals( be, conn, op, matched )
+                                       : NULL;
+                               bdb_entry_return( be, matched );
+
+                       } else {
+                               matched_dn = NULL;
+                               refs = default_referral;
+                       }
+
+                       Debug( LDAP_DEBUG_TRACE, "bdb_add: parent does not exist\n",
+                               0, 0, 0 );
+
+                       send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+                           matched_dn, NULL, refs, NULL );
+
+                       if( matched != NULL ) {
+                               ber_bvecfree( refs );
+                               ch_free( matched_dn );
+                       }
+
+                       goto done;
+               }
+
+               ch_free(pdn);
+
+               if ( ! access_allowed( be, conn, op, p,
+                       children, NULL, ACL_WRITE ) )
+               {
+                       Debug( LDAP_DEBUG_TRACE, "bdb_add: no write access to parent\n",
+                               0, 0, 0 );
+                       rc = LDAP_INSUFFICIENT_ACCESS;
+                       text = "no write access to parent", NULL, NULL;
+                       goto return_results;;
+               }
+
+               if ( is_entry_alias( p ) ) {
+                       /* parent is an alias, don't allow add */
+                       Debug( LDAP_DEBUG_TRACE, "bdb_add: parent is alias\n",
+                               0, 0, 0 );
+                       rc = LDAP_ALIAS_PROBLEM;
+                       text = "parent is an alias";
+                       goto return_results;;
+               }
+
+               if ( is_entry_referral( p ) ) {
+                       /* parent is a referral, don't allow add */
+                       char *matched_dn = ch_strdup( p->e_dn );
+                       struct berval **refs = is_entry_referral( p )
+                               ? get_entry_referrals( be, conn, op, p )
+                               : NULL;
+
+                       Debug( LDAP_DEBUG_TRACE, "bdb_add: parent is referral\n",
+                               0, 0, 0 );
+
+                       send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+                           matched_dn, NULL, refs, NULL );
+
+                       ber_bvecfree( refs );
+                       free( matched_dn );
+                       goto done;
+               }
+
+       } else {
+               if( pdn != NULL ) {
+                       free(pdn);
+               }
+
+               /*
+                * no parent!
+                *      must be adding entry to at suffix
+                *  or with parent ""
+                */
+               if ( !be_isroot( be, op->o_ndn )) {
+                       Debug( LDAP_DEBUG_TRACE, "bdb_add: %s denied\n",
+                               pdn == NULL ? "suffix" : "entry at root",
+                               0, 0 );
+                       rc = LDAP_INSUFFICIENT_ACCESS;
+                       goto return_results;
+               }
+       }
+
+       /* dn2id index */
+       rc = bdb_dn2id_add( be, ltid, e->e_ndn, e->e_id );
+       if ( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE, "bdb_add: dn2id_add failed: %s (%d)\n",
+                       db_strerror(rc), rc, 0 );
+               if( rc == DB_KEYEXIST ) {
+                       rc = LDAP_ALREADY_EXISTS;
+               } else {
+                       rc = LDAP_OTHER;
+               }
+               goto return_results;
+       }
+
+       /* id2entry index */
+       rc = bdb_id2entry_add( be, ltid, e );
+       if ( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE, "bdb_add: id2entry_add failed\n",
+                       0, 0, 0 );
+               rc = LDAP_OTHER;
+               text = "entry store failed";
+               goto return_results;
+       }
+
+#if 0
+       /* attribute indexes */
+       if ( index_entry_add( be, e, e->e_attrs ) != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "bdb_add: index_entry_add failed\n",
+                       0, 0, 0 );
+               rc = LDAP_OTHER;
+               text = "index generation failed";
+               goto return_results;
+       }
+#endif
+
+       rc = txn_commit( ltid, 0 );
+       ltid = NULL;
+
+       if( rc == 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_add: txn_commit failed: %s (%d)\n",
+                       db_strerror(rc), rc, 0 );
+               rc = LDAP_OTHER;
+               text = "commit failed";
+       } else {
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_add: added id=%08x dn=\"%s\"\n",
+                       e->e_id, e->e_dn, 0 );
+               rc = LDAP_SUCCESS;
+               text = NULL;
+       }
+
+return_results:
+       send_ldap_result( conn, op, rc,
+                       NULL, text, NULL, NULL );
+
+
+done:
+       if (p != NULL) {
+               /* free parent and writer lock */
+               bdb_entry_return( be, p ); 
+       }
+
+       if( ltid != NULL ) {
+               txn_abort( ltid );
+       }
+
+       return rc;
+}
index 7efbfcb4b72134f1a6979344bed519aad405c4bb..06361d7530cd0ea2cd37e519877c7cd92e87e1a9 100644 (file)
@@ -39,10 +39,10 @@ LDAP_BEGIN_DECL
 #define BDB_LG_SUBDIR  LDAP_DIRSEP "log"
 #define BDB_DATA_SUBDIR        LDAP_DIRSEP "data"
 
-#define BDB_NEXTID     0
-#define BDB_ENTRIES    1
-#define BDB_DN2ID      2
-#define BDB_INDICES    3
+#define BDB_NEXTID             0
+#define BDB_DN2ID              1
+#define BDB_ID2ENTRY   2
+#define BDB_INDICES            3
 
 struct bdb_db_info {
        DB                      *bdi_db;
@@ -61,7 +61,7 @@ struct bdb_info {
        struct bdb_db_info **bi_databases;
 };
 #define bi_nextid      bi_databases[BDB_NEXTID]
-#define bi_entries     bi_databases[BDB_ENTRIES]
+#define bi_id2entry    bi_databases[BDB_ID2ENTRY]
 #define bi_dn2id       bi_databases[BDB_DN2ID]
 
 LDAP_END_DECL
index cb8048b0483851352b8db3da978d58a13a3572ae..da06c6bec62383fc2d9c7f3ad8e84e0e3485168f 100644 (file)
@@ -147,6 +147,10 @@ SOURCE=.\external.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\id2entry.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\idl.c
 # End Source File
 # Begin Source File
index b0088495731f4fdb373d4304b1b542659cf12b81..1e0f0b6d7b841668ab2228d55049e6c8083d13da 100644 (file)
@@ -15,7 +15,7 @@
 #include "back-bdb.h"
 
 int
-bdb_index_dn_add(
+bdb_dn2id_add(
     Backend    *be,
        DB_TXN *txn,
     const char *dn,
index 56a6e0572b62eeecdcf17840aa3a77fc9f3ba123..aced7cf0dacf787b14ec54bbe6be56efcd9d4645 100644 (file)
@@ -10,7 +10,6 @@
 #include <stdio.h>
 
 #include <ac/string.h>
-#include <ac/socket.h>
 
 #include "slap.h"
 #include "back-bdb.h"
diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c
new file mode 100644 (file)
index 0000000..f613b91
--- /dev/null
@@ -0,0 +1,42 @@
+/* id2entry.c - routines to deal with the id2entry database */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+
+#include "back-bdb.h"
+
+int bdb_id2entry_add(
+       Backend *be,
+       DB_TXN *tid,
+       Entry *e )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       DBT key, data;
+       struct berval *bv;
+       int rc;
+
+       DBTzero( &key );
+       key.data = (char *) &e->e_id;
+       key.size = sizeof(ID);
+
+       rc = entry_encode( e, &bv );
+       if( rc != LDAP_SUCCESS ) {
+               return -1;
+       }
+
+       DBTzero( &data );
+       bv2DBT( bv, &data );
+
+       rc = bdb->bi_id2entry->bdi_db->put( bdb->bi_id2entry->bdi_db,
+               tid, &key, &data, DB_NOOVERWRITE );
+
+       ber_bvfree( bv );
+       return rc;
+}
index e1a36ed165c9bbfda451ef9f4c9012fb89604d2b..c3f2148ce5182ac687c8bb76d81f9de45c4c53d2 100644 (file)
@@ -8,9 +8,7 @@
 #include "portable.h"
 
 #include <stdio.h>
-
 #include <ac/string.h>
-#include <ac/socket.h>
 
 #include "back-bdb.h"
 
index 74d56e680186a5ecca2b6fcb460c5ec8d65886f6..c7f2d9d4e2cbefffbf64954019b8df10c7937c66 100644 (file)
@@ -8,9 +8,7 @@
 #include "portable.h"
 
 #include <stdio.h>
-
 #include <ac/string.h>
-#include <ac/socket.h>
 
 #include "back-bdb.h"
 
@@ -21,8 +19,8 @@ static struct bdbi_database {
        int flags;
 } bdbi_databases[BDB_INDICES] = {
        { "nextid", "nextid", DB_BTREE, 0 },
+       { "dn2entry", "dn2entry", DB_BTREE, 0 },
        { "id2entry", "id2entry", DB_BTREE, 0 },
-       { "dn2entry", "dn2entry", DB_BTREE, 0 }
 };
 
 static int
@@ -283,11 +281,11 @@ bdb_initialize(
 
        bi->bi_extended = bi_back_extended;
 
-       bi->bi_entry_release_rw = bi_back_entry_release_rw;
        bi->bi_acl_group = bi_back_group;
        bi->bi_acl_attribute = bi_back_attribute;
        bi->bi_chk_referrals = bi_back_referrals;
 #endif
+       bi->bi_entry_release_rw = 0;
 
        /*
         * hooks for slap tools
index acf15046c7694ddf4f9b764491b7f8e4e2d4ae6c..68f87b3fd9fd636c5178176b90f5d1f5698d8605 100644 (file)
@@ -8,9 +8,7 @@
 #include "portable.h"
 
 #include <stdio.h>
-
 #include <ac/string.h>
-#include <ac/socket.h>
 
 #include "back-bdb.h"
 
@@ -38,7 +36,7 @@ int bdb_next_id( BackendDB *be, DB_TXN *tid, ID *out )
        data.flags = DB_DBT_USERMEM;
 
        /* get exiting value (with write lock) */
-       rc = bdb->bi_entries->bdi_db->get( bdb->bi_nextid->bdi_db,
+       rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
                ltid, &key, &data, DB_RMW );
 
        if( rc == DB_NOTFOUND ) {
@@ -57,7 +55,7 @@ int bdb_next_id( BackendDB *be, DB_TXN *tid, ID *out )
        id++;
 
        /* store new value */
-       rc = bdb->bi_entries->bdi_db->put( bdb->bi_nextid->bdi_db,
+       rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db,
                ltid, &key, &data, 0 );
 
        *out = id;
index e87da339fc2587481ee524a093651ed35fcb47a7..1992fe6ed0fa3934a136577a8717cb559177e3a4 100644 (file)
@@ -9,7 +9,6 @@
 
 LDAP_BEGIN_DECL
 
-
 /*
  * alias.c
  */
@@ -29,7 +28,7 @@ Entry *bdb_deref_internal_r LDAP_P((
 /*
  * dn2id.c
  */
-int bdb_index_dn_add(
+int bdb_dn2id_add(
        BackendDB *be,
        DB_TXN *tid,
        const char *dn,
@@ -41,11 +40,24 @@ Entry * bdb_dn2entry_rw LDAP_P(( Backend *be, DB_TXN *tid,
 #define dn2entry_r(be, tid, dn, m) bdb_dn2entry_rw((be), (tid), (dn), (m), 0)
 #define dn2entry_w(be, tid, dn, m) bdb_dn2entry_rw((be), (tid), (dn), (m), 1)
 
+/*
+ * entry.c
+ */
+int bdb_entry_return( BackendDB *be, Entry *e );
+
 /*
  * error.c
  */
 void bdb_errcall( const char *pfx, char * msg );
 
+/*
+ * id2entry
+ */
+int bdb_id2entry_add(
+       Backend *be,
+       DB_TXN *tid,
+       Entry *e );
+
 /*
  * idl.c
  */
index 686fd9ff6ef011732a69194896de6e64b39b5388..11b96f3b9b7a9fedaa1c1dd7a974fbf22a913e01 100644 (file)
@@ -8,9 +8,7 @@
 #include "portable.h"
 
 #include <stdio.h>
-
 #include <ac/string.h>
-#include <ac/socket.h>
 
 #include "back-bdb.h"
 
@@ -23,8 +21,8 @@ int bdb_tool_entry_open(
        int rc;
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        
-       rc = bdb->bi_entries->bdi_db->cursor(
-               bdb->bi_entries->bdi_db, NULL, &cursor, 0 );
+       rc = bdb->bi_id2entry->bdi_db->cursor(
+               bdb->bi_id2entry->bdi_db, NULL, &cursor, 0 );
        if( rc != 0 ) {
                return NOID;
        }
@@ -109,29 +107,14 @@ ID bdb_tool_entry_put(
        int rc;
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        DB_TXN *tid;
-       DBT key, data;
-       struct berval *bv;
 
        assert( slapMode & SLAP_TOOL_MODE );
 
-       DBTzero( &key );
-       key.data = (char *) &e->e_id;
-       key.size = sizeof(ID);
-
-       rc = entry_encode( e, &bv );
-       if( rc != LDAP_SUCCESS ) {
-               return NOID;
-       }
-
-       DBTzero( &data );
-       bv2DBT( bv, &data );
-
        Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
                e->e_id, e->e_dn, 0 );
 
        rc = txn_begin( bdb->bi_dbenv, NULL, &tid, 0 );
        if( rc != 0 ) {
-               ber_bvfree( bv );
                return NOID;
        }
 
@@ -140,15 +123,14 @@ ID bdb_tool_entry_put(
                goto done;
        }
 
-       /* store it -- don't override */
-       rc = bdb->bi_entries->bdi_db->put( bdb->bi_entries->bdi_db,
-               tid, &key, &data, DB_NOOVERWRITE );
+       /* add dn2id indices */
+       rc = bdb_dn2id_add( be, tid, e->e_ndn, e->e_id );
        if( rc != 0 ) {
                goto done;
        }
 
-       /* add dn indices */
-       rc = bdb_index_dn_add( be, tid, e->e_ndn, e->e_id );
+       /* id2entry index */
+       rc = bdb_id2entry_add( be, tid, e );
        if( rc != 0 ) {
                goto done;
        }
@@ -161,8 +143,6 @@ ID bdb_tool_entry_put(
 #endif
 
 done:
-       ber_bvfree( bv );
-
        if( rc == 0 ) {
                rc = txn_commit( tid, 0 );
                if( rc != 0 ) {