mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
Add bdb_add() and supporting routines
This commit is contained in:
parent
2b82d4f486
commit
aaab54e142
237
servers/slapd/back-bdb/add.c
Normal file
237
servers/slapd/back-bdb/add.c
Normal file
@ -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, <id, 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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "back-bdb.h"
|
||||
|
||||
int
|
||||
bdb_index_dn_add(
|
||||
bdb_dn2id_add(
|
||||
Backend *be,
|
||||
DB_TXN *txn,
|
||||
const char *dn,
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <ac/socket.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "back-bdb.h"
|
||||
|
42
servers/slapd/back-bdb/id2entry.c
Normal file
42
servers/slapd/back-bdb/id2entry.c
Normal file
@ -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;
|
||||
}
|
@ -8,9 +8,7 @@
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <ac/socket.h>
|
||||
|
||||
#include "back-bdb.h"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 ) {
|
||||
|
Loading…
Reference in New Issue
Block a user