/* OpenLDAP WiredTiger backend */ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * * 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 * . */ /* ACKNOWLEDGEMENTS: * This work was developed by HAMANO Tsukasa * 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: */