mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
394 lines
7.7 KiB
C
394 lines
7.7 KiB
C
/* OpenLDAP WiredTiger backend */
|
|
/* $OpenLDAP$ */
|
|
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
|
*
|
|
* Copyright 2002-2019 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 "config.h"
|
|
#include "idl.h"
|
|
|
|
char *
|
|
mkrevdn(struct berval src){
|
|
char *dst, *p;
|
|
char *rdn;
|
|
size_t rdn_len;
|
|
|
|
p = dst = ch_malloc(src.bv_len + 2);
|
|
while(src.bv_len){
|
|
rdn = ber_bvrchr( &src, ',' );
|
|
if (rdn) {
|
|
rdn_len = src.bv_len;
|
|
src.bv_len = rdn - src.bv_val;
|
|
rdn_len -= src.bv_len + 1;
|
|
rdn++;
|
|
}else{
|
|
/* first rdn */
|
|
rdn_len = src.bv_len;
|
|
rdn = src.bv_val;
|
|
src.bv_len = 0;
|
|
}
|
|
AC_MEMCPY( p, rdn, rdn_len );
|
|
p += rdn_len;
|
|
*p++ = ',';
|
|
}
|
|
*p = '\0';
|
|
return dst;
|
|
}
|
|
|
|
int
|
|
wt_dn2id_add(
|
|
Operation *op,
|
|
WT_SESSION *session,
|
|
ID pid,
|
|
Entry *e)
|
|
{
|
|
int rc;
|
|
WT_CURSOR *cursor = NULL;
|
|
char *revdn = NULL;
|
|
|
|
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_add 0x%lx: \"%s\"\n",
|
|
e->e_id, e->e_ndn );
|
|
assert( e->e_id != NOID );
|
|
|
|
/* 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);
|
|
rc = cursor->insert(cursor);
|
|
if(rc){
|
|
Debug( LDAP_DEBUG_ANY,
|
|
LDAP_XSTRING(wt_dn2id_add)
|
|
": insert failed: %s (%d)\n",
|
|
wiredtiger_strerror(rc), rc );
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
if(revdn){
|
|
ch_free(revdn);
|
|
}
|
|
if(cursor){
|
|
cursor->close(cursor);
|
|
}
|
|
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id_add 0x%lx: %d\n", e->e_id, rc );
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
wt_dn2id_delete(
|
|
Operation *op,
|
|
WT_SESSION *session,
|
|
struct berval *ndn)
|
|
{
|
|
int rc = 0;
|
|
WT_CURSOR *cursor = 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;
|
|
}
|
|
|
|
cursor->set_key(cursor, ndn->bv_val);
|
|
rc = cursor->remove(cursor);
|
|
if ( rc ) {
|
|
Debug( LDAP_DEBUG_ANY,
|
|
LDAP_XSTRING(wt_dn2id_delete)
|
|
": remove failed: %s (%d)\n",
|
|
wiredtiger_strerror(rc), rc );
|
|
goto done;
|
|
}
|
|
|
|
Debug( LDAP_DEBUG_TRACE,
|
|
"<= wt_dn2id_delete %s: %d\n",
|
|
ndn->bv_val, rc );
|
|
done:
|
|
if(cursor){
|
|
cursor->close(cursor);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
wt_dn2id(
|
|
Operation *op,
|
|
WT_SESSION *session,
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
cursor->set_key(cursor, ndn->bv_val);
|
|
rc = cursor->search(cursor);
|
|
switch( rc ){
|
|
case 0:
|
|
break;
|
|
case WT_NOTFOUND:
|
|
goto done;
|
|
default:
|
|
Debug( LDAP_DEBUG_ANY,
|
|
LDAP_XSTRING(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",
|
|
wiredtiger_strerror(rc), rc );
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
if(cursor){
|
|
cursor->close(cursor);
|
|
}
|
|
|
|
if( rc ) {
|
|
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: get failed: %s (%d)\n",
|
|
wiredtiger_strerror(rc), rc );
|
|
} else {
|
|
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: got id=0x%lx\n",
|
|
*id );
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
wt_dn2id_has_children(
|
|
Operation *op,
|
|
WT_SESSION *session,
|
|
ID id )
|
|
{
|
|
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
|
|
WT_CURSOR *cursor = NULL;
|
|
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;
|
|
}
|
|
|
|
cursor->set_key(cursor, key);
|
|
rc = cursor->search(cursor);
|
|
|
|
done:
|
|
if(cursor){
|
|
cursor->close(cursor);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
wt_dn2idl(
|
|
Operation *op,
|
|
WT_SESSION *session,
|
|
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;
|
|
int rc;
|
|
char *revdn = NULL;
|
|
size_t revdn_len;
|
|
char *key;
|
|
ID id, pid;
|
|
|
|
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;
|
|
}
|
|
|
|
revdn = mkrevdn(*ndn);
|
|
revdn_len = strlen(revdn);
|
|
rc = session->open_cursor(session, WT_INDEX_REVDN"(id, pid)",
|
|
NULL, NULL, &cursor);
|
|
if( rc ){
|
|
Debug( LDAP_DEBUG_ANY,
|
|
LDAP_XSTRING(wt_dn2idl)
|
|
": cursor open 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;
|
|
}
|
|
|
|
do {
|
|
rc = cursor->get_key(cursor, &key);
|
|
if( rc ){
|
|
Debug( LDAP_DEBUG_ANY,
|
|
LDAP_XSTRING(wt_dn2idl)
|
|
": get_key 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);
|
|
}
|
|
rc = cursor->next(cursor);
|
|
}while(rc == 0);
|
|
|
|
if (rc == WT_NOTFOUND ) {
|
|
rc = LDAP_SUCCESS;
|
|
}
|
|
|
|
done:
|
|
if(revdn){
|
|
ch_free(revdn);
|
|
}
|
|
if(cursor){
|
|
cursor->close(cursor);
|
|
}
|
|
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
|
|
|
|
/*
|
|
* Local variables:
|
|
* indent-tabs-mode: t
|
|
* tab-width: 4
|
|
* c-basic-offset: 4
|
|
* End:
|
|
*/
|