From 037d513aee9266923d8d88f5a106eb83c9fc1565 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sat, 8 Apr 2006 04:24:48 +0000 Subject: [PATCH] Move LDBM to the attic --- servers/slapd/back-ldbm/Makefile.in | 54 - servers/slapd/back-ldbm/add.c | 338 ------ servers/slapd/back-ldbm/alias.c | 240 ---- servers/slapd/back-ldbm/attr.c | 231 ---- servers/slapd/back-ldbm/back-ldbm.h | 161 --- servers/slapd/back-ldbm/bind.c | 195 ---- servers/slapd/back-ldbm/cache.c | 675 ----------- servers/slapd/back-ldbm/close.c | 43 - servers/slapd/back-ldbm/compare.c | 133 --- servers/slapd/back-ldbm/config.c | 186 --- servers/slapd/back-ldbm/dbcache.c | 356 ------ servers/slapd/back-ldbm/delete.c | 223 ---- servers/slapd/back-ldbm/dn2id.c | 371 ------ servers/slapd/back-ldbm/entry.c | 140 --- servers/slapd/back-ldbm/extended.c | 52 - servers/slapd/back-ldbm/filterindex.c | 684 ----------- servers/slapd/back-ldbm/id2children.c | 71 -- servers/slapd/back-ldbm/id2entry.c | 234 ---- servers/slapd/back-ldbm/idl.c | 1263 --------------------- servers/slapd/back-ldbm/index.c | 327 ------ servers/slapd/back-ldbm/init.c | 266 ----- servers/slapd/back-ldbm/key.c | 95 -- servers/slapd/back-ldbm/ldbm.c | 1211 -------------------- servers/slapd/back-ldbm/ldbm.h | 278 ----- servers/slapd/back-ldbm/modify.c | 305 ----- servers/slapd/back-ldbm/modrdn.c | 445 -------- servers/slapd/back-ldbm/nextid.c | 135 --- servers/slapd/back-ldbm/operational.c | 77 -- servers/slapd/back-ldbm/proto-back-ldbm.h | 263 ----- servers/slapd/back-ldbm/referral.c | 127 --- servers/slapd/back-ldbm/search.c | 571 ---------- servers/slapd/back-ldbm/tools.c | 316 ------ 32 files changed, 10066 deletions(-) delete mode 100644 servers/slapd/back-ldbm/Makefile.in delete mode 100644 servers/slapd/back-ldbm/add.c delete mode 100644 servers/slapd/back-ldbm/alias.c delete mode 100644 servers/slapd/back-ldbm/attr.c delete mode 100644 servers/slapd/back-ldbm/back-ldbm.h delete mode 100644 servers/slapd/back-ldbm/bind.c delete mode 100644 servers/slapd/back-ldbm/cache.c delete mode 100644 servers/slapd/back-ldbm/close.c delete mode 100644 servers/slapd/back-ldbm/compare.c delete mode 100644 servers/slapd/back-ldbm/config.c delete mode 100644 servers/slapd/back-ldbm/dbcache.c delete mode 100644 servers/slapd/back-ldbm/delete.c delete mode 100644 servers/slapd/back-ldbm/dn2id.c delete mode 100644 servers/slapd/back-ldbm/entry.c delete mode 100644 servers/slapd/back-ldbm/extended.c delete mode 100644 servers/slapd/back-ldbm/filterindex.c delete mode 100644 servers/slapd/back-ldbm/id2children.c delete mode 100644 servers/slapd/back-ldbm/id2entry.c delete mode 100644 servers/slapd/back-ldbm/idl.c delete mode 100644 servers/slapd/back-ldbm/index.c delete mode 100644 servers/slapd/back-ldbm/init.c delete mode 100644 servers/slapd/back-ldbm/key.c delete mode 100644 servers/slapd/back-ldbm/ldbm.c delete mode 100644 servers/slapd/back-ldbm/ldbm.h delete mode 100644 servers/slapd/back-ldbm/modify.c delete mode 100644 servers/slapd/back-ldbm/modrdn.c delete mode 100644 servers/slapd/back-ldbm/nextid.c delete mode 100644 servers/slapd/back-ldbm/operational.c delete mode 100644 servers/slapd/back-ldbm/proto-back-ldbm.h delete mode 100644 servers/slapd/back-ldbm/referral.c delete mode 100644 servers/slapd/back-ldbm/search.c delete mode 100644 servers/slapd/back-ldbm/tools.c diff --git a/servers/slapd/back-ldbm/Makefile.in b/servers/slapd/back-ldbm/Makefile.in deleted file mode 100644 index f01e830a72..0000000000 --- a/servers/slapd/back-ldbm/Makefile.in +++ /dev/null @@ -1,54 +0,0 @@ -# Makefile.in for back-ldbm -# $OpenLDAP$ -## This work is part of OpenLDAP Software . -## -## Copyright 1998-2006 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 -## . - -SRCS = idl.c add.c search.c cache.c dbcache.c dn2id.c entry.c \ - id2entry.c index.c id2children.c nextid.c \ - compare.c modify.c modrdn.c delete.c init.c \ - config.c bind.c attr.c filterindex.c close.c \ - alias.c tools.c key.c extended.c \ - referral.c operational.c ldbm.c -OBJS = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo \ - id2entry.lo index.lo id2children.lo nextid.lo \ - compare.lo modify.lo modrdn.lo delete.lo init.lo \ - config.lo bind.lo attr.lo filterindex.lo close.lo \ - alias.lo tools.lo key.lo extended.lo \ - referral.lo operational.lo ldbm.lo - -LDAP_INCDIR= ../../../include -LDAP_LIBDIR= ../../../libraries - -BUILD_OPT = "--enable-ldbm" -BUILD_MOD = @BUILD_LDBM@ - -mod_DEFS = -DSLAPD_IMPORT -MOD_DEFS = $(@BUILD_LDBM@_DEFS) -MOD_LIBS = $(LDBM_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_ldbm - -XINCPATH = -I.. -I$(srcdir)/.. -XDEFS = $(MODULES_CPPFLAGS) -XXSRCS = $(@BUILD_LDBM@_SRCS) - -all-local-lib: ../.backend - -../.backend: lib$(LIBBASE).a - @touch $@ - -depend-common: $(XXSRCS) diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c deleted file mode 100644 index c44f1eb13d..0000000000 --- a/servers/slapd/back-ldbm/add.c +++ /dev/null @@ -1,338 +0,0 @@ -/* add.c - ldap ldbm back-end add routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -static int -ldbm_csn_cb( - Operation *op, - SlapReply *rs ) -{ - op->o_callback = op->o_callback->sc_next; - slap_graduate_commit_csn( op ); - return SLAP_CB_CONTINUE; -} - -int -ldbm_back_add( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - struct berval pdn; - Entry *p = NULL; - ID id = NOID; - AttributeDescription *children = slap_schema.si_ad_children; - AttributeDescription *entry = slap_schema.si_ad_entry; - char textbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof textbuf; - slap_callback cb = { NULL }; - int subentry; - - Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", - op->o_req_dn.bv_val, 0, 0); - - slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); - - cb.sc_cleanup = ldbm_csn_cb; - cb.sc_next = op->o_callback; - op->o_callback = &cb; - - rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL, - get_manageDIT(op), &rs->sr_text, textbuf, textlen ); - - if ( rs->sr_err != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, "entry failed schema check: %s\n", - rs->sr_text, 0, 0 ); - - send_ldap_result( op, rs ); - return rs->sr_err; - } - rs->sr_text = NULL; - - subentry = is_entry_subentry( op->oq_add.rs_e ); - - if ( !access_allowed( op, op->oq_add.rs_e, - entry, NULL, ACL_WADD, NULL ) ) - { - Debug( LDAP_DEBUG_TRACE, "no write access to entry\n", 0, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - "no write access to entry" ); - - return LDAP_INSUFFICIENT_ACCESS; - } - - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - - rs->sr_err = dn2id( op->o_bd, &op->o_req_ndn, &id ); - if ( rs->sr_err || id != NOID ) { - /* if (rs->sr_err) something bad happened to ldbm cache */ - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - rs->sr_err = rs->sr_err ? LDAP_OTHER : LDAP_ALREADY_EXISTS; - send_ldap_result( op, rs ); - return rs->sr_err; - } - - /* - * Get the parent dn and see if the corresponding entry exists. - * If the parent does not exist, only allow the "root" user to - * add the entry. - */ - - if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) { - pdn = slap_empty_bv; - } else { - dnParent( &op->o_req_ndn, &pdn ); - } - - if( pdn.bv_len ) { - Entry *matched = NULL; - - /* get parent with writer lock */ - if ( (p = dn2entry_w( op->o_bd, &pdn, &matched )) == NULL ) { - if ( matched != NULL ) { - rs->sr_matched = ch_strdup( matched->e_dn ); - rs->sr_ref = is_entry_referral( matched ) - ? get_entry_referrals( op, matched ) - : NULL; - cache_return_entry_r( &li->li_cache, matched ); - - } else { - rs->sr_ref = referral_rewrite( default_referral, - NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - } - - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", - 0, 0, 0 ); - - rs->sr_text = rs->sr_ref - ? "parent is referral" : "parent does not exist"; - rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - free( (char *)rs->sr_matched ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return rs->sr_err; - } - - if ( ! access_allowed( op, p, children, NULL, ACL_WADD, NULL ) ) { - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_TRACE, "no write access to parent\n", 0, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - "no write access to parent" ); - - return LDAP_INSUFFICIENT_ACCESS; - } - - if ( is_entry_subentry( p )) { - Debug( LDAP_DEBUG_TRACE, "bdb_add: parent is subentry\n", - 0, 0, 0 ); - rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; - rs->sr_text = "parent is a subentry"; - goto return_results; - } - - if ( is_entry_alias( p ) ) { - /* parent is an alias, don't allow add */ - - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_ALIAS_PROBLEM, - "parent is an alias" ); - - return LDAP_ALIAS_PROBLEM; - } - - if ( is_entry_referral( p ) ) { - /* parent is a referral, don't allow add */ - rs->sr_matched = ch_strdup( p->e_dn ); - rs->sr_ref = is_entry_referral( p ) - ? get_entry_referrals( op, p ) - : NULL; - - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0, - 0, 0 ); - rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - free( (char *)rs->sr_matched ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return rs->sr_err; - } - - if ( subentry ) { - /* FIXME: */ - /* parent must be an administrative point of the required kind */ - } - - } else { - assert( pdn.bv_val == NULL || *pdn.bv_val == '\0' ); - - if (( !be_isroot(op) && !be_shadow_update(op) ) - && !is_entry_glue( op->oq_add.rs_e )) - { - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_TRACE, "%s add denied\n", - pdn.bv_val == NULL ? "suffix" : "entry at root", 0, 0 ); - - send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, NULL ); - return LDAP_NO_SUCH_OBJECT; - } - } - - if ( next_id( op->o_bd, &op->oq_add.rs_e->e_id ) ) { - if( p != NULL) { - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - } - - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_ANY, "ldbm_add: next_id failed\n", - 0, 0, 0 ); - - send_ldap_error( op, rs, LDAP_OTHER, - "next_id add failed" ); - - return LDAP_OTHER; - } - - /* - * Try to add the entry to the cache, assign it a new dnid. - */ - rs->sr_err = cache_add_entry_rw( &li->li_cache, op->oq_add.rs_e, - CACHE_WRITE_LOCK ); - - if ( rs->sr_err != 0 ) { - if( p != NULL) { - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - } - - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0, - 0 ); - - rs->sr_text = rs->sr_err > 0 ? NULL : "cache add failed"; - rs->sr_err = rs->sr_err > 0 ? LDAP_ALREADY_EXISTS : LDAP_OTHER; - send_ldap_result( op, rs ); - - return rs->sr_err; - } - - rs->sr_err = -1; - - /* attribute indexes */ - if ( index_entry_add( op, op->oq_add.rs_e ) != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, "index_entry_add failed\n", 0, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_OTHER, - "index generation failed" ); - - goto return_results; - } - - /* dn2id index */ - if ( dn2id_add( op->o_bd, &op->oq_add.rs_e->e_nname, - op->oq_add.rs_e->e_id ) != 0 ) - { - Debug( LDAP_DEBUG_TRACE, "dn2id_add failed\n", 0, - 0, 0 ); - /* FIXME: delete attr indices? */ - - send_ldap_error( op, rs, LDAP_OTHER, - "DN index generation failed" ); - - goto return_results; - } - - /* id2entry index */ - if ( id2entry_add( op->o_bd, op->oq_add.rs_e ) != 0 ) { - Debug( LDAP_DEBUG_TRACE, "id2entry_add failed\n", 0, - 0, 0 ); - - /* FIXME: delete attr indices? */ - (void) dn2id_delete( op->o_bd, &op->oq_add.rs_e->e_nname, - op->oq_add.rs_e->e_id ); - - send_ldap_error( op, rs, LDAP_OTHER, - "entry store failed" ); - - goto return_results; - } - - rs->sr_err = LDAP_SUCCESS; - rs->sr_text = NULL; - send_ldap_result( op, rs ); - - /* marks the entry as committed, so it is added to the cache; - * otherwise it is removed from the cache, but not destroyed; - * it will be destroyed by the caller */ - cache_entry_commit( op->oq_add.rs_e ); - -return_results:; - if (p != NULL) { - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - } - - if ( rs->sr_err ) { - /* - * in case of error, writer lock is freed - * and entry's private data is destroyed. - * otherwise, this is done when entry is released - */ - cache_return_entry_w( &li->li_cache, op->oq_add.rs_e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - } - - return( rs->sr_err ); -} diff --git a/servers/slapd/back-ldbm/alias.c b/servers/slapd/back-ldbm/alias.c deleted file mode 100644 index d76dca4148..0000000000 --- a/servers/slapd/back-ldbm/alias.c +++ /dev/null @@ -1,240 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include -#include -#include -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - - -static void new_superior( - struct berval *dn, - struct berval *oldSup, - struct berval *newSup, - struct berval *res ); - -static int dnlist_subordinate( - BerVarray dnlist, - struct berval *dn ); - -Entry *deref_internal_r( - Backend* be, - Entry* alias, - struct berval* dn_in, - int* err, - Entry** matched, - const char** text ) -{ - struct berval dn; - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - Entry *entry; - Entry *sup; - unsigned depth; - BerVarray dnlist; - - assert( ( alias != NULL && dn_in == NULL ) - || ( alias == NULL && dn_in != NULL ) ); - - *matched = NULL; - *err = LDAP_NO_SUCH_OBJECT; - *text = NULL; - - if( alias == NULL ) { - ber_dupbv( &dn, dn_in ); - entry = dn2entry_r( be, &dn, &sup ); - - } else { - ber_dupbv( &dn, &alias->e_nname ); - entry = alias; - sup = NULL; - } - - dnlist = NULL; - ber_bvarray_add( &dnlist, &dn ); - - for( depth=0 ; ; depth++ ) { - if( entry != NULL ) { - Entry *newe; - struct berval aliasDN; - - /* have entry, may be an alias */ - - if( !is_entry_alias( entry ) ) { - /* entry is not an alias */ - break; - } - - /* entry is alias */ - if( depth > be->be_max_deref_depth ) { - *matched = entry; - entry = NULL; - *err = LDAP_ALIAS_DEREF_PROBLEM; - *text = "maximum deref depth exceeded"; - break; - } - - /* deref entry */ - if( get_alias_dn( entry, &aliasDN, err, text )) { - *matched = entry; - entry = NULL; - break; - } - - /* check if aliasDN is a subordinate of any DN in our list */ - if( dnlist_subordinate( dnlist, &aliasDN ) ) { - ch_free( aliasDN.bv_val ); - *matched = entry; - entry = NULL; - *err = LDAP_ALIAS_PROBLEM; - *text = "circular alias"; - break; - } - - /* attempt to dereference alias */ - - newe = dn2entry_r( be, &aliasDN, &sup ); - ch_free( aliasDN.bv_val ); - - if( newe != NULL ) { - cache_return_entry_r(&li->li_cache, entry ); - entry = newe; - ber_dupbv( &dn, &entry->e_nname ); - ber_bvarray_add( &dnlist, &dn ); - continue; - } - - if ( sup != NULL ) { - cache_return_entry_r(&li->li_cache, entry ); - entry = NULL; - continue; - } - - /* no newe and no superior, we're done */ - break; - - } else if( sup != NULL ) { - /* have superior, may be an alias */ - Entry *newe; - Entry *newSup; - struct berval supDN; - struct berval aliasDN; - - if( !is_entry_alias( sup ) ) { - /* entry is not an alias */ - *matched = sup; - sup = NULL; - break; - } - - /* entry is alias */ - if( depth > be->be_max_deref_depth ) { - *matched = sup; - entry = NULL; - *err = LDAP_ALIAS_DEREF_PROBLEM; - *text = "maximum deref depth exceeded"; - break; - } - - /* deref entry */ - if( get_alias_dn( sup, &supDN, err, text )) { - *matched = sup; - break; - } - - new_superior( &dn, &sup->e_nname, &supDN, &aliasDN ); - free(supDN.bv_val); - - /* check if aliasDN is a subordinate of any DN in our list */ - if( dnlist_subordinate( dnlist, &aliasDN ) ) { - free(aliasDN.bv_val); - *matched = entry; - entry = NULL; - *err = LDAP_ALIAS_PROBLEM; - *text = "subordinate circular alias"; - break; - } - - /* attempt to dereference alias */ - newe = dn2entry_r( be, &aliasDN, &newSup ); - - if( newe != NULL ) { - free(aliasDN.bv_val); - cache_return_entry_r(&li->li_cache, sup ); - entry = newe; - ber_dupbv( &dn, &entry->e_nname ); - ber_bvarray_add( &dnlist, &dn ); - continue; - } - - if ( newSup != NULL ) { - cache_return_entry_r(&li->li_cache, sup ); - sup = newSup; - ber_dupbv( &dn, &aliasDN ); - continue; - } - - break; - - } else { - /* no newe and no superior, we're done */ - break; - } - } - - ber_bvarray_free( dnlist ); - return entry; -} - - -static void new_superior( - struct berval *dn, - struct berval *oldSup, - struct berval *newSup, - struct berval *newDN ) -{ - size_t dnlen, olen, nlen; - assert( dn && oldSup && newSup && newDN ); - - dnlen = dn->bv_len; - olen = oldSup->bv_len; - nlen = newSup->bv_len; - - newDN->bv_val = ch_malloc( dnlen - olen + nlen + 1 ); - - AC_MEMCPY( newDN->bv_val, dn->bv_val, dnlen - olen ); - AC_MEMCPY( &newDN->bv_val[dnlen - olen], newSup->bv_val, nlen ); - newDN->bv_val[dnlen - olen + nlen] = '\0'; - - return; -} - -static int dnlist_subordinate( - BerVarray dnlist, - struct berval *dn ) -{ - assert( dnlist != NULL ); - - for( ; dnlist->bv_val != NULL; dnlist++ ) { - if( dnIsSuffix( dnlist, dn ) ) { - return 1; - } - } - - return 0; -} diff --git a/servers/slapd/back-ldbm/attr.c b/servers/slapd/back-ldbm/attr.c deleted file mode 100644 index fddbff0b2d..0000000000 --- a/servers/slapd/back-ldbm/attr.c +++ /dev/null @@ -1,231 +0,0 @@ -/* attr.c - backend routines for dealing with attributes */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -/* for the cache of attribute information (which are indexed, etc.) */ -typedef struct ldbm_attrinfo { - AttributeDescription *ai_desc; /* attribute description cn;lang-en */ - slap_mask_t ai_indexmask; /* how the attr is indexed */ -} AttrInfo; - -static int -ainfo_type_cmp( - const void *v_desc, - const void *v_a -) -{ - const AttributeDescription *desc = v_desc; - const AttrInfo *a = v_a; - return SLAP_PTRCMP(desc, a->ai_desc); -} - -static int -ainfo_cmp( - const void *v_a, - const void *v_b -) -{ - const AttrInfo *a = v_a, *b = v_b; - return SLAP_PTRCMP(a->ai_desc, b->ai_desc); -} - -void -attr_mask( - struct ldbminfo *li, - AttributeDescription *desc, - slap_mask_t *indexmask ) -{ - AttrInfo *a; - - a = avl_find( li->li_attrs, desc, ainfo_type_cmp ); - - *indexmask = a != NULL ? a->ai_indexmask : 0; -} - -int -attr_index_config( - struct ldbminfo *li, - const char *fname, - int lineno, - int argc, - char **argv ) -{ - int rc = LDAP_SUCCESS; - int i; - slap_mask_t mask; - char **attrs; - char **indexes = NULL; - - attrs = ldap_str2charray( argv[0], "," ); - - if( attrs == NULL ) { - fprintf( stderr, "%s: line %d: " - "no attributes specified: %s\n", - fname, lineno, argv[0] ); - return LDAP_PARAM_ERROR; - } - - if ( argc > 1 ) { - indexes = ldap_str2charray( argv[1], "," ); - - if( indexes == NULL ) { - fprintf( stderr, "%s: line %d: " - "no indexes specified: %s\n", - fname, lineno, argv[1] ); - rc = LDAP_PARAM_ERROR; - goto fail; - } - } - - if( indexes == NULL ) { - mask = li->li_defaultmask; - - } else { - mask = 0; - - for ( i = 0; indexes[i] != NULL; i++ ) { - slap_mask_t index; - rc = slap_str2index( indexes[i], &index ); - - if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "%s: line %d: " - "index type \"%s\" undefined\n", - fname, lineno, indexes[i] ); - rc = LDAP_PARAM_ERROR; - goto fail; - } - - mask |= index; - } - } - - if( !mask ) { - fprintf( stderr, "%s: line %d: " - "no indexes selected\n", - fname, lineno ); - rc = LDAP_PARAM_ERROR; - goto fail; - } - - for ( i = 0; attrs[i] != NULL; i++ ) { - AttrInfo *a; - AttributeDescription *ad; - const char *text; - - if( strcasecmp( attrs[i], "default" ) == 0 ) { - li->li_defaultmask = mask; - continue; - } - - ad = NULL; - rc = slap_str2ad( attrs[i], &ad, &text ); - - if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "%s: line %d: " - "index attribute \"%s\" undefined\n", - fname, lineno, attrs[i] ); - goto fail; - } - - if( slap_ad_is_binary( ad ) ) { - fprintf( stderr, "%s: line %d: " - "index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - rc = LDAP_UNWILLING_TO_PERFORM; - goto fail; - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( - ad->ad_type->sat_approx - && ad->ad_type->sat_approx->smr_indexer - && ad->ad_type->sat_approx->smr_filter ) ) - { - fprintf( stderr, "%s: line %d: " - "approx index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - rc = LDAP_INAPPROPRIATE_MATCHING; - goto fail; - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( - ad->ad_type->sat_equality - && ad->ad_type->sat_equality->smr_indexer - && ad->ad_type->sat_equality->smr_filter ) ) - { - fprintf( stderr, "%s: line %d: " - "equality index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - rc = LDAP_INAPPROPRIATE_MATCHING; - goto fail; - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( - ad->ad_type->sat_substr - && ad->ad_type->sat_substr->smr_indexer - && ad->ad_type->sat_substr->smr_filter ) ) - { - fprintf( stderr, "%s: line %d: " - "substr index of attribute \"%s\" disallowed\n", - fname, lineno, attrs[i] ); - - rc = LDAP_INAPPROPRIATE_MATCHING; - goto fail; - } - - Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", - ad->ad_cname.bv_val, mask, 0 ); - - a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); - - a->ai_desc = ad; - - a->ai_indexmask = mask; - - rc = avl_insert( &li->li_attrs, (caddr_t) a, - ainfo_cmp, avl_dup_error ); - - if( rc ) { - fprintf( stderr, - "%s: line %d: duplicate index definition for attr \"%s\".\n", - fname, lineno, attrs[i] ); - ch_free( a ); - goto fail; - } - } - - rc = LDAP_SUCCESS; - -fail: - if ( indexes != NULL ) ldap_charray_free( indexes ); - ldap_charray_free( attrs ); - - return rc; -} - -void -attr_index_destroy( Avlnode *tree ) -{ - avl_free( tree, free ); -} diff --git a/servers/slapd/back-ldbm/back-ldbm.h b/servers/slapd/back-ldbm/back-ldbm.h deleted file mode 100644 index a793751392..0000000000 --- a/servers/slapd/back-ldbm/back-ldbm.h +++ /dev/null @@ -1,161 +0,0 @@ -/* back-ldbm.h - ldap ldbm back-end header file */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#ifndef _BACK_LDBM_H_ -#define _BACK_LDBM_H_ - -#include "ldbm.h" -#include "alock.h" - -LDAP_BEGIN_DECL - -#define DEFAULT_CACHE_SIZE 1000 - -#if defined(HAVE_BERKELEY_DB) && DB_VERSION_MAJOR >= 2 -# define DEFAULT_DBCACHE_SIZE (100 * DEFAULT_DB_PAGE_SIZE) -#else -# define DEFAULT_DBCACHE_SIZE 100000 -#endif - -#define DN_BASE_PREFIX SLAP_INDEX_EQUALITY_PREFIX -#define DN_ONE_PREFIX '%' -#define DN_SUBTREE_PREFIX '@' - -/* - * there is a single index for each attribute. these prefixes ensure - * that there is no collision among keys. - */ - -/* allow PREFIX + byte for continuate number */ -#define SLAP_INDEX_CONT_SIZE ( sizeof(SLAP_INDEX_CONT_PREFIX) + sizeof(unsigned char) ) - -#define DEFAULT_BLOCKSIZE 8192 - -/* - * This structure represents an id block on disk and an id list - * in core. - * - * The fields have the following meanings: - * - * b_nmax maximum number of ids in this block. if this is == ALLIDSBLOCK, - * then this block represents all ids. - * b_nids current number of ids in use in this block. if this - * is == INDBLOCK, then this block is an indirect block - * containing a list of other blocks containing actual ids. - * the list is terminated by an id of NOID. - * b_ids a list of the actual ids themselves - */ - -typedef ID ID_BLOCK; - -#define ID_BLOCK_NMAX_OFFSET 0 -#define ID_BLOCK_NIDS_OFFSET 1 -#define ID_BLOCK_IDS_OFFSET 2 - -/* all ID_BLOCK macros operate on a pointer to a ID_BLOCK */ - -#define ID_BLOCK_NMAX(b) ((b)[ID_BLOCK_NMAX_OFFSET]) - -/* Use this macro to get the value, but not to set it. - * By default this is identical to above. - */ -#define ID_BLOCK_NMAXN(b) ID_BLOCK_NMAX(b) -#define ID_BLOCK_NIDS(b) ((b)[ID_BLOCK_NIDS_OFFSET]) -#define ID_BLOCK_ID(b, n) ((b)[ID_BLOCK_IDS_OFFSET+(n)]) - -#define ID_BLOCK_NOID(b, n) (ID_BLOCK_ID((b),(n)) == NOID) - -#define ID_BLOCK_ALLIDS_VALUE 0 -#define ID_BLOCK_ALLIDS(b) (ID_BLOCK_NMAX(b) == ID_BLOCK_ALLIDS_VALUE) - -#define ID_BLOCK_INDIRECT_VALUE 0 -#define ID_BLOCK_INDIRECT(b) (ID_BLOCK_NIDS(b) == ID_BLOCK_INDIRECT_VALUE) - -#define USE_INDIRECT_NIDS 1 - -#ifdef USE_INDIRECT_NIDS -/* - * Use the high bit of ID_BLOCK_NMAX to indicate an INDIRECT block, thus - * freeing up the ID_BLOCK_NIDS to store an actual count. This allows us - * to use binary search on INDIRECT blocks. - */ -#undef ID_BLOCK_NMAXN -#define ID_BLOCK_NMAXN(b) ((b)[ID_BLOCK_NMAX_OFFSET]&0x7fffffff) -#undef ID_BLOCK_INDIRECT_VALUE -#define ID_BLOCK_INDIRECT_VALUE 0x80000000 -#undef ID_BLOCK_INDIRECT -#define ID_BLOCK_INDIRECT(b) (ID_BLOCK_NMAX(b) & ID_BLOCK_INDIRECT_VALUE) - -#endif /* USE_INDIRECT_NIDS */ - -/* for the in-core cache of entries */ -typedef struct ldbm_cache { - int c_maxsize; - int c_cursize; - Avlnode *c_dntree; - Avlnode *c_idtree; - Entry *c_lruhead; /* lru - add accessed entries here */ - Entry *c_lrutail; /* lru - rem lru entries from here */ - ldap_pvt_thread_mutex_t c_mutex; -} Cache; - -#define CACHE_READ_LOCK 0 -#define CACHE_WRITE_LOCK 1 - -/* for the cache of open index files */ -typedef struct ldbm_dbcache { - int dbc_refcnt; - int dbc_maxids; - int dbc_maxindirect; - int dbc_dirty; - int dbc_flags; - time_t dbc_lastref; - long dbc_blksize; - char *dbc_name; - LDBM dbc_db; - ldap_pvt_thread_mutex_t dbc_write_mutex; -} DBCache; - -#define MAXDBCACHE 128 - -struct ldbminfo { - ldap_pvt_thread_rdwr_t li_giant_rwlock; - ID li_nextid; - int li_mode; - slap_mask_t li_defaultmask; - char *li_directory; - Cache li_cache; - Avlnode *li_attrs; - int li_dblocking; /* lock databases */ - int li_dbwritesync; /* write sync */ - int li_dbcachesize; - DBCache li_dbcache[MAXDBCACHE]; - ldap_pvt_thread_mutex_t li_dbcache_mutex; - ldap_pvt_thread_cond_t li_dbcache_cv; - DB_ENV *li_dbenv; - int li_envdirok; - int li_dbsyncfreq; - int li_dbsyncwaitn; - int li_dbsyncwaitinterval; - int li_dbsyncwaitcount; - alock_info_t li_alock_info; -}; - -LDAP_END_DECL - -#include "proto-back-ldbm.h" - -#endif /* _back_ldbm_h_ */ diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c deleted file mode 100644 index 5c523a3cb2..0000000000 --- a/servers/slapd/back-ldbm/bind.c +++ /dev/null @@ -1,195 +0,0 @@ -/* bind.c - ldbm backend bind and unbind routines */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -int -ldbm_back_bind( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - Entry *e; - Attribute *a; - int rc; - Entry *matched; -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND - char krbname[MAX_K_NAME_SZ + 1]; - AttributeDescription *krbattr = slap_schema.si_ad_krbName; - AUTH_DAT ad; -#endif - - AttributeDescription *password = slap_schema.si_ad_userPassword; - - Debug(LDAP_DEBUG_ARGS, - "==> ldbm_back_bind: dn: %s\n", op->o_req_dn.bv_val, 0, 0); - - if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op ) ) { - ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) ); - /* front end will send result */ - return LDAP_SUCCESS; - } - - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); - - /* get entry with reader lock */ - if ( (e = dn2entry_r( op->o_bd, &op->o_req_ndn, &matched )) == NULL ) { - if( matched != NULL ) { - cache_return_entry_r( &li->li_cache, matched ); - } - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - /* allow noauth binds */ - rc = 1; - rs->sr_err = LDAP_INVALID_CREDENTIALS; - send_ldap_result( op, rs ); - return rs->sr_err; - } - - /* 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 ); - rc = LDAP_INVALID_CREDENTIALS; - goto return_results; - } - - if ( is_entry_alias( e ) ) { - /* entry is an alias, don't allow bind */ - Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 ); - -#if 1 - rc = LDAP_INVALID_CREDENTIALS; -#else - rs->sr_text = "entry is alias"; - rc = LDAP_ALIAS_PROBLEM; -#endif - goto return_results; - } - - if ( is_entry_referral( e ) ) { - /* entry is a referral, don't allow bind */ - Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, 0, 0 ); - - rc = LDAP_INVALID_CREDENTIALS; - goto return_results; - } - - switch ( op->oq_bind.rb_method ) { - case LDAP_AUTH_SIMPLE: - if ( (a = attr_find( e->e_attrs, password )) == NULL ) { - /* stop front end from sending result */ - rc = LDAP_INVALID_CREDENTIALS; - goto return_results; - } - - if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred, - &rs->sr_text ) != 0 ) - { - /* failure; stop front end from sending result */ - rc = LDAP_INVALID_CREDENTIALS; - goto return_results; - } - - rc = 0; - break; - -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND - case LDAP_AUTH_KRBV41: - if ( krbv4_ldap_auth( op->o_bd, &op->oq_bind.rb_cred, &ad ) - != LDAP_SUCCESS ) - { - rc = LDAP_INVALID_CREDENTIALS; - goto return_results; - } - - if ( ! access_allowed( op, e, - krbattr, NULL, ACL_AUTH, NULL ) ) - { - rc = LDAP_INSUFFICIENT_ACCESS; - goto return_results; - } - - sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "." - : "", ad.pinst, ad.prealm ); - - if ( (a = attr_find( e->e_attrs, krbattr )) == NULL ) { - /* - * no krbname values present: check against DN - */ - if ( strcasecmp( op->o_req_dn.bv_val, krbname ) == 0 ) { - rc = 0; - break; - } - rc = LDAP_INAPPROPRIATE_AUTH; - goto return_results; - - } else { /* look for krbname match */ - struct berval krbval; - - krbval.bv_val = krbname; - krbval.bv_len = strlen( krbname ); - - if ( value_find( a->a_desc, a->a_vals, &krbval ) != 0 ) { - rc = LDAP_INVALID_CREDENTIALS; - goto return_results; - } - } - rc = 0; - break; -#endif - - default: - assert( 0 ); /* should not be reachable */ - rs->sr_text = "authentication method not supported"; - rc = LDAP_STRONG_AUTH_NOT_SUPPORTED; - goto return_results; - } - - ber_dupbv( &op->oq_bind.rb_edn, &e->e_name ); - -return_results:; - /* free entry and reader lock */ - cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - if ( rc ) { - rs->sr_err = rc; - send_ldap_result( op, rs ); - if ( rs->sr_ref ) { - ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - } - } - - /* front end will send result on success (rc==0) */ - return( rc ); -} - diff --git a/servers/slapd/back-ldbm/cache.c b/servers/slapd/back-ldbm/cache.c deleted file mode 100644 index 0ebd320184..0000000000 --- a/servers/slapd/back-ldbm/cache.c +++ /dev/null @@ -1,675 +0,0 @@ -/* cache.c - routines to maintain an in-core cache of entries */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include -#include - -#include "slap.h" - -#include "back-ldbm.h" - -/* LDBM backend specific entry info -- visible only to the cache */ -typedef struct ldbm_entry_info { - /* - * These items are specific to the LDBM backend and should - * be hidden. Backend cache lock required to access. - */ - int lei_state; /* for the cache */ -#define CACHE_ENTRY_UNDEFINED 0 -#define CACHE_ENTRY_CREATING 1 -#define CACHE_ENTRY_READY 2 -#define CACHE_ENTRY_DELETED 3 -#define CACHE_ENTRY_COMMITTED 4 - - int lei_refcnt; /* # threads ref'ing this entry */ - Entry *lei_lrunext; /* for cache lru list */ - Entry *lei_lruprev; -} EntryInfo; -#undef LEI -#define LEI(e) ((EntryInfo *) ((e)->e_private)) - -static int cache_delete_entry_internal(Cache *cache, Entry *e); -#ifdef LDAP_DEBUG -#ifdef SLAPD_UNUSED -static void lru_print(Cache *cache); -#endif -#endif - -static int -cache_entry_private_init( Entry*e ) -{ - assert( e->e_private == NULL ); - - if( e->e_private != NULL ) { - /* this should never happen */ - return 1; - } - - e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info)); - - return 0; -} - -/* - * marks an entry in CREATING state as committed, so it is really returned - * to the cache. Otherwise an entry in CREATING state is removed. - * Makes e_private be destroyed at the following cache_return_entry_w, - * but lets the entry untouched (owned by someone else) - */ -void -cache_entry_commit( Entry *e ) -{ - assert( e != NULL ); - assert( e->e_private != NULL ); - assert( LEI(e)->lei_state == CACHE_ENTRY_CREATING ); - /* assert( LEI(e)->lei_refcnt == 1 ); */ - - LEI(e)->lei_state = CACHE_ENTRY_COMMITTED; -} - -static int -cache_entry_private_destroy( Entry*e ) -{ - assert( e->e_private != NULL ); - - free( e->e_private ); - e->e_private = NULL; - return 0; -} - -void -cache_return_entry_rw( Cache *cache, Entry *e, int rw ) -{ - ID id; - int refcnt, freeit = 1; - - if ( slapMode != SLAP_SERVER_MODE ) { - return; - } - - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - assert( e->e_private != NULL ); - - id = e->e_id; - refcnt = --LEI(e)->lei_refcnt; - - /* - * if the entry is returned when in CREATING state, it is deleted - * but not freed because it may belong to someone else (do_add, - * for instance) - */ - if ( LEI(e)->lei_state == CACHE_ENTRY_CREATING ) { - cache_delete_entry_internal( cache, e ); - freeit = 0; - /* now the entry is in DELETED state */ - } - - if ( LEI(e)->lei_state == CACHE_ENTRY_COMMITTED ) { - LEI(e)->lei_state = CACHE_ENTRY_READY; - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_TRACE, - "====> cache_return_entry_%s( %ld ): created (%d)\n", - rw ? "w" : "r", id, refcnt ); - - } else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED ) { - if( refcnt > 0 ) { - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_TRACE, - "====> cache_return_entry_%s( %ld ): delete pending (%d)\n", - rw ? "w" : "r", id, refcnt ); - - } else { - cache_entry_private_destroy( e ); - if ( freeit ) { - entry_free( e ); - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_TRACE, - "====> cache_return_entry_%s( %ld ): deleted (%d)\n", - rw ? "w" : "r", id, refcnt ); - } - - } else { - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_TRACE, - "====> cache_return_entry_%s( %ld ): returned (%d)\n", - rw ? "w" : "r", id, refcnt); - } -} - -#define LRU_DELETE( cache, e ) do { \ - if ( LEI(e)->lei_lruprev != NULL ) { \ - LEI(LEI(e)->lei_lruprev)->lei_lrunext = LEI(e)->lei_lrunext; \ - } else { \ - (cache)->c_lruhead = LEI(e)->lei_lrunext; \ - } \ - if ( LEI(e)->lei_lrunext != NULL ) { \ - LEI(LEI(e)->lei_lrunext)->lei_lruprev = LEI(e)->lei_lruprev; \ - } else { \ - (cache)->c_lrutail = LEI(e)->lei_lruprev; \ - } \ -} while(0) - -#define LRU_ADD( cache, e ) do { \ - LEI(e)->lei_lrunext = (cache)->c_lruhead; \ - if ( LEI(e)->lei_lrunext != NULL ) { \ - LEI(LEI(e)->lei_lrunext)->lei_lruprev = (e); \ - } \ - (cache)->c_lruhead = (e); \ - LEI(e)->lei_lruprev = NULL; \ - if ( (cache)->c_lrutail == NULL ) { \ - (cache)->c_lrutail = (e); \ - } \ -} while(0) - -/* - * cache_add_entry_rw - create and lock an entry in the cache - * returns: 0 entry has been created and locked - * 1 entry already existed - * -1 something bad happened - */ -int -cache_add_entry_rw( - Cache *cache, - Entry *e, - int rw -) -{ - int i, rc; - Entry *ee; - - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - assert( e->e_private == NULL ); - - if( cache_entry_private_init(e) != 0 ) { - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_ANY, - "====> cache_add_entry( %ld ): \"%s\": private init failed!\n", - e->e_id, e->e_dn, 0 ); - - return( -1 ); - } - - if ( avl_insert( &cache->c_dntree, (caddr_t) e, - entry_dn_cmp, avl_dup_error ) != 0 ) - { - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_TRACE, - "====> cache_add_entry( %ld ): \"%s\": already in dn cache\n", - e->e_id, e->e_dn, 0 ); - - cache_entry_private_destroy(e); - - return( 1 ); - } - - /* id tree */ - if ( avl_insert( &cache->c_idtree, (caddr_t) e, - entry_id_cmp, avl_dup_error ) != 0 ) - { - Debug( LDAP_DEBUG_ANY, - "====> cache_add_entry( %ld ): \"%s\": already in id cache\n", - e->e_id, e->e_dn, 0 ); - - /* delete from dn tree inserted above */ - if ( avl_delete( &cache->c_dntree, (caddr_t) e, - entry_dn_cmp ) == NULL ) - { - Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n", - 0, 0, 0 ); - } - - cache_entry_private_destroy(e); - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( -1 ); - } - - /* put the entry into 'CREATING' state */ - /* will be marked after when entry is returned */ - LEI(e)->lei_state = CACHE_ENTRY_CREATING; - LEI(e)->lei_refcnt = 1; - - /* lru */ - LRU_ADD( cache, e ); - if ( ++cache->c_cursize > cache->c_maxsize ) { - /* - * find the lru entry not currently in use and delete it. - * in case a lot of entries are in use, only look at the - * first 10 on the tail of the list. - */ - i = 0; - while ( cache->c_lrutail != NULL && - LEI(cache->c_lrutail)->lei_refcnt != 0 && - i < 10 ) - { - /* move this in-use entry to the front of the q */ - ee = cache->c_lrutail; - LRU_DELETE( cache, ee ); - LRU_ADD( cache, ee ); - i++; - } - - /* - * found at least one to delete - try to get back under - * the max cache size. - */ - while ( cache->c_lrutail != NULL && - LEI(cache->c_lrutail)->lei_refcnt == 0 && - cache->c_cursize > cache->c_maxsize ) - { - e = cache->c_lrutail; - - /* delete from cache and lru q */ - /* XXX do we need rc ? */ - rc = cache_delete_entry_internal( cache, e ); - cache_entry_private_destroy( e ); - entry_free( e ); - } - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( 0 ); -} - -/* - * cache_update_entry - update a LOCKED entry which has been deleted. - * returns: 0 entry has been created and locked - * 1 entry already existed - * -1 something bad happened - */ -int -cache_update_entry( - Cache *cache, - Entry *e -) -{ - int i, rc; - Entry *ee; - - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - assert( e->e_private != NULL ); - - if ( avl_insert( &cache->c_dntree, (caddr_t) e, - entry_dn_cmp, avl_dup_error ) != 0 ) - { - Debug( LDAP_DEBUG_TRACE, - "====> cache_update_entry( %ld ): \"%s\": already in dn cache\n", - e->e_id, e->e_dn, 0 ); - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( 1 ); - } - - /* id tree */ - if ( avl_insert( &cache->c_idtree, (caddr_t) e, - entry_id_cmp, avl_dup_error ) != 0 ) - { - Debug( LDAP_DEBUG_ANY, - "====> cache_update_entry( %ld ): \"%s\": already in id cache\n", - e->e_id, e->e_dn, 0 ); - - /* delete from dn tree inserted above */ - if ( avl_delete( &cache->c_dntree, (caddr_t) e, - entry_dn_cmp ) == NULL ) - { - Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n", - 0, 0, 0 ); - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( -1 ); - } - - /* put the entry into 'CREATING' state */ - /* will be marked after when entry is returned */ - LEI(e)->lei_state = CACHE_ENTRY_CREATING; - - /* lru */ - LRU_ADD( cache, e ); - if ( ++cache->c_cursize > cache->c_maxsize ) { - /* - * find the lru entry not currently in use and delete it. - * in case a lot of entries are in use, only look at the - * first 10 on the tail of the list. - */ - i = 0; - while ( cache->c_lrutail != NULL && - LEI(cache->c_lrutail)->lei_refcnt != 0 && - i < 10 ) - { - /* move this in-use entry to the front of the q */ - ee = cache->c_lrutail; - LRU_DELETE( cache, ee ); - LRU_ADD( cache, ee ); - i++; - } - - /* - * found at least one to delete - try to get back under - * the max cache size. - */ - while ( cache->c_lrutail != NULL && - LEI(cache->c_lrutail)->lei_refcnt == 0 && - cache->c_cursize > cache->c_maxsize ) - { - e = cache->c_lrutail; - - /* delete from cache and lru q */ - /* XXX do we need rc ? */ - rc = cache_delete_entry_internal( cache, e ); - cache_entry_private_destroy( e ); - entry_free( e ); - } - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( 0 ); -} - -ID -cache_find_entry_ndn2id( - Backend *be, - Cache *cache, - struct berval *ndn -) -{ - Entry e, *ep; - ID id; - int count = 0; - - /* this function is always called with normalized DN */ - e.e_nname = *ndn; - -try_again: - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e, - entry_dn_cmp )) != NULL ) - { - int state; - count++; - - /* - * ep now points to an unlocked entry - * we do not need to lock the entry if we only - * check the state, refcnt, LRU, and id. - */ - assert( ep->e_private != NULL ); - - /* save id */ - id = ep->e_id; - state = LEI(ep)->lei_state; - - /* - * entry is deleted or not fully created yet - */ - if ( state != CACHE_ENTRY_READY ) { - assert(state != CACHE_ENTRY_UNDEFINED); - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug(LDAP_DEBUG_TRACE, - "====> cache_find_entry_ndn2id(\"%s\"): %ld (not ready) %d\n", - ndn->bv_val, id, state); - - ldap_pvt_thread_yield(); - goto try_again; - } - - /* lru */ - LRU_DELETE( cache, ep ); - LRU_ADD( cache, ep ); - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug(LDAP_DEBUG_TRACE, - "====> cache_find_entry_ndn2id(\"%s\"): %ld (%d tries)\n", - ndn->bv_val, id, count); - - } else { - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - id = NOID; - } - - return( id ); -} - -/* - * cache_find_entry_id - find an entry in the cache, given id - */ - -Entry * -cache_find_entry_id( - Cache *cache, - ID id, - int rw -) -{ - Entry e; - Entry *ep; - int count = 0; - - e.e_id = id; - -try_again: - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e, - entry_id_cmp )) != NULL ) - { - int state; - ID ep_id; - - count++; - - assert( ep->e_private != NULL ); - - ep_id = ep->e_id; - state = LEI(ep)->lei_state; - - /* - * entry is deleted or not fully created yet - */ - if ( state != CACHE_ENTRY_READY ) { - assert(state != CACHE_ENTRY_UNDEFINED); - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug(LDAP_DEBUG_TRACE, - "====> cache_find_entry_id( %ld ): %ld (not ready) %d\n", - id, ep_id, state); - - ldap_pvt_thread_yield(); - goto try_again; - } - - /* lru */ - LRU_DELETE( cache, ep ); - LRU_ADD( cache, ep ); - - LEI(ep)->lei_refcnt++; - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - Debug(LDAP_DEBUG_TRACE, - "====> cache_find_entry_id( %ld ) \"%s\" (found) (%d tries)\n", - ep_id, ep->e_dn, count); - - return( ep ); - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - - return( NULL ); -} - -/* - * cache_delete_entry - delete the entry e from the cache. the caller - * should have obtained e (increasing its ref count) via a call to one - * of the cache_find_* routines. the caller should *not* call the - * cache_return_entry() routine prior to calling cache_delete_entry(). - * it performs this function. - * - * returns: 0 e was deleted ok - * 1 e was not in the cache - * -1 something bad happened - */ -int -cache_delete_entry( - Cache *cache, - Entry *e -) -{ - int rc; - - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - assert( e->e_private != NULL ); - - Debug( LDAP_DEBUG_TRACE, "====> cache_delete_entry( %ld )\n", - e->e_id, 0, 0 ); - - rc = cache_delete_entry_internal( cache, e ); - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); - return( rc ); -} - -static int -cache_delete_entry_internal( - Cache *cache, - Entry *e -) -{ - int rc = 0; /* return code */ - - /* dn tree */ - if ( avl_delete( &cache->c_dntree, (caddr_t) e, entry_dn_cmp ) == NULL ) - { - rc = -1; - } - - /* id tree */ - if ( avl_delete( &cache->c_idtree, (caddr_t) e, entry_id_cmp ) == NULL ) - { - rc = -1; - } - - if (rc != 0) { - return rc; - } - - /* lru */ - LRU_DELETE( cache, e ); - cache->c_cursize--; - - /* - * flag entry to be freed later by a call to cache_return_entry() - */ - LEI(e)->lei_state = CACHE_ENTRY_DELETED; - - return( 0 ); -} - -void -cache_release_all( Cache *cache ) -{ - Entry *e; - int rc; - - /* set cache mutex */ - ldap_pvt_thread_mutex_lock( &cache->c_mutex ); - - Debug( LDAP_DEBUG_TRACE, "====> cache_release_all\n", 0, 0, 0 ); - - - while ( (e = cache->c_lrutail) != NULL && LEI(e)->lei_refcnt == 0 ) { - /* delete from cache and lru q */ - /* XXX do we need rc ? */ - rc = cache_delete_entry_internal( cache, e ); - cache_entry_private_destroy( e ); - entry_free( e ); - } - - if ( cache->c_cursize ) { - Debug( LDAP_DEBUG_TRACE, "Entry-cache could not be emptied\n", 0, 0, 0 ); - } - - /* free cache mutex */ - ldap_pvt_thread_mutex_unlock( &cache->c_mutex ); -} - -#ifdef LDAP_DEBUG -#ifdef SLAPD_UNUSED -static void -lru_print( Cache *cache ) -{ - Entry *e; - - fprintf( stderr, "LRU queue (head to tail):\n" ); - for ( e = cache->c_lruhead; e != NULL; e = LEI(e)->lei_lrunext ) { - fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n", - e->e_dn, e->e_id, LEI(e)->lei_refcnt ); - } - fprintf( stderr, "LRU queue (tail to head):\n" ); - for ( e = cache->c_lrutail; e != NULL; e = LEI(e)->lei_lruprev ) { - fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n", - e->e_dn, e->e_id, LEI(e)->lei_refcnt ); - } -} -#endif -#endif diff --git a/servers/slapd/back-ldbm/close.c b/servers/slapd/back-ldbm/close.c deleted file mode 100644 index 9ed651de3f..0000000000 --- a/servers/slapd/back-ldbm/close.c +++ /dev/null @@ -1,43 +0,0 @@ -/* close.c - close ldbm backend */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include - -#include "slap.h" -#include "back-ldbm.h" - -int -ldbm_back_db_close( Backend *be ) -{ - struct ldbminfo *li = be->be_private; - - Debug( LDAP_DEBUG_TRACE, "ldbm backend syncing\n", 0, 0, 0 ); - - ldbm_cache_flush_all( be ); - Debug( LDAP_DEBUG_TRACE, "ldbm backend done syncing\n", 0, 0, 0 ); - - cache_release_all( &li->li_cache ); - if ( alock_close( &li->li_alock_info )) { - Debug( LDAP_DEBUG_ANY, - "ldbm_back_db_close: alock_close failed\n", 0, 0, 0 ); - } - - return 0; -} diff --git a/servers/slapd/back-ldbm/compare.c b/servers/slapd/back-ldbm/compare.c deleted file mode 100644 index 7100bed6ed..0000000000 --- a/servers/slapd/back-ldbm/compare.c +++ /dev/null @@ -1,133 +0,0 @@ -/* compare.c - ldbm backend compare routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -int -ldbm_back_compare( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - Entry *matched; - Entry *e; - Attribute *a; - int manageDSAit = get_manageDSAit( op ); - - rs->sr_matched = NULL; - rs->sr_ref = NULL; - - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); - - /* get entry with reader lock */ - e = dn2entry_r( op->o_bd, &op->o_req_ndn, &matched ); - if ( e == NULL ) { - if ( matched != NULL ) { - rs->sr_matched = ch_strdup( matched->e_dn ); - rs->sr_ref = is_entry_referral( matched ) - ? get_entry_referrals( op, matched ) - : NULL; - cache_return_entry_r( &li->li_cache, matched ); - } else { - rs->sr_ref = referral_rewrite( default_referral, - NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - } - - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - rs->sr_err = LDAP_REFERRAL; - goto return_results; - } - - if ( !manageDSAit && is_entry_referral( e ) ) { - struct berval bv; - - /* entry is a referral, don't allow add */ - rs->sr_ref = get_entry_referrals( op, e ); - - Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, - 0, 0 ); - - - rs->sr_err = LDAP_REFERRAL; - ber_dupbv_x( &bv, &e->e_name, op->o_tmpmemctx ); - rs->sr_matched = bv.bv_val; - - 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 ) ) - { - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - NULL ); - 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 ( value_find_ex( op->oq_compare.rs_ava->aa_desc, - SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | - SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, - a->a_nvals, &op->oq_compare.rs_ava->aa_value, - op->o_tmpmemctx ) == 0 ) - { - rs->sr_err = LDAP_COMPARE_TRUE; - break; - } - } - -return_results:; - if ( e ) cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - send_ldap_result( op, rs ); - - switch ( rs->sr_err ) { - case LDAP_COMPARE_FALSE: - case LDAP_COMPARE_TRUE: - rs->sr_err = LDAP_SUCCESS; - break; - } - - if ( rs->sr_ref != NULL ) { - ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - } - - if ( rs->sr_matched != NULL ) { - op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx ); - rs->sr_matched = NULL; - } - - return rs->sr_err; -} diff --git a/servers/slapd/back-ldbm/config.c b/servers/slapd/back-ldbm/config.c deleted file mode 100644 index dc8ea7cab5..0000000000 --- a/servers/slapd/back-ldbm/config.c +++ /dev/null @@ -1,186 +0,0 @@ -/* config.c - ldbm backend configuration file routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "lutil.h" - -int -ldbm_back_db_config( - Backend *be, - const char *fname, - int lineno, - int argc, - char **argv -) -{ - int rc; - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - if ( li == NULL ) { - fprintf( stderr, "%s: line %d: ldbm database info is null!\n", - fname, lineno ); - return( 1 ); - } - - /* directory where database files live */ - if ( strcasecmp( argv[0], "directory" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing dir in \"directory \" line\n", - fname, lineno ); - return( 1 ); - } - if ( li->li_directory ) - free( li->li_directory ); - li->li_directory = ch_strdup( argv[1] ); - - /* mode with which to create new database files */ - } else if ( strcasecmp( argv[0], "mode" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing mode in \"mode \" line\n", - fname, lineno ); - return( 1 ); - } - if ( lutil_atoix( &li->li_mode, argv[1], 0 ) != 0 ) { - fprintf( stderr, - "%s: line %d: unable to parse mode=\"%s\" in \"mode \" line\n", - fname, lineno, argv[1] ); - return( 1 ); - } - - /* attribute to index */ - } else if ( strcasecmp( argv[0], "index" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, -"%s: line %d: missing attr in \"index [pres,eq,approx,sub]\" line\n", - fname, lineno ); - return( 1 ); - } else if ( argc > 3 ) { - fprintf( stderr, "%s: line %d: extra junk " - "after \"index [pres,eq,approx,sub]\" line.\n", - fname, lineno ); - return( 1 ); - } - rc = attr_index_config( li, fname, lineno, argc - 1, &argv[1] ); - - if( rc != LDAP_SUCCESS ) return 1; - - /* size of the cache in entries */ - } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing size in \"cachesize \" line\n", - fname, lineno ); - return( 1 ); - } - if ( lutil_atoi( &li->li_cache.c_maxsize, argv[1] ) != 0 ) { - fprintf( stderr, - "%s: line %d: unable to parse cachesize \"%s\"\n", - fname, lineno, argv[1] ); - return( 1 ); - } - - /* size of each dbcache in bytes */ - } else if ( strcasecmp( argv[0], "dbcachesize" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing size in \"dbcachesize \" line\n", - fname, lineno ); - return( 1 ); - } - if ( lutil_atoi( &li->li_dbcachesize, argv[1] ) ) { - fprintf( stderr, - "%s: line %d: unable to parse dbcachesize \"%s\"\n", - fname, lineno, argv[1] ); - return( 1 ); - } - - /* no locking (not safe) */ - } else if ( strcasecmp( argv[0], "dbnolocking" ) == 0 ) { - li->li_dblocking = 0; - - /* no write sync (not safe) */ - } else if ( ( strcasecmp( argv[0], "dbnosync" ) == 0 ) - || ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) ) - { - li->li_dbwritesync = 0; - - /* run sync thread */ - } else if ( strcasecmp( argv[0], "dbsync" ) == 0 ) { -#ifndef NO_THREADS - int i; - if ( argc < 2 ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing frquency value in \"dbsync [ [wait-interval]]\" line\n", - fname, lineno, 0 ); - return 1; - } - - if ( lutil_atoi( &i, argv[1] ) != 0 || i < 0 ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: frquency value (%d) invalid \"dbsync [ [wait-interval]]\" line\n", - fname, lineno, i ); - return 1; - } - - li->li_dbsyncfreq = i; - - if ( argc > 2 ) { - if ( lutil_atoi( &i, argv[2] ) != 0 || i < 0 ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: frquency value (%d) invalid \"dbsync [ [wait-interval]]\" line\n", - fname, lineno, i ); - return 1; - } - li ->li_dbsyncwaitn = i; - } - - if ( argc > 3 ) { - if ( lutil_atoi( &i, argv[3] ) != 0 || i <= 0 ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: frquency value (%d) invalid \"dbsync [ [wait-interval]]\" line\n", - fname, lineno, i ); - return 1; - } - li ->li_dbsyncwaitinterval = i; - } - - /* turn off writesync when sync policy is in place */ - li->li_dbwritesync = 0; - -#else - Debug( LDAP_DEBUG_ANY, - "\"dbsync\" policies not supported in non-threaded environments\n", 0, 0, 0); - return 1; -#endif - - - /* anything else */ - } else { - return SLAP_CONF_UNKNOWN; - } - - return 0; -} diff --git a/servers/slapd/back-ldbm/dbcache.c b/servers/slapd/back-ldbm/dbcache.c deleted file mode 100644 index f812d5cff7..0000000000 --- a/servers/slapd/back-ldbm/dbcache.c +++ /dev/null @@ -1,356 +0,0 @@ -/* ldbmcache.c - maintain a cache of open ldbm files */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include - -DBCache * -ldbm_cache_open( - Backend *be, - const char *name, - const char *suffix, - int flags -) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int i, lru, empty; - time_t oldtime; - char buf[MAXPATHLEN]; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - struct stat st; -#endif - - if (li->li_envdirok) - sprintf( buf, "%s%s", name, suffix ); - else - sprintf( buf, "%s" LDAP_DIRSEP "%s%s", - li->li_directory, name, suffix ); - - if( li->li_dblocking ) { - flags |= LDBM_LOCKING; - } else { - flags |= LDBM_NOLOCKING; - } - - if( li->li_dbwritesync ) { - flags |= LDBM_SYNC; - } else { - flags |= LDBM_NOSYNC; - } - - Debug( LDAP_DEBUG_TRACE, "=> ldbm_cache_open( \"%s\", %d, %o )\n", buf, - flags, li->li_mode ); - - - empty = MAXDBCACHE; - - ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex ); - do { - lru = 0; - oldtime = 1; - for ( i = 0; i < MAXDBCACHE; i++ ) { - /* see if this slot is free */ - if ( li->li_dbcache[i].dbc_name == NULL) { - if (empty == MAXDBCACHE) - empty = i; - continue; - } - - if ( strcmp( li->li_dbcache[i].dbc_name, buf ) == 0 ) { - /* already open - return it */ - if (li->li_dbcache[i].dbc_flags != flags - && li->li_dbcache[i].dbc_refcnt == 0) - { - /* we don't want to use an open cache with different - * permissions (esp. if we need write but the open - * cache is read-only). So close this one if - * possible, and re-open below. - * - * FIXME: what about the case where the refcount - * is > 0? right now, we're using it anyway and - * just praying. Can there be more than one open - * cache to the same db? - * - * Also, it's really only necessary to compare the - * read-only flag, instead of all of the flags, - * but for now I'm checking all of them. - */ - lru = i; - empty = MAXDBCACHE; - break; - } - li->li_dbcache[i].dbc_refcnt++; - Debug( LDAP_DEBUG_TRACE, - "<= ldbm_cache_open (cache %d)\n", i, 0, 0 ); - - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); - return( &li->li_dbcache[i] ); - } - - /* keep track of lru db */ - if (( li->li_dbcache[i].dbc_refcnt == 0 ) && - (( oldtime == 1 ) || - ( li->li_dbcache[i].dbc_lastref < oldtime )) ) - { - lru = i; - oldtime = li->li_dbcache[i].dbc_lastref; - } - } - - i = empty; - if ( i == MAXDBCACHE ) { - /* no empty slots, not already open - close lru and use that slot */ - if ( li->li_dbcache[lru].dbc_refcnt == 0 ) { - i = lru; - ldbm_close( li->li_dbcache[i].dbc_db ); - free( li->li_dbcache[i].dbc_name ); - li->li_dbcache[i].dbc_name = NULL; - } else { - Debug( LDAP_DEBUG_ANY, - "ldbm_cache_open no unused db to close - waiting\n", - 0, 0, 0 ); - - ldap_pvt_thread_cond_wait( &li->li_dbcache_cv, - &li->li_dbcache_mutex ); - /* after waiting for a free slot, go back to square - * one: look for an open cache for this db, or an - * empty slot, or an unref'ed cache, or wait again. - */ - } - } - } while (i == MAXDBCACHE); - - if ( (li->li_dbcache[i].dbc_db = ldbm_open( li->li_dbenv, buf, flags, li->li_mode, - li->li_dbcachesize )) == NULL ) - { - int err = errno; - Debug( LDAP_DEBUG_TRACE, - "<= ldbm_cache_open NULL \"%s\" errno=%d reason=\"%s\")\n", - buf, err, err > -1 && err < sys_nerr ? - sys_errlist[err] : "unknown" ); - - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); - return( NULL ); - } - li->li_dbcache[i].dbc_name = ch_strdup( buf ); - li->li_dbcache[i].dbc_refcnt = 1; - li->li_dbcache[i].dbc_lastref = slap_get_time(); - li->li_dbcache[i].dbc_flags = flags; - li->li_dbcache[i].dbc_dirty = 0; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - if ( stat( buf, &st ) == 0 ) { - li->li_dbcache[i].dbc_blksize = st.st_blksize; - } else -#endif - { - li->li_dbcache[i].dbc_blksize = DEFAULT_BLOCKSIZE; - } - li->li_dbcache[i].dbc_maxids = (li->li_dbcache[i].dbc_blksize / - sizeof(ID)) - ID_BLOCK_IDS_OFFSET; - li->li_dbcache[i].dbc_maxindirect = ( SLAPD_LDBM_MIN_MAXIDS / - li->li_dbcache[i].dbc_maxids ) + 1; - - assert( li->li_dbcache[i].dbc_maxindirect < 256 ); - - Debug( LDAP_DEBUG_ARGS, - "ldbm_cache_open (blksize %ld) (maxids %d) (maxindirect %d)\n", - li->li_dbcache[i].dbc_blksize, li->li_dbcache[i].dbc_maxids, - li->li_dbcache[i].dbc_maxindirect ); - - Debug( LDAP_DEBUG_TRACE, "<= ldbm_cache_open (opened %d)\n", i, 0, 0 ); - - ldap_pvt_thread_mutex_init( &li->li_dbcache[i].dbc_write_mutex ); - - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); - return( &li->li_dbcache[i] ); -} - -void -ldbm_cache_close( Backend *be, DBCache *db ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - if( li->li_dbwritesync && db->dbc_dirty ) { - ldbm_sync( db->dbc_db ); - db->dbc_dirty = 0; - } - - ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex ); - if ( --db->dbc_refcnt <= 0 ) { - db->dbc_refcnt = 0; - ldap_pvt_thread_cond_signal( &li->li_dbcache_cv ); - } - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); -} - -void -ldbm_cache_really_close( Backend *be, DBCache *db ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex ); - if ( --db->dbc_refcnt <= 0 ) { - db->dbc_refcnt = 0; - ldap_pvt_thread_cond_signal( &li->li_dbcache_cv ); - ldbm_close( db->dbc_db ); - free( db->dbc_name ); - db->dbc_name = NULL; - ldap_pvt_thread_mutex_destroy( &db->dbc_write_mutex ); - } - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); -} - -void -ldbm_cache_flush_all( Backend *be ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int i; - - ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex ); - for ( i = 0; i < MAXDBCACHE; i++ ) { - if ( li->li_dbcache[i].dbc_name != NULL ) { - Debug( LDAP_DEBUG_TRACE, "ldbm flushing db (%s)\n", - li->li_dbcache[i].dbc_name, 0, 0 ); - - ldbm_sync( li->li_dbcache[i].dbc_db ); - li->li_dbcache[i].dbc_dirty = 0; - if ( li->li_dbcache[i].dbc_refcnt != 0 ) { - Debug( LDAP_DEBUG_TRACE, - "refcnt = %d, couldn't close db (%s)\n", - li->li_dbcache[i].dbc_refcnt, - li->li_dbcache[i].dbc_name, 0 ); - - } else { - Debug( LDAP_DEBUG_TRACE, - "ldbm closing db (%s)\n", - li->li_dbcache[i].dbc_name, 0, 0 ); - - ldap_pvt_thread_cond_signal( &li->li_dbcache_cv ); - ldbm_close( li->li_dbcache[i].dbc_db ); - free( li->li_dbcache[i].dbc_name ); - li->li_dbcache[i].dbc_name = NULL; - } - } - } - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); -} - -void -ldbm_cache_sync( Backend *be ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int i; - int do_log = 1; - - ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex ); - for ( i = 0; i < MAXDBCACHE; i++ ) { - if ( li->li_dbcache[i].dbc_name != NULL && li->li_dbcache[i].dbc_dirty ) { - if ( do_log ) { - do_log = 0; - Debug( LDAP_DEBUG_TRACE, "syncing %s\n", - li->li_directory, 0, 0 ); - } - Debug( LDAP_DEBUG_TRACE, "ldbm syncing db (%s)\n", - li->li_dbcache[i].dbc_name, 0, 0 ); - ldbm_sync( li->li_dbcache[i].dbc_db ); - li->li_dbcache[i].dbc_dirty = 0; - } - } - ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex ); -} - -#if 0 /* macro in proto-back-ldbm.h */ -Datum -ldbm_cache_fetch( - DBCache *db, - Datum key -) -{ - return ldbm_fetch( db->dbc_db, key ); -} -#endif /* 0 */ - -int -ldbm_cache_store( - DBCache *db, - Datum key, - Datum data, - int flags -) -{ - int rc; - - db->dbc_dirty = 1; - rc = ldbm_store( db->dbc_db, key, data, flags ); - - return( rc ); -} - -int -ldbm_cache_delete( - DBCache *db, - Datum key -) -{ - int rc; - - db->dbc_dirty = 1; - rc = ldbm_delete( db->dbc_db, key ); - - return( rc ); -} - -void * -ldbm_cache_sync_daemon( - void *ctx, - void *arg -) -{ - struct re_s *rtask = arg; - Backend *be = rtask->arg; - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - /* If server is idle, or we've already waited the limit */ - if ( li->li_dbsyncwaitcount == li->li_dbsyncwaitn || - ldap_pvt_thread_pool_backload(&connection_pool) < 2 ) { - rtask->interval.tv_sec = li->li_dbsyncfreq; - li->li_dbsyncwaitcount = 0; - ldbm_cache_sync( be ); - } else { - rtask->interval.tv_sec = li->li_dbsyncwaitinterval; - li->li_dbsyncwaitcount++; - Debug( LDAP_DEBUG_TRACE, "delay #%d syncing %s\n", - li->li_dbsyncwaitcount, li->li_directory, 0 ); - } - - ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); - ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); - ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 ); - ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); - return NULL; -} diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c deleted file mode 100644 index ec623e6253..0000000000 --- a/servers/slapd/back-ldbm/delete.c +++ /dev/null @@ -1,223 +0,0 @@ -/* delete.c - ldbm backend delete routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" -#include "lutil.h" - -int -ldbm_back_delete( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - Entry *matched; - struct berval pdn; - Entry *e, *p = NULL; - int rc = -1; - int manageDSAit = get_manageDSAit( op ); - AttributeDescription *children = slap_schema.si_ad_children; - AttributeDescription *entry = slap_schema.si_ad_entry; - - Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", op->o_req_dn.bv_val, 0, 0); - - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - - /* allocate CSN */ - if ( BER_BVISEMPTY( &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 ); - } - - /* get entry with writer lock */ - e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched ); - - /* FIXME : dn2entry() should return non-glue entry */ - if ( e == NULL || ( !manageDSAit && is_entry_glue( e ))) { - Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: no such object %s\n", - op->o_req_dn.bv_val, 0, 0); - - if ( matched != NULL ) { - rs->sr_matched = ch_strdup( matched->e_dn ); - rs->sr_ref = is_entry_referral( matched ) - ? get_entry_referrals( op, matched ) - : NULL; - cache_return_entry_r( &li->li_cache, matched ); - - } else { - rs->sr_ref = referral_rewrite( default_referral, NULL, - &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - } - - rs->sr_err = LDAP_REFERRAL; - rs->sr_flags |= REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; - goto return_results; - } - - /* check entry for "entry" acl */ - if ( ! access_allowed( op, e, entry, NULL, ACL_WDEL, NULL ) ) - { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_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 ) ) { - /* parent is a referral, don't allow add */ - /* parent is an alias, don't allow add */ - rs->sr_ref = get_entry_referrals( op, e ); - - Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, - 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = ch_strdup( e->e_name.bv_val ); - rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; - goto return_results; - } - - if ( has_children( op->o_bd, e ) ) { - Debug(LDAP_DEBUG_ARGS, "<=- ldbm_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 from parent's id2children entry */ - if( !be_issuffix( op->o_bd, &e->e_nname ) && (dnParent( &e->e_nname, &pdn ), - pdn.bv_len) ) { - if( (p = dn2entry_w( op->o_bd, &pdn, NULL )) == NULL) { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_delete: parent does not exist\n", - 0, 0, 0); - - rs->sr_err = LDAP_OTHER; - rs->sr_text = "could not locate parent of entry"; - goto return_results; - } - - /* check parent for "children" acl */ - if ( ! access_allowed( op, p, - children, NULL, ACL_WDEL, NULL ) ) - { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_delete: no access to parent\n", 0, - 0, 0 ); - - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to parent"; - goto return_results; - } - - } else { - /* no parent, must be root to delete */ - if( ! be_isroot( op ) ) { - if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) - || be_shadow_update( op ) ) { - p = (Entry *)&slap_entry_root; - - rc = access_allowed( op, p, - children, NULL, ACL_WDEL, NULL ); - p = NULL; - - /* check parent for "children" acl */ - if ( ! rc ) { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_delete: no " - "access to parent\n", 0, 0, 0 ); - - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - rs->sr_text = "no write access to parent"; - goto return_results; - } - - } else { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_delete: no parent & " - "not root\n", 0, 0, 0); - - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - goto return_results; - } - } - } - - /* delete from dn2id mapping */ - if ( dn2id_delete( op->o_bd, &e->e_nname, e->e_id ) != 0 ) { - Debug(LDAP_DEBUG_ARGS, - "<=- ldbm_back_delete: operations error %s\n", - op->o_req_dn.bv_val, 0, 0); - - rs->sr_err = LDAP_OTHER; - rs->sr_text = "DN index delete failed"; - goto return_results; - } - - /* delete from disk and cache */ - if ( id2entry_delete( op->o_bd, e ) != 0 ) { - Debug(LDAP_DEBUG_ARGS, - "<=- ldbm_back_delete: operations error %s\n", - op->o_req_dn.bv_val, 0, 0); - - rs->sr_err = LDAP_OTHER; - rs->sr_text = "entry delete failed"; - goto return_results; - } - - /* delete attribute indices */ - (void) index_entry_del( op, e ); - - rs->sr_err = LDAP_SUCCESS; - -return_results:; - rc = rs->sr_err; - - if( p != NULL ) { - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - } - - if ( e != NULL ) { - /* free entry and writer lock */ - cache_return_entry_w( &li->li_cache, e ); - } - - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - send_ldap_result( op, rs ); - slap_graduate_commit_csn( op ); - - return rc; -} diff --git a/servers/slapd/back-ldbm/dn2id.c b/servers/slapd/back-ldbm/dn2id.c deleted file mode 100644 index 93af8de632..0000000000 --- a/servers/slapd/back-ldbm/dn2id.c +++ /dev/null @@ -1,371 +0,0 @@ -/* dn2id.c - routines to deal with the dn2id index */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -int -dn2id_add( - Backend *be, - struct berval *dn, - ID id -) -{ - int rc, flags; - DBCache *db; - Datum key, data; - char *buf; - struct berval ptr, pdn; - - Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn->bv_val, id, 0 ); - - assert( id != NOID ); - - db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ); - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n", - LDBM_SUFFIX, 0, 0 ); - - return( -1 ); - } - - ldbm_datum_init( key ); - key.dsize = dn->bv_len + 2; - buf = ch_malloc( key.dsize ); - key.dptr = buf; - buf[0] = DN_BASE_PREFIX; - ptr.bv_val = buf + 1; - ptr.bv_len = dn->bv_len; - AC_MEMCPY( ptr.bv_val, dn->bv_val, dn->bv_len ); - ptr.bv_val[ dn->bv_len ] = '\0'; - - ldbm_datum_init( data ); - data.dptr = (char *) &id; - data.dsize = sizeof(ID); - - flags = LDBM_INSERT; - rc = ldbm_cache_store( db, key, data, flags ); - - if ( rc != -1 && !be_issuffix( be, &ptr )) { - buf[0] = DN_SUBTREE_PREFIX; - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - rc = idl_insert_key( be, db, key, id ); - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - - if ( rc != -1 ) { - dnParent( &ptr, &pdn ); - - pdn.bv_val[-1] = DN_ONE_PREFIX; - key.dsize = pdn.bv_len + 2; - key.dptr = pdn.bv_val - 1; - ptr = pdn; - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - rc = idl_insert_key( be, db, key, id ); - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - } - } - - while ( rc != -1 && !be_issuffix( be, &ptr )) { - ptr.bv_val[-1] = DN_SUBTREE_PREFIX; - - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - rc = idl_insert_key( be, db, key, id ); - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - - if( rc != 0 ) break; - dnParent( &ptr, &pdn ); - key.dsize = pdn.bv_len + 2; - key.dptr = pdn.bv_val - 1; - ptr = pdn; - } - - free( buf ); - ldbm_cache_close( be, db ); - - Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 ); - - return( rc ); -} - -int -dn2id( - Backend *be, - struct berval *dn, - ID *idp -) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - DBCache *db; - Datum key, data; - unsigned char *tmp; - - Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn->bv_val, 0, 0 ); - - assert( idp != NULL ); - - /* first check the cache */ - *idp = cache_find_entry_ndn2id( be, &li->li_cache, dn ); - if ( *idp != NOID ) { - Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", *idp, - 0, 0 ); - - return( 0 ); - } - - db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ); - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n", - LDBM_SUFFIX, 0, 0 ); - /* - * return code !0 if ldbm cache open failed; - * callers should handle this - */ - *idp = NOID; - return( -1 ); - } - - ldbm_datum_init( key ); - - key.dsize = dn->bv_len + 2; - key.dptr = ch_malloc( key.dsize ); - tmp = (unsigned char *)key.dptr; - tmp[0] = DN_BASE_PREFIX; - tmp++; - AC_MEMCPY( tmp, dn->bv_val, dn->bv_len ); - tmp[dn->bv_len] = '\0'; - - data = ldbm_cache_fetch( db, key ); - - ldbm_cache_close( be, db ); - - free( key.dptr ); - - if ( data.dptr == NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 ); - - *idp = NOID; - return( 0 ); - } - - AC_MEMCPY( (char *) idp, data.dptr, sizeof(ID) ); - - assert( *idp != NOID ); - - ldbm_datum_free( db->dbc_db, data ); - - Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", *idp, 0, 0 ); - - return( 0 ); -} - -int -dn2idl( - Backend *be, - struct berval *dn, - int prefix, - ID_BLOCK **idlp -) -{ - DBCache *db; - Datum key; - unsigned char *tmp; - - Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn->bv_val, 0 ); - - assert( idlp != NULL ); - *idlp = NULL; - - if ( prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn) ) { - *idlp = idl_allids( be ); - return 0; - } - - db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ); - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n", - LDBM_SUFFIX, 0, 0 ); - - return -1; - } - - ldbm_datum_init( key ); - - key.dsize = dn->bv_len + 2; - key.dptr = ch_malloc( key.dsize ); - tmp = (unsigned char *)key.dptr; - tmp[0] = prefix; - tmp++; - AC_MEMCPY( tmp, dn->bv_val, dn->bv_len ); - tmp[dn->bv_len] = '\0'; - - *idlp = idl_fetch( be, db, key ); - - ldbm_cache_close( be, db ); - - free( key.dptr ); - - return( 0 ); -} - - -int -dn2id_delete( - Backend *be, - struct berval *dn, - ID id -) -{ - DBCache *db; - Datum key; - int rc; - char *buf; - struct berval ptr, pdn; - - Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn->bv_val, id, 0 ); - - - assert( id != NOID ); - - db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ); - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX, - 0, 0 ); - - return( -1 ); - } - - ldbm_datum_init( key ); - key.dsize = dn->bv_len + 2; - buf = ch_malloc( key.dsize ); - key.dptr = buf; - buf[0] = DN_BASE_PREFIX; - ptr.bv_val = buf + 1; - ptr.bv_len = dn->bv_len; - AC_MEMCPY( ptr.bv_val, dn->bv_val, dn->bv_len ); - ptr.bv_val[dn->bv_len] = '\0'; - - rc = ldbm_cache_delete( db, key ); - - if( !be_issuffix( be, &ptr )) { - buf[0] = DN_SUBTREE_PREFIX; - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - (void) idl_delete_key( be, db, key, id ); - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - - dnParent( &ptr, &pdn ); - - pdn.bv_val[-1] = DN_ONE_PREFIX; - key.dsize = pdn.bv_len + 2; - key.dptr = pdn.bv_val - 1; - ptr = pdn; - - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - (void) idl_delete_key( be, db, key, id ); - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - } - - while ( rc != -1 && !be_issuffix( be, &ptr )) { - ptr.bv_val[-1] = DN_SUBTREE_PREFIX; - - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - (void) idl_delete_key( be, db, key, id ); - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - - dnParent( &ptr, &pdn ); - key.dsize = pdn.bv_len + 2; - key.dptr = pdn.bv_val - 1; - ptr = pdn; - } - - free( buf ); - - ldbm_cache_close( be, db ); - - Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 ); - - return( rc ); -} - -/* - * dn2entry - look up dn in the cache/indexes and return the corresponding - * entry. - */ - -Entry * -dn2entry_rw( - Backend *be, - struct berval *dn, - Entry **matched, - int rw -) -{ - ID id; - Entry *e = NULL; - struct berval pdn; - - Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n", - rw ? "w" : "r", dn->bv_val, 0); - - - if( matched != NULL ) { - /* caller cares about match */ - *matched = NULL; - } - - if ( dn2id( be, dn, &id ) ) { - /* something bad happened to ldbm cache */ - return( NULL ); - - } - - if ( id != NOID ) { - /* try to return the entry */ - if ((e = id2entry_rw( be, id, rw )) != NULL ) { - return( e ); - } - - Debug(LDAP_DEBUG_ANY, - "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n", - rw ? "w" : "r", id, dn->bv_val); - - /* must have been deleted from underneath us */ - /* treat as if NOID was found */ - } - - /* caller doesn't care about match */ - if( matched == NULL ) return NULL; - - /* entry does not exist - see how much of the dn does exist */ - if ( !be_issuffix( be, dn ) && (dnParent( dn, &pdn ), pdn.bv_len) ) { - /* get entry with reader lock */ - if ((e = dn2entry_r( be, &pdn, matched )) != NULL ) - { - *matched = e; - } - } - - return NULL; -} - diff --git a/servers/slapd/back-ldbm/entry.c b/servers/slapd/back-ldbm/entry.c deleted file mode 100644 index 874d8ccbaa..0000000000 --- a/servers/slapd/back-ldbm/entry.c +++ /dev/null @@ -1,140 +0,0 @@ -/* entry.c - ldbm backend entry_release routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - - -int -ldbm_back_entry_release_rw( - Operation *op, - Entry *e, - int rw -) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - - if ( slapMode == SLAP_SERVER_MODE ) { - /* free entry and reader or writer lock */ - cache_return_entry_rw( &li->li_cache, e, rw ); - /* only do_add calls here with a write lock. - * get_entry doesn't obtain the giant lock, because its - * caller has already obtained it. - */ - if( rw ) { - ldap_pvt_thread_rdwr_wunlock( &li->li_giant_rwlock ); - } -#if 0 - else { - ldap_pvt_thread_rdwr_runlock( &li->li_giant_rwlock ); - } -#endif - - } else { - if ( e->e_private ) { - free( e->e_private ); - e->e_private = NULL; - } - entry_free( e ); - } - - return 0; -} - -/* return LDAP_SUCCESS IFF we can retrieve the specified entry. - */ -int ldbm_back_entry_get( - Operation *op, - struct berval *ndn, - ObjectClass *oc, - AttributeDescription *at, - int rw, - Entry **ent ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - Entry *e; - int rc; - const char *at_name = at ? at->ad_cname.bv_val : "(null)"; - - Debug( LDAP_DEBUG_ARGS, - "=> ldbm_back_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 ); - Debug( LDAP_DEBUG_ARGS, - "=> ldbm_back_entry_get: oc: \"%s\", at: \"%s\"\n", - oc ? oc->soc_cname.bv_val : "(null)", at_name, 0); - - /* don't grab the giant lock - our caller has already gotten it. */ - - /* can we find entry */ - e = dn2entry_rw( op->o_bd, ndn, NULL, rw ); - if (e == NULL) { - Debug( LDAP_DEBUG_ACL, - "=> ldbm_back_entry_get: cannot find entry: \"%s\"\n", - ndn->bv_val, 0, 0 ); - return LDAP_NO_SUCH_OBJECT; - } - - Debug( LDAP_DEBUG_ACL, - "=> ldbm_back_entry_get: found entry: \"%s\"\n", - ndn->bv_val, 0, 0 ); - -#ifdef BDB_ALIASES - /* find attribute values */ - if( is_entry_alias( e ) ) { - Debug( LDAP_DEBUG_ACL, - "<= ldbm_back_entry_get: entry is an alias\n", 0, 0, 0 ); - rc = LDAP_ALIAS_PROBLEM; - goto return_results; - } -#endif - - if( is_entry_referral( e ) ) { - Debug( LDAP_DEBUG_ACL, - "<= ldbm_back_entry_get: entry is a referral\n", 0, 0, 0 ); - rc = LDAP_REFERRAL; - goto return_results; - } - - if ( oc && !is_entry_objectclass( e, oc, 0 )) { - Debug( LDAP_DEBUG_ACL, - "<= ldbm_back_entry_get: failed to find objectClass %s\n", - oc->soc_cname.bv_val, 0, 0 ); - rc = LDAP_NO_SUCH_ATTRIBUTE; - goto return_results; - } - - rc = LDAP_SUCCESS; - -return_results: - if( rc != LDAP_SUCCESS ) { - /* free entry */ - cache_return_entry_rw(&li->li_cache, e, rw); - } else { - *ent = e; - } - - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_entry_get: rc=%d\n", - rc, 0, 0 ); - return(rc); -} diff --git a/servers/slapd/back-ldbm/extended.c b/servers/slapd/back-ldbm/extended.c deleted file mode 100644 index 64a556b0f6..0000000000 --- a/servers/slapd/back-ldbm/extended.c +++ /dev/null @@ -1,52 +0,0 @@ -/* extended.c - ldbm backend extended routines */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" -#include "lber_pvt.h" - -struct exop { - struct berval *oid; - BI_op_extended *extended; -} exop_table[] = { - { NULL, NULL } -}; - -int -ldbm_back_extended( - Operation *op, - SlapReply *rs ) -{ - int i; - - for( i=0; exop_table[i].extended != NULL; i++ ) { - if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) { - return exop_table[i].extended( op, rs ); - } - } - - rs->sr_text = "not supported within naming context"; - return LDAP_UNWILLING_TO_PERFORM; -} - diff --git a/servers/slapd/back-ldbm/filterindex.c b/servers/slapd/back-ldbm/filterindex.c deleted file mode 100644 index 49b4afb175..0000000000 --- a/servers/slapd/back-ldbm/filterindex.c +++ /dev/null @@ -1,684 +0,0 @@ -/* filterindex.c - generate the list of candidate entries from a filter */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -static ID_BLOCK *presence_candidates( - Operation *op, - AttributeDescription *desc ); -static ID_BLOCK *equality_candidates( - Operation *op, AttributeAssertion *ava ); -static ID_BLOCK *approx_candidates( - Operation *op, AttributeAssertion *ava ); -static ID_BLOCK *substring_candidates( - Operation *op, - SubstringsAssertion *sub ); -static ID_BLOCK *list_candidates( - Operation *op, - Filter *flist, - int ftype ); - -ID_BLOCK * -filter_candidates( - Operation *op, - Filter *f -) -{ - char *sub = "SUBTREE"; - ID_BLOCK *result; - - Debug( LDAP_DEBUG_TRACE, "=> filter_candidates\n", 0, 0, 0 ); - - - result = NULL; - switch ( f->f_choice ) { - case SLAPD_FILTER_COMPUTED: - switch( f->f_result ) { - case SLAPD_COMPARE_UNDEFINED: - /* This technically is not the same as FALSE, but it - * certainly will produce no matches. - */ - /* FALLTHRU */ - case LDAP_COMPARE_FALSE: - result = NULL; - break; - case LDAP_COMPARE_TRUE: - result = idl_allids( op->o_bd ); - break; - } - break; - - case SLAPD_FILTER_DN_ONE: - Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 ); - - /* an error is treated as an empty list */ - if ( dn2idl( op->o_bd, f->f_dn, DN_ONE_PREFIX, &result ) != 0 - && result != NULL ) { - idl_free( result ); - result = NULL; - } - break; - -#ifdef SLAPD_FILTER_DN_CHILDREN - case SLAPD_FILTER_DN_CHILDREN: - sub = "CHILDREN"; -#endif - case SLAPD_FILTER_DN_SUBTREE: - Debug( LDAP_DEBUG_FILTER, - "\tDN %s\n", sub, 0, 0 ); - - /* an error is treated as an empty list */ - if ( dn2idl( op->o_bd, f->f_dn, DN_SUBTREE_PREFIX, &result ) != 0 - && result != NULL ) { - idl_free( result ); - result = NULL; - } - break; - - case LDAP_FILTER_PRESENT: - Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 ); - - result = presence_candidates( op, f->f_desc ); - break; - - case LDAP_FILTER_EQUALITY: - Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 ); - - result = equality_candidates( op, f->f_ava ); - break; - - case LDAP_FILTER_APPROX: - Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 ); - - result = approx_candidates( op, f->f_ava ); - break; - - case LDAP_FILTER_SUBSTRINGS: - Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 ); - - result = substring_candidates( op, f->f_sub ); - break; - - case LDAP_FILTER_GE: - Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 ); - - result = presence_candidates( op, f->f_ava->aa_desc ); - break; - - case LDAP_FILTER_LE: - Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 ); - - result = presence_candidates( op, f->f_ava->aa_desc ); - break; - - case LDAP_FILTER_AND: - Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 ); - - result = list_candidates( op, f->f_and, LDAP_FILTER_AND ); - break; - - case LDAP_FILTER_OR: - Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 ); - - result = list_candidates( op, f->f_or, LDAP_FILTER_OR ); - break; - - case LDAP_FILTER_NOT: - Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 ); - - /* - * As candidates lists may contain entries which do - * not match the assertion, negation of the inner candidate - * list could result in matching entries be excluded from - * the returned candidate list. - */ - result = idl_allids( op->o_bd ); - break; - default: - Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN\n", 0, 0, 0 ); - /* unknown filters must not return NULL, to allow - * extended filter processing to be done later. - */ - result = idl_allids( op->o_bd ); - break; - } - - Debug( LDAP_DEBUG_TRACE, "<= filter_candidates %ld\n", - result ? ID_BLOCK_NIDS(result) : 0, 0, 0 ); - - return( result ); -} - -static ID_BLOCK * -presence_candidates( - Operation *op, - AttributeDescription *desc -) -{ - ID_BLOCK *idl; - DBCache *db; - int rc; - char *dbname; - slap_mask_t mask; - struct berval prefix = {0, NULL}; - - Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 ); - - idl = idl_allids( op->o_bd ); - - if( desc == slap_schema.si_ad_objectClass ) { - return idl; - } - - rc = index_param( op->o_bd, desc, LDAP_FILTER_PRESENT, - &dbname, &mask, &prefix ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= presence_candidates: index_param returned=%d\n", - rc, 0, 0 ); - - return idl; - } - - if( dbname == NULL ) { - /* not indexed */ - Debug( LDAP_DEBUG_TRACE, - "<= presense_candidates: not indexed\n", - 0, 0, 0 ); - - return idl; - } - - db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT ); - - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= presense_candidates db open failed (%s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return idl; - } - - if( prefix.bv_val != NULL ) { - idl_free( idl ); - idl = NULL; - - rc = key_read( op->o_bd, db, &prefix, &idl ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= presense_candidates key read failed (%d)\n", - rc, 0, 0 ); - - - } else if( idl == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "<= presense_candidates NULL\n", - 0, 0, 0 ); - - } - } - - ldbm_cache_close( op->o_bd, db ); - - Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - - return( idl ); -} - -static ID_BLOCK * -equality_candidates( - Operation *op, - AttributeAssertion *ava -) -{ - ID_BLOCK *idl; - DBCache *db; - int i; - int rc; - char *dbname; - slap_mask_t mask; - struct berval prefix = {0, NULL}; - struct berval *keys = NULL; - MatchingRule *mr; - - Debug( LDAP_DEBUG_TRACE, "=> equality_candidates\n", 0, 0, 0 ); - - - idl = idl_allids( op->o_bd ); - - rc = index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY, - &dbname, &mask, &prefix ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= equality_candidates: index_param returned=%d\n", - rc, 0, 0 ); - - return idl; - } - - if( dbname == NULL ) { - /* not indexed */ - Debug( LDAP_DEBUG_TRACE, - "<= equality_candidates: not indexed\n", - 0, 0, 0 ); - - return idl; - } - - mr = ava->aa_desc->ad_type->sat_equality; - if( !mr ) { - return idl; - } - - if( !mr->smr_filter ) { - return idl; - } - - rc = (mr->smr_filter)( - LDAP_FILTER_EQUALITY, - mask, - ava->aa_desc->ad_type->sat_syntax, - mr, - &prefix, - &ava->aa_value, - &keys, op->o_tmpmemctx ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= equality_candidates: (%s%s) MR filter failed (%d)\n", - dbname, LDBM_SUFFIX, rc ); - - return idl; - } - - if( keys == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "<= equality_candidates: no keys (%s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return idl; - } - - db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT ); - - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= equality_candidates db open failed (%s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return idl; - } - - for ( i= 0; keys[i].bv_val != NULL; i++ ) { - ID_BLOCK *save; - ID_BLOCK *tmp; - - rc = key_read( op->o_bd, db, &keys[i], &tmp ); - - if( rc != LDAP_SUCCESS ) { - idl_free( idl ); - idl = NULL; - Debug( LDAP_DEBUG_TRACE, - "<= equality_candidates key read failed (%d)\n", - rc, 0, 0 ); - - break; - } - - if( tmp == NULL ) { - idl_free( idl ); - idl = NULL; - Debug( LDAP_DEBUG_TRACE, - "<= equality_candidates NULL\n", - 0, 0, 0 ); - - break; - } - - save = idl; - idl = idl_intersection( op->o_bd, idl, tmp ); - idl_free( save ); - idl_free( tmp ); - - if( idl == NULL ) break; - } - - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - - ldbm_cache_close( op->o_bd, db ); - - - Debug( LDAP_DEBUG_TRACE, "<= equality_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - - return( idl ); -} - -static ID_BLOCK * -approx_candidates( - Operation *op, - AttributeAssertion *ava -) -{ - ID_BLOCK *idl; - DBCache *db; - int i; - int rc; - char *dbname; - slap_mask_t mask; - struct berval prefix = {0, NULL}; - struct berval *keys = NULL; - MatchingRule *mr; - - Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 ); - - - idl = idl_allids( op->o_bd ); - - rc = index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_APPROX, - &dbname, &mask, &prefix ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= approx_candidates: index_param returned=%d\n", - rc, 0, 0 ); - - return idl; - } - - if( dbname == NULL ) { - /* not indexed */ - Debug( LDAP_DEBUG_ANY, - "<= approx_candidates: not indexed\n", - 0, 0, 0 ); - - return idl; - } - - mr = ava->aa_desc->ad_type->sat_approx; - if( !mr ) { - /* no approx matching rule, try equality matching rule */ - mr = ava->aa_desc->ad_type->sat_equality; - } - - if( !mr ) { - return idl; - } - - if( !mr->smr_filter ) { - return idl; - } - - rc = (mr->smr_filter)( - LDAP_FILTER_APPROX, - mask, - ava->aa_desc->ad_type->sat_syntax, - mr, - &prefix, - &ava->aa_value, - &keys, op->o_tmpmemctx ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= approx_candidates: (%s%s) MR filter failed (%d)\n", - dbname, LDBM_SUFFIX, rc ); - - return idl; - } - - if( keys == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "<= approx_candidates: no keys (%s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return idl; - } - - db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT ); - - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= approx_candidates db open failed (%s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return idl; - } - - for ( i= 0; keys[i].bv_val != NULL; i++ ) { - ID_BLOCK *save; - ID_BLOCK *tmp; - - rc = key_read( op->o_bd, db, &keys[i], &tmp ); - - if( rc != LDAP_SUCCESS ) { - idl_free( idl ); - idl = NULL; - Debug( LDAP_DEBUG_TRACE, "<= approx_candidates key read failed (%d)\n", - rc, 0, 0 ); - - break; - } - - if( tmp == NULL ) { - idl_free( idl ); - idl = NULL; - Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n", - 0, 0, 0 ); - - break; - } - - save = idl; - idl = idl_intersection( op->o_bd, idl, tmp ); - idl_free( save ); - idl_free( tmp ); - - if( idl == NULL ) break; - } - - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - - ldbm_cache_close( op->o_bd, db ); - - Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - - return( idl ); -} - -static ID_BLOCK * -list_candidates( - Operation *op, - Filter *flist, - int ftype -) -{ - ID_BLOCK *idl, *tmp, *tmp2; - Filter *f; - - Debug( LDAP_DEBUG_TRACE, "=> list_candidates 0x%x\n", ftype, 0, 0 ); - - - idl = NULL; - for ( f = flist; f != NULL; f = f->f_next ) { - if ( (tmp = filter_candidates( op, f )) == NULL && - ftype == LDAP_FILTER_AND ) { - Debug( LDAP_DEBUG_TRACE, - "<= list_candidates NULL\n", 0, 0, 0 ); - - idl_free( idl ); - return( NULL ); - } - - tmp2 = idl; - if ( idl == NULL ) { - idl = tmp; - } else if ( ftype == LDAP_FILTER_AND ) { - idl = idl_intersection( op->o_bd, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } else { - idl = idl_union( op->o_bd, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } - } - - Debug( LDAP_DEBUG_TRACE, "<= list_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - - return( idl ); -} - -static ID_BLOCK * -substring_candidates( - Operation *op, - SubstringsAssertion *sub -) -{ - ID_BLOCK *idl; - DBCache *db; - int i; - int rc; - char *dbname; - slap_mask_t mask; - struct berval prefix = {0, NULL}; - struct berval *keys = NULL; - MatchingRule *mr; - - Debug( LDAP_DEBUG_TRACE, "=> substrings_candidates\n", 0, 0, 0 ); - - - idl = idl_allids( op->o_bd ); - - rc = index_param( op->o_bd, sub->sa_desc, LDAP_FILTER_SUBSTRINGS, - &dbname, &mask, &prefix ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= substrings_candidates: index_param returned=%d\n", - rc, 0, 0 ); - - return idl; - } - - if( dbname == NULL ) { - /* not indexed */ - Debug( LDAP_DEBUG_ANY, - "<= substrings_candidates: not indexed\n", - 0, 0, 0 ); - - return idl; - } - - mr = sub->sa_desc->ad_type->sat_substr; - - if( !mr ) { - return idl; - } - - if( !mr->smr_filter ) { - return idl; - } - - rc = (mr->smr_filter)( - LDAP_FILTER_SUBSTRINGS, - mask, - sub->sa_desc->ad_type->sat_syntax, - mr, - &prefix, - sub, - &keys, op->o_tmpmemctx ); - - if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= substrings_candidates: (%s%s) MR filter failed (%d)\n", - dbname, LDBM_SUFFIX, rc ); - - return idl; - } - - if( keys == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "<= substrings_candidates: (0x%04lx) no keys (%s%s)\n", - mask, dbname, LDBM_SUFFIX ); - - return idl; - } - - db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT ); - - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= substrings_candidates db open failed (%s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return idl; - } - - for ( i= 0; keys[i].bv_val != NULL; i++ ) { - ID_BLOCK *save; - ID_BLOCK *tmp; - - rc = key_read( op->o_bd, db, &keys[i], &tmp ); - - if( rc != LDAP_SUCCESS ) { - idl_free( idl ); - idl = NULL; - Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates key read failed (%d)\n", - rc, 0, 0 ); - - break; - } - - if( tmp == NULL ) { - idl_free( idl ); - idl = NULL; - Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates NULL\n", - 0, 0, 0 ); - - break; - } - - save = idl; - idl = idl_intersection( op->o_bd, idl, tmp ); - idl_free( save ); - idl_free( tmp ); - - if( idl == NULL ) break; - } - - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - - ldbm_cache_close( op->o_bd, db ); - - Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - - return( idl ); -} diff --git a/servers/slapd/back-ldbm/id2children.c b/servers/slapd/back-ldbm/id2children.c deleted file mode 100644 index c27120aaa1..0000000000 --- a/servers/slapd/back-ldbm/id2children.c +++ /dev/null @@ -1,71 +0,0 @@ -/* id2children.c - routines to deal with the id2children index */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include -#include - -#include - -#include "slap.h" -#include "back-ldbm.h" - -int -has_children( - Backend *be, - Entry *p -) -{ - DBCache *db; - Datum key; - int rc = 0; - ID_BLOCK *idl; - - ldbm_datum_init( key ); - - Debug( LDAP_DEBUG_TRACE, "=> has_children( %ld )\n", p->e_id , 0, 0 ); - - - if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, - LDBM_WRCREAT )) == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= has_children -1 could not open \"dn2id%s\"\n", - LDBM_SUFFIX, 0, 0 ); - - return( 0 ); - } - - key.dsize = strlen( p->e_ndn ) + 2; - key.dptr = ch_malloc( key.dsize ); - sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, p->e_ndn ); - - idl = idl_fetch( be, db, key ); - - free( key.dptr ); - - ldbm_cache_close( be, db ); - - if( idl != NULL ) { - idl_free( idl ); - rc = 1; - } - - Debug( LDAP_DEBUG_TRACE, "<= has_children( %ld ): %s\n", - p->e_id, rc ? "yes" : "no", 0 ); - - return( rc ); -} diff --git a/servers/slapd/back-ldbm/id2entry.c b/servers/slapd/back-ldbm/id2entry.c deleted file mode 100644 index 086355ff9b..0000000000 --- a/servers/slapd/back-ldbm/id2entry.c +++ /dev/null @@ -1,234 +0,0 @@ -/* id2entry.c - routines to deal with the id2entry index */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include - -#include "slap.h" -#include "back-ldbm.h" - -/* - * This routine adds (or updates) an entry on disk. - * The cache should already be updated. - */ - -int -id2entry_add( Backend *be, Entry *e ) -{ - DBCache *db; - Datum key, data; - int len, rc, flags; -#ifndef WORDS_BIGENDIAN - ID id; -#endif - - ldbm_datum_init( key ); - ldbm_datum_init( data ); - - Debug( LDAP_DEBUG_TRACE, "=> id2entry_add( %ld, \"%s\" )\n", e->e_id, - e->e_dn, 0 ); - - - if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) - == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n", - LDBM_SUFFIX, 0, 0 ); - - return( -1 ); - } - -#ifdef WORDS_BIGENDIAN - key.dptr = (char *) &e->e_id; -#else - id = htonl(e->e_id); - key.dptr = (char *) &id; -#endif - key.dsize = sizeof(ID); - - ldap_pvt_thread_mutex_lock( &entry2str_mutex ); - data.dptr = entry2str( e, &len ); - data.dsize = len + 1; - - /* store it */ - flags = LDBM_REPLACE; - rc = ldbm_cache_store( db, key, data, flags ); - - ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); - - ldbm_cache_close( be, db ); - - Debug( LDAP_DEBUG_TRACE, "<= id2entry_add %d\n", rc, 0, 0 ); - - - return( rc ); -} - -int -id2entry_delete( Backend *be, Entry *e ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - DBCache *db; - Datum key; - int rc; -#ifndef WORDS_BIGENDIAN - ID id; -#endif - - Debug(LDAP_DEBUG_TRACE, "=> id2entry_delete( %ld, \"%s\" )\n", e->e_id, - e->e_dn, 0 ); - - -#ifdef notdef -#ifdef LDAP_RDWR_DEBUG - /* check for writer lock */ - assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1); -#endif -#endif - - ldbm_datum_init( key ); - - if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) - == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n", - LDBM_SUFFIX, 0, 0 ); - - return( -1 ); - } - - if ( cache_delete_entry( &li->li_cache, e ) != 0 ) { - Debug(LDAP_DEBUG_ANY, "could not delete %ld (%s) from cache\n", - e->e_id, e->e_dn, 0 ); - - } - -#ifdef WORDS_BIGENDIAN - key.dptr = (char *) &e->e_id; -#else - id = htonl(e->e_id); - key.dptr = (char *) &id; -#endif - key.dsize = sizeof(ID); - - rc = ldbm_cache_delete( db, key ); - - ldbm_cache_close( be, db ); - - Debug( LDAP_DEBUG_TRACE, "<= id2entry_delete %d\n", rc, 0, 0 ); - - return( rc ); -} - -/* returns entry with reader/writer lock */ -Entry * -id2entry_rw( Backend *be, ID id, int rw ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - DBCache *db; - Datum key, data; - Entry *e; -#ifndef WORDS_BIGENDIAN - ID id2; -#endif - - ldbm_datum_init( key ); - ldbm_datum_init( data ); - - Debug( LDAP_DEBUG_TRACE, "=> id2entry_%s( %ld )\n", - rw ? "w" : "r", id, 0 ); - - - if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", - rw ? "w" : "r", id, (unsigned long) e ); - - return( e ); - } - - if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) - == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n", - LDBM_SUFFIX, 0, 0 ); - - return( NULL ); - } - -#ifdef WORDS_BIGENDIAN - key.dptr = (char *) &id; -#else - id2 = htonl(id); - key.dptr = (char *) &id2; -#endif - key.dsize = sizeof(ID); - - data = ldbm_cache_fetch( db, key ); - - if ( data.dptr == NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) not found\n", - rw ? "w" : "r", id, 0 ); - - ldbm_cache_close( be, db ); - return( NULL ); - } - - e = str2entry2( data.dptr, 0 ); - ldbm_datum_free( db->dbc_db, data ); - ldbm_cache_close( be, db ); - - if ( e == NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (failed)\n", - rw ? "w" : "r", id, 0 ); - - return( NULL ); - } - - e->e_id = id; - - if ( slapMode == SLAP_SERVER_MODE - && cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) - { - entry_free( e ); - - /* XXX this is a kludge. - * maybe the entry got added underneath us - * There are many underlying race condtions in the cache/disk code. - */ - if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", - rw ? "w" : "r", id, (unsigned long) e ); - - return( e ); - } - - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (cache add failed)\n", - rw ? "w" : "r", id, 0 ); - - return NULL; - } - - Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (disk)\n", - rw ? "w" : "r", id, (unsigned long) e ); - - if ( slapMode == SLAP_SERVER_MODE ) { - /* marks the entry as committed, so it will get added to the cache - * when the lock is released */ - cache_entry_commit( e ); - } - - return( e ); -} diff --git a/servers/slapd/back-ldbm/idl.c b/servers/slapd/back-ldbm/idl.c deleted file mode 100644 index dec8ef4c9e..0000000000 --- a/servers/slapd/back-ldbm/idl.c +++ /dev/null @@ -1,1263 +0,0 @@ -/* idl.c - ldap id list handling routines */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -static ID_BLOCK* idl_dup( ID_BLOCK *idl ); - -static void cont_alloc( Datum *cont, Datum *key ) -{ - ldbm_datum_init( *cont ); - cont->dsize = 1 + sizeof(ID) + key->dsize; - cont->dptr = ch_malloc( cont->dsize ); - - * (unsigned char *) cont->dptr = SLAP_INDEX_CONT_PREFIX; - - AC_MEMCPY( &((unsigned char *)cont->dptr)[1 + sizeof(ID)], - key->dptr, key->dsize ); -} - -static void cont_id( Datum *cont, ID id ) -{ - unsigned int i; - - for( i=1; i <= sizeof(id); i++) { - ((unsigned char *)cont->dptr)[i] = (unsigned char)(id & 0xFF); - id >>= 8; - } - -} - -static void cont_free( Datum *cont ) -{ - ch_free( cont->dptr ); -} - -#ifdef LDBM_DEBUG_IDL -static void idl_check(ID_BLOCK *idl) -{ - int i, max; - ID_BLOCK last; - - if( ID_BLOCK_ALLIDS(idl) ) - { - return; - } -#ifndef USE_INDIRECT_NIDS - if( ID_BLOCK_INDIRECT(idl) ) - { - for ( max = 0; !ID_BLOCK_NOID(idl, max); max++ ) ; - } else -#endif - { - max = ID_BLOCK_NIDS(idl); - } - if ( max <= 1 ) - { - return; - } - - for( last = ID_BLOCK_ID(idl, 0), i = 1; - i < max; - last = ID_BLOCK_ID(idl, i), i++ ) - { - assert (last < ID_BLOCK_ID(idl, i) ); - } -} -#endif - -/* Allocate an ID_BLOCK with room for nids ids */ -ID_BLOCK * -idl_alloc( unsigned int nids ) -{ - ID_BLOCK *new; - - /* nmax + nids + space for the ids */ - new = (ID_BLOCK *) ch_calloc( (ID_BLOCK_IDS_OFFSET + nids), sizeof(ID) ); - ID_BLOCK_NMAX(new) = nids; - ID_BLOCK_NIDS(new) = 0; - - return( new ); -} - - -/* Allocate an empty ALLIDS ID_BLOCK */ -ID_BLOCK * -idl_allids( Backend *be ) -{ - ID_BLOCK *idl; - ID id; - - idl = idl_alloc( 0 ); - ID_BLOCK_NMAX(idl) = ID_BLOCK_ALLIDS_VALUE; - if ( next_id_get( be, &id ) ) { - idl_free( idl ); - return NULL; - } - ID_BLOCK_NIDS(idl) = id; - - return( idl ); -} - -/* Free an ID_BLOCK */ -void -idl_free( ID_BLOCK *idl ) -{ - if ( idl == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "idl_free: called with NULL pointer\n", - 0, 0, 0 ); - - return; - } - - free( (char *) idl ); -} - - -/* Fetch an single ID_BLOCK from the cache */ -static ID_BLOCK * -idl_fetch_one( - Backend *be, - DBCache *db, - Datum key -) -{ - Datum data; - ID_BLOCK *idl; - - /* Debug( LDAP_DEBUG_TRACE, "=> idl_fetch_one\n", 0, 0, 0 ); */ - - data = ldbm_cache_fetch( db, key ); - - if( data.dptr == NULL ) { - return NULL; - } - - idl = (ID_BLOCK *) data.dptr; - if ( ID_BLOCK_ALLIDS(idl) ) { - /* make sure we have the current value of highest id */ - idl = idl_allids( be ); - } else { - idl = idl_dup((ID_BLOCK *) data.dptr); - } - - ldbm_datum_free( db->dbc_db, data ); - - return idl; -} - - -/* Fetch a set of ID_BLOCKs from the cache - * if not INDIRECT - * if block return is an ALLIDS block, - * return an new ALLIDS block - * otherwise - * return block - * construct super block from all blocks referenced by INDIRECT block - * return super block - */ -ID_BLOCK * -idl_fetch( - Backend *be, - DBCache *db, - Datum key -) -{ - Datum data; - ID_BLOCK *idl; - ID_BLOCK **tmp; - unsigned i, nids, nblocks; - - idl = idl_fetch_one( be, db, key ); - - if ( idl == NULL ) { - return NULL; - } - - if ( ID_BLOCK_ALLIDS(idl) ) { - /* all ids block */ - return( idl ); - } - - if ( ! ID_BLOCK_INDIRECT( idl ) ) { - /* regular block */ - return( idl ); - } - - /* - * this is an indirect block which points to other blocks. - * we need to read in all the blocks it points to and construct - * a big id list containing all the ids, which we will return. - */ - -#ifndef USE_INDIRECT_NIDS - /* count the number of blocks & allocate space for pointers to them */ - for ( nblocks = 0; !ID_BLOCK_NOID(idl, nblocks); nblocks++ ) - ; /* NULL */ -#else - nblocks = ID_BLOCK_NIDS(idl); -#endif - tmp = (ID_BLOCK **) ch_malloc( nblocks * sizeof(ID_BLOCK *) ); - - /* read in all the blocks */ - cont_alloc( &data, &key ); - nids = 0; - for ( i = 0; i < nblocks; i++ ) { - cont_id( &data, ID_BLOCK_ID(idl, i) ); - - if ( (tmp[i] = idl_fetch_one( be, db, data )) == NULL ) { - Debug( LDAP_DEBUG_ANY, - "idl_fetch: one returned NULL\n", 0, 0, 0 ); - - continue; - } - - nids += ID_BLOCK_NIDS(tmp[i]); - } - cont_free( &data ); - idl_free( idl ); - - /* allocate space for the big block */ - idl = idl_alloc( nids ); - ID_BLOCK_NIDS(idl) = nids; - nids = 0; - - /* copy in all the ids from the component blocks */ - for ( i = 0; i < nblocks; i++ ) { - if ( tmp[i] == NULL ) { - continue; - } - - AC_MEMCPY( - (char *) &ID_BLOCK_ID(idl, nids), - (char *) &ID_BLOCK_ID(tmp[i], 0), - ID_BLOCK_NIDS(tmp[i]) * sizeof(ID) ); - nids += ID_BLOCK_NIDS(tmp[i]); - - idl_free( tmp[i] ); - } - free( (char *) tmp ); - - assert( ID_BLOCK_NIDS(idl) == nids ); - -#ifdef LDBM_DEBUG_IDL - idl_check(idl); -#endif - - Debug( LDAP_DEBUG_TRACE, "<= idl_fetch %ld ids (%ld max)\n", - ID_BLOCK_NIDS(idl), ID_BLOCK_NMAXN(idl), 0 ); - - return( idl ); -} - - -/* store a single block */ -static int -idl_store( - Backend *be, - DBCache *db, - Datum key, - ID_BLOCK *idl -) -{ - int rc, flags; - Datum data; - -#ifdef LDBM_DEBUG_IDL - idl_check(idl); -#endif - - ldbm_datum_init( data ); - - /* Debug( LDAP_DEBUG_TRACE, "=> idl_store\n", 0, 0, 0 ); */ - - data.dptr = (char *) idl; - data.dsize = (ID_BLOCK_IDS_OFFSET + ID_BLOCK_NMAXN(idl)) * sizeof(ID); - - flags = LDBM_REPLACE; - rc = ldbm_cache_store( db, key, data, flags ); - - /* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */ - return( rc ); -} - -/* Binary search for id in block, return index - * an index is always returned, even with no match. If no - * match, the returned index is the insertion point. - */ -static unsigned int -idl_find( - ID_BLOCK *b, - ID id -) -{ - int lo=0, hi=ID_BLOCK_NIDS(b)-1, nr=0; - - for (;lo<=hi;) - { - nr = ( lo + hi ) / 2; - if (ID_BLOCK_ID(b, nr) == id) - break; - if (ID_BLOCK_ID(b, nr) > id) - hi = nr - 1; - else - lo = nr + 1; - } - return nr; -} - -/* split the block at id - * locate ID greater than or equal to id. - */ -static void -idl_split_block( - ID_BLOCK *b, - ID id, - ID_BLOCK **right, - ID_BLOCK **left -) -{ - unsigned int nr, nl; - - /* find where to split the block */ - nr = idl_find(b, id); - if ( ID_BLOCK_ID(b,nr) < id ) - nr++; - - nl = ID_BLOCK_NIDS(b) - nr; - - *right = idl_alloc( nr == 0 ? 1 : nr ); - *left = idl_alloc( nl + (nr == 0 ? 0 : 1)); - - /* - * everything before the id being inserted in the first block - * unless there is nothing, in which case the id being inserted - * goes there. - */ - if ( nr == 0 ) { - ID_BLOCK_NIDS(*right) = 1; - ID_BLOCK_ID(*right, 0) = id; - } else { - AC_MEMCPY( - (char *) &ID_BLOCK_ID(*right, 0), - (char *) &ID_BLOCK_ID(b, 0), - nr * sizeof(ID) ); - ID_BLOCK_NIDS(*right) = nr; - ID_BLOCK_ID(*left, 0) = id; - } - - /* the id being inserted & everything after in the second block */ - AC_MEMCPY( - (char *) &ID_BLOCK_ID(*left, (nr == 0 ? 0 : 1)), - (char *) &ID_BLOCK_ID(b, nr), - nl * sizeof(ID) ); - ID_BLOCK_NIDS(*left) = nl + (nr == 0 ? 0 : 1); - -#ifdef LDBM_DEBUG_IDL - idl_check(*right); - idl_check(*left); -#endif -} - - -/* - * idl_change_first - called when an indirect block's first key has - * changed, meaning it needs to be stored under a new key, and the - * header block pointing to it needs updating. - */ -static int -idl_change_first( - Backend *be, - DBCache *db, - Datum hkey, /* header block key */ - ID_BLOCK *h, /* header block */ - int pos, /* pos in h to update */ - Datum bkey, /* data block key */ - ID_BLOCK *b /* data block */ -) -{ - int rc; - - /* Debug( LDAP_DEBUG_TRACE, "=> idl_change_first\n", 0, 0, 0 ); */ - - /* delete old key block */ - if ( (rc = ldbm_cache_delete( db, bkey )) != 0 ) { - Debug( LDAP_DEBUG_ANY, - "idl_change_first: ldbm_cache_delete returned %d\n", - rc, 0, 0 ); - - return( rc ); - } - - /* write block with new key */ - cont_id( &bkey, ID_BLOCK_ID(b, 0) ); - - if ( (rc = idl_store( be, db, bkey, b )) != 0 ) { - Debug( LDAP_DEBUG_ANY, - "idl_change_first: idl_store returned %d\n", rc, 0, 0 ); - - return( rc ); - } - - /* update + write indirect header block */ - ID_BLOCK_ID(h, pos) = ID_BLOCK_ID(b, 0); - if ( (rc = idl_store( be, db, hkey, h )) != 0 ) { - Debug( LDAP_DEBUG_ANY, - "idl_change_first: idl_store returned %d\n", rc, 0, 0 ); - - return( rc ); - } - - return( 0 ); -} - - -int -idl_insert_key( - Backend *be, - DBCache *db, - Datum key, - ID id -) -{ - int i, j, first, rc = 0; - ID_BLOCK *idl, *tmp, *tmp2, *tmp3; - Datum k2; - - if ( (idl = idl_fetch_one( be, db, key )) == NULL ) { - idl = idl_alloc( 1 ); - ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)++) = id; - rc = idl_store( be, db, key, idl ); - - idl_free( idl ); - return( rc ); - } - - if ( ID_BLOCK_ALLIDS( idl ) ) { - /* ALLIDS */ - idl_free( idl ); - return 0; - } - - if ( ! ID_BLOCK_INDIRECT( idl ) ) { - /* regular block */ - switch ( idl_insert( &idl, id, db->dbc_maxids ) ) { - case 0: /* id inserted - store the updated block */ - case 1: - rc = idl_store( be, db, key, idl ); - break; - - case 2: /* id already there - nothing to do */ - rc = 0; - break; - - case 3: /* id not inserted - block must be split */ - /* check threshold for marking this an all-id block */ - if ( db->dbc_maxindirect < 2 ) { - idl_free( idl ); - idl = idl_allids( be ); - rc = idl_store( be, db, key, idl ); - break; - } - - idl_split_block( idl, id, &tmp, &tmp2 ); - idl_free( idl ); - - /* create the header indirect block */ -#ifndef USE_INDIRECT_NIDS - idl = idl_alloc( 3 ); - ID_BLOCK_NMAX(idl) = 3; - ID_BLOCK_NIDS(idl) = ID_BLOCK_INDIRECT_VALUE; - ID_BLOCK_ID(idl, 0) = ID_BLOCK_ID(tmp, 0); - ID_BLOCK_ID(idl, 1) = ID_BLOCK_ID(tmp2, 0); - ID_BLOCK_ID(idl, 2) = NOID; -#else - idl = idl_alloc( 2 ); - ID_BLOCK_NMAX(idl) = 2 | ID_BLOCK_INDIRECT_VALUE; - ID_BLOCK_NIDS(idl) = 2; - ID_BLOCK_ID(idl, 0) = ID_BLOCK_ID(tmp, 0); - ID_BLOCK_ID(idl, 1) = ID_BLOCK_ID(tmp2, 0); -#endif - - /* store it */ - rc = idl_store( be, db, key, idl ); - - cont_alloc( &k2, &key ); - cont_id( &k2, ID_BLOCK_ID(tmp, 0) ); - - rc = idl_store( be, db, k2, tmp ); - - cont_id( &k2, ID_BLOCK_ID(tmp2, 0) ); - rc = idl_store( be, db, k2, tmp2 ); - - cont_free( &k2 ); - - idl_free( tmp ); - idl_free( tmp2 ); - break; - } - - idl_free( idl ); - return( rc ); - } - - /* - * this is an indirect block which points to other blocks. - * we need to read in the block into which the id should be - * inserted, then insert the id and store the block. we might - * have to split the block if it is full, which means we also - * need to write a new "header" block. - */ - -#ifndef USE_INDIRECT_NIDS - /* select the block to try inserting into *//* XXX linear search XXX */ - for ( i = 0; !ID_BLOCK_NOID(idl, i) && id >= ID_BLOCK_ID(idl, i); i++ ) - ; /* NULL */ -#else - i = idl_find(idl, id); - if (ID_BLOCK_ID(idl, i) <= id) - i++; -#endif - if ( i != 0 ) { - i--; - first = 0; - } else { - first = 1; - } - - /* At this point, the following condition must be true: - * ID_BLOCK_ID(idl, i) <= id && id < ID_BLOCK_ID(idl, i+1) - * except when i is the first or the last block. - */ - - /* get the block */ - cont_alloc( &k2, &key ); - cont_id( &k2, ID_BLOCK_ID(idl, i) ); - - if ( (tmp = idl_fetch_one( be, db, k2 )) == NULL ) { - Debug( LDAP_DEBUG_ANY, "idl_insert_key: nonexistent continuation block\n", - 0, 0, 0 ); - - cont_free( &k2 ); - idl_free( idl ); - return( -1 ); - } - - /* insert the id */ - switch ( idl_insert( &tmp, id, db->dbc_maxids ) ) { - case 0: /* id inserted ok */ - if ( (rc = idl_store( be, db, k2, tmp )) != 0 ) { - Debug( LDAP_DEBUG_ANY, - "idl_insert_key: idl_store returned %d\n", rc, 0, 0 ); - - } - break; - - case 1: /* id inserted - first id in block has changed */ - /* - * key for this block has changed, so we have to - * write the block under the new key, delete the - * old key block + update and write the indirect - * header block. - */ - - rc = idl_change_first( be, db, key, idl, i, k2, tmp ); - break; - - case 2: /* id not inserted - already there, do nothing */ - rc = 0; - break; - - case 3: /* id not inserted - block is full */ - /* - * first, see if it will fit in the next block, - * without splitting, unless we're trying to insert - * into the beginning of the first block. - */ - -#ifndef USE_INDIRECT_NIDS - /* is there a next block? */ - if ( !first && !ID_BLOCK_NOID(idl, i + 1) ) { -#else - if ( !first && (unsigned long)(i + 1) < ID_BLOCK_NIDS(idl) ) { -#endif - Datum k3; - /* read it in */ - cont_alloc( &k3, &key ); - cont_id( &k3, ID_BLOCK_ID(idl, i + 1) ); - if ( (tmp2 = idl_fetch_one( be, db, k3 )) == NULL ) { - Debug( LDAP_DEBUG_ANY, - "idl_insert_key: idl_fetch_one returned NULL\n", - 0, 0, 0 ); - - /* split the original block */ - cont_free( &k3 ); - goto split; - } - - /* If the new id is less than the last id in the - * current block, it must not be put into the next - * block. Push the last id of the current block - * into the next block instead. - */ - if (id < ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp) - 1)) { - ID id2 = ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp) - 1); - - --ID_BLOCK_NIDS(tmp); - /* This must succeed since we just popped one - * ID off the end of it. - */ - rc = idl_insert( &tmp, id, db->dbc_maxids ); - - if ( (rc = idl_store( be, db, k2, tmp )) != 0 ) { - Debug( LDAP_DEBUG_ANY, - "idl_insert_key: idl_store returned %d\n", rc, 0, 0 ); - - } - - id = id2; - /* This new id will necessarily be inserted - * as the first id of the next block by the - * following switch() statement. - */ - } - - switch ( (rc = idl_insert( &tmp2, id, - db->dbc_maxids )) ) { - case 1: /* id inserted first in block */ - rc = idl_change_first( be, db, key, idl, - i + 1, k3, tmp2 ); - /* FALL */ - - case 2: /* id already there - how? */ - case 0: /* id inserted: this can never be - * the result of idl_insert, because - * we guaranteed that idl_change_first - * will always be called. - */ - if ( rc == 2 ) { - Debug( LDAP_DEBUG_ANY, - "idl_insert_key: id %ld already in next block\n", - id, 0, 0 ); - - } - - idl_free( tmp ); - idl_free( tmp2 ); - cont_free( &k3 ); - cont_free( &k2 ); - idl_free( idl ); - return( 0 ); - - case 3: /* split the original block */ - break; - } - - idl_free( tmp2 ); - cont_free( &k3 ); - } - -split: - /* - * must split the block, write both new blocks + update - * and write the indirect header block. - */ - - rc = 0; /* optimistic */ - - -#ifndef USE_INDIRECT_NIDS - /* count how many indirect blocks *//* XXX linear count XXX */ - for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ ) - ; /* NULL */ -#else - j = ID_BLOCK_NIDS(idl); -#endif - - /* check it against all-id thresholed */ - if ( j + 1 > db->dbc_maxindirect ) { - /* - * we've passed the all-id threshold, meaning - * that this set of blocks should be replaced - * by a single "all-id" block. our job: delete - * all the indirect blocks, and replace the header - * block by an all-id block. - */ - - /* delete all indirect blocks */ -#ifndef USE_INDIRECT_NIDS - for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ ) { -#else - for ( j = 0; (unsigned long) j < ID_BLOCK_NIDS(idl); j++ ) { -#endif - cont_id( &k2, ID_BLOCK_ID(idl, j) ); - - rc = ldbm_cache_delete( db, k2 ); - } - - /* store allid block in place of header block */ - idl_free( idl ); - idl = idl_allids( be ); - rc = idl_store( be, db, key, idl ); - - cont_free( &k2 ); - idl_free( idl ); - idl_free( tmp ); - return( rc ); - } - - idl_split_block( tmp, id, &tmp2, &tmp3 ); - idl_free( tmp ); - - /* create a new updated indirect header block */ - tmp = idl_alloc( ID_BLOCK_NMAXN(idl) + 1 ); -#ifndef USE_INDIRECT_NIDS - ID_BLOCK_NIDS(tmp) = ID_BLOCK_INDIRECT_VALUE; -#else - ID_BLOCK_NMAX(tmp) |= ID_BLOCK_INDIRECT_VALUE; -#endif - /* everything up to the split block */ - AC_MEMCPY( - (char *) &ID_BLOCK_ID(tmp, 0), - (char *) &ID_BLOCK_ID(idl, 0), - i * sizeof(ID) ); - /* the two new blocks */ - ID_BLOCK_ID(tmp, i) = ID_BLOCK_ID(tmp2, 0); - ID_BLOCK_ID(tmp, i + 1) = ID_BLOCK_ID(tmp3, 0); - /* everything after the split block */ -#ifndef USE_INDIRECT_NIDS - AC_MEMCPY( - (char *) &ID_BLOCK_ID(tmp, i + 2), - (char *) &ID_BLOCK_ID(idl, i + 1), - (ID_BLOCK_NMAXN(idl) - i - 1) * sizeof(ID) ); -#else - AC_MEMCPY( - (char *) &ID_BLOCK_ID(tmp, i + 2), - (char *) &ID_BLOCK_ID(idl, i + 1), - (ID_BLOCK_NIDS(idl) - i - 1) * sizeof(ID) ); - ID_BLOCK_NIDS(tmp) = ID_BLOCK_NIDS(idl) + 1; -#endif - - /* store the header block */ - rc = idl_store( be, db, key, tmp ); - - /* store the first id block */ - cont_id( &k2, ID_BLOCK_ID(tmp2, 0) ); - rc = idl_store( be, db, k2, tmp2 ); - - /* store the second id block */ - cont_id( &k2, ID_BLOCK_ID(tmp3, 0) ); - rc = idl_store( be, db, k2, tmp3 ); - - idl_free( tmp2 ); - idl_free( tmp3 ); - break; - } - - cont_free( &k2 ); - idl_free( tmp ); - idl_free( idl ); - return( rc ); -} - - -/* - * idl_insert - insert an id into an id list. - * - * returns - * 0 id inserted - * 1 id inserted, first id in block has changed - * 2 id not inserted, already there - * 3 id not inserted, block must be split - */ -int -idl_insert( ID_BLOCK **idl, ID id, unsigned int maxids ) -{ - unsigned int i; - - if ( ID_BLOCK_ALLIDS( *idl ) ) { - return( 2 ); /* already there */ - } - - /* is it already there? */ - i = idl_find(*idl, id); - if ( ID_BLOCK_ID(*idl, i) == id ) { - return( 2 ); /* already there */ - } - if ( ID_BLOCK_NIDS(*idl) && ID_BLOCK_ID(*idl, i) < id ) - i++; - - /* do we need to make room for it? */ - if ( ID_BLOCK_NIDS(*idl) == ID_BLOCK_NMAXN(*idl) ) { - /* make room or indicate block needs splitting */ - if ( ID_BLOCK_NMAXN(*idl) >= maxids ) { - return( 3 ); /* block needs splitting */ - } - - ID_BLOCK_NMAX(*idl) *= 2; - if ( ID_BLOCK_NMAXN(*idl) > maxids ) { - ID_BLOCK_NMAX(*idl) = maxids; - } - *idl = (ID_BLOCK *) ch_realloc( (char *) *idl, - (ID_BLOCK_NMAXN(*idl) + ID_BLOCK_IDS_OFFSET) * sizeof(ID) ); - } - - /* make a slot for the new id */ - AC_MEMCPY( &ID_BLOCK_ID(*idl, i+1), &ID_BLOCK_ID(*idl, i), - (ID_BLOCK_NIDS(*idl) - i) * sizeof(ID) ); - - ID_BLOCK_ID(*idl, i) = id; - ID_BLOCK_NIDS(*idl)++; - (void) memset( - (char *) &ID_BLOCK_ID((*idl), ID_BLOCK_NIDS(*idl)), - '\0', - (ID_BLOCK_NMAXN(*idl) - ID_BLOCK_NIDS(*idl)) * sizeof(ID) ); - -#ifdef LDBM_DEBUG_IDL - idl_check(*idl); -#endif - - return( i == 0 ? 1 : 0 ); /* inserted - first id changed or not */ -} - - -int -idl_delete_key ( - Backend *be, - DBCache *db, - Datum key, - ID id -) -{ - Datum data; - ID_BLOCK *idl; - unsigned i; - int j, nids; - - if ( (idl = idl_fetch_one( be, db, key ) ) == NULL ) - { - /* It wasn't found. Hmm... */ - return -1; - } - - if ( ID_BLOCK_ALLIDS( idl ) ) { - idl_free( idl ); - return 0; - } - - if ( ! ID_BLOCK_INDIRECT( idl ) ) { - i = idl_find(idl, id); - if ( ID_BLOCK_ID(idl, i) == id ) { - if( --ID_BLOCK_NIDS(idl) == 0 ) { - ldbm_cache_delete( db, key ); - - } else { - AC_MEMCPY( - &ID_BLOCK_ID(idl, i), - &ID_BLOCK_ID(idl, i+1), - (ID_BLOCK_NIDS(idl)-i) * sizeof(ID) ); - - ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)) = NOID; - - idl_store( be, db, key, idl ); - } - - idl_free( idl ); - return 0; - } - /* We didn't find the ID. Hmmm... */ - idl_free( idl ); - return -1; - } - - /* We have to go through an indirect block and find the ID - in the list of IDL's - */ - cont_alloc( &data, &key ); -#ifndef USE_INDIRECT_NIDS - for ( nids = 0; !ID_BLOCK_NOID(idl, nids); nids++ ) { - ; /* Empty */ - } - - for ( j = 0; j id ) j--; - for (; j>=0; j = -1 ) /* execute once */ -#endif - { - ID_BLOCK *tmp; - cont_id( &data, ID_BLOCK_ID(idl, j) ); - - if ( (tmp = idl_fetch_one( be, db, data )) == NULL ) { - Debug( LDAP_DEBUG_ANY, - "idl_delete_key: idl_fetch of returned NULL\n", 0, 0, 0 ); - - continue; - } - /* - Now try to find the ID in tmp - */ - - i = idl_find(tmp, id); - if ( ID_BLOCK_ID(tmp, i) == id ) - { - AC_MEMCPY( - &ID_BLOCK_ID(tmp, i), - &ID_BLOCK_ID(tmp, i+1), - (ID_BLOCK_NIDS(tmp)-(i+1)) * sizeof(ID)); - ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp)-1 ) = NOID; - ID_BLOCK_NIDS(tmp)--; - - if ( ID_BLOCK_NIDS(tmp) ) { - idl_store ( be, db, data, tmp ); - - } else { - ldbm_cache_delete( db, data ); - AC_MEMCPY( - &ID_BLOCK_ID(idl, j), - &ID_BLOCK_ID(idl, j+1), - (nids-(j+1)) * sizeof(ID)); - ID_BLOCK_ID(idl, nids-1) = NOID; - nids--; -#ifdef USE_INDIRECT_NIDS - ID_BLOCK_NIDS(idl)--; -#endif - if ( ! nids ) - ldbm_cache_delete( db, key ); - else - idl_store( be, db, key, idl ); - } - idl_free( tmp ); - cont_free( &data ); - idl_free( idl ); - return 0; - } - idl_free( tmp ); - } - - cont_free( &data ); - idl_free( idl ); - return -1; -} - - -/* return a duplicate of a single ID_BLOCK */ -static ID_BLOCK * -idl_dup( ID_BLOCK *idl ) -{ - ID_BLOCK *new; - - if ( idl == NULL ) { - return( NULL ); - } - - new = idl_alloc( ID_BLOCK_NMAXN(idl) ); - - AC_MEMCPY( - (char *) new, - (char *) idl, - (ID_BLOCK_NMAXN(idl) + ID_BLOCK_IDS_OFFSET) * sizeof(ID) ); - -#ifdef LDBM_DEBUG_IDL - idl_check(new); -#endif - - return( new ); -} - - -/* return the smaller ID_BLOCK */ -static ID_BLOCK * -idl_min( ID_BLOCK *a, ID_BLOCK *b ) -{ - return( ID_BLOCK_NIDS(a) > ID_BLOCK_NIDS(b) ? b : a ); -} - - -/* - * idl_intersection - return a intersection b - */ -ID_BLOCK * -idl_intersection( - Backend *be, - ID_BLOCK *a, - ID_BLOCK *b -) -{ - unsigned int ai, bi, ni; - ID_BLOCK *n; - - if ( a == NULL || b == NULL ) { - return( NULL ); - } - if ( ID_BLOCK_ALLIDS( a ) ) { - return( idl_dup( b ) ); - } - if ( ID_BLOCK_ALLIDS( b ) ) { - return( idl_dup( a ) ); - } - if ( ID_BLOCK_NIDS(a) == 0 || ID_BLOCK_NIDS(b) == 0 ) { - return( NULL ); - } - - n = idl_dup( idl_min( a, b ) ); - -#ifdef LDBM_DEBUG_IDL - idl_check(a); - idl_check(b); -#endif - - for ( ni = 0, ai = 0, bi = 0; ; ) { - if ( ID_BLOCK_ID(b, bi) == ID_BLOCK_ID(a, ai) ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai); - ai++; - bi++; - if ( ai >= ID_BLOCK_NIDS(a) || bi >= ID_BLOCK_NIDS(b) ) - break; - } else if ( ID_BLOCK_ID(a, ai) < ID_BLOCK_ID(b, bi) ) { - ai++; - if ( ai >= ID_BLOCK_NIDS(a) ) - break; - } else { - bi++; - if ( bi >= ID_BLOCK_NIDS(b) ) - break; - } - } - - if ( ni == 0 ) { - idl_free( n ); - return( NULL ); - } - ID_BLOCK_NIDS(n) = ni; - -#ifdef LDBM_DEBUG_IDL - idl_check(n); -#endif - - return( n ); -} - - -/* - * idl_union - return a union b - */ -ID_BLOCK * -idl_union( - Backend *be, - ID_BLOCK *a, - ID_BLOCK *b -) -{ - unsigned int ai, bi, ni; - ID_BLOCK *n; - - if ( a == NULL ) { - return( idl_dup( b ) ); - } - if ( b == NULL ) { - return( idl_dup( a ) ); - } - if ( ID_BLOCK_ALLIDS( a ) || ID_BLOCK_ALLIDS( b ) ) { - return( idl_allids( be ) ); - } - -#ifdef LDBM_DEBUG_IDL - idl_check(a); - idl_check(b); -#endif - - if ( ID_BLOCK_NIDS(b) < ID_BLOCK_NIDS(a) ) { - n = a; - a = b; - b = n; - } - - n = idl_alloc( ID_BLOCK_NIDS(a) + ID_BLOCK_NIDS(b) ); - - for ( ni = 0, ai = 0, bi = 0; - ai < ID_BLOCK_NIDS(a) && bi < ID_BLOCK_NIDS(b); - ) - { - if ( ID_BLOCK_ID(a, ai) < ID_BLOCK_ID(b, bi) ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai++); - - } else if ( ID_BLOCK_ID(b, bi) < ID_BLOCK_ID(a, ai) ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(b, bi++); - - } else { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai); - ai++, bi++; - } - } - - for ( ; ai < ID_BLOCK_NIDS(a); ai++ ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai); - } - for ( ; bi < ID_BLOCK_NIDS(b); bi++ ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(b, bi); - } - ID_BLOCK_NIDS(n) = ni; - -#ifdef LDBM_DEBUG_IDL - idl_check(n); -#endif - - return( n ); -} - - -/* - * idl_notin - return a intersection ~b (or a minus b) - */ -ID_BLOCK * -idl_notin( - Backend *be, - ID_BLOCK *a, - ID_BLOCK *b -) -{ - unsigned int ni, ai, bi; - ID_BLOCK *n; - - if ( a == NULL ) { - return( NULL ); - } - if ( b == NULL || ID_BLOCK_ALLIDS( b )) { - return( idl_dup( a ) ); - } - - if ( ID_BLOCK_ALLIDS( a ) ) { - n = idl_alloc( SLAPD_LDBM_MIN_MAXIDS ); - ni = 0; - - for ( ai = 1, bi = 0; - ai < ID_BLOCK_NIDS(a) && ni < ID_BLOCK_NMAXN(n) && bi < ID_BLOCK_NMAXN(b); - ai++ ) - { - if ( ID_BLOCK_ID(b, bi) == ai ) { - bi++; - } else { - ID_BLOCK_ID(n, ni++) = ai; - } - } - - for ( ; ai < ID_BLOCK_NIDS(a) && ni < ID_BLOCK_NMAXN(n); ai++ ) { - ID_BLOCK_ID(n, ni++) = ai; - } - - if ( ni == ID_BLOCK_NMAXN(n) ) { - idl_free( n ); - return( idl_allids( be ) ); - } else { - ID_BLOCK_NIDS(n) = ni; - return( n ); - } - } - - n = idl_dup( a ); - - ni = 0; - for ( ai = 0, bi = 0; ai < ID_BLOCK_NIDS(a); ai++ ) { - for ( ; - bi < ID_BLOCK_NIDS(b) && ID_BLOCK_ID(b, bi) < ID_BLOCK_ID(a, ai); - bi++ ) - { - ; /* NULL */ - } - - if ( bi == ID_BLOCK_NIDS(b) ) { - break; - } - - if ( ID_BLOCK_ID(b, bi) != ID_BLOCK_ID(a, ai) ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai); - } - } - - for ( ; ai < ID_BLOCK_NIDS(a); ai++ ) { - ID_BLOCK_ID(n, ni++) = ID_BLOCK_ID(a, ai); - } - ID_BLOCK_NIDS(n) = ni; - -#ifdef LDBM_DEBUG_IDL - idl_check(n); -#endif - - return( n ); -} - -/* return the first ID in the block - * if ALLIDS block - * NIDS > 1 return 1 - * otherwise return NOID - * otherwise return first ID - * - * cursor is set to 1 - */ -ID -idl_firstid( ID_BLOCK *idl, ID *cursor ) -{ - *cursor = 1; - - if ( idl == NULL || ID_BLOCK_NIDS(idl) == 0 ) { - return( NOID ); - } - - if ( ID_BLOCK_ALLIDS( idl ) ) { - return( ID_BLOCK_NIDS(idl) > 1 ? 1 : NOID ); - } - - return( ID_BLOCK_ID(idl, 0) ); -} - -/* return next ID - * if ALLIDS block, cursor is id. - * increment id - * if id < NIDS return id - * otherwise NOID. - * otherwise cursor is index into block - * if index < nids - * return id at index then increment - */ -ID -idl_nextid( ID_BLOCK *idl, ID *cursor ) -{ - if ( ID_BLOCK_ALLIDS( idl ) ) { - if( ++(*cursor) < ID_BLOCK_NIDS(idl) ) { - return *cursor; - } else { - return NOID; - } - } - - if ( *cursor < ID_BLOCK_NIDS(idl) ) { - return( ID_BLOCK_ID(idl, (*cursor)++) ); - } - - return( NOID ); -} diff --git a/servers/slapd/back-ldbm/index.c b/servers/slapd/back-ldbm/index.c deleted file mode 100644 index 70622a89cc..0000000000 --- a/servers/slapd/back-ldbm/index.c +++ /dev/null @@ -1,327 +0,0 @@ -/* index.c - routines for dealing with attribute indexes */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -static slap_mask_t index_mask( - Backend *be, - AttributeDescription *desc, - char **dbname, - struct berval *atname ) -{ - AttributeType *at; - slap_mask_t mask = 0; - - attr_mask( be->be_private, desc, &mask ); - - if( mask ) { - *atname = desc->ad_cname; - *dbname = desc->ad_cname.bv_val; - return mask; - } - - /* If there is a tagging option, did we ever index the base - * type? If so, check for mask, otherwise it's not there. - */ - if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) { - /* has tagging option */ - attr_mask( be->be_private, desc->ad_type->sat_ad, &mask ); - - if( mask && ( mask ^ SLAP_INDEX_NOTAGS ) ) { - *atname = desc->ad_type->sat_cname; - *dbname = desc->ad_type->sat_cname.bv_val; - return mask; - } - } - - /* see if supertype defined mask for its subtypes */ - for( at = desc->ad_type->sat_sup; at != NULL ; at = at->sat_sup ) { - /* If no AD, we've never indexed this type */ - if (!at->sat_ad) - continue; - - attr_mask( be->be_private, at->sat_ad, &mask ); - - if( mask && ( mask ^ SLAP_INDEX_NOSUBTYPES ) ) { - *atname = at->sat_cname; - *dbname = at->sat_cname.bv_val; - return mask; - } - } - - return 0; -} - -int index_is_indexed( - Backend *be, - AttributeDescription *desc ) -{ - slap_mask_t mask; - char *dbname; - struct berval prefix; - - mask = index_mask( be, desc, &dbname, &prefix ); - - if( mask == 0 ) { - return LDAP_INAPPROPRIATE_MATCHING; - } - - return LDAP_SUCCESS; -} - -int index_param( - Backend *be, - AttributeDescription *desc, - int ftype, - char **dbnamep, - slap_mask_t *maskp, - struct berval *prefixp ) -{ - slap_mask_t mask; - char *dbname; - - mask = index_mask( be, desc, &dbname, prefixp ); - - if( mask == 0 ) { - return LDAP_INAPPROPRIATE_MATCHING; - } - - switch( ftype ) { - case LDAP_FILTER_PRESENT: - if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { - goto done; - } - break; - - case LDAP_FILTER_APPROX: - if ( desc->ad_type->sat_approx ) { - if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { - goto done; - } - break; - } - - /* Use EQUALITY rule and index for approximate match */ - /* fall thru */ - - case LDAP_FILTER_EQUALITY: - if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { - goto done; - } - break; - - case LDAP_FILTER_SUBSTRINGS: - if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { - goto done; - } - break; - - default: - return LDAP_OTHER; - } - - return LDAP_INAPPROPRIATE_MATCHING; - -done: - *dbnamep = dbname; - *maskp = mask; - return LDAP_SUCCESS; -} - -static int indexer( - Operation *op, - char *dbname, - struct berval *atname, - BerVarray vals, - ID id, - int opid, - slap_mask_t mask ) -{ - int rc, i; - const char *text; - DBCache *db; - AttributeDescription *ad = NULL; - struct berval *keys; - - assert( mask != 0 ); - - rc = slap_bv2ad( atname, &ad, &text ); - - if( rc != LDAP_SUCCESS ) return rc; - - db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT ); - - if ( db == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= index_read NULL (could not open %s%s)\n", - dbname, LDBM_SUFFIX, 0 ); - - return LDAP_OTHER; - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { - key_change( op->o_bd, db, atname, id, opid ); - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { - rc = ad->ad_type->sat_equality->smr_indexer( - LDAP_FILTER_EQUALITY, - mask, - ad->ad_type->sat_syntax, - ad->ad_type->sat_equality, - atname, vals, &keys, op->o_tmpmemctx ); - - if( rc == LDAP_SUCCESS && keys != NULL ) { - for( i=0; keys[i].bv_val != NULL; i++ ) { - key_change( op->o_bd, db, &keys[i], id, opid ); - } - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - } - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { - rc = ad->ad_type->sat_approx->smr_indexer( - LDAP_FILTER_APPROX, - mask, - ad->ad_type->sat_syntax, - ad->ad_type->sat_approx, - atname, vals, &keys, op->o_tmpmemctx ); - - if( rc == LDAP_SUCCESS && keys != NULL ) { - for( i=0; keys[i].bv_val != NULL; i++ ) { - key_change( op->o_bd, db, &keys[i], id, opid ); - } - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - } - } - - if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { - rc = ad->ad_type->sat_substr->smr_indexer( - LDAP_FILTER_SUBSTRINGS, - mask, - ad->ad_type->sat_syntax, - ad->ad_type->sat_substr, - atname, vals, &keys, op->o_tmpmemctx ); - - if( rc == LDAP_SUCCESS && keys != NULL ) { - for( i=0; keys[i].bv_val != NULL; i++ ) { - key_change( op->o_bd, db, &keys[i], id, opid ); - } - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - } - } - - ldbm_cache_close( op->o_bd, db ); - - return LDAP_SUCCESS; -} - -static int index_at_values( - Operation *op, - AttributeType *type, - struct berval *tags, - BerVarray vals, - ID id, - int opid ) -{ - slap_mask_t mask = 0; - - if( type->sat_sup ) { - /* recurse */ - (void) index_at_values( op, - type->sat_sup, tags, - vals, id, opid ); - } - - /* If this type has no AD, we've never used it before */ - if( type->sat_ad ) { - attr_mask( op->o_bd->be_private, type->sat_ad, &mask ); - } - - if( mask ) { - indexer( op, type->sat_cname.bv_val, - &type->sat_cname, - vals, id, opid, - mask ); - } - - if( tags->bv_len ) { - AttributeDescription *desc; - - mask = 0; - - desc = ad_find_tags(type, tags); - if( desc ) { - attr_mask( op->o_bd->be_private, desc, &mask ); - } - - if( mask ) { - indexer( op, desc->ad_cname.bv_val, &desc->ad_cname, - vals, id, opid, - mask ); - } - } - - return LDAP_SUCCESS; -} - -int index_values( - Operation *op, - AttributeDescription *desc, - BerVarray vals, - ID id, - int opid ) -{ - (void) index_at_values( op, - desc->ad_type, &desc->ad_tags, - vals, id, opid ); - - return LDAP_SUCCESS; -} - -int -index_entry( - Operation *op, - int opid, - Entry *e ) -{ - Attribute *ap = e->e_attrs; - Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n", - opid == SLAP_INDEX_ADD_OP ? "add" : "del", - e->e_id, e->e_dn ); - - /* add each attribute to the indexes */ - for ( ; ap != NULL; ap = ap->a_next ) { - index_values( op, ap->a_desc, - ap->a_nvals, - e->e_id, opid ); - } - - Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n", - opid == SLAP_INDEX_ADD_OP ? "add" : "del", - e->e_id, e->e_dn ); - - return LDAP_SUCCESS; -} - diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c deleted file mode 100644 index 953df87be9..0000000000 --- a/servers/slapd/back-ldbm/init.c +++ /dev/null @@ -1,266 +0,0 @@ -/* init.c - initialize ldbm backend */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include - -int -ldbm_back_initialize( - BackendInfo *bi -) -{ - static char *controls[] = { - LDAP_CONTROL_MANAGEDSAIT, - LDAP_CONTROL_X_PERMISSIVE_MODIFY, - NULL - }; - - bi->bi_controls = controls; - - bi->bi_flags |= - SLAP_BFLAG_INCREMENT | - SLAP_BFLAG_SUBENTRIES | - SLAP_BFLAG_ALIASES | - SLAP_BFLAG_REFERRALS; - - bi->bi_open = ldbm_back_open; - bi->bi_config = NULL; - bi->bi_close = ldbm_back_close; - bi->bi_destroy = ldbm_back_destroy; - - bi->bi_db_init = ldbm_back_db_init; - bi->bi_db_config = ldbm_back_db_config; - bi->bi_db_open = ldbm_back_db_open; - bi->bi_db_close = ldbm_back_db_close; - bi->bi_db_destroy = ldbm_back_db_destroy; - - bi->bi_op_bind = ldbm_back_bind; - bi->bi_op_unbind = 0; - bi->bi_op_search = ldbm_back_search; - bi->bi_op_compare = ldbm_back_compare; - bi->bi_op_modify = ldbm_back_modify; - bi->bi_op_modrdn = ldbm_back_modrdn; - bi->bi_op_add = ldbm_back_add; - bi->bi_op_delete = ldbm_back_delete; - bi->bi_op_abandon = 0; - - bi->bi_extended = ldbm_back_extended; - - bi->bi_entry_release_rw = ldbm_back_entry_release_rw; - bi->bi_entry_get_rw = ldbm_back_entry_get; - bi->bi_chk_referrals = ldbm_back_referrals; - bi->bi_operational = ldbm_back_operational; - bi->bi_has_subordinates = ldbm_back_hasSubordinates; - - /* - * hooks for slap tools - */ - bi->bi_tool_entry_open = ldbm_tool_entry_open; - bi->bi_tool_entry_close = ldbm_tool_entry_close; - bi->bi_tool_entry_first = ldbm_tool_entry_first; - bi->bi_tool_entry_next = ldbm_tool_entry_next; - bi->bi_tool_entry_get = ldbm_tool_entry_get; - bi->bi_tool_entry_put = ldbm_tool_entry_put; - bi->bi_tool_entry_reindex = ldbm_tool_entry_reindex; - bi->bi_tool_sync = ldbm_tool_sync; - - bi->bi_tool_dn2id_get = 0; - bi->bi_tool_id2entry_get = 0; - bi->bi_tool_entry_modify = 0; - - bi->bi_connection_init = 0; - bi->bi_connection_destroy = 0; - - return 0; -} - -int -ldbm_back_destroy( - BackendInfo *bi -) -{ - return 0; -} - -int -ldbm_back_open( - BackendInfo *bi -) -{ - int rc; - - /* initialize the underlying database system */ - rc = ldbm_initialize( NULL ); - return rc; -} - -int -ldbm_back_close( - BackendInfo *bi -) -{ - /* terminate the underlying database system */ - ldbm_shutdown(); - return 0; -} - -int -ldbm_back_db_init( - Backend *be -) -{ - struct ldbminfo *li; - - /* allocate backend-database-specific stuff */ - li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) ); - - /* arrange to read nextid later (on first request for it) */ - li->li_nextid = NOID; - - /* default cache size */ - li->li_cache.c_maxsize = DEFAULT_CACHE_SIZE; - - /* default database cache size */ - li->li_dbcachesize = DEFAULT_DBCACHE_SIZE; - - /* default db mode is with locking */ - li->li_dblocking = 1; - - /* default db mode is with write synchronization */ - li->li_dbwritesync = 1; - - /* default file creation mode */ - li->li_mode = SLAPD_DEFAULT_DB_MODE; - - /* default database directory */ - li->li_directory = ch_strdup( SLAPD_DEFAULT_DB_DIR ); - - /* DB_ENV environment pointer for DB3 */ - li->li_dbenv = 0; - - /* envdirok is turned on by ldbm_initialize_env if DB3 */ - li->li_envdirok = 0; - - /* syncfreq is 0 if disabled, or # seconds */ - li->li_dbsyncfreq = 0; - - /* wait up to dbsyncwaitn times if server is busy */ - li->li_dbsyncwaitn = 12; - - /* delay interval */ - li->li_dbsyncwaitinterval = 5; - - /* current wait counter */ - li->li_dbsyncwaitcount = 0; - - /* initialize various mutex locks & condition variables */ - ldap_pvt_thread_rdwr_init( &li->li_giant_rwlock ); - ldap_pvt_thread_mutex_init( &li->li_cache.c_mutex ); - ldap_pvt_thread_mutex_init( &li->li_dbcache_mutex ); - ldap_pvt_thread_cond_init( &li->li_dbcache_cv ); - - be->be_private = li; - - return 0; -} - -int -ldbm_back_db_open( - BackendDB *be -) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int rc; - - rc = alock_open( &li->li_alock_info, "slapd", - li->li_directory, ALOCK_UNIQUE ); - if ( rc == ALOCK_BUSY ) { - Debug( LDAP_DEBUG_ANY, - "ldbm_back_db_open: database already in use\n", - 0, 0, 0 ); - return -1; - } else if ( rc == ALOCK_RECOVER ) { - Debug( LDAP_DEBUG_ANY, - "ldbm_back_db_open: unclean shutdown detected;" - " database may be inconsistent!\n", - 0, 0, 0 ); - rc = alock_recover( &li->li_alock_info ); - } - if ( rc != ALOCK_CLEAN ) { - Debug( LDAP_DEBUG_ANY, - "ldbm_back_db_open: alock package is unstable;" - " database may be inconsistent!\n", - 0, 0, 0 ); - } - li->li_dbenv = ldbm_initialize_env( li->li_directory, - li->li_dbcachesize, &li->li_envdirok ); - - /* If we're in server mode and a sync frequency was set, - * submit a task to perform periodic db syncs. - */ - if (( slapMode & SLAP_SERVER_MODE ) && li->li_dbsyncfreq > 0 ) - { - ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); - ldap_pvt_runqueue_insert( &slapd_rq, li->li_dbsyncfreq, - ldbm_cache_sync_daemon, be, - "ldbm_cache_sync", be->be_suffix[0].bv_val ); - ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); - } - - return 0; -} - -int -ldbm_back_db_destroy( - BackendDB *be -) -{ - /* should free/destroy every in be_private */ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - if (li->li_dbenv) - ldbm_shutdown_env(li->li_dbenv); - - free( li->li_directory ); - attr_index_destroy( li->li_attrs ); - - ldap_pvt_thread_rdwr_destroy( &li->li_giant_rwlock ); - ldap_pvt_thread_mutex_destroy( &li->li_cache.c_mutex ); - ldap_pvt_thread_mutex_destroy( &li->li_dbcache_mutex ); - ldap_pvt_thread_cond_destroy( &li->li_dbcache_cv ); - - free( be->be_private ); - be->be_private = NULL; - - return 0; -} - -#if SLAPD_LDBM == SLAPD_MOD_DYNAMIC - -/* conditionally define the init_module() function */ -SLAP_BACKEND_INIT_MODULE( ldbm ) - -#endif /* SLAPD_LDBM == SLAPD_MOD_DYNAMIC */ - - diff --git a/servers/slapd/back-ldbm/key.c b/servers/slapd/back-ldbm/key.c deleted file mode 100644 index 32c2df8cfd..0000000000 --- a/servers/slapd/back-ldbm/key.c +++ /dev/null @@ -1,95 +0,0 @@ -/* index.c - routines for dealing with attribute indexes */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -/* read a key */ -int -key_read( - Backend *be, - DBCache *db, - struct berval *k, - ID_BLOCK **idout -) -{ - Datum key; - ID_BLOCK *idl; - - Debug( LDAP_DEBUG_TRACE, "=> key_read\n", 0, 0, 0 ); - - - ldbm_datum_init( key ); - key.dptr = k->bv_val; - key.dsize = k->bv_len; - - idl = idl_fetch( be, db, key ); - - Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - - - *idout = idl; - return LDAP_SUCCESS; -} - -/* Add or remove stuff from index files */ -int -key_change( - Backend *be, - DBCache *db, - struct berval *k, - ID id, - int op -) -{ - int rc; - Datum key; - - Debug( LDAP_DEBUG_TRACE, "=> key_change(%s,%lx)\n", - op == SLAP_INDEX_ADD_OP ? "ADD":"DELETE", (long) id, 0 ); - - - ldbm_datum_init( key ); - key.dptr = k->bv_val; - key.dsize = k->bv_len; - - ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex ); - if (op == SLAP_INDEX_ADD_OP) { - /* Add values */ - rc = idl_insert_key( be, db, key, id ); - - } else { - /* Delete values */ - rc = idl_delete_key( be, db, key, id ); - } - ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex ); - - - Debug( LDAP_DEBUG_TRACE, "<= key_change %d\n", rc, 0, 0 ); - - - ldap_pvt_thread_yield(); - - return rc; -} diff --git a/servers/slapd/back-ldbm/ldbm.c b/servers/slapd/back-ldbm/ldbm.c deleted file mode 100644 index 6790f06d40..0000000000 --- a/servers/slapd/back-ldbm/ldbm.c +++ /dev/null @@ -1,1211 +0,0 @@ -/* ldbm.c - ldap dbm compatibility routines */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 The OpenLDAP Foundation. - * Portions Copyright 1998-2003 Kurt D. Zeilenga. - * Portions Copyright 1998-2001 Net Boolean Incorporated. - * 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 originally developed by the University of Michigan - * (as part of U-MICH LDAP). Additional significant contributors - * include: - * Gary Williams - * Howard Chu - * Juan Gomez - * Kurt D. Zeilenga - * Kurt Spanier - * Mark Whitehouse - * Randy Kundee - */ - -#include "portable.h" - -#ifdef SLAPD_LDBM - -#include - -#include -#include -#include - -#include "ldbm.h" -#include "ldap_pvt_thread.h" - -void -ldbm_datum_free( LDBM ldbm, Datum data ) -{ - if ( data.dptr ) { - free( data.dptr ); - memset( &data, '\0', sizeof( Datum )); - data.dptr = NULL; - } -} - -Datum -ldbm_datum_dup( LDBM ldbm, Datum data ) -{ - Datum dup; - - ldbm_datum_init( dup ); - - if ( data.dsize == 0 ) { - dup.dsize = 0; - dup.dptr = NULL; - - return( dup ); - } - dup.dsize = data.dsize; - - if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL ) { - AC_MEMCPY( dup.dptr, data.dptr, data.dsize ); - } - - return( dup ); -} - -static int ldbm_initialized = 0; - -#if defined( USE_BERKELEY_CDB ) - /* not currently supported */ -#define LDBM_RWLOCK_INIT ((void) 0) -#define LDBM_RWLOCK_DESTROY ((void) 0) -#define LDBM_WLOCK ((void) 0) -#define LDBM_WUNLOCK ((void) 0) -#define LDBM_RLOCK ((void) 0) -#define LDBM_RUNLOCK ((void) 0) - -#elif defined( HAVE_BERKELEY_DB_THREAD ) -static ldap_pvt_thread_rdwr_t ldbm_big_rdwr; -#define LDBM_RWLOCK_INIT (ldap_pvt_thread_rdwr_init( &ldbm_big_rdwr )) -#define LDBM_RWLOCK_DESTROY (ldap_pvt_thread_rdwr_destroy( &ldbm_big_rdwr )) -#define LDBM_WLOCK (ldap_pvt_thread_rdwr_wlock(&ldbm_big_rdwr)) -#define LDBM_WUNLOCK (ldap_pvt_thread_rdwr_wunlock(&ldbm_big_rdwr)) -#define LDBM_RLOCK (ldap_pvt_thread_rdwr_rlock(&ldbm_big_rdwr)) -#define LDBM_RUNLOCK (ldap_pvt_thread_rdwr_runlock(&ldbm_big_rdwr)) - -#else -static ldap_pvt_thread_mutex_t ldbm_big_mutex; -#define LDBM_RWLOCK_INIT (ldap_pvt_thread_mutex_init( &ldbm_big_mutex )) -#define LDBM_RWLOCK_DESTROY (ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex )) -#define LDBM_WLOCK (ldap_pvt_thread_mutex_lock(&ldbm_big_mutex)) -#define LDBM_WUNLOCK (ldap_pvt_thread_mutex_unlock(&ldbm_big_mutex)) -#define LDBM_RLOCK LDBM_WLOCK -#define LDBM_RUNLOCK LDBM_WUNLOCK -#endif - -#if !defined( HAVE_BERKELEY_DB ) || (DB_VERSION_MAJOR < 3) - /* a dbEnv for BERKELEYv2 */ -DB_ENV *ldbm_Env = NULL; /* real or fake, depending on db and version */ -#endif - -/* Let's make the version comparisons a little easier... */ -#undef DB_VERSION_X -#ifdef HAVE_BERKELEY_DB -#define DB_VERSION_X ((DB_VERSION_MAJOR<<16)|(DB_VERSION_MINOR<<8)|DB_VERSION_PATCH) -#endif - -/******************************************************************* - * * - * Create some special functions to initialize Berkeley DB for * - * versions greater than 2. * - * * - *******************************************************************/ -#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 2) - -void * -ldbm_malloc( size_t size ) -{ - /* likely should use ber_mem* routines */ - return( calloc( 1, size ) ); -} - -#ifdef LDAP_SYSLOG -#include -#endif - -static void -#if DB_VERSION_X < 0x040300 -ldbm_db_errcall( const char *prefix, char *message ) -#else -ldbm_db_errcall( const DB_ENV *env, const char *prefix, char *message ) -#endif -{ -#ifdef LDAP_SYSLOG - syslog( LOG_INFO, "ldbm: %s %s", prefix, message ); -#endif -} - -int ldbm_initialize( const char* home ) -{ -#if DB_VERSION_MAJOR < 3 - int err; - u_int32_t envFlags; -#endif - - if(ldbm_initialized++) return 1; - - { - char *version; -#ifdef HAVE_EBCDIC - char v2[1024]; -#endif - int major, minor, patch; - version = db_version( &major, &minor, &patch ); -#ifdef HAVE_EBCDIC - strcpy( v2, version ); - __etoa( v2 ); - version = v2; -#endif - - if( major != DB_VERSION_MAJOR || - minor < DB_VERSION_MINOR ) - { -#ifdef LDAP_SYSLOG - syslog( LOG_INFO, - "ldbm_initialize(): version mismatch\nexpected: %s\ngot: %s\n", - DB_VERSION_STRING, version ); -#endif - return 1; - } - } - -#if DB_VERSION_MAJOR < 3 - ldbm_Env = calloc( 1, sizeof( DB_ENV )); - - if( ldbm_Env == NULL ) return 1; - - ldbm_Env->db_errcall = ldbm_db_errcall; - ldbm_Env->db_errpfx = "==>"; - - envFlags = DB_CREATE | DB_USE_ENVIRON; - - /* add optional flags */ -#ifdef DB_PRIVATE - envFlags |= DB_PRIVATE; -#endif -#ifdef HAVE_BERKELEY_DB_THREAD - envFlags |= DB_THREAD; -#endif - - err = db_appinit( home, NULL, ldbm_Env, envFlags ); - - if ( err ) { -#ifdef LDAP_SYSLOG - syslog( LOG_INFO, "ldbm_initialize(): " - "FATAL error (%d) in db_appinit()\n", err ); -#endif - return( 1 ); - } -#endif - - LDBM_RWLOCK_INIT; - - return 0; -} - -int ldbm_shutdown( void ) -{ - if( !ldbm_initialized ) return 1; - -#if DB_VERSION_MAJOR < 3 - db_appexit( ldbm_Env ); -#endif - - LDBM_RWLOCK_DESTROY; - return 0; -} - -#else /* some DB other than Berkeley V2 or greater */ - -int ldbm_initialize( const char * home ) -{ - if(ldbm_initialized++) return 1; - - LDBM_RWLOCK_INIT; - - return 0; -} - -int ldbm_shutdown( void ) -{ - if( !ldbm_initialized ) return 1; - - LDBM_RWLOCK_DESTROY; - - return 0; -} - -#endif /* HAVE_BERKELEY_DB */ - -#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 3) - -DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok) -{ - DB_ENV *env = NULL; - int err; - u_int32_t envFlags; -#ifdef HAVE_EBCDIC - char n2[2048]; -#endif - - err = db_env_create( &env, 0 ); - - if ( err ) { -#ifdef LDAP_SYSLOG - syslog( LOG_INFO, "ldbm_initialize_env(): " - "FATAL error in db_env_create() : %s (%d)\n", - db_strerror( err ), err ); -#endif - return NULL; - } - -#if DB_VERSION_X >= 0x030300 - /* This interface appeared in 3.3 */ - env->set_alloc( env, ldbm_malloc, NULL, NULL ); -#endif - - env->set_errcall( env, ldbm_db_errcall ); - env->set_errpfx( env, "==>" ); - if (dbcachesize) { - env->set_cachesize( env, 0, dbcachesize, 0 ); - } - - envFlags = DB_CREATE | DB_INIT_MPOOL | DB_USE_ENVIRON; -#ifdef DB_PRIVATE - envFlags |= DB_PRIVATE; -#endif -#ifdef DB_MPOOL_PRIVATE - envFlags |= DB_MPOOL_PRIVATE; -#endif -#ifdef HAVE_BERKELEY_DB_THREAD - envFlags |= DB_THREAD; -#endif - -#ifdef HAVE_EBCDIC - strncpy(n2, home, sizeof(n2)-1); - n2[sizeof(n2)-1] = '\0'; - __atoe(n2); - home = n2; -#endif -#if DB_VERSION_X >= 0x030100 - err = env->open( env, home, envFlags, 0 ); -#else - /* 3.0.x requires an extra argument */ - err = env->open( env, home, NULL, envFlags, 0 ); -#endif - - if ( err != 0 ) { -#ifdef LDAP_SYSLOG - syslog( LOG_INFO, "ldbm_initialize_env(): " - "FATAL error in dbEnv->open() : %s (%d)\n", - db_strerror( err ), err ); -#endif - env->close( env, 0 ); - return NULL; - } - - *envdirok = 1; - return env; -} - -void ldbm_shutdown_env(DB_ENV *env) -{ - env->close( env, 0 ); -} - -#else - -DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok) -{ - return ldbm_Env; -} - -void ldbm_shutdown_env(DB_ENV *env) -{ -} - -#endif - -#if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE ) - -/***************************************************************** - * * - * use berkeley db hash or btree package * - * * - *****************************************************************/ - -LDBM -ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) -{ - LDBM ret = NULL; -#ifdef HAVE_EBCDIC - char n2[2048]; -#endif - -#if DB_VERSION_MAJOR >= 3 - int err; - - LDBM_WLOCK; - - err = db_create( &ret, env, 0 ); - if ( err != 0 ) { - (void)ret->close(ret, 0); - LDBM_WUNLOCK; - - return NULL; - } - -#if DB_VERSION_X < 0x030300 - ret->set_malloc( ret, ldbm_malloc ); -#endif - - ret->set_pagesize( ret, DEFAULT_DB_PAGE_SIZE ); - - /* likely should use ber_mem* routines */ - -#ifdef HAVE_EBCDIC - strncpy(n2, name, sizeof(n2)-1); - n2[sizeof(n2)-1] = '\0'; - __atoe(n2); - name = n2; -#endif -#if DB_VERSION_X >= 0x040111 - err = ret->open( ret, NULL, name, NULL, DB_TYPE, rw, mode); -#else - err = ret->open( ret, name, NULL, DB_TYPE, rw, mode); -#endif - - if ( err != 0 ) { - int tmp = errno; - (void)ret->close(ret, 0); - errno = tmp; - - LDBM_WUNLOCK; - return NULL; - } - - LDBM_WUNLOCK; - -#elif DB_VERSION_MAJOR >= 2 - DB_INFO dbinfo; - - memset( &dbinfo, '\0', sizeof( dbinfo )); - -#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 4 - /* - * BerkeleyDB 2.4 do not allow db_cachesize - * to be specified if an DB_ENV is. - */ -#else - /* set db_cachesize of MPOOL is NOT being used. */ - if (( ldbm_Env == NULL ) || ( ldbm_Env->mp_info == NULL )) { - dbinfo.db_cachesize = dbcachesize; - } -#endif - - dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE; - dbinfo.db_malloc = ldbm_malloc; - - LDBM_WLOCK; - (void) db_open( name, DB_TYPE, rw, mode, ldbm_Env, &dbinfo, &ret ); - LDBM_WUNLOCK; - -#else - void *info; - BTREEINFO binfo; - HASHINFO hinfo; - - if ( DB_TYPE == DB_HASH ) { - memset( (char *) &hinfo, '\0', sizeof(hinfo) ); - hinfo.cachesize = dbcachesize; - info = &hinfo; - } else if ( DB_TYPE == DB_BTREE ) { - memset( (char *) &binfo, '\0', sizeof(binfo) ); - binfo.cachesize = dbcachesize; - info = &binfo; - } else { - info = NULL; - } - - LDBM_WLOCK; - ret = dbopen( name, rw, mode, DB_TYPE, info ); - LDBM_WUNLOCK; -#endif - - return ret; -} - -void -ldbm_close( LDBM ldbm ) -{ - LDBM_WLOCK; -#if DB_VERSION_MAJOR >= 2 - ldbm->close( ldbm, 0 ); -#else - ldbm->close( ldbm ); -#endif - LDBM_WUNLOCK; -} - -void -ldbm_sync( LDBM ldbm ) -{ - LDBM_WLOCK; - (*ldbm->sync)( ldbm, 0 ); - LDBM_WUNLOCK; -} - -Datum -ldbm_fetch( LDBM ldbm, Datum key ) -{ - Datum data; - int rc; - - LDBM_RLOCK; - -#if DB_VERSION_MAJOR >= 2 - ldbm_datum_init( data ); - - data.flags = DB_DBT_MALLOC; - - if ( (rc = ldbm->get( ldbm, NULL, &key, &data, 0 )) != 0 ) { - ldbm_datum_free( ldbm, data ); - data.dptr = NULL; - data.dsize = 0; - } -#else - if ( (rc = ldbm->get( ldbm, &key, &data, 0 )) == 0 ) { - /* Berkeley DB 1.85 don't malloc the data for us */ - /* duplicate it for to ensure reentrancy */ - data = ldbm_datum_dup( ldbm, data ); - } else { - data.dptr = NULL; - data.dsize = 0; - } -#endif - - LDBM_RUNLOCK; - - return( data ); -} - -int -ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) -{ - int rc; - - LDBM_WLOCK; - -#if DB_VERSION_MAJOR >= 2 - rc = ldbm->put( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC ); - rc = (-1) * rc; -#else - rc = ldbm->put( ldbm, &key, &data, flags & ~LDBM_SYNC ); -#endif - - if ( flags & LDBM_SYNC ) - ldbm->sync( ldbm, 0 ); - - LDBM_WUNLOCK; - - return( rc ); -} - -int -ldbm_delete( LDBM ldbm, Datum key ) -{ - int rc; - - LDBM_WLOCK; - -#if DB_VERSION_MAJOR >= 2 - rc = ldbm->del( ldbm, NULL, &key, 0 ); - rc = (-1) * rc; -#else - rc = ldbm->del( ldbm, &key, 0 ); -#endif - ldbm->sync( ldbm, 0 ); - - LDBM_WUNLOCK; - - return( rc ); -} - -Datum -ldbm_firstkey( LDBM ldbm, LDBMCursor **dbch ) -{ - Datum key, data; - int rc; - -#if DB_VERSION_MAJOR >= 2 - LDBMCursor *dbci; - - ldbm_datum_init( key ); - ldbm_datum_init( data ); - - key.flags = data.flags = DB_DBT_MALLOC; - - LDBM_RLOCK; - - /* acquire a cursor for the DB */ -# if DB_VERSION_X >= 0x020600 - rc = ldbm->cursor( ldbm, NULL, &dbci, 0 ); -# else - rc = ldbm->cursor( ldbm, NULL, &dbci ); -# endif - - if( rc ) { - key.dptr = NULL; - } else { - *dbch = dbci; - if ( dbci->c_get( dbci, &key, &data, DB_NEXT ) == 0 ) { - ldbm_datum_free( ldbm, data ); - } else { - key.dptr = NULL; - key.dsize = 0; - } - } - - LDBM_RUNLOCK; - -#else - LDBM_RLOCK; - - rc = ldbm->seq( ldbm, &key, &data, R_FIRST ); - - if ( rc == 0 ) { - key = ldbm_datum_dup( ldbm, key ); - } else { - key.dptr = NULL; - key.dsize = 0; - } - - LDBM_RUNLOCK; -#endif - - return( key ); -} - -Datum -ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) -{ - int rc; - Datum data; - - LDBM_RLOCK; - -#if DB_VERSION_MAJOR >= 2 - ldbm_datum_init( data ); - - ldbm_datum_free( ldbm, key ); - key.flags = data.flags = DB_DBT_MALLOC; - - rc = dbcp->c_get( dbcp, &key, &data, DB_NEXT ); - if ( rc == 0 ) { - ldbm_datum_free( ldbm, data ); - } else -#else - rc = ldbm->seq( ldbm, &key, &data, R_NEXT ); - - if ( rc == 0 ) { - key = ldbm_datum_dup( ldbm, key ); - } else -#endif - { - key.dptr = NULL; - key.dsize = 0; - } - - LDBM_RUNLOCK; - return( key ); -} - -int -ldbm_errno( LDBM ldbm ) -{ - return( errno ); -} - -/****************************************************************** - * * - * END Berkeley section * - * * - ******************************************************************/ - -#elif defined( HAVE_GDBM ) - -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE -#include -#endif - -/***************************************************************** - * * - * use gdbm * - * * - *****************************************************************/ - -LDBM -ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) -{ - LDBM db; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - struct stat st; -#endif -#ifdef HAVE_EBCDIC - char n2[2048]; - - strncpy(n2, name, sizeof(n2)-1); - n2[sizeof(n2)-1] = '\0'; - __atoe(n2); - name = n2; -#endif - - LDBM_WLOCK; - - if ( (db = gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) { - LDBM_WUNLOCK; - return( NULL ); - } - -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - if ( dbcachesize > 0 && stat( name, &st ) == 0 ) { - dbcachesize /= st.st_blksize; - if( dbcachesize == 0 ) dbcachesize = 1; - gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) ); - } -#else - if ( dbcachesize > 0 ) { - dbcachesize /= 4096; - if( dbcachesize == 0 ) dbcachesize = 1; - gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) ); - } -#endif - - LDBM_WUNLOCK; - - return( db ); -} - -void -ldbm_close( LDBM ldbm ) -{ - LDBM_WLOCK; - gdbm_close( ldbm ); - LDBM_WUNLOCK; -} - -void -ldbm_sync( LDBM ldbm ) -{ - LDBM_WLOCK; - gdbm_sync( ldbm ); - LDBM_WUNLOCK; -} - -Datum -ldbm_fetch( LDBM ldbm, Datum key ) -{ - Datum d; - - LDBM_RLOCK; - d = gdbm_fetch( ldbm, key ); - LDBM_RUNLOCK; - - return d; -} - -int -ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) -{ - int rc; - - LDBM_WLOCK; - rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC ); - if ( flags & LDBM_SYNC ) - gdbm_sync( ldbm ); - LDBM_WUNLOCK; - - return( rc ); -} - -int -ldbm_delete( LDBM ldbm, Datum key ) -{ - int rc; - - LDBM_WLOCK; - rc = gdbm_delete( ldbm, key ); - gdbm_sync( ldbm ); - LDBM_WUNLOCK; - - return( rc ); -} - -Datum -ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ) -{ - Datum d; - - LDBM_RLOCK; - d = gdbm_firstkey( ldbm ); - LDBM_RUNLOCK; - - if ( d.dptr != NULL ) { - *dbcp = (Datum *) malloc( sizeof( Datum ) ); - **dbcp = ldbm_datum_dup( ldbm, d ); - } - - return d; -} - -Datum -ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) -{ - Datum d; - - LDBM_RLOCK; - d = gdbm_nextkey( ldbm, *dbcp ); - LDBM_RUNLOCK; - - ldbm_datum_free( ldbm, *dbcp ); - - if ( d.dptr != NULL ) { - *dbcp = ldbm_datum_dup( ldbm, d ); - } else { - free( dbcp ); - } - - return d; -} - -int -ldbm_errno( LDBM ldbm ) -{ - int err; - - LDBM_WLOCK; - err = gdbm_errno; - LDBM_WUNLOCK; - - return( err ); -} - -#elif HAVE_MDBM - -/* MMAPED DBM HASHING DATABASE */ - -#include - -/* #define MDBM_DEBUG */ - -#ifdef MDBM_DEBUG -#include -#endif - -#define NO_NULL_KEY -/* #define MDBM_CHAIN */ - -#ifdef MDBM_CHAIN - -/* Use chaining */ - -#define mdbm_store mdbm_chain_store -#define mdbm_fetch mdbm_chain_fetch -#define mdbm_delete mdbm_chain_delete -#define mdbm_first mdbm_chain_first -#define mdbm_next mdbm_chain_next - -#endif - -#define MDBM_PG_SZ (4*1024) - -/***************************************************************** - * * - * use mdbm * - * * - *****************************************************************/ - -LDBM -ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) -{ - LDBM db; - -#ifdef MDBM_DEBUG - fprintf( stdout, - "==>(mdbm)ldbm_open(name=%s,rw=%x,mode=%x,cachesize=%d)\n", - name ? name : "NULL", rw, mode, dbcachesize ); - fflush( stdout ); -#endif - - LDBM_WLOCK; /* We need locking here, this is the only non-thread - * safe function we have. */ - - if ( (db = mdbm_open( name, rw, mode, MDBM_PG_SZ )) == NULL ) { - LDBM_WUNLOCK; -#ifdef MDBM_DEBUG - fprintf( stdout, "<==(mdbm)ldbm_open(db=NULL)\n" ); - fflush( stdout ); -#endif - return( NULL ); - } - -#ifdef MDBM_CHAIN - (void)mdbm_set_chain(db); -#endif - - LDBM_WUNLOCK; - -#ifdef MDBM_DEBUG - fprintf( stdout, "<==(mdbm)ldbm_open(db=%p)\n", db ); - fflush( stdout ); -#endif - - return( db ); -} - -void -ldbm_close( LDBM ldbm ) -{ - /* Open and close are not reentrant so we need to use locks here */ - -#ifdef MDBM_DEBUG - fprintf( stdout, - "==>(mdbm)ldbm_close(db=%p)\n", ldbm ); - fflush( stdout ); -#endif - - LDBM_WLOCK; - mdbm_close( ldbm ); - LDBM_WUNLOCK; - -#ifdef MDBM_DEBUG - fprintf( stdout, "<==(mdbm)ldbm_close()\n" ); - fflush( stdout ); -#endif -} - -void -ldbm_sync( LDBM ldbm ) -{ - /* XXX: Not sure if this is re-entrant need to check code, if so - * you can leave LOCKS out. - */ - - LDBM_WLOCK; - mdbm_sync( ldbm ); - LDBM_WUNLOCK; -} - -#define MAX_MDBM_RETRY 5 - -Datum -ldbm_fetch( LDBM ldbm, Datum key ) -{ - Datum d; - kvpair k; - int retry = 0; - - /* This hack is needed because MDBM does not take keys - * which begin with NULL when working in the chaining - * mode. - */ - -#ifdef NO_NULL_KEY - k.key.dsize = key.dsize + 1; - k.key.dptr = malloc(k.key.dsize); - *(k.key.dptr) = 'l'; - AC_MEMCPY( (void *)(k.key.dptr + 1), key.dptr, key.dsize ); -#else - k.key = key; -#endif - - k.val.dptr = NULL; - k.val.dsize = 0; - - /* LDBM_RLOCK; */ - do { - d = mdbm_fetch( ldbm, k ); - - if ( d.dsize > 0 ) { - if ( k.val.dptr != NULL ) { - free( k.val.dptr ); - } - - if ( (k.val.dptr = malloc( d.dsize )) != NULL ) { - k.val.dsize = d.dsize; - d = mdbm_fetch( ldbm, k ); - - } else { - d.dsize = 0; - break; - } - }/* if ( d.dsize > 0 ) */ - } while ((d.dsize > k.val.dsize) && (++retry < MAX_MDBM_RETRY)); - /* LDBM_RUNLOCK; */ - -#ifdef NO_NULL_KEY - free(k.key.dptr); -#endif - - return d; -} - -int -ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) -{ - int rc; - Datum int_key; /* Internal key */ - -#ifdef MDBM_DEBUG - fprintf( stdout, - "==>(mdbm)ldbm_store(db=%p, key(dptr=%p,sz=%d), data(dptr=%p,sz=%d), flags=%x)\n", - ldbm, key.dptr, key.dsize, data.dptr, data.dsize, flags ); - fflush( stdout ); -#endif - - /* LDBM_WLOCK; */ - -#ifdef NO_NULL_KEY - int_key.dsize = key.dsize + 1; - int_key.dptr = malloc( int_key.dsize ); - *(int_key.dptr) = 'l'; /* Must not be NULL !*/ - AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); -#else - int_key = key; -#endif - - rc = mdbm_store( ldbm, int_key, data, flags ); - if ( flags & LDBM_SYNC ) { - mdbm_sync( ldbm ); - } - - /* LDBM_WUNLOCK; */ - -#ifdef MDBM_DEBUG - fprintf( stdout, "<==(mdbm)ldbm_store(rc=%d)\n", rc ); - fflush( stdout ); -#endif - -#ifdef NO_NULL_KEY - free(int_key.dptr); -#endif - - return( rc ); -} - -int -ldbm_delete( LDBM ldbm, Datum key ) -{ - int rc; - Datum int_key; - - /* LDBM_WLOCK; */ - -#ifdef NO_NULL_KEY - int_key.dsize = key.dsize + 1; - int_key.dptr = malloc(int_key.dsize); - *(int_key.dptr) = 'l'; - AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); -#else - int_key = key; -#endif - - rc = mdbm_delete( ldbm, int_key ); - - /* LDBM_WUNLOCK; */ -#ifdef NO_NULL_KEY - free(int_key.dptr); -#endif - - return( rc ); -} - -static Datum -ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) -{ - kvpair out; - kvpair in; - Datum ret; - size_t sz = MDBM_PAGE_SIZE(ldbm); -#ifdef NO_NULL_KEY - int delta = 1; -#else - int delta = 0; -#endif - - /* LDBM_RLOCK; */ - - in.key.dsize = sz; /* Assume first key in one pg */ - in.key.dptr = malloc(sz); - - in.val.dptr = NULL; /* Don't need data just key */ - in.val.dsize = 0; - - ret.dptr = NULL; - ret.dsize = NULL; - - out = fptr( ldbm, in ); - - if (out.key.dsize > 0) { - ret.dsize = out.key.dsize - delta; - - if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { - ret.dsize = 0; - ret.dptr = NULL; - - } else { - AC_MEMCPY(ret.dptr, (void *)(out.key.dptr + delta), - ret.dsize ); - } - } - - /* LDBM_RUNLOCK; */ - - free(in.key.dptr); - return ret; -} - -Datum -ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ) -{ - return ldbm_get_next( ldbm, mdbm_first ); -} - -Datum -ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) -{ - /* XXX: - * don't know if this will affect the LDAP server operation - * but mdbm cannot take and input key. - */ - - return ldbm_get_next( ldbm, mdbm_next ); -} - -int -ldbm_errno( LDBM ldbm ) -{ - /* XXX: best we can do with current mdbm interface */ - return( errno ); -} - -#elif defined( HAVE_NDBM ) - -/***************************************************************** - * * - * if no gdbm or mdbm, fall back to using ndbm, the standard unix thing * - * * - *****************************************************************/ - -/* ARGSUSED */ -LDBM -ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) -{ - LDBM ldbm; - - LDBM_WLOCK; - ldbm = dbm_open( name, rw, mode ); - LDBM_WUNLOCK; - - return( ldbm ); -} - -void -ldbm_close( LDBM ldbm ) -{ - LDBM_WLOCK; - dbm_close( ldbm ); - LDBM_WUNLOCK; -} - -/* ARGSUSED */ -void -ldbm_sync( LDBM ldbm ) -{ - return; -} - -Datum -ldbm_fetch( LDBM ldbm, Datum key ) -{ - Datum d; - - LDBM_RLOCK; - d = ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) ); - LDBM_RUNLOCK; - - return d; -} - -int -ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) -{ - int rc; - - LDBM_WLOCK; - rc = dbm_store( ldbm, key, data, flags ); - LDBM_WUNLOCK; - - return rc; -} - -int -ldbm_delete( LDBM ldbm, Datum key ) -{ - int rc; - - LDBM_WLOCK; - rc = dbm_delete( ldbm, key ); - LDBM_WUNLOCK; - - return rc; -} - -Datum -ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ) -{ - Datum d; - - LDBM_RLOCK; - d = dbm_firstkey( ldbm ); - LDBM_RUNLOCK; - - return d; -} - -Datum -ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) -{ - Datum d; - - LDBM_RLOCK; - d = dbm_nextkey( ldbm ); - LDBM_RUNLOCK; - - return d; -} - -int -ldbm_errno( LDBM ldbm ) -{ - int err; - - LDBM_WLOCK; - err = dbm_error( ldbm ); - LDBM_WUNLOCK; - - return err; -} - -#endif /* ndbm */ -#endif /* ldbm */ diff --git a/servers/slapd/back-ldbm/ldbm.h b/servers/slapd/back-ldbm/ldbm.h deleted file mode 100644 index bfa4d5ee68..0000000000 --- a/servers/slapd/back-ldbm/ldbm.h +++ /dev/null @@ -1,278 +0,0 @@ -/* ldbm.h - ldap dbm compatibility routine header file */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 file LICENSE in the - * top-level directory of the distribution or, alternatively, at - * . - */ - -#ifndef _LDBM_H_ -#define _LDBM_H_ - -#include -#include - -/* dummy DB_ENV for non Berkeley DB */ -#if !defined( LDBM_USE_DBBTREE ) && !defined( LDBM_USE_DBHASH ) -# define DB_ENV void -#endif - -#if defined( LDBM_USE_DBBTREE ) || defined( LDBM_USE_DBHASH ) - -/***************************************************************** - * * - * use berkeley db btree or hash package * - * * - *****************************************************************/ -#include -#include -#include - -#ifdef HAVE_DB_185_H -# include -#else -# ifdef HAVE_DB1_DB_H -# include -# else -# include -# endif -#endif - -#ifndef DB_VERSION_MAJOR -# define DB_VERSION_MAJOR 1 -#endif -#ifndef DB_VERSION_MINOR -# define DB_VERSION_MINOR 85 -#endif - -#if DB_VERSION_MAJOR >= 2 -# define R_NOOVERWRITE DB_NOOVERWRITE -# ifndef DEFAULT_DB_PAGE_SIZE -# define DEFAULT_DB_PAGE_SIZE 4096 -# endif -#else -# define DB_ENV void -#endif - - -LDAP_BEGIN_DECL - -typedef DBT Datum; -#define dsize size -#define dptr data - -typedef DB *LDBM; - - -/* for ldbm_open */ -#if DB_VERSION_MAJOR >= 2 -typedef DBC LDBMCursor; - -# define LDBM_READER DB_RDONLY -# define LDBM_WRITER 0x00000 /* hopefully */ -# if defined( HAVE_BERKELEY_DB_THREAD ) -# define LDBM_WRCREAT (DB_NOMMAP|DB_CREATE|DB_THREAD) -# define LDBM_NEWDB (DB_TRUNCATE|DB_CREATE|DB_THREAD) -# else -# define LDBM_WRCREAT (DB_NOMMAP|DB_CREATE) -# define LDBM_NEWDB (DB_TRUNCATE|DB_CREATE) -# endif - -#else -typedef void LDBMCursor; -# define LDBM_READER O_RDONLY -# define LDBM_WRITER O_RDWR -# define LDBM_WRCREAT (O_RDWR|O_CREAT) -# define LDBM_NEWDB (O_RDWR|O_TRUNC|O_CREAT) -#endif - -LDAP_END_DECL - -/* for ldbm_open */ -#define LDBM_NOSYNC 0 -#define LDBM_SYNC 0 -#define LDBM_LOCKING 0 -#define LDBM_NOLOCKING 0 - -/* for ldbm_insert */ -#define LDBM_INSERT R_NOOVERWRITE -#define LDBM_REPLACE 0 - -#ifdef LDBM_USE_DBBTREE -# define LDBM_ORDERED 1 -# define LDBM_SUFFIX ".dbb" -# define DB_TYPE DB_BTREE -#else -# define LDBM_SUFFIX ".dbh" -# define DB_TYPE DB_HASH -#endif - -#elif defined( HAVE_GDBM ) - -/***************************************************************** - * * - * use gdbm if possible * - * * - *****************************************************************/ - -#include - -LDAP_BEGIN_DECL - -typedef datum Datum; -typedef Datum LDBMCursor; -typedef GDBM_FILE LDBM; - -LDAP_END_DECL - -/* for ldbm_open */ -#define LDBM_READER GDBM_READER -#define LDBM_WRITER GDBM_WRITER -#define LDBM_WRCREAT GDBM_WRCREAT -#define LDBM_NEWDB GDBM_NEWDB - -#ifdef GDBM_FAST -#define LDBM_NOSYNC GDBM_FAST -#else -#define LDBM_NOSYNC 0 -#endif - -#ifdef GDBM_SYNC -#define LDBM_SYNC GDBM_SYNC -#else -#define LDBM_SYNC 0 -#endif - -#define LDBM_LOCKING 0 -#ifdef GDBM_NOLOCK -#define LDBM_NOLOCKING GDBM_NOLOCK -#else -#define LDBM_NOLOCKING 0 -#endif - -#define LDBM_SUFFIX ".gdbm" - -/* for ldbm_insert */ -#define LDBM_INSERT GDBM_INSERT -#define LDBM_REPLACE GDBM_REPLACE - -#elif defined( HAVE_MDBM ) - -/***************************************************************** - * * - * use mdbm if possible * - * * - *****************************************************************/ - -#include - -LDAP_BEGIN_DECL - -typedef datum Datum; -typedef int LDBMCursor; -typedef MDBM *LDBM; - -LDAP_END_DECL - -#include -#include -#include - -/* for ldbm_open */ -#define LDBM_READER O_RDONLY -#define LDBM_WRITER O_RDWR -#define LDBM_WRCREAT (O_RDWR|O_CREAT) -#define LDBM_NEWDB (O_RDWR|O_TRUNC|O_CREAT) - -#define LDBM_SYNC 0 -#define LDBM_NOSYNC 0 -#define LDBM_LOCKING 0 -#define LDBM_NOLOCKING 0 - -#define LDBM_SUFFIX ".mdbm" - -/* for ldbm_insert */ -#define LDBM_INSERT MDBM_INSERT -#define LDBM_REPLACE MDBM_REPLACE - -#elif defined( HAVE_NDBM ) - -/***************************************************************** - * * - * if none of the above use ndbm, the standard unix thing * - * * - *****************************************************************/ - -#include - -#ifdef HAVE_FCNTL_H -#include -#endif - -LDAP_BEGIN_DECL - -typedef datum Datum; -typedef int LDBMCursor; -typedef DBM *LDBM; - -LDAP_END_DECL - -/* for ldbm_open */ -#define LDBM_READER O_RDONLY -#define LDBM_WRITER O_WRONLY -#define LDBM_WRCREAT (O_RDWR|O_CREAT) -#define LDBM_NEWDB (O_RDWR|O_TRUNC|O_CREAT) - -#define LDBM_NOSYNC 0 -#define LDBM_SYNC 0 -#define LDBM_NOLOCK 0 -#define LDBM_SYNC 0 - -#define LDBM_SUFFIX ".ndbm" - -/* for ldbm_insert */ -#define LDBM_INSERT DBM_INSERT -#define LDBM_REPLACE DBM_REPLACE - -#endif - -LDAP_BEGIN_DECL - -LDAP_LDBM_F (int) ldbm_initialize( const char * ); -LDAP_LDBM_F (int) ldbm_shutdown( void ); - -LDAP_LDBM_F (DB_ENV*) ldbm_initialize_env(const char *, int dbcachesize, int *envdirok); -LDAP_LDBM_F (void) ldbm_shutdown_env(DB_ENV *); - -LDAP_LDBM_F (int) ldbm_errno( LDBM ldbm ); -LDAP_LDBM_F (LDBM) ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ); -LDAP_LDBM_F (void) ldbm_close( LDBM ldbm ); -LDAP_LDBM_F (void) ldbm_sync( LDBM ldbm ); -LDAP_LDBM_F (void) ldbm_datum_free( LDBM ldbm, Datum data ); -LDAP_LDBM_F (Datum) ldbm_datum_dup( LDBM ldbm, Datum data ); -LDAP_LDBM_F (Datum) ldbm_fetch( LDBM ldbm, Datum key ); -LDAP_LDBM_F (int) ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ); -LDAP_LDBM_F (int) ldbm_delete( LDBM ldbm, Datum key ); - -LDAP_LDBM_F (Datum) ldbm_firstkey( LDBM ldbm, LDBMCursor **cursor ); -LDAP_LDBM_F (Datum) ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *cursor ); - -/* initialization of Datum structures */ -#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 2) - LDAP_LDBM_F (void *) ldbm_malloc( size_t size ); -# define ldbm_datum_init(d) ((void)memset(&(d), '\0', sizeof(Datum))) -#else -# define ldbm_datum_init(d) ((void)0) -#endif /* HAVE_BERKELEY_DB */ - -LDAP_END_DECL - -#endif /* _ldbm_h_ */ diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c deleted file mode 100644 index 18557bf624..0000000000 --- a/servers/slapd/back-ldbm/modify.c +++ /dev/null @@ -1,305 +0,0 @@ -/* modify.c - ldbm backend modify routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -/* We need this function because of LDAP modrdn. If we do not - * add this there would be a bunch of code replication here - * and there and of course the likelihood of bugs increases. - * Juan C. Gomez (gomez@engr.sgi.com) 05/18/99 - */ -int ldbm_modify_internal( - Operation *op, - Modifications *modlist, - Entry *e, - const char **text, - char *textbuf, - size_t textlen ) -{ - int rc = LDAP_SUCCESS; - Modification *mod; - Modifications *ml; - Attribute *save_attrs; - Attribute *ap; - - Debug(LDAP_DEBUG_TRACE, - "ldbm_modify_internal: %s\n", - e->e_name.bv_val, - get_permissiveModify(op) ? " (permissive)" : "", - 0 ); - - if ( !acl_check_modlist( op, e, modlist )) { - return LDAP_INSUFFICIENT_ACCESS; - } - - save_attrs = e->e_attrs; - e->e_attrs = attrs_dup( e->e_attrs ); - - for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { - mod = &ml->sml_mod; - - switch ( mod->sm_op ) { - case LDAP_MOD_ADD: - Debug(LDAP_DEBUG_ARGS, - "ldbm_modify_internal: add\n", 0, 0, 0); - - rc = modify_add_values( e, mod, get_permissiveModify( op ), - text, textbuf, textlen ); - if( rc != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n", - rc, *text, 0); - } - break; - - case LDAP_MOD_DELETE: - Debug(LDAP_DEBUG_ARGS, - "ldbm_modify_internal: delete\n", 0, 0, 0); - - rc = modify_delete_values( e, mod, get_permissiveModify( op ), - text, textbuf, textlen ); - assert( rc != LDAP_TYPE_OR_VALUE_EXISTS ); - if( rc != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n", - rc, *text, 0); - } - break; - - case LDAP_MOD_REPLACE: - Debug(LDAP_DEBUG_ARGS, - "ldbm_modify_internal: replace\n", 0, 0, 0); - - rc = modify_replace_values( e, mod, get_permissiveModify( op ), - text, textbuf, textlen ); - if( rc != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n", - rc, *text, 0); - } - break; - - case LDAP_MOD_INCREMENT: - Debug(LDAP_DEBUG_ARGS, - "ldbm_modify_internal: increment\n",0,0,0); - - rc = modify_increment_values( e, mod, get_permissiveModify( op ), - text, textbuf, textlen ); - if( rc != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n", - rc, *text, 0); - } - break; - - case SLAP_MOD_SOFTADD: - Debug(LDAP_DEBUG_ARGS, - "ldbm_modify_internal: softadd\n", 0, 0, 0); - - /* Avoid problems in index_add_mods() - * We need to add index if necessary. - */ - mod->sm_op = LDAP_MOD_ADD; - - rc = modify_add_values( e, mod, get_permissiveModify( op ), - text, textbuf, textlen ); - mod->sm_op = SLAP_MOD_SOFTADD; - if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) { - rc = LDAP_SUCCESS; - } - - if( rc != LDAP_SUCCESS ) { - Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n", - rc, *text, 0); - } - break; - - default: - Debug(LDAP_DEBUG_ANY, "ldbm_modify_internal: invalid op %d\n", - mod->sm_op, 0, 0); - - rc = LDAP_OTHER; - *text = "Invalid modify operation"; - Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n", - rc, *text, 0); - } - - if ( rc != LDAP_SUCCESS ) { - goto exit; - } - - /* If objectClass was modified, reset the flags */ - if ( mod->sm_desc == slap_schema.si_ad_objectClass ) { - e->e_ocflags = 0; - } - - /* check if modified attribute was indexed */ - rc = index_is_indexed( op->o_bd, mod->sm_desc ); - if ( rc == LDAP_SUCCESS ) { - ap = attr_find( save_attrs, mod->sm_desc ); - if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL; - - ap = attr_find( e->e_attrs, mod->sm_desc ); - if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD; - } - } - - /* check that the entry still obeys the schema */ - rc = entry_schema_check( op, e, save_attrs, get_manageDIT(op), - text, textbuf, textlen ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, "entry failed schema check: %s\n", - *text, 0, 0 ); - - goto exit; - } - - /* check for abandon */ - if ( op->o_abandon ) { - rc = SLAPD_ABANDON; - goto exit; - } - - /* update the indices of the modified attributes */ - - /* start with deleting the old index entries */ - for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { - if ( ap->a_flags & SLAP_ATTR_IXDEL ) { - rc = index_values( op, ap->a_desc, - ap->a_nvals, - e->e_id, SLAP_INDEX_DELETE_OP ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "ldbm_modify_internal: Attribute index delete failure\n", - 0, 0, 0 ); - goto exit; - } - ap->a_flags &= ~SLAP_ATTR_IXDEL; - } - } - - /* add the new index entries */ - for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { - if ( ap->a_flags & SLAP_ATTR_IXADD ) { - rc = index_values( op, ap->a_desc, - ap->a_nvals, - e->e_id, SLAP_INDEX_ADD_OP ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "ldbm_modify_internal: Attribute index add failure\n", - 0, 0, 0 ); - goto exit; - } - ap->a_flags &= ~SLAP_ATTR_IXADD; - } - } - -exit: - if ( rc == LDAP_SUCCESS ) { - attrs_free( save_attrs ); - } else { - for ( ap = save_attrs; ap; ap = ap->a_next ) { - ap->a_flags = 0; - } - attrs_free( e->e_attrs ); - e->e_attrs = save_attrs; - } - - return rc; -} - -int -ldbm_back_modify( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - Entry *matched; - Entry *e; - int manageDSAit = get_manageDSAit( op ); - char textbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof textbuf; - - Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0); - - slap_mods_opattrs( op, &op->orm_modlist, 1 ); - - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - - /* acquire and lock entry */ - e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched ); - - /* FIXME: dn2entry() should return non-glue entry */ - if (( e == NULL ) || ( !manageDSAit && e && is_entry_glue( e ))) { - if ( matched != NULL ) { - rs->sr_matched = ber_strdup_x( matched->e_dn, op->o_tmpmemctx ); - rs->sr_ref = is_entry_referral( matched ) - ? get_entry_referrals( op, matched ) - : NULL; - cache_return_entry_r( &li->li_cache, matched ); - } else { - rs->sr_ref = referral_rewrite( default_referral, NULL, - &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - } - - rs->sr_err = LDAP_REFERRAL; - rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; - goto return_results; - } - - if ( !manageDSAit && is_entry_referral( e ) ) { - /* parent is a referral, don't allow add */ - /* parent is an alias, don't allow add */ - rs->sr_ref = get_entry_referrals( op, e ); - - Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, - 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = ber_strdup_x( e->e_name.bv_val, op->o_tmpmemctx ); - rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; - goto return_results; - } - - /* Modify the entry */ - rs->sr_err = ldbm_modify_internal( op, op->oq_modify.rs_modlist, e, - &rs->sr_text, textbuf, textlen ); - - /* change the entry itself */ - if( rs->sr_err == LDAP_SUCCESS ) { - if ( id2entry_add( op->o_bd, e ) != 0 ) { - rs->sr_err = LDAP_OTHER; - rs->sr_text = "id2entry failure"; - } - } - -return_results:; - if( e != NULL ) cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - send_ldap_result( op, rs ); - slap_graduate_commit_csn( op ); - - rs->sr_text = NULL; - return rs->sr_err; -} diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c deleted file mode 100644 index 4ed808c339..0000000000 --- a/servers/slapd/back-ldbm/modrdn.c +++ /dev/null @@ -1,445 +0,0 @@ -/* modrdn.c - ldbm backend modrdn routine */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ -/* Portions Copyright 1999, Juan C. Gomez, All rights reserved. - * This software is not subject to any license of Silicon Graphics - * Inc. or Purdue University. - * - * Redistribution and use in source and binary forms are permitted - * without restriction or fee of any kind as long as this notice - * is preserved. - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -int -ldbm_back_modrdn( - Operation *op, - SlapReply *rs ) -{ - AttributeDescription *children = slap_schema.si_ad_children; - AttributeDescription *entry = slap_schema.si_ad_entry; - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - struct berval p_dn, p_ndn; - struct berval new_dn = BER_BVNULL, new_ndn = BER_BVNULL; - struct berval old_ndn = BER_BVNULL; - Entry *e, *p = NULL; - Entry *matched; - /* LDAP v2 supporting correct attribute handling. */ - int rc_id = 0; - ID id = NOID; - char textbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof textbuf; - /* Added to support newSuperior */ - Entry *np = NULL; /* newSuperior Entry */ - struct berval *np_ndn = NULL; /* newSuperior ndn */ - struct berval *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */ - /* Used to interface with ldbm_modify_internal() */ - int manageDSAit = get_manageDSAit( op ); - - Debug( LDAP_DEBUG_TRACE, - "==>ldbm_back_modrdn: dn: %s newSuperior=%s\n", - op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "NULL", - ( op->oq_modrdn.rs_newSup && op->oq_modrdn.rs_newSup->bv_len ) - ? op->oq_modrdn.rs_newSup->bv_val : "NULL", 0 ); - - slap_mods_opattrs( op, &op->orr_modlist, 1 ); - - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - - e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched ); - - /* get entry with writer lock */ - /* FIXME: dn2entry() should return non-glue entry */ - if (( e == NULL ) || ( !manageDSAit && e && is_entry_glue( e ))) { - if ( matched != NULL ) { - rs->sr_matched = strdup( matched->e_dn ); - rs->sr_ref = is_entry_referral( matched ) - ? get_entry_referrals( op, matched ) - : NULL; - cache_return_entry_r( &li->li_cache, matched ); - } else { - rs->sr_ref = referral_rewrite( default_referral, NULL, - &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - } - - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - - rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - free( (char *)rs->sr_matched ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return rs->sr_err; - } - - /* check entry for "entry" acl */ - if ( ! access_allowed( op, e, entry, NULL, ACL_WRITE, NULL ) ) - { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_modrdn: no write access to entry\n", 0, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - "no write access to entry" ); - - goto return_results; - } - - if (!manageDSAit && is_entry_referral( e ) ) { - /* parent is a referral, don't allow add */ - /* parent is an alias, don't allow add */ - rs->sr_ref = get_entry_referrals( op, e ); - - Debug( LDAP_DEBUG_TRACE, "entry %s is referral\n", e->e_dn, - 0, 0 ); - - rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e->e_name.bv_val; - send_ldap_result( op, rs ); - - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - goto return_results; - } - - if ( has_children( op->o_bd, e ) ) { - Debug( LDAP_DEBUG_TRACE, "entry %s has children\n", e->e_dn, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_NOT_ALLOWED_ON_NONLEAF, - "subtree rename not supported" ); - goto return_results; - } - - if ( be_issuffix( op->o_bd, &e->e_nname ) ) { - p_ndn = slap_empty_bv ; - } else { - dnParent( &e->e_nname, &p_ndn ); - } - - if ( p_ndn.bv_len != 0 ) { - /* Make sure parent entry exist and we can write its - * children. - */ - - if( (p = dn2entry_w( op->o_bd, &p_ndn, NULL )) == NULL) { - Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", - 0, 0, 0); - - send_ldap_error( op, rs, LDAP_OTHER, - "parent entry does not exist" ); - - goto return_results; - } - } else { - p = (Entry *)&slap_entry_root; - } - - /* check parent for "children" acl */ - rs->sr_err = access_allowed( op, p, children, NULL, - op->oq_modrdn.rs_newSup != NULL ? - ACL_WDEL : ACL_WRITE, - NULL ); - - if ( BER_BVISEMPTY( &p_ndn )) - p = NULL; - - if ( !rs->sr_err ) - { - Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0, - 0, 0 ); - - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - NULL ); - goto return_results; - } - - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: wr to children of entry %s OK\n", - p_ndn.bv_val, 0, 0 ); - - if ( p_ndn.bv_val == slap_empty_bv.bv_val ) { - p_dn = slap_empty_bv; - } else { - dnParent( &e->e_name, &p_dn ); - } - - Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n", - p_dn.bv_val, 0, 0 ); - - new_parent_dn = &p_dn; /* New Parent unless newSuperior given */ - - if ( op->oq_modrdn.rs_newSup != NULL ) { - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: new parent \"%s\" requested...\n", - op->oq_modrdn.rs_newSup->bv_val, 0, 0 ); - - np_ndn = op->oq_modrdn.rs_nnewSup; - - /* newSuperior == oldParent? */ - if ( dn_match( &p_ndn, np_ndn ) ) { - Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: " - "new parent\"%s\" seems to be the same as the " - "old parent \"%s\"\n", - op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val, 0 ); - - op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */ - } - } - - if ( op->oq_modrdn.rs_newSup != NULL ) { - /* newSuperior == entry being moved?, if so ==> ERROR */ - /* Get Entry with dn=newSuperior. Does newSuperior exist? */ - - if ( op->oq_modrdn.rs_nnewSup->bv_len ) { - if( (np = dn2entry_w( op->o_bd, np_ndn, NULL )) == NULL) { - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: newSup(ndn=%s) not here!\n", - np_ndn->bv_val, 0, 0); - - send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, - "newSuperior not found" ); - goto return_results; - } - - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: wr to new parent OK np=%p, id=%ld\n", - (void *) np, np->e_id, 0 ); - - /* check newSuperior for "children" acl */ - if ( !access_allowed( op, np, children, NULL, - ACL_WADD, NULL ) ) - { - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: no wr to newSup children\n", - 0, 0, 0 ); - - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); - goto return_results; - } - - if ( is_entry_alias( np ) ) { - /* parent is an alias, don't allow add */ - Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 ); - - - send_ldap_error( op, rs, LDAP_ALIAS_PROBLEM, - "newSuperior is an alias" ); - - goto return_results; - } - - if ( is_entry_referral( np ) ) { - /* parent is a referral, don't allow add */ - Debug( LDAP_DEBUG_TRACE, "entry (%s) is referral\n", - np->e_dn, 0, 0 ); - - send_ldap_error( op, rs, LDAP_OTHER, - "newSuperior is a referral" ); - - goto return_results; - } - - } else { - if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) - || be_shadow_update( op ) ) { - int can_access; - np = (Entry *)&slap_entry_root; - - can_access = access_allowed( op, np, - children, NULL, ACL_WADD, NULL ); - np = NULL; - - /* check parent for "children" acl */ - if ( ! can_access ) { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_modrdn: no " - "access to new superior\n", 0, 0, 0 ); - - send_ldap_error( op, rs, - LDAP_INSUFFICIENT_ACCESS, - NULL ); - goto return_results; - } - - } else { - Debug( LDAP_DEBUG_TRACE, - "<=- ldbm_back_modrdn: \"\" " - "not allowed as new superior\n", - 0, 0, 0); - - send_ldap_error( op, rs, - LDAP_INSUFFICIENT_ACCESS, - NULL ); - goto return_results; - } - } - - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: wr to new parent's children OK\n", - 0, 0, 0 ); - - new_parent_dn = op->oq_modrdn.rs_newSup; - } - - /* Build target dn and make sure target entry doesn't exist already. */ - build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL ); - dnNormalize( 0, NULL, NULL, &new_dn, &new_ndn, NULL ); - - Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s\n", - new_ndn.bv_val, 0, 0 ); - - /* check for abandon */ - if ( op->o_abandon ) { - rs->sr_err = SLAPD_ABANDON; - goto return_results; - } - - if ( ( rc_id = dn2id ( op->o_bd, &new_ndn, &id ) ) || id != NOID ) { - /* if (rc_id) something bad happened to ldbm cache */ - rs->sr_err = rc_id ? LDAP_OTHER : LDAP_ALREADY_EXISTS; - send_ldap_result( op, rs ); - goto return_results; - } - - Debug( LDAP_DEBUG_TRACE, - "ldbm_back_modrdn: new ndn=%s does not exist\n", - new_ndn.bv_val, 0, 0 ); - - Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n", - 0, 0, 0 ); - - assert( op->orr_modlist != NULL ); - - /* check for abandon */ - if ( op->o_abandon ) { - rs->sr_err = SLAPD_ABANDON; - goto return_results; - } - - (void) cache_delete_entry( &li->li_cache, e ); - - free( e->e_dn ); - old_ndn = e->e_nname; - e->e_name = new_dn; - e->e_nname = new_ndn; - new_dn.bv_val = NULL; - new_ndn.bv_val = NULL; - - /* NOTE: after this you must not free new_dn or new_ndn! - * They are used by cache. - */ - - /* modify memory copy of entry */ - rs->sr_err = ldbm_modify_internal( op, op->orr_modlist, e, - &rs->sr_text, textbuf, textlen ); - switch ( rs->sr_err ) { - case LDAP_SUCCESS: - break; - - default: - send_ldap_result( op, rs ); - /* FALLTHRU */ - case SLAPD_ABANDON: - goto return_results; - } - - /* - * NOTE: the backend MUST delete then add the entry, - * otherwise indexing may get hosed - * FIXME: if a new ID was used, the add could be done first. - * that would be safer. - */ - - /* delete old one */ - if ( dn2id_delete( op->o_bd, &old_ndn, e->e_id ) != 0 ) { - send_ldap_error( op, rs, LDAP_OTHER, - "DN index delete fail" ); - goto return_results; - } - - /* add new one */ - if ( dn2id_add( op->o_bd, &e->e_nname, e->e_id ) != 0 ) { - /* try to repair old entry - probably hopeless */ - if( dn2id_add( op->o_bd, &old_ndn, e->e_id) != 0 ) { - send_ldap_error( op, rs, LDAP_OTHER, - "DN index add and repair failed" ); - } else { - send_ldap_error( op, rs, LDAP_OTHER, - "DN index add failed" ); - } - goto return_results; - } - - /* id2entry index */ - if ( id2entry_add( op->o_bd, e ) != 0 ) { - /* Try to undo */ - int rc; - rc = dn2id_delete( op->o_bd, &e->e_nname, e->e_id ); - rc |= dn2id_add( op->o_bd, &old_ndn, e->e_id ); - if( rc ) { - send_ldap_error( op, rs, LDAP_OTHER, - "entry update and repair failed" ); - } else { - send_ldap_error( op, rs, LDAP_OTHER, - "entry update failed" ); - } - goto return_results; - } - - (void) cache_update_entry( &li->li_cache, e ); - - rs->sr_err = LDAP_SUCCESS; - rs->sr_text = NULL; - send_ldap_result( op, rs ); - cache_entry_commit( e ); - -return_results: - 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( old_ndn.bv_val != NULL ) free( old_ndn.bv_val ); - - /* LDAP v3 Support */ - if( np != NULL ) { - /* free new parent and writer lock */ - cache_return_entry_w( &li->li_cache, np ); - } - - if( p != NULL ) { - /* free parent and writer lock */ - cache_return_entry_w( &li->li_cache, p ); - } - - /* free entry and writer lock */ - cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - rs->sr_text = NULL; - return( rs->sr_err ); -} diff --git a/servers/slapd/back-ldbm/nextid.c b/servers/slapd/back-ldbm/nextid.c deleted file mode 100644 index c80a7015bf..0000000000 --- a/servers/slapd/back-ldbm/nextid.c +++ /dev/null @@ -1,135 +0,0 @@ -/* nextid.c - keep track of the next id to be given out */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -static int -next_id_read( Backend *be, ID *idp ) -{ - Datum key, data; - DBCache *db; - - *idp = NOID; - - if ( (db = ldbm_cache_open( be, "nextid", LDBM_SUFFIX, LDBM_WRCREAT )) - == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open/create nextid" LDBM_SUFFIX "\n", - 0, 0, 0 ); - - return( -1 ); - } - - ldbm_datum_init( key ); - key.dptr = (char *) idp; - key.dsize = sizeof(ID); - - data = ldbm_cache_fetch( db, key ); - - if( data.dptr != NULL ) { - AC_MEMCPY( idp, data.dptr, sizeof( ID ) ); - ldbm_datum_free( db->dbc_db, data ); - - } else { - *idp = 1; - } - - ldbm_cache_close( be, db ); - return( 0 ); -} - -int -next_id_write( Backend *be, ID id ) -{ - Datum key, data; - DBCache *db; - ID noid = NOID; - int flags, rc = 0; - - if ( (db = ldbm_cache_open( be, "nextid", LDBM_SUFFIX, LDBM_WRCREAT )) - == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open/create nextid" LDBM_SUFFIX "\n", - 0, 0, 0 ); - - return( -1 ); - } - - ldbm_datum_init( key ); - ldbm_datum_init( data ); - - key.dptr = (char *) &noid; - key.dsize = sizeof(ID); - - data.dptr = (char *) &id; - data.dsize = sizeof(ID); - - flags = LDBM_REPLACE; - if ( ldbm_cache_store( db, key, data, flags ) != 0 ) { - rc = -1; - } - - ldbm_cache_close( be, db ); - return( rc ); -} - -int -next_id_get( Backend *be, ID *idp ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int rc = 0; - - *idp = NOID; - - if ( li->li_nextid == NOID ) { - if ( ( rc = next_id_read( be, idp ) ) ) { - return( rc ); - } - li->li_nextid = *idp; - } - - *idp = li->li_nextid; - - return( rc ); -} - -int -next_id( Backend *be, ID *idp ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int rc = 0; - - if ( li->li_nextid == NOID ) { - if ( ( rc = next_id_read( be, idp ) ) ) { - return( rc ); - } - li->li_nextid = *idp; - } - - *idp = li->li_nextid++; - if ( next_id_write( be, li->li_nextid ) ) { - rc = -1; - } - - return( rc ); -} diff --git a/servers/slapd/back-ldbm/operational.c b/servers/slapd/back-ldbm/operational.c deleted file mode 100644 index 384437cbf8..0000000000 --- a/servers/slapd/back-ldbm/operational.c +++ /dev/null @@ -1,77 +0,0 @@ -/* operational.c - ldbm backend operational attributes function */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -/* - * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE - * if the entry has children or not. - */ -int -ldbm_back_hasSubordinates( - Operation *op, - Entry *e, - int *hasSubordinates ) -{ - if ( has_children( op->o_bd, e ) ) { - *hasSubordinates = LDAP_COMPARE_TRUE; - - } else { - *hasSubordinates = LDAP_COMPARE_FALSE; - } - - return 0; -} - -/* - * sets the supported operational attributes (if required) - */ -int -ldbm_back_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 hs; - - hs = has_children( op->o_bd, rs->sr_entry ); - *ap = slap_operational_hasSubordinate( hs ); - assert( *ap != NULL ); - - ap = &(*ap)->a_next; - } - - return 0; -} - diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h deleted file mode 100644 index 8af8808846..0000000000 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ /dev/null @@ -1,263 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#ifndef _PROTO_BACK_LDBM -#define _PROTO_BACK_LDBM - -#include - -LDAP_BEGIN_DECL - -/* - * alias.c - */ -Entry *deref_internal_r LDAP_P(( - Backend *be, - Entry *e, - struct berval *dn, - int *err, - Entry **matched, - const char **text )); - -#define deref_entry_r( be, e, err, matched, text ) \ - deref_internal_r( be, e, NULL, err, matched, text ) -#define deref_dn_r( be, dn, err, matched, text ) \ - deref_internal_r( be, NULL, dn, err, matched, text) - -/* - * attr.c - */ - -void attr_mask LDAP_P(( struct ldbminfo *li, - AttributeDescription *desc, - slap_mask_t *indexmask )); - -int attr_index_config LDAP_P(( struct ldbminfo *li, - const char *fname, int lineno, - int argc, char **argv )); -void attr_index_destroy LDAP_P(( Avlnode *tree )); - -/* - * cache.c - */ - -int cache_add_entry_rw LDAP_P(( Cache *cache, Entry *e, int rw )); -int cache_update_entry LDAP_P(( Cache *cache, Entry *e )); -void cache_return_entry_rw LDAP_P(( Cache *cache, Entry *e, int rw )); -#define cache_return_entry_r(c, e) cache_return_entry_rw((c), (e), 0) -#define cache_return_entry_w(c, e) cache_return_entry_rw((c), (e), 1) -void cache_entry_commit LDAP_P(( Entry *e )); - -ID cache_find_entry_ndn2id LDAP_P(( Backend *be, Cache *cache, struct berval *ndn )); -Entry * cache_find_entry_id LDAP_P(( Cache *cache, ID id, int rw )); -int cache_delete_entry LDAP_P(( Cache *cache, Entry *e )); -void cache_release_all LDAP_P(( Cache *cache )); - -/* - * dbcache.c - */ - -DBCache * ldbm_cache_open LDAP_P(( Backend *be, - const char *name, const char *suffix, int flags )); -void ldbm_cache_close LDAP_P(( Backend *be, DBCache *db )); -void ldbm_cache_really_close LDAP_P(( Backend *be, DBCache *db )); -void ldbm_cache_flush_all LDAP_P(( Backend *be )); -void ldbm_cache_sync LDAP_P(( Backend *be )); -#if 0 /* replaced by macro */ -Datum ldbm_cache_fetch LDAP_P(( DBCache *db, Datum key )); -#else /* 1 */ -#define ldbm_cache_fetch( db, key ) ldbm_fetch( (db)->dbc_db, (key) ) -#endif /* 1 */ -int ldbm_cache_store LDAP_P(( DBCache *db, Datum key, Datum data, int flags )); -int ldbm_cache_delete LDAP_P(( DBCache *db, Datum key )); -void *ldbm_cache_sync_daemon LDAP_P(( void *ctx, void *arg )); - -/* - * dn2id.c - */ - -int dn2id_add LDAP_P(( Backend *be, struct berval *dn, ID id )); -int dn2id LDAP_P(( Backend *be, struct berval *dn, ID *idp )); -int dn2idl LDAP_P(( Backend *be, struct berval *dn, int prefix, ID_BLOCK **idlp )); -int dn2id_delete LDAP_P(( Backend *be, struct berval *dn, ID id )); - -Entry * dn2entry_rw LDAP_P(( Backend *be, struct berval *dn, Entry **matched, int rw )); -#define dn2entry_r(be, dn, m) dn2entry_rw((be), (dn), (m), 0) -#define dn2entry_w(be, dn, m) dn2entry_rw((be), (dn), (m), 1) - -/* - * entry.c - */ -BI_entry_release_rw ldbm_back_entry_release_rw; -BI_entry_get_rw ldbm_back_entry_get; - -/* - * filterindex.c - */ - -ID_BLOCK * filter_candidates LDAP_P(( Operation *op, Filter *f )); - -/* - * id2children.c - */ - -int id2children_add LDAP_P(( Backend *be, Entry *p, Entry *e )); -int id2children_remove LDAP_P(( Backend *be, Entry *p, Entry *e )); -int has_children LDAP_P(( Backend *be, Entry *p )); - -/* - * id2entry.c - */ - -int id2entry_add LDAP_P(( Backend *be, Entry *e )); -int id2entry_delete LDAP_P(( Backend *be, Entry *e )); - -Entry * id2entry_rw LDAP_P(( Backend *be, ID id, int rw )); -#define id2entry_r(be, id) id2entry_rw((be), (id), 0) -#define id2entry_w(be, id) id2entry_rw((be), (id), 1) - -/* - * idl.c - */ - -ID_BLOCK * idl_alloc LDAP_P(( unsigned int nids )); -ID_BLOCK * idl_allids LDAP_P(( Backend *be )); -void idl_free LDAP_P(( ID_BLOCK *idl )); -ID_BLOCK * idl_fetch LDAP_P(( Backend *be, DBCache *db, Datum key )); -int idl_insert_key LDAP_P(( Backend *be, DBCache *db, Datum key, ID id )); -int idl_insert LDAP_P(( ID_BLOCK **idl, ID id, unsigned int maxids )); -int idl_delete_key LDAP_P(( Backend *be, DBCache *db, Datum key, ID id )); -ID_BLOCK * idl_intersection LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b )); -ID_BLOCK * idl_union LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b )); -ID_BLOCK * idl_notin LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b )); -ID idl_firstid LDAP_P(( ID_BLOCK *idl, ID *cursor )); -ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID *cursor )); - -/* - * index.c - */ -extern int -index_is_indexed LDAP_P(( - Backend *be, - AttributeDescription *desc )); - -extern int -index_param LDAP_P(( - Backend *be, - AttributeDescription *desc, - int ftype, - char **dbname, - slap_mask_t *mask, - struct berval *prefix )); - -extern int -index_values LDAP_P(( - Operation *op, - AttributeDescription *desc, - BerVarray vals, - ID id, - int opid )); - -int index_entry LDAP_P(( Operation *op, int r, Entry *e )); -#define index_entry_add(be,e) index_entry((be),SLAP_INDEX_ADD_OP,(e)) -#define index_entry_del(be,e) index_entry((be),SLAP_INDEX_DELETE_OP,(e)) - - -/* - * key.c - */ -extern int -key_change LDAP_P(( - Backend *be, - DBCache *db, - struct berval *k, - ID id, - int op )); -extern int -key_read LDAP_P(( - Backend *be, - DBCache *db, - struct berval *k, - ID_BLOCK **idout )); - -/* - * modify.c - * These prototypes are placed here because they are used by modify and - * modify rdn which are implemented in different files. - * - * We need ldbm_internal_modify here because of LDAP modrdn & modify use - * it. If we do not add this, there would be a bunch of code replication - * here and there and of course the likelihood of bugs increases. - * Juan C. Gomez (gomez@engr.sgi.com) 05/18/99 - * - */ - -/* returns LDAP error code indicating error OR SLAPD_ABANDON */ -int ldbm_modify_internal LDAP_P(( Operation *op, - Modifications *mods, Entry *e, - const char **text, char *textbuf, size_t textlen )); - -/* - * nextid.c - */ - -int next_id LDAP_P(( Backend *be, ID *idp )); -int next_id_get LDAP_P(( Backend *be, ID *idp )); -int next_id_write LDAP_P(( Backend *be, ID id )); - -/* - * former external.h - */ - -extern BI_init ldbm_back_initialize; - -extern BI_open ldbm_back_open; -extern BI_close ldbm_back_close; -extern BI_destroy ldbm_back_destroy; - -extern BI_db_init ldbm_back_db_init; -extern BI_db_open ldbm_back_db_open; -extern BI_db_close ldbm_back_db_close; -extern BI_db_destroy ldbm_back_db_destroy; -extern BI_db_config ldbm_back_db_config; - -extern BI_op_extended ldbm_back_extended; -extern BI_op_bind ldbm_back_bind; -extern BI_op_search ldbm_back_search; -extern BI_op_compare ldbm_back_compare; -extern BI_op_modify ldbm_back_modify; -extern BI_op_modrdn ldbm_back_modrdn; -extern BI_op_add ldbm_back_add; -extern BI_op_delete ldbm_back_delete; - -extern BI_operational ldbm_back_operational; -extern BI_has_subordinates ldbm_back_hasSubordinates; - -/* hooks for slap tools */ -extern BI_tool_entry_open ldbm_tool_entry_open; -extern BI_tool_entry_close ldbm_tool_entry_close; -extern BI_tool_entry_first ldbm_tool_entry_first; -extern BI_tool_entry_next ldbm_tool_entry_next; -extern BI_tool_entry_get ldbm_tool_entry_get; -extern BI_tool_entry_put ldbm_tool_entry_put; - -extern BI_tool_entry_reindex ldbm_tool_entry_reindex; -extern BI_tool_sync ldbm_tool_sync; - -extern BI_chk_referrals ldbm_back_referrals; - -LDAP_END_DECL - -#endif /* _PROTO_BACK_LDBM */ diff --git a/servers/slapd/back-ldbm/referral.c b/servers/slapd/back-ldbm/referral.c deleted file mode 100644 index ba3e5fb2ec..0000000000 --- a/servers/slapd/back-ldbm/referral.c +++ /dev/null @@ -1,127 +0,0 @@ -/* referral.c - LDBM backend referral handler */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -int -ldbm_back_referrals( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - Entry *e, *matched; - int rc = LDAP_SUCCESS; - - if( op->o_tag == LDAP_REQ_SEARCH ) { - /* let search take care of itself */ - return LDAP_SUCCESS; - } - - if( get_manageDSAit( op ) ) { - /* let op take care of DSA management */ - return LDAP_SUCCESS; - } - - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); - - /* get entry with reader lock */ - e = dn2entry_r( op->o_bd, &op->o_req_ndn, &matched ); - if ( e == NULL ) { - if ( matched != NULL ) { - rs->sr_matched = ch_strdup( matched->e_dn ); - - Debug( LDAP_DEBUG_TRACE, - "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n", - op->o_tag, op->o_req_dn.bv_val, rs->sr_matched ); - - if ( is_entry_referral( matched ) ) { - rc = rs->sr_err = LDAP_OTHER; - rs->sr_ref = get_entry_referrals( op, matched ); - } - - cache_return_entry_r( &li->li_cache, matched ); - - } else if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) && default_referral != NULL ) { - rc = rs->sr_err = LDAP_OTHER; - rs->sr_ref = referral_rewrite( default_referral, - NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - } - - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - if ( rs->sr_ref != NULL ) { - /* send referrals */ - rc = rs->sr_err = LDAP_REFERRAL; - - } else { - rs->sr_text = rs->sr_matched ? "bad referral object" : "bad default referral"; - } - - if ( rc != LDAP_SUCCESS ) { - send_ldap_result( op, rs ); - } - - if ( rs->sr_matched ) free( (char *)rs->sr_matched ); - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - rs->sr_text = NULL; - rs->sr_ref = NULL; - rs->sr_matched = NULL; - - return rc; - } - - if ( is_entry_referral( e ) ) { - /* entry is a referral */ - BerVarray refs = get_entry_referrals( op, e ); - rs->sr_ref = referral_rewrite( - refs, &e->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - - Debug( LDAP_DEBUG_TRACE, - "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n", - op->o_tag, op->o_req_dn.bv_val, e->e_dn ); - - rs->sr_matched = e->e_name.bv_val; - if( rs->sr_ref != NULL ) { - rc = rs->sr_err = LDAP_REFERRAL; - rs->sr_text = NULL; - - } else { - rc = rs->sr_err = LDAP_OTHER; - rs->sr_text = "bad referral object"; - } - send_ldap_result( op, rs ); - - if ( refs != NULL ) ber_bvarray_free( refs ); - rs->sr_err = rc; - rs->sr_ref = NULL; - rs->sr_text = NULL; - rs->sr_matched = NULL; - } - - cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - return rc; -} diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c deleted file mode 100644 index 0f949ca5b0..0000000000 --- a/servers/slapd/back-ldbm/search.c +++ /dev/null @@ -1,571 +0,0 @@ -/* search.c - ldbm backend search function */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" -#include "proto-back-ldbm.h" - -static ID_BLOCK *base_candidate( - Backend *be, Entry *e ); - -static ID_BLOCK *search_candidates( - Operation *op, Entry *e, Filter *filter, - int scope, int deref, int manageDSAit ); - - -int -ldbm_back_search( - Operation *op, - SlapReply *rs ) -{ - struct ldbminfo *li = (struct ldbminfo *) op->o_bd->be_private; - int rc; - time_t stoptime; - ID_BLOCK *candidates; - ID id, cursor; - Entry *e; - Entry *matched = NULL; - struct berval realbase = BER_BVNULL; - int manageDSAit = get_manageDSAit( op ); -#ifdef SLAP_ACL_HONOR_DISCLOSE - slap_mask_t mask; -#endif - - Debug(LDAP_DEBUG_TRACE, "=> ldbm_back_search\n", 0, 0, 0); - - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); - - if ( op->o_req_ndn.bv_len == 0 ) { - /* DIT root special case */ - e = (Entry *) &slap_entry_root; - - /* need normalized dn below */ - ber_dupbv( &realbase, &e->e_nname ); - - candidates = search_candidates( op, e, op->ors_filter, - op->ors_scope, op->ors_deref, - manageDSAit || get_domainScope(op) ); - - goto searchit; - - } else if ( op->ors_deref & LDAP_DEREF_FINDING ) { - /* deref dn and get entry with reader lock */ - e = deref_dn_r( op->o_bd, &op->o_req_ndn, - &rs->sr_err, &matched, &rs->sr_text ); - - if( rs->sr_err == LDAP_NO_SUCH_OBJECT ) rs->sr_err = LDAP_REFERRAL; - - } else { - /* get entry with reader lock */ - e = dn2entry_r( op->o_bd, &op->o_req_ndn, &matched ); - rs->sr_err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL; - rs->sr_text = NULL; - } - - if ( e == NULL ) { - struct berval matched_dn = BER_BVNULL; - - if ( matched != NULL ) { - BerVarray erefs = NULL; - -#ifdef SLAP_ACL_HONOR_DISCLOSE - if ( ! access_allowed( op, matched, - slap_schema.si_ad_entry, - NULL, ACL_DISCLOSE, NULL ) ) - { - rs->sr_err = LDAP_NO_SUCH_OBJECT; - - } else -#endif /* SLAP_ACL_HONOR_DISCLOSE */ - { - ber_dupbv( &matched_dn, &matched->e_name ); - - erefs = is_entry_referral( matched ) - ? get_entry_referrals( op, matched ) - : NULL; - } - - cache_return_entry_r( &li->li_cache, matched ); - - if ( erefs ) { - rs->sr_ref = referral_rewrite( erefs, &matched_dn, - &op->o_req_dn, op->ors_scope ); - - ber_bvarray_free( erefs ); - } - - } else { - rs->sr_ref = referral_rewrite( default_referral, - NULL, &op->o_req_dn, op->ors_scope ); - } - - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - rs->sr_matched = matched_dn.bv_val; - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - ber_memfree( matched_dn.bv_val ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return rs->sr_err; - } - -#ifdef SLAP_ACL_HONOR_DISCLOSE - /* NOTE: __NEW__ "search" access is required - * on searchBase object */ - if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry, - NULL, ACL_SEARCH, NULL, &mask ) ) - { - if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) { - rs->sr_err = LDAP_NO_SUCH_OBJECT; - } else { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - } - - cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - send_ldap_result( op, rs ); - return rs->sr_err; - } -#endif /* SLAP_ACL_HONOR_DISCLOSE */ - - if ( !manageDSAit && is_entry_referral( e ) ) { - /* entry is a referral, don't allow add */ - struct berval matched_dn = BER_BVNULL; - BerVarray erefs = NULL; - - rs->sr_ref = NULL; - rs->sr_err = LDAP_OTHER; - rs->sr_text = "bad referral object"; - - ber_dupbv( &matched_dn, &e->e_name ); - erefs = get_entry_referrals( op, e ); - - cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - Debug( LDAP_DEBUG_TRACE, - "ldbm_search: entry is referral\n", - 0, 0, 0 ); - - if ( erefs ) { - rs->sr_ref = referral_rewrite( erefs, &matched_dn, - &op->o_req_dn, op->ors_scope ); - - ber_bvarray_free( erefs ); - - if ( rs->sr_ref ) { - rs->sr_err = LDAP_REFERRAL; - rs->sr_text = NULL; - } - } - - rs->sr_matched = matched_dn.bv_val; - send_ldap_result( op, rs ); - ber_bvarray_free( rs->sr_ref ); - ber_memfree( matched_dn.bv_val ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return rs->sr_err; - } - - if ( is_entry_alias( e ) ) { - /* don't deref */ - op->ors_deref = LDAP_DEREF_NEVER; - } - - if ( op->ors_scope == LDAP_SCOPE_BASE ) { - candidates = base_candidate( op->o_bd, e ); - - } else { - candidates = search_candidates( op, e, op->ors_filter, - op->ors_scope, op->ors_deref, manageDSAit ); - } - - /* need normalized dn below */ - ber_dupbv( &realbase, &e->e_nname ); - - cache_return_entry_r( &li->li_cache, e ); - -searchit: - if ( candidates == NULL ) { - /* no candidates */ - Debug( LDAP_DEBUG_TRACE, "ldbm_search: no candidates\n", - 0, 0, 0 ); - - rs->sr_err = LDAP_SUCCESS; - send_ldap_result( op, rs ); - - rc = LDAP_SUCCESS; - goto done; - } - - /* if candidates exceed to-be-checked entries, abort */ - if ( op->ors_limit /* isroot == FALSE */ - && op->ors_limit->lms_s_unchecked != -1 - && ID_BLOCK_NIDS( candidates ) > (unsigned) op->ors_limit->lms_s_unchecked ) - { - send_ldap_error( op, rs, LDAP_ADMINLIMIT_EXCEEDED, NULL ); - rc = LDAP_SUCCESS; - goto done; - } - - /* compute it anyway; root does not use it */ - stoptime = op->o_time + op->ors_tlimit; - rs->sr_attrs = op->ors_attrs; - - for ( id = idl_firstid( candidates, &cursor ); id != NOID; - id = idl_nextid( candidates, &cursor ) ) - { - int scopeok = 0; - int result = 0; - - /* check for abandon */ - if ( op->o_abandon ) { - rc = SLAPD_ABANDON; - goto done; - } - - /* check time limit */ - if ( op->ors_tlimit != SLAP_NO_LIMIT - && slap_get_time() > stoptime ) - { - rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; - send_ldap_result( op, rs ); - rc = LDAP_SUCCESS; - goto done; - } - - /* get the entry with reader lock */ - e = id2entry_r( op->o_bd, id ); - - if ( e == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "ldbm_search: candidate %ld not found\n", - id, 0, 0 ); - - goto loop_continue; - } - - rs->sr_entry = e; - - if ( is_entry_subentry( e ) ) { - if( op->ors_scope != LDAP_SCOPE_BASE ) { - if(!get_subentries_visibility( op )) { - /* only subentries are visible */ - goto loop_continue; - } - } else if ( get_subentries( op ) && - !get_subentries_visibility( op )) - { - /* only subentries are visible */ - goto loop_continue; - } - } else if ( get_subentries_visibility( op )) { - /* only subentries are visible */ - goto loop_continue; - } - - if ( op->ors_deref & LDAP_DEREF_SEARCHING && - is_entry_alias( e ) ) - { - Entry *matched; - int err; - const char *text; - - e = deref_entry_r( op->o_bd, e, &err, &matched, &text ); - - if( e == NULL ) { - e = matched; - goto loop_continue; - } - - if( e->e_id == id ) { - /* circular loop */ - goto loop_continue; - } - - /* need to skip alias which deref into scope */ - if( op->ors_scope == LDAP_SCOPE_ONELEVEL ) { - struct berval pdn; - dnParent( &e->e_nname, &pdn ); - if ( ber_bvcmp( &pdn, &realbase ) ) { - goto loop_continue; - } - - } else if ( dnIsSuffix( &e->e_nname, &realbase ) ) { - /* alias is within scope */ - Debug( LDAP_DEBUG_TRACE, - "ldbm_search: alias \"%s\" in subtree\n", - e->e_dn, 0, 0 ); - - goto loop_continue; - } - - rs->sr_entry = e; - - scopeok = 1; - } - - /* - * If it's a referral, add it to the list of referrals. - * Only do this for non-base searches, and don't check - * the filter explicitly here since it's only a candidate - * anyway. - */ - if ( !manageDSAit && op->ors_scope != LDAP_SCOPE_BASE && - is_entry_referral( e ) ) - { - struct berval dn; - - /* check scope */ - if ( !scopeok && op->ors_scope == LDAP_SCOPE_ONELEVEL ) { - if ( !be_issuffix( op->o_bd, &e->e_nname ) ) { - dnParent( &e->e_nname, &dn ); - scopeok = dn_match( &dn, &realbase ); - } else { - scopeok = (realbase.bv_len == 0); - } - - } else if ( !scopeok - && op->ors_scope == LDAP_SCOPE_SUBTREE ) - { - scopeok = dnIsSuffix( &e->e_nname, &realbase ); - -#ifdef LDAP_SCOPE_SUBORDINATE - } else if ( !scopeok - && op->ors_scope == LDAP_SCOPE_SUBORDINATE ) - { - scopeok = !dn_match( &e->e_nname, &realbase ) - && dnIsSuffix( &e->e_nname, &realbase ); -#endif - - } else { - scopeok = 1; - } - - if( scopeok ) { - BerVarray erefs = get_entry_referrals( op, e ); - rs->sr_ref = referral_rewrite( erefs, - &e->e_name, NULL, - op->ors_scope == LDAP_SCOPE_ONELEVEL - ? LDAP_SCOPE_BASE - : LDAP_SCOPE_SUBTREE ); - - ber_bvarray_free( erefs ); - - send_search_reference( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - - } else { - Debug( LDAP_DEBUG_TRACE, - "ldbm_search: candidate referral %ld scope not okay\n", - id, 0, 0 ); - } - - goto loop_continue; - } - - if ( !manageDSAit && is_entry_glue( e )) { - goto loop_continue; - } - - /* if it matches the filter and scope, send it */ - result = test_filter( op, e, op->ors_filter ); - - if ( result == LDAP_COMPARE_TRUE ) { - struct berval dn; - - /* check scope */ - if ( !scopeok && op->ors_scope == LDAP_SCOPE_ONELEVEL ) { - if ( !be_issuffix( op->o_bd, &e->e_nname ) ) { - dnParent( &e->e_nname, &dn ); - scopeok = dn_match( &dn, &realbase ); - } else { - scopeok = (realbase.bv_len == 0); - } - - } else if ( !scopeok && - op->ors_scope == LDAP_SCOPE_SUBTREE ) - { - scopeok = dnIsSuffix( &e->e_nname, &realbase ); - - } else if ( !scopeok && - op->ors_scope == LDAP_SCOPE_SUBORDINATE ) - { - scopeok = !dn_match( &e->e_nname, &realbase ) - && dnIsSuffix( &e->e_nname, &realbase ); - - } else { - scopeok = 1; - } - - if ( scopeok ) { - if (e) { - rs->sr_flags = 0; - rs->sr_err = send_search_entry( op, rs ); - - switch ( rs->sr_err ) { - case LDAP_UNAVAILABLE: /* connection closed */ - cache_return_entry_r( &li->li_cache, e ); - rc = LDAP_SUCCESS; - goto done; - case LDAP_SIZELIMIT_EXCEEDED: - cache_return_entry_r( &li->li_cache, e ); - rc = rs->sr_err; - rs->sr_entry = NULL; - send_ldap_result( op, rs ); - rc = LDAP_SUCCESS; - goto done; - } - } - - } else { - Debug( LDAP_DEBUG_TRACE, - "ldbm_search: candidate entry %ld scope not okay\n", - id, 0, 0 ); - } - - } else { - Debug( LDAP_DEBUG_TRACE, - "ldbm_search: candidate entry %ld does not match filter\n", - id, 0, 0 ); - } - -loop_continue: - if( e != NULL ) { - /* free reader lock */ - cache_return_entry_r( &li->li_cache, e ); - } - - ldap_pvt_thread_yield(); - } - - rs->sr_err = rs->sr_v2ref ? LDAP_REFERRAL : LDAP_SUCCESS; - rs->sr_ref = rs->sr_v2ref; - send_ldap_result( op, rs ); - - rc = LDAP_SUCCESS; - -done: - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - - if( candidates != NULL ) - idl_free( candidates ); - - if( rs->sr_v2ref ) ber_bvarray_free( rs->sr_v2ref ); - if( realbase.bv_val ) free( realbase.bv_val ); - - return rc; -} - -static ID_BLOCK * -base_candidate( - Backend *be, - Entry *e ) -{ - ID_BLOCK *idl; - - Debug(LDAP_DEBUG_TRACE, "base_candidates: base: \"%s\"\n", - e->e_dn, 0, 0); - - - idl = idl_alloc( 1 ); - idl_insert( &idl, e->e_id, 1 ); - - return( idl ); -} - -static ID_BLOCK * -search_candidates( - Operation *op, - Entry *e, - Filter *filter, - int scope, - int deref, - int manageDSAit ) -{ - ID_BLOCK *candidates; - Filter f, fand, rf, af, xf; - AttributeAssertion aa_ref, aa_alias; - struct berval bv_ref = { sizeof("referral")-1, "referral" }; - struct berval bv_alias = { sizeof("alias")-1, "alias" }; - Filter sf; - AttributeAssertion aa_subentry; - - Debug(LDAP_DEBUG_TRACE, - "search_candidates: base=\"%s\" s=%d d=%d\n", - e->e_ndn, scope, deref ); - - - xf.f_or = filter; - xf.f_choice = LDAP_FILTER_OR; - xf.f_next = NULL; - - if( !manageDSAit ) { - /* match referrals */ - rf.f_choice = LDAP_FILTER_EQUALITY; - rf.f_ava = &aa_ref; - rf.f_av_desc = slap_schema.si_ad_objectClass; - rf.f_av_value = bv_ref; - rf.f_next = xf.f_or; - xf.f_or = &rf; - } - - if( deref & LDAP_DEREF_SEARCHING ) { - /* match aliases */ - af.f_choice = LDAP_FILTER_EQUALITY; - af.f_ava = &aa_alias; - af.f_av_desc = slap_schema.si_ad_objectClass; - af.f_av_value = bv_alias; - af.f_next = xf.f_or; - xf.f_or = ⁡ - } - - f.f_next = NULL; - f.f_choice = LDAP_FILTER_AND; - f.f_and = &fand; - fand.f_choice = scope == LDAP_SCOPE_ONELEVEL - ? SLAPD_FILTER_DN_ONE - : SLAPD_FILTER_DN_SUBTREE; - fand.f_dn = &e->e_nname; - fand.f_next = xf.f_or == filter ? filter : &xf ; - - if ( get_subentries_visibility( op )) { - struct berval bv_subentry = { sizeof("SUBENTRY")-1, "SUBENTRY" }; - sf.f_choice = LDAP_FILTER_EQUALITY; - sf.f_ava = &aa_subentry; - sf.f_av_desc = slap_schema.si_ad_objectClass; - sf.f_av_value = bv_subentry; - sf.f_next = fand.f_next; - fand.f_next = &sf; - } - - candidates = filter_candidates( op, &f ); - return( candidates ); -} diff --git a/servers/slapd/back-ldbm/tools.c b/servers/slapd/back-ldbm/tools.c deleted file mode 100644 index db2b31e91b..0000000000 --- a/servers/slapd/back-ldbm/tools.c +++ /dev/null @@ -1,316 +0,0 @@ -/* tools.c - tools for slap tools */ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * Copyright 1998-2006 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 - * . - */ - -#include "portable.h" - -#include - -#include -#include - -#include "slap.h" -#include "back-ldbm.h" - -static LDBMCursor *cursorp = NULL; -static DBCache *id2entry = NULL; - -int ldbm_tool_entry_open( - BackendDB *be, int mode ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int flags; - - assert( slapMode & SLAP_TOOL_MODE ); - assert( id2entry == NULL ); - - switch( mode ) { - case 1: - flags = LDBM_WRCREAT; - break; - case 2: -#ifdef TRUNCATE_MODE - flags = LDBM_NEWDB; -#else - flags = LDBM_WRCREAT; -#endif - break; - default: - flags = LDBM_READER; - } - - li->li_dbwritesync = 0; - - if ( (id2entry = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, flags )) - == NULL ) { - Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry" LDBM_SUFFIX "\n", - 0, 0, 0 ); - - return( -1 ); - } - - return 0; -} - -int ldbm_tool_entry_close( - BackendDB *be ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - assert( slapMode & SLAP_TOOL_MODE ); - assert( id2entry != NULL ); - - ldbm_cache_close( be, id2entry ); - li->li_dbwritesync = 1; - id2entry = NULL; - - return 0; -} - -ID ldbm_tool_entry_first( - BackendDB *be ) -{ - Datum key; - ID id; - - assert( slapMode & SLAP_TOOL_MODE ); - assert( id2entry != NULL ); - - key = ldbm_firstkey( id2entry->dbc_db, &cursorp ); - - if( key.dptr == NULL ) { - return NOID; - } - - AC_MEMCPY( &id, key.dptr, key.dsize ); -#ifndef WORDS_BIGENDIAN - id = ntohl( id ); -#endif - - ldbm_datum_free( id2entry->dbc_db, key ); - - return id; -} - -ID ldbm_tool_entry_next( - BackendDB *be ) -{ - Datum key; - ID id; - - assert( slapMode & SLAP_TOOL_MODE ); - assert( id2entry != NULL ); - - /* allow for NEXTID */ - ldbm_datum_init( key ); - - key = ldbm_nextkey( id2entry->dbc_db, key, cursorp ); - - if( key.dptr == NULL ) { - return NOID; - } - - AC_MEMCPY( &id, key.dptr, key.dsize ); -#ifndef WORDS_BIGENDIAN - id = ntohl( id ); -#endif - - ldbm_datum_free( id2entry->dbc_db, key ); - - return id; -} - -Entry* ldbm_tool_entry_get( BackendDB *be, ID id ) -{ - Entry *e; - Datum key, data; -#ifndef WORDS_BIGENDIAN - ID id2; -#endif - assert( slapMode & SLAP_TOOL_MODE ); - assert( id2entry != NULL ); - - ldbm_datum_init( key ); - -#ifndef WORDS_BIGENDIAN - id2 = htonl( id ); - key.dptr = (char *) &id2; -#else - key.dptr = (char *) &id; -#endif - key.dsize = sizeof(ID); - - data = ldbm_cache_fetch( id2entry, key ); - - if ( data.dptr == NULL ) { - return NULL; - } - - e = str2entry2( data.dptr, 0 ); - ldbm_datum_free( id2entry->dbc_db, data ); - - if( e != NULL ) { - e->e_id = id; - } - - return e; -} - -ID ldbm_tool_entry_put( - BackendDB *be, - Entry *e, - struct berval *text ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - Datum key, data; - int rc, len; - ID id; - Operation op = {0}; - Opheader ohdr = {0}; - - assert( slapMode & SLAP_TOOL_MODE ); - assert( id2entry != NULL ); - - assert( text != NULL ); - assert( text->bv_val != NULL ); - assert( text->bv_val[0] == '\0' ); /* overconservative? */ - - if ( next_id_get( be, &id ) || id == NOID ) { - strncpy( text->bv_val, "unable to get nextid", text->bv_len ); - return NOID; - } - - e->e_id = li->li_nextid++; - - Debug( LDAP_DEBUG_TRACE, "=> ldbm_tool_entry_put( %ld, \"%s\" )\n", - e->e_id, e->e_dn, 0 ); - - if ( dn2id( be, &e->e_nname, &id ) ) { - /* something bad happened to ldbm cache */ - strncpy( text->bv_val, "ldbm cache corrupted", text->bv_len ); - return NOID; - } - - if( id != NOID ) { - Debug( LDAP_DEBUG_TRACE, - "<= ldbm_tool_entry_put: \"%s\" already exists (id=%ld)\n", - e->e_ndn, id, 0 ); - strncpy( text->bv_val, "already exists", text->bv_len ); - return NOID; - } - - op.o_hdr = &ohdr; - op.o_bd = be; - op.o_tmpmemctx = NULL; - op.o_tmpmfuncs = &ch_mfuncs; - - rc = index_entry_add( &op, e ); - if( rc != 0 ) { - strncpy( text->bv_val, "index add failed", text->bv_len ); - return NOID; - } - - rc = dn2id_add( be, &e->e_nname, e->e_id ); - if( rc != 0 ) { - strncpy( text->bv_val, "dn2id add failed", text->bv_len ); - return NOID; - } - - ldbm_datum_init( key ); - ldbm_datum_init( data ); - -#ifndef WORDS_BIGENDIAN - id = htonl( e->e_id ); - key.dptr = (char *) &id; -#else - key.dptr = (char *) &e->e_id; -#endif - key.dsize = sizeof(ID); - - data.dptr = entry2str( e, &len ); - data.dsize = len + 1; - - /* store it */ - rc = ldbm_cache_store( id2entry, key, data, LDBM_REPLACE ); - - if( rc != 0 ) { - (void) dn2id_delete( be, &e->e_nname, e->e_id ); - strncpy( text->bv_val, "cache store failed", text->bv_len ); - return NOID; - } - - return e->e_id; -} - -int ldbm_tool_entry_reindex( - BackendDB *be, - ID id ) -{ - int rc; - Entry *e; - Operation op = {0}; - Opheader ohdr = {0}; - - Debug( LDAP_DEBUG_ARGS, "=> ldbm_tool_entry_reindex( %ld )\n", - (long) id, 0, 0 ); - - - e = ldbm_tool_entry_get( be, id ); - - if( e == NULL ) { - Debug( LDAP_DEBUG_ANY, - "ldbm_tool_entry_reindex:: could not locate id=%ld\n", - (long) id, 0, 0 ); - - return -1; - } - - /* - * just (re)add them for now - * assume that some other routine (not yet implemented) - * will zap index databases - * - */ - - Debug( LDAP_DEBUG_TRACE, "=> ldbm_tool_entry_reindex( %ld, \"%s\" )\n", - id, e->e_dn, 0 ); - - dn2id_add( be, &e->e_nname, e->e_id ); - - op.o_hdr = &ohdr; - op.o_bd = be; - op.o_tmpmemctx = NULL; - op.o_tmpmfuncs = &ch_mfuncs; - rc = index_entry_add( &op, e ); - - entry_free( e ); - - return rc; -} - -int ldbm_tool_sync( BackendDB *be ) -{ - struct ldbminfo *li = (struct ldbminfo *) be->be_private; - - assert( slapMode & SLAP_TOOL_MODE ); - - if ( li->li_nextid != NOID ) { - if ( next_id_write( be, li->li_nextid ) ) { - return( -1 ); - } - } - - return 0; -} -- 2.39.5