mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-18 21:26:29 -05:00
ITS#9463 cumulative fix for back-wt
- LDAP MODRDN handling - support paged response - add wt_extended - add config emit - wt_key_read() return WT_NOTFOUND if not found key. - add ext_candidates() - fix idlcache session name - fix warning - don't reuse idlcache cursor - set correct pid when modrdn with newsuperior - fix condition bug - fix send_search_entry() error handling - fix for referral handling - fix for readonly mode - fix sizelimit response - support modrdn - improve modify handling - clear ancestor idlcache - fix for multi-DIT - IMPORTANT CHANGES: Compatibility is broken with previous database table, please restore database from LDIF. - checking for scope=children - sort dn2idl result - fix cursor leak - support db_open with readonly mode - add wt_tool_entry_delete - initialize comp variable - support referrals - implement wt_tool_dn2id_get() and wt_tool_entry_modify() for slapadd -w - skip redundant scan, and more debug message - fix OID conflict with back-passwd - no need to close session, It may cause SEGV. - fixed wt_dn2entry for empty DN - support multiple database - Construct wiredtiger's config parameter. It allow multi line wtconfig settings - add idlcache - fix concurrent modification to a entry with multi values - prevent to add duplicate dn entry - suppress error message "search_near failed: WT_NOTFOUND" - update Debug statements - back-wt does not support subtree rename - fix for @ondra review - update slapd-wt.5 and warning for mode option - add back-wt test into test target - add scope checking
This commit is contained in:
parent
f19a1da188
commit
2aaaf98315
34 changed files with 2480 additions and 814 deletions
|
|
@ -33,6 +33,25 @@ A separate directory must be specified for each database.
|
|||
The default is
|
||||
.BR LOCALSTATEDIR/openldap\-data .
|
||||
.TP
|
||||
.BI idlcache \ <boolean>
|
||||
Use the in-memory idlcache. The default is true.
|
||||
.TP
|
||||
\fBindex \fR{\fI<attrlist>\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI<special>\fR]
|
||||
Specify the indexes to maintain for the given attribute (or
|
||||
list of attributes).
|
||||
Some attributes only support a subset of indexes.
|
||||
If only an \fI<attr>\fP is given, the indices specified for \fBdefault\fR
|
||||
are maintained.
|
||||
Note that setting a default does not imply that all attributes will be
|
||||
indexed. Also, for best performance, an
|
||||
.B eq
|
||||
index should always be configured for the
|
||||
.B objectClass
|
||||
attribute.
|
||||
.TP
|
||||
.BI mode \ <integer>
|
||||
back-wt does not support mode option. use umask instead.
|
||||
.TP
|
||||
\fBwtconfig \fR{\fBcreate\fR,\fBcache_size=512M\fR,\fBasync=(enabled)\fR}
|
||||
Specify configuration for wiredtiger, This parameter is pass to
|
||||
.BR wiredtiger_open (3).
|
||||
|
|
@ -52,19 +71,6 @@ maximum heap memory to allocate for the cache.
|
|||
asynchronous operations configuration options. disabled by default.
|
||||
.RE
|
||||
.RS
|
||||
.TP
|
||||
\fBindex \fR{\fI<attrlist>\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI<special>\fR]
|
||||
Specify the indexes to maintain for the given attribute (or
|
||||
list of attributes).
|
||||
Some attributes only support a subset of indexes.
|
||||
If only an \fI<attr>\fP is given, the indices specified for \fBdefault\fR
|
||||
are maintained.
|
||||
Note that setting a default does not imply that all attributes will be
|
||||
indexed. Also, for best performance, an
|
||||
.B eq
|
||||
index should always be configured for the
|
||||
.B objectClass
|
||||
attribute.
|
||||
|
||||
.SH ACCESS CONTROL
|
||||
The
|
||||
|
|
|
|||
|
|
@ -14,18 +14,18 @@
|
|||
## <http://www.OpenLDAP.org/license.html>.
|
||||
|
||||
SRCS = init.c tools.c config.c \
|
||||
add.c bind.c compare.c delete.c modify.c search.c \
|
||||
operational.c \
|
||||
add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
|
||||
extended.c operational.c \
|
||||
attr.c index.c key.c filterindex.c \
|
||||
dn2entry.c dn2id.c id2entry.c idl.c \
|
||||
nextid.c ctx.c
|
||||
nextid.c ctx.c cache.c
|
||||
|
||||
OBJS = init.lo tools.lo config.lo \
|
||||
add.lo bind.lo compare.lo delete.lo modify.lo search.lo \
|
||||
operational.lo \
|
||||
add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
|
||||
extended.lo operational.lo \
|
||||
attr.lo index.lo key.lo filterindex.lo \
|
||||
dn2entry.lo dn2id.lo id2entry.lo idl.lo \
|
||||
nextid.lo ctx.lo
|
||||
nextid.lo ctx.lo cache.lo
|
||||
|
||||
LDAP_INCDIR= ../../../include
|
||||
LDAP_LIBDIR= ../../../libraries
|
||||
|
|
|
|||
|
|
@ -34,20 +34,17 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
size_t textlen = sizeof textbuf;
|
||||
AttributeDescription *children = slap_schema.si_ad_children;
|
||||
AttributeDescription *entry = slap_schema.si_ad_entry;
|
||||
ID eid;
|
||||
int num_retries = 0;
|
||||
int success;
|
||||
ID eid = NOID;
|
||||
LDAPControl **postread_ctrl = NULL;
|
||||
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
|
||||
int num_ctrls = 0;
|
||||
wt_ctx *wc;
|
||||
Entry *e = NULL;
|
||||
Entry *p = NULL;
|
||||
ID pid;
|
||||
ID pid = NOID;
|
||||
int rc;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_add) ": %s\n",
|
||||
op->ora_e->e_name.bv_val );
|
||||
Debug( LDAP_DEBUG_ARGS, "==> wt_add: %s\n", op->ora_e->e_name.bv_val );
|
||||
|
||||
ctrls[num_ctrls] = 0;
|
||||
|
||||
|
|
@ -57,8 +54,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": entry failed schema check: %s (%d)\n",
|
||||
"wt_add: entry failed schema check: %s (%d)\n",
|
||||
rs->sr_text, rs->sr_err );
|
||||
goto return_results;
|
||||
}
|
||||
|
|
@ -68,8 +64,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": entry failed op attrs add: %s (%d)\n",
|
||||
"wt_add: entry failed op attrs add: %s (%d)\n",
|
||||
rs->sr_text, rs->sr_err );
|
||||
goto return_results;
|
||||
}
|
||||
|
|
@ -97,9 +92,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": wt_ctx_get failed\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_add: wt_ctx_get failed\n" );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
send_ldap_result( op, rs );
|
||||
|
|
@ -117,9 +110,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
default:
|
||||
/* TODO: retry handling */
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": error at wt_dn2entry() rc=%d\n",
|
||||
rc );
|
||||
"wt_add: error at wt_dn2entry() rc=%d\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
|
|
@ -133,9 +124,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": error at wt_dn2pentry() rc=%d\n",
|
||||
rc );
|
||||
"wt_add: error at wt_dn2pentry() rc=%d\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
|
|
@ -156,9 +145,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
rs->sr_ref = NULL;
|
||||
}
|
||||
p = NULL;
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": parent "
|
||||
"does not exist\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: parent does not exist\n" );
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
goto return_results;
|
||||
|
|
@ -173,8 +160,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
*/
|
||||
p = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": no write access to parent\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: no write access to parent\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
rs->sr_text = "no write access to parent";
|
||||
goto return_results;;
|
||||
|
|
@ -185,8 +171,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
wt_entry_return( p );
|
||||
p = NULL;
|
||||
/* parent is a subentry, don't allow add */
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": parent is subentry\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: parent is subentry\n" );
|
||||
rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
|
||||
rs->sr_text = "parent is a subentry";
|
||||
goto return_results;;
|
||||
|
|
@ -196,8 +181,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
wt_entry_return( p );
|
||||
p = NULL;
|
||||
/* parent is an alias, don't allow add */
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": parent is alias\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: parent is alias\n" );
|
||||
rs->sr_err = LDAP_ALIAS_PROBLEM;
|
||||
rs->sr_text = "parent is an alias";
|
||||
goto return_results;;
|
||||
|
|
@ -213,8 +197,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
ber_bvarray_free( ref );
|
||||
wt_entry_return( p );
|
||||
p = NULL;
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": parent is referral\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: parent is referral\n" );
|
||||
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
|
|
@ -261,8 +244,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
entry, NULL, ACL_WADD, NULL );
|
||||
|
||||
if ( ! rs->sr_err ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": no write access to entry\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: no write access to entry\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
rs->sr_text = "no write access to entry";
|
||||
goto return_results;
|
||||
|
|
@ -272,33 +254,29 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
* Check ACL for attribute write access
|
||||
*/
|
||||
if (!acl_check_modlist(op, op->ora_e, op->ora_modlist)) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": no write access to attribute\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: no write access to attribute\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
rs->sr_text = "no write access to attribute";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
rc = wc->session->begin_transaction(wc->session, "isolation=read-uncommitted");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "begin_transaction failed";
|
||||
goto return_results;
|
||||
}
|
||||
Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(wt_add) ": session id: %p\n",
|
||||
wc->session );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_add: session id: %p\n", wc->session );
|
||||
|
||||
wt_next_id( op->o_bd, &eid );
|
||||
op->ora_e->e_id = eid;
|
||||
|
||||
rc = wt_dn2id_add( op, wc->session, pid, op->ora_e );
|
||||
rc = wt_dn2id_add( op, wc, pid, op->ora_e );
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": dn2id_add failed: %s (%d)\n",
|
||||
"wt_add: dn2id_add failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
switch( rc ) {
|
||||
case WT_DUPLICATE_KEY:
|
||||
|
|
@ -311,11 +289,10 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
goto return_results;
|
||||
}
|
||||
|
||||
rc = wt_id2entry_add( op, wc->session, op->ora_e );
|
||||
rc = wt_id2entry_add( op, wc, op->ora_e );
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": id2entry_add failed: %s (%d)\n",
|
||||
"wt_add: id2entry_add failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
if ( rc == LDAP_ADMINLIMIT_EXCEEDED ) {
|
||||
rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
|
||||
|
|
@ -332,8 +309,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
rc = wt_index_entry_add( op, wc, op->ora_e );
|
||||
if ( rc ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_add)
|
||||
": index add failed: %s (%d)\n",
|
||||
"<== wt_add: index add failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "index add failed";
|
||||
|
|
@ -344,8 +320,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_add)
|
||||
": commit_transaction failed: %s (%d)\n",
|
||||
"<== wt_add: commit_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "commit_transaction failed";
|
||||
|
|
@ -363,9 +338,7 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
if ( slap_read_controls( op, rs, op->ora_e,
|
||||
&slap_post_read_bv, postread_ctrl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<=- " LDAP_XSTRING(wt_add) ": post-read "
|
||||
"failed!\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "<=- wt_add: post-read failed!\n" );
|
||||
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
|
||||
/* FIXME: is it correct to abort
|
||||
* operation if control fails? */
|
||||
|
|
@ -375,12 +348,11 @@ wt_add( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": added%s id=%08lx dn=\"%s\"\n",
|
||||
"wt_add: added%s id=%08lx dn=\"%s\"\n",
|
||||
op->o_noop ? " (no-op)" : "",
|
||||
op->ora_e->e_id, op->ora_e->e_dn );
|
||||
|
||||
return_results:
|
||||
success = rs->sr_err;
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
slap_graduate_commit_csn( op );
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "back-wt.h"
|
||||
#include "slap-config.h"
|
||||
#include "lutil.h"
|
||||
|
||||
/* Find the ad, return -1 if not found,
|
||||
* set point for insertion if ins is non-NULL
|
||||
|
|
@ -57,7 +58,7 @@ wt_attr_slot( struct wt_info *wi, AttributeDescription *ad, int *ins )
|
|||
static int
|
||||
ainfo_insert( struct wt_info *wi, AttrInfo *a )
|
||||
{
|
||||
int x;
|
||||
int x = INT_MAX;
|
||||
int i = wt_attr_slot( wi, a->ai_desc, &x );
|
||||
|
||||
/* Is it a dup? */
|
||||
|
|
@ -357,6 +358,44 @@ done:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
wt_attr_index_unparser( void *v1, void *v2 )
|
||||
{
|
||||
AttrInfo *ai = v1;
|
||||
BerVarray *bva = v2;
|
||||
struct berval bv;
|
||||
char *ptr;
|
||||
|
||||
slap_index2bvlen( ai->ai_indexmask, &bv );
|
||||
if ( bv.bv_len ) {
|
||||
bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1;
|
||||
ptr = ch_malloc( bv.bv_len+1 );
|
||||
bv.bv_val = lutil_strcopy(ptr,
|
||||
(const char*)ai->ai_desc->ad_cname.bv_val );
|
||||
*bv.bv_val++ = ' ';
|
||||
slap_index2bv( ai->ai_indexmask, &bv );
|
||||
bv.bv_val = ptr;
|
||||
ber_bvarray_add( bva, &bv );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static AttributeDescription addef = { NULL, NULL, BER_BVC("default") };
|
||||
static AttrInfo aidef = { &addef };
|
||||
|
||||
void
|
||||
wt_attr_index_unparse( struct wt_info *wi, BerVarray *bva )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( wi->wi_defaultmask ) {
|
||||
aidef.ai_indexmask = wi->wi_defaultmask;
|
||||
wt_attr_index_unparser( &aidef, bva );
|
||||
}
|
||||
for ( i=0; i<wi->wi_nattrs; i++ )
|
||||
wt_attr_index_unparser( wi->wi_attrs[i], bva );
|
||||
}
|
||||
|
||||
void
|
||||
wt_attr_info_free( AttrInfo *ai )
|
||||
{
|
||||
|
|
@ -377,8 +416,6 @@ wt_attr_index_destroy( struct wt_info *wi )
|
|||
free( wi->wi_attrs );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
|
|
|
|||
|
|
@ -33,10 +33,13 @@
|
|||
/* The default search IDL stack cache depth */
|
||||
#define DEFAULT_SEARCH_STACK_DEPTH 16
|
||||
|
||||
#define WT_CONFIG_MAX 2048
|
||||
|
||||
struct wt_info {
|
||||
WT_CONNECTION *wi_conn;
|
||||
char *wi_dbenv_home;
|
||||
char *wi_dbenv_config;
|
||||
WT_CONNECTION *wi_cache;
|
||||
char *wi_home;
|
||||
char *wi_config;
|
||||
ID wi_lastid;
|
||||
|
||||
slap_mask_t wi_defaultmask;
|
||||
|
|
@ -53,23 +56,41 @@ struct wt_info {
|
|||
#define WT_DEL_INDEX 0x08
|
||||
#define WT_RE_OPEN 0x10
|
||||
#define WT_NEED_UPGRADE 0x20
|
||||
#define WT_USE_IDLCACHE 0x40
|
||||
};
|
||||
|
||||
#define WT_TABLE_ID2ENTRY "table:id2entry"
|
||||
#define WT_TABLE_DN2ID "table:dn2id"
|
||||
|
||||
#define WT_INDEX_DN "index:id2entry:dn"
|
||||
#define WT_INDEX_NDN "index:dn2id:ndn"
|
||||
#define WT_INDEX_PID "index:dn2id:pid"
|
||||
/* Currently, revdn is primary key, the revdn index is obsolete. */
|
||||
#define WT_INDEX_REVDN "index:dn2id:revdn"
|
||||
|
||||
/* table for cache */
|
||||
#define WT_TABLE_IDLCACHE "table:idlcache"
|
||||
|
||||
#define ITEMzero(item) (memset((item), 0, sizeof(WT_ITEM)))
|
||||
#define ITEM2bv(item,bv) ((bv)->bv_val = (item)->data, \
|
||||
(bv)->bv_len = (item)->size)
|
||||
#define bv2ITEM(bv,item) ((item)->data = (bv)->bv_val, \
|
||||
(item)->size = (bv)->bv_len )
|
||||
|
||||
#define WT_INDEX_CACHE_SIZE 1024
|
||||
|
||||
typedef struct {
|
||||
WT_SESSION *session;
|
||||
int is_begin_transaction;
|
||||
WT_CURSOR *dn2id;
|
||||
WT_CURSOR *dn2id_w;
|
||||
WT_CURSOR *dn2id_ndn;
|
||||
WT_CURSOR *dn2entry;
|
||||
WT_CURSOR *id2entry;
|
||||
WT_CURSOR *id2entry_add;
|
||||
WT_CURSOR *id2entry_update;
|
||||
WT_SESSION *idlcache_session;
|
||||
WT_CURSOR *index_pid;
|
||||
} wt_ctx;
|
||||
|
||||
/* for the cache of attribute information (which are indexed, etc.) */
|
||||
|
|
|
|||
|
|
@ -29,15 +29,13 @@ int
|
|||
wt_bind( Operation *op, SlapReply *rs )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
WT_SESSION *session;
|
||||
wt_ctx *wc;
|
||||
int rc;
|
||||
Entry *e = NULL;
|
||||
Attribute *a;
|
||||
AttributeDescription *password = slap_schema.si_ad_userPassword;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"==> " LDAP_XSTRING(wt_bind) ": dn: %s\n",
|
||||
Debug( LDAP_DEBUG_ARGS, "==> wt_bind: dn: %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
|
||||
/* allow noauth binds */
|
||||
|
|
@ -59,8 +57,7 @@ wt_bind( Operation *op, SlapReply *rs )
|
|||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_bind)
|
||||
": wt_ctx_get failed\n" );
|
||||
"wt_bind: wt_ctx_get failed\n" );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
send_ldap_result( op, rs );
|
||||
|
|
|
|||
231
servers/slapd/back-wt/cache.c
Normal file
231
servers/slapd/back-wt/cache.c
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/* OpenLDAP WiredTiger backend */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2002-2017 The OpenLDAP Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
/* ACKNOWLEDGEMENTS:
|
||||
* This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
|
||||
* based on back-bdb for inclusion in OpenLDAP Software.
|
||||
* WiredTiger is a product of MongoDB Inc.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ac/string.h>
|
||||
#include "back-wt.h"
|
||||
#include "slap-config.h"
|
||||
#include "idl.h"
|
||||
|
||||
int wt_idlcache_get(wt_ctx *wc, struct berval *ndn, int scope, ID *ids)
|
||||
{
|
||||
int rc = 0;
|
||||
WT_ITEM item;
|
||||
WT_SESSION *session = wc->idlcache_session;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_idlcache_get(\"%s\", %d)\n",
|
||||
ndn->bv_val, scope );
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
|
||||
NULL, &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_get: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
cursor->set_key(cursor, ndn->bv_val, (int8_t)scope);
|
||||
rc = cursor->search(cursor);
|
||||
switch( rc ){
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: miss\n" );
|
||||
goto done;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "<= wt_idlcache_get: search failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rc = 0;
|
||||
goto done;
|
||||
}
|
||||
rc = cursor->get_value(cursor, &item);
|
||||
if (rc) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_get: get_value failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
if (item.size == 0) {
|
||||
Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: updating\n");
|
||||
rc = WT_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
memcpy(ids, item.data, item.size);
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<= wt_idlcache_get: hit id=%ld first=%ld last=%ld\n",
|
||||
(long)ids[0],
|
||||
(long)WT_IDL_FIRST(ids),
|
||||
(long)WT_IDL_LAST(ids));
|
||||
done:
|
||||
if(cursor) {
|
||||
cursor->close(cursor);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wt_idlcache_set(wt_ctx *wc, struct berval *ndn, int scope, ID *ids)
|
||||
{
|
||||
int rc = 0;
|
||||
WT_ITEM item;
|
||||
WT_SESSION *session = wc->idlcache_session;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_idlcache_set(\"%s\", %d)\n",
|
||||
ndn->bv_val, scope );
|
||||
|
||||
item.size = WT_IDL_SIZEOF(ids);
|
||||
item.data = ids;
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_set: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
cursor->set_key(cursor, ndn->bv_val, (int8_t)scope);
|
||||
cursor->set_value(cursor, &item);
|
||||
rc = cursor->update(cursor);
|
||||
switch( rc ){
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
// updating cache by another thread
|
||||
goto done;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_set: update failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<= wt_idlcache_set: set idl size=%ld\n",
|
||||
(long)ids[0]);
|
||||
done:
|
||||
if(cursor) {
|
||||
cursor->close(cursor);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wt_idlcache_begin(wt_ctx *wc, struct berval *ndn, int scope)
|
||||
{
|
||||
int rc = 0;
|
||||
WT_ITEM item;
|
||||
WT_SESSION *session = wc->idlcache_session;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_idlcache_begin(\"%s\", %d)\n",
|
||||
ndn->bv_val, scope );
|
||||
|
||||
item.size = 0;
|
||||
item.data = "";
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
|
||||
"overwrite=true", &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_begin: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
cursor->set_key(cursor, ndn->bv_val, (int8_t)scope);
|
||||
cursor->set_value(cursor, &item);
|
||||
rc = cursor->update(cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_begin: update failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<= wt_idlcache_begin: set updating\n" );
|
||||
|
||||
done:
|
||||
if(cursor) {
|
||||
cursor->close(cursor);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wt_idlcache_clear(Operation *op, wt_ctx *wc, struct berval *ndn)
|
||||
{
|
||||
BackendDB *be = op->o_bd;
|
||||
int rc = 0;
|
||||
struct berval pdn = *ndn;
|
||||
WT_SESSION *session = wc->idlcache_session;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
int level = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_idlcache_clear(\"%s\")\n",
|
||||
ndn->bv_val );
|
||||
|
||||
if (be_issuffix( be, ndn )) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
|
||||
NULL, &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_idlcache_clear: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
|
||||
do {
|
||||
dnParent( &pdn, &pdn );
|
||||
if (level == 0) {
|
||||
/* clear only parent level cache */
|
||||
cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_ONE);
|
||||
cursor->remove(cursor);
|
||||
}
|
||||
cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_SUB);
|
||||
cursor->remove(cursor);
|
||||
cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_CHILDREN);
|
||||
cursor->remove(cursor);
|
||||
level++;
|
||||
}while(!be_issuffix( be, &pdn ));
|
||||
|
||||
if(cursor) {
|
||||
cursor->close(cursor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
|
@ -36,22 +36,20 @@ wt_compare( Operation *op, SlapReply *rs )
|
|||
int rc;
|
||||
wt_ctx *wc = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_compare) ": %s\n",
|
||||
Debug( LDAP_DEBUG_ARGS, "==> wt_compare: %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_compare)
|
||||
": wt_ctx_get failed\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_compare: wt_ctx_get failed\n" );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
send_ldap_result( op, rs );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
rs->sr_err = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rs->sr_err ) {
|
||||
rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
case WT_NOTFOUND:
|
||||
break;
|
||||
|
|
@ -61,37 +59,45 @@ wt_compare( Operation *op, SlapReply *rs )
|
|||
goto return_results;
|
||||
}
|
||||
|
||||
if ( rs->sr_err == WT_NOTFOUND ) {
|
||||
if ( e != NULL ) {
|
||||
/* return referral only if "disclose" is granted on the object */
|
||||
if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
|
||||
NULL, ACL_DISCLOSE, NULL ) )
|
||||
{
|
||||
if ( rc == WT_NOTFOUND ||
|
||||
(!manageDSAit && e && is_entry_glue( e ) )) {
|
||||
|
||||
if ( !e ) {
|
||||
rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
} else {
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
if ( is_entry_referral( e )) {
|
||||
BerVarray ref = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( ref,
|
||||
&e->e_name,
|
||||
&op->o_req_dn,
|
||||
LDAP_SCOPE_DEFAULT );
|
||||
ber_bvarray_free( ref );
|
||||
} else {
|
||||
rs->sr_ref = NULL;
|
||||
}
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_compare: wt_dn2aentry failed (%d)\n",
|
||||
rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
wt_entry_return( e );
|
||||
e = NULL;
|
||||
} else {
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
NULL,
|
||||
&op->o_req_dn,
|
||||
LDAP_SCOPE_DEFAULT );
|
||||
rs->sr_err = rs->sr_ref ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
|
||||
/* return referral only if "disclose" is granted on the object */
|
||||
if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
|
||||
NULL, ACL_DISCLOSE, NULL ) )
|
||||
{
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
} else {
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
if ( is_entry_referral( e )) {
|
||||
BerVarray ref = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( ref,
|
||||
&e->e_name,
|
||||
&op->o_req_dn,
|
||||
LDAP_SCOPE_DEFAULT );
|
||||
ber_bvarray_free( ref );
|
||||
} else {
|
||||
rs->sr_ref = NULL;
|
||||
}
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
}
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ enum {
|
|||
WT_DIRECTORY = 1,
|
||||
WT_CONFIG,
|
||||
WT_INDEX,
|
||||
WT_MODE,
|
||||
WT_IDLCACHE,
|
||||
};
|
||||
|
||||
static ConfigTable wtcfg[] = {
|
||||
|
|
@ -43,27 +45,35 @@ static ConfigTable wtcfg[] = {
|
|||
"DESC 'Directory for database content' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "wtconfig", "config", 2, 2, 0, ARG_STRING|ARG_MAGIC|WT_CONFIG,
|
||||
wt_cf_gen, "( OLcfgDbAt:13.1 NAME 'olcWtConfig' "
|
||||
"DESC 'Configuration for WiredTiger' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|WT_INDEX,
|
||||
wt_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
|
||||
"DESC 'Attribute index parameters' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
||||
{ "mode", "mode", 2, 2, 0, ARG_MAGIC|WT_MODE,
|
||||
wt_cf_gen, "( OLcfgDbAt:0.3 NAME 'olcDbMode' "
|
||||
"DESC 'Unix permissions of database files' "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "wtconfig", "config", 2, 2, 0, ARG_STRING|ARG_MAGIC|WT_CONFIG,
|
||||
wt_cf_gen, "( OLcfgDbAt:13.1 NAME 'olcWtConfig' "
|
||||
"DESC 'Configuration for WiredTiger' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "idlcache", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|WT_IDLCACHE,
|
||||
wt_cf_gen, "( OLcfgDbAt:13.2 NAME 'olcIDLcache' "
|
||||
"DESC 'enable IDL cache' "
|
||||
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
|
||||
{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
|
||||
NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static ConfigOCs wtocs[] = {
|
||||
{ "( OLcfgDbOc:9.1 "
|
||||
{ "( OLcfgDbOc:13.1 "
|
||||
"NAME 'olcWtConfig' "
|
||||
"DESC 'Wt backend configuration' "
|
||||
"SUP olcDatabaseConfig "
|
||||
"MUST olcDbDirectory "
|
||||
"MAY ( olcWtConfig $ olcDbIndex ) )",
|
||||
"MAY ( olcWtConfig $ olcDbIndex $ olcDbMode $ olcIDLcache) )",
|
||||
Cft_Database, wtcfg },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
|
@ -73,6 +83,7 @@ static void *
|
|||
wt_online_index( void *ctx, void *arg )
|
||||
{
|
||||
// Not implement yet
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Cleanup loose ends after Modify completes */
|
||||
|
|
@ -89,20 +100,47 @@ wt_cf_gen( ConfigArgs *c )
|
|||
struct wt_info *wi = (struct wt_info *) c->be->be_private;
|
||||
int rc;
|
||||
|
||||
if(c->op == SLAP_CONFIG_EMIT) {
|
||||
if( c->op == SLAP_CONFIG_EMIT ) {
|
||||
rc = 0;
|
||||
switch( c->type ) {
|
||||
case WT_DIRECTORY:
|
||||
if ( wi->wi_home ) {
|
||||
c->value_string = ch_strdup( wi->wi_home );
|
||||
} else {
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
case WT_INDEX:
|
||||
wt_attr_index_unparse( wi, &c->rvalue_vals );
|
||||
if ( !c->rvalue_vals ) rc = 1;
|
||||
break;
|
||||
case WT_IDLCACHE:
|
||||
if ( wi->wi_flags & WT_USE_IDLCACHE) {
|
||||
c->value_int = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
} else if ( c->op == LDAP_MOD_DELETE ) {
|
||||
rc = 0;
|
||||
// not implement yet
|
||||
return rc;
|
||||
}
|
||||
|
||||
switch( c->type ) {
|
||||
case WT_DIRECTORY:
|
||||
ch_free( wi->wi_dbenv_home );
|
||||
wi->wi_dbenv_home = c->value_string;
|
||||
ch_free( wi->wi_home );
|
||||
wi->wi_home = c->value_string;
|
||||
break;
|
||||
case WT_CONFIG:
|
||||
ch_free( wi->wi_dbenv_config );
|
||||
wi->wi_dbenv_config = c->value_string;
|
||||
if(strlen(wi->wi_config) + 1 + strlen(c->value_string) > WT_CONFIG_MAX){
|
||||
fprintf( stderr, "%s: "
|
||||
"\"wtconfig\" are too long. Increase WT_CONFIG_MAX or you may realloc the buffer.\n",
|
||||
c->log );
|
||||
return 1;
|
||||
}
|
||||
/* size of wi->wi_config is WT_CONFIG_MAX + 1, it's guaranteed with NUL-terminate. */
|
||||
strcat(wi->wi_config, ",");
|
||||
strcat(wi->wi_config, c->value_string);
|
||||
break;
|
||||
|
||||
case WT_INDEX:
|
||||
|
|
@ -135,6 +173,19 @@ wt_cf_gen( ConfigArgs *c )
|
|||
}
|
||||
break;
|
||||
|
||||
case WT_MODE:
|
||||
fprintf( stderr, "%s: "
|
||||
"back-wt does not support \"mode\" option. use umask instead.\n",
|
||||
c->log );
|
||||
return 1;
|
||||
|
||||
case WT_IDLCACHE:
|
||||
if ( c->value_int ) {
|
||||
wi->wi_flags |= WT_USE_IDLCACHE;
|
||||
} else {
|
||||
wi->wi_flags &= ~WT_USE_IDLCACHE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,24 +30,32 @@ wt_ctx_init(struct wt_info *wi)
|
|||
|
||||
wc = ch_malloc( sizeof( wt_ctx ) );
|
||||
if( !wc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_ctx_init)
|
||||
": cannot allocate memory\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_ctx_init: cannot allocate memory\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(wc, 0, sizeof(wt_ctx));
|
||||
|
||||
if(!wc->session){
|
||||
rc = wi->wi_conn->open_session(wi->wi_conn, NULL, NULL, &wc->session);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_ctx_session)
|
||||
": open_session error %s(%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NULL;
|
||||
}
|
||||
rc = wi->wi_conn->open_session(wi->wi_conn, NULL, NULL, &wc->session);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY, "wt_ctx_init: open_session error %s(%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* readonly mode */
|
||||
if (!wi->wi_cache) {
|
||||
return wc;
|
||||
}
|
||||
|
||||
rc = wi->wi_cache->open_session(wi->wi_cache, NULL, NULL, &wc->idlcache_session);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_ctx_init: cannnot open idlcache session %s(%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wc;
|
||||
}
|
||||
|
||||
|
|
@ -57,9 +65,19 @@ wt_ctx_free( void *key, void *data )
|
|||
wt_ctx *wc = data;
|
||||
|
||||
if(wc->session){
|
||||
wc->session->close(wc->session, NULL);
|
||||
/*
|
||||
* The session will close automatically when db closing.
|
||||
* We can close session here, but it's require to check db
|
||||
* status, otherwise it will cause SEGV.
|
||||
*/
|
||||
/*
|
||||
if(IS_DB_OPEN) {
|
||||
wc->session->close(wc->session, NULL);
|
||||
}
|
||||
*/
|
||||
wc->session = NULL;
|
||||
}
|
||||
|
||||
ch_free(wc);
|
||||
}
|
||||
|
||||
|
|
@ -70,17 +88,15 @@ wt_ctx_get(Operation *op, struct wt_info *wi){
|
|||
wt_ctx *wc = NULL;
|
||||
|
||||
rc = ldap_pvt_thread_pool_getkey(op->o_threadctx,
|
||||
wt_ctx_get, &data, NULL );
|
||||
wi, &data, NULL );
|
||||
if( rc ){
|
||||
wc = wt_ctx_init(wi);
|
||||
if( !wc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_ctx)
|
||||
": wt_ctx_init failed\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_ctx: wt_ctx_init failed\n" );
|
||||
return NULL;
|
||||
}
|
||||
rc = ldap_pvt_thread_pool_setkey( op->o_threadctx,
|
||||
wt_ctx_get, wc, wt_ctx_free,
|
||||
wi, wc, wt_ctx_free,
|
||||
NULL, NULL );
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY, "wt_ctx: setkey error(%d)\n",
|
||||
|
|
@ -92,45 +108,6 @@ wt_ctx_get(Operation *op, struct wt_info *wi){
|
|||
return (wt_ctx *)data;
|
||||
}
|
||||
|
||||
WT_CURSOR *
|
||||
wt_ctx_index_cursor(wt_ctx *wc, struct berval *name, int create)
|
||||
{
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
char tablename[1024];
|
||||
int rc;
|
||||
|
||||
snprintf(tablename, sizeof(tablename), "table:%s", name->bv_val);
|
||||
|
||||
rc = session->open_cursor(session, tablename, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
if (rc == ENOENT && create) {
|
||||
rc = session->create(session,
|
||||
tablename,
|
||||
"key_format=uQ,"
|
||||
"value_format=x,"
|
||||
"columns=(key, id, none)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(indexer) ": table \"%s\": "
|
||||
"cannot create idnex table: %s (%d)\n",
|
||||
tablename, wiredtiger_strerror(rc), rc);
|
||||
return NULL;
|
||||
}
|
||||
rc = session->open_cursor(session, tablename, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
}
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry_put)
|
||||
": open cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
|
|
|
|||
|
|
@ -44,12 +44,11 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
|
||||
wt_ctx *wc;
|
||||
int rc;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
|
||||
int parent_is_glue = 0;
|
||||
int parent_is_leaf = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_delete) ": %s\n",
|
||||
Debug( LDAP_DEBUG_ARGS, "==> wt_delete: %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
|
||||
if( op->o_txnSpec && txn_preop( op, rs ))
|
||||
|
|
@ -60,9 +59,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_delete)
|
||||
": wt_ctx_get failed\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_delete: wt_ctx_get failed\n" );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
|
|
@ -89,26 +86,37 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
case WT_NOTFOUND:
|
||||
break;
|
||||
default:
|
||||
/* TODO: error handling */
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_delete)
|
||||
": error at wt_dn2entry() rc=%d\n",
|
||||
rc );
|
||||
"wt_delete: error at wt_dn2entry() rc=%d\n", rc );
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( rc == WT_NOTFOUND && pdn.bv_len != 0 ) {
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_delete) ": no such object %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
"<== wt_delete: parent not found %s\n", op->o_req_dn.bv_val );
|
||||
rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
Debug( LDAP_DEBUG_ARGS, "<== wt_delete: rc=%d\n", rc );
|
||||
|
||||
if ( p && !BER_BVISEMPTY( &p->e_name )) {
|
||||
rs->sr_matched = ch_strdup( p->e_name.bv_val );
|
||||
if ( is_entry_referral( p )) {
|
||||
BerVarray ref = get_entry_referrals( op, p );
|
||||
rs->sr_ref = referral_rewrite( ref, &p->e_name,
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_delete: wt_dn2aentry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( e && !BER_BVISEMPTY( &e->e_name )) {
|
||||
rs->sr_matched = ch_strdup( e->e_name.bv_val );
|
||||
if ( is_entry_referral( e )) {
|
||||
BerVarray ref = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( ref, &e->e_name,
|
||||
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
|
||||
ber_bvarray_free( ref );
|
||||
} else {
|
||||
|
|
@ -130,30 +138,36 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": no such object %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
goto return_results;
|
||||
break;
|
||||
default:
|
||||
/* TODO: error handling */
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_delete)
|
||||
": error at wt_dn2entry() rc=%d\n",
|
||||
rc );
|
||||
"wt_delete: error at wt_dn2entry() rc=%d\n", rc );
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* FIXME : dn2entry() should return non-glue entry */
|
||||
if ( !manageDSAit && is_entry_glue( e ) ) {
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": glue entry %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
if (rc == WT_NOTFOUND ||
|
||||
( !manageDSAit && e && is_entry_glue( e ) )) {
|
||||
if ( !e ) {
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== wt_delete: no such object %s\n",
|
||||
op->o_req_dn.bv_val);
|
||||
rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_delete: wt_dn2aentry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
if ( is_entry_referral( e )) {
|
||||
|
|
@ -177,8 +191,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
|
||||
if ( !rs->sr_err ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete) ": no write "
|
||||
"access to parent\n" );
|
||||
"<== wt_delete: no write access to parent\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
rs->sr_text = "no write access to parent";
|
||||
goto return_results;
|
||||
|
|
@ -199,8 +212,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
|
||||
if ( !rs->sr_err ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": no access to parent\n" );
|
||||
"<== wt_delete: no access to parent\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
rs->sr_text = "no write access to parent";
|
||||
goto return_results;
|
||||
|
|
@ -208,8 +220,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": no parent and not root\n" );
|
||||
"<== wt_delete: no parent and not root\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
}
|
||||
|
|
@ -227,8 +238,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
entry, NULL, ACL_WDEL, NULL );
|
||||
if ( !rs->sr_err ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete) ": no write access "
|
||||
"to entry\n" );
|
||||
"<== wt_delete: no write access to entry\n" );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
rs->sr_text = "no write access to entry";
|
||||
goto return_results;
|
||||
|
|
@ -238,8 +248,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
/* entry is a referral, don't allow delete */
|
||||
rs->sr_ref = get_entry_referrals( op, e );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(tw_delete) ": entry is referral\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_delete: entry is referral\n" );
|
||||
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_matched = ch_strdup( e->e_name.bv_val );
|
||||
|
|
@ -257,8 +266,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
&slap_pre_read_bv, preread_ctrl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete) ": pre-read "
|
||||
"failed!\n" );
|
||||
"<== wt_delete: pre-read failed!\n" );
|
||||
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
|
||||
/* FIXME: is it correct to abort
|
||||
* operation if control fails? */
|
||||
|
|
@ -268,21 +276,18 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
/* Can't do it if we have kids */
|
||||
rc = wt_dn2id_has_children( op, wc->session, e->e_id );
|
||||
rc = wt_dn2id_has_children( op, wc, e->e_id );
|
||||
if( rc != WT_NOTFOUND ) {
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": non-leaf %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
"<== wt_delete: non-leaf %s\n", op->o_req_dn.bv_val );
|
||||
rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
|
||||
rs->sr_text = "subordinate objects must be deleted first";
|
||||
break;
|
||||
default:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": has_children failed: %s (%d)\n",
|
||||
"<== wt_delete: has_children failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
|
|
@ -294,7 +299,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
|
||||
"wt_delete: begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "begin_transaction failed";
|
||||
|
|
@ -302,11 +307,10 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
/* delete from dn2id */
|
||||
rc = wt_dn2id_delete( op, wc->session, &e->e_nname);
|
||||
rc = wt_dn2id_delete( op, wc, &op->o_req_ndn);
|
||||
if ( rc ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": dn2id failed: %s (%d)\n",
|
||||
"<== wt_delete: dn2id failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "dn2id delete failed";
|
||||
|
|
@ -318,8 +322,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
rc = wt_index_entry_del( op, wc, e );
|
||||
if ( rc ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": index delete failed: %s (%d)\n",
|
||||
"<== wt_delete: index delete failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "index delete failed";
|
||||
|
|
@ -334,7 +337,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
assert( !BER_BVISNULL( &op->o_csn ) );
|
||||
vals[0] = op->o_csn;
|
||||
BER_BVZERO( &vals[1] );
|
||||
rs->sr_err = wt_index_values( op, wc->session, slap_schema.si_ad_entryCSN,
|
||||
rs->sr_err = wt_index_values( op, wc, slap_schema.si_ad_entryCSN,
|
||||
vals, 0, SLAP_INDEX_ADD_OP );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
rs->sr_text = "entryCSN index update failed";
|
||||
|
|
@ -345,11 +348,10 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
/* delete from id2entry */
|
||||
rc = wt_id2entry_delete( op, wc->session, e );
|
||||
rc = wt_id2entry_delete( op, wc, e );
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": id2entry failed: %s (%d)\n",
|
||||
"<== wt_delete: id2entry failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "entry delete failed";
|
||||
|
|
@ -364,8 +366,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": commit_transaction failed: %s (%d)\n",
|
||||
"<== wt_delete: commit_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "commit_transaction failed";
|
||||
|
|
@ -373,8 +374,7 @@ wt_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_delete)
|
||||
": deleted%s id=%08lx dn=\"%s\"\n",
|
||||
"wt_delete: deleted%s id=%08lx dn=\"%s\"\n",
|
||||
op->o_noop ? " (no-op)" : "", e->e_id, op->o_req_dn.bv_val );
|
||||
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -35,28 +35,33 @@ int wt_dn2entry( BackendDB *be,
|
|||
struct berval *ndn,
|
||||
Entry **ep ){
|
||||
uint64_t id;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_ITEM item;
|
||||
EntryHeader eh;
|
||||
int rc;
|
||||
int eoff;
|
||||
Entry *e = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->dn2entry;
|
||||
|
||||
if( ndn->bv_len == 0 ){
|
||||
/* parent of root dn */
|
||||
return WT_NOTFOUND;
|
||||
/* empty dn */
|
||||
e = entry_alloc();
|
||||
ber_dupbv(&e->e_nname, ndn);
|
||||
*ep = e;
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
rc = session->open_cursor(session,
|
||||
WT_INDEX_DN"(id, entry)",
|
||||
NULL, NULL, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2entry)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session,
|
||||
WT_INDEX_DN"(id, entry)",
|
||||
NULL, NULL, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2entry: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->dn2entry = cursor;
|
||||
}
|
||||
|
||||
cursor->set_key(cursor, ndn->bv_val);
|
||||
|
|
@ -68,8 +73,7 @@ int wt_dn2entry( BackendDB *be,
|
|||
goto done;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2entry)
|
||||
": search failed: %s (%d)\n",
|
||||
"wt_dn2entry: search failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -86,9 +90,7 @@ int wt_dn2entry( BackendDB *be,
|
|||
rc = entry_decode( &eh, &e );
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2entry)
|
||||
": entry decode error: %d\n",
|
||||
rc );
|
||||
"wt_dn2entry: entry decode error: %d\n", rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -96,9 +98,17 @@ int wt_dn2entry( BackendDB *be,
|
|||
*ep = e;
|
||||
|
||||
done:
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->dn2entry = NULL;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +132,41 @@ int wt_dn2pentry( BackendDB *be,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* dn2aentry - return ancestor entry */
|
||||
int wt_dn2aentry( BackendDB *be,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
Entry **ep ) {
|
||||
Entry *e = NULL;
|
||||
struct berval pdn;
|
||||
int rc;
|
||||
|
||||
if (be_issuffix( be, ndn )) {
|
||||
*ep = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dnParent( ndn, &pdn );
|
||||
rc = wt_dn2entry(be, wc, &pdn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
*ep = e;
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rc = wt_dn2aentry(be, wc, &pdn, &e);
|
||||
if (rc != 0 && rc != WT_NOTFOUND) {
|
||||
return rc;
|
||||
}
|
||||
*ep = e;
|
||||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2aentry: failed %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "slap-config.h"
|
||||
#include "idl.h"
|
||||
|
||||
char *
|
||||
static char *
|
||||
mkrevdn(struct berval src){
|
||||
char *dst, *p;
|
||||
char *rdn;
|
||||
|
|
@ -46,7 +46,7 @@ mkrevdn(struct berval src){
|
|||
rdn = src.bv_val;
|
||||
src.bv_len = 0;
|
||||
}
|
||||
AC_MEMCPY( p, rdn, rdn_len );
|
||||
memcpy( p, rdn, rdn_len );
|
||||
p += rdn_len;
|
||||
*p++ = ',';
|
||||
}
|
||||
|
|
@ -57,12 +57,14 @@ mkrevdn(struct berval src){
|
|||
int
|
||||
wt_dn2id_add(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
ID pid,
|
||||
Entry *e)
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
int rc;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->dn2id_w;
|
||||
char *revdn = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_add 0x%lx: \"%s\"\n",
|
||||
|
|
@ -72,33 +74,47 @@ wt_dn2id_add(
|
|||
/* make reverse dn */
|
||||
revdn = mkrevdn(e->e_nname);
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
|
||||
NULL, &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_add)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
cursor->set_key(cursor, e->e_ndn);
|
||||
cursor->set_value(cursor, e->e_id, pid, revdn);
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2id_add: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->dn2id_w = cursor;
|
||||
}
|
||||
cursor->set_key(cursor, revdn);
|
||||
cursor->set_value(cursor, e->e_ndn, e->e_id, pid);
|
||||
rc = cursor->insert(cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_add)
|
||||
": insert failed: %s (%d)\n",
|
||||
"wt_dn2id_add: insert failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (wi->wi_flags & WT_USE_IDLCACHE) {
|
||||
wt_idlcache_clear(op, wc, &e->e_nname);
|
||||
}
|
||||
|
||||
done:
|
||||
if(revdn){
|
||||
ch_free(revdn);
|
||||
}
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->dn2id_w = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id_add 0x%lx: %d\n", e->e_id, rc );
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -106,73 +122,94 @@ done:
|
|||
int
|
||||
wt_dn2id_delete(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn)
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
int rc = 0;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->dn2id_w;
|
||||
char *revdn = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_delete %s\n", ndn->bv_val );
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
|
||||
NULL, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_delete)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
/* make reverse dn */
|
||||
revdn = mkrevdn(*ndn);
|
||||
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2id_delete: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->dn2id_w = cursor;
|
||||
}
|
||||
|
||||
cursor->set_key(cursor, ndn->bv_val);
|
||||
cursor->set_key(cursor, revdn);
|
||||
rc = cursor->remove(cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_delete)
|
||||
": remove failed: %s (%d)\n",
|
||||
"wt_dn2id_delete: remove failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (wi->wi_flags & WT_USE_IDLCACHE) {
|
||||
wt_idlcache_clear(op, wc, ndn);
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= wt_dn2id_delete %s: %d\n",
|
||||
ndn->bv_val, rc );
|
||||
"<= wt_dn2id_delete %s: %d\n", ndn->bv_val, rc );
|
||||
done:
|
||||
if(revdn){
|
||||
ch_free(revdn);
|
||||
}
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->dn2id_w = NULL;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
wt_dn2id(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
ID *id)
|
||||
{
|
||||
WT_CURSOR *cursor = NULL;
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
int rc;
|
||||
ID nid;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->dn2id_ndn;
|
||||
int rc = LDAP_SUCCESS;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n",
|
||||
ndn->bv_val );
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n", ndn->bv_val );
|
||||
|
||||
if ( ndn->bv_len == 0 ) {
|
||||
*id = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_DN2ID
|
||||
"(id)",
|
||||
NULL, NULL, &cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id)
|
||||
": cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_INDEX_NDN
|
||||
"(id)",
|
||||
NULL, NULL, &cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2id: cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->dn2id_ndn = cursor;
|
||||
}
|
||||
|
||||
cursor->set_key(cursor, ndn->bv_val);
|
||||
|
|
@ -184,24 +221,30 @@ wt_dn2id(
|
|||
goto done;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id)
|
||||
": search failed: %s (%d)\n",
|
||||
"wt_dn2id: search failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
rc = cursor->get_value(cursor, id);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id)
|
||||
": get_value failed: %s (%d)\n",
|
||||
"wt_dn2id: get_value failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->dn2id_ndn = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: get failed: %s (%d)\n",
|
||||
|
|
@ -217,47 +260,56 @@ done:
|
|||
int
|
||||
wt_dn2id_has_children(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
ID id )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->index_pid;
|
||||
int rc;
|
||||
uint64_t key = id;
|
||||
|
||||
rc = session->open_cursor(session, WT_INDEX_PID,
|
||||
NULL, NULL, &cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_has_children)
|
||||
": cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_INDEX_PID,
|
||||
NULL, NULL, &cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2id_has_children: cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->index_pid = cursor;
|
||||
}
|
||||
|
||||
cursor->set_key(cursor, key);
|
||||
rc = cursor->search(cursor);
|
||||
|
||||
done:
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->index_pid = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
wt_dn2idl(
|
||||
wt_dn2idl_db(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
Entry *e,
|
||||
ID *ids,
|
||||
ID *stack)
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
int exact = 0;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->dn2id;
|
||||
int rc;
|
||||
char *revdn = NULL;
|
||||
size_t revdn_len;
|
||||
|
|
@ -268,73 +320,58 @@ wt_dn2idl(
|
|||
"=> wt_dn2idl(\"%s\")\n",
|
||||
ndn->bv_val );
|
||||
|
||||
if(op->ors_scope != LDAP_SCOPE_ONELEVEL &&
|
||||
be_issuffix( op->o_bd, &e->e_nname )){
|
||||
WT_IDL_ALL(wi, ids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
revdn = mkrevdn(*ndn);
|
||||
revdn_len = strlen(revdn);
|
||||
rc = session->open_cursor(session, WT_INDEX_REVDN"(id, pid)",
|
||||
NULL, NULL, &cursor);
|
||||
|
||||
if ( !cursor ) {
|
||||
rc = session->open_cursor(session, WT_TABLE_DN2ID"(id, pid)",
|
||||
NULL, NULL, &cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2idl: cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->dn2id = cursor;
|
||||
}
|
||||
cursor->set_key(cursor, revdn);
|
||||
rc = cursor->search(cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2idl)
|
||||
": cursor open failed: %s (%d)\n",
|
||||
"wt_dn2idl: search failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
cursor->set_key(cursor, revdn);
|
||||
rc = cursor->search_near(cursor, &exact);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2idl)
|
||||
": search failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
|
||||
if( op->ors_scope == LDAP_SCOPE_CHILDREN ) {
|
||||
cursor->next(cursor);
|
||||
}
|
||||
|
||||
do {
|
||||
rc = cursor->get_key(cursor, &key);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2idl)
|
||||
": get_key failed: %s (%d)\n",
|
||||
"wt_dn2idl: get_key failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
rc = cursor->get_value(cursor, &id, &pid);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_dn2id: get_value failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if( strncmp(revdn, key, revdn_len) ){
|
||||
if(exact < 0){
|
||||
rc = cursor->next(cursor);
|
||||
if (rc) {
|
||||
break;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
exact = 0;
|
||||
rc = cursor->get_value(cursor, &id, &pid);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id)
|
||||
": get_value failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
if( op->ors_scope == LDAP_SCOPE_ONELEVEL &&
|
||||
e->e_id != pid){
|
||||
rc = cursor->next(cursor);
|
||||
if ( rc ) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}else{
|
||||
wt_idl_append_one(ids, id);
|
||||
|
||||
if( op->ors_scope == LDAP_SCOPE_ONELEVEL && e->e_id != pid ){
|
||||
goto next;
|
||||
}
|
||||
wt_idl_append_one(ids, id);
|
||||
next:
|
||||
rc = cursor->next(cursor);
|
||||
}while(rc == 0);
|
||||
|
||||
|
|
@ -342,47 +379,70 @@ wt_dn2idl(
|
|||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
wt_idl_sort(ids, stack);
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= wt_dn2idl_db: size=%ld first=%ld last=%ld\n",
|
||||
(long) ids[0],
|
||||
(long) WT_IDL_FIRST(ids),
|
||||
(long) WT_IDL_LAST(ids) );
|
||||
|
||||
done:
|
||||
if(revdn){
|
||||
ch_free(revdn);
|
||||
}
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->dn2id = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
wt_dn2id(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
struct berval *dn,
|
||||
ID *id)
|
||||
{
|
||||
struct wt_info *wi = (struct wy_info *) op->o_bd->be_private;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
int rc;
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n", dn->bv_val );
|
||||
|
||||
rc = session->open_cursor(session, WT_INDEX_DN"(id)",
|
||||
NULL, NULL, &cursor);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id)
|
||||
": cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
cursor->set_key(cursor, dn->bv_val);
|
||||
rc = cursor->search(cursor);
|
||||
if( !rc ){
|
||||
cursor->get_key(cursor, &id);
|
||||
}
|
||||
cursor->close(cursor);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
wt_dn2idl(
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
Entry *e,
|
||||
ID *ids,
|
||||
ID *stack)
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
int rc;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_dn2idl(\"%s\")\n", ndn->bv_val );
|
||||
|
||||
if(op->ors_scope != LDAP_SCOPE_ONELEVEL &&
|
||||
be_issuffix( op->o_bd, &e->e_nname )){
|
||||
WT_IDL_ALL(wi, ids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wi->wi_flags & WT_USE_IDLCACHE) {
|
||||
rc = wt_idlcache_get(wc, ndn, op->ors_scope, ids);
|
||||
if (rc == 0) {
|
||||
/* cache hit */
|
||||
return rc;
|
||||
}
|
||||
/* cache miss */
|
||||
}
|
||||
|
||||
if ( wi->wi_flags & WT_USE_IDLCACHE ) {
|
||||
wt_idlcache_begin(wc, ndn, op->ors_scope);
|
||||
}
|
||||
rc = wt_dn2idl_db(op, wc, ndn, e, ids, stack);
|
||||
if ( rc == 0 && wi->wi_flags & WT_USE_IDLCACHE ) {
|
||||
wt_idlcache_set(wc, ndn, op->ors_scope, ids);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
|
|
|||
58
servers/slapd/back-wt/extended.c
Normal file
58
servers/slapd/back-wt/extended.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* OpenLDAP WiredTiger backend */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2002-2015 The OpenLDAP Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
/* ACKNOWLEDGEMENTS:
|
||||
* This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
|
||||
* based on back-bdb for inclusion in OpenLDAP Software.
|
||||
* WiredTiger is a product of MongoDB Inc.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ac/string.h>
|
||||
|
||||
#include "back-wt.h"
|
||||
#include "lber_pvt.h"
|
||||
|
||||
static struct exop {
|
||||
struct berval *oid;
|
||||
BI_op_extended *extended;
|
||||
} exop_table[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int
|
||||
wt_extended( Operation *op, SlapReply *rs )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; exop_table[i].extended != NULL; i++ ) {
|
||||
if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) {
|
||||
return (exop_table[i].extended)( op, rs );
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_text = "not supported within naming context";
|
||||
return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
|
@ -75,7 +75,7 @@ presence_candidates(
|
|||
}
|
||||
|
||||
/* open index cursor */
|
||||
cursor = wt_ctx_index_cursor(wc, &desc->ad_type->sat_cname, 0);
|
||||
cursor = wt_index_open(wc, &desc->ad_type->sat_cname, 0);
|
||||
if( !cursor ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= wt_presence_candidates: open index cursor failed: %s\n",
|
||||
|
|
@ -85,9 +85,7 @@ presence_candidates(
|
|||
|
||||
rc = wt_key_read( op->o_bd, cursor, &prefix, ids, NULL, 0 );
|
||||
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
}
|
||||
cursor->close(cursor);
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<= wt_presence_candidates: id=%ld first=%ld last=%ld\n",
|
||||
(long) ids[0],
|
||||
|
|
@ -114,12 +112,12 @@ equality_candidates(
|
|||
MatchingRule *mr;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_equality_candidates (%s)\n",
|
||||
ava->aa_desc->ad_cname.bv_val );
|
||||
Debug( LDAP_DEBUG_TRACE, "=> wt_equality_candidates (%s=%s)\n",
|
||||
ava->aa_desc->ad_cname.bv_val, ava->aa_value.bv_val );
|
||||
|
||||
if ( ava->aa_desc == slap_schema.si_ad_entryDN ) {
|
||||
ID id = NOID;
|
||||
rc = wt_dn2id(op, wc->session, &ava->aa_value, &id);
|
||||
rc = wt_dn2id(op, wc, &ava->aa_value, &id);
|
||||
if( rc == 0 ){
|
||||
wt_idl_append_one(ids, id);
|
||||
}else if ( rc == WT_NOTFOUND ) {
|
||||
|
|
@ -182,7 +180,7 @@ equality_candidates(
|
|||
}
|
||||
|
||||
/* open index cursor */
|
||||
cursor = wt_ctx_index_cursor(wc, &ava->aa_desc->ad_type->sat_cname, 0);
|
||||
cursor = wt_index_open(wc, &ava->aa_desc->ad_type->sat_cname, 0);
|
||||
if( !cursor ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= wt_equality_candidates: open index cursor failed: %s\n",
|
||||
|
|
@ -198,8 +196,7 @@ equality_candidates(
|
|||
break;
|
||||
} else if( rc != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= wt_equality_candidates: (%s) "
|
||||
"key read failed (%d)\n",
|
||||
"<= wt_equality_candidates: (%s) key read failed (%d)\n",
|
||||
ava->aa_desc->ad_cname.bv_val, rc );
|
||||
break;
|
||||
}
|
||||
|
|
@ -215,9 +212,7 @@ equality_candidates(
|
|||
|
||||
ber_bvarray_free_x( keys, op->o_tmpmemctx );
|
||||
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
}
|
||||
cursor->close(cursor);
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= wt_equality_candidates: id=%ld, first=%ld, last=%ld\n",
|
||||
|
|
@ -305,7 +300,7 @@ approx_candidates(
|
|||
}
|
||||
|
||||
/* open index cursor */
|
||||
cursor = wt_ctx_index_cursor(wc, &ava->aa_desc->ad_type->sat_cname, 0);
|
||||
cursor = wt_index_open(wc, &ava->aa_desc->ad_type->sat_cname, 0);
|
||||
if( !cursor ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= wt_approx_candidates: open index cursor failed: %s\n",
|
||||
|
|
@ -346,9 +341,7 @@ approx_candidates(
|
|||
|
||||
ber_bvarray_free_x( keys, op->o_tmpmemctx );
|
||||
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
}
|
||||
cursor->close(cursor);
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= wt_approx_candidates %ld, first=%ld, last=%ld\n",
|
||||
|
|
@ -393,8 +386,7 @@ substring_candidates(
|
|||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= wt_substring_candidates: (%s) "
|
||||
"index_param failed (%d)\n",
|
||||
"<= wt_substring_candidates: (%s) index_param failed (%d)\n",
|
||||
sub->sa_desc->ad_cname.bv_val, rc );
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -433,7 +425,7 @@ substring_candidates(
|
|||
}
|
||||
|
||||
/* open index cursor */
|
||||
cursor = wt_ctx_index_cursor(wc, &sub->sa_desc->ad_cname, 0);
|
||||
cursor = wt_index_open(wc, &sub->sa_desc->ad_cname, 0);
|
||||
if( !cursor ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= wt_substring_candidates: open index cursor failed: %s\n",
|
||||
|
|
@ -475,9 +467,7 @@ substring_candidates(
|
|||
|
||||
ber_bvarray_free_x( keys, op->o_tmpmemctx );
|
||||
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
}
|
||||
cursor->close(cursor);
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= wt_substring_candidates: %ld, first=%ld, last=%ld\n",
|
||||
|
|
@ -487,6 +477,56 @@ substring_candidates(
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
static int
|
||||
comp_candidates (
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
MatchingRuleAssertion *mra,
|
||||
ComponentFilter *f,
|
||||
ID *ids,
|
||||
ID *tmp,
|
||||
ID *stack)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if ( !f ) return LDAP_PROTOCOL_ERROR;
|
||||
|
||||
Debug( LDAP_DEBUG_FILTER, "comp_candidates\n" );
|
||||
/* TODO: */
|
||||
Debug( LDAP_DEBUG_FILTER, "=> not implement yet\n" );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
ext_candidates(
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
MatchingRuleAssertion *mra,
|
||||
ID *ids,
|
||||
ID *tmp,
|
||||
ID *stack )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
/*
|
||||
* Currently Only Component Indexing for componentFilterMatch is supported
|
||||
* Indexing for an extensible filter is not supported yet
|
||||
*/
|
||||
if ( mra->ma_cf ) {
|
||||
return comp_candidates ( op, wc, mra, mra->ma_cf, ids, tmp, stack);
|
||||
}
|
||||
#endif
|
||||
if ( mra->ma_desc == slap_schema.si_ad_entryDN ) {
|
||||
/* TODO: */
|
||||
Debug( LDAP_DEBUG_FILTER, "=> not implement yet.\n" );
|
||||
}
|
||||
WT_IDL_ALL( wi, ids );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
list_candidates(
|
||||
|
|
@ -569,7 +609,7 @@ wt_filter_candidates(
|
|||
ID *stack )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *)op->o_bd->be_private;
|
||||
int rc = 0;
|
||||
int rc = LDAP_SUCCESS;
|
||||
Debug( LDAP_DEBUG_FILTER, "=> wt_filter_candidates\n" );
|
||||
|
||||
if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
|
||||
|
|
@ -649,9 +689,8 @@ wt_filter_candidates(
|
|||
break;
|
||||
|
||||
case LDAP_FILTER_EXT:
|
||||
/* TODO: not implement yet */
|
||||
Debug( LDAP_DEBUG_FILTER, "\tEXT\n" );
|
||||
rc = presence_candidates( op, wc, f->f_ava->aa_desc, ids );
|
||||
rc = ext_candidates( op, wc, f->f_mra, ids, tmp, stack);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -667,7 +706,7 @@ done:
|
|||
(long) ids[0],
|
||||
(long) WT_IDL_FIRST( ids ),
|
||||
(long) WT_IDL_LAST( ids ) );
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -24,12 +24,11 @@
|
|||
|
||||
static int wt_id2entry_put(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
Entry *e,
|
||||
const char *config )
|
||||
WT_CURSOR *cursor)
|
||||
{
|
||||
struct berval bv;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_ITEM item;
|
||||
int rc;
|
||||
|
||||
|
|
@ -40,63 +39,108 @@ static int wt_id2entry_put(
|
|||
item.size = bv.bv_len;
|
||||
item.data = bv.bv_val;
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
|
||||
config, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry_put)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
cursor->set_key(cursor, e->e_id);
|
||||
cursor->set_value(cursor, e->e_ndn, &item);
|
||||
rc = cursor->insert(cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry_put)
|
||||
": insert failed: %s (%d)\n",
|
||||
"wt_id2entry_put: insert failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
ch_free( bv.bv_val );
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wt_id2entry_add(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
Entry *e )
|
||||
{
|
||||
return wt_id2entry_put(op, session, e, "overwrite=false");
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->id2entry_add;
|
||||
int rc;
|
||||
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_id2entry_put: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
wc->id2entry_add = cursor;
|
||||
}
|
||||
|
||||
rc = wt_id2entry_put(op, wc, e, cursor);
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->id2entry_add = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wt_id2entry_update(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
Entry *e )
|
||||
{
|
||||
return wt_id2entry_put(op, session, e, "overwrite=true");
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->id2entry_update;
|
||||
int rc;
|
||||
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
|
||||
"overwrite=true", &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_id2entry_put: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
wc->id2entry_update = cursor;
|
||||
}
|
||||
rc = wt_id2entry_put(op, wc, e, cursor);
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->id2entry_update = NULL;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wt_id2entry_delete(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
Entry *e )
|
||||
{
|
||||
int rc;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
|
||||
NULL, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry_delete)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
"wt_id2entry_delete: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -104,8 +148,7 @@ int wt_id2entry_delete(
|
|||
rc = cursor->remove(cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry_delete)
|
||||
": remove failed: %s (%d)\n",
|
||||
"wt_id2entry_delete: remove failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -118,24 +161,27 @@ done:
|
|||
}
|
||||
|
||||
int wt_id2entry( BackendDB *be,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
ID id,
|
||||
Entry **ep ){
|
||||
int rc;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
WT_CURSOR *cursor = wc->id2entry;
|
||||
WT_ITEM item;
|
||||
EntryHeader eh;
|
||||
int eoff;
|
||||
Entry *e = NULL;
|
||||
|
||||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY"(entry)", NULL,
|
||||
NULL, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
if(!cursor){
|
||||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY"(entry)", NULL,
|
||||
NULL, &cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_id2entry: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
wc->id2entry = cursor;
|
||||
}
|
||||
|
||||
cursor->set_key(cursor, id);
|
||||
|
|
@ -156,18 +202,25 @@ int wt_id2entry( BackendDB *be,
|
|||
rc = entry_decode( &eh, &e );
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_id2entry)
|
||||
": entry decode error: %d\n",
|
||||
rc );
|
||||
"wt_id2entry: entry decode error: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
e->e_id = id;
|
||||
*ep = e;
|
||||
|
||||
done:
|
||||
|
||||
#ifdef WT_CURSOR_CACHE
|
||||
if(cursor){
|
||||
cursor->reset(cursor);
|
||||
}
|
||||
#else
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
wc->id2entry = NULL;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +263,6 @@ int wt_entry_release(
|
|||
Entry *e,
|
||||
int rw )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
return wt_entry_return( e );
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +277,70 @@ int wt_entry_get(
|
|||
int rw,
|
||||
Entry **ent )
|
||||
{
|
||||
return 0;
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
wt_ctx *wc;
|
||||
Entry *e = NULL;
|
||||
int rc;
|
||||
const char *at_name = at ? at->ad_cname.bv_val : "(null)";
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_entry_get: ndn: \"%s\"\n", ndn->bv_val );
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_entry_get: oc: \"%s\", at: \"%s\"\n",
|
||||
oc ? oc->soc_cname.bv_val : "(null)", at_name );
|
||||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_entry_get: wt_ctx_get failed\n" );
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
rc = wt_dn2entry(op->o_bd, wc, ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"wt_entry_get: cannot find entry: \"%s\"\n",
|
||||
ndn->bv_val );
|
||||
return LDAP_NO_SUCH_OBJECT;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_entry_get: wt_dn2entry failed %s rc=%d\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rc = LDAP_OTHER;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"wt_entry_get: found entry: \"%s\"\n", ndn->bv_val );
|
||||
|
||||
if ( oc && !is_entry_objectclass( e, oc, 0 )) {
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"wt_entry_get: failed to find objectClass %s\n",
|
||||
oc->soc_cname.bv_val );
|
||||
rc = LDAP_NO_SUCH_ATTRIBUTE;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* NOTE: attr_find() or attrs_find()? */
|
||||
if ( at && attr_find( e->e_attrs, at ) == NULL ) {
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"wt_entry_get: failed to find attribute %s\n",
|
||||
at->ad_cname.bv_val );
|
||||
rc = LDAP_NO_SUCH_ATTRIBUTE;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
return_results:
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
wt_entry_return( e );
|
||||
}else{
|
||||
*ent = e;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_entry_get: rc=%d\n", rc );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@
|
|||
#define IDL_MIN(x,y) ( (x) < (y) ? (x) : (y) )
|
||||
#define IDL_CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) )
|
||||
|
||||
#if IDL_DEBUG > 0
|
||||
static void idl_check( ID *ids )
|
||||
void wt_idl_check( ID *ids )
|
||||
{
|
||||
if( WT_IDL_IS_RANGE( ids ) ) {
|
||||
assert( WT_IDL_RANGE_FIRST(ids) <= WT_IDL_RANGE_LAST(ids) );
|
||||
|
|
@ -44,8 +43,7 @@ static void idl_check( ID *ids )
|
|||
}
|
||||
}
|
||||
|
||||
#if IDL_DEBUG > 1
|
||||
static void idl_dump( ID *ids )
|
||||
void wt_idl_dump( ID *ids )
|
||||
{
|
||||
if( WT_IDL_IS_RANGE( ids ) ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
|
|
@ -67,10 +65,8 @@ static void idl_dump( ID *ids )
|
|||
Debug( LDAP_DEBUG_ANY, "\n" );
|
||||
}
|
||||
|
||||
idl_check( ids );
|
||||
wt_idl_check( ids );
|
||||
}
|
||||
#endif /* IDL_DEBUG > 1 */
|
||||
#endif /* IDL_DEBUG > 0 */
|
||||
|
||||
unsigned wt_idl_search( ID *ids, ID id )
|
||||
{
|
||||
|
|
@ -138,7 +134,7 @@ int wt_idl_insert( ID *ids, ID id )
|
|||
Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", (long) id, x );
|
||||
idl_dump( ids );
|
||||
#elif IDL_DEBUG > 0
|
||||
idl_check( ids );
|
||||
wt_idl_check( ids );
|
||||
#endif
|
||||
|
||||
if (WT_IDL_IS_RANGE( ids )) {
|
||||
|
|
@ -183,9 +179,9 @@ int wt_idl_insert( ID *ids, ID id )
|
|||
}
|
||||
|
||||
#if IDL_DEBUG > 1
|
||||
idl_dump( ids );
|
||||
wt_idl_dump( ids );
|
||||
#elif IDL_DEBUG > 0
|
||||
idl_check( ids );
|
||||
wt_idl_check( ids );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
@ -199,7 +195,7 @@ static int wt_idl_delete( ID *ids, ID id )
|
|||
Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x );
|
||||
idl_dump( ids );
|
||||
#elif IDL_DEBUG > 0
|
||||
idl_check( ids );
|
||||
wt_idl_check( ids );
|
||||
#endif
|
||||
|
||||
if (WT_IDL_IS_RANGE( ids )) {
|
||||
|
|
@ -240,9 +236,9 @@ static int wt_idl_delete( ID *ids, ID id )
|
|||
}
|
||||
|
||||
#if IDL_DEBUG > 1
|
||||
idl_dump( ids );
|
||||
wt_idl_dump( ids );
|
||||
#elif IDL_DEBUG > 0
|
||||
idl_check( ids );
|
||||
wt_idl_check( ids );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* WiredTiger is a product of MongoDB Inc.
|
||||
*/
|
||||
|
||||
#ifndef _WI_IDL_H_
|
||||
#ifndef _WT_IDL_H_
|
||||
#define _WT_IDL_H_
|
||||
|
||||
/* IDL sizes - likely should be even bigger
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ac/string.h>
|
||||
#include "back-wt.h"
|
||||
#include "slap-config.h"
|
||||
|
||||
|
|
@ -80,7 +81,6 @@ int wt_index_param(
|
|||
struct berval *prefixp )
|
||||
{
|
||||
AttrInfo *ai;
|
||||
int rc;
|
||||
slap_mask_t mask, type = 0;
|
||||
|
||||
ai = wt_index_mask( be, desc, prefixp );
|
||||
|
|
@ -148,17 +148,15 @@ static int indexer(
|
|||
int opid,
|
||||
slap_mask_t mask )
|
||||
{
|
||||
int rc, i;
|
||||
int rc = LDAP_SUCCESS, i;
|
||||
struct berval *keys;
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
assert( mask != 0 );
|
||||
|
||||
cursor = wt_ctx_index_cursor(wc, atname, 1);
|
||||
cursor = wt_index_open(wc, atname, 1);
|
||||
if( !cursor ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(indexer)
|
||||
": open index cursor failed: %s\n",
|
||||
"indexer: open index cursor failed: %s\n",
|
||||
atname->bv_val );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -236,9 +234,7 @@ static int indexer(
|
|||
}
|
||||
|
||||
done:
|
||||
if(cursor){
|
||||
cursor->close(cursor);
|
||||
}
|
||||
cursor->close(cursor);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +248,7 @@ static int index_at_values(
|
|||
ID id,
|
||||
int opid )
|
||||
{
|
||||
int rc;
|
||||
int rc = LDAP_SUCCESS;
|
||||
slap_mask_t mask = 0;
|
||||
int ixop = opid;
|
||||
AttrInfo *ai = NULL;
|
||||
|
|
@ -382,6 +378,42 @@ wt_index_entry( Operation *op, wt_ctx *wc, int opid, Entry *e )
|
|||
return 0;
|
||||
}
|
||||
|
||||
WT_CURSOR *
|
||||
wt_index_open(wt_ctx *wc, struct berval *name, int create)
|
||||
{
|
||||
WT_CURSOR *cursor = NULL;
|
||||
WT_SESSION *session = wc->session;
|
||||
char uri[1024];
|
||||
int rc;
|
||||
|
||||
snprintf(uri, sizeof(uri), "table:%s", name->bv_val);
|
||||
|
||||
rc = session->open_cursor(session, uri, NULL, "overwrite=false", &cursor);
|
||||
if (rc == ENOENT && create) {
|
||||
rc = session->create(session, uri,
|
||||
"key_format=uQ,"
|
||||
"value_format=x,"
|
||||
"columns=(key, id, none)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_index_open: table \"%s\": "
|
||||
"cannot create index table: %s (%d)\n",
|
||||
uri, wiredtiger_strerror(rc), rc);
|
||||
return NULL;
|
||||
}
|
||||
rc = session->open_cursor(session, uri, NULL,
|
||||
"overwrite=false", &cursor);
|
||||
}
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_index_open: table \"%s\": "
|
||||
": open cursor failed: %s (%d)\n",
|
||||
uri, wiredtiger_strerror(rc), rc);
|
||||
return NULL;
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
|
|
|
|||
|
|
@ -31,17 +31,21 @@ wt_db_init( BackendDB *be, ConfigReply *cr )
|
|||
{
|
||||
struct wt_info *wi;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_db_init) ": Initializing wt backend\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_db_init: Initializing wt backend\n" );
|
||||
|
||||
/* allocate backend-database-specific stuff */
|
||||
wi = ch_calloc( 1, sizeof(struct wt_info) );
|
||||
|
||||
wi->wi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
|
||||
wi->wi_dbenv_config = ch_strdup("create");
|
||||
wi = ch_calloc( 1, sizeof(struct wt_info) );
|
||||
wi->wi_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
|
||||
wi->wi_config = ch_calloc( 1, WT_CONFIG_MAX + 1);
|
||||
if ( slapMode & SLAP_TOOL_READONLY ) {
|
||||
strcpy(wi->wi_config, "readonly");
|
||||
} else {
|
||||
strcpy(wi->wi_config, "create");
|
||||
}
|
||||
wi->wi_lastid = 0;
|
||||
wi->wi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
|
||||
wi->wi_search_stack = NULL;
|
||||
wi->wi_flags = WT_USE_IDLCACHE;
|
||||
|
||||
be->be_private = wi;
|
||||
be->be_cf_ocs = be->bd_info->bi_cf_ocs;
|
||||
|
|
@ -55,51 +59,65 @@ wt_db_open( BackendDB *be, ConfigReply *cr )
|
|||
struct wt_info *wi = (struct wt_info *) be->be_private;
|
||||
int rc;
|
||||
struct stat st;
|
||||
WT_CONNECTION *conn;
|
||||
WT_SESSION *session;
|
||||
WT_SESSION *session = NULL;
|
||||
WT_SESSION *cache_session = NULL;
|
||||
|
||||
if ( be->be_suffix == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": need suffix.\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_db_open: need suffix.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
LDAP_XSTRING(wt_db_open) ": \"%s\"\n",
|
||||
be->be_suffix[0].bv_val );
|
||||
"wt_db_open: \"%s\", home=%s, config=%s\n",
|
||||
be->be_suffix[0].bv_val, wi->wi_home, wi->wi_config );
|
||||
|
||||
/* Check existence of home. Any error means trouble */
|
||||
rc = stat( wi->wi_dbenv_home, &st );
|
||||
rc = stat( wi->wi_home, &st );
|
||||
if( rc ) {
|
||||
int saved_errno = errno;
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot access database directory \"%s\" (%d).\n",
|
||||
be->be_suffix[0].bv_val, wi->wi_dbenv_home, saved_errno );
|
||||
be->be_suffix[0].bv_val, wi->wi_home, saved_errno );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open and create database */
|
||||
rc = wiredtiger_open(wi->wi_dbenv_home, NULL,
|
||||
wi->wi_dbenv_config, &conn);
|
||||
rc = wiredtiger_open(wi->wi_home, NULL,
|
||||
wi->wi_config, &wi->wi_conn);
|
||||
if( rc ) {
|
||||
int saved_errno = errno;
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot open database \"%s\" (%d).\n",
|
||||
be->be_suffix[0].bv_val, wi->wi_dbenv_home, saved_errno );
|
||||
be->be_suffix[0].bv_val, wi->wi_home, saved_errno );
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = conn->open_session(conn, NULL, NULL, &session);
|
||||
rc = wi->wi_conn->open_session(wi->wi_conn, NULL, NULL, &session);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot open session: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( slapMode & SLAP_TOOL_READONLY ) {
|
||||
goto readonly;
|
||||
}
|
||||
|
||||
/* checking for obsolete table */
|
||||
rc = session->verify(session, WT_INDEX_REVDN, NULL);
|
||||
if ( !rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_db_open: database \"%s\": "
|
||||
"incompatible wiredtiger table, please restore from LDIF.\n",
|
||||
be->be_suffix[0].bv_val );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create tables and indexes */
|
||||
rc = session->create(session,
|
||||
WT_TABLE_ID2ENTRY,
|
||||
"key_format=Q,"
|
||||
|
|
@ -107,7 +125,7 @@ wt_db_open( BackendDB *be, ConfigReply *cr )
|
|||
"columns=(id,dn,entry)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot create entry table: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
|
|
@ -116,11 +134,11 @@ wt_db_open( BackendDB *be, ConfigReply *cr )
|
|||
rc = session->create(session,
|
||||
WT_TABLE_DN2ID,
|
||||
"key_format=S,"
|
||||
"value_format=QQS,"
|
||||
"columns=(ndn,id,pid,revdn)");
|
||||
"value_format=SQQ,"
|
||||
"columns=(revdn,ndn,id,pid)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot create entry table: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
|
|
@ -130,7 +148,7 @@ wt_db_open( BackendDB *be, ConfigReply *cr )
|
|||
rc = session->create(session, WT_INDEX_DN, "columns=(dn)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot create dn index: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
|
|
@ -139,36 +157,72 @@ wt_db_open( BackendDB *be, ConfigReply *cr )
|
|||
rc = session->create(session, WT_INDEX_PID, "columns=(pid)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot create pid index: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = session->create(session, WT_INDEX_REVDN, "columns=(revdn)");
|
||||
rc = session->create(session, WT_INDEX_NDN, "columns=(ndn)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": database \"%s\": "
|
||||
"cannot create revdn index: \"%s\"\n",
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot create ndn index: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open in-memory database for idlcache */
|
||||
rc = wiredtiger_open(be->be_suffix[0].bv_val, NULL,
|
||||
"in_memory=true", &wi->wi_cache);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot open database for cache (%s).\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = wi->wi_cache->open_session(wi->wi_cache, NULL, NULL, &cache_session);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot open session for cache: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = cache_session->create(cache_session,
|
||||
WT_TABLE_IDLCACHE,
|
||||
"key_format=Sb,"
|
||||
"value_format=u,"
|
||||
"columns=(ndn,scope,idl)");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_db_open: database \"%s\": "
|
||||
"cannot create idlcache table: \"%s\"\n",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
readonly:
|
||||
rc = wt_last_id( be, session, &wi->wi_lastid);
|
||||
if (rc) {
|
||||
snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
|
||||
"last_id() failed: %s(%d).",
|
||||
be->be_suffix[0].bv_val, wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_open) ": %s\n",
|
||||
cr->msg );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_db_open: %s\n", cr->msg );
|
||||
return rc;
|
||||
}
|
||||
|
||||
session->close(session, NULL);
|
||||
wi->wi_conn = conn;
|
||||
wi->wi_flags |= WT_IS_OPEN;
|
||||
if (session) {
|
||||
session->close(session, NULL);
|
||||
}
|
||||
if (cache_session) {
|
||||
cache_session->close(cache_session, NULL);
|
||||
}
|
||||
|
||||
wi->wi_flags |= WT_IS_OPEN;
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -178,13 +232,15 @@ wt_db_close( BackendDB *be, ConfigReply *cr )
|
|||
struct wt_info *wi = (struct wt_info *) be->be_private;
|
||||
int rc;
|
||||
|
||||
if ( !wi->wi_conn ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = wi->wi_conn->close(wi->wi_conn, NULL);
|
||||
if( rc ) {
|
||||
int saved_errno = errno;
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_db_close)
|
||||
": cannot close database (%d).\n",
|
||||
saved_errno );
|
||||
"wt_db_close: cannot close database (%d).\n", saved_errno );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -198,13 +254,14 @@ wt_db_destroy( Backend *be, ConfigReply *cr )
|
|||
{
|
||||
struct wt_info *wi = (struct wt_info *) be->be_private;
|
||||
|
||||
if( wi->wi_dbenv_home ) {
|
||||
ch_free( wi->wi_dbenv_home );
|
||||
wi->wi_dbenv_home = NULL;
|
||||
if( wi->wi_home ) {
|
||||
ch_free( wi->wi_home );
|
||||
wi->wi_home = NULL;
|
||||
}
|
||||
if( wi->wi_dbenv_config ) {
|
||||
ch_free( wi->wi_dbenv_config );
|
||||
wi->wi_dbenv_config = NULL;
|
||||
|
||||
if( wi->wi_config ) {
|
||||
ch_free( wi->wi_config );
|
||||
wi->wi_config = NULL;
|
||||
}
|
||||
|
||||
wt_attr_index_destroy( wi );
|
||||
|
|
@ -217,7 +274,7 @@ wt_db_destroy( Backend *be, ConfigReply *cr )
|
|||
int
|
||||
wt_back_initialize( BackendInfo *bi )
|
||||
{
|
||||
static char *controls[] = {
|
||||
static const char *controls[] = {
|
||||
LDAP_CONTROL_ASSERT,
|
||||
LDAP_CONTROL_MANAGEDSAIT,
|
||||
LDAP_CONTROL_NOOP,
|
||||
|
|
@ -226,13 +283,15 @@ wt_back_initialize( BackendInfo *bi )
|
|||
LDAP_CONTROL_POST_READ,
|
||||
LDAP_CONTROL_SUBENTRIES,
|
||||
LDAP_CONTROL_X_PERMISSIVE_MODIFY,
|
||||
#ifdef LDAP_X_TXN
|
||||
LDAP_CONTROL_X_TXN_SPEC,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/* initialize the database system */
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_back_initialize)
|
||||
": initialize WiredTiger backend\n" );
|
||||
"wt_back_initialize: initialize WiredTiger backend\n" );
|
||||
|
||||
bi->bi_flags |=
|
||||
SLAP_BFLAG_INCREMENT |
|
||||
|
|
@ -240,10 +299,11 @@ wt_back_initialize( BackendInfo *bi )
|
|||
SLAP_BFLAG_ALIASES |
|
||||
SLAP_BFLAG_REFERRALS;
|
||||
|
||||
bi->bi_controls = controls;
|
||||
/* version check */
|
||||
bi->bi_controls = (char **)controls;
|
||||
|
||||
/* version check */
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_back_initialize) ": %s\n",
|
||||
"wt_back_initialize: %s\n",
|
||||
wiredtiger_version(NULL, NULL, NULL) );
|
||||
|
||||
bi->bi_open = 0;
|
||||
|
|
@ -263,15 +323,19 @@ wt_back_initialize( BackendInfo *bi )
|
|||
bi->bi_op_search = wt_search;
|
||||
bi->bi_op_compare = wt_compare;
|
||||
bi->bi_op_modify = wt_modify;
|
||||
bi->bi_op_modrdn = 0;
|
||||
bi->bi_op_modrdn = wt_modrdn;
|
||||
bi->bi_op_delete = wt_delete;
|
||||
bi->bi_op_abandon = 0;
|
||||
|
||||
bi->bi_extended = 0;
|
||||
bi->bi_extended = wt_extended;
|
||||
#ifdef LDAP_X_TXN
|
||||
bi->bi_op_txn = 0;
|
||||
#endif
|
||||
|
||||
bi->bi_chk_referrals = 0;
|
||||
bi->bi_operational = wt_operational;
|
||||
|
||||
bi->bi_has_subordinates = wt_hasSubordinates;
|
||||
bi->bi_entry_release_rw = wt_entry_release;
|
||||
bi->bi_entry_get_rw = wt_entry_get;
|
||||
|
||||
|
|
@ -283,6 +347,13 @@ wt_back_initialize( BackendInfo *bi )
|
|||
bi->bi_tool_entry_get = wt_tool_entry_get;
|
||||
bi->bi_tool_entry_put = wt_tool_entry_put;
|
||||
bi->bi_tool_entry_reindex = wt_tool_entry_reindex;
|
||||
bi->bi_tool_sync = 0;
|
||||
bi->bi_tool_dn2id_get = wt_tool_dn2id_get;
|
||||
bi->bi_tool_entry_modify = wt_tool_entry_modify;
|
||||
|
||||
#if LDAP_VENDOR_VERSION_MINOR == X || LDAP_VENDOR_VERSION_MINOR >= 5
|
||||
bi->bi_tool_entry_delete = wt_tool_entry_delete;
|
||||
#endif
|
||||
|
||||
bi->bi_connection_init = 0;
|
||||
bi->bi_connection_destroy = 0;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ int
|
|||
wt_key_read(
|
||||
Backend *be,
|
||||
WT_CURSOR *cursor,
|
||||
struct berval *k,
|
||||
struct berval *bkey,
|
||||
ID *ids,
|
||||
WT_CURSOR **saved_cursor,
|
||||
int get_flag
|
||||
|
|
@ -43,33 +43,42 @@ wt_key_read(
|
|||
int exact;
|
||||
WT_ITEM key2;
|
||||
ID id;
|
||||
int comp;
|
||||
long scanned = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> key_read\n" );
|
||||
|
||||
WT_IDL_ZERO(ids);
|
||||
|
||||
bv2ITEM(k, &key);
|
||||
bv2ITEM(bkey, &key);
|
||||
cursor->set_key(cursor, &key, 0);
|
||||
rc = cursor->search_near(cursor, &exact);
|
||||
if( rc ){
|
||||
switch( rc ){
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rc = LDAP_SUCCESS;
|
||||
goto done;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_key_read)
|
||||
": search_near failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
"wt_key_read: search_near failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
do {
|
||||
scanned++;
|
||||
rc = cursor->get_key(cursor, &key2, &id);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_key_read)
|
||||
": get_key failed: %s (%d)\n",
|
||||
"wt_key_read: get_key failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
break;
|
||||
}
|
||||
|
||||
if (key.size != key2.size || memcmp(key.data, key2.data, key.size)) {
|
||||
comp = 0;
|
||||
if (key.size != key2.size ||
|
||||
(comp = memcmp(key2.data, key.data, key.size))) {
|
||||
if(comp > 0){
|
||||
break;
|
||||
}
|
||||
if(exact < 0){
|
||||
rc = cursor->next(cursor);
|
||||
if (rc) {
|
||||
|
|
@ -85,17 +94,17 @@ wt_key_read(
|
|||
rc = cursor->next(cursor);
|
||||
} while(rc == 0);
|
||||
|
||||
if (rc == WT_NOTFOUND ) {
|
||||
if ( rc == WT_NOTFOUND && exact == 0 ) {
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
done:
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<= wt_key_read: failed (%d)\n",
|
||||
rc );
|
||||
Debug( LDAP_DEBUG_TRACE, "<= wt_key_read: failed (%d) %ld scanned\n",
|
||||
rc, scanned );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "<= wt_key_read %ld candidates\n",
|
||||
(long) WT_IDL_N(ids) );
|
||||
Debug( LDAP_DEBUG_TRACE, "<= wt_key_read %ld candidates %ld scanned\n",
|
||||
(long) WT_IDL_N(ids), scanned );
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
@ -131,10 +140,11 @@ wt_key_change(
|
|||
if ( rc == WT_NOTFOUND ) rc = 0;
|
||||
}
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_key_change)
|
||||
": error: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
if ( rc != WT_ROLLBACK ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_key_change: error: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
B * top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
/* ACKNOWLEDGEMENTS:
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ac/string.h>
|
||||
#include "back-wt.h"
|
||||
#include "slap-config.h"
|
||||
|
||||
|
|
@ -150,7 +151,7 @@ int wt_modify_internal(
|
|||
break;
|
||||
}
|
||||
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: delete %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val );
|
||||
err = modify_delete_values( e, mod, get_permissiveModify(op),
|
||||
|
|
@ -164,7 +165,7 @@ int wt_modify_internal(
|
|||
break;
|
||||
|
||||
case LDAP_MOD_REPLACE:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: replace %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val );
|
||||
err = modify_replace_values( e, mod, get_permissiveModify(op),
|
||||
|
|
@ -178,22 +179,21 @@ int wt_modify_internal(
|
|||
break;
|
||||
|
||||
case LDAP_MOD_INCREMENT:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: increment %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val );
|
||||
err = modify_increment_values( e, mod, get_permissiveModify(op),
|
||||
text, textbuf, textlen );
|
||||
if( err != LDAP_SUCCESS ) {
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: %d %s\n",
|
||||
err, *text );
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: %d %s\n", err, *text );
|
||||
} else {
|
||||
got_delete = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_SOFTADD:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: softadd %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val );
|
||||
/* Avoid problems in index_add_mods()
|
||||
|
|
@ -217,7 +217,7 @@ int wt_modify_internal(
|
|||
break;
|
||||
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_modify_internal: softdel %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val );
|
||||
/* Avoid problems in index_delete_mods()
|
||||
|
|
@ -314,8 +314,7 @@ int wt_modify_internal(
|
|||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"entry failed schema check: %s\n",
|
||||
*text );
|
||||
"entry failed schema check: %s\n", *text );
|
||||
}
|
||||
|
||||
/* if NOOP then silently revert to saved attrs */
|
||||
|
|
@ -447,7 +446,7 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
wt_ctx *wc = NULL;
|
||||
Entry *e = NULL;
|
||||
Entry *e = NULL;
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
|
|
@ -460,19 +459,18 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
|
||||
int rc;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(wt_modify) ": %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
Debug( LDAP_DEBUG_ARGS, "wt_modify: %s\n", op->o_req_dn.bv_val );
|
||||
|
||||
#ifdef LDAP_X_TXN
|
||||
if( op->o_txnSpec && txn_preop( op, rs ))
|
||||
return rs->sr_err;
|
||||
#endif
|
||||
|
||||
ctrls[num_ctrls] = NULL;
|
||||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_add)
|
||||
": wt_ctx_get failed\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modify: wt_ctx_get failed\n" );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
send_ldap_result( op, rs );
|
||||
|
|
@ -487,35 +485,75 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
slap_mods_opattrs( op, &op->orm_modlist, 1 );
|
||||
}
|
||||
|
||||
retry:
|
||||
/* begin transaction */
|
||||
wc->is_begin_transaction = 0;
|
||||
rc = wc->session->begin_transaction(wc->session, "isolation=snapshot");
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modify: begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "begin_transaction failed";
|
||||
goto return_results;
|
||||
}
|
||||
wc->is_begin_transaction = 1;
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_modify: session id: %p\n", wc->session );
|
||||
|
||||
/* get entry */
|
||||
rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_delete)
|
||||
": no such object %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
/* TODO: lookup referrals */
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
goto return_results;
|
||||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_modify)
|
||||
": wt_dn2entry failed (%d)\n",
|
||||
rc );
|
||||
"<== wt_modify: wt_dn2entry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( rc == WT_NOTFOUND ||
|
||||
( !manageDSAit && e && is_entry_glue( e ))) {
|
||||
if ( !e ) {
|
||||
rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modify: wt_dna2entry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
|
||||
if ( is_entry_referral( e ) ) {
|
||||
BerVarray ref = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( ref, &e->e_name,
|
||||
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
|
||||
ber_bvarray_free( ref );
|
||||
} else {
|
||||
rs->sr_ref = NULL;
|
||||
}
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( !manageDSAit && is_entry_referral( e ) ) {
|
||||
/* entry is a referral, don't allow modify */
|
||||
rs->sr_ref = get_entry_referrals( op, e );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_modify) ": entry is referral\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_modify: entry is referral\n" );
|
||||
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_matched = e->e_name.bv_val;
|
||||
|
|
@ -541,8 +579,7 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
&slap_pre_read_bv, preread_ctrl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<=- " LDAP_XSTRING(wt_modify) ": pre-read "
|
||||
"failed!\n" );
|
||||
"<=- wt_modify: pre-read failed!\n" );
|
||||
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
|
||||
/* FIXME: is it correct to abort
|
||||
* operation if control fails? */
|
||||
|
|
@ -551,72 +588,46 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
}
|
||||
}
|
||||
|
||||
/* begin transaction */
|
||||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "begin_transaction failed";
|
||||
goto return_results;
|
||||
}
|
||||
Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(wt_modify) ": session id: %p\n",
|
||||
wc->session );
|
||||
|
||||
/* Modify the entry */
|
||||
dummy = *e;
|
||||
rs->sr_err = wt_modify_internal( op, wc, op->orm_modlist,
|
||||
&dummy, &rs->sr_text, textbuf, textlen );
|
||||
if( rs->sr_err != LDAP_SUCCESS ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_modify) ": modify failed (%d)\n",
|
||||
rs->sr_err );
|
||||
switch ( rs->sr_err ) {
|
||||
case LDAP_SUCCESS:
|
||||
break;
|
||||
case WT_ROLLBACK:
|
||||
Debug (LDAP_DEBUG_TRACE, "wt_modify: rollback wt_modify_internal failed.\n" );
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
goto retry;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modify: modify failed (%d)\n", rs->sr_err );
|
||||
/* Only free attrs if they were dup'd. */
|
||||
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* change the entry itself */
|
||||
rs->sr_err = wt_id2entry_update( op, wc->session, &dummy );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_modify) ": id2entry update failed " "(%d)\n",
|
||||
rs->sr_err );
|
||||
if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) {
|
||||
rs->sr_text = "entry too big";
|
||||
} else {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "entry update failed";
|
||||
}
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if( op->o_noop ) {
|
||||
rs->sr_err = wt_id2entry_update( op, wc, &dummy );
|
||||
switch ( rs->sr_err ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_ROLLBACK:
|
||||
Debug (LDAP_DEBUG_TRACE, "wt_modify: rollback wt_id2entry_update failed.\n");
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
rs->sr_err = LDAP_X_NO_OPERATION;
|
||||
goto retry;
|
||||
case LDAP_ADMINLIMIT_EXCEEDED:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modify: id2entry update failed (%d)\n",
|
||||
rs->sr_err);
|
||||
rs->sr_text = "entry too big";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* Only free attrs if they were dup'd. */
|
||||
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
|
||||
|
||||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== " LDAP_XSTRING(wt_modify)
|
||||
": commit failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modify: id2entry update failed (%d)\n",
|
||||
rs->sr_err);
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "commit failed";
|
||||
rs->sr_text = "entry update failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_modify) ": updated%s id=%08lx dn=\"%s\"\n",
|
||||
op->o_noop ? " (no-op)" : "",
|
||||
dummy.e_id, op->o_req_dn.bv_val );
|
||||
|
||||
if( op->o_postread ) {
|
||||
if( postread_ctrl == NULL ) {
|
||||
postread_ctrl = &ctrls[num_ctrls++];
|
||||
|
|
@ -626,8 +637,7 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
&slap_post_read_bv, postread_ctrl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<=- " LDAP_XSTRING(wt_modify)
|
||||
": post-read failed!\n" );
|
||||
"<== wt_modify: post-read failed!\n");
|
||||
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
|
||||
/* FIXME: is it correct to abort
|
||||
* operation if control fails? */
|
||||
|
|
@ -635,10 +645,34 @@ wt_modify( Operation *op, SlapReply *rs )
|
|||
}
|
||||
}
|
||||
}
|
||||
if( num_ctrls ) rs->sr_ctrls = ctrls;
|
||||
|
||||
if( op->o_noop ) {
|
||||
rs->sr_err = LDAP_X_NO_OPERATION;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* Only free attrs if they were dup'd. */
|
||||
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
|
||||
|
||||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
wc->is_begin_transaction = 0;
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_modify: commit failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "commit failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modify: updated%s id=%08lx dn=\"%s\"\n",
|
||||
op->o_noop ? " (no-op)" : "",
|
||||
dummy.e_id, op->o_req_dn.bv_val );
|
||||
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
rs->sr_text = NULL;
|
||||
if( num_ctrls ) rs->sr_ctrls = ctrls;
|
||||
|
||||
return_results:
|
||||
if( dummy.e_attrs ) {
|
||||
|
|
@ -649,6 +683,12 @@ return_results:
|
|||
done:
|
||||
slap_graduate_commit_csn( op );
|
||||
|
||||
if( wc && wc->is_begin_transaction ){
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_modify: rollback transaction\n" );
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
wc->is_begin_transaction = 0;
|
||||
}
|
||||
|
||||
if( e != NULL ) {
|
||||
wt_entry_return( e );
|
||||
}
|
||||
|
|
@ -662,8 +702,6 @@ done:
|
|||
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
rs->sr_text = NULL;
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
|
|
|||
552
servers/slapd/back-wt/modrdn.c
Normal file
552
servers/slapd/back-wt/modrdn.c
Normal file
|
|
@ -0,0 +1,552 @@
|
|||
/* OpenLDAP WiredTiger backend */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2002-2015 The OpenLDAP Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
/* ACKNOWLEDGEMENTS:
|
||||
* This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
|
||||
* based on back-bdb for inclusion in OpenLDAP Software.
|
||||
* WiredTiger is a product of MongoDB Inc.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "back-wt.h"
|
||||
#include "slap-config.h"
|
||||
|
||||
int
|
||||
wt_modrdn( Operation *op, SlapReply *rs )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
AttributeDescription *children = slap_schema.si_ad_children;
|
||||
AttributeDescription *entry = slap_schema.si_ad_entry;
|
||||
wt_ctx *wc = NULL;
|
||||
Entry *e = NULL;
|
||||
Entry *p = NULL;
|
||||
Entry *ne = NULL;
|
||||
Entry dummy = {0};
|
||||
|
||||
struct berval p_dn, p_ndn;
|
||||
struct berval new_dn = {0, NULL}, new_ndn = {0, NULL};
|
||||
|
||||
Entry *np = NULL; /* newSuperior Entry */
|
||||
struct berval *np_dn = NULL; /* newSuperior dn */
|
||||
struct berval *np_ndn = NULL; /* newSuperior ndn */
|
||||
struct berval *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */
|
||||
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
LDAPControl **preread_ctrl = NULL;
|
||||
LDAPControl **postread_ctrl = NULL;
|
||||
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
|
||||
int num_ctrls = 0;
|
||||
|
||||
int rc;
|
||||
|
||||
int parent_is_glue = 0;
|
||||
int parent_is_leaf = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "==> wt_modrdn(%s -> newrdn=%s - newsup=%s)\n",
|
||||
op->o_req_dn.bv_val,
|
||||
op->oq_modrdn.rs_newrdn.bv_val,
|
||||
op->oq_modrdn.rs_newSup?op->oq_modrdn.rs_newSup->bv_val:"NULL" );
|
||||
|
||||
ctrls[num_ctrls] = NULL;
|
||||
|
||||
slap_mods_opattrs( op, &op->orr_modlist, 1 );
|
||||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modrdn: wt_ctx_get failed\n");
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
send_ldap_result( op, rs );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
/* get parent entry */
|
||||
if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
|
||||
rs->sr_err = LDAP_NAMING_VIOLATION;
|
||||
rs->sr_text = "cannot rename suffix entry";
|
||||
goto return_results;
|
||||
} else {
|
||||
dnParent( &op->o_req_ndn, &p_ndn );
|
||||
}
|
||||
|
||||
rc = wt_dn2entry(op->o_bd, wc, &p_ndn, &p);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== wt_modrdn: parent does not exist %s\n", p_ndn.bv_val);
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<== wt_modrdn: wt_dn2entry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* check parent for "children" acl */
|
||||
rc = access_allowed( op, p, children, NULL,
|
||||
op->oq_modrdn.rs_newSup == NULL ?
|
||||
ACL_WRITE : ACL_WDEL, NULL );
|
||||
|
||||
if ( !rc ) {
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: no access to parent\n");
|
||||
rs->sr_text = "no write access to old parent's children";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: wr to children of entry %s OK\n", p_ndn.bv_val );
|
||||
|
||||
if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
|
||||
p_dn = slap_empty_bv;
|
||||
} else {
|
||||
dnParent( &op->o_req_dn, &p_dn );
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: parent dn=%s\n", p_dn.bv_val );
|
||||
|
||||
/* get entry */
|
||||
rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<== wt_modrdn: wt_dn2entry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( rc == WT_NOTFOUND ||
|
||||
( !manageDSAit && e && is_entry_glue( e ) )) {
|
||||
|
||||
if ( !e ) {
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== wt_modrdn: no such object %s\n", op->o_req_dn.bv_val);
|
||||
rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "wt_modrdn: wt_dn2aentry failed (%d)\n", rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
|
||||
if ( is_entry_referral( e ) ) {
|
||||
BerVarray ref = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( ref, &e->e_name,
|
||||
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
|
||||
ber_bvarray_free( ref );
|
||||
} else {
|
||||
rs->sr_ref = NULL;
|
||||
}
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( get_assert( op ) &&
|
||||
( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
|
||||
{
|
||||
rs->sr_err = LDAP_ASSERTION_FAILED;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* check write on old entry */
|
||||
rc = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL );
|
||||
if ( !rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_modrdn: no access to entry\n");
|
||||
rs->sr_text = "no write access to old entry";
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* Can't do it if we have kids */
|
||||
rc = wt_dn2id_has_children( op, wc, e->e_id );
|
||||
if( rc != WT_NOTFOUND ) {
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
Debug(LDAP_DEBUG_ARGS, "<== wt_modrdn: non-leaf %s\n", op->o_req_dn.bv_val);
|
||||
rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
|
||||
rs->sr_text = "subtree rename not supported";
|
||||
break;
|
||||
default:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"<== wt_modrdn: has_children failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
}
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if (!manageDSAit && is_entry_referral( e ) ) {
|
||||
/* parent is a referral, don't allow add */
|
||||
rs->sr_ref = get_entry_referrals( op, e );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: entry %s is referral\n", e->e_dn );
|
||||
|
||||
rs->sr_err = LDAP_REFERRAL,
|
||||
rs->sr_matched = e->e_name.bv_val;
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
ber_bvarray_free( rs->sr_ref );
|
||||
rs->sr_ref = NULL;
|
||||
rs->sr_matched = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_parent_dn = &p_dn; /* New Parent unless newSuperior given */
|
||||
if ( op->oq_modrdn.rs_newSup != NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: new parent \"%s\" requested...\n",
|
||||
op->oq_modrdn.rs_newSup->bv_val );
|
||||
|
||||
/* newSuperior == oldParent? */
|
||||
if( dn_match( &p_ndn, op->oq_modrdn.rs_nnewSup ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: new parent \"%s\" same as the old parent \"%s\"\n",
|
||||
op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val );
|
||||
op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */
|
||||
}
|
||||
}
|
||||
|
||||
if ( op->oq_modrdn.rs_newSup != NULL ) {
|
||||
if ( op->oq_modrdn.rs_newSup->bv_len ) {
|
||||
np_dn = op->oq_modrdn.rs_newSup;
|
||||
np_ndn = op->oq_modrdn.rs_nnewSup;
|
||||
|
||||
/* newSuperior == oldParent? - checked above */
|
||||
/* newSuperior == entry being moved?, if so ==> ERROR */
|
||||
if ( dnIsSuffix( np_ndn, &e->e_nname )) {
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
rs->sr_text = "new superior not found";
|
||||
goto return_results;
|
||||
}
|
||||
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
|
||||
rc = wt_dn2entry(op->o_bd, wc, np_ndn, &np);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<== wt_modrdn: new superior not found: %s\n",
|
||||
np_ndn->bv_val );
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
rs->sr_text = "new superior not found";
|
||||
goto return_results;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<== wt_modrdn: wt_dn2entry failed %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: wr to new parent OK np=%p, id=%ld\n",
|
||||
(void *) np, (long) np->e_id );
|
||||
rs->sr_err = access_allowed( op, np, children,
|
||||
NULL, ACL_WADD, NULL );
|
||||
if( ! rs->sr_err ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: no wr to newSup children\n" );
|
||||
rs->sr_text = "no write access to new superior's children";
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto return_results;
|
||||
}
|
||||
if ( is_entry_alias( np ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: entry is alias\n" );
|
||||
rs->sr_text = "new superior is an alias";
|
||||
rs->sr_err = LDAP_ALIAS_PROBLEM;
|
||||
goto return_results;
|
||||
}
|
||||
if ( is_entry_referral( np ) ) {
|
||||
/* parent is a referral, don't allow add */
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: entry is referral\n" );
|
||||
rs->sr_text = "new superior is a referral";
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
goto return_results;
|
||||
}
|
||||
} else {
|
||||
/* no parent, modrdn entry directly under root */
|
||||
/* TODO: */
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: no parent, not implement yet\n" );
|
||||
rs->sr_text = "not implement yet";
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: wr to new parent's children OK\n" );
|
||||
new_parent_dn = np_dn;
|
||||
}
|
||||
|
||||
/* Build target dn and make sure target entry doesn't exist already. */
|
||||
if (!new_dn.bv_val) {
|
||||
build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL );
|
||||
}
|
||||
|
||||
if (!new_ndn.bv_val) {
|
||||
struct berval bv = {0, NULL};
|
||||
dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
|
||||
ber_dupbv( &new_ndn, &bv );
|
||||
/* FIXME: why not call dnNormalize() w/o ctx? */
|
||||
op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: new ndn=%s\n", new_ndn.bv_val );
|
||||
|
||||
/* check new entry */
|
||||
rc = wt_dn2entry(op->o_bd, wc, &new_ndn, &ne);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
/* Allow rename to same DN */
|
||||
if(e->e_id == ne->e_id){
|
||||
break;
|
||||
}
|
||||
rs->sr_err = LDAP_ALREADY_EXISTS;
|
||||
goto return_results;
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<== wt_modrdn: wt_dn2entry failed %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
assert( op->orr_modlist != NULL );
|
||||
|
||||
if( op->o_preread ) {
|
||||
if( preread_ctrl == NULL ) {
|
||||
preread_ctrl = &ctrls[num_ctrls++];
|
||||
ctrls[num_ctrls] = NULL;
|
||||
}
|
||||
if( slap_read_controls( op, rs, e,
|
||||
&slap_pre_read_bv, preread_ctrl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_modrdn: pre-read failed!\n" );
|
||||
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
|
||||
/* FIXME: is it correct to abort
|
||||
* operation if control fails? */
|
||||
goto return_results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* begin transaction */
|
||||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "begin_transaction failed";
|
||||
goto return_results;
|
||||
}
|
||||
wc->is_begin_transaction = 1;
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: session id: %p\n", wc->session );
|
||||
|
||||
/* delete old DN */
|
||||
rc = wt_dn2id_delete( op, wc, &e->e_nname);
|
||||
if ( rc ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<== wt_modrdn: delete failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "dn2id delete failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* copy the entry, then override some fields */
|
||||
dummy = *e;
|
||||
dummy.e_name = new_dn;
|
||||
dummy.e_nname = new_ndn;
|
||||
dummy.e_attrs = NULL;
|
||||
|
||||
/* add new DN */
|
||||
rc = wt_dn2id_add( op, wc, np?np->e_id:p->e_id, &dummy );
|
||||
if ( rc ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<== wt_modrdn: add failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "DN add failed";
|
||||
goto return_results;
|
||||
}
|
||||
dummy.e_attrs = e->e_attrs;
|
||||
|
||||
rc = wt_modify_internal( op, wc, op->orm_modlist,
|
||||
&dummy, &rs->sr_text, textbuf, textlen );
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"<== wt_modrdn: modify failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* update entry */
|
||||
rc = wt_id2entry_update( op, wc, &dummy );
|
||||
if ( rc != 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: id2entry update failed(%d)\n", rc );
|
||||
if ( rc == LDAP_ADMINLIMIT_EXCEEDED ) {
|
||||
rs->sr_text = "entry too big";
|
||||
} else {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "entry update failed";
|
||||
}
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( p_ndn.bv_len != 0 ) {
|
||||
parent_is_glue = is_entry_glue(p);
|
||||
/* TODO: glue entry handling */
|
||||
}
|
||||
|
||||
if( op->o_postread ) {
|
||||
if( postread_ctrl == NULL ) {
|
||||
postread_ctrl = &ctrls[num_ctrls++];
|
||||
ctrls[num_ctrls] = NULL;
|
||||
}
|
||||
if( slap_read_controls( op, rs, &dummy,
|
||||
&slap_post_read_bv, postread_ctrl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_modrdn: post-read failed!\n" );
|
||||
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
|
||||
/* FIXME: is it correct to abort
|
||||
* operation if control fails? */
|
||||
goto return_results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( op->o_noop ) {
|
||||
rs->sr_err = LDAP_X_NO_OPERATION;
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
wc->is_begin_transaction = 0;
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_modrdn: commit failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "commit failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"wt_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
|
||||
op->o_noop ? " (no-op)" : "",
|
||||
dummy.e_id, op->o_req_dn.bv_val );
|
||||
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
rs->sr_text = NULL;
|
||||
if( num_ctrls ) rs->sr_ctrls = ctrls;
|
||||
|
||||
return_results:
|
||||
if ( dummy.e_attrs ) {
|
||||
attrs_free( dummy.e_attrs );
|
||||
}
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
|
||||
op->o_delete_glue_parent = 1;
|
||||
}
|
||||
|
||||
done:
|
||||
if( wc && wc->is_begin_transaction ){
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_modrdn: rollback transaction\n" );
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
wc->is_begin_transaction = 0;
|
||||
}
|
||||
|
||||
slap_graduate_commit_csn( op );
|
||||
|
||||
if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
|
||||
if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
|
||||
|
||||
/* free entry */
|
||||
if( e != NULL ) {
|
||||
wt_entry_return( e );
|
||||
}
|
||||
/* free parent entry */
|
||||
if( p != NULL ) {
|
||||
wt_entry_return( p );
|
||||
}
|
||||
/* free new entry */
|
||||
if( ne != NULL ) {
|
||||
wt_entry_return( ne );
|
||||
}
|
||||
/* free new parent entry */
|
||||
if( np != NULL ) {
|
||||
wt_entry_return( np );
|
||||
}
|
||||
|
||||
if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
|
||||
slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
|
||||
slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
|
||||
}
|
||||
if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
|
||||
slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
|
||||
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
|
||||
}
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
|
@ -41,8 +41,7 @@ int wt_last_id( BackendDB *be, WT_SESSION *session, ID *out )
|
|||
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL, NULL, &cursor);
|
||||
if(rc){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_last_id)
|
||||
": open_cursor failed: %s (%d)\n",
|
||||
"wt_last_id: open_cursor failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -53,8 +52,7 @@ int wt_last_id( BackendDB *be, WT_SESSION *session, ID *out )
|
|||
rc = cursor->get_key(cursor, &id);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_last_id)
|
||||
": get_key failed: %s (%d)\n",
|
||||
"wt_last_id: get_key failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -66,16 +64,14 @@ int wt_last_id( BackendDB *be, WT_SESSION *session, ID *out )
|
|||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_last_id)
|
||||
": prev failed: %s (%d)\n",
|
||||
"wt_last_id: prev failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
}
|
||||
|
||||
rc = cursor->close(cursor);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_last_id)
|
||||
": close failed: %s (%d)\n",
|
||||
"wt_last_id: close failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,12 +42,11 @@ wt_hasSubordinates(
|
|||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_compare)
|
||||
": wt_ctx_get failed\n" );
|
||||
"wt_hasSubordinates: wt_ctx_get failed\n" );
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
rc = wt_dn2id_has_children(op, wc->session, e->e_id);
|
||||
rc = wt_dn2id_has_children(op, wc, e->e_id);
|
||||
switch(rc){
|
||||
case 0:
|
||||
*hasSubordinates = LDAP_COMPARE_TRUE;
|
||||
|
|
@ -58,8 +57,7 @@ wt_hasSubordinates(
|
|||
break;
|
||||
default:
|
||||
Debug(LDAP_DEBUG_ANY,
|
||||
"<=- " LDAP_XSTRING(wt_hasSubordinates)
|
||||
": has_children failed: %s (%d)\n",
|
||||
"<=- wt_hasSubordinates: has_children failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
rc = LDAP_OTHER;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,15 +26,29 @@ LDAP_BEGIN_DECL
|
|||
|
||||
#define WT_UCTYPE "WT"
|
||||
|
||||
/*
|
||||
* attr.c
|
||||
*/
|
||||
|
||||
AttrInfo *wt_attr_mask( struct wt_info *wi, AttributeDescription *desc );
|
||||
void wt_attr_flush( struct wt_info *wi );
|
||||
void wt_attr_index_unparse( struct wt_info *wi, BerVarray *bva );
|
||||
int wt_attr_index_config(
|
||||
struct wt_info *wi,
|
||||
const char *fname,
|
||||
int lineno,
|
||||
int argc,
|
||||
char **argv,
|
||||
struct config_reply_s *c_reply);
|
||||
void wt_attr_index_destroy( struct wt_info *wi );
|
||||
|
||||
/*
|
||||
* id2entry.c
|
||||
*/
|
||||
int wt_id2entry_add(Operation *op, WT_SESSION *session, Entry *e );
|
||||
int wt_id2entry_update(Operation *op, WT_SESSION *session, Entry *e );
|
||||
int wt_id2entry_delete(Operation *op, WT_SESSION *session, Entry *e );
|
||||
int wt_id2entry(BackendDB *be, wt_ctx *wc, ID id, Entry **ep );
|
||||
int wt_id2entry_add(Operation *op, wt_ctx *wc, Entry *e );
|
||||
int wt_id2entry_update(Operation *op, wt_ctx *wc, Entry *e );
|
||||
int wt_id2entry_delete(Operation *op, wt_ctx *wc, Entry *e );
|
||||
|
||||
BI_entry_release_rw wt_entry_release;
|
||||
BI_entry_get_rw wt_entry_get;
|
||||
|
|
@ -50,12 +64,47 @@ unsigned wt_idl_search( ID *ids, ID id );
|
|||
|
||||
ID wt_idl_first( ID *ids, ID *cursor );
|
||||
ID wt_idl_next( ID *ids, ID *cursor );
|
||||
|
||||
int wt_idl_append_one( ID *ids, ID id );
|
||||
void wt_idl_sort( ID *ids, ID *tmp );
|
||||
int wt_idl_intersection( ID *a, ID *b );
|
||||
int wt_filter_candidates(
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
Filter *f,
|
||||
ID *ids,
|
||||
ID *tmp,
|
||||
ID *stack );
|
||||
int
|
||||
wt_idl_union(
|
||||
ID *a,
|
||||
ID *b );
|
||||
|
||||
/*
|
||||
* index.c
|
||||
*/
|
||||
|
||||
extern AttrInfo *
|
||||
wt_index_mask LDAP_P((
|
||||
Backend *be,
|
||||
AttributeDescription *desc,
|
||||
struct berval *atname ));
|
||||
|
||||
int wt_index_entry LDAP_P(( Operation *op, wt_ctx *wc, int r, Entry *e ));
|
||||
int wt_index_values(
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
AttributeDescription *desc,
|
||||
BerVarray vals,
|
||||
ID id,
|
||||
int opid );
|
||||
int wt_index_param(
|
||||
Backend *be,
|
||||
AttributeDescription *desc,
|
||||
int ftype,
|
||||
slap_mask_t *maskp,
|
||||
struct berval *prefixp );
|
||||
|
||||
WT_CURSOR *wt_index_open(wt_ctx *wc, struct berval *name, int create);
|
||||
|
||||
#define wt_index_entry_add(op,t,e) \
|
||||
wt_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e))
|
||||
|
|
@ -110,23 +159,38 @@ int wt_back_init_cf( BackendInfo *bi );
|
|||
int
|
||||
wt_dn2id(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
ID *id);
|
||||
|
||||
int
|
||||
wt_dn2id_add(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
ID pid,
|
||||
Entry *e);
|
||||
|
||||
int
|
||||
wt_dn2idl(
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
Entry *e,
|
||||
ID *ids,
|
||||
ID *stack);
|
||||
|
||||
int
|
||||
wt_dn2id_delete(
|
||||
Operation *op,
|
||||
WT_SESSION *session,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn);
|
||||
|
||||
int
|
||||
wt_dn2id_has_children(
|
||||
Operation *op,
|
||||
wt_ctx *wc,
|
||||
ID id );
|
||||
|
||||
/*
|
||||
* dn2entry.c
|
||||
*/
|
||||
|
|
@ -139,6 +203,10 @@ int wt_dn2pentry( BackendDB *be,
|
|||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
Entry **ep );
|
||||
int wt_dn2aentry( BackendDB *be,
|
||||
wt_ctx *wc,
|
||||
struct berval *ndn,
|
||||
Entry **ep );
|
||||
|
||||
/*
|
||||
* former ctx.c
|
||||
|
|
@ -146,8 +214,14 @@ int wt_dn2pentry( BackendDB *be,
|
|||
wt_ctx *wt_ctx_init(struct wt_info *wi);
|
||||
void wt_ctx_free(void *key, void *data);
|
||||
wt_ctx *wt_ctx_get(Operation *op, struct wt_info *wi);
|
||||
WT_CURSOR *wt_ctx_index_cursor(wt_ctx *wc, struct berval *name, int create);
|
||||
|
||||
/*
|
||||
* former cache.c
|
||||
*/
|
||||
int wt_idlcache_get(wt_ctx *wc, struct berval *ndn, int scope, ID *ids);
|
||||
int wt_idlcache_set(wt_ctx *wc, struct berval *ndn, int scope, ID *ids);
|
||||
int wt_idlcache_begin(wt_ctx *wc, struct berval *ndn, int scope);
|
||||
int wt_idlcache_clear(Operation *op, wt_ctx *wc, struct berval *ndn);
|
||||
|
||||
/*
|
||||
* former external.h
|
||||
|
|
@ -159,13 +233,16 @@ extern BI_op_add wt_add;
|
|||
extern BI_op_bind wt_bind;
|
||||
extern BI_op_compare wt_compare;
|
||||
extern BI_op_delete wt_delete;
|
||||
extern BI_op_delete wt_modify;
|
||||
|
||||
extern BI_op_modify wt_modify;
|
||||
extern BI_op_modrdn wt_modrdn;
|
||||
extern BI_op_search wt_search;
|
||||
extern BI_op_extended wt_extended;
|
||||
|
||||
extern BI_operational wt_operational;
|
||||
extern BI_has_subordinates wt_hasSubordinates;
|
||||
|
||||
/* tools.c */
|
||||
int wt_entry_header(WT_ITEM *item, EntryHeader *eh);
|
||||
extern BI_tool_entry_open wt_tool_entry_open;
|
||||
extern BI_tool_entry_close wt_tool_entry_close;
|
||||
extern BI_tool_entry_first_x wt_tool_entry_first_x;
|
||||
|
|
@ -175,6 +252,7 @@ extern BI_tool_entry_put wt_tool_entry_put;
|
|||
extern BI_tool_entry_reindex wt_tool_entry_reindex;
|
||||
extern BI_tool_dn2id_get wt_tool_dn2id_get;
|
||||
extern BI_tool_entry_modify wt_tool_entry_modify;
|
||||
extern BI_tool_entry_delete wt_tool_entry_delete;
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ static int base_candidate(
|
|||
ID *ids )
|
||||
{
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
LDAP_XSTRING(base_candidate)
|
||||
": base: \"%s\" (0x%08lx)\n",
|
||||
"base_candidate: base: \"%s\" (0x%08lx)\n",
|
||||
e->e_nname.bv_val, (long) e->e_id );
|
||||
|
||||
ids[0] = 1;
|
||||
|
|
@ -138,8 +137,7 @@ static int search_candidates(
|
|||
AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search_candidates)
|
||||
": base=\"%s\" (0x%08lx) scope=%d\n",
|
||||
"wt_search_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
|
||||
e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope );
|
||||
|
||||
xf.f_or = op->oq_search.rs_filter;
|
||||
|
|
@ -195,9 +193,9 @@ static int search_candidates(
|
|||
if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
|
||||
rc = search_aliases( op, rs, e, wc->session, ids, scopes, stack );
|
||||
if ( WT_IDL_IS_ZERO( ids ) && rc == LDAP_SUCCESS )
|
||||
rc = wt_dn2idl( op, wc->session, &e->e_nname, e, ids, stack );
|
||||
rc = wt_dn2idl( op, wc, &e->e_nname, e, ids, stack );
|
||||
} else {
|
||||
rc = wt_dn2idl(op, wc->session, &e->e_nname, e, ids, stack );
|
||||
rc = wt_dn2idl(op, wc, &e->e_nname, e, ids, stack );
|
||||
}
|
||||
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
|
|
@ -211,14 +209,11 @@ static int search_candidates(
|
|||
|
||||
if( rc ) {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search_candidates)
|
||||
": failed (rc=%d)\n",
|
||||
rc );
|
||||
"wt_search_candidates: failed (rc=%d)\n", rc );
|
||||
|
||||
} else {
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search_candidates)
|
||||
": id=%ld first=%ld last=%ld\n",
|
||||
"wt_search_candidates: id=%ld first=%ld last=%ld\n",
|
||||
(long) ids[0],
|
||||
(long) WT_IDL_FIRST(ids),
|
||||
(long) WT_IDL_LAST(ids));
|
||||
|
|
@ -247,7 +242,7 @@ parse_paged_cookie( Operation *op, SlapReply *rs )
|
|||
goto done;
|
||||
}
|
||||
|
||||
AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
|
||||
memcpy( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
|
||||
|
||||
if ( reqcookie > ps->ps_cookie ) {
|
||||
/* bad cookie */
|
||||
|
|
@ -285,8 +280,7 @@ send_paged_response(
|
|||
struct berval cookie;
|
||||
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
LDAP_XSTRING(send_paged_response)
|
||||
": lastid=0x%08lx nentries=%d\n",
|
||||
"send_paged_response: lastid=0x%08lx nentries=%d\n",
|
||||
lastid ? *lastid : 0, rs->sr_nentries );
|
||||
|
||||
ctrls[1] = NULL;
|
||||
|
|
@ -333,34 +327,28 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
ID id, cursor;
|
||||
ID lastid = NOID;
|
||||
AttributeName *attrs;
|
||||
OpExtra *oex;
|
||||
int manageDSAit;
|
||||
wt_ctx *wc;
|
||||
int rc;
|
||||
int rc = LDAP_OTHER;
|
||||
Entry *e = NULL;
|
||||
Entry *ae = NULL;
|
||||
Entry *base = NULL;
|
||||
slap_mask_t mask;
|
||||
time_t stoptime;
|
||||
|
||||
ID candidates[WT_IDL_UM_SIZE];
|
||||
ID iscopes[WT_IDL_DB_SIZE];
|
||||
ID scopes[WT_IDL_DB_SIZE];
|
||||
int tentries = 0;
|
||||
unsigned nentries = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_search) ": %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
attrs = op->oq_search.rs_attrs;
|
||||
Debug( LDAP_DEBUG_ARGS, "==> wt_search: %s\n", op->o_req_dn.bv_val );
|
||||
|
||||
manageDSAit = get_manageDSAit( op );
|
||||
|
||||
wc = wt_ctx_get(op, wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_search)
|
||||
": wt_ctx_get failed: %d\n",
|
||||
rc );
|
||||
"wt_search: wt_ctx_get failed: %d\n", rc );
|
||||
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -371,20 +359,12 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== " LDAP_XSTRING(wt_search)
|
||||
": no such object %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &ae);
|
||||
break;
|
||||
default:
|
||||
/* TODO: error handling */
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_delete)
|
||||
": error at wt_dn2entry() rc=%d\n",
|
||||
rc );
|
||||
"<== wt_search: error at wt_dn2entry() rc=%d\n", rc );
|
||||
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -394,7 +374,37 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
// TODO
|
||||
if ( ae ) {
|
||||
struct berval matched_dn = BER_BVNULL;
|
||||
/* found ancestor entry */
|
||||
if ( access_allowed( op, ae,
|
||||
slap_schema.si_ad_entry,
|
||||
NULL, ACL_DISCLOSE, NULL ) ) {
|
||||
BerVarray erefs = NULL;
|
||||
ber_dupbv( &matched_dn, &ae->e_name );
|
||||
erefs = is_entry_referral( ae )
|
||||
? get_entry_referrals( op, ae )
|
||||
: NULL;
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_matched = matched_dn.bv_val;
|
||||
if ( erefs ) {
|
||||
rs->sr_ref = referral_rewrite( erefs, &matched_dn,
|
||||
&op->o_req_dn, op->oq_search.rs_scope );
|
||||
ber_bvarray_free( erefs );
|
||||
}
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_search: ancestor is referral\n");
|
||||
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"wt_search: no such object %s\n",
|
||||
op->o_req_dn.bv_val);
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* NOTE: __NEW__ "search" access is required
|
||||
|
|
@ -413,8 +423,27 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
if ( !manageDSAit && is_entry_referral( e ) ) {
|
||||
/* entry is a referral */
|
||||
/* TODO: */
|
||||
struct berval matched_dn = BER_BVNULL;
|
||||
BerVarray erefs = NULL;
|
||||
ber_dupbv( &matched_dn, &e->e_name );
|
||||
erefs = get_entry_referrals( op, e );
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
if ( erefs ) {
|
||||
rs->sr_ref = referral_rewrite( erefs, &matched_dn,
|
||||
&op->o_req_dn, op->oq_search.rs_scope );
|
||||
ber_bvarray_free( erefs );
|
||||
if ( !rs->sr_ref ) {
|
||||
rs->sr_text = "bad_referral object";
|
||||
}
|
||||
}
|
||||
Debug( LDAP_DEBUG_ARGS, "wt_search: entry is referral\n");
|
||||
rs->sr_matched = matched_dn.bv_val;
|
||||
send_ldap_result( op, rs );
|
||||
ber_bvarray_free( rs->sr_ref );
|
||||
rs->sr_ref = NULL;
|
||||
ber_memfree( matched_dn.bv_val );
|
||||
rs->sr_matched = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( get_assert( op ) &&
|
||||
|
|
@ -445,8 +474,7 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
case WT_NOTFOUND:
|
||||
break;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_search) ": error search_candidates\n" );
|
||||
Debug( LDAP_DEBUG_ANY, "wt_search: error search_candidates\n" );
|
||||
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -457,8 +485,7 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
cursor = 0;
|
||||
|
||||
if ( candidates[0] == 0 ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search) ": no candidates\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_search: no candidates\n" );
|
||||
goto nochange;
|
||||
}
|
||||
|
||||
|
|
@ -497,9 +524,7 @@ wt_search( Operation *op, SlapReply *rs )
|
|||
}
|
||||
id = wt_idl_first( candidates, &cursor );
|
||||
if ( id == NOID ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search)
|
||||
": no paged results candidates\n" );
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_search: no paged results candidates\n" );
|
||||
send_paged_response( op, rs, &lastid, 0 );
|
||||
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
|
|
@ -549,7 +574,7 @@ loop_begin:
|
|||
|
||||
fetch_entry_retry:
|
||||
|
||||
rc = wt_id2entry(op->o_bd, wc->session, id, &e);
|
||||
rc = wt_id2entry(op->o_bd, wc, id, &e);
|
||||
/* TODO: error handling */
|
||||
if ( e == NULL ) {
|
||||
/* TODO: */
|
||||
|
|
@ -583,8 +608,11 @@ loop_begin:
|
|||
case LDAP_SCOPE_ONELEVEL:
|
||||
scopeok = 1;
|
||||
break;
|
||||
case LDAP_SCOPE_CHILDREN:
|
||||
if ( id == base->e_id ) break;
|
||||
/* Fall-thru */
|
||||
case LDAP_SCOPE_SUBTREE:
|
||||
scopeok = 1;
|
||||
scopeok = dnIsSuffix(&e->e_nname, &base->e_nname);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -605,9 +633,7 @@ loop_begin:
|
|||
/* Not in scope, ignore it */
|
||||
if ( !scopeok )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search)
|
||||
": %ld scope not okay\n",
|
||||
Debug( LDAP_DEBUG_TRACE, "wt_search: %ld scope not okay\n",
|
||||
(long) id );
|
||||
goto loop_continue;
|
||||
}
|
||||
|
|
@ -620,7 +646,16 @@ loop_begin:
|
|||
if ( !manageDSAit && op->oq_search.rs_scope != LDAP_SCOPE_BASE
|
||||
&& is_entry_referral( e ) )
|
||||
{
|
||||
/* TODO: referral */
|
||||
BerVarray erefs = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL,
|
||||
op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL
|
||||
? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE );
|
||||
rs->sr_entry = e;
|
||||
send_search_reference( op, rs );
|
||||
rs->sr_entry = NULL;
|
||||
ber_bvarray_free( rs->sr_ref );
|
||||
ber_bvarray_free( erefs );
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
if ( !manageDSAit && is_entry_glue( e )) {
|
||||
|
|
@ -632,7 +667,13 @@ loop_begin:
|
|||
if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
|
||||
/* check size limit */
|
||||
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
|
||||
/* TODO: */
|
||||
if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
|
||||
wt_entry_return( e );
|
||||
e = NULL;
|
||||
send_paged_response( op, rs, &lastid, tentries );
|
||||
goto done;
|
||||
}
|
||||
lastid = id;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
|
|
@ -648,19 +689,28 @@ loop_begin:
|
|||
rs->sr_attrs = NULL;
|
||||
rs->sr_entry = NULL;
|
||||
e = NULL;
|
||||
}
|
||||
switch ( rs->sr_err ) {
|
||||
case LDAP_SUCCESS: /* entry sent ok */
|
||||
break;
|
||||
default:
|
||||
/* TODO: error handling */
|
||||
break;
|
||||
|
||||
switch ( rs->sr_err ) {
|
||||
case LDAP_SUCCESS: /* entry sent ok */
|
||||
break;
|
||||
default: /* entry not sent */
|
||||
break;
|
||||
case LDAP_BUSY:
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
case LDAP_UNAVAILABLE:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
goto done;
|
||||
case LDAP_SIZELIMIT_EXCEEDED:
|
||||
rs->sr_ref = rs->sr_v2ref;
|
||||
send_ldap_result( op, rs );
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(wt_search)
|
||||
": %ld does not match filter\n",
|
||||
(long) id );
|
||||
"wt_search: %ld does not match filter\n", (long) id );
|
||||
}
|
||||
|
||||
loop_continue:
|
||||
|
|
@ -676,8 +726,7 @@ nochange:
|
|||
rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL;
|
||||
rs->sr_rspoid = NULL;
|
||||
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
|
||||
/* not implement yet */
|
||||
/* send_paged_response( op, rs, NULL, 0 ); */
|
||||
send_paged_response( op, rs, NULL, 0 );
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
|
|
@ -694,6 +743,10 @@ done:
|
|||
wt_entry_return( e );
|
||||
}
|
||||
|
||||
if( ae ) {
|
||||
wt_entry_return( ae );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,15 +33,11 @@ typedef struct dn_id {
|
|||
|
||||
#define HOLE_SIZE 4096
|
||||
static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
|
||||
static unsigned nhmax = HOLE_SIZE;
|
||||
static unsigned nholes;
|
||||
|
||||
static int index_nattrs;
|
||||
|
||||
static struct berval *tool_base;
|
||||
static int tool_scope;
|
||||
static Filter *tool_filter;
|
||||
static Entry *tool_next_entry;
|
||||
|
||||
static wt_ctx *wc;
|
||||
static WT_CURSOR *reader;
|
||||
|
|
@ -51,14 +47,12 @@ int
|
|||
wt_tool_entry_open( BackendDB *be, int mode )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) be->be_private;
|
||||
WT_CONNECTION *conn = wi->wi_conn;
|
||||
int rc;
|
||||
|
||||
wc = wt_ctx_init(wi);
|
||||
if( !wc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_open)
|
||||
": wt_ctx_get failed\n" );
|
||||
"wt_tool_entry_open: wt_ctx_get failed\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -66,8 +60,7 @@ wt_tool_entry_open( BackendDB *be, int mode )
|
|||
,NULL, NULL, &reader);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_open)
|
||||
": cursor open failed: %s (%d)\n",
|
||||
"wt_tool_entry_open: cursor open failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -78,8 +71,6 @@ wt_tool_entry_open( BackendDB *be, int mode )
|
|||
int
|
||||
wt_tool_entry_close( BackendDB *be )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( reader ) {
|
||||
reader->close(reader);
|
||||
reader = NULL;
|
||||
|
|
@ -127,8 +118,7 @@ wt_tool_entry_next( BackendDB *be )
|
|||
return NOID;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_next)
|
||||
": next failed: %s (%d)\n",
|
||||
"wt_tool_entry_next: next failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NOID;
|
||||
}
|
||||
|
|
@ -136,16 +126,7 @@ wt_tool_entry_next( BackendDB *be )
|
|||
rc = reader->get_key(reader, &id);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_next)
|
||||
": get_key failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
}
|
||||
|
||||
rc = reader->get_value(reader, &item);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_next)
|
||||
": get_value failed: %s (%d)\n",
|
||||
"wt_tool_entry_next: get_key failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
}
|
||||
return id;
|
||||
|
|
@ -169,7 +150,8 @@ entry_getlen(unsigned char **buf)
|
|||
return len;
|
||||
}
|
||||
|
||||
int wt_entry_header(WT_ITEM *item, EntryHeader *eh){
|
||||
int wt_entry_header(WT_ITEM *item, EntryHeader *eh)
|
||||
{
|
||||
unsigned char *ptr = (unsigned char *)item->data;
|
||||
|
||||
/* Some overlays can create empty entries
|
||||
|
|
@ -191,6 +173,22 @@ wt_tool_entry_get( BackendDB *be, ID id )
|
|||
assert( be != NULL );
|
||||
assert( slapMode & SLAP_TOOL_MODE );
|
||||
|
||||
reader->set_key(reader, id);
|
||||
rc = reader->search(reader);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_tool_entry_get: search failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
rc = reader->get_value(reader, &item);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_tool_entry_get: get_value failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = wt_entry_header( &item, &eh );
|
||||
assert( rc == 0 );
|
||||
eoff = eh.data - (char *)item.data;
|
||||
|
|
@ -209,6 +207,7 @@ wt_tool_entry_get( BackendDB *be, ID id )
|
|||
e->e_id = id;
|
||||
}
|
||||
|
||||
done:
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +217,6 @@ static int wt_tool_next_id(
|
|||
struct berval *text,
|
||||
int hole )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
||||
struct berval dn = e->e_name;
|
||||
struct berval ndn = e->e_nname;
|
||||
struct berval pdn, npdn;
|
||||
|
|
@ -231,7 +229,7 @@ static int wt_tool_next_id(
|
|||
return 0;
|
||||
}
|
||||
|
||||
rc = wt_dn2id(op, wc->session, &ndn, &id);
|
||||
rc = wt_dn2id(op, wc, &ndn, &id);
|
||||
if(rc == 0){
|
||||
e->e_id = id;
|
||||
}else if( rc == WT_NOTFOUND ){
|
||||
|
|
@ -258,7 +256,7 @@ static int wt_tool_next_id(
|
|||
pid = id;
|
||||
}
|
||||
wt_next_id( op->o_bd, &e->e_id );
|
||||
rc = wt_dn2id_add(op, wc->session, pid, e);
|
||||
rc = wt_dn2id_add(op, wc, pid, e);
|
||||
if( rc ){
|
||||
snprintf( text->bv_val, text->bv_len,
|
||||
"wt_dn2id_add failed: %s (%d)",
|
||||
|
|
@ -298,11 +296,9 @@ wt_tool_index_add(
|
|||
ID
|
||||
wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) be->be_private;
|
||||
int rc;
|
||||
|
||||
Operation op = {0};
|
||||
Opheader ohdr = {0};
|
||||
Operation op = {0};
|
||||
Opheader ohdr = {0};
|
||||
|
||||
assert( slapMode & SLAP_TOOL_MODE );
|
||||
assert( text != NULL );
|
||||
|
|
@ -310,14 +306,12 @@ wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
|
|||
assert( text->bv_val[0] == '\0' ); /* overconservative? */
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_put)
|
||||
": ( \"%s\" )\n", e->e_dn );
|
||||
"=> wt_tool_entry_put: ( \"%s\" )\n", e->e_dn );
|
||||
|
||||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_add)
|
||||
": begin_transaction failed: %s (%d)\n",
|
||||
"wt_dn2id_add: begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NOID;
|
||||
}
|
||||
|
|
@ -333,18 +327,17 @@ wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
|
|||
"wt_tool_next_id failed: %s (%d)",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
|
||||
text->bv_val );
|
||||
"=> wt_tool_entry_put: %s\n", text->bv_val );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = wt_id2entry_add( &op, wc->session, e );
|
||||
rc = wt_id2entry_add( &op, wc, e );
|
||||
if( rc != 0 ) {
|
||||
snprintf( text->bv_val, text->bv_len,
|
||||
"id2entry_add failed: %s (%d)",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
|
||||
"=> wt_tool_entry_put: %s\n",
|
||||
text->bv_val );
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -356,8 +349,7 @@ wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
|
|||
rc == LDAP_OTHER ? "Internal error" :
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
|
||||
text->bv_val );
|
||||
"=> wt_tool_entry_put: %s\n", text->bv_val );
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -369,8 +361,7 @@ done:
|
|||
"txn_commit failed: %s (%d)",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
|
||||
text->bv_val );
|
||||
"=> wt_tool_entry_put: %s\n", text->bv_val );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
}else{
|
||||
|
|
@ -380,8 +371,7 @@ done:
|
|||
rc == LDAP_OTHER ? "Internal error" :
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
|
||||
text->bv_val );
|
||||
"=> wt_tool_entry_put: %s\n", text->bv_val );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
|
||||
|
|
@ -400,8 +390,7 @@ int wt_tool_entry_reindex(
|
|||
Opheader ohdr = {0};
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld )\n",
|
||||
(long) id );
|
||||
"=> wt_tool_entry_reindex( %ld )\n", (long) id );
|
||||
assert( tool_base == NULL );
|
||||
assert( tool_filter == NULL );
|
||||
|
||||
|
|
@ -443,8 +432,7 @@ int wt_tool_entry_reindex(
|
|||
}
|
||||
if ( j == wi->wi_nattrs ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_reindex)
|
||||
": no index configured for %s\n",
|
||||
"wt_tool_entry_reindex: no index configured for %s\n",
|
||||
adv[i]->ad_cname.bv_val );
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -456,8 +444,7 @@ int wt_tool_entry_reindex(
|
|||
e = wt_tool_entry_get( be, id );
|
||||
|
||||
if( e == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_tool_entry_reindex)
|
||||
Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_reindex"
|
||||
": could not locate id=%ld\n",
|
||||
(long) id );
|
||||
return -1;
|
||||
|
|
@ -471,13 +458,12 @@ int wt_tool_entry_reindex(
|
|||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(wt_dn2id_add)
|
||||
": begin_transaction failed: %s (%d)\n",
|
||||
"wt_tool_entry_reindex: begin_transaction failed %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld, \"%s\" )\n",
|
||||
"=> wt_tool_entry_reindex( %ld, \"%s\" )\n",
|
||||
(long) id, e->e_dn );
|
||||
|
||||
rc = wt_tool_index_add( &op, wc, e );
|
||||
|
|
@ -487,15 +473,13 @@ done:
|
|||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
if( rc ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_reindex)
|
||||
"commit_transaction failed: %s (%d)\n",
|
||||
"=> wt_tool_entry_reindex: commit_transaction failed %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
}
|
||||
}else{
|
||||
rc = wc->session->rollback_transaction(wc->session, NULL);
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(wt_tool_entry_reindex)
|
||||
": rollback transaction %s (%d)\n",
|
||||
"=> wt_tool_entry_reindex: rollback transaction %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
}
|
||||
|
||||
|
|
@ -504,6 +488,221 @@ done:
|
|||
return rc;
|
||||
}
|
||||
|
||||
ID wt_tool_dn2id_get(
|
||||
Backend *be,
|
||||
struct berval *dn
|
||||
)
|
||||
{
|
||||
Operation op = {0};
|
||||
Opheader ohdr = {0};
|
||||
ID id;
|
||||
int rc;
|
||||
|
||||
if ( BER_BVISEMPTY(dn) )
|
||||
return 0;
|
||||
|
||||
op.o_hdr = &ohdr;
|
||||
op.o_bd = be;
|
||||
op.o_tmpmemctx = NULL;
|
||||
op.o_tmpmfuncs = &ch_mfuncs;
|
||||
|
||||
rc = wt_dn2id(&op, wc, dn, &id);
|
||||
switch( rc ){
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
return NOID;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_tool_entry_get: entry get failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NOID;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
ID wt_tool_entry_modify(
|
||||
BackendDB *be,
|
||||
Entry *e,
|
||||
struct berval *text )
|
||||
{
|
||||
int rc;
|
||||
Operation op = {0};
|
||||
Opheader ohdr = {0};
|
||||
|
||||
assert( be != NULL );
|
||||
assert( slapMode & SLAP_TOOL_MODE );
|
||||
|
||||
assert( text != NULL );
|
||||
assert( text->bv_val != NULL );
|
||||
assert( text->bv_val[0] == '\0' ); /* overconservative? */
|
||||
|
||||
assert ( e->e_id != NOID );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_tool_entry_modify( %ld, \"%s\" )\n",
|
||||
(long) e->e_id, e->e_dn );
|
||||
|
||||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify"
|
||||
": begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
return NOID;
|
||||
}
|
||||
|
||||
op.o_hdr = &ohdr;
|
||||
op.o_bd = be;
|
||||
op.o_tmpmemctx = NULL;
|
||||
op.o_tmpmfuncs = &ch_mfuncs;
|
||||
|
||||
rc = wt_id2entry_update( &op, wc, e );
|
||||
if( rc != 0 ) {
|
||||
snprintf( text->bv_val, text->bv_len,
|
||||
"id2entry_update failed: %s (%d)",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify: %s\n",
|
||||
text->bv_val );
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if ( rc == 0 ){
|
||||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
if( rc != 0 ) {
|
||||
snprintf( text->bv_val, text->bv_len,
|
||||
"txn_commit failed: %s (%d)",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify: %s\n",
|
||||
text->bv_val );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
}else{
|
||||
rc = wc->session->rollback_transaction(wc->session, NULL);
|
||||
snprintf( text->bv_val, text->bv_len,
|
||||
"txn_aborted! %s (%d)",
|
||||
rc == LDAP_OTHER ? "Internal error" :
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify: %s\n",
|
||||
text->bv_val );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
|
||||
return e->e_id;
|
||||
}
|
||||
|
||||
int wt_tool_entry_delete(
|
||||
BackendDB *be,
|
||||
struct berval *ndn,
|
||||
struct berval *text )
|
||||
{
|
||||
struct wt_info *wi = (struct wt_info *) be->be_private;
|
||||
int rc;
|
||||
Operation op = {0};
|
||||
Opheader ohdr = {0};
|
||||
Entry *e = NULL;
|
||||
|
||||
assert( be != NULL );
|
||||
assert( slapMode & SLAP_TOOL_MODE );
|
||||
|
||||
assert( text != NULL );
|
||||
assert( text->bv_val != NULL );
|
||||
assert( text->bv_val[0] == '\0' ); /* overconservative? */
|
||||
|
||||
assert ( ndn != NULL );
|
||||
assert ( ndn->bv_val != NULL );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=> wt_tool_entry_delete( %s )\n",
|
||||
ndn->bv_val );
|
||||
|
||||
op.o_hdr = &ohdr;
|
||||
op.o_bd = be;
|
||||
op.o_tmpmemctx = NULL;
|
||||
op.o_tmpmfuncs = &ch_mfuncs;
|
||||
|
||||
/* get entry */
|
||||
rc = wt_dn2entry(op.o_bd, wc, ndn, &e);
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
break;
|
||||
case WT_NOTFOUND:
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"<== wt_tool_entry_delete: no such object %s\n",
|
||||
ndn->bv_val);
|
||||
goto done;
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_tool_entry_delete: error at wt_dn2entry() rc=%d\n",
|
||||
rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = wt_dn2id_has_children( &op, wc, e->e_id );
|
||||
if( rc != WT_NOTFOUND ) {
|
||||
/* subordinate objects must be deleted first */
|
||||
rc = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = wc->session->begin_transaction(wc->session, NULL);
|
||||
if( rc ){
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"wt_tool_entry_delete: begin_transaction failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* delete from dn2id */
|
||||
rc = wt_dn2id_delete( &op, wc, &e->e_nname);
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_tool_entry_delete: dn2id failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* delete indices for old attributes */
|
||||
rc = wt_index_entry_del( &op, wc, e );
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_tool_entry_delete: index delete failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* delete from id2entry */
|
||||
rc = wt_id2entry_delete( &op, wc, e );
|
||||
if ( rc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<== wt_tool_entry_delete: id2entry failed: %s (%d)\n",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
wc->session->rollback_transaction(wc->session, NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = wc->session->commit_transaction(wc->session, NULL);
|
||||
if( rc != 0 ) {
|
||||
snprintf( text->bv_val, text->bv_len,
|
||||
"txn_commit failed: %s (%d)",
|
||||
wiredtiger_strerror(rc), rc );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> wt_tool_entry_delete: %s\n",
|
||||
text->bv_val );
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
/* free entry */
|
||||
if( e != NULL ) {
|
||||
wt_entry_return( e );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: t
|
||||
|
|
|
|||
|
|
@ -20,16 +20,19 @@ BUILD_MDB=@BUILD_MDB@
|
|||
BUILD_SQL=@BUILD_SQL@
|
||||
BUILD_SLAPD=@BUILD_SLAPD@
|
||||
BUILD_BALANCER=@BUILD_BALANCER@
|
||||
BUILD_WT=@BUILD_WT@
|
||||
|
||||
# test primary backends (default)
|
||||
test tests:
|
||||
@$(MAKE) mdb
|
||||
@$(MAKE) lloadd
|
||||
@$(MAKE) wt
|
||||
|
||||
# test all backends
|
||||
alltests: tests
|
||||
@$(MAKE) sql
|
||||
@$(MAKE) ldif
|
||||
@$(MAKE) wt
|
||||
|
||||
mdb test-mdb: mdb-$(BUILD_MDB)
|
||||
mdb-no:
|
||||
|
|
@ -51,6 +54,13 @@ ldif test-ldif: FORCE
|
|||
@echo "Initiating LDAP tests for LDIF..."
|
||||
@$(RUN) -b ldif all
|
||||
|
||||
wt test-wt: wt-$(BUILD_WT)
|
||||
wt-no:
|
||||
@echo "run configure with --enable-wt to run back-wt tests"
|
||||
|
||||
wt-yes wt-mod: FORCE
|
||||
@$(RUN) -b wt all
|
||||
|
||||
lloadd test-lloadd: lloadd-$(BUILD_BALANCER)
|
||||
lloadd-no:
|
||||
@echo "run configure with --enable-balancer to run the Load Balancer tests"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ verify basic functionality of the LDAP libraries and slapd.
|
|||
To run SQL tests, define SLAPD_USE_SQL=<rdbms> and type
|
||||
"make sql"; define SLAPD_USE_SQLWRITE=yes
|
||||
to enable write tests as well.
|
||||
To run WT tests, type "make wt".
|
||||
To run regression tests, type "make regressions"
|
||||
|
||||
The test scripts depends on a number of tools commonly available on
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ AC_asyncmeta=asyncmeta@BUILD_ASYNCMETA@
|
|||
AC_perl=perl@BUILD_PERL@
|
||||
AC_relay=relay@BUILD_RELAY@
|
||||
AC_sql=sql@BUILD_SQL@
|
||||
AC_wt=@BUILD_WT@
|
||||
|
||||
# overlays
|
||||
AC_accesslog=accesslog@BUILD_ACCESSLOG@
|
||||
|
|
@ -188,6 +189,7 @@ INDEXDB=noindexdb MAINDB=nomaindb
|
|||
case $BACKEND in
|
||||
mdb) INDEXDB=indexdb MAINDB=maindb ;;
|
||||
ndb) INDEXDB=indexdb ;;
|
||||
wt) INDEXDB=indexdb ;;
|
||||
esac
|
||||
|
||||
export BACKEND BACKENDTYPE INDEXDB MAINDB \
|
||||
|
|
|
|||
|
|
@ -19,7 +19,12 @@ echo "running defines.sh"
|
|||
if test $REFINT = refintno; then
|
||||
echo "Referential Integrity overlay not available, test skipped"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $BACKEND = wt ; then
|
||||
echo "back-wt does not support subtree rename"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p $TESTDIR $DBDIR1
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@
|
|||
echo "running defines.sh"
|
||||
. $SRCDIR/scripts/defines.sh
|
||||
|
||||
if test $BACKEND = wt ; then
|
||||
echo "back-wt does not support subtree rename"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p $TESTDIR $DBDIR1
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT1..."
|
||||
|
|
|
|||
|
|
@ -20,12 +20,17 @@ echo "running defines.sh"
|
|||
if test $MEMBEROF = memberofno; then
|
||||
echo "Memberof overlay not available, test skipped"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $REFINT = refintno; then
|
||||
echo "Referential Integrity overlay not available, test skipped"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $BACKEND = wt ; then
|
||||
echo "back-wt does not support subtree rename"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p $TESTDIR $DBDIR1 $TESTDIR/confdir
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue