From 7b635c7054de5891557f6e92e6ba10a2209574d3 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 3 Mar 2008 10:18:09 +0000 Subject: [PATCH] Deleting, not yet ready for prime time... --- servers/slapd/back-ndb/Makefile.in | 59 -- servers/slapd/back-ndb/TODO | 9 - servers/slapd/back-ndb/add.cpp | 265 ----- servers/slapd/back-ndb/attrsets.conf | 36 - servers/slapd/back-ndb/back-ndb.h | 163 ---- servers/slapd/back-ndb/bind.cpp | 158 --- servers/slapd/back-ndb/compare.cpp | 168 ---- servers/slapd/back-ndb/config.cpp | 287 ------ servers/slapd/back-ndb/delete.cpp | 318 ------ servers/slapd/back-ndb/init.cpp | 403 -------- servers/slapd/back-ndb/modify.cpp | 458 --------- servers/slapd/back-ndb/modrdn.cpp | 504 ---------- servers/slapd/back-ndb/ndbio.cpp | 1356 -------------------------- servers/slapd/back-ndb/proto-ndb.h | 164 ---- servers/slapd/back-ndb/search.cpp | 660 ------------- servers/slapd/back-ndb/tools.cpp | 524 ---------- 16 files changed, 5532 deletions(-) delete mode 100644 servers/slapd/back-ndb/Makefile.in delete mode 100644 servers/slapd/back-ndb/TODO delete mode 100644 servers/slapd/back-ndb/add.cpp delete mode 100644 servers/slapd/back-ndb/attrsets.conf delete mode 100644 servers/slapd/back-ndb/back-ndb.h delete mode 100644 servers/slapd/back-ndb/bind.cpp delete mode 100644 servers/slapd/back-ndb/compare.cpp delete mode 100644 servers/slapd/back-ndb/config.cpp delete mode 100644 servers/slapd/back-ndb/delete.cpp delete mode 100644 servers/slapd/back-ndb/init.cpp delete mode 100644 servers/slapd/back-ndb/modify.cpp delete mode 100644 servers/slapd/back-ndb/modrdn.cpp delete mode 100644 servers/slapd/back-ndb/ndbio.cpp delete mode 100644 servers/slapd/back-ndb/proto-ndb.h delete mode 100644 servers/slapd/back-ndb/search.cpp delete mode 100644 servers/slapd/back-ndb/tools.cpp diff --git a/servers/slapd/back-ndb/Makefile.in b/servers/slapd/back-ndb/Makefile.in deleted file mode 100644 index 84253fd4e1..0000000000 --- a/servers/slapd/back-ndb/Makefile.in +++ /dev/null @@ -1,59 +0,0 @@ -# Makefile.in for back-ndb -# $OpenLDAP$ -## This work is part of OpenLDAP Software . -## -## Copyright 2008 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 initially developed by Howard Chu for inclusion -## in OpenLDAP Software. This work was sponsored by MySQL. - -SRCS = init.cpp tools.cpp config.cpp ndbio.cpp \ - add.cpp bind.cpp compare.cpp delete.cpp modify.cpp modrdn.cpp search.cpp - -OBJS = init.lo tools.lo config.lo ndbio.lo \ - add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo - -LDAP_INCDIR= ../../../include -LDAP_LIBDIR= ../../../libraries - -BUILD_OPT = "--enable-ndb" -BUILD_MOD = @BUILD_NDB@ - -mod_DEFS = -DSLAPD_IMPORT -MOD_DEFS = $(@BUILD_NDB@_DEFS) -MOD_LIBS = $(SLAPD_NDB_LIBS) - -shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) -NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) -UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) - -LIBBASE = back_ndb - -XINCPATH = -I.. -I$(srcdir)/.. @SLAPD_NDB_INCS@ -XDEFS = $(MODULES_CPPFLAGS) - -AC_CXX = g++ -CXX = $(AC_CXX) -LTCXX_MOD = $(LIBTOOL) $(LTONLY_MOD) --mode=compile \ - $(CXX) $(LT_CFLAGS) $(LT_CPPFLAGS) $(MOD_DEFS) -c - -all-local-lib: ../.backend - -.SUFFIXES: .c .o .lo .cpp - -.cpp.lo: - $(LTCXX_MOD) $< - -../.backend: lib$(LIBBASE).a - @touch $@ - diff --git a/servers/slapd/back-ndb/TODO b/servers/slapd/back-ndb/TODO deleted file mode 100644 index 2c4f090903..0000000000 --- a/servers/slapd/back-ndb/TODO +++ /dev/null @@ -1,9 +0,0 @@ -LDAP features not currently supported: - -multi-valued attributes -tagged attributes -extensibleObjects -aliases -referrals -substring indexing -subtree rename diff --git a/servers/slapd/back-ndb/add.cpp b/servers/slapd/back-ndb/add.cpp deleted file mode 100644 index 44c182d82b..0000000000 --- a/servers/slapd/back-ndb/add.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* add.cpp - ldap NDB back-end add routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include - -#include "back-ndb.h" - -extern "C" int -ndb_back_add(Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - Entry p = {0}; - char textbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof textbuf; - AttributeDescription *children = slap_schema.si_ad_children; - AttributeDescription *entry = slap_schema.si_ad_entry; - NdbArgs NA; - NdbRdns rdns; - struct berval matched; - - int num_retries = 0; - int success; - - LDAPControl **postread_ctrl = NULL; - LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; - int num_ctrls = 0; - - Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(ndb_back_add) ": %s\n", - op->oq_add.rs_e->e_name.bv_val, 0, 0); - - ctrls[num_ctrls] = 0; - - /* check entry's schema */ - rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL, - get_relax(op), 1, &rs->sr_text, textbuf, textlen ); - if ( rs->sr_err != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": entry failed schema check: " - "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); - goto return_results; - } - - /* add opattrs to shadow as well, only missing attrs will actually - * be added; helps compatibility with older OL versions */ - 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(ndb_back_add) ": entry failed op attrs add: " - "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); - goto return_results; - } - - /* Get our NDB handle */ - rs->sr_err = ndb_thread_handle( op, &NA.ndb ); - - /* - * Get the parent dn and see if the corresponding entry exists. - */ - if ( be_issuffix( op->o_bd, &op->oq_add.rs_e->e_nname ) ) { - p.e_name = slap_empty_bv; - p.e_nname = slap_empty_bv; - } else { - dnParent( &op->oq_add.rs_e->e_nname, &p.e_nname ); - dnParent( &op->oq_add.rs_e->e_name, &p.e_name ); - } - - op->ora_e->e_id = NOID; - rdns.nr_num = 0; - NA.rdns = &rdns; - - if( 0 ) { -retry: /* transaction retry */ - NA.txn->close(); - NA.txn = NULL; - if ( op->o_abandon ) { - rs->sr_err = SLAPD_ABANDON; - goto return_results; - } - ndb_trans_backoff( ++num_retries ); - } - - NA.txn = NA.ndb->startTransaction(); - rs->sr_text = NULL; - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - /* get entry or parent */ - { - Entry dummy; - dummy.e_name = op->ora_e->e_name; - NA.e = &dummy; - NA.ocs = &matched; - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 0, &matched ); - } - switch( rs->sr_err ) { - case 0: - rs->sr_err = LDAP_ALREADY_EXISTS; - goto return_results; - case LDAP_NO_SUCH_OBJECT: - break; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; -#endif - case LDAP_BUSY: - rs->sr_text = "ldap server busy"; - goto return_results; - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - if ( ber_bvstrcasecmp( &p.e_nname, &matched ) ) { - rs->sr_matched = matched.bv_val; - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": parent " - "does not exist\n", 0, 0, 0 ); - - rs->sr_text = "parent does not exist"; - rs->sr_err = LDAP_NO_SUCH_OBJECT; - goto return_results; - } - - rs->sr_err = access_allowed( op, &p, - children, NULL, ACL_WADD, NULL ); - - if ( ! rs->sr_err ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": no write access to parent\n", - 0, 0, 0 ); - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to parent"; - goto return_results;; - } - - rs->sr_err = access_allowed( op, op->oq_add.rs_e, - entry, NULL, ACL_WADD, NULL ); - - if ( ! rs->sr_err ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": no write access to entry\n", - 0, 0, 0 ); - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to entry"; - goto return_results;; - } - - /* acquire entry ID */ - if ( op->ora_e->e_id == NOID ) { - rs->sr_err = ndb_next_id( op->o_bd, NA.ndb, &op->ora_e->e_id ); - if( rs->sr_err != 0 ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": next_id failed (%d)\n", - rs->sr_err, 0, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - } - - NA.e = op->ora_e; - /* dn2id index */ - rs->sr_err = ndb_entry_put_info( op->o_bd, &NA, 0 ); - - /* id2entry index */ - rs->sr_err = ndb_entry_put_data( op->o_bd, &NA, 0 ); - - /* post-read */ - if( op->o_postread ) { - if( postread_ctrl == NULL ) { - postread_ctrl = &ctrls[num_ctrls++]; - ctrls[num_ctrls] = NULL; - } - if ( slap_read_controls( op, rs, op->oq_add.rs_e, - &slap_post_read_bv, postread_ctrl ) ) - { - Debug( LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_add) ": post-read " - "failed!\n", 0, 0, 0 ); - if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { - /* FIXME: is it correct to abort - * operation if control fails? */ - goto return_results; - } - } - } - - if ( op->o_noop ) { - if (( rs->sr_err=NA.txn->execute( Rollback )) != 0 ) { - rs->sr_text = "txn (no-op) failed"; - } else { - rs->sr_err = LDAP_X_NO_OPERATION; - } - - } else { - if(( rs->sr_err=NA.txn->execute( Commit )) != 0 ) { - rs->sr_text = "txn_commit failed"; - } else { - rs->sr_err = LDAP_SUCCESS; - } - } - - if ( rs->sr_err != LDAP_SUCCESS && rs->sr_err != LDAP_X_NO_OPERATION ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": %s : %s (%d)\n", - rs->sr_text, NA.txn->getNdbError().message, NA.txn->getNdbError().code ); - rs->sr_err = LDAP_OTHER; - goto return_results; - } - NA.txn->close(); - NA.txn = NULL; - - Debug(LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_add) ": added%s id=%08lx dn=\"%s\"\n", - op->o_noop ? " (no-op)" : "", - op->oq_add.rs_e->e_id, op->oq_add.rs_e->e_dn ); - - rs->sr_text = NULL; - if( num_ctrls ) rs->sr_ctrls = ctrls; - -return_results: - success = rs->sr_err; - send_ldap_result( op, rs ); - slap_graduate_commit_csn( op ); - - if( NA.txn != NULL ) { - NA.txn->execute( Rollback ); - NA.txn->close(); - } - - 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; -} diff --git a/servers/slapd/back-ndb/attrsets.conf b/servers/slapd/back-ndb/attrsets.conf deleted file mode 100644 index f135e0ab1e..0000000000 --- a/servers/slapd/back-ndb/attrsets.conf +++ /dev/null @@ -1,36 +0,0 @@ -# Definition of useful attribute sets -# from X.521 section 5 -# -# TelecommunicationAttributeSet ATTRIBUTE ::= { -# facsimileTelephoneNumber | -# internationalISDNNumber | -# telephoneNumber | -# teletexTerminalIdentifier | -# telexNumber | -# preferredDeliveryMethod | -# destinationIndicator | -# registeredAddress | -# x121Address } -# -# PostalAttributeSet ATTRIBUTE ::= { -# physicalDeliveryOfficeName | -# postalAddress | -# postalCode | -# postOfficeBox | -# streetAddress } -# -# LocaleAttributeSet ATTRIBUTE ::= { -# localityName | -# stateOrProvinceName | -# streetAddress } -# -# OrganizationalAttributeSet ATTRIBUTE ::= { -# description | -# LocaleAttributeSet | -# PostalAttributeSet | -# TelecommunicationAttributeSet | -# businessCategory | -# seeAlso | -# searchGuide | -# userPassword } - diff --git a/servers/slapd/back-ndb/back-ndb.h b/servers/slapd/back-ndb/back-ndb.h deleted file mode 100644 index 750eb4e13d..0000000000 --- a/servers/slapd/back-ndb/back-ndb.h +++ /dev/null @@ -1,163 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#ifndef SLAPD_NDB_H -#define SLAPD_NDB_H - -#include "slap.h" - -#include -#include - -LDAP_BEGIN_DECL - -/* The general design is to use one relational table per objectclass. This is - * complicated by objectclass inheritance and auxiliary classes though. - * - * Attributes must only occur in a single table. For objectclasses that inherit - * from other classes, attributes defined in the superior class are only stored - * in the superior class' table. When multiple unrelated classes define the same - * attributes, an attributeSet should be defined instead, containing all of the - * common attributes. - * - * The no_set table lists which other attributeSets apply to the current - * objectClass. The no_attrs table lists all of the non-inherited attributes of - * the class, including those residing in an attributeSet. - * - * Usually the table is named identically to the objectClass, but it can also - * be explicitly named something else if needed. - */ -#define NDB_MAX_OCSETS 8 - -struct ndb_attrinfo; - -typedef struct ndb_ocinfo { - struct berval no_name; /* objectclass cname */ - struct berval no_table; - ObjectClass *no_oc; - struct ndb_ocinfo *no_sets[NDB_MAX_OCSETS]; - struct ndb_attrinfo **no_attrs; - int no_flag; - int no_nsets; - int no_nattrs; -} NdbOcInfo; - -#define NDB_INFO_ATLEN 0x01 -#define NDB_INFO_ATSET 0x02 -#define NDB_INFO_INDEX 0x04 -#define NDB_INFO_ACTIVE 0x08 - -typedef struct ndb_attrinfo { - struct berval na_name; /* attribute cname */ - AttributeDescription *na_desc; - AttributeType *na_attr; - NdbOcInfo *na_oi; - int na_flag; - int na_len; - int na_column; - int na_ixcol; -} NdbAttrInfo; - -typedef struct ListNode { - struct ListNode *ln_next; - void *ln_data; -} ListNode; - -#define NDB_IS_OPEN(ni) (ni->ni_cluster != NULL) - -struct ndb_info { - /* NDB connection */ - char *ni_connectstr; - char *ni_dbname; - Ndb_cluster_connection **ni_cluster; - - /* MySQL connection parameters */ - MYSQL ni_sql; - char *ni_hostname; - char *ni_username; - char *ni_password; - char *ni_socket; - unsigned long ni_clflag; - unsigned int ni_port; - - /* Search filter processing */ - int ni_search_stack_depth; - void *ni_search_stack; - -#define DEFAULT_SEARCH_STACK_DEPTH 16 -#define MINIMUM_SEARCH_STACK_DEPTH 8 - - /* Schema config */ - NdbOcInfo *ni_opattrs; - ListNode *ni_attridxs; - ListNode *ni_attrlens; - ListNode *ni_attrsets; - ldap_pvt_thread_rdwr_t ni_ai_rwlock; - Avlnode *ni_ai_tree; - ldap_pvt_thread_rdwr_t ni_oc_rwlock; - Avlnode *ni_oc_tree; - int ni_nconns; /* number of connections to open */ - int ni_nextconn; /* next conn to use */ - ldap_pvt_thread_mutex_t ni_conn_mutex; -}; - -#define NDB_MAX_RDNS 16 -#define NDB_RDN_LEN 128 -#define NDB_MAX_OCS 64 - -#define DN2ID_TABLE "OL_dn2id" -#define EID_COLUMN 0U -#define OCS_COLUMN 1U -#define RDN_COLUMN 2U -#define IDX_COLUMN (2U+NDB_MAX_RDNS) - -#define NEXTID_TABLE "OL_nextid" - -#define NDB_OC_BUFLEN 1026 /* 1024 data plus 2 len bytes */ - -#define INDEX_NAME "OL_index" - -typedef struct NdbRdns { - short nr_num; - char nr_buf[NDB_MAX_RDNS][NDB_RDN_LEN+1]; -} NdbRdns; - -typedef struct NdbOcs { - int no_ninfo; - int no_ntext; - NdbOcInfo *no_info[NDB_MAX_OCS]; - struct berval no_text[NDB_MAX_OCS]; -} NdbOcs; - -typedef struct NdbArgs { - Ndb *ndb; - NdbTransaction *txn; - Entry *e; - NdbRdns *rdns; - struct berval *ocs; -} NdbArgs; - -#define NDB_NO_SUCH_OBJECT 626 -#define NDB_ALREADY_EXISTS 630 - -LDAP_END_DECL - -#include "proto-ndb.h" - -#endif diff --git a/servers/slapd/back-ndb/bind.cpp b/servers/slapd/back-ndb/bind.cpp deleted file mode 100644 index d8465becb4..0000000000 --- a/servers/slapd/back-ndb/bind.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* bind.cpp - ndb backend bind routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include -#include - -#include "back-ndb.h" - -extern "C" int -ndb_back_bind( Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - Entry e = {0}; - Attribute *a; - - AttributeDescription *password = slap_schema.si_ad_userPassword; - - NdbArgs NA; - - Debug( LDAP_DEBUG_ARGS, - "==> " LDAP_XSTRING(ndb_back_bind) ": dn: %s\n", - op->o_req_dn.bv_val, 0, 0); - - /* allow noauth binds */ - switch ( be_rootdn_bind( op, NULL ) ) { - case SLAP_CB_CONTINUE: - break; - - default: - return rs->sr_err; - } - - /* Get our NDB handle */ - rs->sr_err = ndb_thread_handle( op, &NA.ndb ); - - e.e_name = op->o_req_dn; - e.e_nname = op->o_req_ndn; - -dn2entry_retry: - NA.txn = NA.ndb->startTransaction(); - rs->sr_text = NULL; - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_bind) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto done; - } - - /* get entry */ - { - NdbRdns rdns; - rdns.nr_num = 0; - NA.rdns = &rdns; - NA.ocs = NULL; - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 0, NULL ); - } - switch(rs->sr_err) { - case 0: - break; - case LDAP_NO_SUCH_OBJECT: - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto done; - case LDAP_BUSY: - rs->sr_text = "ldap_server_busy"; - goto done; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto dn2entry_retry; -#endif - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto done; - } - - rs->sr_err = ndb_entry_get_data( op->o_bd, &NA, 0 ); - ber_bvarray_free( NA.ocs ); - ber_dupbv( &op->oq_bind.rb_edn, &e.e_name ); - - /* check for deleted */ - if ( is_entry_subentry( &e ) ) { - /* entry is an subentry, don't allow bind */ - Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0, - 0, 0 ); - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto done; - } - - if ( is_entry_alias( &e ) ) { - /* entry is an alias, don't allow bind */ - Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 ); - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto done; - } - - if ( is_entry_referral( &e ) ) { - Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, - 0, 0 ); - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto done; - } - - switch ( op->oq_bind.rb_method ) { - case LDAP_AUTH_SIMPLE: - a = attr_find( e.e_attrs, password ); - if ( a == NULL ) { - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto done; - } - - if ( slap_passwd_check( op, &e, a, &op->oq_bind.rb_cred, - &rs->sr_text ) != 0 ) - { - /* failure; stop front end from sending result */ - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto done; - } - - rs->sr_err = 0; - break; - - default: - assert( 0 ); /* should not be reachable */ - rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED; - rs->sr_text = "authentication method not supported"; - } - -done: - NA.txn->close(); - if ( rs->sr_err ) { - send_ldap_result( op, rs ); - } - /* front end will send result on success (rs->sr_err==0) */ - return rs->sr_err; -} diff --git a/servers/slapd/back-ndb/compare.cpp b/servers/slapd/back-ndb/compare.cpp deleted file mode 100644 index 907ed8b7b7..0000000000 --- a/servers/slapd/back-ndb/compare.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* compare.cpp - ndb backend compare routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include - -#include "back-ndb.h" - -int -ndb_back_compare( Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - Entry e = {0}; - Attribute *a; - int manageDSAit = get_manageDSAit( op ); - - NdbArgs NA; - NdbRdns rdns; - struct berval matched; - - /* Get our NDB handle */ - rs->sr_err = ndb_thread_handle( op, &NA.ndb ); - - rdns.nr_num = 0; - NA.rdns = &rdns; - e.e_name = op->o_req_dn; - e.e_nname = op->o_req_ndn; - -dn2entry_retry: - NA.txn = NA.ndb->startTransaction(); - rs->sr_text = NULL; - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_compare) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - NA.ocs = NULL; - /* get entry */ - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 0, &matched ); - switch( rs->sr_err ) { - case 0: - break; - case LDAP_NO_SUCH_OBJECT: - rs->sr_matched = matched.bv_val; - goto return_results; - case LDAP_BUSY: - rs->sr_text = "ldap server busy"; - goto return_results; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto dn2entry_retry; -#endif - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - rs->sr_err = ndb_entry_get_data( op->o_bd, &NA, 0 ); - ber_bvarray_free( NA.ocs ); - if (!manageDSAit && is_entry_referral( &e ) ) { - /* 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 { - /* entry is a referral, don't allow compare */ - rs->sr_ref = get_entry_referrals( op, &e ); - rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e.e_name.bv_val; - } - - Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, 0, 0 ); - goto return_results; - } - - if ( get_assert( op ) && - ( test_filter( op, &e, (Filter *)get_assertion( op )) != LDAP_COMPARE_TRUE )) - { - if ( !access_allowed( op, &e, slap_schema.si_ad_entry, - NULL, ACL_DISCLOSE, NULL ) ) - { - rs->sr_err = LDAP_NO_SUCH_OBJECT; - } else { - rs->sr_err = LDAP_ASSERTION_FAILED; - } - goto return_results; - } - - if ( !access_allowed( op, &e, op->oq_compare.rs_ava->aa_desc, - &op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL ) ) - { - /* return error 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_err = LDAP_INSUFFICIENT_ACCESS; - } - goto return_results; - } - - rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE; - - for ( a = attrs_find( e.e_attrs, op->oq_compare.rs_ava->aa_desc ); - a != NULL; - a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) ) - { - rs->sr_err = LDAP_COMPARE_FALSE; - - if ( attr_valfind( a, - SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | - SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, - &op->oq_compare.rs_ava->aa_value, NULL, - op->o_tmpmemctx ) == 0 ) - { - rs->sr_err = LDAP_COMPARE_TRUE; - break; - } - } - -return_results: - NA.txn->close(); - if ( e.e_attrs ) { - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - } - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - - switch ( rs->sr_err ) { - case LDAP_COMPARE_FALSE: - case LDAP_COMPARE_TRUE: - rs->sr_err = LDAP_SUCCESS; - break; - } - - return rs->sr_err; -} diff --git a/servers/slapd/back-ndb/config.cpp b/servers/slapd/back-ndb/config.cpp deleted file mode 100644 index 8b8c302abb..0000000000 --- a/servers/slapd/back-ndb/config.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* config.cpp - ndb backend configuration file routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" -#include "lutil.h" - -#include "back-ndb.h" - -#include "config.h" - -extern "C" { - static ConfigDriver ndb_cf_gen; -}; - -enum { - NDB_ATLEN = 1, - NDB_ATSET, - NDB_INDEX -}; - -static ConfigTable ndbcfg[] = { - { "dbhost", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_hostname), - "( OLcfgDbAt:6.1 NAME 'olcDbHost' " - "DESC 'Hostname of SQL server' " - "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "dbname", "name", 2, 2, 0, ARG_STRING|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_dbname), - "( OLcfgDbAt:6.2 NAME 'olcDbName' " - "DESC 'Name of SQL database' " - "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "dbuser", "username", 2, 2, 0, ARG_STRING|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_username), - "( OLcfgDbAt:6.3 NAME 'olcDbUser' " - "DESC 'Username for SQL session' " - "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "dbpass", "password", 2, 2, 0, ARG_STRING|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_password), - "( OLcfgDbAt:6.4 NAME 'olcDbPass' " - "DESC 'Password for SQL session' " - "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "dbport", "port", 2, 2, 0, ARG_UINT|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_port), - "( OLcfgDbAt:6.5 NAME 'olcDbPort' " - "DESC 'Port number of SQL server' " - "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, - { "dbsocket", "path", 2, 2, 0, ARG_STRING|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_socket), - "( OLcfgDbAt:6.6 NAME 'olcDbSocket' " - "DESC 'Local socket path of SQL server' " - "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "dbflag", "flag", 2, 2, 0, ARG_LONG|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_clflag), - "( OLcfgDbAt:6.7 NAME 'olcDbFlag' " - "DESC 'Flags for SQL session' " - "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, - { "dbconnect", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_connectstr), - "( OLcfgDbAt:6.8 NAME 'olcDbConnect' " - "DESC 'Hostname of NDB server' " - "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "dbconnections", "number", 2, 2, 0, ARG_INT|ARG_OFFSET, - (void *)offsetof(struct ndb_info, ni_nconns), - "( OLcfgDbAt:6.9 NAME 'olcDbConnections' " - "DESC 'Number of cluster connections to open' " - "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, - { "attrlen", "attr> be->be_private; - int i, rc; - NdbAttrInfo *ai; - NdbOcInfo *oci; - ListNode *ln, **l2; - struct berval bv, *bva; - - if ( c->op == SLAP_CONFIG_EMIT ) { - char buf[BUFSIZ]; - rc = 0; - bv.bv_val = buf; - switch( c->type ) { - case NDB_ATLEN: - if ( ni->ni_attrlens ) { - for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) { - ai = (NdbAttrInfo *)ln->ln_data; - bv.bv_len = snprintf( buf, sizeof(buf), - "%s %d", ai->na_name.bv_val, - ai->na_len ); - value_add_one( &c->rvalue_vals, &bv ); - } - } else { - rc = 1; - } - break; - - case NDB_ATSET: - if ( ni->ni_attrsets ) { - char *ptr, *end = buf+sizeof(buf); - for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) { - oci = (NdbOcInfo *)ln->ln_data; - ptr = lutil_strcopy( buf, oci->no_name.bv_val ); - *ptr++ = ' '; - for ( i=0; ino_nattrs; i++ ) { - if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 ) - break; - if ( i ) - *ptr++ = ','; - ptr = lutil_strcopy(ptr, - oci->no_attrs[i]->na_name.bv_val ); - } - bv.bv_len = ptr - buf; - value_add_one( &c->rvalue_vals, &bv ); - } - } else { - rc = 1; - } - break; - - case NDB_INDEX: - if ( ni->ni_attridxs ) { - for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { - ai = (NdbAttrInfo *)ln->ln_data; - value_add_one( &c->rvalue_vals, &ai->na_name ); - } - } else { - rc = 1; - } - break; - - } - return rc; - } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ - rc = 0; - switch( c->type ) { - case NDB_INDEX: - if ( c->valx == -1 ) { - int i; - - /* delete all */ - - } else { - - } - break; - } - return rc; - } - - switch( c->type ) { - case NDB_ATLEN: - ber_str2bv( c->argv[1], 0, 0, &bv ); - ai = ndb_ai_get( ni, &bv ); - if ( !ai ) { - snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", - c->log, c->argv[1] ); - Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); - return -1; - } - for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) { - if ( ln->ln_data == (void *)ai ) { - snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s", - c->log, c->argv[1] ); - Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); - return -1; - } - } - ai->na_len = atoi( c->argv[2] ); - ai->na_flag |= NDB_INFO_ATLEN; - ln = (ListNode *)ch_malloc( sizeof(ListNode)); - ln->ln_data = ai; - ln->ln_next = NULL; - for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next ); - *l2 = ln; - break; - - case NDB_INDEX: - ber_str2bv( c->argv[1], 0, 0, &bv ); - ai = ndb_ai_get( ni, &bv ); - if ( !ai ) { - snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", - c->log, c->argv[1] ); - Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); - return -1; - } - for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) { - if ( ln->ln_data == (void *)ai ) { - snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s", - c->log, c->argv[1] ); - Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); - return -1; - } - } - ai->na_flag |= NDB_INFO_INDEX; - ln = (ListNode *)ch_malloc( sizeof(ListNode)); - ln->ln_data = ai; - ln->ln_next = NULL; - for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next ); - *l2 = ln; - break; - - case NDB_ATSET: - ber_str2bv( c->argv[1], 0, 0, &bv ); - bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',' ); - rc = ndb_aset_get( ni, &bv, bva, &oci ); - ch_free( bva ); - if ( rc ) { - if ( rc == LDAP_ALREADY_EXISTS ) { - snprintf( c->cr_msg, sizeof( c->cr_msg ), - "%s: attrset %s already defined", - c->log, c->argv[1] ); - } else { - snprintf( c->cr_msg, sizeof( c->cr_msg ), - "%s: invalid attrset %s (%d)", - c->log, c->argv[1], rc ); - } - Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); - return -1; - } - ln = (ListNode *)ch_malloc( sizeof(ListNode)); - ln->ln_data = oci; - ln->ln_next = NULL; - for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next ); - *l2 = ln; - break; - } - return 0; -} - -extern "C" -int ndb_back_init_cf( BackendInfo *bi ) -{ - bi->bi_cf_ocs = ndbocs; - - return config_register_schema( ndbcfg, ndbocs ); -} diff --git a/servers/slapd/back-ndb/delete.cpp b/servers/slapd/back-ndb/delete.cpp deleted file mode 100644 index 6c969abe3f..0000000000 --- a/servers/slapd/back-ndb/delete.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* delete.cpp - ndb backend delete routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include - -#include "lutil.h" -#include "back-ndb.h" - -static struct berval glue_bv = BER_BVC("glue"); - -int -ndb_back_delete( Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - Entry e = {0}; - Entry p = {0}; - int manageDSAit = get_manageDSAit( op ); - AttributeDescription *children = slap_schema.si_ad_children; - AttributeDescription *entry = slap_schema.si_ad_entry; - - NdbArgs NA; - NdbRdns rdns; - struct berval matched; - - int num_retries = 0; - - int rc; - - LDAPControl **preread_ctrl = NULL; - LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; - int num_ctrls = 0; - - Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(ndb_back_delete) ": %s\n", - op->o_req_dn.bv_val, 0, 0 ); - - ctrls[num_ctrls] = 0; - - /* allocate CSN */ - if ( BER_BVISNULL( &op->o_csn ) ) { - struct berval csn; - char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; - - csn.bv_val = csnbuf; - csn.bv_len = sizeof(csnbuf); - slap_get_csn( op, &csn, 1 ); - } - - if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) { - dnParent( &op->o_req_dn, &p.e_name ); - dnParent( &op->o_req_ndn, &p.e_nname ); - } - - /* Get our NDB handle */ - rs->sr_err = ndb_thread_handle( op, &NA.ndb ); - rdns.nr_num = 0; - NA.rdns = &rdns; - NA.ocs = NULL; - NA.e = &e; - e.e_name = op->o_req_dn; - e.e_nname = op->o_req_ndn; - - if( 0 ) { -retry: /* transaction retry */ - NA.txn->close(); - NA.txn = NULL; - Debug( LDAP_DEBUG_TRACE, - "==> " LDAP_XSTRING(ndb_back_delete) ": retrying...\n", - 0, 0, 0 ); - if ( op->o_abandon ) { - rs->sr_err = SLAPD_ABANDON; - goto return_results; - } - if ( NA.ocs ) { - ber_bvarray_free( NA.ocs ); - NA.ocs = NULL; - } - ndb_trans_backoff( ++num_retries ); - } - - /* begin transaction */ - NA.txn = NA.ndb->startTransaction(); - rs->sr_text = NULL; - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_delete) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - /* get entry */ - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 1, &matched ); - switch( rs->sr_err ) { - case 0: - case LDAP_NO_SUCH_OBJECT: - break; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; -#endif - case LDAP_BUSY: - rs->sr_text = "ldap server busy"; - goto return_results; - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - if ( rs->sr_err == LDAP_NO_SUCH_OBJECT || - ( !manageDSAit && bvmatch( NA.ocs, &glue_bv ))) { - Debug( LDAP_DEBUG_ARGS, - "<=- " LDAP_XSTRING(ndb_back_delete) ": no such object %s\n", - op->o_req_dn.bv_val, 0, 0); - - if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) { - rs->sr_matched = matched.bv_val; - } else { - rs->sr_matched = p.e_name.bv_val; - rs->sr_err = LDAP_NO_SUCH_OBJECT; - } - goto return_results; - } - - /* check parent for "children" acl */ - rs->sr_err = access_allowed( op, &p, - children, NULL, ACL_WDEL, NULL ); - - if ( !rs->sr_err ) { - Debug( LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_delete) ": no write " - "access to parent\n", 0, 0, 0 ); - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to parent"; - goto return_results; - } - - rs->sr_err = ndb_entry_get_data( op->o_bd, &NA, 1 ); - - rs->sr_err = access_allowed( op, &e, - entry, NULL, ACL_WDEL, NULL ); - - if ( !rs->sr_err ) { - Debug( LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_delete) ": no write access " - "to entry\n", 0, 0, 0 ); - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to entry"; - goto return_results; - } - - if ( !manageDSAit && is_entry_referral( &e ) ) { - /* entry is a referral, don't allow delete */ - rs->sr_ref = get_entry_referrals( op, &e ); - - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_delete) ": entry is referral\n", - 0, 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e.e_name.bv_val; - rs->sr_flags = REP_REF_MUSTBEFREED; - goto return_results; - } - - if ( get_assert( op ) && - ( test_filter( op, &e, (Filter *)get_assertion( op )) != LDAP_COMPARE_TRUE )) - { - rs->sr_err = LDAP_ASSERTION_FAILED; - goto return_results; - } - - /* pre-read */ - 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, - "<=- " LDAP_XSTRING(ndb_back_delete) ": pre-read " - "failed!\n", 0, 0, 0 ); - if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { - /* FIXME: is it correct to abort - * operation if control fails? */ - goto return_results; - } - } - } - - /* Can't do it if we have kids */ - rs->sr_err = ndb_has_children( &NA, &rc ); - if ( rs->sr_err ) { - Debug(LDAP_DEBUG_ARGS, - "<=- " LDAP_XSTRING(ndb_back_delete) - ": has_children failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - if ( rc == LDAP_COMPARE_TRUE ) { - Debug(LDAP_DEBUG_ARGS, - "<=- " LDAP_XSTRING(ndb_back_delete) - ": non-leaf %s\n", - op->o_req_dn.bv_val, 0, 0); - rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; - rs->sr_text = "subordinate objects must be deleted first"; - goto return_results; - } - - /* delete info */ - rs->sr_err = ndb_entry_del_info( op->o_bd, &NA ); - if ( rs->sr_err != 0 ) { - Debug(LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_delete) ": del_info failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); - rs->sr_text = "DN index delete failed"; - rs->sr_err = LDAP_OTHER; - goto return_results; - } - - /* delete data */ - rs->sr_err = ndb_entry_del_data( op->o_bd, &NA ); - if ( rs->sr_err != 0 ) { - Debug( LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_delete) ": del_data failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); - rs->sr_text = "entry delete failed"; - rs->sr_err = LDAP_OTHER; - goto return_results; - } - - if( op->o_noop ) { - if (( rs->sr_err=NA.txn->execute( Rollback )) != 0 ) { - rs->sr_text = "txn (no-op) failed"; - } else { - rs->sr_err = LDAP_X_NO_OPERATION; - } - } else { - if(( rs->sr_err=NA.txn->execute( Commit )) != 0 ) { - rs->sr_text = "txn_commit failed"; - } else { - rs->sr_err = LDAP_SUCCESS; - } - } - - if( rs->sr_err != LDAP_SUCCESS && rs->sr_err != LDAP_X_NO_OPERATION ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_delete) ": txn_%s failed: %s (%d)\n", - op->o_noop ? "abort (no-op)" : "commit", - NA.txn->getNdbError().message, NA.txn->getNdbError().code ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "commit failed"; - - goto return_results; - } - NA.txn->close(); - NA.txn = NULL; - - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_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; - rs->sr_text = NULL; - if( num_ctrls ) rs->sr_ctrls = ctrls; - -return_results: - if ( NA.ocs ) { - ber_bvarray_free( NA.ocs ); - NA.ocs = NULL; - } - - /* free entry */ - if( e.e_attrs != NULL ) { - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - } - - if( NA.txn != NULL ) { - NA.txn->execute( Rollback ); - NA.txn->close(); - } - - send_ldap_result( op, rs ); - slap_graduate_commit_csn( op ); - - 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 ); - } - return rs->sr_err; -} diff --git a/servers/slapd/back-ndb/init.cpp b/servers/slapd/back-ndb/init.cpp deleted file mode 100644 index 82dcfa00b8..0000000000 --- a/servers/slapd/back-ndb/init.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/* init.cpp - initialize ndb backend */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include -#include -#include -#include -#include -#include "back-ndb.h" -#include -#include "config.h" - -extern "C" { - static BI_db_init ndb_db_init; - static BI_db_close ndb_db_close; - static BI_db_open ndb_db_open; - static BI_db_destroy ndb_db_destroy; -} - -static struct berval ndb_optable = BER_BVC("OL_opattrs"); - -static struct berval ndb_opattrs[] = { - BER_BVC("structuralObjectClass"), - BER_BVC("entryUUID"), - BER_BVC("creatorsName"), - BER_BVC("createTimestamp"), - BER_BVC("entryCSN"), - BER_BVC("modifiersName"), - BER_BVC("modifyTimestamp"), - BER_BVNULL -}; - -static int ndb_oplens[] = { - 0, /* structuralOC, default */ - 36, /* entryUUID */ - 0, /* creatorsName, default */ - 26, /* createTimestamp */ - 40, /* entryCSN */ - 0, /* modifiersName, default */ - 26, /* modifyTimestamp */ - -1 -}; - -static int -ndb_db_init( BackendDB *be, ConfigReply *cr ) -{ - struct ndb_info *ni; - int rc = 0; - - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_db_init) ": Initializing ndb database\n", - 0, 0, 0 ); - - /* allocate backend-database-specific stuff */ - ni = (struct ndb_info *) ch_calloc( 1, sizeof(struct ndb_info) ); - - be->be_private = ni; - be->be_cf_ocs = be->bd_info->bi_cf_ocs; - - ni->ni_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH; - - ldap_pvt_thread_rdwr_init( &ni->ni_ai_rwlock ); - ldap_pvt_thread_rdwr_init( &ni->ni_oc_rwlock ); - ldap_pvt_thread_mutex_init( &ni->ni_conn_mutex ); - -#ifdef DO_MONITORING - rc = ndb_monitor_db_init( be ); -#endif - - return rc; -} - -static int -ndb_db_close( BackendDB *be, ConfigReply *cr ); - -static int -ndb_db_open( BackendDB *be, ConfigReply *cr ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - char sqlbuf[BUFSIZ], *ptr; - int rc, i; - - if ( be->be_suffix == NULL ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: need suffix" ); - Debug( LDAP_DEBUG_ANY, "%s\n", - cr->msg, 0, 0 ); - return -1; - } - - Debug( LDAP_DEBUG_ARGS, - LDAP_XSTRING(ndb_db_open) ": \"%s\"\n", - be->be_suffix[0].bv_val, 0, 0 ); - - if ( ni->ni_nconns < 1 ) - ni->ni_nconns = 1; - - ni->ni_cluster = (Ndb_cluster_connection **)ch_malloc( ni->ni_nconns * sizeof( Ndb_cluster_connection *)); - for ( i=0; ini_nconns; i++ ) { - ni->ni_cluster[i] = new Ndb_cluster_connection( ni->ni_connectstr ); - rc = ni->ni_cluster[i]->connect( 4, 5, 1 ); - } - for ( i=0; ini_nconns; i++ ) { - rc = ni->ni_cluster[i]->wait_until_ready( 30, 0 ); - } - - mysql_init( &ni->ni_sql ); - if ( !mysql_real_connect( &ni->ni_sql, ni->ni_hostname, ni->ni_username, ni->ni_password, - "", ni->ni_port, ni->ni_socket, ni->ni_clflag )) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: mysql_real_connect failed, %s (%d)", - mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - rc = -1; - goto fail; - } - - sprintf( sqlbuf, "CREATE DATABASE IF NOT EXISTS %s", ni->ni_dbname ); - rc = mysql_query( &ni->ni_sql, sqlbuf ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: CREATE DATABASE %s failed, %s (%d)", - ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - goto fail; - } - - sprintf( sqlbuf, "USE %s", ni->ni_dbname ); - rc = mysql_query( &ni->ni_sql, sqlbuf ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: USE DATABASE %s failed, %s (%d)", - ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - goto fail; - } - - ptr = sqlbuf; - ptr += sprintf( ptr, "CREATE TABLE IF NOT EXISTS " DN2ID_TABLE " (" - "eid bigint unsigned NOT NULL, " - "object_classes VARCHAR(1024) NOT NULL, " - "a0 VARCHAR(128) NOT NULL DEFAULT '', " - "a1 VARCHAR(128) NOT NULL DEFAULT '', " - "a2 VARCHAR(128) NOT NULL DEFAULT '', " - "a3 VARCHAR(128) NOT NULL DEFAULT '', " - "a4 VARCHAR(128) NOT NULL DEFAULT '', " - "a5 VARCHAR(128) NOT NULL DEFAULT '', " - "a6 VARCHAR(128) NOT NULL DEFAULT '', " - "a7 VARCHAR(128) NOT NULL DEFAULT '', " - "a8 VARCHAR(128) NOT NULL DEFAULT '', " - "a9 VARCHAR(128) NOT NULL DEFAULT '', " - "a10 VARCHAR(128) NOT NULL DEFAULT '', " - "a11 VARCHAR(128) NOT NULL DEFAULT '', " - "a12 VARCHAR(128) NOT NULL DEFAULT '', " - "a13 VARCHAR(128) NOT NULL DEFAULT '', " - "a14 VARCHAR(128) NOT NULL DEFAULT '', " - "a15 VARCHAR(128) NOT NULL DEFAULT '', " - "PRIMARY KEY (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), " - "UNIQUE KEY eid (eid) USING HASH" ); - /* Create index columns */ - if ( ni->ni_attridxs ) { - ListNode *ln; - int newcol = 0; - - *ptr++ = ','; - *ptr++ = ' '; - for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { - NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data; - ptr += sprintf( ptr, "`%s` VARCHAR(%d), ", - ai->na_name.bv_val, ai->na_len ); - } - ptr = lutil_strcopy(ptr, "KEY " INDEX_NAME " (" ); - - for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { - NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data; - if ( newcol ) *ptr++ = ','; - *ptr++ = '`'; - ptr = lutil_strcopy( ptr, ai->na_name.bv_val ); - *ptr++ = '`'; - ai->na_ixcol = newcol + 18; - newcol++; - } - *ptr++ = ')'; - } - strcpy( ptr, ") ENGINE=ndb" ); - rc = mysql_query( &ni->ni_sql, sqlbuf ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: CREATE TABLE " DN2ID_TABLE " failed, %s (%d)", - mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - goto fail; - } - - rc = mysql_query( &ni->ni_sql, "CREATE TABLE IF NOT EXISTS " NEXTID_TABLE " (" - "a bigint unsigned AUTO_INCREMENT PRIMARY KEY ) ENGINE=ndb" ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: CREATE TABLE " NEXTID_TABLE " failed, %s (%d)", - mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - goto fail; - } - - { - NdbOcInfo *oci; - - rc = ndb_aset_get( ni, &ndb_optable, ndb_opattrs, &oci ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: ndb_aset_get( %s ) failed (%d)", - ndb_optable.bv_val, rc ); - goto fail; - } - for ( i=0; ndb_oplens[i] >= 0; i++ ) { - if ( ndb_oplens[i] ) - oci->no_attrs[i]->na_len = ndb_oplens[i]; - } - rc = ndb_aset_create( ni, oci ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: ndb_aset_create( %s ) failed (%d)", - ndb_optable.bv_val, rc ); - goto fail; - } - ni->ni_opattrs = oci; - } - /* Create attribute sets */ - { - ListNode *ln; - - for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) { - NdbOcInfo *oci = (NdbOcInfo *)ln->ln_data; - rc = ndb_aset_create( ni, oci ); - if ( rc ) { - snprintf( cr->msg, sizeof( cr->msg ), - "ndb_db_open: ndb_aset_create( %s ) failed (%d)", - oci->no_name.bv_val, rc ); - goto fail; - } - } - } - /* Initialize any currently used objectClasses */ - { - Ndb *ndb; - const NdbDictionary::Dictionary *myDict; - - ndb = new Ndb( ni->ni_cluster[0], ni->ni_dbname ); - ndb->init(1024); - - myDict = ndb->getDictionary(); - ndb_oc_read( ni, myDict ); - delete ndb; - } - -#ifdef DO_MONITORING - /* monitor setup */ - rc = ndb_monitor_db_open( be ); - if ( rc != 0 ) { - goto fail; - } -#endif - - return 0; - -fail: - Debug( LDAP_DEBUG_ANY, "%s\n", - cr->msg, 0, 0 ); - ndb_db_close( be, NULL ); - return rc; -} - -static int -ndb_db_close( BackendDB *be, ConfigReply *cr ) -{ - int i, rc; - struct ndb_info *ni = (struct ndb_info *) be->be_private; - - mysql_close( &ni->ni_sql ); - for ( i=0; ini_nconns; i++ ) { - delete ni->ni_cluster[i]; - ni->ni_cluster[i] = NULL; - } - ch_free( ni->ni_cluster ); - ni->ni_cluster = NULL; - -#ifdef DO_MONITORING - /* monitor handling */ - (void)ndb_monitor_db_close( be ); -#endif - - return 0; -} - -static int -ndb_db_destroy( BackendDB *be, ConfigReply *cr ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - -#ifdef DO_MONITORING - /* monitor handling */ - (void)ndb_monitor_db_destroy( be ); -#endif - - ldap_pvt_thread_mutex_destroy( &ni->ni_conn_mutex ); - ldap_pvt_thread_rdwr_destroy( &ni->ni_ai_rwlock ); - ldap_pvt_thread_rdwr_destroy( &ni->ni_oc_rwlock ); - - ch_free( ni ); - be->be_private = NULL; - - return 0; -} - -extern "C" int -ndb_back_initialize( - BackendInfo *bi ) -{ - int rc = 0; - - /* initialize the underlying database system */ - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_initialize) ": initialize ndb backend\n", 0, 0, 0 ); - - ndb_init(); - - bi->bi_open = 0; - bi->bi_close = 0; - bi->bi_config = 0; - bi->bi_destroy = 0; - - bi->bi_db_init = ndb_db_init; - bi->bi_db_config = config_generic_wrapper; - bi->bi_db_open = ndb_db_open; - bi->bi_db_close = ndb_db_close; - bi->bi_db_destroy = ndb_db_destroy; - - bi->bi_op_add = ndb_back_add; - bi->bi_op_bind = ndb_back_bind; - bi->bi_op_compare = ndb_back_compare; - bi->bi_op_delete = ndb_back_delete; - bi->bi_op_modify = ndb_back_modify; - bi->bi_op_modrdn = ndb_back_modrdn; - bi->bi_op_search = ndb_back_search; - - bi->bi_op_unbind = 0; - -#if 0 - bi->bi_extended = ndb_extended; - - bi->bi_chk_referrals = ndb_referrals; -#endif - bi->bi_operational = ndb_operational; - bi->bi_has_subordinates = ndb_has_subordinates; - bi->bi_entry_release_rw = 0; - bi->bi_entry_get_rw = ndb_entry_get; - - /* - * hooks for slap tools - */ - bi->bi_tool_entry_open = ndb_tool_entry_open; - bi->bi_tool_entry_close = ndb_tool_entry_close; - bi->bi_tool_entry_first = ndb_tool_entry_first; - bi->bi_tool_entry_next = ndb_tool_entry_next; - bi->bi_tool_entry_get = ndb_tool_entry_get; - bi->bi_tool_entry_put = ndb_tool_entry_put; -#if 0 - bi->bi_tool_entry_reindex = ndb_tool_entry_reindex; - bi->bi_tool_sync = 0; - bi->bi_tool_dn2id_get = ndb_tool_dn2id_get; - bi->bi_tool_entry_modify = ndb_tool_entry_modify; -#endif - - bi->bi_connection_init = 0; - bi->bi_connection_destroy = 0; - - rc = ndb_back_init_cf( bi ); - - return rc; -} - -#if SLAPD_NDB == SLAPD_MOD_DYNAMIC - -/* conditionally define the init_module() function */ -SLAP_BACKEND_INIT_MODULE( ndb ) - -#endif /* SLAPD_NDB == SLAPD_MOD_DYNAMIC */ - diff --git a/servers/slapd/back-ndb/modify.cpp b/servers/slapd/back-ndb/modify.cpp deleted file mode 100644 index d171bbcab5..0000000000 --- a/servers/slapd/back-ndb/modify.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* modify.cpp - ndb backend modify routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include -#include - -#include "back-ndb.h" - -int ndb_modify_internal( - Operation *op, - NdbArgs *NA, - const char **text, - char *textbuf, - size_t textlen ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - Modification *mod; - Modifications *ml; - Modifications *modlist = op->orm_modlist; - NdbAttrInfo **modai, *atmp; - const NdbDictionary::Dictionary *myDict; - const NdbDictionary::Table *myTable; - int got_oc = 0, nmods = 0, nai = 0, i; - int rc, err, indexed = 0; - - Debug( LDAP_DEBUG_TRACE, "ndb_modify_internal: 0x%08lx: %s\n", - NA->e->e_id, NA->e->e_dn, 0); - - if ( !acl_check_modlist( op, NA->e, modlist )) { - return LDAP_INSUFFICIENT_ACCESS; - } - - for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { - mod = &ml->sml_mod; - nmods++; - - switch ( mod->sm_op ) { - case LDAP_MOD_ADD: - Debug(LDAP_DEBUG_ARGS, - "ndb_modify_internal: add %s\n", - mod->sm_desc->ad_cname.bv_val, 0, 0); - err = modify_add_values( NA->e, mod, get_permissiveModify(op), - text, textbuf, textlen ); - if( err != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n", - err, *text, 0); - } - break; - - case LDAP_MOD_DELETE: - Debug(LDAP_DEBUG_ARGS, - "ndb_modify_internal: delete %s\n", - mod->sm_desc->ad_cname.bv_val, 0, 0); - err = modify_delete_values( NA->e, mod, get_permissiveModify(op), - text, textbuf, textlen ); - assert( err != LDAP_TYPE_OR_VALUE_EXISTS ); - if( err != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n", - err, *text, 0); - } - break; - - case LDAP_MOD_REPLACE: - Debug(LDAP_DEBUG_ARGS, - "ndb_modify_internal: replace %s\n", - mod->sm_desc->ad_cname.bv_val, 0, 0); - err = modify_replace_values( NA->e, mod, get_permissiveModify(op), - text, textbuf, textlen ); - if( err != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n", - err, *text, 0); - } - break; - - case LDAP_MOD_INCREMENT: - Debug(LDAP_DEBUG_ARGS, - "ndb_modify_internal: increment %s\n", - mod->sm_desc->ad_cname.bv_val, 0, 0); - err = modify_increment_values( NA->e, mod, get_permissiveModify(op), - text, textbuf, textlen ); - if( err != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, - "ndb_modify_internal: %d %s\n", - err, *text, 0); - } - break; - - case SLAP_MOD_SOFTADD: - Debug(LDAP_DEBUG_ARGS, - "ndb_modify_internal: softadd %s\n", - mod->sm_desc->ad_cname.bv_val, 0, 0); - mod->sm_op = LDAP_MOD_ADD; - - err = modify_add_values( NA->e, mod, get_permissiveModify(op), - text, textbuf, textlen ); - - mod->sm_op = SLAP_MOD_SOFTADD; - - if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) { - err = LDAP_SUCCESS; - } - - if( err != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n", - err, *text, 0); - } - break; - - default: - Debug(LDAP_DEBUG_ANY, "ndb_modify_internal: invalid op %d\n", - mod->sm_op, 0, 0); - *text = "Invalid modify operation"; - err = LDAP_OTHER; - Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n", - err, *text, 0); - } - - if ( err != LDAP_SUCCESS ) { - return err; - } - - /* If objectClass was modified, reset the flags */ - if ( mod->sm_desc == slap_schema.si_ad_objectClass ) { - NA->e->e_ocflags = 0; - got_oc = 1; - } - } - - /* check that the entry still obeys the schema */ - rc = entry_schema_check( op, NA->e, NULL, get_relax(op), 0, - text, textbuf, textlen ); - if ( rc != LDAP_SUCCESS || op->o_noop ) { - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "entry failed schema check: %s\n", - *text, 0, 0 ); - } - return rc; - } - - /* apply modifications to DB */ - modai = (NdbAttrInfo **)op->o_tmpalloc( nmods * sizeof(NdbAttrInfo*), op->o_tmpmemctx ); - - /* Get the unique list of modified attributes */ - ldap_pvt_thread_rdwr_rlock( &ni->ni_ai_rwlock ); - for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { - /* Already took care of objectclass */ - if ( ml->sml_desc == slap_schema.si_ad_objectClass ) - continue; - for ( i=0; isml_desc->ad_type == modai[i]->na_attr ) - break; - } - /* This attr was already updated */ - if ( i < nai ) - continue; - modai[nai] = ndb_ai_find( ni, ml->sml_desc->ad_type ); - if ( modai[nai]->na_flag & NDB_INFO_INDEX ) - indexed++; - nai++; - } - ldap_pvt_thread_rdwr_runlock( &ni->ni_ai_rwlock ); - - if ( got_oc || indexed ) { - rc = ndb_entry_put_info( op->o_bd, NA, 1 ); - if ( rc ) return rc; - } - - myDict = NA->ndb->getDictionary(); - - /* One operation per table... */ - for ( i=0; igetTable( atmp->na_oi->no_table.bv_val ); - if ( !myTable ) continue; - myOp = NULL; - nmods = 0; - rc = ndb_oc_attrs( NA->txn, myTable, NA->e, atmp->na_oi, &atmp, 1, 1, &nmods, &myOp ); - if ( rc ) return rc; - for ( j=i+1; jna_oi == atmp->na_oi ) { - atmp = modai[j]; - modai[j] = NULL; - rc = ndb_oc_attrs( NA->txn, myTable, NA->e, atmp->na_oi, &atmp, 1, 1, &nmods, &myOp ); - if ( rc ) return rc; - } - } - } - return 0; -} - - -int -ndb_back_modify( Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - Entry e = {0}; - int manageDSAit = get_manageDSAit( op ); - char textbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof textbuf; - - int num_retries = 0; - - NdbArgs NA; - NdbRdns rdns; - struct berval matched; - - LDAPControl **preread_ctrl = NULL; - LDAPControl **postread_ctrl = NULL; - LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; - int num_ctrls = 0; - - int rc; - - Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(ndb_back_modify) ": %s\n", - op->o_req_dn.bv_val, 0, 0 ); - - ctrls[num_ctrls] = NULL; - - slap_mods_opattrs( op, &op->orm_modlist, 1 ); - - e.e_name = op->o_req_dn; - e.e_nname = op->o_req_ndn; - - /* Get our NDB handle */ - rs->sr_err = ndb_thread_handle( op, &NA.ndb ); - rdns.nr_num = 0; - NA.rdns = &rdns; - NA.e = &e; - - if( 0 ) { -retry: /* transaction retry */ - NA.txn->close(); - NA.txn = NULL; - if( e.e_attrs ) { - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - } - Debug(LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modify) ": retrying...\n", 0, 0, 0); - if ( op->o_abandon ) { - rs->sr_err = SLAPD_ABANDON; - goto return_results; - } - if ( NA.ocs ) { - ber_bvarray_free( NA.ocs ); - } - ndb_trans_backoff( ++num_retries ); - } - NA.ocs = NULL; - - /* begin transaction */ - NA.txn = NA.ndb->startTransaction(); - rs->sr_text = NULL; - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modify) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - /* get entry or ancestor */ - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 0, &matched ); - switch( rs->sr_err ) { - case 0: - break; - case LDAP_NO_SUCH_OBJECT: - Debug( LDAP_DEBUG_ARGS, - "<=- ndb_back_modify: no such object %s\n", - op->o_req_dn.bv_val, 0, 0 ); - rs->sr_matched = matched.bv_val; - goto return_results; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; -#endif - case LDAP_BUSY: - rs->sr_text = "ldap server busy"; - goto return_results; - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - /* acquire and lock entry */ - rs->sr_err = ndb_entry_get_data( op->o_bd, &NA, 1 ); - - 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(ndb_back_modify) ": entry is referral\n", - 0, 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e.e_name.bv_val; - rs->sr_flags = REP_REF_MUSTBEFREED; - goto return_results; - } - - if ( get_assert( op ) && - ( test_filter( op, &e, (Filter*)get_assertion( op )) != LDAP_COMPARE_TRUE )) - { - rs->sr_err = LDAP_ASSERTION_FAILED; - goto return_results; - } - - 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, - "<=- " LDAP_XSTRING(ndb_back_modify) ": pre-read " - "failed!\n", 0, 0, 0 ); - if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { - /* FIXME: is it correct to abort - * operation if control fails? */ - goto return_results; - } - } - } - - /* Modify the entry */ - rs->sr_err = ndb_modify_internal( op, &NA, &rs->sr_text, textbuf, textlen ); - - if( rs->sr_err != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modify) ": modify failed (%d)\n", - rs->sr_err, 0, 0 ); -#if 0 - switch( rs->sr_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } -#endif - goto return_results; - } - - if( op->o_postread ) { - if( postread_ctrl == NULL ) { - postread_ctrl = &ctrls[num_ctrls++]; - ctrls[num_ctrls] = NULL; - } - if( slap_read_controls( op, rs, &e, - &slap_post_read_bv, postread_ctrl ) ) - { - Debug( LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_modify) - ": post-read failed!\n", 0, 0, 0 ); - if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { - /* FIXME: is it correct to abort - * operation if control fails? */ - goto return_results; - } - } - } - - if( op->o_noop ) { - if ( ( rs->sr_err = NA.txn->execute( Rollback ) ) != 0 ) { - rs->sr_text = "txn_abort (no-op) failed"; - } else { - rs->sr_err = LDAP_X_NO_OPERATION; - } - } else { - if ( ( rs->sr_err = NA.txn->execute( Commit ) ) != 0 ) { - rs->sr_text = "txn_commit failed"; - } else { - rs->sr_err = LDAP_SUCCESS; - } - } - - if( rs->sr_err != LDAP_SUCCESS && rs->sr_err != LDAP_X_NO_OPERATION ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modify) ": txn_%s failed: %s (%d)\n", - op->o_noop ? "abort (no-op)" : "commit", - NA.txn->getNdbError().message, NA.txn->getNdbError().code ); - rs->sr_err = LDAP_OTHER; - goto return_results; - } - NA.txn->close(); - NA.txn = NULL; - - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modify) ": updated%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; - rs->sr_text = NULL; - if( num_ctrls ) rs->sr_ctrls = ctrls; - -return_results: - if ( NA.ocs ) { - ber_bvarray_free( NA.ocs ); - NA.ocs = NULL; - } - - if ( e.e_attrs != NULL ) { - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - } - - if( NA.txn != NULL ) { - NA.txn->execute( Rollback ); - NA.txn->close(); - } - - send_ldap_result( op, rs ); - slap_graduate_commit_csn( op ); - - 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 ); - } - - rs->sr_text = NULL; - return rs->sr_err; -} diff --git a/servers/slapd/back-ndb/modrdn.cpp b/servers/slapd/back-ndb/modrdn.cpp deleted file mode 100644 index c9ac0d89e7..0000000000 --- a/servers/slapd/back-ndb/modrdn.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/* modrdn.cpp - ndb backend modrdn routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include - -#include "back-ndb.h" - -int -ndb_back_modrdn( Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - AttributeDescription *children = slap_schema.si_ad_children; - AttributeDescription *entry = slap_schema.si_ad_entry; - struct berval new_dn = BER_BVNULL, new_ndn = BER_BVNULL; - Entry e = {0}; - Entry e2 = {0}; - char textbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof textbuf; - - struct berval *np_dn = NULL; /* newSuperior dn */ - struct berval *np_ndn = NULL; /* newSuperior ndn */ - - int manageDSAit = get_manageDSAit( op ); - int num_retries = 0; - - NdbArgs NA, NA2; - NdbRdns rdns, rdn2; - struct berval matched; - - LDAPControl **preread_ctrl = NULL; - LDAPControl **postread_ctrl = NULL; - LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; - int num_ctrls = 0; - - int rc; - - Debug( LDAP_DEBUG_ARGS, "==>" LDAP_XSTRING(ndb_back_modrdn) "(%s,%s,%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 ); - - e.e_name = op->o_req_dn; - e.e_nname = op->o_req_ndn; - - /* Get our NDB handle */ - rs->sr_err = ndb_thread_handle( op, &NA.ndb ); - rdns.nr_num = 0; - NA.rdns = &rdns; - NA.e = &e; - NA2.ndb = NA.ndb; - NA2.e = &e2; - NA2.rdns = &rdn2; - - if( 0 ) { -retry: /* transaction retry */ - NA.txn->close(); - NA.txn = NULL; - if ( e.e_attrs ) { - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - } - Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(ndb_back_modrdn) - ": retrying...\n", 0, 0, 0 ); - if ( op->o_abandon ) { - rs->sr_err = SLAPD_ABANDON; - goto return_results; - } - if ( NA.ocs ) { - ber_bvarray_free( NA.ocs ); - } - ndb_trans_backoff( ++num_retries ); - } - NA.ocs = NULL; - - /* begin transaction */ - NA.txn = NA.ndb->startTransaction(); - rs->sr_text = NULL; - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - NA2.txn = NA.txn; - - /* get entry */ - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 1, &matched ); - switch( rs->sr_err ) { - case 0: - break; - case LDAP_NO_SUCH_OBJECT: - Debug( LDAP_DEBUG_ARGS, - "<=- ndb_back_modrdn: no such object %s\n", - op->o_req_dn.bv_val, 0, 0 ); - rs->sr_matched = matched.bv_val; - goto return_results; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; -#endif - case LDAP_BUSY: - rs->sr_text = "ldap server busy"; - goto return_results; - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - - /* acquire and lock entry */ - rs->sr_err = ndb_entry_get_data( op->o_bd, &NA, 1 ); - - if ( get_assert( op ) && - ( test_filter( op, &e, (Filter *)get_assertion( op )) != LDAP_COMPARE_TRUE )) - { - rs->sr_err = LDAP_ASSERTION_FAILED; - goto return_results; - } - - /* check write on old entry */ - rs->sr_err = access_allowed( op, &e, entry, NULL, ACL_WRITE, NULL ); - if ( ! rs->sr_err ) { - Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0, - 0, 0 ); - 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 */ - rs->sr_err = ndb_has_children( &NA, &rc ); - if ( rs->sr_err ) { - Debug(LDAP_DEBUG_ARGS, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": has_children failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - if ( rc == LDAP_COMPARE_TRUE ) { - Debug(LDAP_DEBUG_ARGS, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": non-leaf %s\n", - op->o_req_dn.bv_val, 0, 0); - rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; - rs->sr_text = "subtree rename not supported"; - goto return_results; - } - - if (!manageDSAit && is_entry_referral( &e ) ) { - /* entry is a referral, don't allow modrdn */ - rs->sr_ref = get_entry_referrals( op, &e ); - - Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(ndb_back_modrdn) - ": entry %s is referral\n", e.e_dn, 0, 0 ); - - rs->sr_err = LDAP_REFERRAL, - rs->sr_matched = op->o_req_dn.bv_val; - rs->sr_flags = REP_REF_MUSTBEFREED; - goto return_results; - } - - if ( be_issuffix( op->o_bd, &e.e_nname ) ) { - /* There can only be one suffix entry */ - rs->sr_err = LDAP_NAMING_VIOLATION; - rs->sr_text = "cannot rename suffix entry"; - goto return_results; - } else { - dnParent( &e.e_nname, &e2.e_nname ); - dnParent( &e.e_name, &e2.e_name ); - } - - /* check parent for "children" acl */ - rs->sr_err = access_allowed( op, &e2, - children, NULL, - op->oq_modrdn.rs_newSup == NULL ? - ACL_WRITE : ACL_WDEL, - NULL ); - - if ( ! rs->sr_err ) { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0, - 0, 0 ); - rs->sr_text = "no write access to old parent's children"; - goto return_results; - } - - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) ": wr to children " - "of entry %s OK\n", e2.e_name.bv_val, 0, 0 ); - - if ( op->oq_modrdn.rs_newSup != NULL ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) - ": new parent \"%s\" requested...\n", - op->oq_modrdn.rs_newSup->bv_val, 0, 0 ); - - /* newSuperior == oldParent? */ - if( dn_match( &e2.e_nname, op->oq_modrdn.rs_nnewSup ) ) { - Debug( LDAP_DEBUG_TRACE, "bdb_back_modrdn: " - "new parent \"%s\" same as the old parent \"%s\"\n", - op->oq_modrdn.rs_newSup->bv_val, e2.e_name.bv_val, 0 ); - op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */ - } - } - - if ( op->oq_modrdn.rs_newSup != NULL ) { - if ( op->oq_modrdn.rs_newSup->bv_len ) { - rdn2.nr_num = 0; - 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? */ - - e2.e_name = *np_dn; - e2.e_nname = *np_ndn; - NA2.ocs = &matched; - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA2, 1, NULL ); - switch( rs->sr_err ) { - case 0: - break; - case LDAP_NO_SUCH_OBJECT: - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) - ": newSup(ndn=%s) not here!\n", - np_ndn->bv_val, 0, 0); - rs->sr_text = "new superior not found"; - goto return_results; -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; -#endif - case LDAP_BUSY: - rs->sr_text = "ldap server busy"; - goto return_results; - default: - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto return_results; - } - } - - /* check newSuperior for "children" acl */ - rs->sr_err = access_allowed( op, &e2, children, - NULL, ACL_WADD, NULL ); - if( ! rs->sr_err ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) - ": no wr to newSup children\n", - 0, 0, 0 ); - rs->sr_text = "no write access to new superior's children"; - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - goto return_results; - } - - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) - ": wr to new parent OK id=%ld\n", - (long) e2.e_id, 0, 0 ); - } - - /* Build target dn and make sure target entry doesn't exist already. */ - if (!new_dn.bv_val) { - build_new_dn( &new_dn, &e2.e_name, &op->oq_modrdn.rs_newrdn, NULL ); - } - - if (!new_ndn.bv_val) { - build_new_dn( &new_ndn, &e2.e_nname, &op->oq_modrdn.rs_nnewrdn, NULL ); - } - - Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(ndb_back_modrdn) ": new ndn=%s\n", - new_ndn.bv_val, 0, 0 ); - - /* Allow rename to same DN */ - if ( !bvmatch ( &new_ndn, &e.e_nname )) { - rdn2.nr_num = 0; - e2.e_name = new_dn; - e2.e_nname = new_ndn; - NA2.ocs = &matched; - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA2, 1, NULL ); - switch( rs->sr_err ) { -#if 0 - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; -#endif - case LDAP_NO_SUCH_OBJECT: - break; - case 0: - rs->sr_err = LDAP_ALREADY_EXISTS; - goto return_results; - default: - 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, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": pre-read failed!\n", 0, 0, 0 ); - if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { - /* FIXME: is it correct to abort - * operation if control fails? */ - goto return_results; - } - } - } - - /* delete old DN */ - rs->sr_err = ndb_entry_del_info( op->o_bd, &NA ); - if ( rs->sr_err != 0 ) { - Debug(LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": dn2id del failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); -#if 0 - switch( rs->sr_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } -#endif - rs->sr_err = LDAP_OTHER; - rs->sr_text = "DN index delete fail"; - goto return_results; - } - - /* copy entry fields */ - e2.e_attrs = e.e_attrs; - e2.e_id = e.e_id; - - /* add new DN */ - rs->sr_err = ndb_entry_put_info( op->o_bd, &NA2, 0 ); - if ( rs->sr_err != 0 ) { - Debug(LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": dn2id add failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); -#if 0 - switch( rs->sr_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } -#endif - rs->sr_err = LDAP_OTHER; - rs->sr_text = "DN index add failed"; - goto return_results; - } - - /* modify entry */ - rs->sr_err = ndb_modify_internal( op, &NA2, - &rs->sr_text, textbuf, textlen ); - if( rs->sr_err != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": modify failed: %s (%d)\n", - NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 ); -#if 0 - switch( rs->sr_err ) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - } -#endif - goto return_results; - } - - e.e_attrs = e2.e_attrs; - - if( op->o_postread ) { - if( postread_ctrl == NULL ) { - postread_ctrl = &ctrls[num_ctrls++]; - ctrls[num_ctrls] = NULL; - } - if( slap_read_controls( op, rs, &e2, - &slap_post_read_bv, postread_ctrl ) ) - { - Debug( LDAP_DEBUG_TRACE, - "<=- " LDAP_XSTRING(ndb_back_modrdn) - ": post-read failed!\n", 0, 0, 0 ); - if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { - /* FIXME: is it correct to abort - * operation if control fails? */ - goto return_results; - } - } - } - - if( op->o_noop ) { - if(( rs->sr_err = NA.txn->execute( Rollback )) != 0 ) { - rs->sr_text = "txn_abort (no-op) failed"; - } else { - rs->sr_err = LDAP_X_NO_OPERATION; - } - } else { - if(( rs->sr_err = NA.txn->execute( Commit )) != 0 ) { - rs->sr_text = "txn_commit failed"; - } else { - rs->sr_err = LDAP_SUCCESS; - } - } - - if( rs->sr_err != LDAP_SUCCESS && rs->sr_err != LDAP_X_NO_OPERATION ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) ": txn_%s failed: %s (%d)\n", - op->o_noop ? "abort (no-op)" : "commit", - NA.txn->getNdbError().message, NA.txn->getNdbError().code ); - rs->sr_err = LDAP_OTHER; - goto return_results; - } - NA.txn->close(); - NA.txn = NULL; - - Debug(LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_modrdn) - ": rdn modified%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; - rs->sr_text = NULL; - if( num_ctrls ) rs->sr_ctrls = ctrls; - -return_results: - if ( NA.ocs ) { - ber_bvarray_free( NA.ocs ); - NA.ocs = NULL; - } - - if ( e.e_attrs ) { - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - } - - if( NA.txn != NULL ) { - NA.txn->execute( Rollback ); - NA.txn->close(); - } - - send_ldap_result( op, rs ); - 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 ); - - 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 ); - } - - rs->sr_text = NULL; - return rs->sr_err; -} diff --git a/servers/slapd/back-ndb/ndbio.cpp b/servers/slapd/back-ndb/ndbio.cpp deleted file mode 100644 index bfca544ecd..0000000000 --- a/servers/slapd/back-ndb/ndbio.cpp +++ /dev/null @@ -1,1356 +0,0 @@ -/* ndbio.cpp - get/set/del data for NDB */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include -#include -#include - -#include "back-ndb.h" - -/* For reference only */ -typedef struct MedVar { - Int16 len; /* length is always little-endian */ - char buf[1024]; -} MedVar; - -extern "C" { - static int ndb_name_cmp( const void *v1, const void *v2 ); - static int ndb_oc_dup_err( void *v1, void *v2 ); -}; - -static int -ndb_name_cmp( const void *v1, const void *v2 ) -{ - NdbOcInfo *oc1 = (NdbOcInfo *)v1, *oc2 = (NdbOcInfo *)v2; - return ber_bvstrcasecmp( &oc1->no_name, &oc2->no_name ); -} - -static int -ndb_oc_dup_err( void *v1, void *v2 ) -{ - NdbOcInfo *oc = (NdbOcInfo *)v2; - - oc->no_oc = (ObjectClass *)v1; - return -1; -} - -/* Find an existing NdbAttrInfo */ -extern "C" NdbAttrInfo * -ndb_ai_find( struct ndb_info *ni, AttributeType *at ) -{ - NdbAttrInfo atmp; - atmp.na_name = at->sat_cname; - - return (NdbAttrInfo *)avl_find( ni->ni_ai_tree, &atmp, ndb_name_cmp ); -} - -/* Find or create an NdbAttrInfo */ -extern "C" NdbAttrInfo * -ndb_ai_get( struct ndb_info *ni, struct berval *aname ) -{ - NdbAttrInfo atmp, *ai; - atmp.na_name = *aname; - - ai = (NdbAttrInfo *)avl_find( ni->ni_ai_tree, &atmp, ndb_name_cmp ); - if ( !ai ) { - const char *text; - AttributeDescription *ad = NULL; - - if ( slap_bv2ad( aname, &ad, &text )) - return NULL; - - ai = (NdbAttrInfo *)ch_malloc( sizeof( NdbAttrInfo )); - ai->na_desc = ad; - ai->na_attr = ai->na_desc->ad_type; - ai->na_name = ai->na_attr->sat_cname; - ai->na_oi = NULL; - ai->na_flag = 0; - ai->na_ixcol = 0; - ai->na_len = ai->na_attr->sat_atype.at_syntax_len; - /* Reasonable default */ - if ( !ai->na_len ) { - if ( ai->na_attr->sat_syntax == slap_schema.si_syn_distinguishedName ) - ai->na_len = 1024; - else - ai->na_len = 128; - } - /* Arbitrary limit */ - if ( ai->na_len > 1024 ) - ai->na_len = 1024; - avl_insert( &ni->ni_ai_tree, ai, ndb_name_cmp, avl_dup_error ); - } - return ai; -} - -static int -ndb_ai_check( struct ndb_info *ni, NdbOcInfo *oci, AttributeType **attrs, char **ptr, int *col, - int create ) -{ - NdbAttrInfo *ai, atmp; - int i; - - for ( i=0; attrs[i]; i++ ) { - if ( attrs[i] == slap_schema.si_ad_objectClass->ad_type ) - continue; - /* skip attrs that are in a superior */ - if ( oci->no_oc && oci->no_oc->soc_sups ) { - int j, k, found=0; - ObjectClass *oc; - for ( j=0; oci->no_oc->soc_sups[j]; j++ ) { - oc = oci->no_oc->soc_sups[j]; - if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT ) - continue; - if ( oc->soc_required ) { - for ( k=0; oc->soc_required[k]; k++ ) { - if ( attrs[i] == oc->soc_required[k] ) { - found = 1; - break; - } - } - if ( found ) break; - } - if ( oc->soc_allowed ) { - for ( k=0; oc->soc_allowed[k]; k++ ) { - if ( attrs[i] == oc->soc_allowed[k] ) { - found = 1; - break; - } - } - if ( found ) break; - } - } - if ( found ) - continue; - } - - ai = ndb_ai_get( ni, &attrs[i]->sat_cname ); - if ( !ai ) { - /* can never happen */ - return LDAP_OTHER; - } - - /* An indexed attr is defined before its OC is */ - if ( !ai->na_oi ) { - ai->na_oi = oci; - ai->na_column = (*col)++; - } - - oci->no_attrs[oci->no_nattrs++] = ai; - - /* An attrset attr may already be defined */ - if ( ai->na_oi != oci ) { - int j; - for ( j=0; jno_nsets; j++ ) - if ( oci->no_sets[j] == ai->na_oi ) break; - if ( j >= oci->no_nsets ) { - /* FIXME: data loss if more sets are in use */ - if ( oci->no_nsets < NDB_MAX_OCSETS ) { - oci->no_sets[oci->no_nsets++] = ai->na_oi; - } - } - continue; - } - - if ( create ) { - *ptr += sprintf( *ptr, ", `%s` VARCHAR(%d)", ai->na_attr->sat_cname.bv_val, - ai->na_len ); - } - } - return 0; -} - -static int -ndb_oc_create( struct ndb_info *ni, NdbOcInfo *oci, int create ) -{ - char buf[4096], *ptr; - int i, rc = 0, col; - - if ( create ) { - ptr = buf + sprintf( buf, - "CREATE TABLE `%s` (eid bigint unsigned NOT NULL PRIMARY KEY", - oci->no_table.bv_val ); - } - - col = 0; - if ( oci->no_oc->soc_required ) { - for ( i=0; oci->no_oc->soc_required[i]; i++ ); - col += i; - } - if ( oci->no_oc->soc_allowed ) { - for ( i=0; oci->no_oc->soc_allowed[i]; i++ ); - col += i; - } - /* assume all are present */ - oci->no_attrs = (struct ndb_attrinfo **)ch_malloc( col * sizeof(struct ndb_attrinfo *)); - - col = 1; - ldap_pvt_thread_rdwr_wlock( &ni->ni_ai_rwlock ); - if ( oci->no_oc->soc_required ) { - rc = ndb_ai_check( ni, oci, oci->no_oc->soc_required, &ptr, &col, create ); - } - if ( !rc && oci->no_oc->soc_allowed ) { - rc = ndb_ai_check( ni, oci, oci->no_oc->soc_allowed, &ptr, &col, create ); - } - ldap_pvt_thread_rdwr_wunlock( &ni->ni_ai_rwlock ); - - /* shrink down to just the needed size */ - oci->no_attrs = (struct ndb_attrinfo **)ch_realloc( oci->no_attrs, - oci->no_nattrs * sizeof(struct ndb_attrinfo *)); - - if ( create ) { - ptr = lutil_strcopy( ptr, " ) ENGINE=ndb" ); - rc = mysql_real_query( &ni->ni_sql, buf, ptr - buf ); - if ( rc ) { - Debug( LDAP_DEBUG_ANY, - "ndb_oc_create: CREATE TABLE %s failed, %s (%d)\n", - oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - } - } - return rc; -} - -/* Read table definitions from the DB and populate ObjectClassInfo */ -extern "C" int -ndb_oc_read( struct ndb_info *ni, const NdbDictionary::Dictionary *myDict ) -{ - const NdbDictionary::Table *myTable; - const NdbDictionary::Column *myCol; - NdbOcInfo *oci, octmp; - NdbAttrInfo *ai; - ObjectClass *oc; - NdbDictionary::Dictionary::List myList; - struct berval bv; - int i, j, rc, col; - - rc = myDict->listObjects( myList, NdbDictionary::Object::UserTable ); - /* Populate our objectClass structures */ - for ( i=0; ini_dbname )) - continue; - /* Ignore internal tables */ - if ( !strncmp( myList.elements[i].name, "OL_", 3 )) - continue; - ber_str2bv( myList.elements[i].name, 0, 0, &octmp.no_name ); - oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp ); - if ( oci ) - continue; - - oc = oc_bvfind( &octmp.no_name ); - if ( !oc ) { - /* undefined - shouldn't happen */ - continue; - } - myTable = myDict->getTable( myList.elements[i].name ); - oci = (NdbOcInfo *)ch_malloc( sizeof( NdbOcInfo )+oc->soc_cname.bv_len+1 ); - oci->no_table.bv_val = (char *)(oci+1); - strcpy( oci->no_table.bv_val, oc->soc_cname.bv_val ); - oci->no_table.bv_len = oc->soc_cname.bv_len; - oci->no_name = oci->no_table; - oci->no_oc = oc; - oci->no_flag = 0; - oci->no_nsets = 0; - oci->no_nattrs = 0; - col = 0; - /* Make space for all attrs, even tho sups will be dropped */ - if ( oci->no_oc->soc_required ) { - for ( j=0; oci->no_oc->soc_required[j]; j++ ); - col = j; - } - if ( oci->no_oc->soc_allowed ) { - for ( j=0; oci->no_oc->soc_allowed[j]; j++ ); - col += j; - } - oci->no_attrs = (struct ndb_attrinfo **)ch_malloc( col * sizeof(struct ndb_attrinfo *)); - avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, avl_dup_error ); - - col = myTable->getNoOfColumns(); - /* Skip 0, eid */ - for ( j = 1; jgetColumn( j ); - ber_str2bv( myCol->getName(), 0, 0, &bv ); - ai = ndb_ai_get( ni, &bv ); - /* shouldn't happen */ - if ( !ai ) - continue; - ai->na_oi = oci; - ai->na_column = j; - ai->na_len = myCol->getLength(); - } - } - /* Link to any attrsets */ - for ( i=0; ini_dbname )) - continue; - /* Ignore internal tables */ - if ( !strncmp( myList.elements[i].name, "OL_", 3 )) - continue; - ber_str2bv( myList.elements[i].name, 0, 0, &octmp.no_name ); - oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp ); - /* shouldn't happen */ - if ( !oci ) - continue; - col = 1; - if ( oci->no_oc->soc_required ) { - rc = ndb_ai_check( ni, oci, oci->no_oc->soc_required, NULL, &col, 0 ); - } - if ( oci->no_oc->soc_allowed ) { - rc = ndb_ai_check( ni, oci, oci->no_oc->soc_allowed, NULL, &col, 0 ); - } - /* shrink down to just the needed size */ - oci->no_attrs = (struct ndb_attrinfo **)ch_realloc( oci->no_attrs, - oci->no_nattrs * sizeof(struct ndb_attrinfo *)); - } - return 0; -} - -static int -ndb_oc_get( struct ndb_info *ni, const NdbDictionary::Dictionary *myDict, - struct berval *oname, NdbOcs *out ) -{ - const NdbDictionary::Table *myTable; - NdbOcInfo *oci, octmp; - ObjectClass *oc; - int i, rc; - - /* shortcut top */ - if ( ber_bvstrcasecmp( oname, &slap_schema.si_oc_top->soc_cname )) { - octmp.no_name = *oname; - oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp ); - if ( oci ) { - oc = oci->no_oc; - } else { - oc = oc_bvfind( oname ); - if ( !oc ) { - /* undefined - shouldn't happen */ - return LDAP_INVALID_SYNTAX; - } - } - if ( oc->soc_sups ) { - int i; - - for ( i=0; oc->soc_sups[i]; i++ ) { - rc = ndb_oc_get( ni, myDict, &oc->soc_sups[i]->soc_cname, out ); - if ( rc ) return rc; - } - } - } else { - oc = slap_schema.si_oc_top; - } - /* Only insert once */ - for ( i=0; ino_ntext; i++ ) - if ( out->no_text[i].bv_val == oc->soc_cname.bv_val ) - break; - if ( i == out->no_ntext ) - out->no_text[out->no_ntext++] = oc->soc_cname; - - /* ignore top, etc... */ - if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT ) - return 0; - - if ( !oci ) { - ldap_pvt_thread_rdwr_runlock( &ni->ni_oc_rwlock ); - oci = (NdbOcInfo *)ch_malloc( sizeof( NdbOcInfo )+oc->soc_cname.bv_len+1 ); - oci->no_table.bv_val = (char *)(oci+1); - strcpy( oci->no_table.bv_val, oc->soc_cname.bv_val ); - oci->no_table.bv_len = oc->soc_cname.bv_len; - oci->no_name = oci->no_table; - oci->no_oc = oc; - oci->no_flag = 0; - oci->no_nsets = 0; - oci->no_nattrs = 0; - ldap_pvt_thread_rdwr_wlock( &ni->ni_oc_rwlock ); - if ( avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, ndb_oc_dup_err )) { - octmp.no_oc = oci->no_oc; - ch_free( oci ); - oci = (NdbOcInfo *)octmp.no_oc; - } - /* see if the oc table already exists in the DB */ - myTable = myDict->getTable( oci->no_table.bv_val ); - rc = ndb_oc_create( ni, oci, myTable == NULL ); - ldap_pvt_thread_rdwr_wunlock( &ni->ni_oc_rwlock ); - ldap_pvt_thread_rdwr_rlock( &ni->ni_oc_rwlock ); - if ( rc ) return rc; - } - /* Only insert once */ - for ( i=0; ino_ninfo; i++ ) - if ( out->no_info[i] == oci ) - break; - if ( i == out->no_ninfo ) - out->no_info[out->no_ninfo++] = oci; - return 0; -} - -extern "C" int -ndb_aset_get( struct ndb_info *ni, struct berval *sname, struct berval *attrs, NdbOcInfo **ret ) -{ - NdbOcInfo *oci, octmp; - int i, rc; - - octmp.no_name = *sname; - oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp ); - if ( oci ) - return LDAP_ALREADY_EXISTS; - - for ( i=0; !BER_BVISNULL( &attrs[i] ); i++ ) { - if ( !at_bvfind( &attrs[i] )) - return LDAP_NO_SUCH_ATTRIBUTE; - } - i++; - - oci = (NdbOcInfo *)ch_calloc( 1, sizeof( NdbOcInfo ) + sizeof( ObjectClass ) + - i*sizeof(AttributeType *) + sname->bv_len+1 ); - oci->no_oc = (ObjectClass *)(oci+1); - oci->no_oc->soc_required = (AttributeType **)(oci->no_oc+1); - oci->no_table.bv_val = (char *)(oci->no_oc->soc_required+i); - - for ( i=0; !BER_BVISNULL( &attrs[i] ); i++ ) - oci->no_oc->soc_required[i] = at_bvfind( &attrs[i] ); - - strcpy( oci->no_table.bv_val, sname->bv_val ); - oci->no_table.bv_len = sname->bv_len; - oci->no_name = oci->no_table; - oci->no_oc->soc_cname = oci->no_name; - oci->no_flag = NDB_INFO_ATSET; - - rc = ndb_oc_create( ni, oci, 0 ); - if ( !rc ) - rc = avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, avl_dup_error ); - if ( rc ) { - ch_free( oci ); - } else { - *ret = oci; - } - return rc; -} - -extern "C" int -ndb_aset_create( struct ndb_info *ni, NdbOcInfo *oci ) -{ - char buf[4096], *ptr; - NdbAttrInfo *ai; - int i; - - ptr = buf + sprintf( buf, - "CREATE TABLE IF NOT EXISTS `%s` (eid bigint unsigned NOT NULL PRIMARY KEY", - oci->no_table.bv_val ); - - for ( i=0; ino_nattrs; i++ ) { - if ( oci->no_attrs[i]->na_oi != oci ) - continue; - ai = oci->no_attrs[i]; - ptr += sprintf( ptr, ", `%s` VARCHAR(%d)", ai->na_attr->sat_cname.bv_val, - ai->na_len ); - if ( ai->na_flag & NDB_INFO_INDEX ) { - ptr += sprintf( ptr, ", INDEX (`%s`)", ai->na_attr->sat_cname.bv_val ); - } - } - ptr = lutil_strcopy( ptr, " ) ENGINE=ndb" ); - i = mysql_real_query( &ni->ni_sql, buf, ptr - buf ); - if ( i ) { - Debug( LDAP_DEBUG_ANY, - "ndb_aset_create: CREATE TABLE %s failed, %s (%d)\n", - oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); - } - return i; -} - -static int -ndb_oc_check( BackendDB *be, Ndb *ndb, - struct berval *ocsin, NdbOcs *out ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - const NdbDictionary::Dictionary *myDict = ndb->getDictionary(); - - int i, rc = 0; - - out->no_ninfo = 0; - out->no_ntext = 0; - - /* Find all objectclasses and their superiors. List - * the superiors first. - */ - - ldap_pvt_thread_rdwr_rlock( &ni->ni_oc_rwlock ); - for ( i=0; !BER_BVISNULL( &ocsin[i] ); i++ ) { - rc = ndb_oc_get( ni, myDict, &ocsin[i], out ); - if ( rc ) break; - } - ldap_pvt_thread_rdwr_runlock( &ni->ni_oc_rwlock ); - return rc; -} - -/* set all the unique attrs of this objectclass into the table - * max row size is 8192 bytes; how do we detect if the row is too large? - * - * FIXME: Currently only stores the first value of any multivalued attribute. - */ -extern "C" int -ndb_oc_attrs( - NdbTransaction *txn, - const NdbDictionary::Table *myTable, - Entry *e, - NdbOcInfo *no, - NdbAttrInfo **attrs, - int nattrs, - int update, - int *num, - NdbOperation **retop -) -{ - char buf[65538], *ptr; - Attribute *a; - NdbOperation *myop = retop ? *retop : NULL; - int i; - - for ( i=0; ina_oi != no ) - continue; - for ( a=e->e_attrs; a; a=a->a_next ) { - if ( a->a_desc->ad_type == attrs[i]->na_attr ) - break; - } - /* If we found a match, set its value. If we found no match - * and we're updating, delete its value. - */ - if ( a || update ) { - /* objectclass is in dn_idx_table */ - if ( a && a->a_desc == slap_schema.si_ad_objectClass ) - continue; - - /* First attr, get the op, set the type and primary key */ - if ( !*num ) { - Uint64 eid = e->e_id; - myop = txn->getNdbOperation( myTable ); - if ( !myop ) - return LDAP_OTHER; - if ( update ) { - if ( myop->writeTuple()) - return LDAP_OTHER; - } else { - if ( myop->insertTuple()) - return LDAP_OTHER; - } - if ( myop->equal( EID_COLUMN, eid )) - return LDAP_OTHER; - } - ptr = buf; - if ( a ) { - if ( a->a_vals[0].bv_len > attrs[i]->na_len ) { - Debug( LDAP_DEBUG_ANY, "ndb_oc_attrs: attribute %s too long for column\n", - attrs[i]->na_name.bv_val, 0, 0 ); - return LDAP_CONSTRAINT_VIOLATION; - } - *ptr++ = a->a_vals[0].bv_len & 0xff; - if ( attrs[i]->na_len > 255 ) { - /* MedVar */ - *ptr++ = a->a_vals[0].bv_len >> 8; - } - memcpy( ptr, a->a_vals[0].bv_val, a->a_vals[0].bv_len ); - ptr = buf; - } else { - ptr = NULL; - } - if ( myop->setValue( attrs[i]->na_column, ptr )) - return LDAP_OTHER; - (*num)++; - } - } - if ( retop ) - *retop = myop; - return LDAP_SUCCESS; -} - -static int -ndb_oc_put( - const NdbDictionary::Dictionary *myDict, - NdbTransaction *txn, NdbOcInfo *no, Entry *e, int update ) -{ - const NdbDictionary::Table *myTable; - int i, rc; - - for ( i=0; ino_nsets; i++ ) { - rc = ndb_oc_put( myDict, txn, no->no_sets[i], e, update ); - if ( rc ) - return rc; - } - - myTable = myDict->getTable( no->no_table.bv_val ); - if ( !myTable ) - return LDAP_OTHER; - - i = 0; - return ndb_oc_attrs( txn, myTable, e, no, no->no_attrs, no->no_nattrs, update, &i, NULL ); -} - -extern "C" int -ndb_entry_put_data( - BackendDB *be, - NdbArgs *NA, - int update -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - ObjectClass *oc; - Attribute *aoc, *a; - const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary(); - const NdbDictionary::Table *myTable; - NdbOperation *myop; - NdbOcs myOcs; - int i, rc; - - /* Get the entry's objectClass attribute */ - aoc = attr_find( NA->e->e_attrs, slap_schema.si_ad_objectClass ); - if ( !aoc ) - return LDAP_OTHER; - - ndb_oc_check( be, NA->ndb, aoc->a_nvals, &myOcs ); - myOcs.no_info[myOcs.no_ninfo++] = ni->ni_opattrs; - - /* Walk thru objectclasses, find all the attributes belonging to a class */ - for ( i=0; itxn, myOcs.no_info[i], NA->e, update ); - if ( rc ) return rc; - } - - return 0; -} - -static void -ndb_oc_get( NdbOcInfo *no, int *j, int *nocs, NdbOcInfo ***oclist ) -{ - int i; - NdbOcInfo **ol2; - - for ( i=0; ino_nsets; i++ ) { - ndb_oc_get( no->no_sets[i], j, nocs, oclist ); - } - if ( *j >= *nocs ) { - *nocs *= 2; - ol2 = (NdbOcInfo **)ch_realloc( *oclist, *nocs * sizeof(NdbOcInfo *)); - *oclist = ol2; - } - ol2 = *oclist; - ol2[(*j)++] = no; -} - -/* Retrieve attribute data for given entry. The entry's DN and eid should - * already be populated. - */ -extern "C" int -ndb_entry_get_data( - BackendDB *be, - NdbArgs *NA, - int update -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary(); - const NdbDictionary::Table *myTable; - NdbOperation *myop; - Uint64 eid; - - Attribute *aoc, *a; - NdbOcs myOcs; - NdbOcInfo *oci, **oclist = NULL; - char abuf[65536], *ptr, **attrs = NULL; - - /* FIXME: abuf should be dynamically allocated */ - - int i, j, k, nocs, nattrs, rc = LDAP_OTHER, alen; - - attr_merge( NA->e, slap_schema.si_ad_objectClass, NA->ocs, NULL ); - - eid = NA->e->e_id; - - ndb_oc_check( be, NA->ndb, NA->ocs, &myOcs ); - myOcs.no_info[myOcs.no_ninfo++] = ni->ni_opattrs; - nocs = myOcs.no_ninfo; - - oclist = (NdbOcInfo **)ch_calloc( 1, nocs * sizeof(NdbOcInfo *)); - - for ( i=0, j=0; ino_nattrs; - - attrs = (char **)ch_malloc( nattrs * sizeof(char *)); - - k = 0; - ptr = abuf; - for ( i=0; igetTable( oci->no_table.bv_val ); - - myop = NA->txn->getNdbOperation( myTable ); - if ( !myop ) - goto leave; - if ( myop->readTuple( update ? NdbOperation::LM_Exclusive : NdbOperation::LM_CommittedRead )) - goto leave; - if ( myop->equal( EID_COLUMN, eid )) - goto leave; - - for ( j=0; jno_nattrs; j++ ) { - if ( oci->no_attrs[j]->na_oi != oci ) - continue; - attrs[k] = ptr; - *ptr++ = 0; - if ( oci->no_attrs[j]->na_len > 255 ) - *ptr++ = 0; - ptr += oci->no_attrs[j]->na_len + 1; - myop->getValue( oci->no_attrs[j]->na_column, attrs[k++] ); - } - } - if ( NA->txn->execute( update ? NdbTransaction::NoCommit : NdbTransaction::Commit, - update ? NdbOperation::AO_IgnoreError : NdbOperation::AbortOnError, 1) < 0 ) - goto leave; - - /* count results */ - nattrs = 0; - k = 0; - for ( i=0; ino_nattrs; j++ ) { - unsigned char *buf; - int len; - if ( oci->no_attrs[j]->na_oi != oci ) - continue; - buf = (unsigned char *)attrs[k++]; - len = buf[0]; - if ( oci->no_attrs[j]->na_len > 255 ) { - /* MedVar */ - len |= (buf[1] << 8); - } - if ( !len ) - continue; - nattrs++; - } - } - - a = attrs_alloc( nattrs ); - NA->e->e_attrs->a_next = a; - k = 0; - for ( i=0; ino_nattrs; j++ ) { - unsigned char *buf; - struct berval bv, nbv; - if ( oci->no_attrs[j]->na_oi != oci ) - continue; - buf = (unsigned char *)attrs[k++]; - bv.bv_len = buf[0]; - if ( oci->no_attrs[j]->na_len > 255 ) { - /* MedVar */ - bv.bv_len |= (buf[1] << 8); - bv.bv_val = (char *)buf+2; - } else { - bv.bv_val = (char *)buf+1; - } - if ( bv.bv_len == 0 ) - continue; - bv.bv_val[bv.bv_len] = '\0'; - a->a_desc = oci->no_attrs[j]->na_desc; - attr_normalize_one( a->a_desc, &bv, &nbv, NULL ); - a->a_vals = NULL; - a->a_nvals = NULL; - a->a_numvals = 1; - value_add_one( &a->a_vals, &bv ); - if ( !BER_BVISNULL( &nbv )) { - ber_bvarray_add( &a->a_nvals, &nbv ); - } else { - a->a_nvals = a->a_vals; - } - a = a->a_next; - } - } - - rc = 0; -leave: - if ( attrs ) { - ch_free( attrs ); - } - if ( oclist ) { - ch_free( oclist ); - } - - return rc; -} - -static int -ndb_oc_del( - const NdbDictionary::Dictionary *myDict, - NdbTransaction *txn, Uint64 eid, NdbOcInfo *no ) -{ - const NdbDictionary::Table *myTable; - NdbOperation *myop; - int i, rc; - - for ( i=0; ino_nsets; i++ ) { - rc = ndb_oc_del( myDict, txn, eid, no->no_sets[i] ); - if ( rc ) rc; - } - myTable = myDict->getTable( no->no_table.bv_val ); - - myop = txn->getNdbOperation( myTable ); - if ( !myop ) - return LDAP_OTHER; - if ( myop->deleteTuple() ) - return LDAP_OTHER; - if ( myop->equal( EID_COLUMN, eid )) - return LDAP_OTHER; - - return 0; -} - -extern "C" int -ndb_entry_del_data( - BackendDB *be, - NdbArgs *NA -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary(); - const NdbDictionary::Table *myTable; - NdbOperation *myop; - Uint64 eid = NA->e->e_id; - int i; - NdbOcs myOcs; - - ndb_oc_check( be, NA->ndb, NA->ocs, &myOcs ); - myOcs.no_info[myOcs.no_ninfo++] = ni->ni_opattrs; - - for ( i=0; itxn, eid, myOcs.no_info[i] )) - return LDAP_OTHER; - } - - return 0; -} - -extern "C" int -ndb_dn2rdns( - struct berval *dn, - NdbRdns *rdns -) -{ - char *beg, *end; - int i, len; - - /* Walk thru RDNs */ - end = dn->bv_val + dn->bv_len; - for ( i=0; i dn->bv_val; beg-- ) { - if (*beg == ',') { - beg++; - break; - } - } - if ( beg >= dn->bv_val ) { - len = end - beg; - /* RDN is too long */ - if ( len > NDB_RDN_LEN ) - return LDAP_CONSTRAINT_VIOLATION; - memcpy( rdns->nr_buf[i]+1, beg, len ); - } else { - break; - } - rdns->nr_buf[i][0] = len; - end = beg - 1; - } - /* Too many RDNs in DN */ - if ( i == NDB_MAX_RDNS && beg > dn->bv_val ) { - return LDAP_CONSTRAINT_VIOLATION; - } - rdns->nr_num = i; - return 0; -} - -static int -ndb_rdns2keys( - NdbOperation *myop, - NdbRdns *rdns -) -{ - int i; - char dummy[2] = {0,0}; - - /* Walk thru RDNs */ - for ( i=0; inr_num; i++ ) { - if ( myop->equal( i+RDN_COLUMN, rdns->nr_buf[i] )) - return LDAP_OTHER; - } - for ( ; iequal( i+RDN_COLUMN, dummy )) - return LDAP_OTHER; - } - return 0; -} - -/* Store the DN2ID_TABLE fields */ -extern "C" int -ndb_entry_put_info( - BackendDB *be, - NdbArgs *NA, - int update -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary(); - const NdbDictionary::Table *myTable = myDict->getTable( DN2ID_TABLE ); - NdbOperation *myop; - NdbAttrInfo *ai; - Attribute *aoc, *a; - - /* Get the entry's objectClass attribute; it's ok to be - * absent on a fresh insert - */ - aoc = attr_find( NA->e->e_attrs, slap_schema.si_ad_objectClass ); - if ( update && !aoc ) - return LDAP_OBJECT_CLASS_VIOLATION; - - myop = NA->txn->getNdbOperation( myTable ); - if ( !myop ) - return LDAP_OTHER; - if ( update ) { - if ( myop->updateTuple()) - return LDAP_OTHER; - } else { - if ( myop->insertTuple()) - return LDAP_OTHER; - } - - if ( ndb_rdns2keys( myop, NA->rdns )) - return LDAP_OTHER; - - /* Set entry ID */ - { - Uint64 eid = NA->e->e_id; - if ( myop->setValue( EID_COLUMN, eid )) - return LDAP_OTHER; - } - - /* Set list of objectClasses */ - if ( aoc ) { - char *ptr, buf[sizeof(MedVar)]; - NdbOcs myOcs; - int i; - - ndb_oc_check( be, NA->ndb, aoc->a_nvals, &myOcs ); - ptr = buf+2; - for ( i=0; i= &buf[sizeof(buf)] ) - break; - if ( i ) *ptr++ = ' '; - ptr = lutil_strcopy( ptr, myOcs.no_text[i].bv_val ); - } - i = ptr - buf - 2; - buf[0] = i & 0xff; - buf[1] = i >> 8; - if ( myop->setValue( OCS_COLUMN, buf )) - return LDAP_OTHER; - } - - /* Set any indexed attrs */ - for ( a = NA->e->e_attrs; a; a=a->a_next ) { - ai = ndb_ai_find( ni, a->a_desc->ad_type ); - if ( ai && ( ai->na_flag & NDB_INFO_INDEX )) { - char *ptr, buf[sizeof(MedVar)]; - int len; - - ptr = buf+1; - len = a->a_vals[0].bv_len; - /* FIXME: data loss */ - if ( len > ai->na_len ) - len = ai->na_len; - buf[0] = len & 0xff; - if ( ai->na_len > 255 ) { - *ptr++ = len >> 8; - } - memcpy( ptr, a->a_vals[0].bv_val, len ); - if ( myop->setValue( ai->na_ixcol, buf )) - return LDAP_OTHER; - } - } - - return 0; -} - -extern "C" struct berval * -ndb_str2bvarray( - char *str, - int len, - char delim -) -{ - struct berval *list, tmp; - char *beg; - int i, num; - - for ( i = 1, beg = str;; i++ ) { - beg = strchr( beg, delim ); - if ( !beg ) - break; - beg++; - } - - num = i; - list = (struct berval *)ch_malloc( (num+1)*sizeof(struct berval)); - - for ( i = 0, beg = str; ibe_private; - const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary(); - const NdbDictionary::Table *myTable = myDict->getTable( DN2ID_TABLE ); - NdbOperation *myop; - NdbRecAttr *attr1, *attr2; - char idbuf[2*sizeof(ID)]; - char ocbuf[NDB_OC_BUFLEN]; - - if ( matched ) { - BER_BVZERO( matched ); - } - if ( !myTable ) { - return LDAP_OTHER; - } - - myop = NA->txn->getNdbOperation( myTable ); - if ( !myop ) { - return LDAP_OTHER; - } - - if ( myop->readTuple( update ? NdbOperation::LM_Exclusive : NdbOperation::LM_CommittedRead )) { - return LDAP_OTHER; - } - - if ( !NA->rdns->nr_num && ndb_dn2rdns( &NA->e->e_name, NA->rdns )) { - return LDAP_NO_SUCH_OBJECT; - } - - if ( ndb_rdns2keys( myop, NA->rdns )) { - return LDAP_OTHER; - } - - attr1 = myop->getValue( EID_COLUMN, idbuf ); - if ( !attr1 ) { - return LDAP_OTHER; - } - - ocbuf[0] = 0; - ocbuf[1] = 0; - if ( !NA->ocs ) { - attr2 = myop->getValue( OCS_COLUMN, ocbuf ); - if ( !attr2 ) { - return LDAP_OTHER; - } - } - - if ( NA->txn->execute(NdbTransaction::NoCommit, NdbOperation::AO_IgnoreError, 1) < 0 ) { - return LDAP_OTHER; - } - - switch( myop->getNdbError().code ) { - case 0: - if ( !attr1->isNULL() && ( NA->e->e_id = attr1->u_64_value() )) { - /* If we didn't care about OCs, or we got them */ - if ( NA->ocs || ocbuf[0] || ocbuf[1] ) { - /* If wanted, return them */ - if ( !NA->ocs ) - NA->ocs = ndb_ref2oclist( ocbuf ); - break; - } - } - /* FALLTHRU */ - case NDB_NO_SUCH_OBJECT: /* no such tuple: look for closest parent */ - if ( matched ) { - NdbOperation *ops[NDB_MAX_RDNS]; - int i, j, k; - char dummy[2] = {0,0}; - - /* get to last RDN, then back up 1 */ - k = NA->rdns->nr_num - 1; - - for ( i=0; itxn->getNdbOperation( myTable ); - if ( !ops[i] ) - return LDAP_OTHER; - if ( ops[i]->readTuple( NdbOperation::LM_CommittedRead )) - return LDAP_OTHER; - for ( j=0; j<=i; j++ ) { - if ( ops[i]->equal( j+RDN_COLUMN, NA->rdns->nr_buf[j] )) - return LDAP_OTHER; - } - for ( ;jequal( j+RDN_COLUMN, dummy )) - return LDAP_OTHER; - } - } - if ( NA->txn->execute(NdbTransaction::NoCommit, NdbOperation::AO_IgnoreError, 1) < 0 ) { - return LDAP_OTHER; - } - for ( --i; i>=0; i-- ) { - if ( ops[i]->getNdbError().code == 0 ) { - for ( j=0; j<=i; j++ ) - matched->bv_len += NA->rdns->nr_buf[j][0]; - matched->bv_len += i; - matched->bv_val = NA->e->e_name.bv_val + - NA->e->e_name.bv_len - matched->bv_len; - break; - } - } - } - return LDAP_NO_SUCH_OBJECT; - default: - return LDAP_OTHER; - } - - return 0; -} - -extern "C" int -ndb_entry_del_info( - BackendDB *be, - NdbArgs *NA -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary(); - const NdbDictionary::Table *myTable = myDict->getTable( DN2ID_TABLE ); - NdbOperation *myop; - - myop = NA->txn->getNdbOperation( myTable ); - if ( !myop ) - return LDAP_OTHER; - if ( myop->deleteTuple()) - return LDAP_OTHER; - - if ( ndb_rdns2keys( myop, NA->rdns )) - return LDAP_OTHER; - - /* Let caller invoke the roundtrip */ - /* return txn->execute(NoCommit); */ - return 0; -} - -extern "C" int -ndb_next_id( - BackendDB *be, - Ndb *ndb, - ID *id -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - const NdbDictionary::Dictionary *myDict = ndb->getDictionary(); - const NdbDictionary::Table *myTable = myDict->getTable( NEXTID_TABLE ); - Uint64 nid = 0; - int rc; - - if ( !myTable ) { - Debug( LDAP_DEBUG_ANY, "ndb_next_id: " NEXTID_TABLE " table is missing\n", - 0, 0, 0 ); - return LDAP_OTHER; - } - - rc = ndb->getAutoIncrementValue( myTable, nid, 1000 ); - if ( !rc ) - *id = nid; - return rc; -} - -extern "C" { static void ndb_thread_hfree( void *key, void *data ); }; -static void -ndb_thread_hfree( void *key, void *data ) -{ - Ndb *ndb = (Ndb *)data; - delete ndb; -} - -extern "C" int -ndb_thread_handle( - Operation *op, - Ndb **ndb ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - void *data; - - if ( ldap_pvt_thread_pool_getkey( op->o_threadctx, ni, &data, NULL )) { - Ndb *myNdb; - int rc; - ldap_pvt_thread_mutex_lock( &ni->ni_conn_mutex ); - myNdb = new Ndb( ni->ni_cluster[ni->ni_nextconn++], ni->ni_dbname ); - if ( ni->ni_nextconn >= ni->ni_nconns ) - ni->ni_nextconn = 0; - ldap_pvt_thread_mutex_unlock( &ni->ni_conn_mutex ); - if ( !myNdb ) { - return LDAP_OTHER; - } - rc = myNdb->init(1024); - if ( rc ) { - delete myNdb; - Debug( LDAP_DEBUG_ANY, "ndb_thread_handle: err %d\n", - rc, 0, 0 ); - return rc; - } - data = (void *)myNdb; - if (( rc = ldap_pvt_thread_pool_setkey( op->o_threadctx, ni, - data, ndb_thread_hfree, NULL, NULL ))) { - delete myNdb; - Debug( LDAP_DEBUG_ANY, "ndb_thread_handle: err %d\n", - rc, 0, 0 ); - return rc; - } - } - *ndb = (Ndb *)data; - return 0; -} - -extern "C" int -ndb_entry_get( - Operation *op, - struct berval *ndn, - ObjectClass *oc, - AttributeDescription *ad, - int rw, - Entry **ent ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - NdbArgs NA; - Entry e = {0}; - int rc; - - /* Get our NDB handle */ - rc = ndb_thread_handle( op, &NA.ndb ); - - NA.txn = NA.ndb->startTransaction(); - if( !NA.txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_entry_get) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - return 1; - } - - e.e_name = *ndn; - NA.e = &e; - /* get entry */ - { - NdbRdns rdns; - rdns.nr_num = 0; - NA.ocs = NULL; - NA.rdns = &rdns; - rc = ndb_entry_get_info( op->o_bd, &NA, rw, NULL ); - } - if ( rc == 0 ) { - e.e_name = *ndn; - e.e_nname = *ndn; - rc = ndb_entry_get_data( op->o_bd, &NA, 0 ); - ber_bvarray_free( NA.ocs ); - if ( rc == 0 ) { - if ( oc && !is_entry_objectclass_or_sub( &e, oc )) { - attrs_free( e.e_attrs ); - rc = 1; - } - } - } - if ( rc == 0 ) { - *ent = entry_alloc(); - **ent = e; - ber_dupbv( &(*ent)->e_name, ndn ); - ber_dupbv( &(*ent)->e_nname, ndn ); - } else { - rc = 1; - } - NA.txn->close(); - return rc; -} - -/* Congestion avoidance code - * for Deadlock Rollback - */ - -extern "C" void -ndb_trans_backoff( int num_retries ) -{ - int i; - int delay = 0; - int pow_retries = 1; - unsigned long key = 0; - unsigned long max_key = -1; - struct timeval timeout; - - lutil_entropy( (unsigned char *) &key, sizeof( unsigned long )); - - for ( i = 0; i < num_retries; i++ ) { - if ( i >= 5 ) break; - pow_retries *= 4; - } - - delay = 16384 * (key * (double) pow_retries / (double) max_key); - delay = delay ? delay : 1; - - Debug( LDAP_DEBUG_TRACE, "delay = %d, num_retries = %d\n", delay, num_retries, 0 ); - - timeout.tv_sec = delay / 1000000; - timeout.tv_usec = delay % 1000000; - select( 0, NULL, NULL, NULL, &timeout ); -} diff --git a/servers/slapd/back-ndb/proto-ndb.h b/servers/slapd/back-ndb/proto-ndb.h deleted file mode 100644 index 9a2e1b8bc5..0000000000 --- a/servers/slapd/back-ndb/proto-ndb.h +++ /dev/null @@ -1,164 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#ifndef _PROTO_NDB_H -#define _PROTO_NDB_H - -LDAP_BEGIN_DECL - -extern BI_init ndb_back_initialize; - -extern BI_open ndb_back_open; -extern BI_close ndb_back_close; -extern BI_destroy ndb_back_destroy; - -extern BI_db_init ndb_back_db_init; -extern BI_db_destroy ndb_back_db_destroy; - -extern BI_op_bind ndb_back_bind; -extern BI_op_unbind ndb_back_unbind; -extern BI_op_search ndb_back_search; -extern BI_op_compare ndb_back_compare; -extern BI_op_modify ndb_back_modify; -extern BI_op_modrdn ndb_back_modrdn; -extern BI_op_add ndb_back_add; -extern BI_op_delete ndb_back_delete; - -extern BI_operational ndb_operational; -extern BI_has_subordinates ndb_has_subordinates; -extern BI_entry_get_rw ndb_entry_get; - -extern BI_tool_entry_open ndb_tool_entry_open; -extern BI_tool_entry_close ndb_tool_entry_close; -extern BI_tool_entry_first ndb_tool_entry_first; -extern BI_tool_entry_next ndb_tool_entry_next; -extern BI_tool_entry_get ndb_tool_entry_get; -extern BI_tool_entry_put ndb_tool_entry_put; -extern BI_tool_dn2id_get ndb_tool_dn2id_get; - -extern int ndb_modify_internal( - Operation *op, - NdbArgs *NA, - const char **text, - char *textbuf, - size_t textlen ); - -extern int -ndb_entry_get_data( - BackendDB *be, - NdbArgs *args, - int update ); - -extern int -ndb_entry_put_data( - BackendDB *be, - NdbArgs *args, - int update ); - -extern int -ndb_entry_del_data( - BackendDB *be, - NdbArgs *args ); - -extern int -ndb_entry_put_info( - BackendDB *be, - NdbArgs *args, - int update ); - -extern int -ndb_entry_get_info( - BackendDB *be, - NdbArgs *args, - int update, - struct berval *matched ); - -extern "C" int -ndb_entry_del_info( - BackendDB *be, - NdbArgs *args ); - -extern int -ndb_dn2rdns( - struct berval *dn, - NdbRdns *buf ); - -extern NdbAttrInfo * -ndb_ai_find( struct ndb_info *ni, AttributeType *at ); - -extern NdbAttrInfo * -ndb_ai_get( struct ndb_info *ni, struct berval *at ); - -extern int -ndb_aset_get( struct ndb_info *ni, struct berval *sname, struct berval *attrs, NdbOcInfo **ret ); - -extern int -ndb_aset_create( struct ndb_info *ni, NdbOcInfo *oci ); - -extern int -ndb_oc_read( struct ndb_info *ni, const NdbDictionary::Dictionary *dict ); - -extern int -ndb_oc_attrs( - NdbTransaction *txn, - const NdbDictionary::Table *myTable, - Entry *e, - NdbOcInfo *no, - NdbAttrInfo **attrs, - int nattrs, - int update, - int *num, - NdbOperation **retop ); - -extern int -ndb_has_children( - NdbArgs *NA, - int *hasChildren ); - -extern struct berval * -ndb_str2bvarray( - char *str, - int len, - char delim ); - -extern struct berval * -ndb_ref2oclist( - const char *ref ); - -extern int -ndb_next_id( - BackendDB *be, - Ndb *ndb, - ID *id ); - -extern int -ndb_thread_handle( - Operation *op, - Ndb **ndb ); - -extern int -ndb_back_init_cf( - BackendInfo *bi ); - -extern void -ndb_trans_backoff( int num_retries ); - -LDAP_END_DECL - -#endif /* _PROTO_NDB_H */ diff --git a/servers/slapd/back-ndb/search.cpp b/servers/slapd/back-ndb/search.cpp deleted file mode 100644 index 27ff48c993..0000000000 --- a/servers/slapd/back-ndb/search.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* search.cpp - tools for slap tools */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include -#include - -#include "lutil.h" - -#include "back-ndb.h" - -static int -ndb_dn2bound( - NdbIndexScanOperation *myop, - NdbRdns *rdns -) -{ - unsigned int i; - - /* Walk thru RDNs */ - for ( i=0; inr_num; i++ ) { - /* Note: RDN_COLUMN offset not needed here */ - if ( myop->setBound( i, NdbIndexScanOperation::BoundEQ, rdns->nr_buf[i] )) - return LDAP_OTHER; - } - return i; -} - -/* Check that all filter terms reside in the same table. - * - * If any of the filter terms are indexed, then only an IndexScan of the OL_index - * will be performed. If none are indexed, but all the terms reside in a single - * table, a Scan can be performed with the LDAP filter transformed into a ScanFilter. - * - * Otherwise, a full scan of the DB must be done with all filtering done by slapd. - */ -static int ndb_filter_check( struct ndb_info *ni, Filter *f, - NdbOcInfo **oci, int *indexed, int *ocfilter ) -{ - AttributeDescription *ad = NULL; - ber_tag_t choice = f->f_choice; - int rc = 0, undef = 0; - - if ( choice & SLAPD_FILTER_UNDEFINED ) { - choice &= SLAPD_FILTER_MASK; - undef = 1; - } - switch( choice ) { - case LDAP_FILTER_AND: - case LDAP_FILTER_OR: - case LDAP_FILTER_NOT: - for ( f = f->f_list; f; f=f->f_next ) { - rc = ndb_filter_check( ni, f, oci, indexed, ocfilter ); - if ( rc ) return rc; - } - break; - case LDAP_FILTER_PRESENT: - ad = f->f_desc; - break; - case LDAP_FILTER_EQUALITY: - case LDAP_FILTER_SUBSTRINGS: - case LDAP_FILTER_GE: - case LDAP_FILTER_LE: - case LDAP_FILTER_APPROX: - ad = f->f_av_desc; - break; - default: - break; - } - if ( ad && !undef ) { - NdbAttrInfo *ai; - /* ObjectClass filtering is in dn2id table */ - if ( ad == slap_schema.si_ad_objectClass ) { - if ( choice == LDAP_FILTER_EQUALITY ) - (*ocfilter)++; - return 0; - } - ai = ndb_ai_find( ni, ad->ad_type ); - if ( ai ) { - if ( ai->na_flag & NDB_INFO_INDEX ) - (*indexed)++; - if ( *oci ) { - if ( ai->na_oi != *oci ) - rc = -1; - } else { - *oci = ai->na_oi; - } - } - } - return rc; -} - -static int ndb_filter_set( Operation *op, struct ndb_info *ni, Filter *f, int indexed, - NdbIndexScanOperation *scan, NdbScanFilter **sf, int *bounds ) -{ - AttributeDescription *ad = NULL; - ber_tag_t choice = f->f_choice; - int undef = 0; - - if ( choice & SLAPD_FILTER_UNDEFINED ) { - choice &= SLAPD_FILTER_MASK; - undef = 1; - } - switch( choice ) { - case LDAP_FILTER_NOT: - /* no indexing for these */ - break; - case LDAP_FILTER_OR: - /* FIXME: these bounds aren't right. */ - if ( indexed ) { - scan->end_of_bound( (*bounds)++ ); - } - case LDAP_FILTER_AND: - for ( f = f->f_list; f; f=f->f_next ) { - if ( ndb_filter_set( op, ni, f, indexed, scan, sf, bounds )) - return -1; - } - break; - case LDAP_FILTER_PRESENT: - ad = f->f_desc; - break; - case LDAP_FILTER_EQUALITY: - case LDAP_FILTER_SUBSTRINGS: - case LDAP_FILTER_GE: - case LDAP_FILTER_LE: - case LDAP_FILTER_APPROX: - ad = f->f_av_desc; - break; - default: - break; - } - if ( ad && !undef ) { - NdbAttrInfo *ai; - /* ObjectClass filtering is in dn2id table */ - if ( ad == slap_schema.si_ad_objectClass ) { - return 0; - } - ai = ndb_ai_find( ni, ad->ad_type ); - if ( ai ) { - if ( ai->na_flag & NDB_INFO_INDEX ) { - char *buf, *ptr; - NdbIndexScanOperation::BoundType bt; - int rc; - - switch(choice) { - case LDAP_FILTER_PRESENT: - rc = scan->setBound( ai->na_ixcol - IDX_COLUMN, - NdbIndexScanOperation::BoundGT, NULL ); - break; - case LDAP_FILTER_EQUALITY: - case LDAP_FILTER_APPROX: - bt = NdbIndexScanOperation::BoundEQ; - goto setit; - case LDAP_FILTER_GE: - bt = NdbIndexScanOperation::BoundGE; - goto setit; - case LDAP_FILTER_LE: - bt = NdbIndexScanOperation::BoundLE; - setit: - rc = f->f_av_value.bv_len+1; - if ( ai->na_len > 255 ) - rc++; - buf = (char *)op->o_tmpalloc( rc, op->o_tmpmemctx ); - rc = f->f_av_value.bv_len; - buf[0] = rc & 0xff; - ptr = buf+1; - if ( ai->na_len > 255 ) { - buf[1] = (rc >> 8); - ptr++; - } - memcpy( ptr, f->f_av_value.bv_val, f->f_av_value.bv_len ); - rc = scan->setBound( ai->na_ixcol - IDX_COLUMN, bt, buf ); - op->o_tmpfree( buf, op->o_tmpmemctx ); - break; - default: - break; - } - } else { - } - } - } - return 0; -} - -static int ndb_oc_search( Operation *op, SlapReply *rs, Ndb *ndb, NdbTransaction *txn, - NdbRdns *rbase, NdbOcInfo *oci, int indexed ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - const NdbDictionary::Dictionary *myDict = ndb->getDictionary(); - const NdbDictionary::Table *myTable; - const NdbDictionary::Index *myIndex; - NdbIndexScanOperation *scan; - NdbIndexOperation *ixop; - NdbScanFilter *sf = NULL; - struct berval *ocs, matched; - NdbRecAttr *scanID, *scanOC, *scanDN[NDB_MAX_RDNS]; - char dnBuf[2048], *ptr; - NdbRdns rdns; - NdbArgs NA; - char idbuf[2*sizeof(ID)]; - char ocbuf[NDB_OC_BUFLEN]; - int i, rc, bounds; - Entry e = {0}; - Uint64 eid; - - myTable = myDict->getTable( oci->no_table.bv_val ); - if ( indexed ) { - scan = txn->getNdbIndexScanOperation( INDEX_NAME, DN2ID_TABLE ); - if ( !scan ) - return LDAP_OTHER; - } else { - myIndex = myDict->getIndex( "eid$unique", DN2ID_TABLE ); - if ( !myIndex ) { - Debug( LDAP_DEBUG_ANY, DN2ID_TABLE " eid index is missing!\n", 0, 0, 0 ); - rs->sr_err = LDAP_OTHER; - goto leave; - } - scan = (NdbIndexScanOperation *)txn->getNdbScanOperation( myTable ); - if ( !scan ) - return LDAP_OTHER; - sf = new NdbScanFilter(scan); - if ( !sf ) - return LDAP_OTHER; - switch ( op->ors_filter->f_choice ) { - case LDAP_FILTER_AND: - case LDAP_FILTER_OR: - case LDAP_FILTER_NOT: - break; - default: - if ( sf->begin() < 0 ) { - rc = LDAP_OTHER; - goto leave; - } - } - } - scan->readTuples( NdbOperation::LM_CommittedRead ); - - bounds = 0; - rc = ndb_filter_set( op, ni, op->ors_filter, indexed, scan, &sf, &bounds ); - if ( rc ) - goto leave; - - scanID = scan->getValue( EID_COLUMN, idbuf ); - if ( indexed ) { - scanOC = scan->getValue( OCS_COLUMN, ocbuf ); - for ( i=0; igetValue( RDN_COLUMN+i, rdns.nr_buf[i] ); - } - } - - if ( txn->execute( NdbTransaction::NoCommit, NdbOperation::AbortOnError, 1 )) { - rs->sr_err = LDAP_OTHER; - goto leave; - } - - e.e_name.bv_val = dnBuf; - NA.e = &e; - NA.ndb = ndb; - while ( scan->nextResult() == 0 ) { - NdbTransaction *tx2; - if ( op->o_abandon ) - break; - eid = scanID->u_64_value(); - e.e_id = eid; - if ( !indexed ) { - tx2 = ndb->startTransaction( myTable ); - if ( !tx2 ) { - rs->sr_err = LDAP_OTHER; - goto leave; - } - - ixop = tx2->getNdbIndexOperation( myIndex ); - if ( !ixop ) { - tx2->close(); - rs->sr_err = LDAP_OTHER; - goto leave; - } - ixop->readTuple( NdbOperation::LM_CommittedRead ); - ixop->equal( EID_COLUMN, eid ); - - scanOC = ixop->getValue( OCS_COLUMN, ocbuf ); - for ( i=0; igetValue( RDN_COLUMN+i, rdns.nr_buf[i] ); - } - rc = tx2->execute( NdbTransaction::Commit, NdbOperation::AbortOnError, 1 ); - tx2->close(); - if ( rc ) { - rs->sr_err = LDAP_OTHER; - goto leave; - } - } - - ocs = ndb_ref2oclist( ocbuf ); - for ( i=0; iisNULL() || !rdns.nr_buf[i][0] ) - break; - } - rdns.nr_num = i; - - /* entry must be subordinate to the base */ - if ( i < rbase->nr_num ) { - continue; - } - - ptr = dnBuf; - for ( --i; i>=0; i-- ) { - char *buf; - int len; - buf = rdns.nr_buf[i]; - len = *buf++; - ptr = lutil_strncopy( ptr, buf, len ); - if ( i ) *ptr++ = ','; - } - *ptr = '\0'; - e.e_name.bv_len = ptr - dnBuf; - - /* More scope checks */ - /* If indexed, these can be moved into the ScanFilter */ - switch( op->ors_scope ) { - case LDAP_SCOPE_ONELEVEL: - if ( rdns.nr_num != rbase->nr_num+1 ) - continue; - case LDAP_SCOPE_SUBORDINATE: - if ( rdns.nr_num == rbase->nr_num ) - continue; - case LDAP_SCOPE_SUBTREE: - default: - if ( e.e_name.bv_len <= op->o_req_dn.bv_len ) { - if ( op->ors_scope != LDAP_SCOPE_SUBTREE || - strcasecmp( op->o_req_dn.bv_val, e.e_name.bv_val )) - continue; - } else if ( strcasecmp( op->o_req_dn.bv_val, e.e_name.bv_val + - e.e_name.bv_len - op->o_req_dn.bv_len )) - continue; - } - - dnNormalize( 0, NULL, NULL, &e.e_name, &e.e_nname, op->o_tmpmemctx ); - { -#ifdef notdef /* NDBapi is broken here */ - Ndb::Key_part_ptr keys[2]; - char xbuf[32]; - keys[0].ptr = &eid; - keys[0].len = sizeof(eid); - keys[1].ptr = NULL; - keys[1].len = 0; - tx2 = ndb->startTransaction( myTable, keys, xbuf, sizeof(xbuf)); -#else - tx2 = ndb->startTransaction( myTable ); -#endif - if ( !tx2 ) { - rs->sr_err = LDAP_OTHER; - goto leave; - } - NA.txn = tx2; - NA.ocs = ocs; - rc = ndb_entry_get_data( op->o_bd, &NA, 0 ); - tx2->close(); - } - ber_bvarray_free( ocs ); - rc = test_filter( op, &e, op->ors_filter ); - if ( rc == LDAP_COMPARE_TRUE ) { - rs->sr_entry = &e; - rs->sr_attrs = op->ors_attrs; - rs->sr_flags = 0; - rc = send_search_entry( op, rs ); - rs->sr_entry = NULL; - } else { - rc = 0; - } - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - op->o_tmpfree( e.e_nname.bv_val, op->o_tmpmemctx ); - if ( rc ) break; - } -leave: - if ( sf ) delete sf; - return rc; -} - -extern "C" -int ndb_back_search( Operation *op, SlapReply *rs ) -{ - struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; - NdbTransaction *txn, *tx2; - NdbIndexScanOperation *scan; - NdbScanFilter *sf = NULL; - Entry e = {0}; - int rc, i, ocfilter, indexed; - struct berval matched; - NdbRecAttr *scanID, *scanOC, *scanDN[NDB_MAX_RDNS]; - char dnBuf[2048], *ptr; - char idbuf[2*sizeof(ID)]; - char ocbuf[NDB_OC_BUFLEN]; - NdbRdns rdns; - NdbOcInfo *oci; - NdbArgs NA; - - rc = ndb_thread_handle( op, &NA.ndb ); - rdns.nr_num = 0; - - txn = NA.ndb->startTransaction(); - if ( !txn ) { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(ndb_back_search) ": startTransaction failed: %s (%d)\n", - NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "internal error"; - goto leave; - } - - NA.txn = txn; - e.e_name = op->o_req_dn; - NA.e = &e; - NA.rdns = &rdns; - NA.ocs = op->ors_scope == LDAP_SCOPE_BASE ? NULL : &matched; - - rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 0, &matched ); - if ( rs->sr_err ) { - if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) - rs->sr_matched = matched.bv_val; - goto leave; - } - - if ( op->ors_scope == LDAP_SCOPE_BASE ) { - e.e_name = op->o_req_dn; - e.e_nname = op->o_req_ndn; - rc = ndb_entry_get_data( op->o_bd, &NA, 0 ); - ber_bvarray_free( NA.ocs ); - rc = test_filter( op, &e, op->ors_filter ); - if ( rc == LDAP_COMPARE_TRUE ) { - rs->sr_entry = &e; - rs->sr_attrs = op->ors_attrs; - rs->sr_flags = 0; - send_search_entry( op, rs ); - rs->sr_entry = NULL; - } - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - rs->sr_err = LDAP_SUCCESS; - goto leave; - } else if ( rdns.nr_num == NDB_MAX_RDNS ) { - if ( op->ors_scope == LDAP_SCOPE_ONELEVEL || - op->ors_scope == LDAP_SCOPE_CHILDREN ) - rs->sr_err = LDAP_SUCCESS; - goto leave; - } - - /* See if we can handle the filter. Filtering on objectClass is only done - * in the DN2ID table scan. If all other filter terms reside in one table, - * then we scan the OC table instead of the DN2ID table. - */ - oci = NULL; - indexed = 0; - ocfilter = 0; - rc = ndb_filter_check( ni, op->ors_filter, &oci, &indexed, &ocfilter ); - if ( rc ) { - Debug( LDAP_DEBUG_TRACE, "ndb_back_search: " - "filter attributes from multiple tables, indexing ignored\n", - 0, 0, 0 ); - } else if ( oci ) { - rc = ndb_oc_search( op, rs, NA.ndb, txn, &rdns, oci, indexed ); - goto leave; - } - - scan = txn->getNdbIndexScanOperation( "PRIMARY", DN2ID_TABLE ); - scan->readTuples( NdbOperation::LM_CommittedRead ); - rc = ndb_dn2bound( scan, &rdns ); - - switch( op->ors_scope ) { - case LDAP_SCOPE_ONELEVEL: - sf = new NdbScanFilter(scan); - if ( sf->begin() < 0 || - sf->cmp(NdbScanFilter::COND_NOT_LIKE, rc+3, "_%", - STRLENOF("_%")) < 0 || - sf->end() < 0 ) { - rs->sr_err = LDAP_OTHER; - goto leave; - } - /* FALLTHRU */ - case LDAP_SCOPE_CHILDREN: - /* Note: RDN_COLUMN offset not needed here */ - scan->setBound( rc, NdbIndexScanOperation::BoundLT, "\0" ); - /* FALLTHRU */ - case LDAP_SCOPE_SUBTREE: - break; - } - scanID = scan->getValue( EID_COLUMN, idbuf ); - scanOC = scan->getValue( OCS_COLUMN, ocbuf ); - for ( i=0; igetValue( RDN_COLUMN+i, rdns.nr_buf[i] ); - } - if ( txn->execute( NdbTransaction::NoCommit, NdbOperation::AbortOnError, 1 )) { - rs->sr_err = LDAP_OTHER; - goto leave; - } - - e.e_name.bv_val = dnBuf; - while ( scan->nextResult() == 0 ) { - if ( op->o_abandon ) - break; - e.e_id = scanID->u_64_value(); - NA.ocs = ndb_ref2oclist( ocbuf ); - for ( i=0; iisNULL() || !rdns.nr_buf[i][0] ) - break; - } - ptr = dnBuf; - rdns.nr_num = i; - for ( --i; i>=0; i-- ) { - char *buf; - int len; - buf = rdns.nr_buf[i]; - len = *buf++; - ptr = lutil_strncopy( ptr, buf, len ); - if ( i ) *ptr++ = ','; - } - *ptr = '\0'; - e.e_name.bv_len = ptr - dnBuf; - dnNormalize( 0, NULL, NULL, &e.e_name, &e.e_nname, op->o_tmpmemctx ); - NA.txn = NA.ndb->startTransaction(); - rc = ndb_entry_get_data( op->o_bd, &NA, 0 ); - NA.txn->close(); - ber_bvarray_free( NA.ocs ); - rc = test_filter( op, &e, op->ors_filter ); - if ( rc == LDAP_COMPARE_TRUE ) { - rs->sr_entry = &e; - rs->sr_attrs = op->ors_attrs; - rs->sr_flags = 0; - rc = send_search_entry( op, rs ); - rs->sr_entry = NULL; - } else { - rc = 0; - } - attrs_free( e.e_attrs ); - e.e_attrs = NULL; - op->o_tmpfree( e.e_nname.bv_val, op->o_tmpmemctx ); - if ( rc ) break; - } -leave: - if ( sf ) - delete sf; - txn->close(); - send_ldap_result( op, rs ); - return rs->sr_err; -} - -extern "C" int -ndb_has_children( - NdbArgs *NA, - int *hasChildren -) -{ - NdbIndexScanOperation *scan; - char idbuf[2*sizeof(ID)]; - int rc; - - if ( NA->rdns->nr_num >= NDB_MAX_RDNS ) { - *hasChildren = LDAP_COMPARE_FALSE; - return 0; - } - - scan = NA->txn->getNdbIndexScanOperation( "PRIMARY", DN2ID_TABLE ); - if ( !scan ) - return LDAP_OTHER; - scan->readTuples( NdbOperation::LM_Read, 0U, 0U, 1U ); - rc = ndb_dn2bound( scan, NA->rdns ); - if ( rc < NDB_MAX_RDNS ) { - scan->setBound( rc, NdbIndexScanOperation::BoundLT, "\0" ); - } - scan->interpret_exit_last_row(); - scan->getValue( EID_COLUMN, idbuf ); - if ( NA->txn->execute( NdbTransaction::NoCommit, NdbOperation::AO_IgnoreError, 1 )) { - return LDAP_OTHER; - } - if (rc < NDB_MAX_RDNS && scan->nextResult() == 0 ) - *hasChildren = LDAP_COMPARE_TRUE; - else - *hasChildren = LDAP_COMPARE_FALSE; - return 0; -} - -extern "C" int -ndb_has_subordinates( - Operation *op, - Entry *e, - int *hasSubordinates ) -{ - NdbArgs NA; - NdbRdns rdns; - int rc; - - NA.rdns = &rdns; - rc = ndb_dn2rdns( &e->e_nname, &rdns ); - - if ( rc == 0 ) { - rc = ndb_thread_handle( op, &NA.ndb ); - NA.txn = NA.ndb->startTransaction(); - if ( NA.txn ) { - rc = ndb_has_children( &NA, hasSubordinates ); - NA.txn->close(); - } - } - - return rc; -} - -/* - * sets the supported operational attributes (if required) - */ -extern "C" int -ndb_operational( - Operation *op, - SlapReply *rs ) -{ - Attribute **ap; - - assert( rs->sr_entry != NULL ); - - for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) - /* just count */ ; - - if ( SLAP_OPATTRS( rs->sr_attr_flags ) || - ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) - { - int hasSubordinates, rc; - - rc = ndb_has_subordinates( op, rs->sr_entry, &hasSubordinates ); - if ( rc == LDAP_SUCCESS ) { - *ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE ); - assert( *ap != NULL ); - - ap = &(*ap)->a_next; - } - } - - return LDAP_SUCCESS; -} - diff --git a/servers/slapd/back-ndb/tools.cpp b/servers/slapd/back-ndb/tools.cpp deleted file mode 100644 index a75bee84d9..0000000000 --- a/servers/slapd/back-ndb/tools.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/* tools.cpp - tools for slap tools */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2008 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 initially developed by Howard Chu for inclusion - * in OpenLDAP Software. This work was sponsored by MySQL. - */ - -#include "portable.h" - -#include -#include -#include - -#include "lutil.h" - -#include "back-ndb.h" - -typedef struct dn_id { - ID id; - struct berval dn; -} dn_id; - -#define HOLE_SIZE 4096 -static dn_id hbuf[HOLE_SIZE], *holes = hbuf; -static unsigned nhmax = HOLE_SIZE; -static unsigned nholes; -static Avlnode *myParents; - -static Ndb *myNdb; -static NdbTransaction *myScanTxn; -static NdbIndexScanOperation *myScanOp; - -static NdbRecAttr *myScanID, *myScanOC; -static NdbRecAttr *myScanDN[NDB_MAX_RDNS]; -static char myDNbuf[2048]; -static char myIdbuf[2*sizeof(ID)]; -static char myOcbuf[NDB_OC_BUFLEN]; -static NdbRdns myRdns; - -static NdbTransaction *myPutTxn; -static int myPutCnt; - -static struct berval *myOcList; -static struct berval myDn; - -extern "C" -int ndb_tool_entry_open( - BackendDB *be, int mode ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - - myNdb = new Ndb( ni->ni_cluster[0], ni->ni_dbname ); - return myNdb->init(1024); -} - -extern "C" -int ndb_tool_entry_close( - BackendDB *be ) -{ - if ( myPutTxn ) { - int rc = myPutTxn->execute(NdbTransaction::Commit); - if( rc != 0 ) { - char text[1024]; - snprintf( text, sizeof(text), - "txn_commit failed: %s (%d)", - myPutTxn->getNdbError().message, myPutTxn->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_entry_put) ": %s\n", - text, 0, 0 ); - } - myPutTxn->close(); - myPutTxn = NULL; - } - myPutCnt = 0; - - if( nholes ) { - unsigned i; - fprintf( stderr, "Error, entries missing!\n"); - for (i=0; ibe_private; - char *ptr; - ID id; - int i; - - assert( be != NULL ); - assert( slapMode & SLAP_TOOL_MODE ); - - if ( myScanOp->nextResult() ) { - myScanOp->close(); - myScanOp = NULL; - myScanTxn->close(); - myScanTxn = NULL; - return NOID; - } - id = myScanID->u_64_value(); - - if ( myOcList ) { - ber_bvarray_free( myOcList ); - } - myOcList = ndb_ref2oclist( myOcbuf ); - for ( i=0; iisNULL() || !myRdns.nr_buf[i] ) - break; - } - myRdns.nr_num = i; - ptr = myDNbuf; - for ( --i; i>=0; i-- ) { - char *buf; - int len; - buf = myRdns.nr_buf[i]; - len = *buf++; - ptr = lutil_strncopy( ptr, buf, len ); - if ( i ) - *ptr++ = ','; - } - *ptr = '\0'; - myDn.bv_val = myDNbuf; - myDn.bv_len = ptr - myDNbuf; - - return id; -} - -extern "C" -ID ndb_tool_entry_first( - BackendDB *be ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - int i, rc; - - myScanTxn = myNdb->startTransaction(); - if ( !myScanTxn ) - return NOID; - - myScanOp = myScanTxn->getNdbIndexScanOperation( "PRIMARY", DN2ID_TABLE ); - if ( !myScanOp ) - return NOID; - - if ( myScanOp->readTuples( NdbOperation::LM_CommittedRead, NdbScanOperation::SF_KeyInfo )) - return NOID; - - myScanID = myScanOp->getValue( EID_COLUMN, myIdbuf ); - myScanOC = myScanOp->getValue( OCS_COLUMN, myOcbuf ); - for ( i=0; igetValue( i+RDN_COLUMN, myRdns.nr_buf[i] ); - } - if ( myScanTxn->execute( NdbTransaction::NoCommit, NdbOperation::AbortOnError, 1 )) - return NOID; - - return ndb_tool_entry_next( be ); -} - -extern "C" -ID ndb_tool_dn2id_get( - Backend *be, - struct berval *dn -) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - NdbArgs NA; - NdbRdns rdns; - Entry e; - char text[1024]; - int rc; - - if ( BER_BVISEMPTY(dn) ) - return 0; - - NA.ndb = myNdb; - NA.txn = myNdb->startTransaction(); - if ( !NA.txn ) { - snprintf( text, sizeof(text), - "startTransaction failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_dn2id_get) ": %s\n", - text, 0, 0 ); - return NOID; - } - if ( myOcList ) { - ber_bvarray_free( myOcList ); - myOcList = NULL; - } - NA.e = &e; - e.e_name = *dn; - NA.rdns = &rdns; - NA.ocs = NULL; - rc = ndb_entry_get_info( be, &NA, 0, NULL ); - myOcList = NA.ocs; - NA.txn->close(); - if ( rc ) - return NOID; - - myDn = *dn; - - return e.e_id; -} - -extern "C" -Entry* ndb_tool_entry_get( BackendDB *be, ID id ) -{ - NdbArgs NA; - int rc; - char text[1024]; - - assert( be != NULL ); - assert( slapMode & SLAP_TOOL_MODE ); - - NA.txn = myNdb->startTransaction(); - if ( !NA.txn ) { - snprintf( text, sizeof(text), - "start_transaction failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_entry_get) ": %s\n", - text, 0, 0 ); - return NULL; - } - - NA.e = entry_alloc(); - NA.e->e_id = id; - ber_dupbv( &NA.e->e_name, &myDn ); - dnNormalize( 0, NULL, NULL, &NA.e->e_name, &NA.e->e_nname, NULL ); - - - NA.ndb = myNdb; - NA.ocs = myOcList; - rc = ndb_entry_get_data( be, &NA, 0 ); - - if ( rc ) { - entry_free( NA.e ); - NA.e = NULL; - } - NA.txn->close(); - - return NA.e; -} - -static struct berval glueval[] = { - BER_BVC("glue"), - BER_BVNULL -}; - -static int ndb_dnid_cmp( const void *v1, const void *v2 ) -{ - struct dn_id *dn1 = (struct dn_id *)v1, - *dn2 = (struct dn_id *)v2; - return ber_bvcmp( &dn1->dn, &dn2->dn ); -} - -static int ndb_tool_next_id( - BackendDB *be, - NdbArgs *NA, - struct berval *text, - int hole ) -{ - struct berval ndn = NA->e->e_nname; - int rc; - - if (ndn.bv_len == 0) { - NA->e->e_id = 0; - return 0; - } - - rc = ndb_entry_get_info( be, NA, 0, NULL ); - if ( rc ) { - Attribute *a, tmp = {0}; - if ( !be_issuffix( be, &ndn ) ) { - struct dn_id *dptr; - struct berval npdn; - dnParent( &ndn, &npdn ); - NA->e->e_nname = npdn; - NA->rdns->nr_num--; - rc = ndb_tool_next_id( be, NA, text, 1 ); - NA->e->e_nname = ndn; - NA->rdns->nr_num++; - if ( rc ) { - return rc; - } - /* If parent didn't exist, it was created just now - * and its ID is now in e->e_id. - */ - dptr = (struct dn_id *)ch_malloc( sizeof( struct dn_id ) + npdn.bv_len + 1); - dptr->id = NA->e->e_id; - dptr->dn.bv_val = (char *)(dptr+1); - strcpy(dptr->dn.bv_val, npdn.bv_val ); - dptr->dn.bv_len = npdn.bv_len; - if ( avl_insert( &myParents, dptr, ndb_dnid_cmp, avl_dup_error )) { - ch_free( dptr ); - } - } - rc = ndb_next_id( be, myNdb, &NA->e->e_id ); - if ( rc ) { - snprintf( text->bv_val, text->bv_len, - "next_id failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> ndb_tool_next_id: %s\n", text->bv_val, 0, 0 ); - return rc; - } - if ( hole ) { - a = NA->e->e_attrs; - NA->e->e_attrs = &tmp; - tmp.a_desc = slap_schema.si_ad_objectClass; - tmp.a_vals = glueval; - tmp.a_nvals = tmp.a_vals; - tmp.a_numvals = 1; - } - rc = ndb_entry_put_info( be, NA, 0 ); - if ( hole ) { - NA->e->e_attrs = a; - } - if ( rc ) { - snprintf( text->bv_val, text->bv_len, - "ndb_entry_put_info failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> ndb_tool_next_id: %s\n", text->bv_val, 0, 0 ); - } else if ( hole ) { - if ( nholes == nhmax - 1 ) { - if ( holes == hbuf ) { - holes = (dn_id *)ch_malloc( nhmax * sizeof(dn_id) * 2 ); - AC_MEMCPY( holes, hbuf, sizeof(hbuf) ); - } else { - holes = (dn_id *)ch_realloc( holes, nhmax * sizeof(dn_id) * 2 ); - } - nhmax *= 2; - } - ber_dupbv( &holes[nholes].dn, &ndn ); - holes[nholes++].id = NA->e->e_id; - } - } else if ( !hole ) { - unsigned i; - - for ( i=0; ie->e_id ) { - int j; - free(holes[i].dn.bv_val); - for (j=i;j NA->e->e_id ) { - break; - } - } - } - return rc; -} - -extern "C" -ID ndb_tool_entry_put( - BackendDB *be, - Entry *e, - struct berval *text ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - struct dn_id dtmp, *dptr; - NdbArgs NA; - NdbRdns rdns; - int rc, slow = 0; - - assert( be != NULL ); - assert( slapMode & SLAP_TOOL_MODE ); - - assert( text != NULL ); - assert( text->bv_val != NULL ); - assert( text->bv_val[0] == '\0' ); /* overconservative? */ - - Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(ndb_tool_entry_put) - "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 ); - - if ( !be_issuffix( be, &e->e_nname )) { - dnParent( &e->e_nname, &dtmp.dn ); - dptr = (struct dn_id *)avl_find( myParents, &dtmp, ndb_dnid_cmp ); - if ( !dptr ) - slow = 1; - } - - rdns.nr_num = 0; - - if ( !slow ) { - rc = ndb_next_id( be, myNdb, &e->e_id ); - if ( rc ) { - snprintf( text->bv_val, text->bv_len, - "next_id failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> ndb_tool_next_id: %s\n", text->bv_val, 0, 0 ); - return rc; - } - } - - if ( !myPutTxn ) - myPutTxn = myNdb->startTransaction(); - if ( !myPutTxn ) { - snprintf( text->bv_val, text->bv_len, - "start_transaction failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_entry_put) ": %s\n", - text->bv_val, 0, 0 ); - return NOID; - } - - /* add dn2id indices */ - ndb_dn2rdns( &e->e_name, &rdns ); - NA.rdns = &rdns; - NA.e = e; - NA.ndb = myNdb; - NA.txn = myPutTxn; - if ( slow ) { - rc = ndb_tool_next_id( be, &NA, text, 0 ); - if( rc != 0 ) { - goto done; - } - } else { - rc = ndb_entry_put_info( be, &NA, 0 ); - if ( rc != 0 ) { - goto done; - } - } - - /* id2entry index */ - rc = ndb_entry_put_data( be, &NA, 0 ); - if( rc != 0 ) { - snprintf( text->bv_val, text->bv_len, - "ndb_entry_put_data failed: %s (%d)", - myNdb->getNdbError().message, myNdb->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_entry_put) ": %s\n", - text->bv_val, 0, 0 ); - goto done; - } - -done: - if( rc == 0 ) { - myPutCnt++; - if ( !( myPutCnt & 0x0f )) { - rc = myPutTxn->execute(NdbTransaction::Commit); - if( rc != 0 ) { - snprintf( text->bv_val, text->bv_len, - "txn_commit failed: %s (%d)", - myPutTxn->getNdbError().message, myPutTxn->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_entry_put) ": %s\n", - text->bv_val, 0, 0 ); - e->e_id = NOID; - } - myPutTxn->close(); - myPutTxn = NULL; - } - } else { - snprintf( text->bv_val, text->bv_len, - "txn_aborted! %s (%d)", - myPutTxn->getNdbError().message, myPutTxn->getNdbError().code ); - Debug( LDAP_DEBUG_ANY, - "=> " LDAP_XSTRING(ndb_tool_entry_put) ": %s\n", - text->bv_val, 0, 0 ); - e->e_id = NOID; - myPutTxn->close(); - } - - return e->e_id; -} - -extern "C" -int ndb_tool_entry_reindex( - BackendDB *be, - ID id, - AttributeDescription **adv ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - - Debug( LDAP_DEBUG_ARGS, - "=> " LDAP_XSTRING(ndb_tool_entry_reindex) "( %ld )\n", - (long) id, 0, 0 ); - - return 0; -} - -extern "C" -ID ndb_tool_entry_modify( - BackendDB *be, - Entry *e, - struct berval *text ) -{ - struct ndb_info *ni = (struct ndb_info *) be->be_private; - int rc; - - Debug( LDAP_DEBUG_TRACE, - "=> " LDAP_XSTRING(ndb_tool_entry_modify) "( %ld, \"%s\" )\n", - (long) e->e_id, e->e_dn, 0 ); - -done: - return e->e_id; -} - -- 2.39.5