Home | History | Annotate | Line # | Download | only in back-mdb
init.c revision 1.1.1.3.4.1
      1  1.1.1.3.4.1    martin /*	$NetBSD: init.c,v 1.1.1.3.4.1 2020/04/13 07:56:18 martin Exp $	*/
      2          1.1      tron 
      3          1.1      tron /* init.c - initialize mdb backend */
      4          1.1      tron /* $OpenLDAP$ */
      5          1.1      tron /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6          1.1      tron  *
      7  1.1.1.3.4.1    martin  * Copyright 2000-2019 The OpenLDAP Foundation.
      8          1.1      tron  * All rights reserved.
      9          1.1      tron  *
     10          1.1      tron  * Redistribution and use in source and binary forms, with or without
     11          1.1      tron  * modification, are permitted only as authorized by the OpenLDAP
     12          1.1      tron  * Public License.
     13          1.1      tron  *
     14          1.1      tron  * A copy of this license is available in the file LICENSE in the
     15          1.1      tron  * top-level directory of the distribution or, alternatively, at
     16          1.1      tron  * <http://www.OpenLDAP.org/license.html>.
     17          1.1      tron  */
     18          1.1      tron 
     19      1.1.1.2  christos #include <sys/cdefs.h>
     20  1.1.1.3.4.1    martin __RCSID("$NetBSD: init.c,v 1.1.1.3.4.1 2020/04/13 07:56:18 martin Exp $");
     21      1.1.1.2  christos 
     22          1.1      tron #include "portable.h"
     23          1.1      tron 
     24          1.1      tron #include <stdio.h>
     25          1.1      tron #include <ac/string.h>
     26          1.1      tron #include <ac/unistd.h>
     27          1.1      tron #include <ac/stdlib.h>
     28          1.1      tron #include <ac/errno.h>
     29          1.1      tron #include <sys/stat.h>
     30          1.1      tron #include "back-mdb.h"
     31          1.1      tron #include <lutil.h>
     32          1.1      tron #include <ldap_rq.h>
     33          1.1      tron #include "config.h"
     34          1.1      tron 
     35          1.1      tron static const struct berval mdmi_databases[] = {
     36          1.1      tron 	BER_BVC("ad2i"),
     37          1.1      tron 	BER_BVC("dn2i"),
     38          1.1      tron 	BER_BVC("id2e"),
     39          1.1      tron 	BER_BVNULL
     40          1.1      tron };
     41          1.1      tron 
     42          1.1      tron static int
     43          1.1      tron mdb_id_compare( const MDB_val *a, const MDB_val *b )
     44          1.1      tron {
     45          1.1      tron 	return *(ID *)a->mv_data < *(ID *)b->mv_data ? -1 : *(ID *)a->mv_data > *(ID *)b->mv_data;
     46          1.1      tron }
     47          1.1      tron 
     48          1.1      tron static int
     49          1.1      tron mdb_db_init( BackendDB *be, ConfigReply *cr )
     50          1.1      tron {
     51          1.1      tron 	struct mdb_info	*mdb;
     52          1.1      tron 	int rc;
     53          1.1      tron 
     54          1.1      tron 	Debug( LDAP_DEBUG_TRACE,
     55          1.1      tron 		LDAP_XSTRING(mdb_db_init) ": Initializing mdb database\n",
     56          1.1      tron 		0, 0, 0 );
     57          1.1      tron 
     58          1.1      tron 	/* allocate backend-database-specific stuff */
     59          1.1      tron 	mdb = (struct mdb_info *) ch_calloc( 1, sizeof(struct mdb_info) );
     60          1.1      tron 
     61          1.1      tron 	/* DBEnv parameters */
     62          1.1      tron 	mdb->mi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
     63          1.1      tron 	mdb->mi_dbenv_flags = 0;
     64          1.1      tron 	mdb->mi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
     65          1.1      tron 
     66          1.1      tron 	mdb->mi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
     67          1.1      tron 	mdb->mi_search_stack = NULL;
     68          1.1      tron 
     69          1.1      tron 	mdb->mi_mapsize = DEFAULT_MAPSIZE;
     70      1.1.1.2  christos 	mdb->mi_rtxn_size = DEFAULT_RTXN_SIZE;
     71          1.1      tron 
     72          1.1      tron 	be->be_private = mdb;
     73          1.1      tron 	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
     74          1.1      tron 
     75          1.1      tron #ifndef MDB_MULTIPLE_SUFFIXES
     76          1.1      tron 	SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_ONE_SUFFIX;
     77          1.1      tron #endif
     78          1.1      tron 
     79          1.1      tron 	rc = mdb_monitor_db_init( be );
     80          1.1      tron 
     81          1.1      tron 	return rc;
     82          1.1      tron }
     83          1.1      tron 
     84          1.1      tron static int
     85          1.1      tron mdb_db_close( BackendDB *be, ConfigReply *cr );
     86          1.1      tron 
     87          1.1      tron static int
     88          1.1      tron mdb_db_open( BackendDB *be, ConfigReply *cr )
     89          1.1      tron {
     90          1.1      tron 	int rc, i;
     91          1.1      tron 	struct mdb_info *mdb = (struct mdb_info *) be->be_private;
     92          1.1      tron 	struct stat stat1;
     93          1.1      tron 	uint32_t flags;
     94          1.1      tron 	char *dbhome;
     95          1.1      tron 	MDB_txn *txn;
     96          1.1      tron 
     97          1.1      tron 	if ( be->be_suffix == NULL ) {
     98          1.1      tron 		Debug( LDAP_DEBUG_ANY,
     99          1.1      tron 			LDAP_XSTRING(mdb_db_open) ": need suffix.\n",
    100          1.1      tron 			1, 0, 0 );
    101          1.1      tron 		return -1;
    102          1.1      tron 	}
    103          1.1      tron 
    104          1.1      tron 	Debug( LDAP_DEBUG_ARGS,
    105          1.1      tron 		LDAP_XSTRING(mdb_db_open) ": \"%s\"\n",
    106          1.1      tron 		be->be_suffix[0].bv_val, 0, 0 );
    107          1.1      tron 
    108          1.1      tron 	/* Check existence of dbenv_home. Any error means trouble */
    109          1.1      tron 	rc = stat( mdb->mi_dbenv_home, &stat1 );
    110          1.1      tron 	if( rc != 0 ) {
    111          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    112          1.1      tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    113          1.1      tron 			"cannot access database directory \"%s\" (%d).\n",
    114          1.1      tron 			be->be_suffix[0].bv_val, mdb->mi_dbenv_home, errno );
    115          1.1      tron 		return -1;
    116          1.1      tron 	}
    117          1.1      tron 
    118          1.1      tron 	/* mdb is always clean */
    119          1.1      tron 	be->be_flags |= SLAP_DBFLAG_CLEAN;
    120          1.1      tron 
    121          1.1      tron 	rc = mdb_env_create( &mdb->mi_dbenv );
    122          1.1      tron 	if( rc != 0 ) {
    123          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    124          1.1      tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    125          1.1      tron 			"mdb_env_create failed: %s (%d).\n",
    126          1.1      tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    127          1.1      tron 		goto fail;
    128          1.1      tron 	}
    129          1.1      tron 
    130          1.1      tron 	if ( mdb->mi_readers ) {
    131          1.1      tron 		rc = mdb_env_set_maxreaders( mdb->mi_dbenv, mdb->mi_readers );
    132          1.1      tron 		if( rc != 0 ) {
    133          1.1      tron 			Debug( LDAP_DEBUG_ANY,
    134          1.1      tron 				LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    135          1.1      tron 				"mdb_env_set_maxreaders failed: %s (%d).\n",
    136          1.1      tron 				be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    137          1.1      tron 			goto fail;
    138          1.1      tron 		}
    139          1.1      tron 	}
    140          1.1      tron 
    141          1.1      tron 	rc = mdb_env_set_mapsize( mdb->mi_dbenv, mdb->mi_mapsize );
    142          1.1      tron 	if( rc != 0 ) {
    143          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    144          1.1      tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    145          1.1      tron 			"mdb_env_set_mapsize failed: %s (%d).\n",
    146          1.1      tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    147          1.1      tron 		goto fail;
    148          1.1      tron 	}
    149          1.1      tron 
    150          1.1      tron 	rc = mdb_env_set_maxdbs( mdb->mi_dbenv, MDB_INDICES );
    151          1.1      tron 	if( rc != 0 ) {
    152          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    153          1.1      tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    154          1.1      tron 			"mdb_env_set_maxdbs failed: %s (%d).\n",
    155          1.1      tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    156          1.1      tron 		goto fail;
    157          1.1      tron 	}
    158          1.1      tron 
    159          1.1      tron #ifdef HAVE_EBCDIC
    160          1.1      tron 	strcpy( path, mdb->mi_dbenv_home );
    161          1.1      tron 	__atoe( path );
    162          1.1      tron 	dbhome = path;
    163          1.1      tron #else
    164          1.1      tron 	dbhome = mdb->mi_dbenv_home;
    165          1.1      tron #endif
    166          1.1      tron 
    167          1.1      tron 	Debug( LDAP_DEBUG_TRACE,
    168          1.1      tron 		LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    169          1.1      tron 		"dbenv_open(%s).\n",
    170          1.1      tron 		be->be_suffix[0].bv_val, mdb->mi_dbenv_home, 0);
    171          1.1      tron 
    172          1.1      tron 	flags = mdb->mi_dbenv_flags;
    173          1.1      tron 
    174          1.1      tron 	if ( slapMode & SLAP_TOOL_QUICK )
    175          1.1      tron 		flags |= MDB_NOSYNC|MDB_WRITEMAP;
    176          1.1      tron 
    177          1.1      tron 	if ( slapMode & SLAP_TOOL_READONLY)
    178          1.1      tron 		flags |= MDB_RDONLY;
    179          1.1      tron 
    180          1.1      tron 	rc = mdb_env_open( mdb->mi_dbenv, dbhome,
    181          1.1      tron 			flags, mdb->mi_dbenv_mode );
    182          1.1      tron 
    183          1.1      tron 	if ( rc ) {
    184          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    185      1.1.1.2  christos 			LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened: %s (%d). "
    186          1.1      tron 			"Restore from backup!\n",
    187      1.1.1.2  christos 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    188          1.1      tron 		goto fail;
    189          1.1      tron 	}
    190          1.1      tron 
    191          1.1      tron 	rc = mdb_txn_begin( mdb->mi_dbenv, NULL, flags & MDB_RDONLY, &txn );
    192          1.1      tron 	if ( rc ) {
    193          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    194      1.1.1.2  christos 			LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened: %s (%d). "
    195          1.1      tron 			"Restore from backup!\n",
    196      1.1.1.2  christos 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    197          1.1      tron 		goto fail;
    198          1.1      tron 	}
    199          1.1      tron 
    200          1.1      tron 	/* open (and create) main databases */
    201          1.1      tron 	for( i = 0; mdmi_databases[i].bv_val; i++ ) {
    202          1.1      tron 		flags = MDB_INTEGERKEY;
    203          1.1      tron 		if( i == MDB_ID2ENTRY ) {
    204          1.1      tron 			if ( !(slapMode & (SLAP_TOOL_READMAIN|SLAP_TOOL_READONLY) ))
    205          1.1      tron 				flags |= MDB_CREATE;
    206          1.1      tron 		} else {
    207          1.1      tron 			if ( i == MDB_DN2ID )
    208          1.1      tron 				flags |= MDB_DUPSORT;
    209          1.1      tron 			if ( !(slapMode & SLAP_TOOL_READONLY) )
    210          1.1      tron 				flags |= MDB_CREATE;
    211          1.1      tron 		}
    212          1.1      tron 
    213          1.1      tron 		rc = mdb_dbi_open( txn,
    214          1.1      tron 			mdmi_databases[i].bv_val,
    215          1.1      tron 			flags,
    216          1.1      tron 			&mdb->mi_dbis[i] );
    217          1.1      tron 
    218          1.1      tron 		if ( rc != 0 ) {
    219          1.1      tron 			snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
    220          1.1      tron 				"mdb_dbi_open(%s/%s) failed: %s (%d).",
    221          1.1      tron 				be->be_suffix[0].bv_val,
    222          1.1      tron 				mdb->mi_dbenv_home, mdmi_databases[i].bv_val,
    223          1.1      tron 				mdb_strerror(rc), rc );
    224          1.1      tron 			Debug( LDAP_DEBUG_ANY,
    225          1.1      tron 				LDAP_XSTRING(mdb_db_open) ": %s\n",
    226          1.1      tron 				cr->msg, 0, 0 );
    227          1.1      tron 			goto fail;
    228          1.1      tron 		}
    229          1.1      tron 
    230          1.1      tron 		if ( i == MDB_ID2ENTRY )
    231          1.1      tron 			mdb_set_compare( txn, mdb->mi_dbis[i], mdb_id_compare );
    232          1.1      tron 		else if ( i == MDB_DN2ID ) {
    233          1.1      tron 			MDB_cursor *mc;
    234          1.1      tron 			MDB_val key, data;
    235          1.1      tron 			mdb_set_dupsort( txn, mdb->mi_dbis[i], mdb_dup_compare );
    236          1.1      tron 			/* check for old dn2id format */
    237          1.1      tron 			rc = mdb_cursor_open( txn, mdb->mi_dbis[i], &mc );
    238          1.1      tron 			/* first record is always ID 0 */
    239          1.1      tron 			rc = mdb_cursor_get( mc, &key, &data, MDB_FIRST );
    240          1.1      tron 			if ( rc == 0 ) {
    241          1.1      tron 				rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT );
    242          1.1      tron 				if ( rc == 0 ) {
    243          1.1      tron 					int len;
    244          1.1      tron 					unsigned char *ptr;
    245          1.1      tron 					ptr = data.mv_data;
    246          1.1      tron 					len = (ptr[0] & 0x7f) << 8 | ptr[1];
    247          1.1      tron 					if (data.mv_size < 2*len + 4 + 2*sizeof(ID)) {
    248          1.1      tron 						snprintf( cr->msg, sizeof(cr->msg),
    249          1.1      tron 						"database \"%s\": DN index needs upgrade, "
    250          1.1      tron 						"run \"slapindex entryDN\".",
    251          1.1      tron 						be->be_suffix[0].bv_val );
    252          1.1      tron 						Debug( LDAP_DEBUG_ANY,
    253          1.1      tron 							LDAP_XSTRING(mdb_db_open) ": %s\n",
    254          1.1      tron 							cr->msg, 0, 0 );
    255          1.1      tron 						if ( !(slapMode & SLAP_TOOL_READMAIN ))
    256          1.1      tron 							rc = LDAP_OTHER;
    257          1.1      tron 						mdb->mi_flags |= MDB_NEED_UPGRADE;
    258          1.1      tron 					}
    259          1.1      tron 				}
    260          1.1      tron 			}
    261          1.1      tron 			mdb_cursor_close( mc );
    262          1.1      tron 			if ( rc == LDAP_OTHER )
    263          1.1      tron 				goto fail;
    264          1.1      tron 		}
    265          1.1      tron 	}
    266          1.1      tron 
    267          1.1      tron 	rc = mdb_ad_read( mdb, txn );
    268          1.1      tron 	if ( rc ) {
    269          1.1      tron 		mdb_txn_abort( txn );
    270          1.1      tron 		goto fail;
    271          1.1      tron 	}
    272          1.1      tron 
    273      1.1.1.2  christos 	/* slapcat doesn't need indexes. avoid a failure if
    274      1.1.1.2  christos 	 * a configured index wasn't created yet.
    275      1.1.1.2  christos 	 */
    276      1.1.1.2  christos 	if ( !(slapMode & SLAP_TOOL_READONLY) ) {
    277      1.1.1.2  christos 		rc = mdb_attr_dbs_open( be, txn, cr );
    278      1.1.1.2  christos 		if ( rc ) {
    279      1.1.1.2  christos 			mdb_txn_abort( txn );
    280      1.1.1.2  christos 			goto fail;
    281      1.1.1.2  christos 		}
    282          1.1      tron 	}
    283          1.1      tron 
    284          1.1      tron 	rc = mdb_txn_commit(txn);
    285          1.1      tron 	if ( rc != 0 ) {
    286          1.1      tron 		Debug( LDAP_DEBUG_ANY,
    287          1.1      tron 			LDAP_XSTRING(mdb_db_open) ": database %s: "
    288          1.1      tron 			"txn_commit failed: %s (%d)\n",
    289          1.1      tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    290          1.1      tron 		goto fail;
    291          1.1      tron 	}
    292          1.1      tron 
    293          1.1      tron 	/* monitor setup */
    294          1.1      tron 	rc = mdb_monitor_db_open( be );
    295          1.1      tron 	if ( rc != 0 ) {
    296          1.1      tron 		goto fail;
    297          1.1      tron 	}
    298          1.1      tron 
    299          1.1      tron 	mdb->mi_flags |= MDB_IS_OPEN;
    300          1.1      tron 
    301          1.1      tron 	return 0;
    302          1.1      tron 
    303          1.1      tron fail:
    304          1.1      tron 	mdb_db_close( be, NULL );
    305          1.1      tron 	return rc;
    306          1.1      tron }
    307          1.1      tron 
    308          1.1      tron static int
    309          1.1      tron mdb_db_close( BackendDB *be, ConfigReply *cr )
    310          1.1      tron {
    311          1.1      tron 	int rc;
    312          1.1      tron 	struct mdb_info *mdb = (struct mdb_info *) be->be_private;
    313          1.1      tron 
    314          1.1      tron 	/* monitor handling */
    315          1.1      tron 	(void)mdb_monitor_db_close( be );
    316          1.1      tron 
    317          1.1      tron 	mdb->mi_flags &= ~MDB_IS_OPEN;
    318          1.1      tron 
    319          1.1      tron 	if( mdb->mi_dbenv ) {
    320          1.1      tron 		mdb_reader_flush( mdb->mi_dbenv );
    321          1.1      tron 	}
    322          1.1      tron 
    323          1.1      tron 	if ( mdb->mi_dbenv ) {
    324          1.1      tron 		if ( mdb->mi_dbis[0] ) {
    325          1.1      tron 			int i;
    326          1.1      tron 
    327          1.1      tron 			mdb_attr_dbs_close( mdb );
    328          1.1      tron 			for ( i=0; i<MDB_NDB; i++ )
    329          1.1      tron 				mdb_dbi_close( mdb->mi_dbenv, mdb->mi_dbis[i] );
    330          1.1      tron 
    331          1.1      tron 			/* force a sync, but not if we were ReadOnly,
    332          1.1      tron 			 * and not in Quick mode.
    333          1.1      tron 			 */
    334          1.1      tron 			if (!(slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY))) {
    335          1.1      tron 				rc = mdb_env_sync( mdb->mi_dbenv, 1 );
    336          1.1      tron 				if( rc != 0 ) {
    337          1.1      tron 					Debug( LDAP_DEBUG_ANY,
    338          1.1      tron 						"mdb_db_close: database \"%s\": "
    339          1.1      tron 						"mdb_env_sync failed: %s (%d).\n",
    340          1.1      tron 						be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    341          1.1      tron 				}
    342          1.1      tron 			}
    343          1.1      tron 		}
    344          1.1      tron 
    345          1.1      tron 		mdb_env_close( mdb->mi_dbenv );
    346          1.1      tron 		mdb->mi_dbenv = NULL;
    347          1.1      tron 	}
    348          1.1      tron 
    349          1.1      tron 	return 0;
    350          1.1      tron }
    351          1.1      tron 
    352          1.1      tron static int
    353          1.1      tron mdb_db_destroy( BackendDB *be, ConfigReply *cr )
    354          1.1      tron {
    355          1.1      tron 	struct mdb_info *mdb = (struct mdb_info *) be->be_private;
    356          1.1      tron 
    357          1.1      tron 	/* stop and remove checkpoint task */
    358          1.1      tron 	if ( mdb->mi_txn_cp_task ) {
    359          1.1      tron 		struct re_s *re = mdb->mi_txn_cp_task;
    360          1.1      tron 		mdb->mi_txn_cp_task = NULL;
    361          1.1      tron 		ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
    362          1.1      tron 		if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
    363          1.1      tron 			ldap_pvt_runqueue_stoptask( &slapd_rq, re );
    364          1.1      tron 		ldap_pvt_runqueue_remove( &slapd_rq, re );
    365          1.1      tron 		ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
    366          1.1      tron 	}
    367          1.1      tron 
    368          1.1      tron 	/* monitor handling */
    369          1.1      tron 	(void)mdb_monitor_db_destroy( be );
    370          1.1      tron 
    371          1.1      tron 	if( mdb->mi_dbenv_home ) ch_free( mdb->mi_dbenv_home );
    372          1.1      tron 
    373          1.1      tron 	mdb_attr_index_destroy( mdb );
    374          1.1      tron 
    375          1.1      tron 	ch_free( mdb );
    376          1.1      tron 	be->be_private = NULL;
    377          1.1      tron 
    378          1.1      tron 	return 0;
    379          1.1      tron }
    380          1.1      tron 
    381          1.1      tron int
    382          1.1      tron mdb_back_initialize(
    383          1.1      tron 	BackendInfo	*bi )
    384          1.1      tron {
    385          1.1      tron 	int rc;
    386          1.1      tron 
    387          1.1      tron 	static char *controls[] = {
    388          1.1      tron 		LDAP_CONTROL_ASSERT,
    389          1.1      tron 		LDAP_CONTROL_MANAGEDSAIT,
    390          1.1      tron 		LDAP_CONTROL_NOOP,
    391          1.1      tron 		LDAP_CONTROL_PAGEDRESULTS,
    392          1.1      tron 		LDAP_CONTROL_PRE_READ,
    393          1.1      tron 		LDAP_CONTROL_POST_READ,
    394          1.1      tron 		LDAP_CONTROL_SUBENTRIES,
    395          1.1      tron 		LDAP_CONTROL_X_PERMISSIVE_MODIFY,
    396          1.1      tron #ifdef LDAP_X_TXN
    397          1.1      tron 		LDAP_CONTROL_X_TXN_SPEC,
    398          1.1      tron #endif
    399          1.1      tron 		NULL
    400          1.1      tron 	};
    401          1.1      tron 
    402          1.1      tron 	/* initialize the underlying database system */
    403          1.1      tron 	Debug( LDAP_DEBUG_TRACE,
    404          1.1      tron 		LDAP_XSTRING(mdb_back_initialize) ": initialize "
    405          1.1      tron 		MDB_UCTYPE " backend\n", 0, 0, 0 );
    406          1.1      tron 
    407          1.1      tron 	bi->bi_flags |=
    408          1.1      tron 		SLAP_BFLAG_INCREMENT |
    409          1.1      tron 		SLAP_BFLAG_SUBENTRIES |
    410          1.1      tron 		SLAP_BFLAG_ALIASES |
    411          1.1      tron 		SLAP_BFLAG_REFERRALS;
    412          1.1      tron 
    413          1.1      tron 	bi->bi_controls = controls;
    414          1.1      tron 
    415          1.1      tron 	{	/* version check */
    416          1.1      tron 		int major, minor, patch, ver;
    417          1.1      tron 		char *version = mdb_version( &major, &minor, &patch );
    418          1.1      tron #ifdef HAVE_EBCDIC
    419          1.1      tron 		char v2[1024];
    420          1.1      tron 
    421          1.1      tron 		/* All our stdio does an ASCII to EBCDIC conversion on
    422          1.1      tron 		 * the output. Strings from the MDB library are already
    423          1.1      tron 		 * in EBCDIC; we have to go back and forth...
    424          1.1      tron 		 */
    425          1.1      tron 		strcpy( v2, version );
    426          1.1      tron 		__etoa( v2 );
    427          1.1      tron 		version = v2;
    428          1.1      tron #endif
    429          1.1      tron 		ver = (major << 24) | (minor << 16) | patch;
    430          1.1      tron 		if( ver != MDB_VERSION_FULL ) {
    431          1.1      tron 			/* fail if a versions don't match */
    432          1.1      tron 			Debug( LDAP_DEBUG_ANY,
    433          1.1      tron 				LDAP_XSTRING(mdb_back_initialize) ": "
    434          1.1      tron 				"MDB library version mismatch:"
    435          1.1      tron 				" expected " MDB_VERSION_STRING ","
    436          1.1      tron 				" got %s\n", version, 0, 0 );
    437          1.1      tron 			return -1;
    438          1.1      tron 		}
    439          1.1      tron 
    440          1.1      tron 		Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_back_initialize)
    441          1.1      tron 			": %s\n", version, 0, 0 );
    442          1.1      tron 	}
    443          1.1      tron 
    444          1.1      tron 	bi->bi_open = 0;
    445          1.1      tron 	bi->bi_close = 0;
    446          1.1      tron 	bi->bi_config = 0;
    447          1.1      tron 	bi->bi_destroy = 0;
    448          1.1      tron 
    449          1.1      tron 	bi->bi_db_init = mdb_db_init;
    450          1.1      tron 	bi->bi_db_config = config_generic_wrapper;
    451          1.1      tron 	bi->bi_db_open = mdb_db_open;
    452          1.1      tron 	bi->bi_db_close = mdb_db_close;
    453          1.1      tron 	bi->bi_db_destroy = mdb_db_destroy;
    454          1.1      tron 
    455          1.1      tron 	bi->bi_op_add = mdb_add;
    456          1.1      tron 	bi->bi_op_bind = mdb_bind;
    457          1.1      tron 	bi->bi_op_compare = mdb_compare;
    458          1.1      tron 	bi->bi_op_delete = mdb_delete;
    459          1.1      tron 	bi->bi_op_modify = mdb_modify;
    460          1.1      tron 	bi->bi_op_modrdn = mdb_modrdn;
    461          1.1      tron 	bi->bi_op_search = mdb_search;
    462          1.1      tron 
    463          1.1      tron 	bi->bi_op_unbind = 0;
    464          1.1      tron 
    465          1.1      tron 	bi->bi_extended = mdb_extended;
    466          1.1      tron 
    467          1.1      tron 	bi->bi_chk_referrals = 0;
    468          1.1      tron 	bi->bi_operational = mdb_operational;
    469          1.1      tron 
    470          1.1      tron 	bi->bi_has_subordinates = mdb_hasSubordinates;
    471          1.1      tron 	bi->bi_entry_release_rw = mdb_entry_release;
    472          1.1      tron 	bi->bi_entry_get_rw = mdb_entry_get;
    473          1.1      tron 
    474          1.1      tron 	/*
    475          1.1      tron 	 * hooks for slap tools
    476          1.1      tron 	 */
    477          1.1      tron 	bi->bi_tool_entry_open = mdb_tool_entry_open;
    478          1.1      tron 	bi->bi_tool_entry_close = mdb_tool_entry_close;
    479          1.1      tron 	bi->bi_tool_entry_first = backend_tool_entry_first;
    480          1.1      tron 	bi->bi_tool_entry_first_x = mdb_tool_entry_first_x;
    481          1.1      tron 	bi->bi_tool_entry_next = mdb_tool_entry_next;
    482          1.1      tron 	bi->bi_tool_entry_get = mdb_tool_entry_get;
    483          1.1      tron 	bi->bi_tool_entry_put = mdb_tool_entry_put;
    484          1.1      tron 	bi->bi_tool_entry_reindex = mdb_tool_entry_reindex;
    485          1.1      tron 	bi->bi_tool_sync = 0;
    486          1.1      tron 	bi->bi_tool_dn2id_get = mdb_tool_dn2id_get;
    487          1.1      tron 	bi->bi_tool_entry_modify = mdb_tool_entry_modify;
    488          1.1      tron 
    489          1.1      tron 	bi->bi_connection_init = 0;
    490          1.1      tron 	bi->bi_connection_destroy = 0;
    491          1.1      tron 
    492          1.1      tron 	rc = mdb_back_init_cf( bi );
    493          1.1      tron 
    494          1.1      tron 	return rc;
    495          1.1      tron }
    496          1.1      tron 
    497          1.1      tron #if	(SLAPD_MDB == SLAPD_MOD_DYNAMIC)
    498          1.1      tron 
    499          1.1      tron SLAP_BACKEND_INIT_MODULE( mdb )
    500          1.1      tron 
    501          1.1      tron #endif /* SLAPD_MDB == SLAPD_MOD_DYNAMIC */
    502          1.1      tron 
    503