xref: /freebsd/crypto/heimdal/lib/hdb/db3.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
15e9cd1aeSAssar Westerlund /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997 - 2006 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 
364137ff4cSJacques Vidrine #if HAVE_DB3
374137ff4cSJacques Vidrine 
38*ae771770SStanislav Sedov #ifdef HAVE_DBHEADER
39*ae771770SStanislav Sedov #include <db.h>
40*ae771770SStanislav Sedov #elif HAVE_DB5_DB_H
41*ae771770SStanislav Sedov #include <db5/db.h>
42*ae771770SStanislav Sedov #elif HAVE_DB4_DB_H
431c43270aSJacques Vidrine #include <db4/db.h>
44*ae771770SStanislav Sedov #elif HAVE_DB3_DB_H
451c43270aSJacques Vidrine #include <db3/db.h>
461c43270aSJacques Vidrine #else
474137ff4cSJacques Vidrine #include <db.h>
481c43270aSJacques Vidrine #endif
494137ff4cSJacques Vidrine 
505e9cd1aeSAssar Westerlund static krb5_error_code
DB_close(krb5_context context,HDB * db)515e9cd1aeSAssar Westerlund DB_close(krb5_context context, HDB *db)
525e9cd1aeSAssar Westerlund {
53c19800e8SDoug Rabson     DB *d = (DB*)db->hdb_db;
54c19800e8SDoug Rabson     DBC *dbcp = (DBC*)db->hdb_dbc;
555e9cd1aeSAssar Westerlund 
56c19800e8SDoug Rabson     (*dbcp->c_close)(dbcp);
57c19800e8SDoug Rabson     db->hdb_dbc = 0;
58c19800e8SDoug Rabson     (*d->close)(d, 0);
595e9cd1aeSAssar Westerlund     return 0;
605e9cd1aeSAssar Westerlund }
615e9cd1aeSAssar Westerlund 
625e9cd1aeSAssar Westerlund static krb5_error_code
DB_destroy(krb5_context context,HDB * db)635e9cd1aeSAssar Westerlund DB_destroy(krb5_context context, HDB *db)
645e9cd1aeSAssar Westerlund {
655e9cd1aeSAssar Westerlund     krb5_error_code ret;
665e9cd1aeSAssar Westerlund 
675e9cd1aeSAssar Westerlund     ret = hdb_clear_master_key (context, db);
68c19800e8SDoug Rabson     free(db->hdb_name);
695e9cd1aeSAssar Westerlund     free(db);
705e9cd1aeSAssar Westerlund     return ret;
715e9cd1aeSAssar Westerlund }
725e9cd1aeSAssar Westerlund 
735e9cd1aeSAssar Westerlund static krb5_error_code
DB_lock(krb5_context context,HDB * db,int operation)745e9cd1aeSAssar Westerlund DB_lock(krb5_context context, HDB *db, int operation)
755e9cd1aeSAssar Westerlund {
76c19800e8SDoug Rabson     DB *d = (DB*)db->hdb_db;
775e9cd1aeSAssar Westerlund     int fd;
785e9cd1aeSAssar Westerlund     if ((*d->fd)(d, &fd))
795e9cd1aeSAssar Westerlund 	return HDB_ERR_CANT_LOCK_DB;
805e9cd1aeSAssar Westerlund     return hdb_lock(fd, operation);
815e9cd1aeSAssar Westerlund }
825e9cd1aeSAssar Westerlund 
835e9cd1aeSAssar Westerlund static krb5_error_code
DB_unlock(krb5_context context,HDB * db)845e9cd1aeSAssar Westerlund DB_unlock(krb5_context context, HDB *db)
855e9cd1aeSAssar Westerlund {
86c19800e8SDoug Rabson     DB *d = (DB*)db->hdb_db;
875e9cd1aeSAssar Westerlund     int fd;
885e9cd1aeSAssar Westerlund     if ((*d->fd)(d, &fd))
895e9cd1aeSAssar Westerlund 	return HDB_ERR_CANT_LOCK_DB;
905e9cd1aeSAssar Westerlund     return hdb_unlock(fd);
915e9cd1aeSAssar Westerlund }
925e9cd1aeSAssar Westerlund 
935e9cd1aeSAssar Westerlund 
945e9cd1aeSAssar Westerlund static krb5_error_code
DB_seq(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry,int flag)955e9cd1aeSAssar Westerlund DB_seq(krb5_context context, HDB *db,
96c19800e8SDoug Rabson        unsigned flags, hdb_entry_ex *entry, int flag)
975e9cd1aeSAssar Westerlund {
985e9cd1aeSAssar Westerlund     DBT key, value;
99c19800e8SDoug Rabson     DBC *dbcp = db->hdb_dbc;
1005e9cd1aeSAssar Westerlund     krb5_data key_data, data;
1015e9cd1aeSAssar Westerlund     int code;
1025e9cd1aeSAssar Westerlund 
1035e9cd1aeSAssar Westerlund     memset(&key, 0, sizeof(DBT));
1045e9cd1aeSAssar Westerlund     memset(&value, 0, sizeof(DBT));
105c19800e8SDoug Rabson     if ((*db->hdb_lock)(context, db, HDB_RLOCK))
1065e9cd1aeSAssar Westerlund 	return HDB_ERR_DB_INUSE;
107c19800e8SDoug Rabson     code = (*dbcp->c_get)(dbcp, &key, &value, flag);
108c19800e8SDoug Rabson     (*db->hdb_unlock)(context, db); /* XXX check value */
1095e9cd1aeSAssar Westerlund     if (code == DB_NOTFOUND)
1105e9cd1aeSAssar Westerlund 	return HDB_ERR_NOENTRY;
1115e9cd1aeSAssar Westerlund     if (code)
1125e9cd1aeSAssar Westerlund 	return code;
1135e9cd1aeSAssar Westerlund 
1145e9cd1aeSAssar Westerlund     key_data.data = key.data;
1155e9cd1aeSAssar Westerlund     key_data.length = key.size;
1165e9cd1aeSAssar Westerlund     data.data = value.data;
1175e9cd1aeSAssar Westerlund     data.length = value.size;
118c19800e8SDoug Rabson     memset(entry, 0, sizeof(*entry));
119c19800e8SDoug Rabson     if (hdb_value2entry(context, &data, &entry->entry))
1205e9cd1aeSAssar Westerlund 	return DB_seq(context, db, flags, entry, DB_NEXT);
121c19800e8SDoug Rabson     if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) {
122c19800e8SDoug Rabson 	code = hdb_unseal_keys (context, db, &entry->entry);
1235e9cd1aeSAssar Westerlund 	if (code)
1245e9cd1aeSAssar Westerlund 	    hdb_free_entry (context, entry);
1255e9cd1aeSAssar Westerlund     }
126c19800e8SDoug Rabson     if (entry->entry.principal == NULL) {
127c19800e8SDoug Rabson 	entry->entry.principal = malloc(sizeof(*entry->entry.principal));
128c19800e8SDoug Rabson 	if (entry->entry.principal == NULL) {
1295e9cd1aeSAssar Westerlund 	    hdb_free_entry (context, entry);
130*ae771770SStanislav Sedov 	    krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
1314137ff4cSJacques Vidrine 	    return ENOMEM;
1325e9cd1aeSAssar Westerlund 	} else {
133c19800e8SDoug Rabson 	    hdb_key2principal(context, &key_data, entry->entry.principal);
1345e9cd1aeSAssar Westerlund 	}
1355e9cd1aeSAssar Westerlund     }
1365e9cd1aeSAssar Westerlund     return 0;
1375e9cd1aeSAssar Westerlund }
1385e9cd1aeSAssar Westerlund 
1395e9cd1aeSAssar Westerlund 
1405e9cd1aeSAssar Westerlund static krb5_error_code
DB_firstkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)141c19800e8SDoug Rabson DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
1425e9cd1aeSAssar Westerlund {
1435e9cd1aeSAssar Westerlund     return DB_seq(context, db, flags, entry, DB_FIRST);
1445e9cd1aeSAssar Westerlund }
1455e9cd1aeSAssar Westerlund 
1465e9cd1aeSAssar Westerlund 
1475e9cd1aeSAssar Westerlund static krb5_error_code
DB_nextkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)148c19800e8SDoug Rabson DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
1495e9cd1aeSAssar Westerlund {
1505e9cd1aeSAssar Westerlund     return DB_seq(context, db, flags, entry, DB_NEXT);
1515e9cd1aeSAssar Westerlund }
1525e9cd1aeSAssar Westerlund 
1535e9cd1aeSAssar Westerlund static krb5_error_code
DB_rename(krb5_context context,HDB * db,const char * new_name)1545e9cd1aeSAssar Westerlund DB_rename(krb5_context context, HDB *db, const char *new_name)
1555e9cd1aeSAssar Westerlund {
1565e9cd1aeSAssar Westerlund     int ret;
1575e9cd1aeSAssar Westerlund     char *old, *new;
1585e9cd1aeSAssar Westerlund 
159c19800e8SDoug Rabson     asprintf(&old, "%s.db", db->hdb_name);
1605e9cd1aeSAssar Westerlund     asprintf(&new, "%s.db", new_name);
1615e9cd1aeSAssar Westerlund     ret = rename(old, new);
1625e9cd1aeSAssar Westerlund     free(old);
1635e9cd1aeSAssar Westerlund     free(new);
1645e9cd1aeSAssar Westerlund     if(ret)
1655e9cd1aeSAssar Westerlund 	return errno;
1665e9cd1aeSAssar Westerlund 
167c19800e8SDoug Rabson     free(db->hdb_name);
168c19800e8SDoug Rabson     db->hdb_name = strdup(new_name);
1695e9cd1aeSAssar Westerlund     return 0;
1705e9cd1aeSAssar Westerlund }
1715e9cd1aeSAssar Westerlund 
1725e9cd1aeSAssar Westerlund static krb5_error_code
DB__get(krb5_context context,HDB * db,krb5_data key,krb5_data * reply)1735e9cd1aeSAssar Westerlund DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
1745e9cd1aeSAssar Westerlund {
175c19800e8SDoug Rabson     DB *d = (DB*)db->hdb_db;
1765e9cd1aeSAssar Westerlund     DBT k, v;
1775e9cd1aeSAssar Westerlund     int code;
1785e9cd1aeSAssar Westerlund 
1795e9cd1aeSAssar Westerlund     memset(&k, 0, sizeof(DBT));
1805e9cd1aeSAssar Westerlund     memset(&v, 0, sizeof(DBT));
1815e9cd1aeSAssar Westerlund     k.data = key.data;
1825e9cd1aeSAssar Westerlund     k.size = key.length;
1835e9cd1aeSAssar Westerlund     k.flags = 0;
184c19800e8SDoug Rabson     if ((code = (*db->hdb_lock)(context, db, HDB_RLOCK)))
1855e9cd1aeSAssar Westerlund 	return code;
186c19800e8SDoug Rabson     code = (*d->get)(d, NULL, &k, &v, 0);
187c19800e8SDoug Rabson     (*db->hdb_unlock)(context, db);
1885e9cd1aeSAssar Westerlund     if(code == DB_NOTFOUND)
1895e9cd1aeSAssar Westerlund 	return HDB_ERR_NOENTRY;
1905e9cd1aeSAssar Westerlund     if(code)
1915e9cd1aeSAssar Westerlund 	return code;
1925e9cd1aeSAssar Westerlund 
1935e9cd1aeSAssar Westerlund     krb5_data_copy(reply, v.data, v.size);
1945e9cd1aeSAssar Westerlund     return 0;
1955e9cd1aeSAssar Westerlund }
1965e9cd1aeSAssar Westerlund 
1975e9cd1aeSAssar Westerlund static krb5_error_code
DB__put(krb5_context context,HDB * db,int replace,krb5_data key,krb5_data value)1985e9cd1aeSAssar Westerlund DB__put(krb5_context context, HDB *db, int replace,
1995e9cd1aeSAssar Westerlund 	krb5_data key, krb5_data value)
2005e9cd1aeSAssar Westerlund {
201c19800e8SDoug Rabson     DB *d = (DB*)db->hdb_db;
2025e9cd1aeSAssar Westerlund     DBT k, v;
2035e9cd1aeSAssar Westerlund     int code;
2045e9cd1aeSAssar Westerlund 
2055e9cd1aeSAssar Westerlund     memset(&k, 0, sizeof(DBT));
2065e9cd1aeSAssar Westerlund     memset(&v, 0, sizeof(DBT));
2075e9cd1aeSAssar Westerlund     k.data = key.data;
2085e9cd1aeSAssar Westerlund     k.size = key.length;
2095e9cd1aeSAssar Westerlund     k.flags = 0;
2105e9cd1aeSAssar Westerlund     v.data = value.data;
2115e9cd1aeSAssar Westerlund     v.size = value.length;
2125e9cd1aeSAssar Westerlund     v.flags = 0;
213c19800e8SDoug Rabson     if ((code = (*db->hdb_lock)(context, db, HDB_WLOCK)))
2145e9cd1aeSAssar Westerlund 	return code;
215c19800e8SDoug Rabson     code = (*d->put)(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE);
216c19800e8SDoug Rabson     (*db->hdb_unlock)(context, db);
2175e9cd1aeSAssar Westerlund     if(code == DB_KEYEXIST)
2185e9cd1aeSAssar Westerlund 	return HDB_ERR_EXISTS;
2195e9cd1aeSAssar Westerlund     if(code)
2205e9cd1aeSAssar Westerlund 	return errno;
2215e9cd1aeSAssar Westerlund     return 0;
2225e9cd1aeSAssar Westerlund }
2235e9cd1aeSAssar Westerlund 
2245e9cd1aeSAssar Westerlund static krb5_error_code
DB__del(krb5_context context,HDB * db,krb5_data key)2255e9cd1aeSAssar Westerlund DB__del(krb5_context context, HDB *db, krb5_data key)
2265e9cd1aeSAssar Westerlund {
227c19800e8SDoug Rabson     DB *d = (DB*)db->hdb_db;
2285e9cd1aeSAssar Westerlund     DBT k;
2295e9cd1aeSAssar Westerlund     krb5_error_code code;
2305e9cd1aeSAssar Westerlund     memset(&k, 0, sizeof(DBT));
2315e9cd1aeSAssar Westerlund     k.data = key.data;
2325e9cd1aeSAssar Westerlund     k.size = key.length;
2335e9cd1aeSAssar Westerlund     k.flags = 0;
234c19800e8SDoug Rabson     code = (*db->hdb_lock)(context, db, HDB_WLOCK);
2355e9cd1aeSAssar Westerlund     if(code)
2365e9cd1aeSAssar Westerlund 	return code;
237c19800e8SDoug Rabson     code = (*d->del)(d, NULL, &k, 0);
238c19800e8SDoug Rabson     (*db->hdb_unlock)(context, db);
2395e9cd1aeSAssar Westerlund     if(code == DB_NOTFOUND)
2405e9cd1aeSAssar Westerlund 	return HDB_ERR_NOENTRY;
2415e9cd1aeSAssar Westerlund     if(code)
2425e9cd1aeSAssar Westerlund 	return code;
2435e9cd1aeSAssar Westerlund     return 0;
2445e9cd1aeSAssar Westerlund }
2455e9cd1aeSAssar Westerlund 
2465e9cd1aeSAssar Westerlund static krb5_error_code
DB_open(krb5_context context,HDB * db,int flags,mode_t mode)2475e9cd1aeSAssar Westerlund DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
2485e9cd1aeSAssar Westerlund {
249c19800e8SDoug Rabson     DBC *dbc = NULL;
2505e9cd1aeSAssar Westerlund     char *fn;
2515e9cd1aeSAssar Westerlund     krb5_error_code ret;
2525e9cd1aeSAssar Westerlund     DB *d;
2535e9cd1aeSAssar Westerlund     int myflags = 0;
2545e9cd1aeSAssar Westerlund 
2555e9cd1aeSAssar Westerlund     if (flags & O_CREAT)
2565e9cd1aeSAssar Westerlund       myflags |= DB_CREATE;
2575e9cd1aeSAssar Westerlund 
2585e9cd1aeSAssar Westerlund     if (flags & O_EXCL)
2595e9cd1aeSAssar Westerlund       myflags |= DB_EXCL;
2605e9cd1aeSAssar Westerlund 
261c19800e8SDoug Rabson     if((flags & O_ACCMODE) == O_RDONLY)
2625e9cd1aeSAssar Westerlund       myflags |= DB_RDONLY;
2635e9cd1aeSAssar Westerlund 
2645e9cd1aeSAssar Westerlund     if (flags & O_TRUNC)
2655e9cd1aeSAssar Westerlund       myflags |= DB_TRUNCATE;
2665e9cd1aeSAssar Westerlund 
267c19800e8SDoug Rabson     asprintf(&fn, "%s.db", db->hdb_name);
2684137ff4cSJacques Vidrine     if (fn == NULL) {
269*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
2705e9cd1aeSAssar Westerlund 	return ENOMEM;
2714137ff4cSJacques Vidrine     }
272*ae771770SStanislav Sedov     if (db_create(&d, NULL, 0) != 0) {
273*ae771770SStanislav Sedov 	free(fn);
274*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
275*ae771770SStanislav Sedov 	return ENOMEM;
276*ae771770SStanislav Sedov     }
277c19800e8SDoug Rabson     db->hdb_db = d;
278c19800e8SDoug Rabson 
279c19800e8SDoug Rabson #if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 1)
280c19800e8SDoug Rabson     ret = (*d->open)(db->hdb_db, NULL, fn, NULL, DB_BTREE, myflags, mode);
2811c43270aSJacques Vidrine #else
282c19800e8SDoug Rabson     ret = (*d->open)(db->hdb_db, fn, NULL, DB_BTREE, myflags, mode);
2831c43270aSJacques Vidrine #endif
284c19800e8SDoug Rabson 
285c19800e8SDoug Rabson     if (ret == ENOENT) {
2865e9cd1aeSAssar Westerlund 	/* try to open without .db extension */
287c19800e8SDoug Rabson #if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 1)
288c19800e8SDoug Rabson 	ret = (*d->open)(db->hdb_db, NULL, db->hdb_name, NULL, DB_BTREE,
289c19800e8SDoug Rabson 			 myflags, mode);
2901c43270aSJacques Vidrine #else
291c19800e8SDoug Rabson 	ret = (*d->open)(db->hdb_db, db->hdb_name, NULL, DB_BTREE,
292c19800e8SDoug Rabson 			 myflags, mode);
2931c43270aSJacques Vidrine #endif
294c19800e8SDoug Rabson     }
295c19800e8SDoug Rabson 
296c19800e8SDoug Rabson     if (ret) {
2975e9cd1aeSAssar Westerlund 	free(fn);
298*ae771770SStanislav Sedov 	krb5_set_error_message(context, ret, "opening %s: %s",
299c19800e8SDoug Rabson 			      db->hdb_name, strerror(ret));
3005e9cd1aeSAssar Westerlund 	return ret;
3015e9cd1aeSAssar Westerlund     }
3025e9cd1aeSAssar Westerlund     free(fn);
3035e9cd1aeSAssar Westerlund 
304c19800e8SDoug Rabson     ret = (*d->cursor)(d, NULL, &dbc, 0);
3054137ff4cSJacques Vidrine     if (ret) {
306*ae771770SStanislav Sedov 	krb5_set_error_message(context, ret, "d->cursor: %s", strerror(ret));
3075e9cd1aeSAssar Westerlund         return ret;
3084137ff4cSJacques Vidrine     }
309c19800e8SDoug Rabson     db->hdb_dbc = dbc;
3105e9cd1aeSAssar Westerlund 
3115e9cd1aeSAssar Westerlund     if((flags & O_ACCMODE) == O_RDONLY)
3125e9cd1aeSAssar Westerlund 	ret = hdb_check_db_format(context, db);
3135e9cd1aeSAssar Westerlund     else
3145e9cd1aeSAssar Westerlund 	ret = hdb_init_db(context, db);
3155e9cd1aeSAssar Westerlund     if(ret == HDB_ERR_NOENTRY)
3165e9cd1aeSAssar Westerlund 	return 0;
317c19800e8SDoug Rabson     if (ret) {
318c19800e8SDoug Rabson 	DB_close(context, db);
319*ae771770SStanislav Sedov 	krb5_set_error_message(context, ret, "hdb_open: failed %s database %s",
320c19800e8SDoug Rabson 			       (flags & O_ACCMODE) == O_RDONLY ?
321c19800e8SDoug Rabson 			       "checking format of" : "initialize",
322c19800e8SDoug Rabson 			       db->hdb_name);
323c19800e8SDoug Rabson     }
324c19800e8SDoug Rabson 
3255e9cd1aeSAssar Westerlund     return ret;
3265e9cd1aeSAssar Westerlund }
3275e9cd1aeSAssar Westerlund 
3285e9cd1aeSAssar Westerlund krb5_error_code
hdb_db_create(krb5_context context,HDB ** db,const char * filename)3295e9cd1aeSAssar Westerlund hdb_db_create(krb5_context context, HDB **db,
3305e9cd1aeSAssar Westerlund 	      const char *filename)
3315e9cd1aeSAssar Westerlund {
332c19800e8SDoug Rabson     *db = calloc(1, sizeof(**db));
3334137ff4cSJacques Vidrine     if (*db == NULL) {
334*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
3355e9cd1aeSAssar Westerlund 	return ENOMEM;
3364137ff4cSJacques Vidrine     }
3375e9cd1aeSAssar Westerlund 
338c19800e8SDoug Rabson     (*db)->hdb_db = NULL;
339c19800e8SDoug Rabson     (*db)->hdb_name = strdup(filename);
340c19800e8SDoug Rabson     if ((*db)->hdb_name == NULL) {
3414137ff4cSJacques Vidrine 	free(*db);
3424137ff4cSJacques Vidrine 	*db = NULL;
343*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
3444137ff4cSJacques Vidrine 	return ENOMEM;
3454137ff4cSJacques Vidrine     }
346c19800e8SDoug Rabson     (*db)->hdb_master_key_set = 0;
347c19800e8SDoug Rabson     (*db)->hdb_openp = 0;
348*ae771770SStanislav Sedov     (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
349c19800e8SDoug Rabson     (*db)->hdb_open  = DB_open;
350c19800e8SDoug Rabson     (*db)->hdb_close = DB_close;
351*ae771770SStanislav Sedov     (*db)->hdb_fetch_kvno = _hdb_fetch_kvno;
352c19800e8SDoug Rabson     (*db)->hdb_store = _hdb_store;
353c19800e8SDoug Rabson     (*db)->hdb_remove = _hdb_remove;
354c19800e8SDoug Rabson     (*db)->hdb_firstkey = DB_firstkey;
355c19800e8SDoug Rabson     (*db)->hdb_nextkey= DB_nextkey;
356c19800e8SDoug Rabson     (*db)->hdb_lock = DB_lock;
357c19800e8SDoug Rabson     (*db)->hdb_unlock = DB_unlock;
358c19800e8SDoug Rabson     (*db)->hdb_rename = DB_rename;
359c19800e8SDoug Rabson     (*db)->hdb__get = DB__get;
360c19800e8SDoug Rabson     (*db)->hdb__put = DB__put;
361c19800e8SDoug Rabson     (*db)->hdb__del = DB__del;
362c19800e8SDoug Rabson     (*db)->hdb_destroy = DB_destroy;
3635e9cd1aeSAssar Westerlund     return 0;
3645e9cd1aeSAssar Westerlund }
3654137ff4cSJacques Vidrine #endif /* HAVE_DB3 */
366