]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/init.c
Call node_find_cmp() with (void *)&ulong instead of (void *)ulong.
[openldap] / servers / slapd / back-bdb / init.c
1 /* init.c - initialize bdb backend */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11 #include <ac/string.h>
12 #include <ac/unistd.h>
13 #include <ac/stdlib.h>
14
15 #include <lutil.h>
16
17 #include "back-bdb.h"
18 #include "external.h"
19
20 static struct bdbi_database {
21         char *file;
22         char *name;
23         int type;
24         int flags;
25 } bdbi_databases[] = {
26         { "id2entry" BDB_SUFFIX, "id2entry", DB_BTREE, 0 },
27 #ifdef BDB_HIER
28         { "id2parent" BDB_SUFFIX, "id2parent", DB_BTREE, 0 },
29 #else
30         { "dn2id" BDB_SUFFIX, "dn2id", DB_BTREE, 0 },
31 #endif
32         { NULL, NULL, 0, 0 }
33 };
34
35 struct berval bdb_uuid = { 0, NULL };
36
37 typedef void * db_malloc(size_t);
38 typedef void * db_realloc(void *, size_t);
39
40 #if 0
41 static int
42 bdb_open( BackendInfo *bi )
43 {
44         return 0;
45 }
46
47 static int
48 bdb_destroy( BackendInfo *bi )
49 {
50         return 0;
51 }
52
53 static int
54 bdb_close( BackendInfo *bi )
55 {
56         /* terminate the underlying database system */
57         return 0;
58 }
59 #endif
60
61 static int
62 bdb_db_init( BackendDB *be )
63 {
64         struct bdb_info *bdb;
65
66 #ifdef NEW_LOGGING
67         LDAP_LOG( BACK_BDB, ENTRY, "bdb_db_init", 0, 0, 0 );
68 #else
69         Debug( LDAP_DEBUG_ANY,
70                 "bdb_db_init: Initializing BDB database\n",
71                 0, 0, 0 );
72 #endif
73
74         /* indicate system schema supported */
75         be->be_flags |=
76 #ifdef BDB_SUBENTRIES
77                 SLAP_BFLAG_SUBENTRIES |
78 #endif
79 #ifdef BDB_ALIASES
80                 SLAP_BFLAG_ALIASES |
81 #endif
82                 SLAP_BFLAG_REFERRALS;
83
84         /* allocate backend-database-specific stuff */
85         bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) );
86
87         /* DBEnv parameters */
88         bdb->bi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
89         bdb->bi_dbenv_xflags = 0;
90         bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
91
92         bdb->bi_cache.c_maxsize = DEFAULT_CACHE_SIZE;
93
94         bdb->bi_lock_detect = DB_LOCK_DEFAULT;
95         bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
96         bdb->bi_search_stack = NULL;
97
98 #ifdef LDAP_CLIENT_UPDATE
99         LDAP_LIST_INIT (&bdb->psearch_list);
100 #endif
101
102         ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex );
103         ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex );
104         ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_mutex );
105         ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
106 #ifdef BDB_HIER
107         ldap_pvt_thread_rdwr_init( &bdb->bi_tree_rdwr );
108 #endif
109
110         be->be_private = bdb;
111
112         return 0;
113 }
114
115 int
116 bdb_bt_compare(
117         DB *db, 
118         const DBT *usrkey,
119         const DBT *curkey
120 )
121 {
122         unsigned char *u, *c;
123         int i;
124
125         u = usrkey->data;
126         c = curkey->data;
127
128 #ifdef WORDS_BIGENDIAN
129         for( i = 0; i < sizeof(ID); i++)
130 #else
131         for( i = sizeof(ID)-1; i >= 0; i--)
132 #endif
133         {
134                 if( u[i] - c[i] )
135                         return u[i] - c[i];
136         }
137         return 0;
138 }
139
140 static int
141 bdb_db_open( BackendDB *be )
142 {
143         int rc, i;
144         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
145         u_int32_t flags;
146 #ifdef HAVE_EBCDIC
147         char path[MAXPATHLEN];
148 #endif
149
150 #ifdef NEW_LOGGING
151         LDAP_LOG( BACK_BDB, ARGS, 
152                 "bdb_db_open: %s\n", be->be_suffix[0].bv_val, 0, 0 );
153 #else
154         Debug( LDAP_DEBUG_ARGS,
155                 "bdb_db_open: %s\n",
156                 be->be_suffix[0].bv_val, 0, 0 );
157 #endif
158
159         /* we should check existance of dbenv_home and db_directory */
160
161         rc = db_env_create( &bdb->bi_dbenv, 0 );
162         if( rc != 0 ) {
163 #ifdef NEW_LOGGING
164                 LDAP_LOG( BACK_BDB, ERR, 
165                         "bdb_db_open: db_env_create failed: %s (%d)\n", 
166                         db_strerror(rc), rc, 0 );
167 #else
168                 Debug( LDAP_DEBUG_ANY,
169                         "bdb_db_open: db_env_create failed: %s (%d)\n",
170                         db_strerror(rc), rc, 0 );
171 #endif
172                 return rc;
173         }
174
175         flags = DB_INIT_MPOOL | DB_THREAD | DB_CREATE
176                 | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;
177         
178 #if 0
179         /* Never do automatic recovery, must perform it manually.
180          * Otherwise restarting with gentlehup will corrupt the
181          * database.
182          */
183         if( !(slapMode & SLAP_TOOL_MODE) ) flags |= DB_RECOVER;
184 #endif
185
186         bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
187         bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
188         bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );
189
190 #ifdef SLAP_IDL_CACHE
191         if ( bdb->bi_idl_cache_max_size ) {
192                 ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_mutex );
193                 bdb->bi_idl_cache_size = 0;
194         }
195 #endif
196
197 #ifdef BDB_SUBDIRS
198         {
199                 char dir[MAXPATHLEN];
200                 size_t len = strlen( bdb->bi_dbenv_home );
201
202                 strcpy( dir, bdb->bi_dbenv_home );
203                 strcat( &dir[len], BDB_TMP_SUBDIR );
204                 
205                 rc = bdb->bi_dbenv->set_tmp_dir( bdb->bi_dbenv, dir );
206                 if( rc != 0 ) {
207 #ifdef NEW_LOGGING
208                         LDAP_LOG( BACK_BDB, ERR, 
209                                 "bdb_db_open: set_tmp_dir(%s) failed: %s (%d)\n", 
210                                 dir, db_strerror(rc), rc );
211 #else
212                         Debug( LDAP_DEBUG_ANY,
213                                 "bdb_db_open: set_tmp_dir(%s) failed: %s (%d)\n",
214                                 dir, db_strerror(rc), rc );
215 #endif
216                         return rc;
217                 }
218
219                 strcat( &dir[len], BDB_LG_SUBDIR );
220
221                 rc = bdb->bi_dbenv->set_lg_dir( bdb->bi_dbenv, dir );
222                 if( rc != 0 ) {
223 #ifdef NEW_LOGGING
224                         LDAP_LOG( BACK_BDB, ERR, 
225                                 "bdb_db_open: set_lg_dir(%s) failed: %s (%d)\n", 
226                                 dir, db_strerror(rc), rc );
227 #else
228                         Debug( LDAP_DEBUG_ANY,
229                                 "bdb_db_open: set_lg_dir(%s) failed: %s (%d)\n",
230                                 dir, db_strerror(rc), rc );
231 #endif
232                         return rc;
233                 }
234
235                 strcat( &dir[len], BDB_DATA_SUBDIR );
236
237                 rc = bdb->bi_dbenv->set_data_dir( bdb->bi_dbenv, dir );
238                 if( rc != 0 ) {
239 #ifdef NEW_LOGGING
240                         LDAP_LOG( BACK_BDB, ERR, 
241                                 "bdb_db_open: set_data_dir(%s) failed: %s (%d)\n",
242                                 dir, db_strerror(rc), rc );
243 #else
244                         Debug( LDAP_DEBUG_ANY,
245                                 "bdb_db_open: set_data_dir(%s) failed: %s (%d)\n",
246                                 dir, db_strerror(rc), rc );
247 #endif
248                         return rc;
249                 }
250         }
251 #endif
252
253 #ifdef NEW_LOGGING
254         LDAP_LOG( BACK_BDB, DETAIL1, 
255                 "bdb_db_open: dbenv_open %s\n", bdb->bi_dbenv_home, 0, 0 );
256 #else
257         Debug( LDAP_DEBUG_TRACE,
258                 "bdb_db_open: dbenv_open(%s)\n",
259                 bdb->bi_dbenv_home, 0, 0);
260 #endif
261
262 #ifdef HAVE_EBCDIC
263         strcpy( path, bdb->bi_dbenv_home );
264         __atoe( path );
265         rc = bdb->bi_dbenv->open( bdb->bi_dbenv,
266                 path,
267                 flags,
268                 bdb->bi_dbenv_mode );
269 #else
270         rc = bdb->bi_dbenv->open( bdb->bi_dbenv,
271                 bdb->bi_dbenv_home,
272                 flags,
273                 bdb->bi_dbenv_mode );
274 #endif
275         if( rc != 0 ) {
276 #ifdef NEW_LOGGING
277                 LDAP_LOG( BACK_BDB, ERR, 
278                         "bdb_db_open: dbenv_open failed: %s (%d)\n", 
279                         db_strerror(rc), rc, 0 );
280 #else
281                 Debug( LDAP_DEBUG_ANY,
282                         "bdb_db_open: dbenv_open failed: %s (%d)\n",
283                         db_strerror(rc), rc, 0 );
284 #endif
285                 return rc;
286         }
287
288         if( bdb->bi_dbenv_xflags != 0 ) {
289                 rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv,
290                         bdb->bi_dbenv_xflags, 1);
291                 if( rc != 0 ) {
292 #ifdef NEW_LOGGING
293                         LDAP_LOG( BACK_BDB, ERR, 
294                                 "bdb_db_open: dbenv_set_flags failed: %s (%d)\n", 
295                                 db_strerror(rc), rc, 0 );
296 #else
297                         Debug( LDAP_DEBUG_ANY,
298                                 "bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
299                                 db_strerror(rc), rc, 0 );
300 #endif
301                         return rc;
302                 }
303         }
304
305         flags = DB_THREAD | DB_CREATE | bdb->bi_db_opflags;
306
307         bdb->bi_databases = (struct bdb_db_info **) ch_malloc(
308                 BDB_INDICES * sizeof(struct bdb_db_info *) );
309
310         /* open (and create) main database */
311         for( i = 0; bdbi_databases[i].name; i++ ) {
312                 struct bdb_db_info *db;
313
314                 db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
315
316                 rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
317                 if( rc != 0 ) {
318 #ifdef NEW_LOGGING
319                         LDAP_LOG( BACK_BDB, ERR, 
320                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n", 
321                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
322 #else
323                         Debug( LDAP_DEBUG_ANY,
324                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n",
325                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
326 #endif
327                         return rc;
328                 }
329
330                 if( i == BDB_ID2ENTRY ) {
331                         rc = db->bdi_db->set_bt_compare( db->bdi_db,
332                                 bdb_bt_compare );
333                         rc = db->bdi_db->set_pagesize( db->bdi_db,
334                                 BDB_ID2ENTRY_PAGESIZE );
335                 } else {
336 #ifdef BDB_HIER
337                         rc = db->bdi_db->set_bt_compare( db->bdi_db,
338                                 bdb_bt_compare );
339 #else
340                         rc = db->bdi_db->set_flags( db->bdi_db, 
341                                 DB_DUP | DB_DUPSORT );
342                         rc = db->bdi_db->set_dup_compare( db->bdi_db,
343                                 bdb_bt_compare );
344 #endif
345                         rc = db->bdi_db->set_pagesize( db->bdi_db,
346                                 BDB_PAGESIZE );
347                 }
348
349 #ifdef HAVE_EBCDIC
350                 strcpy( path, bdbi_databases[i].file );
351                 __atoe( path );
352                 rc = DB_OPEN( db->bdi_db, 
353                         path,
354                 /*      bdbi_databases[i].name, */ NULL,
355                         bdbi_databases[i].type,
356                         bdbi_databases[i].flags | flags,
357                         bdb->bi_dbenv_mode );
358 #else
359                 rc = DB_OPEN( db->bdi_db, 
360                         bdbi_databases[i].file,
361                 /*      bdbi_databases[i].name, */ NULL,
362                         bdbi_databases[i].type,
363                         bdbi_databases[i].flags | flags,
364                         bdb->bi_dbenv_mode );
365 #endif
366
367                 if( rc != 0 ) {
368 #ifdef NEW_LOGGING
369                         LDAP_LOG( BACK_BDB, ERR, 
370                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n", 
371                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
372 #else
373                         Debug( LDAP_DEBUG_ANY,
374                                 "bdb_db_open: db_open(%s) failed: %s (%d)\n",
375                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
376 #endif
377                         return rc;
378                 }
379
380                 db->bdi_name = bdbi_databases[i].name;
381                 bdb->bi_databases[i] = db;
382         }
383
384         bdb->bi_databases[i] = NULL;
385         bdb->bi_ndatabases = i;
386
387         /* get nextid */
388         rc = bdb_last_id( be, NULL );
389         if( rc != 0 ) {
390 #ifdef NEW_LOGGING
391                         LDAP_LOG( BACK_BDB, ERR, 
392                                 "bdb_db_open: last_id(%s) failed: %s (%d)\n", 
393                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
394 #else
395                 Debug( LDAP_DEBUG_ANY,
396                         "bdb_db_open: last_id(%s) failed: %s (%d)\n",
397                         bdb->bi_dbenv_home, db_strerror(rc), rc );
398 #endif
399                 return rc;
400         }
401
402         /* <insert> open (and create) index databases */
403 #ifdef BDB_HIER
404         rc = bdb_build_tree( be );
405 #endif
406         return 0;
407 }
408
409 static int
410 bdb_db_close( BackendDB *be )
411 {
412         int rc;
413         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
414         struct bdb_db_info *db;
415 #ifdef SLAP_IDL_CACHE
416         bdb_idl_cache_entry_t *entry, *next_entry;
417 #endif
418
419         while( bdb->bi_ndatabases-- ) {
420                 db = bdb->bi_databases[bdb->bi_ndatabases];
421                 rc = db->bdi_db->close( db->bdi_db, 0 );
422                 /* Lower numbered names are not strdup'd */
423                 if( bdb->bi_ndatabases >= BDB_NDB )
424                         free( db->bdi_name );
425                 free( db );
426         }
427         free( bdb->bi_databases );
428         bdb_attr_index_destroy( bdb->bi_attrs );
429
430         bdb_cache_release_all (&bdb->bi_cache);
431
432 #ifdef SLAP_IDL_CACHE
433         ldap_pvt_thread_mutex_lock ( &bdb->bi_idl_tree_mutex );
434         entry = bdb->bi_idl_lru_head;
435         while ( entry != NULL ) {
436                 next_entry = entry->idl_lru_next;
437                 free( entry->idl );
438                 free( entry->kstr.bv_val );
439                 free( entry );
440                 entry = next_entry;
441         }
442         ldap_pvt_thread_mutex_unlock ( &bdb->bi_idl_tree_mutex );
443 #endif
444
445         return 0;
446 }
447
448 static int
449 bdb_db_destroy( BackendDB *be )
450 {
451         int rc;
452         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
453
454         /* close db environment */
455         if( bdb->bi_dbenv ) {
456                 /* force a checkpoint */
457                 rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE );
458                 if( rc != 0 ) {
459 #ifdef NEW_LOGGING
460                         LDAP_LOG( BACK_BDB, ERR, 
461                                 "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
462                                 db_strerror(rc), rc, 0 );
463 #else
464                         Debug( LDAP_DEBUG_ANY,
465                                 "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
466                                 db_strerror(rc), rc, 0 );
467 #endif
468                 }
469
470                 bdb_cache_release_all (&bdb->bi_cache);
471
472                 rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
473                 bdb->bi_dbenv = NULL;
474                 if( rc != 0 ) {
475 #ifdef NEW_LOGGING
476                         LDAP_LOG( BACK_BDB, ERR, 
477                                 "bdb_db_destroy: close failed: %s (%d)\n", 
478                                 db_strerror(rc), rc, 0 );
479 #else
480                         Debug( LDAP_DEBUG_ANY,
481                                 "bdb_db_destroy: close failed: %s (%d)\n",
482                                 db_strerror(rc), rc, 0 );
483 #endif
484                         return rc;
485                 }
486         }
487
488         if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
489
490 #ifdef BDB_HIER
491         ldap_pvt_thread_rdwr_destroy( &bdb->bi_tree_rdwr );
492 #endif
493         ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
494         ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
495         ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
496         ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
497
498         ch_free( bdb );
499         be->be_private = NULL;
500
501         return 0;
502 }
503
504 #ifdef SLAPD_BDB_DYNAMIC
505 int back_bdb_LTX_init_module( int argc, char *argv[] ) {
506         BackendInfo bi;
507
508         memset( &bi, '\0', sizeof(bi) );
509         bi.bi_type = "bdb";
510         bi.bi_init = bdb_initialize;
511
512         backend_add( &bi );
513         return 0;
514 }
515 #endif /* SLAPD_BDB_DYNAMIC */
516
517 int
518 bdb_initialize(
519         BackendInfo     *bi
520 )
521 {
522         static char *controls[] = {
523                 LDAP_CONTROL_MANAGEDSAIT,
524                 LDAP_CONTROL_NOOP,
525                 LDAP_CONTROL_PAGEDRESULTS,
526                 LDAP_CONTROL_VALUESRETURNFILTER,
527 #ifdef LDAP_CONTROL_SUBENTRIES
528                 LDAP_CONTROL_SUBENTRIES,
529 #endif
530 #ifdef LDAP_CLIENT_UPDATE
531                 LDAP_CONTROL_CLIENT_UPDATE,
532 #endif
533                 NULL
534         };
535
536         bi->bi_controls = controls;
537
538         /* initialize the underlying database system */
539 #ifdef NEW_LOGGING
540         LDAP_LOG( BACK_BDB, ENTRY, "bdb_db_initialize\n", 0, 0, 0 );
541 #else
542         Debug( LDAP_DEBUG_TRACE, "bdb_initialize: initialize BDB backend\n",
543                 0, 0, 0 );
544 #endif
545
546         {       /* version check */
547                 int major, minor, patch;
548                 char *version = db_version( &major, &minor, &patch );
549 #ifdef HAVE_EBCDIC
550                 char v2[1024];
551
552                 /* All our stdio does an ASCII to EBCDIC conversion on
553                  * the output. Strings from the BDB library are already
554                  * in EBCDIC; we have to go back and forth...
555                  */
556                 strcpy( v2, version );
557                 __etoa( v2 );
558                 version = v2;
559 #endif
560
561                 if( major != DB_VERSION_MAJOR ||
562                         minor != DB_VERSION_MINOR ||
563                         patch < DB_VERSION_PATCH )
564                 {
565 #ifdef NEW_LOGGING
566                         LDAP_LOG( BACK_BDB, ERR, 
567                                 "bdb_db_initialize: version mismatch: "
568                                 "\texpected: %s \tgot: %s\n", DB_VERSION_STRING, version, 0 );
569 #else
570                         Debug( LDAP_DEBUG_ANY,
571                                 "bdb_initialize: version mismatch\n"
572                                 "\texpected: " DB_VERSION_STRING "\n"
573                                 "\tgot: %s \n", version, 0, 0 );
574 #endif
575                 }
576
577 #ifdef NEW_LOGGING
578                 LDAP_LOG( BACK_BDB, DETAIL1, 
579                         "bdb_db_initialize: %s\n", version, 0, 0 );
580 #else
581                 Debug( LDAP_DEBUG_ANY, "bdb_initialize: %s\n",
582                         version, 0, 0 );
583 #endif
584         }
585
586         db_env_set_func_free( ber_memfree );
587         db_env_set_func_malloc( (db_malloc *)ber_memalloc );
588         db_env_set_func_realloc( (db_realloc *)ber_memrealloc );
589 #ifndef NO_THREAD
590         /* This is a no-op on a NO_THREAD build. Leave the default
591          * alone so that BDB will sleep on interprocess conflicts.
592          */
593         db_env_set_func_yield( ldap_pvt_thread_yield );
594 #endif
595
596         {
597                 static char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
598
599                 bdb_uuid.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ));
600                 bdb_uuid.bv_val = uuidbuf;
601         }
602
603         bi->bi_open = 0;
604         bi->bi_close = 0;
605         bi->bi_config = 0;
606         bi->bi_destroy = 0;
607
608         bi->bi_db_init = bdb_db_init;
609         bi->bi_db_config = bdb_db_config;
610         bi->bi_db_open = bdb_db_open;
611         bi->bi_db_close = bdb_db_close;
612         bi->bi_db_destroy = bdb_db_destroy;
613
614         bi->bi_op_add = bdb_add;
615         bi->bi_op_bind = bdb_bind;
616         bi->bi_op_compare = bdb_compare;
617         bi->bi_op_delete = bdb_delete;
618         bi->bi_op_modify = bdb_modify;
619         bi->bi_op_modrdn = bdb_modrdn;
620         bi->bi_op_search = bdb_search;
621
622         bi->bi_op_unbind = 0;
623         bi->bi_op_abandon = 0;
624
625         bi->bi_extended = bdb_extended;
626
627 #if 1
628         /*
629          * these routines (and their callers) are not yet designed
630          * to work with transaction.  Using them may cause deadlock.
631          */
632         bi->bi_acl_group = bdb_group;
633         bi->bi_acl_attribute = bdb_attribute;
634 #else
635         bi->bi_acl_group = 0;
636         bi->bi_acl_attribute = 0;
637 #endif
638
639         bi->bi_chk_referrals = bdb_referrals;
640         bi->bi_operational = bdb_operational;
641         bi->bi_has_subordinates = bdb_hasSubordinates;
642         bi->bi_entry_release_rw = bdb_entry_release;
643
644         /*
645          * hooks for slap tools
646          */
647         bi->bi_tool_entry_open = bdb_tool_entry_open;
648         bi->bi_tool_entry_close = bdb_tool_entry_close;
649         bi->bi_tool_entry_first = bdb_tool_entry_next;
650         bi->bi_tool_entry_next = bdb_tool_entry_next;
651         bi->bi_tool_entry_get = bdb_tool_entry_get;
652         bi->bi_tool_entry_put = bdb_tool_entry_put;
653         bi->bi_tool_entry_reindex = bdb_tool_entry_reindex;
654         bi->bi_tool_sync = 0;
655
656         bi->bi_connection_init = 0;
657         bi->bi_connection_destroy = 0;
658
659         return 0;
660 }