add berkeley db3 interface. contributed by Derrick J Brashear <shadow@dementia.org>
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@8312 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		| @@ -28,6 +28,7 @@ libhdb_la_SOURCES = 				\ | |||||||
| 		    hdb.c			\ | 		    hdb.c			\ | ||||||
| 		    common.c			\ | 		    common.c			\ | ||||||
| 		    db.c			\ | 		    db.c			\ | ||||||
|  | 		    db3.c			\ | ||||||
| 		    ndbm.c			\ | 		    ndbm.c			\ | ||||||
| 		    hdb-ldap.c			\ | 		    hdb-ldap.c			\ | ||||||
| 		    print.c			\ | 		    print.c			\ | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ | |||||||
|  |  | ||||||
| RCSID("$Id$"); | RCSID("$Id$"); | ||||||
|  |  | ||||||
| #ifdef HAVE_DB_H | #if defined(HAVE_DB_H) && DB_VERSION_MAJOR < 3 | ||||||
|  |  | ||||||
| static krb5_error_code | static krb5_error_code | ||||||
| DB_close(krb5_context context, HDB *db) | DB_close(krb5_context context, HDB *db) | ||||||
|   | |||||||
							
								
								
									
										297
									
								
								lib/hdb/db3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								lib/hdb/db3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,297 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H<>gskolan | ||||||
|  |  * (Royal Institute of Technology, Stockholm, Sweden).  | ||||||
|  |  * All rights reserved.  | ||||||
|  |  * | ||||||
|  |  * Redistribution and use in source and binary forms, with or without  | ||||||
|  |  * modification, are permitted provided that the following conditions  | ||||||
|  |  * are met:  | ||||||
|  |  * | ||||||
|  |  * 1. Redistributions of source code must retain the above copyright  | ||||||
|  |  *    notice, this list of conditions and the following disclaimer.  | ||||||
|  |  * | ||||||
|  |  * 2. Redistributions in binary form must reproduce the above copyright  | ||||||
|  |  *    notice, this list of conditions and the following disclaimer in the  | ||||||
|  |  *    documentation and/or other materials provided with the distribution.  | ||||||
|  |  * | ||||||
|  |  * 3. Neither the name of the Institute nor the names of its contributors  | ||||||
|  |  *    may be used to endorse or promote products derived from this software  | ||||||
|  |  *    without specific prior written permission.  | ||||||
|  |  * | ||||||
|  |  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  | ||||||
|  |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | ||||||
|  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  | ||||||
|  |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  | ||||||
|  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  | ||||||
|  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  | ||||||
|  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | ||||||
|  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  | ||||||
|  |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  | ||||||
|  |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  | ||||||
|  |  * SUCH DAMAGE.  | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "hdb_locl.h" | ||||||
|  |  | ||||||
|  | RCSID("$Id$"); | ||||||
|  |  | ||||||
|  | #if defined(HAVE_DB_H) && DB_VERSION_MAJOR == 3 | ||||||
|  | static krb5_error_code | ||||||
|  | DB_close(krb5_context context, HDB *db) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     d->close(d, 0); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_destroy(krb5_context context, HDB *db) | ||||||
|  | { | ||||||
|  |     krb5_error_code ret; | ||||||
|  |  | ||||||
|  |     ret = hdb_clear_master_key (context, db); | ||||||
|  |     free(db->name); | ||||||
|  |     free(db); | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_lock(krb5_context context, HDB *db, int operation) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     int fd; | ||||||
|  |     if ((*d->fd)(d, &fd)) | ||||||
|  | 	return HDB_ERR_CANT_LOCK_DB; | ||||||
|  |     return hdb_lock(fd, operation); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_unlock(krb5_context context, HDB *db) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     int fd; | ||||||
|  |     if ((*d->fd)(d, &fd)) | ||||||
|  | 	return HDB_ERR_CANT_LOCK_DB; | ||||||
|  |     return hdb_unlock(fd); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_seq(krb5_context context, HDB *db, | ||||||
|  |        unsigned flags, hdb_entry *entry, int flag) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     DBT key, value; | ||||||
|  |     DBC *dbcp; | ||||||
|  |     krb5_data key_data, data; | ||||||
|  |     int code; | ||||||
|  |  | ||||||
|  |     memset(&key, 0, sizeof(DBT)); | ||||||
|  |     memset(&value, 0, sizeof(DBT)); | ||||||
|  |     if (db->lock(context, db, HDB_RLOCK)) | ||||||
|  | 	return HDB_ERR_DB_INUSE; | ||||||
|  |     code = d->cursor(d, NULL, (DBC **)&db->dbc, 0); | ||||||
|  |     if (code) | ||||||
|  | 	return code; | ||||||
|  |     dbcp=db->dbc; | ||||||
|  |     code = dbcp->c_get(dbcp, &key, &value, flag); | ||||||
|  |     db->unlock(context, db); /* XXX check value */ | ||||||
|  |     if (code == DB_NOTFOUND) | ||||||
|  | 	return HDB_ERR_NOENTRY; | ||||||
|  |     if (code) | ||||||
|  | 	return code; | ||||||
|  |  | ||||||
|  |     key_data.data = key.data; | ||||||
|  |     key_data.length = key.size; | ||||||
|  |     data.data = value.data; | ||||||
|  |     data.length = value.size; | ||||||
|  |     if (hdb_value2entry(context, &data, entry)) | ||||||
|  | 	return DB_seq(context, db, flags, entry, DB_NEXT); | ||||||
|  |     if (db->master_key_set && (flags & HDB_F_DECRYPT)) | ||||||
|  | 	hdb_unseal_keys (db, entry); | ||||||
|  |     if (entry->principal == NULL) { | ||||||
|  | 	entry->principal = malloc(sizeof(*entry->principal)); | ||||||
|  | 	hdb_key2principal(context, &key_data, entry->principal); | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) | ||||||
|  | { | ||||||
|  |     return DB_seq(context, db, flags, entry, DB_FIRST); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) | ||||||
|  | { | ||||||
|  |     return DB_seq(context, db, flags, entry, DB_NEXT); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_rename(krb5_context context, HDB *db, const char *new_name) | ||||||
|  | { | ||||||
|  |     int ret; | ||||||
|  |     char *old, *new; | ||||||
|  |  | ||||||
|  |     asprintf(&old, "%s.db", db->name); | ||||||
|  |     asprintf(&new, "%s.db", new_name); | ||||||
|  |     ret = rename(old, new); | ||||||
|  |     free(old); | ||||||
|  |     free(new); | ||||||
|  |     if(ret) | ||||||
|  | 	return errno; | ||||||
|  |      | ||||||
|  |     free(db->name); | ||||||
|  |     db->name = strdup(new_name); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     DBT k, v; | ||||||
|  |     int code; | ||||||
|  |  | ||||||
|  |     memset(&k, 0, sizeof(DBT)); | ||||||
|  |     memset(&v, 0, sizeof(DBT)); | ||||||
|  |     k.data = key.data; | ||||||
|  |     k.size = key.length; | ||||||
|  |     k.flags = 0; | ||||||
|  |     if ((code = db->lock(context, db, HDB_RLOCK))) | ||||||
|  | 	return code; | ||||||
|  |     code = d->get(d, NULL, &k, &v, 0); | ||||||
|  |     db->unlock(context, db); | ||||||
|  |     if(code == DB_NOTFOUND) | ||||||
|  | 	return HDB_ERR_NOENTRY; | ||||||
|  |     if(code) | ||||||
|  | 	return code; | ||||||
|  |  | ||||||
|  |     krb5_data_copy(reply, v.data, v.size); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB__put(krb5_context context, HDB *db, int replace,  | ||||||
|  | 	krb5_data key, krb5_data value) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     DBT k, v; | ||||||
|  |     int code; | ||||||
|  |  | ||||||
|  |     memset(&k, 0, sizeof(DBT)); | ||||||
|  |     memset(&v, 0, sizeof(DBT)); | ||||||
|  |     k.data = key.data; | ||||||
|  |     k.size = key.length; | ||||||
|  |     k.flags = 0; | ||||||
|  |     v.data = value.data; | ||||||
|  |     v.size = value.length; | ||||||
|  |     v.flags = 0; | ||||||
|  |     if ((code = db->lock(context, db, HDB_WLOCK))) | ||||||
|  | 	return code; | ||||||
|  |     code = d->put(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE); | ||||||
|  |     db->unlock(context, db); | ||||||
|  |     if(code == DB_KEYEXIST) | ||||||
|  | 	return HDB_ERR_EXISTS; | ||||||
|  |     if(code) | ||||||
|  | 	return errno; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB__del(krb5_context context, HDB *db, krb5_data key) | ||||||
|  | { | ||||||
|  |     DB *d = (DB*)db->db; | ||||||
|  |     DBT k; | ||||||
|  |     krb5_error_code code; | ||||||
|  |     memset(&k, 0, sizeof(DBT)); | ||||||
|  |     k.data = key.data; | ||||||
|  |     k.size = key.length; | ||||||
|  |     k.flags = 0; | ||||||
|  |     code = db->lock(context, db, HDB_WLOCK); | ||||||
|  |     if(code) | ||||||
|  | 	return code; | ||||||
|  |     code = d->del(d, NULL, &k, 0); | ||||||
|  |     db->unlock(context, db); | ||||||
|  |     if(code == DB_NOTFOUND) | ||||||
|  | 	return HDB_ERR_NOENTRY; | ||||||
|  |     if(code) | ||||||
|  | 	return code; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static krb5_error_code | ||||||
|  | DB_open(krb5_context context, HDB *db, int flags, mode_t mode) | ||||||
|  | { | ||||||
|  |     char *fn; | ||||||
|  |     krb5_error_code ret; | ||||||
|  |     DB *d; | ||||||
|  |     int myflags = 0; | ||||||
|  |  | ||||||
|  |     if (flags & O_CREAT) | ||||||
|  |       myflags |= DB_CREATE; | ||||||
|  |  | ||||||
|  |     if (flags & O_EXCL) | ||||||
|  |       myflags |= DB_EXCL; | ||||||
|  |  | ||||||
|  |     if (flags & O_RDONLY) | ||||||
|  |       myflags |= DB_RDONLY; | ||||||
|  |  | ||||||
|  |     if (flags & O_TRUNC) | ||||||
|  |       myflags |= DB_TRUNCATE; | ||||||
|  |  | ||||||
|  |     asprintf(&fn, "%s.db", db->name); | ||||||
|  |     if (fn == NULL) | ||||||
|  | 	return ENOMEM; | ||||||
|  |     db_create(&d, NULL, 0); | ||||||
|  |     db->db = d; | ||||||
|  |     if ((ret = d->open(db->db, fn, NULL, DB_BTREE, myflags, mode))) { | ||||||
|  |       if(ret == ENOENT) | ||||||
|  | 	/* try to open without .db extension */ | ||||||
|  | 	if (d->open(db->db, db->name, NULL, DB_BTREE, myflags, mode)) { | ||||||
|  | 	  free(fn); | ||||||
|  | 	  return ret; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     free(fn); | ||||||
|  |     if((flags & O_ACCMODE) == O_RDONLY) | ||||||
|  | 	ret = hdb_check_db_format(context, db); | ||||||
|  |     else | ||||||
|  | 	ret = hdb_init_db(context, db); | ||||||
|  |     if(ret == HDB_ERR_NOENTRY) | ||||||
|  | 	return 0; | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | krb5_error_code | ||||||
|  | hdb_db_create(krb5_context context, HDB **db,  | ||||||
|  | 	      const char *filename) | ||||||
|  | { | ||||||
|  |     *db = malloc(sizeof(**db)); | ||||||
|  |     if (*db == NULL) | ||||||
|  | 	return ENOMEM; | ||||||
|  |  | ||||||
|  |     (*db)->db = NULL; | ||||||
|  |     (*db)->name = strdup(filename); | ||||||
|  |     (*db)->master_key_set = 0; | ||||||
|  |     (*db)->openp = 0; | ||||||
|  |     (*db)->open  = DB_open; | ||||||
|  |     (*db)->close = DB_close; | ||||||
|  |     (*db)->fetch = _hdb_fetch; | ||||||
|  |     (*db)->store = _hdb_store; | ||||||
|  |     (*db)->remove = _hdb_remove; | ||||||
|  |     (*db)->firstkey = DB_firstkey; | ||||||
|  |     (*db)->nextkey= DB_nextkey; | ||||||
|  |     (*db)->lock = DB_lock; | ||||||
|  |     (*db)->unlock = DB_unlock; | ||||||
|  |     (*db)->rename = DB_rename; | ||||||
|  |     (*db)->_get = DB__get; | ||||||
|  |     (*db)->_put = DB__put; | ||||||
|  |     (*db)->_del = DB__del; | ||||||
|  |     (*db)->destroy = DB_destroy; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user
	 Assar Westerlund
					Assar Westerlund