summaryrefslogtreecommitdiffstats
path: root/servers/slapd/back-wt/id2entry.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--servers/slapd/back-wt/id2entry.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/servers/slapd/back-wt/id2entry.c b/servers/slapd/back-wt/id2entry.c
new file mode 100644
index 0000000..95b197c
--- /dev/null
+++ b/servers/slapd/back-wt/id2entry.c
@@ -0,0 +1,352 @@
+/* OpenLDAP WiredTiger backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2002-2022 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 "back-wt.h"
+#include "slap-config.h"
+
+static int wt_id2entry_put(
+ Operation *op,
+ wt_ctx *wc,
+ Entry *e,
+ WT_CURSOR *cursor)
+{
+ struct berval bv;
+ WT_ITEM item;
+ int rc;
+
+ rc = entry_encode( e, &bv );
+ if(rc != LDAP_SUCCESS){
+ return -1;
+ }
+ item.size = bv.bv_len;
+ item.data = bv.bv_val;
+
+ 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,
+ "wt_id2entry_put: insert failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+
+done:
+ ch_free( bv.bv_val );
+
+ return rc;
+}
+
+int wt_id2entry_add(
+ Operation *op,
+ wt_ctx *wc,
+ Entry *e )
+{
+ 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_ctx *wc,
+ Entry *e )
+{
+ 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_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,
+ "wt_id2entry_delete: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ cursor->set_key(cursor, e->e_id);
+ rc = cursor->remove(cursor);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_id2entry_delete: remove failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+
+done:
+ if(cursor){
+ cursor->close(cursor);
+ }
+ return rc;
+}
+
+int wt_id2entry( BackendDB *be,
+ wt_ctx *wc,
+ ID id,
+ Entry **ep ){
+ int rc;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->id2entry;
+ WT_ITEM item;
+ EntryHeader eh;
+ int eoff;
+ Entry *e = NULL;
+
+ 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);
+ rc = cursor->search(cursor);
+ if ( rc ) {
+ goto done;
+ }
+
+ cursor->get_value(cursor, &item);
+ rc = wt_entry_header( &item, &eh );
+ eoff = eh.data - (char *)item.data;
+ eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + item.size;
+ eh.bv.bv_val = ch_malloc( eh.bv.bv_len );
+ memset(eh.bv.bv_val, 0xff, eh.bv.bv_len);
+ eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
+ memcpy(eh.data, item.data, item.size);
+ eh.data += eoff;
+ rc = entry_decode( &eh, &e );
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "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;
+}
+
+int wt_entry_return(
+ Entry *e
+ )
+{
+ if ( !e ) {
+ return 0;
+ }
+
+ /* Our entries are allocated in two blocks; the data comes from
+ * the db itself and the Entry structure and associated pointers
+ * are allocated in entry_decode. The db data pointer is saved
+ * in e_bv.
+ */
+ if ( e->e_bv.bv_val ) {
+#if 0
+ /* See if the DNs were changed by modrdn */
+ if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
+ e->e_bv.bv_val + e->e_bv.bv_len ) {
+ ch_free(e->e_name.bv_val);
+ ch_free(e->e_nname.bv_val);
+ }
+#endif
+ e->e_name.bv_val = NULL;
+ e->e_nname.bv_val = NULL;
+ /* In tool mode the e_bv buffer is realloc'd, leave it alone */
+ if( !(slapMode & SLAP_TOOL_MODE) ) {
+ free( e->e_bv.bv_val );
+ }
+ BER_BVZERO( &e->e_bv );
+ }
+
+ entry_free( e );
+}
+
+int wt_entry_release(
+ Operation *op,
+ Entry *e,
+ int rw )
+{
+ return wt_entry_return( e );
+}
+
+/*
+ * return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int wt_entry_get(
+ Operation *op,
+ struct berval *ndn,
+ ObjectClass *oc,
+ AttributeDescription *at,
+ int rw,
+ Entry **ent )
+{
+ 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;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: t
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */