1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray * All rights reserved.
5b528cefcSMark Murray *
6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray * modification, are permitted provided that the following conditions
8b528cefcSMark Murray * are met:
9b528cefcSMark Murray *
10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray *
13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray * documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray *
17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray * may be used to endorse or promote products derived from this software
19b528cefcSMark Murray * without specific prior written permission.
20b528cefcSMark Murray *
21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray * SUCH DAMAGE.
32b528cefcSMark Murray */
33b528cefcSMark Murray
34b528cefcSMark Murray #include "hdb_locl.h"
35b528cefcSMark Murray
364137ff4cSJacques Vidrine #if HAVE_NDBM
374137ff4cSJacques Vidrine
384137ff4cSJacques Vidrine #if defined(HAVE_GDBM_NDBM_H)
394137ff4cSJacques Vidrine #include <gdbm/ndbm.h>
40*ae771770SStanislav Sedov #define WRITE_SUPPORT 1
414137ff4cSJacques Vidrine #elif defined(HAVE_NDBM_H)
424137ff4cSJacques Vidrine #include <ndbm.h>
434137ff4cSJacques Vidrine #elif defined(HAVE_DBM_H)
44*ae771770SStanislav Sedov #define WRITE_SUPPORT 1
454137ff4cSJacques Vidrine #include <dbm.h>
464137ff4cSJacques Vidrine #endif
47b528cefcSMark Murray
48b528cefcSMark Murray struct ndbm_db {
49b528cefcSMark Murray DBM *db;
50b528cefcSMark Murray int lock_fd;
51b528cefcSMark Murray };
52b528cefcSMark Murray
53b528cefcSMark Murray static krb5_error_code
NDBM_destroy(krb5_context context,HDB * db)54b528cefcSMark Murray NDBM_destroy(krb5_context context, HDB *db)
55b528cefcSMark Murray {
56*ae771770SStanislav Sedov hdb_clear_master_key (context, db);
57c19800e8SDoug Rabson free(db->hdb_name);
58b528cefcSMark Murray free(db);
59b528cefcSMark Murray return 0;
60b528cefcSMark Murray }
61b528cefcSMark Murray
62b528cefcSMark Murray static krb5_error_code
NDBM_lock(krb5_context context,HDB * db,int operation)63b528cefcSMark Murray NDBM_lock(krb5_context context, HDB *db, int operation)
64b528cefcSMark Murray {
65c19800e8SDoug Rabson struct ndbm_db *d = db->hdb_db;
66b528cefcSMark Murray return hdb_lock(d->lock_fd, operation);
67b528cefcSMark Murray }
68b528cefcSMark Murray
69b528cefcSMark Murray static krb5_error_code
NDBM_unlock(krb5_context context,HDB * db)70b528cefcSMark Murray NDBM_unlock(krb5_context context, HDB *db)
71b528cefcSMark Murray {
72c19800e8SDoug Rabson struct ndbm_db *d = db->hdb_db;
73b528cefcSMark Murray return hdb_unlock(d->lock_fd);
74b528cefcSMark Murray }
75b528cefcSMark Murray
76b528cefcSMark Murray static krb5_error_code
NDBM_seq(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry,int first)77b528cefcSMark Murray NDBM_seq(krb5_context context, HDB *db,
78c19800e8SDoug Rabson unsigned flags, hdb_entry_ex *entry, int first)
79b528cefcSMark Murray
80b528cefcSMark Murray {
81c19800e8SDoug Rabson struct ndbm_db *d = (struct ndbm_db *)db->hdb_db;
82b528cefcSMark Murray datum key, value;
83b528cefcSMark Murray krb5_data key_data, data;
845e9cd1aeSAssar Westerlund krb5_error_code ret = 0;
85b528cefcSMark Murray
86b528cefcSMark Murray if(first)
87b528cefcSMark Murray key = dbm_firstkey(d->db);
88b528cefcSMark Murray else
89b528cefcSMark Murray key = dbm_nextkey(d->db);
90b528cefcSMark Murray if(key.dptr == NULL)
91b528cefcSMark Murray return HDB_ERR_NOENTRY;
92b528cefcSMark Murray key_data.data = key.dptr;
93b528cefcSMark Murray key_data.length = key.dsize;
94c19800e8SDoug Rabson ret = db->hdb_lock(context, db, HDB_RLOCK);
95b528cefcSMark Murray if(ret) return ret;
96b528cefcSMark Murray value = dbm_fetch(d->db, key);
97c19800e8SDoug Rabson db->hdb_unlock(context, db);
98b528cefcSMark Murray data.data = value.dptr;
99b528cefcSMark Murray data.length = value.dsize;
100c19800e8SDoug Rabson memset(entry, 0, sizeof(*entry));
101c19800e8SDoug Rabson if(hdb_value2entry(context, &data, &entry->entry))
102b528cefcSMark Murray return NDBM_seq(context, db, flags, entry, 0);
103c19800e8SDoug Rabson if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) {
104c19800e8SDoug Rabson ret = hdb_unseal_keys (context, db, &entry->entry);
1055e9cd1aeSAssar Westerlund if (ret)
1065e9cd1aeSAssar Westerlund hdb_free_entry (context, entry);
1075e9cd1aeSAssar Westerlund }
108c19800e8SDoug Rabson if (ret == 0 && entry->entry.principal == NULL) {
109c19800e8SDoug Rabson entry->entry.principal = malloc (sizeof(*entry->entry.principal));
110c19800e8SDoug Rabson if (entry->entry.principal == NULL) {
1115e9cd1aeSAssar Westerlund hdb_free_entry (context, entry);
112*ae771770SStanislav Sedov ret = ENOMEM;
113*ae771770SStanislav Sedov krb5_set_error_message(context, ret, "malloc: out of memory");
1145e9cd1aeSAssar Westerlund } else {
115c19800e8SDoug Rabson hdb_key2principal (context, &key_data, entry->entry.principal);
116b528cefcSMark Murray }
1175e9cd1aeSAssar Westerlund }
1185e9cd1aeSAssar Westerlund return ret;
119b528cefcSMark Murray }
120b528cefcSMark Murray
121b528cefcSMark Murray
122b528cefcSMark Murray static krb5_error_code
NDBM_firstkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)123c19800e8SDoug Rabson NDBM_firstkey(krb5_context context, HDB *db,unsigned flags,hdb_entry_ex *entry)
124b528cefcSMark Murray {
125b528cefcSMark Murray return NDBM_seq(context, db, flags, entry, 1);
126b528cefcSMark Murray }
127b528cefcSMark Murray
128b528cefcSMark Murray
129b528cefcSMark Murray static krb5_error_code
NDBM_nextkey(krb5_context context,HDB * db,unsigned flags,hdb_entry_ex * entry)130c19800e8SDoug Rabson NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry_ex *entry)
131b528cefcSMark Murray {
132b528cefcSMark Murray return NDBM_seq(context, db, flags, entry, 0);
133b528cefcSMark Murray }
134b528cefcSMark Murray
135b528cefcSMark Murray static krb5_error_code
open_lock_file(krb5_context context,const char * db_name,int * fd)136*ae771770SStanislav Sedov open_lock_file(krb5_context context, const char *db_name, int *fd)
137b528cefcSMark Murray {
138*ae771770SStanislav Sedov char *lock_file;
139b528cefcSMark Murray
140b528cefcSMark Murray /* lock old and new databases */
141*ae771770SStanislav Sedov asprintf(&lock_file, "%s.lock", db_name);
142*ae771770SStanislav Sedov if(lock_file == NULL) {
143*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
1444137ff4cSJacques Vidrine return ENOMEM;
1454137ff4cSJacques Vidrine }
146*ae771770SStanislav Sedov
147*ae771770SStanislav Sedov *fd = open(lock_file, O_RDWR | O_CREAT, 0600);
148*ae771770SStanislav Sedov free(lock_file);
149*ae771770SStanislav Sedov if(*fd < 0) {
150*ae771770SStanislav Sedov int ret = errno;
151*ae771770SStanislav Sedov krb5_set_error_message(context, ret, "open(%s): %s", lock_file,
1524137ff4cSJacques Vidrine strerror(ret));
153b528cefcSMark Murray return ret;
154b528cefcSMark Murray }
155*ae771770SStanislav Sedov return 0;
156*ae771770SStanislav Sedov }
157*ae771770SStanislav Sedov
158*ae771770SStanislav Sedov
159*ae771770SStanislav Sedov static krb5_error_code
NDBM_rename(krb5_context context,HDB * db,const char * new_name)160*ae771770SStanislav Sedov NDBM_rename(krb5_context context, HDB *db, const char *new_name)
161*ae771770SStanislav Sedov {
162*ae771770SStanislav Sedov int ret;
163*ae771770SStanislav Sedov char *old_dir, *old_pag, *new_dir, *new_pag;
164*ae771770SStanislav Sedov int old_lock_fd, new_lock_fd;
165*ae771770SStanislav Sedov
166*ae771770SStanislav Sedov /* lock old and new databases */
167*ae771770SStanislav Sedov ret = open_lock_file(context, db->hdb_name, &old_lock_fd);
168*ae771770SStanislav Sedov if (ret)
169*ae771770SStanislav Sedov return ret;
170*ae771770SStanislav Sedov
171*ae771770SStanislav Sedov ret = hdb_lock(old_lock_fd, HDB_WLOCK);
172b528cefcSMark Murray if(ret) {
173*ae771770SStanislav Sedov close(old_lock_fd);
174*ae771770SStanislav Sedov return ret;
175*ae771770SStanislav Sedov }
176*ae771770SStanislav Sedov
177*ae771770SStanislav Sedov ret = open_lock_file(context, new_name, &new_lock_fd);
178*ae771770SStanislav Sedov if (ret) {
179*ae771770SStanislav Sedov hdb_unlock(old_lock_fd);
180*ae771770SStanislav Sedov close(old_lock_fd);
181*ae771770SStanislav Sedov return ret;
182*ae771770SStanislav Sedov }
183*ae771770SStanislav Sedov
184*ae771770SStanislav Sedov ret = hdb_lock(new_lock_fd, HDB_WLOCK);
185*ae771770SStanislav Sedov if(ret) {
186*ae771770SStanislav Sedov hdb_unlock(old_lock_fd);
187*ae771770SStanislav Sedov close(old_lock_fd);
188*ae771770SStanislav Sedov close(new_lock_fd);
189b528cefcSMark Murray return ret;
190b528cefcSMark Murray }
191b528cefcSMark Murray
192c19800e8SDoug Rabson asprintf(&old_dir, "%s.dir", db->hdb_name);
193c19800e8SDoug Rabson asprintf(&old_pag, "%s.pag", db->hdb_name);
194b528cefcSMark Murray asprintf(&new_dir, "%s.dir", new_name);
195b528cefcSMark Murray asprintf(&new_pag, "%s.pag", new_name);
196b528cefcSMark Murray
197b528cefcSMark Murray ret = rename(old_dir, new_dir) || rename(old_pag, new_pag);
198*ae771770SStanislav Sedov if (ret) {
199*ae771770SStanislav Sedov ret = errno;
200*ae771770SStanislav Sedov if (ret == 0)
201*ae771770SStanislav Sedov ret = EPERM;
202*ae771770SStanislav Sedov krb5_set_error_message(context, ret, "rename: %s", strerror(ret));
203*ae771770SStanislav Sedov }
204*ae771770SStanislav Sedov
205b528cefcSMark Murray free(old_dir);
206b528cefcSMark Murray free(old_pag);
207b528cefcSMark Murray free(new_dir);
208b528cefcSMark Murray free(new_pag);
209b528cefcSMark Murray
210*ae771770SStanislav Sedov hdb_unlock(new_lock_fd);
211*ae771770SStanislav Sedov hdb_unlock(old_lock_fd);
212*ae771770SStanislav Sedov close(new_lock_fd);
213*ae771770SStanislav Sedov close(old_lock_fd);
214*ae771770SStanislav Sedov
215*ae771770SStanislav Sedov if(ret)
2164137ff4cSJacques Vidrine return ret;
217b528cefcSMark Murray
218c19800e8SDoug Rabson free(db->hdb_name);
219c19800e8SDoug Rabson db->hdb_name = strdup(new_name);
220b528cefcSMark Murray return 0;
221b528cefcSMark Murray }
222b528cefcSMark Murray
223b528cefcSMark Murray static krb5_error_code
NDBM__get(krb5_context context,HDB * db,krb5_data key,krb5_data * reply)224b528cefcSMark Murray NDBM__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply)
225b528cefcSMark Murray {
226c19800e8SDoug Rabson struct ndbm_db *d = (struct ndbm_db *)db->hdb_db;
227b528cefcSMark Murray datum k, v;
228b528cefcSMark Murray int code;
229b528cefcSMark Murray
230b528cefcSMark Murray k.dptr = key.data;
231b528cefcSMark Murray k.dsize = key.length;
232c19800e8SDoug Rabson code = db->hdb_lock(context, db, HDB_RLOCK);
233b528cefcSMark Murray if(code)
234b528cefcSMark Murray return code;
235b528cefcSMark Murray v = dbm_fetch(d->db, k);
236c19800e8SDoug Rabson db->hdb_unlock(context, db);
237b528cefcSMark Murray if(v.dptr == NULL)
238b528cefcSMark Murray return HDB_ERR_NOENTRY;
239b528cefcSMark Murray
240b528cefcSMark Murray krb5_data_copy(reply, v.dptr, v.dsize);
241b528cefcSMark Murray return 0;
242b528cefcSMark Murray }
243b528cefcSMark Murray
244b528cefcSMark Murray static krb5_error_code
NDBM__put(krb5_context context,HDB * db,int replace,krb5_data key,krb5_data value)245b528cefcSMark Murray NDBM__put(krb5_context context, HDB *db, int replace,
246b528cefcSMark Murray krb5_data key, krb5_data value)
247b528cefcSMark Murray {
248*ae771770SStanislav Sedov #ifdef WRITE_SUPPORT
249c19800e8SDoug Rabson struct ndbm_db *d = (struct ndbm_db *)db->hdb_db;
250b528cefcSMark Murray datum k, v;
251b528cefcSMark Murray int code;
252b528cefcSMark Murray
253b528cefcSMark Murray k.dptr = key.data;
254b528cefcSMark Murray k.dsize = key.length;
255b528cefcSMark Murray v.dptr = value.data;
256b528cefcSMark Murray v.dsize = value.length;
257b528cefcSMark Murray
258c19800e8SDoug Rabson code = db->hdb_lock(context, db, HDB_WLOCK);
259b528cefcSMark Murray if(code)
260b528cefcSMark Murray return code;
261b528cefcSMark Murray code = dbm_store(d->db, k, v, replace ? DBM_REPLACE : DBM_INSERT);
262c19800e8SDoug Rabson db->hdb_unlock(context, db);
263b528cefcSMark Murray if(code == 1)
264b528cefcSMark Murray return HDB_ERR_EXISTS;
265b528cefcSMark Murray if (code < 0)
266b528cefcSMark Murray return code;
267b528cefcSMark Murray return 0;
268*ae771770SStanislav Sedov #else
269*ae771770SStanislav Sedov return HDB_ERR_NO_WRITE_SUPPORT;
270*ae771770SStanislav Sedov #endif
271b528cefcSMark Murray }
272b528cefcSMark Murray
273b528cefcSMark Murray static krb5_error_code
NDBM__del(krb5_context context,HDB * db,krb5_data key)274b528cefcSMark Murray NDBM__del(krb5_context context, HDB *db, krb5_data key)
275b528cefcSMark Murray {
276c19800e8SDoug Rabson struct ndbm_db *d = (struct ndbm_db *)db->hdb_db;
277b528cefcSMark Murray datum k;
278b528cefcSMark Murray int code;
279b528cefcSMark Murray krb5_error_code ret;
280b528cefcSMark Murray
281b528cefcSMark Murray k.dptr = key.data;
282b528cefcSMark Murray k.dsize = key.length;
283c19800e8SDoug Rabson ret = db->hdb_lock(context, db, HDB_WLOCK);
284b528cefcSMark Murray if(ret) return ret;
285b528cefcSMark Murray code = dbm_delete(d->db, k);
286c19800e8SDoug Rabson db->hdb_unlock(context, db);
287b528cefcSMark Murray if(code < 0)
288b528cefcSMark Murray return errno;
289b528cefcSMark Murray return 0;
290b528cefcSMark Murray }
291b528cefcSMark Murray
292c19800e8SDoug Rabson
293c19800e8SDoug Rabson static krb5_error_code
NDBM_close(krb5_context context,HDB * db)294c19800e8SDoug Rabson NDBM_close(krb5_context context, HDB *db)
295c19800e8SDoug Rabson {
296c19800e8SDoug Rabson struct ndbm_db *d = db->hdb_db;
297c19800e8SDoug Rabson dbm_close(d->db);
298c19800e8SDoug Rabson close(d->lock_fd);
299c19800e8SDoug Rabson free(d);
300c19800e8SDoug Rabson return 0;
301c19800e8SDoug Rabson }
302c19800e8SDoug Rabson
303b528cefcSMark Murray static krb5_error_code
NDBM_open(krb5_context context,HDB * db,int flags,mode_t mode)304b528cefcSMark Murray NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
305b528cefcSMark Murray {
306b528cefcSMark Murray krb5_error_code ret;
307b528cefcSMark Murray struct ndbm_db *d = malloc(sizeof(*d));
308b528cefcSMark Murray
3094137ff4cSJacques Vidrine if(d == NULL) {
310*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
311b528cefcSMark Murray return ENOMEM;
3124137ff4cSJacques Vidrine }
313*ae771770SStanislav Sedov
314c19800e8SDoug Rabson d->db = dbm_open((char*)db->hdb_name, flags, mode);
315b528cefcSMark Murray if(d->db == NULL){
3164137ff4cSJacques Vidrine ret = errno;
317b528cefcSMark Murray free(d);
318*ae771770SStanislav Sedov krb5_set_error_message(context, ret, "dbm_open(%s): %s", db->hdb_name,
3194137ff4cSJacques Vidrine strerror(ret));
3204137ff4cSJacques Vidrine return ret;
321b528cefcSMark Murray }
322*ae771770SStanislav Sedov
323*ae771770SStanislav Sedov ret = open_lock_file(context, db->hdb_name, &d->lock_fd);
324*ae771770SStanislav Sedov if (ret) {
3254137ff4cSJacques Vidrine ret = errno;
326b528cefcSMark Murray dbm_close(d->db);
327b528cefcSMark Murray free(d);
328*ae771770SStanislav Sedov krb5_set_error_message(context, ret, "open(lock file): %s",
3294137ff4cSJacques Vidrine strerror(ret));
3304137ff4cSJacques Vidrine return ret;
331b528cefcSMark Murray }
332*ae771770SStanislav Sedov
333c19800e8SDoug Rabson db->hdb_db = d;
334b528cefcSMark Murray if((flags & O_ACCMODE) == O_RDONLY)
335b528cefcSMark Murray ret = hdb_check_db_format(context, db);
336b528cefcSMark Murray else
337b528cefcSMark Murray ret = hdb_init_db(context, db);
338b528cefcSMark Murray if(ret == HDB_ERR_NOENTRY)
339b528cefcSMark Murray return 0;
340c19800e8SDoug Rabson if (ret) {
341c19800e8SDoug Rabson NDBM_close(context, db);
342*ae771770SStanislav Sedov krb5_set_error_message(context, ret, "hdb_open: failed %s database %s",
343c19800e8SDoug Rabson (flags & O_ACCMODE) == O_RDONLY ?
344c19800e8SDoug Rabson "checking format of" : "initialize",
345c19800e8SDoug Rabson db->hdb_name);
346b528cefcSMark Murray }
347c19800e8SDoug Rabson return ret;
348b528cefcSMark Murray }
349b528cefcSMark Murray
350b528cefcSMark Murray krb5_error_code
hdb_ndbm_create(krb5_context context,HDB ** db,const char * filename)351b528cefcSMark Murray hdb_ndbm_create(krb5_context context, HDB **db,
352b528cefcSMark Murray const char *filename)
353b528cefcSMark Murray {
354c19800e8SDoug Rabson *db = calloc(1, sizeof(**db));
3554137ff4cSJacques Vidrine if (*db == NULL) {
356*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
357b528cefcSMark Murray return ENOMEM;
3584137ff4cSJacques Vidrine }
359b528cefcSMark Murray
360c19800e8SDoug Rabson (*db)->hdb_db = NULL;
361c19800e8SDoug Rabson (*db)->hdb_name = strdup(filename);
362c19800e8SDoug Rabson if ((*db)->hdb_name == NULL) {
3634137ff4cSJacques Vidrine free(*db);
3644137ff4cSJacques Vidrine *db = NULL;
365*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
3664137ff4cSJacques Vidrine return ENOMEM;
3674137ff4cSJacques Vidrine }
368c19800e8SDoug Rabson (*db)->hdb_master_key_set = 0;
369c19800e8SDoug Rabson (*db)->hdb_openp = 0;
370*ae771770SStanislav Sedov (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
371c19800e8SDoug Rabson (*db)->hdb_open = NDBM_open;
372c19800e8SDoug Rabson (*db)->hdb_close = NDBM_close;
373*ae771770SStanislav Sedov (*db)->hdb_fetch_kvno = _hdb_fetch_kvno;
374c19800e8SDoug Rabson (*db)->hdb_store = _hdb_store;
375c19800e8SDoug Rabson (*db)->hdb_remove = _hdb_remove;
376c19800e8SDoug Rabson (*db)->hdb_firstkey = NDBM_firstkey;
377c19800e8SDoug Rabson (*db)->hdb_nextkey= NDBM_nextkey;
378c19800e8SDoug Rabson (*db)->hdb_lock = NDBM_lock;
379c19800e8SDoug Rabson (*db)->hdb_unlock = NDBM_unlock;
380c19800e8SDoug Rabson (*db)->hdb_rename = NDBM_rename;
381c19800e8SDoug Rabson (*db)->hdb__get = NDBM__get;
382c19800e8SDoug Rabson (*db)->hdb__put = NDBM__put;
383c19800e8SDoug Rabson (*db)->hdb__del = NDBM__del;
384c19800e8SDoug Rabson (*db)->hdb_destroy = NDBM_destroy;
385b528cefcSMark Murray return 0;
386b528cefcSMark Murray }
387b528cefcSMark Murray
3884137ff4cSJacques Vidrine #endif /* HAVE_NDBM */
389