xref: /freebsd/crypto/heimdal/lib/hdb/db3.c (revision 1c43270ada91f3473174c2bf81fba64963b7e4ac)
15e9cd1aeSAssar Westerlund /*
25e9cd1aeSAssar Westerlund  * Copyright (c) 1997 - 2001 Kungliga Tekniska H�gskolan
35e9cd1aeSAssar Westerlund  * (Royal Institute of Technology, Stockholm, Sweden).
45e9cd1aeSAssar Westerlund  * All rights reserved.
55e9cd1aeSAssar Westerlund  *
65e9cd1aeSAssar Westerlund  * Redistribution and use in source and binary forms, with or without
75e9cd1aeSAssar Westerlund  * modification, are permitted provided that the following conditions
85e9cd1aeSAssar Westerlund  * are met:
95e9cd1aeSAssar Westerlund  *
105e9cd1aeSAssar Westerlund  * 1. Redistributions of source code must retain the above copyright
115e9cd1aeSAssar Westerlund  *    notice, this list of conditions and the following disclaimer.
125e9cd1aeSAssar Westerlund  *
135e9cd1aeSAssar Westerlund  * 2. Redistributions in binary form must reproduce the above copyright
145e9cd1aeSAssar Westerlund  *    notice, this list of conditions and the following disclaimer in the
155e9cd1aeSAssar Westerlund  *    documentation and/or other materials provided with the distribution.
165e9cd1aeSAssar Westerlund  *
175e9cd1aeSAssar Westerlund  * 3. Neither the name of the Institute nor the names of its contributors
185e9cd1aeSAssar Westerlund  *    may be used to endorse or promote products derived from this software
195e9cd1aeSAssar Westerlund  *    without specific prior written permission.
205e9cd1aeSAssar Westerlund  *
215e9cd1aeSAssar Westerlund  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
225e9cd1aeSAssar Westerlund  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
235e9cd1aeSAssar Westerlund  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
245e9cd1aeSAssar Westerlund  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
255e9cd1aeSAssar Westerlund  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
265e9cd1aeSAssar Westerlund  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
275e9cd1aeSAssar Westerlund  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
285e9cd1aeSAssar Westerlund  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
295e9cd1aeSAssar Westerlund  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
305e9cd1aeSAssar Westerlund  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
315e9cd1aeSAssar Westerlund  * SUCH DAMAGE.
325e9cd1aeSAssar Westerlund  */
335e9cd1aeSAssar Westerlund 
345e9cd1aeSAssar Westerlund #include "hdb_locl.h"
355e9cd1aeSAssar Westerlund 
361c43270aSJacques Vidrine RCSID("$Id: db3.c,v 1.8.6.1 2003/08/29 16:59:39 lha Exp $");
375e9cd1aeSAssar Westerlund 
384137ff4cSJacques Vidrine #if HAVE_DB3
394137ff4cSJacques Vidrine 
401c43270aSJacques Vidrine #ifdef HAVE_DB4_DB_H
411c43270aSJacques Vidrine #include <db4/db.h>
421c43270aSJacques Vidrine #elif defined(HAVE_DB3_DB_H)
431c43270aSJacques Vidrine #include <db3/db.h>
441c43270aSJacques Vidrine #else
454137ff4cSJacques Vidrine #include <db.h>
461c43270aSJacques Vidrine #endif
474137ff4cSJacques Vidrine 
485e9cd1aeSAssar Westerlund static krb5_error_code
495e9cd1aeSAssar Westerlund DB_close(krb5_context context, HDB *db)
505e9cd1aeSAssar Westerlund {
515e9cd1aeSAssar Westerlund     DB *d = (DB*)db->db;
525e9cd1aeSAssar Westerlund     DBC *dbcp = (DBC*)db->dbc;
535e9cd1aeSAssar Westerlund 
545e9cd1aeSAssar Westerlund     dbcp->c_close(dbcp);
555e9cd1aeSAssar Westerlund     db->dbc = 0;
565e9cd1aeSAssar Westerlund     d->close(d, 0);
575e9cd1aeSAssar Westerlund     return 0;
585e9cd1aeSAssar Westerlund }
595e9cd1aeSAssar Westerlund 
605e9cd1aeSAssar Westerlund static krb5_error_code
615e9cd1aeSAssar Westerlund DB_destroy(krb5_context context, HDB *db)
625e9cd1aeSAssar Westerlund {
635e9cd1aeSAssar Westerlund     krb5_error_code ret;
645e9cd1aeSAssar Westerlund 
655e9cd1aeSAssar Westerlund     ret = hdb_clear_master_key (context, db);
665e9cd1aeSAssar Westerlund     free(db->name);
675e9cd1aeSAssar Westerlund     free(db);
685e9cd1aeSAssar Westerlund     return ret;
695e9cd1aeSAssar Westerlund }
705e9cd1aeSAssar Westerlund 
715e9cd1aeSAssar Westerlund static krb5_error_code
725e9cd1aeSAssar Westerlund DB_lock(krb5_context context, HDB *db, int operation)
735e9cd1aeSAssar Westerlund {
745e9cd1aeSAssar Westerlund     DB *d = (DB*)db->db;
755e9cd1aeSAssar Westerlund     int fd;
765e9cd1aeSAssar Westerlund     if ((*d->fd)(d, &fd))
775e9cd1aeSAssar Westerlund 	return HDB_ERR_CANT_LOCK_DB;
785e9cd1aeSAssar Westerlund     return hdb_lock(fd, operation);
795e9cd1aeSAssar Westerlund }
805e9cd1aeSAssar Westerlund 
815e9cd1aeSAssar Westerlund static krb5_error_code
825e9cd1aeSAssar Westerlund DB_unlock(krb5_context context, HDB *db)
835e9cd1aeSAssar Westerlund {
845e9cd1aeSAssar Westerlund     DB *d = (DB*)db->db;
855e9cd1aeSAssar Westerlund     int fd;
865e9cd1aeSAssar Westerlund     if ((*d->fd)(d, &fd))
875e9cd1aeSAssar Westerlund 	return HDB_ERR_CANT_LOCK_DB;
885e9cd1aeSAssar Westerlund     return hdb_unlock(fd);
895e9cd1aeSAssar Westerlund }
905e9cd1aeSAssar Westerlund 
915e9cd1aeSAssar Westerlund 
925e9cd1aeSAssar Westerlund static krb5_error_code
935e9cd1aeSAssar Westerlund DB_seq(krb5_context context, HDB *db,
945e9cd1aeSAssar Westerlund        unsigned flags, hdb_entry *entry, int flag)
955e9cd1aeSAssar Westerlund {
965e9cd1aeSAssar Westerlund     DBT key, value;
975e9cd1aeSAssar Westerlund     DBC *dbcp = db->dbc;
985e9cd1aeSAssar Westerlund     krb5_data key_data, data;
995e9cd1aeSAssar Westerlund     int code;
1005e9cd1aeSAssar Westerlund 
1015e9cd1aeSAssar Westerlund     memset(&key, 0, sizeof(DBT));
1025e9cd1aeSAssar Westerlund     memset(&value, 0, sizeof(DBT));
1035e9cd1aeSAssar Westerlund     if (db->lock(context, db, HDB_RLOCK))
1045e9cd1aeSAssar Westerlund 	return HDB_ERR_DB_INUSE;
1055e9cd1aeSAssar Westerlund     code = dbcp->c_get(dbcp, &key, &value, flag);
1065e9cd1aeSAssar Westerlund     db->unlock(context, db); /* XXX check value */
1075e9cd1aeSAssar Westerlund     if (code == DB_NOTFOUND)
1085e9cd1aeSAssar Westerlund 	return HDB_ERR_NOENTRY;
1095e9cd1aeSAssar Westerlund     if (code)
1105e9cd1aeSAssar Westerlund 	return code;
1115e9cd1aeSAssar Westerlund 
1125e9cd1aeSAssar Westerlund     key_data.data = key.data;
1135e9cd1aeSAssar Westerlund     key_data.length = key.size;
1145e9cd1aeSAssar Westerlund     data.data = value.data;
1155e9cd1aeSAssar Westerlund     data.length = value.size;
1165e9cd1aeSAssar Westerlund     if (hdb_value2entry(context, &data, entry))
1175e9cd1aeSAssar Westerlund 	return DB_seq(context, db, flags, entry, DB_NEXT);
1185e9cd1aeSAssar Westerlund     if (db->master_key_set && (flags & HDB_F_DECRYPT)) {
1195e9cd1aeSAssar Westerlund 	code = hdb_unseal_keys (context, db, entry);
1205e9cd1aeSAssar Westerlund 	if (code)
1215e9cd1aeSAssar Westerlund 	    hdb_free_entry (context, entry);
1225e9cd1aeSAssar Westerlund     }
1235e9cd1aeSAssar Westerlund     if (entry->principal == NULL) {
1245e9cd1aeSAssar Westerlund 	entry->principal = malloc(sizeof(*entry->principal));
1255e9cd1aeSAssar Westerlund 	if (entry->principal == NULL) {
1265e9cd1aeSAssar Westerlund 	    hdb_free_entry (context, entry);
1274137ff4cSJacques Vidrine 	    krb5_set_error_string(context, "malloc: out of memory");
1284137ff4cSJacques Vidrine 	    return ENOMEM;
1295e9cd1aeSAssar Westerlund 	} else {
1305e9cd1aeSAssar Westerlund 	    hdb_key2principal(context, &key_data, entry->principal);
1315e9cd1aeSAssar Westerlund 	}
1325e9cd1aeSAssar Westerlund     }
1335e9cd1aeSAssar Westerlund     return 0;
1345e9cd1aeSAssar Westerlund }
1355e9cd1aeSAssar Westerlund 
1365e9cd1aeSAssar Westerlund 
1375e9cd1aeSAssar Westerlund static krb5_error_code
1385e9cd1aeSAssar Westerlund DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
1395e9cd1aeSAssar Westerlund {
1405e9cd1aeSAssar Westerlund     return DB_seq(context, db, flags, entry, DB_FIRST);
1415e9cd1aeSAssar Westerlund }
1425e9cd1aeSAssar Westerlund 
1435e9cd1aeSAssar Westerlund 
1445e9cd1aeSAssar Westerlund static krb5_error_code
1455e9cd1aeSAssar Westerlund DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
1465e9cd1aeSAssar Westerlund {
1475e9cd1aeSAssar Westerlund     return DB_seq(context, db, flags, entry, DB_NEXT);
1485e9cd1aeSAssar Westerlund }
1495e9cd1aeSAssar Westerlund 
1505e9cd1aeSAssar Westerlund static krb5_error_code
1515e9cd1aeSAssar Westerlund DB_rename(krb5_context context, HDB *db, const char *new_name)
1525e9cd1aeSAssar Westerlund {
1535e9cd1aeSAssar Westerlund     int ret;
1545e9cd1aeSAssar Westerlund     char *old, *new;
1555e9cd1aeSAssar Westerlund 
1565e9cd1aeSAssar Westerlund     asprintf(&old, "%s.db", db->name);
1575e9cd1aeSAssar Westerlund     asprintf(&new, "%s.db", new_name);
1585e9cd1aeSAssar Westerlund     ret = rename(old, new);
1595e9cd1aeSAssar Westerlund     free(old);
1605e9cd1aeSAssar Westerlund     free(new);
1615e9cd1aeSAssar Westerlund     if(ret)
1625e9cd1aeSAssar Westerlund 	return errno;
1635e9cd1aeSAssar Westerlund 
1645e9cd1aeSAssar Westerlund     free(db->name);
1655e9cd1aeSAssar Westerlund     db->name = strdup(new_name);
1665e9cd1aeSAssar Westerlund     return 0;
1675e9cd1aeSAssar Westerlund }
1685e9cd1aeSAssar Westerlund 
1695e9cd1aeSAssar Westerlund static krb5_error_code
1705e9cd1aeSAssar Westerlund DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
1715e9cd1aeSAssar Westerlund {
1725e9cd1aeSAssar Westerlund     DB *d = (DB*)db->db;
1735e9cd1aeSAssar Westerlund     DBT k, v;
1745e9cd1aeSAssar Westerlund     int code;
1755e9cd1aeSAssar Westerlund 
1765e9cd1aeSAssar Westerlund     memset(&k, 0, sizeof(DBT));
1775e9cd1aeSAssar Westerlund     memset(&v, 0, sizeof(DBT));
1785e9cd1aeSAssar Westerlund     k.data = key.data;
1795e9cd1aeSAssar Westerlund     k.size = key.length;
1805e9cd1aeSAssar Westerlund     k.flags = 0;
1815e9cd1aeSAssar Westerlund     if ((code = db->lock(context, db, HDB_RLOCK)))
1825e9cd1aeSAssar Westerlund 	return code;
1835e9cd1aeSAssar Westerlund     code = d->get(d, NULL, &k, &v, 0);
1845e9cd1aeSAssar Westerlund     db->unlock(context, db);
1855e9cd1aeSAssar Westerlund     if(code == DB_NOTFOUND)
1865e9cd1aeSAssar Westerlund 	return HDB_ERR_NOENTRY;
1875e9cd1aeSAssar Westerlund     if(code)
1885e9cd1aeSAssar Westerlund 	return code;
1895e9cd1aeSAssar Westerlund 
1905e9cd1aeSAssar Westerlund     krb5_data_copy(reply, v.data, v.size);
1915e9cd1aeSAssar Westerlund     return 0;
1925e9cd1aeSAssar Westerlund }
1935e9cd1aeSAssar Westerlund 
1945e9cd1aeSAssar Westerlund static krb5_error_code
1955e9cd1aeSAssar Westerlund DB__put(krb5_context context, HDB *db, int replace,
1965e9cd1aeSAssar Westerlund 	krb5_data key, krb5_data value)
1975e9cd1aeSAssar Westerlund {
1985e9cd1aeSAssar Westerlund     DB *d = (DB*)db->db;
1995e9cd1aeSAssar Westerlund     DBT k, v;
2005e9cd1aeSAssar Westerlund     int code;
2015e9cd1aeSAssar Westerlund 
2025e9cd1aeSAssar Westerlund     memset(&k, 0, sizeof(DBT));
2035e9cd1aeSAssar Westerlund     memset(&v, 0, sizeof(DBT));
2045e9cd1aeSAssar Westerlund     k.data = key.data;
2055e9cd1aeSAssar Westerlund     k.size = key.length;
2065e9cd1aeSAssar Westerlund     k.flags = 0;
2075e9cd1aeSAssar Westerlund     v.data = value.data;
2085e9cd1aeSAssar Westerlund     v.size = value.length;
2095e9cd1aeSAssar Westerlund     v.flags = 0;
2105e9cd1aeSAssar Westerlund     if ((code = db->lock(context, db, HDB_WLOCK)))
2115e9cd1aeSAssar Westerlund 	return code;
2125e9cd1aeSAssar Westerlund     code = d->put(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE);
2135e9cd1aeSAssar Westerlund     db->unlock(context, db);
2145e9cd1aeSAssar Westerlund     if(code == DB_KEYEXIST)
2155e9cd1aeSAssar Westerlund 	return HDB_ERR_EXISTS;
2165e9cd1aeSAssar Westerlund     if(code)
2175e9cd1aeSAssar Westerlund 	return errno;
2185e9cd1aeSAssar Westerlund     return 0;
2195e9cd1aeSAssar Westerlund }
2205e9cd1aeSAssar Westerlund 
2215e9cd1aeSAssar Westerlund static krb5_error_code
2225e9cd1aeSAssar Westerlund DB__del(krb5_context context, HDB *db, krb5_data key)
2235e9cd1aeSAssar Westerlund {
2245e9cd1aeSAssar Westerlund     DB *d = (DB*)db->db;
2255e9cd1aeSAssar Westerlund     DBT k;
2265e9cd1aeSAssar Westerlund     krb5_error_code code;
2275e9cd1aeSAssar Westerlund     memset(&k, 0, sizeof(DBT));
2285e9cd1aeSAssar Westerlund     k.data = key.data;
2295e9cd1aeSAssar Westerlund     k.size = key.length;
2305e9cd1aeSAssar Westerlund     k.flags = 0;
2315e9cd1aeSAssar Westerlund     code = db->lock(context, db, HDB_WLOCK);
2325e9cd1aeSAssar Westerlund     if(code)
2335e9cd1aeSAssar Westerlund 	return code;
2345e9cd1aeSAssar Westerlund     code = d->del(d, NULL, &k, 0);
2355e9cd1aeSAssar Westerlund     db->unlock(context, db);
2365e9cd1aeSAssar Westerlund     if(code == DB_NOTFOUND)
2375e9cd1aeSAssar Westerlund 	return HDB_ERR_NOENTRY;
2385e9cd1aeSAssar Westerlund     if(code)
2395e9cd1aeSAssar Westerlund 	return code;
2405e9cd1aeSAssar Westerlund     return 0;
2415e9cd1aeSAssar Westerlund }
2425e9cd1aeSAssar Westerlund 
2435e9cd1aeSAssar Westerlund static krb5_error_code
2445e9cd1aeSAssar Westerlund DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
2455e9cd1aeSAssar Westerlund {
2465e9cd1aeSAssar Westerlund     char *fn;
2475e9cd1aeSAssar Westerlund     krb5_error_code ret;
2485e9cd1aeSAssar Westerlund     DB *d;
2495e9cd1aeSAssar Westerlund     int myflags = 0;
2505e9cd1aeSAssar Westerlund 
2515e9cd1aeSAssar Westerlund     if (flags & O_CREAT)
2525e9cd1aeSAssar Westerlund       myflags |= DB_CREATE;
2535e9cd1aeSAssar Westerlund 
2545e9cd1aeSAssar Westerlund     if (flags & O_EXCL)
2555e9cd1aeSAssar Westerlund       myflags |= DB_EXCL;
2565e9cd1aeSAssar Westerlund 
2575e9cd1aeSAssar Westerlund     if (flags & O_RDONLY)
2585e9cd1aeSAssar Westerlund       myflags |= DB_RDONLY;
2595e9cd1aeSAssar Westerlund 
2605e9cd1aeSAssar Westerlund     if (flags & O_TRUNC)
2615e9cd1aeSAssar Westerlund       myflags |= DB_TRUNCATE;
2625e9cd1aeSAssar Westerlund 
2635e9cd1aeSAssar Westerlund     asprintf(&fn, "%s.db", db->name);
2644137ff4cSJacques Vidrine     if (fn == NULL) {
2654137ff4cSJacques Vidrine 	krb5_set_error_string(context, "malloc: out of memory");
2665e9cd1aeSAssar Westerlund 	return ENOMEM;
2674137ff4cSJacques Vidrine     }
2685e9cd1aeSAssar Westerlund     db_create(&d, NULL, 0);
2695e9cd1aeSAssar Westerlund     db->db = d;
2701c43270aSJacques Vidrine #if (DB_VERSION_MAJOR > 3) && (DB_VERSION_MINOR > 0)
2711c43270aSJacques Vidrine     if ((ret = d->open(db->db, NULL, fn, NULL, DB_BTREE, myflags, mode))) {
2721c43270aSJacques Vidrine #else
2735e9cd1aeSAssar Westerlund     if ((ret = d->open(db->db, fn, NULL, DB_BTREE, myflags, mode))) {
2741c43270aSJacques Vidrine #endif
2755e9cd1aeSAssar Westerlund       if(ret == ENOENT)
2765e9cd1aeSAssar Westerlund 	/* try to open without .db extension */
2771c43270aSJacques Vidrine #if (DB_VERSION_MAJOR > 3) && (DB_VERSION_MINOR > 0)
2781c43270aSJacques Vidrine 	if (d->open(db->db, NULL, db->name, NULL, DB_BTREE, myflags, mode)) {
2791c43270aSJacques Vidrine #else
2805e9cd1aeSAssar Westerlund 	if (d->open(db->db, db->name, NULL, DB_BTREE, myflags, mode)) {
2811c43270aSJacques Vidrine #endif
2825e9cd1aeSAssar Westerlund 	  free(fn);
2834137ff4cSJacques Vidrine 	  krb5_set_error_string(context, "opening %s: %s",
2844137ff4cSJacques Vidrine 				db->name, strerror(ret));
2855e9cd1aeSAssar Westerlund 	  return ret;
2865e9cd1aeSAssar Westerlund 	}
2875e9cd1aeSAssar Westerlund     }
2885e9cd1aeSAssar Westerlund     free(fn);
2895e9cd1aeSAssar Westerlund 
2905e9cd1aeSAssar Westerlund     ret = d->cursor(d, NULL, (DBC **)&db->dbc, 0);
2914137ff4cSJacques Vidrine     if (ret) {
2924137ff4cSJacques Vidrine 	krb5_set_error_string(context, "d->cursor: %s", strerror(ret));
2935e9cd1aeSAssar Westerlund         return ret;
2944137ff4cSJacques Vidrine     }
2955e9cd1aeSAssar Westerlund 
2965e9cd1aeSAssar Westerlund     if((flags & O_ACCMODE) == O_RDONLY)
2975e9cd1aeSAssar Westerlund 	ret = hdb_check_db_format(context, db);
2985e9cd1aeSAssar Westerlund     else
2995e9cd1aeSAssar Westerlund 	ret = hdb_init_db(context, db);
3005e9cd1aeSAssar Westerlund     if(ret == HDB_ERR_NOENTRY)
3015e9cd1aeSAssar Westerlund 	return 0;
3025e9cd1aeSAssar Westerlund     return ret;
3035e9cd1aeSAssar Westerlund }
3045e9cd1aeSAssar Westerlund 
3055e9cd1aeSAssar Westerlund krb5_error_code
3065e9cd1aeSAssar Westerlund hdb_db_create(krb5_context context, HDB **db,
3075e9cd1aeSAssar Westerlund 	      const char *filename)
3085e9cd1aeSAssar Westerlund {
3095e9cd1aeSAssar Westerlund     *db = malloc(sizeof(**db));
3104137ff4cSJacques Vidrine     if (*db == NULL) {
3114137ff4cSJacques Vidrine 	krb5_set_error_string(context, "malloc: out of memory");
3125e9cd1aeSAssar Westerlund 	return ENOMEM;
3134137ff4cSJacques Vidrine     }
3145e9cd1aeSAssar Westerlund 
3155e9cd1aeSAssar Westerlund     (*db)->db = NULL;
3165e9cd1aeSAssar Westerlund     (*db)->name = strdup(filename);
3174137ff4cSJacques Vidrine     if ((*db)->name == NULL) {
3184137ff4cSJacques Vidrine 	krb5_set_error_string(context, "malloc: out of memory");
3194137ff4cSJacques Vidrine 	free(*db);
3204137ff4cSJacques Vidrine 	*db = NULL;
3214137ff4cSJacques Vidrine 	return ENOMEM;
3224137ff4cSJacques Vidrine     }
3235e9cd1aeSAssar Westerlund     (*db)->master_key_set = 0;
3245e9cd1aeSAssar Westerlund     (*db)->openp = 0;
3255e9cd1aeSAssar Westerlund     (*db)->open  = DB_open;
3265e9cd1aeSAssar Westerlund     (*db)->close = DB_close;
3275e9cd1aeSAssar Westerlund     (*db)->fetch = _hdb_fetch;
3285e9cd1aeSAssar Westerlund     (*db)->store = _hdb_store;
3295e9cd1aeSAssar Westerlund     (*db)->remove = _hdb_remove;
3305e9cd1aeSAssar Westerlund     (*db)->firstkey = DB_firstkey;
3315e9cd1aeSAssar Westerlund     (*db)->nextkey= DB_nextkey;
3325e9cd1aeSAssar Westerlund     (*db)->lock = DB_lock;
3335e9cd1aeSAssar Westerlund     (*db)->unlock = DB_unlock;
3345e9cd1aeSAssar Westerlund     (*db)->rename = DB_rename;
3355e9cd1aeSAssar Westerlund     (*db)->_get = DB__get;
3365e9cd1aeSAssar Westerlund     (*db)->_put = DB__put;
3375e9cd1aeSAssar Westerlund     (*db)->_del = DB__del;
3385e9cd1aeSAssar Westerlund     (*db)->destroy = DB_destroy;
3395e9cd1aeSAssar Westerlund     return 0;
3405e9cd1aeSAssar Westerlund }
3414137ff4cSJacques Vidrine #endif /* HAVE_DB3 */
342