From af870da6194b47c6cd09445c1e03832d00e951bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 20 Oct 2006 23:32:23 +0000 Subject: r19428: moved tdbutil.c from lib/tdb/common/ to lib/util/util_tdb.c tdbutil.c is Samba specific, so should not be part of the generic tdb library (This used to be commit 979dd24f5e44605fc1603b690913b8c31be7478f) --- source4/lib/gencache/gencache.c | 1 - source4/lib/messaging/config.mk | 3 +- source4/lib/messaging/messaging.c | 3 +- source4/lib/samba3/group.c | 3 +- source4/lib/samba3/idmap.c | 3 +- source4/lib/samba3/policy.c | 3 +- source4/lib/samba3/registry.c | 3 +- source4/lib/samba3/secrets.c | 2 +- source4/lib/samba3/share_info.c | 3 +- source4/lib/samba3/tdbsam.c | 3 +- source4/lib/tdb/common/tdbutil.c | 549 ------------------------------------ source4/lib/tdb/config.mk | 2 +- source4/lib/tdb/include/tdbutil.h | 51 ---- source4/lib/util/config.mk | 10 + source4/lib/util/util_tdb.c | 541 +++++++++++++++++++++++++++++++++++ source4/ntvfs/common/notify.c | 2 +- source4/passdb/config.mk | 3 +- source4/passdb/secrets.c | 3 +- source4/torture/basic/mangle_test.c | 3 +- 19 files changed, 576 insertions(+), 615 deletions(-) delete mode 100644 source4/lib/tdb/common/tdbutil.c delete mode 100644 source4/lib/tdb/include/tdbutil.h create mode 100644 source4/lib/util/util_tdb.c (limited to 'source4') diff --git a/source4/lib/gencache/gencache.c b/source4/lib/gencache/gencache.c index 4c60d76095..dff67054d4 100644 --- a/source4/lib/gencache/gencache.c +++ b/source4/lib/gencache/gencache.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "lib/tdb/include/tdbutil.h" #include "system/time.h" #include "system/filesys.h" #include "db_wrap.h" diff --git a/source4/lib/messaging/config.mk b/source4/lib/messaging/config.mk index 5a0cc4c18f..186f54ba74 100644 --- a/source4/lib/messaging/config.mk +++ b/source4/lib/messaging/config.mk @@ -7,6 +7,7 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = \ DB_WRAP \ NDR_IRPC \ - UNIX_PRIVS + UNIX_PRIVS \ + UTIL_TDB # End SUBSYSTEM MESSAGING ################################################ diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index 00b33017d8..09e04fda9b 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -29,9 +29,10 @@ #include "librpc/gen_ndr/ndr_irpc.h" #include "lib/messaging/irpc.h" #include "db_wrap.h" -#include "lib/tdb/include/tdbutil.h" #include "lib/util/unix_privs.h" #include "librpc/rpc/dcerpc.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" /* change the message version with any incompatible changes in the protocol */ #define MESSAGING_VERSION 1 diff --git a/source4/lib/samba3/group.c b/source4/lib/samba3/group.c index fcf015de68..44d8775e42 100644 --- a/source4/lib/samba3/group.c +++ b/source4/lib/samba3/group.c @@ -21,7 +21,8 @@ #include "includes.h" #include "lib/samba3/samba3.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "system/filesys.h" #include "libcli/security/security.h" diff --git a/source4/lib/samba3/idmap.c b/source4/lib/samba3/idmap.c index 334accc2aa..c5c771cdd3 100644 --- a/source4/lib/samba3/idmap.c +++ b/source4/lib/samba3/idmap.c @@ -24,7 +24,8 @@ */ #include "includes.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "lib/samba3/samba3.h" #include "system/filesys.h" #include "libcli/security/security.h" diff --git a/source4/lib/samba3/policy.c b/source4/lib/samba3/policy.c index cfe6284fc4..936a16bca8 100644 --- a/source4/lib/samba3/policy.c +++ b/source4/lib/samba3/policy.c @@ -19,7 +19,8 @@ */ #include "includes.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "lib/samba3/samba3.h" #include "system/filesys.h" diff --git a/source4/lib/samba3/registry.c b/source4/lib/samba3/registry.c index 7f68c9df74..05855b6583 100644 --- a/source4/lib/samba3/registry.c +++ b/source4/lib/samba3/registry.c @@ -24,7 +24,8 @@ #include "includes.h" #include "lib/samba3/samba3.h" #include "librpc/gen_ndr/winreg.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "system/filesys.h" #include "pstring.h" diff --git a/source4/lib/samba3/secrets.c b/source4/lib/samba3/secrets.c index 479fedbc28..f838b06154 100644 --- a/source4/lib/samba3/secrets.c +++ b/source4/lib/samba3/secrets.c @@ -26,10 +26,10 @@ #include "includes.h" #include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "lib/samba3/samba3.h" #include "system/filesys.h" #include "librpc/gen_ndr/security.h" -#include "lib/tdb/include/tdbutil.h" #include "auth/credentials/credentials.h" /** diff --git a/source4/lib/samba3/share_info.c b/source4/lib/samba3/share_info.c index 318e0ff01f..464dcc38e3 100644 --- a/source4/lib/samba3/share_info.c +++ b/source4/lib/samba3/share_info.c @@ -23,7 +23,8 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_security.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "lib/samba3/samba3.h" #include "system/filesys.h" diff --git a/source4/lib/samba3/tdbsam.c b/source4/lib/samba3/tdbsam.c index 148a3c90f5..0d4854a270 100644 --- a/source4/lib/samba3/tdbsam.c +++ b/source4/lib/samba3/tdbsam.c @@ -22,7 +22,8 @@ #include "includes.h" #include "system/filesys.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "lib/samba3/samba3.h" #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" diff --git a/source4/lib/tdb/common/tdbutil.c b/source4/lib/tdb/common/tdbutil.c deleted file mode 100644 index 1cf1eb8842..0000000000 --- a/source4/lib/tdb/common/tdbutil.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - tdb utility functions - - Copyright (C) Andrew Tridgell 1992-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - NOTE: these utility functions are specific to Samba, and are not part - of the core tdb code -*/ - -#include "includes.h" -#include "lib/tdb/include/tdbutil.h" -#include "system/glob.h" -#include "system/wait.h" -#include "system/filesys.h" -#include "lib/util/dlinklist.h" -#include "pstring.h" - -/* these are little tdb utility functions that are meant to make - dealing with a tdb database a little less cumbersome in Samba */ - -/*************************************************************** - Make a TDB_DATA and keep the const warning in one place -****************************************************************/ - -static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) -{ - TDB_DATA ret; - ret.dptr = discard_const_p(unsigned char, dptr); - ret.dsize = dsize; - return ret; -} - -/**************************************************************************** - Lock a chain by string. Return -1 if lock failed. -****************************************************************************/ - -int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - return tdb_chainlock(tdb, key); -} - -/**************************************************************************** - Unlock a chain by string. -****************************************************************************/ - -void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - tdb_chainunlock(tdb, key); -} - -/**************************************************************************** - Read lock a chain by string. Return -1 if lock failed. -****************************************************************************/ - -int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - return tdb_chainlock_read(tdb, key); -} - -/**************************************************************************** - Read unlock a chain by string. -****************************************************************************/ - -void tdb_read_unlock_bystring(struct tdb_context *tdb, const char *keyval) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - tdb_chainunlock_read(tdb, key); -} - - -/**************************************************************************** - Fetch a int32_t value by a arbitrary blob key, return -1 if not found. - Output is int32_t in native byte order. -****************************************************************************/ - -int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, const char *keyval, size_t len) -{ - TDB_DATA key = make_tdb_data(keyval, len); - TDB_DATA data; - int32_t ret; - - data = tdb_fetch(tdb, key); - if (!data.dptr || data.dsize != sizeof(int32_t)) { - SAFE_FREE(data.dptr); - return -1; - } - - ret = IVAL(data.dptr,0); - SAFE_FREE(data.dptr); - return ret; -} - -/**************************************************************************** - Fetch a int32_t value by string key, return -1 if not found. - Output is int32_t in native byte order. -****************************************************************************/ - -int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr) -{ - return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1); -} - -/**************************************************************************** - Store a int32_t value by an arbitary blob key, return 0 on success, -1 on failure. - Input is int32_t in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -int tdb_store_int32_byblob(struct tdb_context *tdb, const char *keystr, size_t len, int32_t v) -{ - TDB_DATA key = make_tdb_data(keystr, len); - TDB_DATA data; - int32_t v_store; - - SIVAL(&v_store,0,v); - data.dptr = (void *)&v_store; - data.dsize = sizeof(int32_t); - - return tdb_store(tdb, key, data, TDB_REPLACE); -} - -/**************************************************************************** - Store a int32_t value by string key, return 0 on success, -1 on failure. - Input is int32_t in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v) -{ - return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v); -} - -/**************************************************************************** - Fetch a uint32_t value by a arbitrary blob key, return -1 if not found. - Output is uint32_t in native byte order. -****************************************************************************/ - -BOOL tdb_fetch_uint32_byblob(struct tdb_context *tdb, const char *keyval, size_t len, uint32_t *value) -{ - TDB_DATA key = make_tdb_data(keyval, len); - TDB_DATA data; - - data = tdb_fetch(tdb, key); - if (!data.dptr || data.dsize != sizeof(uint32_t)) { - SAFE_FREE(data.dptr); - return False; - } - - *value = IVAL(data.dptr,0); - SAFE_FREE(data.dptr); - return True; -} - -/**************************************************************************** - Fetch a uint32_t value by string key, return -1 if not found. - Output is uint32_t in native byte order. -****************************************************************************/ - -BOOL tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value) -{ - return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); -} - -/**************************************************************************** - Store a uint32_t value by an arbitary blob key, return 0 on success, -1 on failure. - Input is uint32_t in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -BOOL tdb_store_uint32_byblob(struct tdb_context *tdb, const char *keystr, size_t len, uint32_t value) -{ - TDB_DATA key = make_tdb_data(keystr, len); - TDB_DATA data; - uint32_t v_store; - BOOL ret = True; - - SIVAL(&v_store, 0, value); - data.dptr = (void *)&v_store; - data.dsize = sizeof(uint32_t); - - if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) - ret = False; - - return ret; -} - -/**************************************************************************** - Store a uint32_t value by string key, return 0 on success, -1 on failure. - Input is uint32_t in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -BOOL tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value) -{ - return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); -} -/**************************************************************************** - Store a buffer by a null terminated string key. Return 0 on success, -1 - on failure. -****************************************************************************/ - -int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags) -{ - TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - - return tdb_store(tdb, key, data, flags); -} - -/**************************************************************************** - Fetch a buffer using a null terminated string key. Don't forget to call - free() on the result dptr. -****************************************************************************/ - -TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr) -{ - TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - - return tdb_fetch(tdb, key); -} - -/**************************************************************************** - Delete an entry using a null terminated string key. -****************************************************************************/ - -int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr) -{ - TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - - return tdb_delete(tdb, key); -} - -/**************************************************************************** - Atomic integer change. Returns old value. To create, set initial value in *oldval. -****************************************************************************/ - -int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val) -{ - int32_t val; - int32_t ret = -1; - - if (tdb_lock_bystring(tdb, keystr) == -1) - return -1; - - if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { - /* The lookup failed */ - if (tdb_error(tdb) != TDB_ERR_NOEXIST) { - /* but not because it didn't exist */ - goto err_out; - } - - /* Start with 'old' value */ - val = *oldval; - - } else { - /* It worked, set return value (oldval) to tdb data */ - *oldval = val; - } - - /* Increment value for storage and return next time */ - val += change_val; - - if (tdb_store_int32(tdb, keystr, val) == -1) - goto err_out; - - ret = 0; - - err_out: - - tdb_unlock_bystring(tdb, keystr); - return ret; -} - -/**************************************************************************** - Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval. -****************************************************************************/ - -BOOL tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr, uint32_t *oldval, uint32_t change_val) -{ - uint32_t val; - BOOL ret = False; - - if (tdb_lock_bystring(tdb, keystr) == -1) - return False; - - if (!tdb_fetch_uint32(tdb, keystr, &val)) { - /* It failed */ - if (tdb_error(tdb) != TDB_ERR_NOEXIST) { - /* and not because it didn't exist */ - goto err_out; - } - - /* Start with 'old' value */ - val = *oldval; - - } else { - /* it worked, set return value (oldval) to tdb data */ - *oldval = val; - - } - - /* get a new value to store */ - val += change_val; - - if (!tdb_store_uint32(tdb, keystr, val)) - goto err_out; - - ret = True; - - err_out: - - tdb_unlock_bystring(tdb, keystr); - return ret; -} - -/**************************************************************************** - Allow tdb_delete to be used as a tdb_traversal_fn. -****************************************************************************/ - -int tdb_traverse_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - return tdb_delete(the_tdb, key); -} - - - -/**************************************************************************** - Useful pair of routines for packing/unpacking data consisting of - integers and strings. -****************************************************************************/ - -size_t tdb_pack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...) -{ - va_list ap; - uint8_t bt; - uint16_t w; - uint32_t d; - int i; - void *p; - int len; - char *s; - char c; - char *buf0 = buf; - const char *fmt0 = fmt; - int bufsize0 = bufsize; - tdb_log_func log_fn = tdb_log_fn(tdb); - - va_start(ap, fmt); - - while (*fmt) { - switch ((c = *fmt++)) { - case 'b': /* unsigned 8-bit integer */ - len = 1; - bt = (uint8_t)va_arg(ap, int); - if (bufsize && bufsize >= len) - SSVAL(buf, 0, bt); - break; - case 'w': /* unsigned 16-bit integer */ - len = 2; - w = (uint16_t)va_arg(ap, int); - if (bufsize && bufsize >= len) - SSVAL(buf, 0, w); - break; - case 'd': /* signed 32-bit integer (standard int in most systems) */ - len = 4; - d = va_arg(ap, uint32_t); - if (bufsize && bufsize >= len) - SIVAL(buf, 0, d); - break; - case 'p': /* pointer */ - len = 4; - p = va_arg(ap, void *); - d = p?1:0; - if (bufsize && bufsize >= len) - SIVAL(buf, 0, d); - break; - case 'P': /* null-terminated string */ - s = va_arg(ap,char *); - w = strlen(s); - len = w + 1; - if (bufsize && bufsize >= len) - memcpy(buf, s, len); - break; - case 'f': /* null-terminated string */ - s = va_arg(ap,char *); - w = strlen(s); - len = w + 1; - if (bufsize && bufsize >= len) - memcpy(buf, s, len); - break; - case 'B': /* fixed-length string */ - i = va_arg(ap, int); - s = va_arg(ap, char *); - len = 4+i; - if (bufsize && bufsize >= len) { - SIVAL(buf, 0, i); - memcpy(buf+4, s, i); - } - break; - default: - log_fn(tdb, 0,"Unknown tdb_pack format %c in %s\n", - c, fmt); - len = 0; - break; - } - - buf += len; - if (bufsize) - bufsize -= len; - if (bufsize < 0) - bufsize = 0; - } - - va_end(ap); - - log_fn(tdb, 18,"tdb_pack(%s, %d) -> %d\n", - fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)); - - return PTR_DIFF(buf, buf0); -} - -/**************************************************************************** - Useful pair of routines for packing/unpacking data consisting of - integers and strings. -****************************************************************************/ - -int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...) -{ - va_list ap; - uint8_t *bt; - uint16_t *w; - uint32_t *d; - int len; - int *i; - void **p; - char *s, **b; - char c; - char *buf0 = buf; - const char *fmt0 = fmt; - int bufsize0 = bufsize; - tdb_log_func log_fn = tdb_log_fn(tdb); - - va_start(ap, fmt); - - while (*fmt) { - switch ((c=*fmt++)) { - case 'b': - len = 1; - bt = va_arg(ap, uint8_t *); - if (bufsize < len) - goto no_space; - *bt = SVAL(buf, 0); - break; - case 'w': - len = 2; - w = va_arg(ap, uint16_t *); - if (bufsize < len) - goto no_space; - *w = SVAL(buf, 0); - break; - case 'd': - len = 4; - d = va_arg(ap, uint32_t *); - if (bufsize < len) - goto no_space; - *d = IVAL(buf, 0); - break; - case 'p': - len = 4; - p = va_arg(ap, void **); - if (bufsize < len) - goto no_space; - *p = (void *)IVAL(buf, 0); - break; - case 'P': - s = va_arg(ap,char *); - len = strlen(buf) + 1; - if (bufsize < len || len > sizeof(pstring)) - goto no_space; - memcpy(s, buf, len); - break; - case 'f': - s = va_arg(ap,char *); - len = strlen(buf) + 1; - if (bufsize < len || len > sizeof(fstring)) - goto no_space; - memcpy(s, buf, len); - break; - case 'B': - i = va_arg(ap, int *); - b = va_arg(ap, char **); - len = 4; - if (bufsize < len) - goto no_space; - *i = IVAL(buf, 0); - if (! *i) { - *b = NULL; - break; - } - len += *i; - if (bufsize < len) - goto no_space; - *b = (char *)malloc(*i); - if (! *b) - goto no_space; - memcpy(*b, buf+4, *i); - break; - default: - log_fn(tdb, 0, "Unknown tdb_unpack format %c in %s\n", - c, fmt); - - len = 0; - break; - } - - buf += len; - bufsize -= len; - } - - va_end(ap); - - log_fn(tdb, 18, "tdb_unpack(%s, %d) -> %d\n", - fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)); - - return PTR_DIFF(buf, buf0); - - no_space: - return -1; -} diff --git a/source4/lib/tdb/config.mk b/source4/lib/tdb/config.mk index c5d1a33990..0162b78381 100644 --- a/source4/lib/tdb/config.mk +++ b/source4/lib/tdb/config.mk @@ -7,7 +7,7 @@ DESCRIPTION = Trivial Database Library OBJ_FILES = \ common/tdb.o common/dump.o common/io.o common/lock.o \ common/open.o common/traverse.o common/freelist.o \ - common/error.o common/transaction.o common/tdbutil.o + common/error.o common/transaction.o CFLAGS = -Ilib/tdb/include PUBLIC_HEADERS = include/tdb.h # diff --git a/source4/lib/tdb/include/tdbutil.h b/source4/lib/tdb/include/tdbutil.h deleted file mode 100644 index 26747373f4..0000000000 --- a/source4/lib/tdb/include/tdbutil.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Unix SMB/CIFS implementation. - tdb utility functions - Copyright (C) Andrew Tridgell 1999 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __TDBUTIL_H__ -#define __TDBUTIL_H__ - -#include "tdb.h" - -/* single node of a list returned by tdb_search_keys */ -typedef struct keys_node -{ - struct keys_node *prev, *next; - TDB_DATA node_key; -} TDB_LIST_NODE; - - -TDB_LIST_NODE *tdb_search_keys(struct tdb_context*, const char*); -void tdb_search_list_free(TDB_LIST_NODE*); -int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val); -int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval); -void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval); -int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr); -BOOL tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value); -int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v); -BOOL tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value); -int tdb_traverse_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state); -int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags); -TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr); -int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr); -int tdb_unpack(struct tdb_context *tdb, char *buf, int bufsize, const char *fmt, ...); -size_t tdb_pack(struct tdb_context *tdb, char *buf, int bufsize, const char *fmt, ...); - -#endif /* __TDBUTIL_H__ */ diff --git a/source4/lib/util/config.mk b/source4/lib/util/config.mk index 401b4df005..5e49eb839a 100644 --- a/source4/lib/util/config.mk +++ b/source4/lib/util/config.mk @@ -49,3 +49,13 @@ PUBLIC_DEPENDENCIES = XATTR # # End SUBSYSTEM WRAP_XATTR ################################################ + +################################################ +# Start SUBSYSTEM UTIL_TDB +[SUBSYSTEM::UTIL_TDB] +PUBLIC_PROTO_HEADER = util_tdb.h +OBJ_FILES = \ + util_tdb.o +PUBLIC_DEPENDENCIES = LIBTDB +# End SUBSYSTEM UTIL_TDB +################################################ diff --git a/source4/lib/util/util_tdb.c b/source4/lib/util/util_tdb.c new file mode 100644 index 0000000000..820fc2dbb1 --- /dev/null +++ b/source4/lib/util/util_tdb.c @@ -0,0 +1,541 @@ +/* + Unix SMB/CIFS implementation. + + tdb utility functions + + Copyright (C) Andrew Tridgell 1992-2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/tdb/include/tdb.h" +#include "pstring.h" + +/* these are little tdb utility functions that are meant to make + dealing with a tdb database a little less cumbersome in Samba */ + +/*************************************************************** + Make a TDB_DATA and keep the const warning in one place +****************************************************************/ + +static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) +{ + TDB_DATA ret; + ret.dptr = discard_const_p(unsigned char, dptr); + ret.dsize = dsize; + return ret; +} + +/**************************************************************************** + Lock a chain by string. Return -1 if lock failed. +****************************************************************************/ + +int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + return tdb_chainlock(tdb, key); +} + +/**************************************************************************** + Unlock a chain by string. +****************************************************************************/ + +void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + tdb_chainunlock(tdb, key); +} + +/**************************************************************************** + Read lock a chain by string. Return -1 if lock failed. +****************************************************************************/ + +int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + return tdb_chainlock_read(tdb, key); +} + +/**************************************************************************** + Read unlock a chain by string. +****************************************************************************/ + +void tdb_read_unlock_bystring(struct tdb_context *tdb, const char *keyval) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + tdb_chainunlock_read(tdb, key); +} + + +/**************************************************************************** + Fetch a int32_t value by a arbitrary blob key, return -1 if not found. + Output is int32_t in native byte order. +****************************************************************************/ + +int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, const char *keyval, size_t len) +{ + TDB_DATA key = make_tdb_data(keyval, len); + TDB_DATA data; + int32_t ret; + + data = tdb_fetch(tdb, key); + if (!data.dptr || data.dsize != sizeof(int32_t)) { + SAFE_FREE(data.dptr); + return -1; + } + + ret = IVAL(data.dptr,0); + SAFE_FREE(data.dptr); + return ret; +} + +/**************************************************************************** + Fetch a int32_t value by string key, return -1 if not found. + Output is int32_t in native byte order. +****************************************************************************/ + +int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr) +{ + return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1); +} + +/**************************************************************************** + Store a int32_t value by an arbitary blob key, return 0 on success, -1 on failure. + Input is int32_t in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +int tdb_store_int32_byblob(struct tdb_context *tdb, const char *keystr, size_t len, int32_t v) +{ + TDB_DATA key = make_tdb_data(keystr, len); + TDB_DATA data; + int32_t v_store; + + SIVAL(&v_store,0,v); + data.dptr = (void *)&v_store; + data.dsize = sizeof(int32_t); + + return tdb_store(tdb, key, data, TDB_REPLACE); +} + +/**************************************************************************** + Store a int32_t value by string key, return 0 on success, -1 on failure. + Input is int32_t in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v) +{ + return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v); +} + +/**************************************************************************** + Fetch a uint32_t value by a arbitrary blob key, return -1 if not found. + Output is uint32_t in native byte order. +****************************************************************************/ + +BOOL tdb_fetch_uint32_byblob(struct tdb_context *tdb, const char *keyval, size_t len, uint32_t *value) +{ + TDB_DATA key = make_tdb_data(keyval, len); + TDB_DATA data; + + data = tdb_fetch(tdb, key); + if (!data.dptr || data.dsize != sizeof(uint32_t)) { + SAFE_FREE(data.dptr); + return False; + } + + *value = IVAL(data.dptr,0); + SAFE_FREE(data.dptr); + return True; +} + +/**************************************************************************** + Fetch a uint32_t value by string key, return -1 if not found. + Output is uint32_t in native byte order. +****************************************************************************/ + +BOOL tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value) +{ + return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); +} + +/**************************************************************************** + Store a uint32_t value by an arbitary blob key, return 0 on success, -1 on failure. + Input is uint32_t in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +BOOL tdb_store_uint32_byblob(struct tdb_context *tdb, const char *keystr, size_t len, uint32_t value) +{ + TDB_DATA key = make_tdb_data(keystr, len); + TDB_DATA data; + uint32_t v_store; + BOOL ret = True; + + SIVAL(&v_store, 0, value); + data.dptr = (void *)&v_store; + data.dsize = sizeof(uint32_t); + + if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) + ret = False; + + return ret; +} + +/**************************************************************************** + Store a uint32_t value by string key, return 0 on success, -1 on failure. + Input is uint32_t in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +BOOL tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value) +{ + return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); +} +/**************************************************************************** + Store a buffer by a null terminated string key. Return 0 on success, -1 + on failure. +****************************************************************************/ + +int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_store(tdb, key, data, flags); +} + +/**************************************************************************** + Fetch a buffer using a null terminated string key. Don't forget to call + free() on the result dptr. +****************************************************************************/ + +TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_fetch(tdb, key); +} + +/**************************************************************************** + Delete an entry using a null terminated string key. +****************************************************************************/ + +int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_delete(tdb, key); +} + +/**************************************************************************** + Atomic integer change. Returns old value. To create, set initial value in *oldval. +****************************************************************************/ + +int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val) +{ + int32_t val; + int32_t ret = -1; + + if (tdb_lock_bystring(tdb, keystr) == -1) + return -1; + + if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { + /* The lookup failed */ + if (tdb_error(tdb) != TDB_ERR_NOEXIST) { + /* but not because it didn't exist */ + goto err_out; + } + + /* Start with 'old' value */ + val = *oldval; + + } else { + /* It worked, set return value (oldval) to tdb data */ + *oldval = val; + } + + /* Increment value for storage and return next time */ + val += change_val; + + if (tdb_store_int32(tdb, keystr, val) == -1) + goto err_out; + + ret = 0; + + err_out: + + tdb_unlock_bystring(tdb, keystr); + return ret; +} + +/**************************************************************************** + Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval. +****************************************************************************/ + +BOOL tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr, uint32_t *oldval, uint32_t change_val) +{ + uint32_t val; + BOOL ret = False; + + if (tdb_lock_bystring(tdb, keystr) == -1) + return False; + + if (!tdb_fetch_uint32(tdb, keystr, &val)) { + /* It failed */ + if (tdb_error(tdb) != TDB_ERR_NOEXIST) { + /* and not because it didn't exist */ + goto err_out; + } + + /* Start with 'old' value */ + val = *oldval; + + } else { + /* it worked, set return value (oldval) to tdb data */ + *oldval = val; + + } + + /* get a new value to store */ + val += change_val; + + if (!tdb_store_uint32(tdb, keystr, val)) + goto err_out; + + ret = True; + + err_out: + + tdb_unlock_bystring(tdb, keystr); + return ret; +} + +/**************************************************************************** + Allow tdb_delete to be used as a tdb_traversal_fn. +****************************************************************************/ + +int tdb_traverse_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, + void *state) +{ + return tdb_delete(the_tdb, key); +} + + + +/**************************************************************************** + Useful pair of routines for packing/unpacking data consisting of + integers and strings. +****************************************************************************/ + +size_t tdb_pack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...) +{ + va_list ap; + uint8_t bt; + uint16_t w; + uint32_t d; + int i; + void *p; + int len; + char *s; + char c; + char *buf0 = buf; + const char *fmt0 = fmt; + int bufsize0 = bufsize; + tdb_log_func log_fn = tdb_log_fn(tdb); + + va_start(ap, fmt); + + while (*fmt) { + switch ((c = *fmt++)) { + case 'b': /* unsigned 8-bit integer */ + len = 1; + bt = (uint8_t)va_arg(ap, int); + if (bufsize && bufsize >= len) + SSVAL(buf, 0, bt); + break; + case 'w': /* unsigned 16-bit integer */ + len = 2; + w = (uint16_t)va_arg(ap, int); + if (bufsize && bufsize >= len) + SSVAL(buf, 0, w); + break; + case 'd': /* signed 32-bit integer (standard int in most systems) */ + len = 4; + d = va_arg(ap, uint32_t); + if (bufsize && bufsize >= len) + SIVAL(buf, 0, d); + break; + case 'p': /* pointer */ + len = 4; + p = va_arg(ap, void *); + d = p?1:0; + if (bufsize && bufsize >= len) + SIVAL(buf, 0, d); + break; + case 'P': /* null-terminated string */ + s = va_arg(ap,char *); + w = strlen(s); + len = w + 1; + if (bufsize && bufsize >= len) + memcpy(buf, s, len); + break; + case 'f': /* null-terminated string */ + s = va_arg(ap,char *); + w = strlen(s); + len = w + 1; + if (bufsize && bufsize >= len) + memcpy(buf, s, len); + break; + case 'B': /* fixed-length string */ + i = va_arg(ap, int); + s = va_arg(ap, char *); + len = 4+i; + if (bufsize && bufsize >= len) { + SIVAL(buf, 0, i); + memcpy(buf+4, s, i); + } + break; + default: + log_fn(tdb, 0,"Unknown tdb_pack format %c in %s\n", + c, fmt); + len = 0; + break; + } + + buf += len; + if (bufsize) + bufsize -= len; + if (bufsize < 0) + bufsize = 0; + } + + va_end(ap); + + log_fn(tdb, 18,"tdb_pack(%s, %d) -> %d\n", + fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)); + + return PTR_DIFF(buf, buf0); +} + +/**************************************************************************** + Useful pair of routines for packing/unpacking data consisting of + integers and strings. +****************************************************************************/ + +int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...) +{ + va_list ap; + uint8_t *bt; + uint16_t *w; + uint32_t *d; + int len; + int *i; + void **p; + char *s, **b; + char c; + char *buf0 = buf; + const char *fmt0 = fmt; + int bufsize0 = bufsize; + tdb_log_func log_fn = tdb_log_fn(tdb); + + va_start(ap, fmt); + + while (*fmt) { + switch ((c=*fmt++)) { + case 'b': + len = 1; + bt = va_arg(ap, uint8_t *); + if (bufsize < len) + goto no_space; + *bt = SVAL(buf, 0); + break; + case 'w': + len = 2; + w = va_arg(ap, uint16_t *); + if (bufsize < len) + goto no_space; + *w = SVAL(buf, 0); + break; + case 'd': + len = 4; + d = va_arg(ap, uint32_t *); + if (bufsize < len) + goto no_space; + *d = IVAL(buf, 0); + break; + case 'p': + len = 4; + p = va_arg(ap, void **); + if (bufsize < len) + goto no_space; + *p = (void *)IVAL(buf, 0); + break; + case 'P': + s = va_arg(ap,char *); + len = strlen(buf) + 1; + if (bufsize < len || len > sizeof(pstring)) + goto no_space; + memcpy(s, buf, len); + break; + case 'f': + s = va_arg(ap,char *); + len = strlen(buf) + 1; + if (bufsize < len || len > sizeof(fstring)) + goto no_space; + memcpy(s, buf, len); + break; + case 'B': + i = va_arg(ap, int *); + b = va_arg(ap, char **); + len = 4; + if (bufsize < len) + goto no_space; + *i = IVAL(buf, 0); + if (! *i) { + *b = NULL; + break; + } + len += *i; + if (bufsize < len) + goto no_space; + *b = (char *)malloc(*i); + if (! *b) + goto no_space; + memcpy(*b, buf+4, *i); + break; + default: + log_fn(tdb, 0, "Unknown tdb_unpack format %c in %s\n", + c, fmt); + + len = 0; + break; + } + + buf += len; + bufsize -= len; + } + + va_end(ap); + + log_fn(tdb, 18, "tdb_unpack(%s, %d) -> %d\n", + fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)); + + return PTR_DIFF(buf, buf0); + + no_space: + return -1; +} diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 17c6e81c6f..19a60a51a9 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -27,7 +27,7 @@ #include "includes.h" #include "system/filesys.h" #include "lib/tdb/include/tdb.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/util/util_tdb.h" #include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" diff --git a/source4/passdb/config.mk b/source4/passdb/config.mk index 51e2c4a83e..81897323c9 100644 --- a/source4/passdb/config.mk +++ b/source4/passdb/config.mk @@ -1,4 +1,5 @@ [SUBSYSTEM::SECRETS] PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = secrets.o -PRIVATE_DEPENDENCIES = DB_WRAP +PRIVATE_DEPENDENCIES = DB_WRAP UTIL_TDB + diff --git a/source4/passdb/secrets.c b/source4/passdb/secrets.c index 7171fa11ab..876be607f1 100644 --- a/source4/passdb/secrets.c +++ b/source4/passdb/secrets.c @@ -23,12 +23,13 @@ such as the local SID and machine trust password */ #include "includes.h" -#include "lib/tdb/include/tdbutil.h" #include "secrets.h" #include "param/param.h" #include "system/filesys.h" #include "db_wrap.h" #include "lib/ldb/include/ldb.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "dsdb/samdb/samdb.h" static struct tdb_wrap *tdb; diff --git a/source4/torture/basic/mangle_test.c b/source4/torture/basic/mangle_test.c index 091e471e8a..68ee0b63f5 100644 --- a/source4/torture/basic/mangle_test.c +++ b/source4/torture/basic/mangle_test.c @@ -22,7 +22,8 @@ #include "torture/torture.h" #include "system/filesys.h" #include "system/dir.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/tdb/include/tdb.h" +#include "lib/util/util_tdb.h" #include "libcli/libcli.h" #include "torture/util.h" #include "pstring.h" -- cgit