xref: /minix3/crypto/external/bsd/heimdal/dist/lib/hdb/db3.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: db3.c,v 1.1.1.2 2014/04/24 12:45:28 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc  * are met:
11ebfedea0SLionel Sambuc  *
12ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc  *
15ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc  *
19ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc  *    without specific prior written permission.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc  * SUCH DAMAGE.
34ebfedea0SLionel Sambuc  */
35ebfedea0SLionel Sambuc 
36ebfedea0SLionel Sambuc #include "hdb_locl.h"
37ebfedea0SLionel Sambuc 
38ebfedea0SLionel Sambuc #if HAVE_DB3
39ebfedea0SLionel Sambuc 
40ebfedea0SLionel Sambuc #ifdef HAVE_DBHEADER
41ebfedea0SLionel Sambuc #include <db.h>
42ebfedea0SLionel Sambuc #elif HAVE_DB5_DB_H
43ebfedea0SLionel Sambuc #include <db5/db.h>
44ebfedea0SLionel Sambuc #elif HAVE_DB4_DB_H
45ebfedea0SLionel Sambuc #include <db4/db.h>
46ebfedea0SLionel Sambuc #elif HAVE_DB3_DB_H
47ebfedea0SLionel Sambuc #include <db3/db.h>
48ebfedea0SLionel Sambuc #else
49ebfedea0SLionel Sambuc #include <db.h>
50ebfedea0SLionel Sambuc #endif
51ebfedea0SLionel Sambuc 
52ebfedea0SLionel Sambuc static krb5_error_code
DB_close(krb5_context context,HDB * db)53ebfedea0SLionel Sambuc DB_close(krb5_context context, HDB *db)
54ebfedea0SLionel Sambuc {
55ebfedea0SLionel Sambuc     DB *d = (DB*)db->hdb_db;
56ebfedea0SLionel Sambuc     DBC *dbcp = (DBC*)db->hdb_dbc;
57ebfedea0SLionel Sambuc 
58ebfedea0SLionel Sambuc     (*dbcp->c_close)(dbcp);
59ebfedea0SLionel Sambuc     db->hdb_dbc = 0;
60ebfedea0SLionel Sambuc     (*d->close)(d, 0);
61ebfedea0SLionel Sambuc     return 0;
62ebfedea0SLionel Sambuc }
63ebfedea0SLionel Sambuc 
64ebfedea0SLionel Sambuc static krb5_error_code
DB_destroy(krb5_context context,HDB * db)65ebfedea0SLionel Sambuc DB_destroy(krb5_context context, HDB *db)
66ebfedea0SLionel Sambuc {
67ebfedea0SLionel Sambuc     krb5_error_code ret;
68ebfedea0SLionel Sambuc 
69ebfedea0SLionel Sambuc     ret = hdb_clear_master_key (context, db);
70ebfedea0SLionel Sambuc     free(db->hdb_name);
71ebfedea0SLionel Sambuc     free(db);
72ebfedea0SLionel Sambuc     return ret;
73ebfedea0SLionel Sambuc }
74ebfedea0SLionel Sambuc 
75ebfedea0SLionel Sambuc static krb5_error_code
DB_lock(krb5_context context,HDB * db,int operation)76ebfedea0SLionel Sambuc DB_lock(krb5_context context, HDB *db, int operation)
77ebfedea0SLionel Sambuc {
78ebfedea0SLionel Sambuc     DB *d = (DB*)db->hdb_db;
79ebfedea0SLionel Sambuc     int fd;
80ebfedea0SLionel Sambuc     if ((*d->fd)(d, &fd))
81ebfedea0SLionel Sambuc 	return HDB_ERR_CANT_LOCK_DB;
82ebfedea0SLionel Sambuc     return hdb_lock(fd, operation);
83ebfedea0SLionel Sambuc }
84ebfedea0SLionel Sambuc 
85ebfedea0SLionel Sambuc static krb5_error_code
DB_unlock(krb5_context context,HDB * db)86ebfedea0SLionel Sambuc DB_unlock(krb5_context context, HDB *db)
87ebfedea0SLionel Sambuc {
88ebfedea0SLionel Sambuc     DB *d = (DB*)db->hdb_db;
89ebfedea0SLionel Sambuc     int fd;
90ebfedea0SLionel Sambuc     if ((*d->fd)(d, &fd))
91ebfedea0SLionel Sambuc 	return HDB_ERR_CANT_LOCK_DB;
92ebfedea0SLionel Sambuc     return hdb_unlock(fd);
93ebfedea0SLionel Sambuc }
94ebfedea0SLionel Sambuc 
95ebfedea0SLionel Sambuc 
96ebfedea0SLionel Sambuc static krb5_error_code
DB_seq(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry,int flag)97ebfedea0SLionel Sambuc DB_seq(krb5_context context, HDB *db,
98ebfedea0SLionel Sambuc        unsigned flags, hdb_entry_ex *entry, int flag)
99ebfedea0SLionel Sambuc {
100ebfedea0SLionel Sambuc     DBT key, value;
101ebfedea0SLionel Sambuc     DBC *dbcp = db->hdb_dbc;
102ebfedea0SLionel Sambuc     krb5_data key_data, data;
103ebfedea0SLionel Sambuc     int code;
104ebfedea0SLionel Sambuc 
105ebfedea0SLionel Sambuc     memset(&key, 0, sizeof(DBT));
106ebfedea0SLionel Sambuc     memset(&value, 0, sizeof(DBT));
107ebfedea0SLionel Sambuc     if ((*db->hdb_lock)(context, db, HDB_RLOCK))
108ebfedea0SLionel Sambuc 	return HDB_ERR_DB_INUSE;
109ebfedea0SLionel Sambuc     code = (*dbcp->c_get)(dbcp, &key, &value, flag);
110ebfedea0SLionel Sambuc     (*db->hdb_unlock)(context, db); /* XXX check value */
111ebfedea0SLionel Sambuc     if (code == DB_NOTFOUND)
112ebfedea0SLionel Sambuc 	return HDB_ERR_NOENTRY;
113ebfedea0SLionel Sambuc     if (code)
114ebfedea0SLionel Sambuc 	return code;
115ebfedea0SLionel Sambuc 
116ebfedea0SLionel Sambuc     key_data.data = key.data;
117ebfedea0SLionel Sambuc     key_data.length = key.size;
118ebfedea0SLionel Sambuc     data.data = value.data;
119ebfedea0SLionel Sambuc     data.length = value.size;
120ebfedea0SLionel Sambuc     memset(entry, 0, sizeof(*entry));
121ebfedea0SLionel Sambuc     if (hdb_value2entry(context, &data, &entry->entry))
122ebfedea0SLionel Sambuc 	return DB_seq(context, db, flags, entry, DB_NEXT);
123ebfedea0SLionel Sambuc     if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) {
124ebfedea0SLionel Sambuc 	code = hdb_unseal_keys (context, db, &entry->entry);
125ebfedea0SLionel Sambuc 	if (code)
126ebfedea0SLionel Sambuc 	    hdb_free_entry (context, entry);
127ebfedea0SLionel Sambuc     }
128ebfedea0SLionel Sambuc     if (entry->entry.principal == NULL) {
129ebfedea0SLionel Sambuc 	entry->entry.principal = malloc(sizeof(*entry->entry.principal));
130ebfedea0SLionel Sambuc 	if (entry->entry.principal == NULL) {
131ebfedea0SLionel Sambuc 	    hdb_free_entry (context, entry);
132ebfedea0SLionel Sambuc 	    krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
133ebfedea0SLionel Sambuc 	    return ENOMEM;
134ebfedea0SLionel Sambuc 	} else {
135ebfedea0SLionel Sambuc 	    hdb_key2principal(context, &key_data, entry->entry.principal);
136ebfedea0SLionel Sambuc 	}
137ebfedea0SLionel Sambuc     }
138ebfedea0SLionel Sambuc     return 0;
139ebfedea0SLionel Sambuc }
140ebfedea0SLionel Sambuc 
141ebfedea0SLionel Sambuc 
142ebfedea0SLionel Sambuc static krb5_error_code
DB_firstkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)143ebfedea0SLionel Sambuc DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
144ebfedea0SLionel Sambuc {
145ebfedea0SLionel Sambuc     return DB_seq(context, db, flags, entry, DB_FIRST);
146ebfedea0SLionel Sambuc }
147ebfedea0SLionel Sambuc 
148ebfedea0SLionel Sambuc 
149ebfedea0SLionel Sambuc static krb5_error_code
DB_nextkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)150ebfedea0SLionel Sambuc DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
151ebfedea0SLionel Sambuc {
152ebfedea0SLionel Sambuc     return DB_seq(context, db, flags, entry, DB_NEXT);
153ebfedea0SLionel Sambuc }
154ebfedea0SLionel Sambuc 
155ebfedea0SLionel Sambuc static krb5_error_code
DB_rename(krb5_context context,HDB * db,const char * new_name)156ebfedea0SLionel Sambuc DB_rename(krb5_context context, HDB *db, const char *new_name)
157ebfedea0SLionel Sambuc {
158ebfedea0SLionel Sambuc     int ret;
159ebfedea0SLionel Sambuc     char *old, *new;
160ebfedea0SLionel Sambuc 
161ebfedea0SLionel Sambuc     asprintf(&old, "%s.db", db->hdb_name);
162ebfedea0SLionel Sambuc     asprintf(&new, "%s.db", new_name);
163ebfedea0SLionel Sambuc     ret = rename(old, new);
164ebfedea0SLionel Sambuc     free(old);
165ebfedea0SLionel Sambuc     free(new);
166ebfedea0SLionel Sambuc     if(ret)
167ebfedea0SLionel Sambuc 	return errno;
168ebfedea0SLionel Sambuc 
169ebfedea0SLionel Sambuc     free(db->hdb_name);
170ebfedea0SLionel Sambuc     db->hdb_name = strdup(new_name);
171ebfedea0SLionel Sambuc     return 0;
172ebfedea0SLionel Sambuc }
173ebfedea0SLionel Sambuc 
174ebfedea0SLionel Sambuc static krb5_error_code
DB__get(krb5_context context,HDB * db,krb5_data key,krb5_data * reply)175ebfedea0SLionel Sambuc DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
176ebfedea0SLionel Sambuc {
177ebfedea0SLionel Sambuc     DB *d = (DB*)db->hdb_db;
178ebfedea0SLionel Sambuc     DBT k, v;
179ebfedea0SLionel Sambuc     int code;
180ebfedea0SLionel Sambuc 
181ebfedea0SLionel Sambuc     memset(&k, 0, sizeof(DBT));
182ebfedea0SLionel Sambuc     memset(&v, 0, sizeof(DBT));
183ebfedea0SLionel Sambuc     k.data = key.data;
184ebfedea0SLionel Sambuc     k.size = key.length;
185ebfedea0SLionel Sambuc     k.flags = 0;
186ebfedea0SLionel Sambuc     if ((code = (*db->hdb_lock)(context, db, HDB_RLOCK)))
187ebfedea0SLionel Sambuc 	return code;
188ebfedea0SLionel Sambuc     code = (*d->get)(d, NULL, &k, &v, 0);
189ebfedea0SLionel Sambuc     (*db->hdb_unlock)(context, db);
190ebfedea0SLionel Sambuc     if(code == DB_NOTFOUND)
191ebfedea0SLionel Sambuc 	return HDB_ERR_NOENTRY;
192ebfedea0SLionel Sambuc     if(code)
193ebfedea0SLionel Sambuc 	return code;
194ebfedea0SLionel Sambuc 
195ebfedea0SLionel Sambuc     krb5_data_copy(reply, v.data, v.size);
196ebfedea0SLionel Sambuc     return 0;
197ebfedea0SLionel Sambuc }
198ebfedea0SLionel Sambuc 
199ebfedea0SLionel Sambuc static krb5_error_code
DB__put(krb5_context context,HDB * db,int replace,krb5_data key,krb5_data value)200ebfedea0SLionel Sambuc DB__put(krb5_context context, HDB *db, int replace,
201ebfedea0SLionel Sambuc 	krb5_data key, krb5_data value)
202ebfedea0SLionel Sambuc {
203ebfedea0SLionel Sambuc     DB *d = (DB*)db->hdb_db;
204ebfedea0SLionel Sambuc     DBT k, v;
205ebfedea0SLionel Sambuc     int code;
206ebfedea0SLionel Sambuc 
207ebfedea0SLionel Sambuc     memset(&k, 0, sizeof(DBT));
208ebfedea0SLionel Sambuc     memset(&v, 0, sizeof(DBT));
209ebfedea0SLionel Sambuc     k.data = key.data;
210ebfedea0SLionel Sambuc     k.size = key.length;
211ebfedea0SLionel Sambuc     k.flags = 0;
212ebfedea0SLionel Sambuc     v.data = value.data;
213ebfedea0SLionel Sambuc     v.size = value.length;
214ebfedea0SLionel Sambuc     v.flags = 0;
215ebfedea0SLionel Sambuc     if ((code = (*db->hdb_lock)(context, db, HDB_WLOCK)))
216ebfedea0SLionel Sambuc 	return code;
217ebfedea0SLionel Sambuc     code = (*d->put)(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE);
218ebfedea0SLionel Sambuc     (*db->hdb_unlock)(context, db);
219ebfedea0SLionel Sambuc     if(code == DB_KEYEXIST)
220ebfedea0SLionel Sambuc 	return HDB_ERR_EXISTS;
221ebfedea0SLionel Sambuc     if(code)
222ebfedea0SLionel Sambuc 	return errno;
223ebfedea0SLionel Sambuc     return 0;
224ebfedea0SLionel Sambuc }
225ebfedea0SLionel Sambuc 
226ebfedea0SLionel Sambuc static krb5_error_code
DB__del(krb5_context context,HDB * db,krb5_data key)227ebfedea0SLionel Sambuc DB__del(krb5_context context, HDB *db, krb5_data key)
228ebfedea0SLionel Sambuc {
229ebfedea0SLionel Sambuc     DB *d = (DB*)db->hdb_db;
230ebfedea0SLionel Sambuc     DBT k;
231ebfedea0SLionel Sambuc     krb5_error_code code;
232ebfedea0SLionel Sambuc     memset(&k, 0, sizeof(DBT));
233ebfedea0SLionel Sambuc     k.data = key.data;
234ebfedea0SLionel Sambuc     k.size = key.length;
235ebfedea0SLionel Sambuc     k.flags = 0;
236ebfedea0SLionel Sambuc     code = (*db->hdb_lock)(context, db, HDB_WLOCK);
237ebfedea0SLionel Sambuc     if(code)
238ebfedea0SLionel Sambuc 	return code;
239ebfedea0SLionel Sambuc     code = (*d->del)(d, NULL, &k, 0);
240ebfedea0SLionel Sambuc     (*db->hdb_unlock)(context, db);
241ebfedea0SLionel Sambuc     if(code == DB_NOTFOUND)
242ebfedea0SLionel Sambuc 	return HDB_ERR_NOENTRY;
243ebfedea0SLionel Sambuc     if(code)
244ebfedea0SLionel Sambuc 	return code;
245ebfedea0SLionel Sambuc     return 0;
246ebfedea0SLionel Sambuc }
247ebfedea0SLionel Sambuc 
248ebfedea0SLionel Sambuc static krb5_error_code
DB_open(krb5_context context,HDB * db,int flags,mode_t mode)249ebfedea0SLionel Sambuc DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
250ebfedea0SLionel Sambuc {
251ebfedea0SLionel Sambuc     DBC *dbc = NULL;
252ebfedea0SLionel Sambuc     char *fn;
253ebfedea0SLionel Sambuc     krb5_error_code ret;
254ebfedea0SLionel Sambuc     DB *d;
255ebfedea0SLionel Sambuc     int myflags = 0;
256ebfedea0SLionel Sambuc 
257ebfedea0SLionel Sambuc     if (flags & O_CREAT)
258ebfedea0SLionel Sambuc       myflags |= DB_CREATE;
259ebfedea0SLionel Sambuc 
260ebfedea0SLionel Sambuc     if (flags & O_EXCL)
261ebfedea0SLionel Sambuc       myflags |= DB_EXCL;
262ebfedea0SLionel Sambuc 
263ebfedea0SLionel Sambuc     if((flags & O_ACCMODE) == O_RDONLY)
264ebfedea0SLionel Sambuc       myflags |= DB_RDONLY;
265ebfedea0SLionel Sambuc 
266ebfedea0SLionel Sambuc     if (flags & O_TRUNC)
267ebfedea0SLionel Sambuc       myflags |= DB_TRUNCATE;
268ebfedea0SLionel Sambuc 
269ebfedea0SLionel Sambuc     asprintf(&fn, "%s.db", db->hdb_name);
270ebfedea0SLionel Sambuc     if (fn == NULL) {
271ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
272ebfedea0SLionel Sambuc 	return ENOMEM;
273ebfedea0SLionel Sambuc     }
274ebfedea0SLionel Sambuc     if (db_create(&d, NULL, 0) != 0) {
275ebfedea0SLionel Sambuc 	free(fn);
276ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
277ebfedea0SLionel Sambuc 	return ENOMEM;
278ebfedea0SLionel Sambuc     }
279ebfedea0SLionel Sambuc     db->hdb_db = d;
280ebfedea0SLionel Sambuc 
281*0a6a1f1dSLionel Sambuc #if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 1))
282ebfedea0SLionel Sambuc     ret = (*d->open)(db->hdb_db, NULL, fn, NULL, DB_BTREE, myflags, mode);
283ebfedea0SLionel Sambuc #else
284ebfedea0SLionel Sambuc     ret = (*d->open)(db->hdb_db, fn, NULL, DB_BTREE, myflags, mode);
285ebfedea0SLionel Sambuc #endif
286ebfedea0SLionel Sambuc 
287ebfedea0SLionel Sambuc     if (ret == ENOENT) {
288ebfedea0SLionel Sambuc 	/* try to open without .db extension */
289*0a6a1f1dSLionel Sambuc #if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 1))
290ebfedea0SLionel Sambuc 	ret = (*d->open)(db->hdb_db, NULL, db->hdb_name, NULL, DB_BTREE,
291ebfedea0SLionel Sambuc 			 myflags, mode);
292ebfedea0SLionel Sambuc #else
293ebfedea0SLionel Sambuc 	ret = (*d->open)(db->hdb_db, db->hdb_name, NULL, DB_BTREE,
294ebfedea0SLionel Sambuc 			 myflags, mode);
295ebfedea0SLionel Sambuc #endif
296ebfedea0SLionel Sambuc     }
297ebfedea0SLionel Sambuc 
298ebfedea0SLionel Sambuc     if (ret) {
299ebfedea0SLionel Sambuc 	free(fn);
300ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "opening %s: %s",
301ebfedea0SLionel Sambuc 			      db->hdb_name, strerror(ret));
302ebfedea0SLionel Sambuc 	return ret;
303ebfedea0SLionel Sambuc     }
304ebfedea0SLionel Sambuc     free(fn);
305ebfedea0SLionel Sambuc 
306ebfedea0SLionel Sambuc     ret = (*d->cursor)(d, NULL, &dbc, 0);
307ebfedea0SLionel Sambuc     if (ret) {
308ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "d->cursor: %s", strerror(ret));
309ebfedea0SLionel Sambuc         return ret;
310ebfedea0SLionel Sambuc     }
311ebfedea0SLionel Sambuc     db->hdb_dbc = dbc;
312ebfedea0SLionel Sambuc 
313ebfedea0SLionel Sambuc     if((flags & O_ACCMODE) == O_RDONLY)
314ebfedea0SLionel Sambuc 	ret = hdb_check_db_format(context, db);
315ebfedea0SLionel Sambuc     else
316ebfedea0SLionel Sambuc 	ret = hdb_init_db(context, db);
317ebfedea0SLionel Sambuc     if(ret == HDB_ERR_NOENTRY)
318ebfedea0SLionel Sambuc 	return 0;
319ebfedea0SLionel Sambuc     if (ret) {
320ebfedea0SLionel Sambuc 	DB_close(context, db);
321ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "hdb_open: failed %s database %s",
322ebfedea0SLionel Sambuc 			       (flags & O_ACCMODE) == O_RDONLY ?
323ebfedea0SLionel Sambuc 			       "checking format of" : "initialize",
324ebfedea0SLionel Sambuc 			       db->hdb_name);
325ebfedea0SLionel Sambuc     }
326ebfedea0SLionel Sambuc 
327ebfedea0SLionel Sambuc     return ret;
328ebfedea0SLionel Sambuc }
329ebfedea0SLionel Sambuc 
330ebfedea0SLionel Sambuc krb5_error_code
hdb_db_create(krb5_context context,HDB ** db,const char * filename)331ebfedea0SLionel Sambuc hdb_db_create(krb5_context context, HDB **db,
332ebfedea0SLionel Sambuc 	      const char *filename)
333ebfedea0SLionel Sambuc {
334ebfedea0SLionel Sambuc     *db = calloc(1, sizeof(**db));
335ebfedea0SLionel Sambuc     if (*db == NULL) {
336ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
337ebfedea0SLionel Sambuc 	return ENOMEM;
338ebfedea0SLionel Sambuc     }
339ebfedea0SLionel Sambuc 
340ebfedea0SLionel Sambuc     (*db)->hdb_db = NULL;
341ebfedea0SLionel Sambuc     (*db)->hdb_name = strdup(filename);
342ebfedea0SLionel Sambuc     if ((*db)->hdb_name == NULL) {
343ebfedea0SLionel Sambuc 	free(*db);
344ebfedea0SLionel Sambuc 	*db = NULL;
345ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
346ebfedea0SLionel Sambuc 	return ENOMEM;
347ebfedea0SLionel Sambuc     }
348ebfedea0SLionel Sambuc     (*db)->hdb_master_key_set = 0;
349ebfedea0SLionel Sambuc     (*db)->hdb_openp = 0;
350ebfedea0SLionel Sambuc     (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
351ebfedea0SLionel Sambuc     (*db)->hdb_open  = DB_open;
352ebfedea0SLionel Sambuc     (*db)->hdb_close = DB_close;
353ebfedea0SLionel Sambuc     (*db)->hdb_fetch_kvno = _hdb_fetch_kvno;
354ebfedea0SLionel Sambuc     (*db)->hdb_store = _hdb_store;
355ebfedea0SLionel Sambuc     (*db)->hdb_remove = _hdb_remove;
356ebfedea0SLionel Sambuc     (*db)->hdb_firstkey = DB_firstkey;
357ebfedea0SLionel Sambuc     (*db)->hdb_nextkey= DB_nextkey;
358ebfedea0SLionel Sambuc     (*db)->hdb_lock = DB_lock;
359ebfedea0SLionel Sambuc     (*db)->hdb_unlock = DB_unlock;
360ebfedea0SLionel Sambuc     (*db)->hdb_rename = DB_rename;
361ebfedea0SLionel Sambuc     (*db)->hdb__get = DB__get;
362ebfedea0SLionel Sambuc     (*db)->hdb__put = DB__put;
363ebfedea0SLionel Sambuc     (*db)->hdb__del = DB__del;
364ebfedea0SLionel Sambuc     (*db)->hdb_destroy = DB_destroy;
365ebfedea0SLionel Sambuc     return 0;
366ebfedea0SLionel Sambuc }
367ebfedea0SLionel Sambuc #endif /* HAVE_DB3 */
368