* removed some unused code
authorAndrew Tridgell <tridge@samba.org>
Wed, 10 Dec 2003 03:02:12 +0000 (03:02 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 10 Dec 2003 03:02:12 +0000 (03:02 +0000)
 * updated tdb to latest version from Samba3

 * removed some extraneous ';' in tdbutil.c (Thanks to Erlend Aasland
   for pointing this out)
(This used to be commit f3eaf270e57d8d2e2157a6a36e260860c7f71c19)

20 files changed:
source4/Makefile.in
source4/include/includes.h
source4/include/rpc_lsa.h
source4/lib/tdb/spinlock.c
source4/lib/tdb/spinlock.h
source4/lib/tdb/tdb.c
source4/lib/tdb/tdbutil.c
source4/passdb/privileges.c [deleted file]
source4/smbd/process.c
source4/tdb/spinlock.c
source4/tdb/spinlock.h
source4/tdb/tdb.c
source4/tdb/tdbbackup.c
source4/tdb/tdbtool.c
source4/tdb/tdbtorture.c
source4/tdb/tdbutil.c
source4/torture/mangle_test.c
source4/utils/tdb/tdbbackup.c
source4/utils/tdb/tdbtool.c
source4/utils/tdb/tdbtorture.c

index 73db956fae4aa24f95484d788a03edc7466301f0..85d51de58d3242d38fd1e8a23eb2b00539e32d9e 100644 (file)
@@ -238,8 +238,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
                passdb/machine_sid.o passdb/pdb_smbpasswd.o \
                passdb/pdb_tdb.o passdb/pdb_ldap.o \
                passdb/pdb_unix.o passdb/pdb_guest.o passdb/util_sam_sid.o \
-               passdb/pdb_compat.o passdb/pdb_nisplus.o \
-               passdb/privileges.o 
+               passdb/pdb_compat.o passdb/pdb_nisplus.o
 
 XML_OBJ = modules/xml.o
 MYSQL_OBJ = modules/mysql.o
@@ -648,7 +647,7 @@ pch: basics
        $(CC) -I. -I$(srcdir) $(FLAGS) -c $(srcdir)/include/includes.h -o $(srcdir)/include/includes.h.gch
 
 
-idl:
+idl: build/pidl/idl.pm
        script/build_idl.sh FULL
 
 idl_test: build/pidl/idl.pm
index d8784f618b6023eced0176803f6588659ad9b455..fe6fcf5bce33b8fbd3c83c43c9afbfd29563e8d0 100644 (file)
 /*
  * Define additional missing types
  */
-#if defined(HAVE_SIG_ATOMIC_T_TYPE) && defined(AIX)
+#if defined(HAVE_SIG_ATOMIC_T_TYPE)
 typedef sig_atomic_t SIG_ATOMIC_T;
-#elif defined(HAVE_SIG_ATOMIC_T_TYPE) && !defined(AIX)
-typedef sig_atomic_t VOLATILE SIG_ATOMIC_T;
 #else
-typedef int VOLATILE SIG_ATOMIC_T;
+typedef int SIG_ATOMIC_T;
 #endif
 
 #ifndef HAVE_SOCKLEN_T_TYPE
index d4040af3aa943988a949c841aa0414867676cb6a..fb76546aa7f2187010161c59d63e1f2091ce53d5 100644 (file)
 
 #include "rpc_misc.h"
 
-/* Opcodes available on PIPE_LSARPC */
-
-#define LSA_CLOSE              0x00
-#define LSA_DELETE             0x01
-#define LSA_ENUM_PRIVS         0x02
-#define LSA_QUERYSECOBJ        0x03
-#define LSA_SETSECOBJ          0x04
-#define LSA_CHANGEPASSWORD     0x05
-#define LSA_OPENPOLICY         0x06
-#define LSA_QUERYINFOPOLICY    0x07
-#define LSA_SETINFOPOLICY      0x08
-#define LSA_CLEARAUDITLOG      0x09
-#define LSA_CREATEACCOUNT      0x0a
-#define LSA_ENUM_ACCOUNTS      0x0b
-#define LSA_CREATETRUSTDOM     0x0c
-#define LSA_ENUMTRUSTDOM       0x0d
-#define LSA_LOOKUPNAMES        0x0e
-#define LSA_LOOKUPSIDS         0x0f
-#define LSA_CREATESECRET       0x10
-#define LSA_OPENACCOUNT               0x11
-#define LSA_ENUMPRIVSACCOUNT   0x12
-#define LSA_ADDPRIVS           0x13
-#define LSA_REMOVEPRIVS        0x14
-#define LSA_GETQUOTAS          0x15
-#define LSA_SETQUOTAS          0x16
-#define LSA_GETSYSTEMACCOUNT   0x17
-#define LSA_SETSYSTEMACCOUNT   0x18
-#define LSA_OPENTRUSTDOM       0x19
-#define LSA_QUERYTRUSTDOM      0x1a
-#define LSA_SETINFOTRUSTDOM    0x1b
-#define LSA_OPENSECRET         0x1c
-#define LSA_SETSECRET          0x1d
-#define LSA_QUERYSECRET        0x1e
-#define LSA_LOOKUPPRIVVALUE    0x1f
-#define LSA_LOOKUPPRIVNAME     0x20
-#define LSA_PRIV_GET_DISPNAME  0x21
-#define LSA_DELETEOBJECT       0x22
-#define LSA_ENUMACCTWITHRIGHT  0x23
-#define LSA_ENUMACCTRIGHTS     0x24
-#define LSA_ADDACCTRIGHTS      0x25
-#define LSA_REMOVEACCTRIGHTS   0x26
-#define LSA_QUERYTRUSTDOMINFO  0x27
-#define LSA_SETTRUSTDOMINFO    0x28
-#define LSA_DELETETRUSTDOM     0x29
-#define LSA_STOREPRIVDATA      0x2a
-#define LSA_RETRPRIVDATA       0x2b
-#define LSA_OPENPOLICY2        0x2c
-#define LSA_UNK_GET_CONNUSER   0x2d /* LsaGetConnectedCredentials ? */
-#define LSA_QUERYINFO2         0x2e
-
-/* XXXX these are here to get a compile! */
-#define LSA_LOOKUPRIDS      0xFD
-
 typedef struct seq_qos_info
 {
        uint32 len; /* 12 */
index 2370ce3bdd93286d8c86e3f7c410a3e0ad1e37a4..3fddeafb2c1a3412a9d3d309c68a0242eafc9e86 100644 (file)
@@ -372,7 +372,7 @@ int tdb_create_rwlocks(int fd, unsigned int hash_size)
        unsigned size, i;
        tdb_rwlock_t *rwlocks;
 
-       size = (hash_size + 1) * sizeof(tdb_rwlock_t);
+       size = TDB_SPINLOCK_SIZE(hash_size);
        rwlocks = malloc(size);
        if (!rwlocks)
                return -1;
index d6a2ac6eb88a2a80de55d4e89cbc70a37876e8df..967fe37457fb9a69b754c3ef50fc860d729a7963 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __SPINLOCK_H__
 #define __SPINLOCK_H__
 
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
@@ -39,6 +39,8 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
 int tdb_create_rwlocks(int fd, unsigned int hash_size);
 int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
 
+#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t))
+
 #else /* !USE_SPINLOCKS */
 #if 0
 #define tdb_create_rwlocks(fd, hash_size) 0
@@ -50,6 +52,8 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
 int tdb_create_rwlocks(int fd, unsigned int hash_size);
 #endif
 int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+#define TDB_SPINLOCK_SIZE(hash_size) 0
+
 #endif
 
 #endif
index 513fbce5194f30def7f124708a37928ef4016607..fc210f42d4f51a5873466aa39a44b22118d31601 100644 (file)
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
+
+
+/* NOTE: If you use tdbs under valgrind, and in particular if you run
+ * tdbtorture, you may get spurious "uninitialized value" warnings.  I
+ * think this is because valgrind doesn't understand that the mmap'd
+ * area may be written to by other processes.  Memory can, from the
+ * point of view of the grinded process, spontaneously become
+ * initialized.
+ *
+ * I can think of a few solutions.  [mbp 20030311]
+ *
+ * 1 - Write suppressions for Valgrind so that it doesn't complain
+ * about this.  Probably the most reasonable but people need to
+ * remember to use them.
+ *
+ * 2 - Use IO not mmap when running under valgrind.  Not so nice.
+ *
+ * 3 - Use the special valgrind macros to mark memory as valid at the
+ * right time.  Probably too hard -- the process just doesn't know.
+ */ 
+
 #ifdef STANDALONE
 #if HAVE_CONFIG_H
 #include <config.h>
@@ -56,6 +77,8 @@
 #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
 #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
 #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off))
+#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size))
+
 
 /* NB assumes there is a local variable called "tdb" that is the
  * current context, also takes doubly-parenthesized print-style
@@ -214,10 +237,15 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
                                 tdb->fd, offset, rw_type, lck_type));
                }
                /* Was it an alarm timeout ? */
-               if (errno == EINTR && palarm_fired && *palarm_fired)
+               if (errno == EINTR && palarm_fired && *palarm_fired) {
+                       TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n", 
+                                tdb->fd, offset, rw_type, lck_type));
                        return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
+               }
                /* Otherwise - generic lock error. */
                /* errno set by fcntl */
+               TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", 
+                        tdb->fd, offset, rw_type, lck_type, strerror(errno)));
                return TDB_ERRCODE(TDB_ERR_LOCK, -1);
        }
        return 0;
@@ -642,10 +670,10 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
 left:
        /* Look left */
        left = offset - sizeof(tdb_off);
-       if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) {
+       if (left > TDB_DATA_START(tdb->header.hash_size)) {
                struct list_struct l;
                tdb_off leftsize;
-
+               
                /* Read in tailer and jump back to header */
                if (ofs_read(tdb, left, &leftsize) == -1) {
                        TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left));
@@ -994,12 +1022,11 @@ static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash)
 }
 
 /* As tdb_find, but if you succeed, keep the lock */
-static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype,
+static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype,
                             struct list_struct *rec)
 {
-       u32 hash, rec_ptr;
+       u32 rec_ptr;
 
-       hash = tdb_hash(&key);
        if (!tdb_keylocked(tdb, hash))
                return 0;
        if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
@@ -1040,13 +1067,13 @@ const char *tdb_errorstr(TDB_CONTEXT *tdb)
    on failure return -1.
 */
 
-static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
+static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf)
 {
        struct list_struct rec;
        tdb_off rec_ptr;
 
        /* find entry */
-       if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec)))
+       if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
                return -1;
 
        /* must be long enough key, data and tailer */
@@ -1080,9 +1107,11 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
        tdb_off rec_ptr;
        struct list_struct rec;
        TDB_DATA ret;
+       u32 hash;
 
        /* find which hash bucket it is in */
-       if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec)))
+       hash = tdb_hash(&key);
+       if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
                return tdb_null;
 
        if (rec.data_len)
@@ -1101,16 +1130,22 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
    this doesn't match the conventions in the rest of this module, but is
    compatible with gdbm
 */
-int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
+static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
 {
        struct list_struct rec;
        
-       if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0)
+       if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0)
                return 0;
        tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
        return 1;
 }
 
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+       u32 hash = tdb_hash(&key);
+       return tdb_exists_hash(tdb, key, hash);
+}
+
 /* record lock stops delete underneath */
 static int lock_record(TDB_CONTEXT *tdb, tdb_off off)
 {
@@ -1236,7 +1271,8 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
                        /* Try to clean dead ones from old traverses */
                        current = tlock->off;
                        tlock->off = rec->next;
-                       if (do_delete(tdb, current, rec) != 0)
+                       if (!tdb->read_only && 
+                           do_delete(tdb, current, rec) != 0)
                                goto fail;
                }
                tdb_unlock(tdb, tlock->hash, F_WRLCK);
@@ -1366,7 +1402,7 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
 
        if (!tdb->travlocks.off) {
                /* No previous element: do normal find, and lock record */
-               tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec);
+               tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb_hash(&oldkey), F_WRLCK, &rec);
                if (!tdb->travlocks.off)
                        return tdb_null;
                tdb->travlocks.hash = BUCKET(rec.full_hash);
@@ -1394,13 +1430,13 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
 }
 
 /* delete an entry in the database given a key */
-int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
+static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
 {
        tdb_off rec_ptr;
        struct list_struct rec;
        int ret;
 
-       if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
+       if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec)))
                return -1;
        ret = do_delete(tdb, rec_ptr, &rec);
        if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
@@ -1408,6 +1444,12 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
        return ret;
 }
 
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+       u32 hash = tdb_hash(&key);
+       return tdb_delete_hash(tdb, key, hash);
+}
+
 /* store an element in the database, replacing any existing element
    with the same key 
 
@@ -1430,13 +1472,13 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
 
        /* check for it existing, on insert. */
        if (flag == TDB_INSERT) {
-               if (tdb_exists(tdb, key)) {
+               if (tdb_exists_hash(tdb, key, hash)) {
                        tdb->ecode = TDB_ERR_EXISTS;
                        goto fail;
                }
        } else {
                /* first try in-place update, on modify or replace. */
-               if (tdb_update(tdb, key, dbuf) == 0)
+               if (tdb_update_hash(tdb, key, hash, dbuf) == 0)
                        goto out;
                if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST)
                        goto fail;
@@ -1448,7 +1490,7 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
            care.  Doing this first reduces fragmentation, and avoids
            coalescing with `allocated' block before it's updated. */
        if (flag != TDB_INSERT)
-               tdb_delete(tdb, key);
+               tdb_delete_hash(tdb, key, hash);
 
        /* Copy key+value *before* allocating free space in case malloc
           fails and we are left with a dead spot in the tdb. */
@@ -1497,13 +1539,13 @@ fail:
    is <= the old data size and the key exists.
    on failure return -1. Record must be locked before calling.
 */
-static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
+static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf)
 {
        struct list_struct rec;
        tdb_off rec_ptr;
 
        /* find entry */
-       if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec)))
+       if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
                return -1;
 
        /* Append of 0 is always ok. */
@@ -1545,7 +1587,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
                return -1;
 
        /* first try in-place. */
-       if (tdb_append_inplace(tdb, key, new_dbuf) == 0)
+       if (tdb_append_inplace(tdb, key, hash, new_dbuf) == 0)
                goto out;
 
        /* reset the error code potentially set by the tdb_append_inplace() */
@@ -1588,7 +1630,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
            care.  Doing this first reduces fragmentation, and avoids
            coalescing with `allocated' block before it's updated. */
 
-       tdb_delete(tdb, key);
+       tdb_delete_hash(tdb, key, hash);
 
        if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec)))
                goto fail;
@@ -1728,8 +1770,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
 
        if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
            || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
-           || tdb->header.version != TDB_VERSION
-           || (tdb->header.hash_size != hash_size
+           || (tdb->header.version != TDB_VERSION
                && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
                /* its not a valid database - possibly initialise it */
                if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
@@ -1934,6 +1975,8 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
 void tdb_unlockkeys(TDB_CONTEXT *tdb)
 {
        u32 i;
+       if (!tdb->lockedkeys)
+               return;
        for (i = 0; i < tdb->lockedkeys[0]; i++)
                tdb_unlock(tdb, tdb->lockedkeys[i+1], F_WRLCK);
        SAFE_FREE(tdb->lockedkeys);
index 0d8f6128cc5f8e7d0cec89d3b2822227026bdf7d..ce5188300cc5baf8dc0e1e43129712cbf9b247a4 100644 (file)
@@ -266,7 +266,7 @@ BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value)
  on failure.
 ****************************************************************************/
 
-int tdb_store_by_string(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags)
+int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags)
 {
        TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
        
@@ -278,7 +278,7 @@ int tdb_store_by_string(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int
  free() on the result dptr.
 ****************************************************************************/
 
-TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, const char *keystr)
+TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr)
 {
        TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
 
@@ -289,7 +289,7 @@ TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, const char *keystr)
  Delete an entry using a null terminated string key. 
 ****************************************************************************/
 
-int tdb_delete_by_string(TDB_CONTEXT *tdb, const char *keystr)
+int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr)
 {
        TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
 
@@ -311,7 +311,7 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldva
        if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
                /* The lookup failed */
                if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
-                       /* but not becouse it didn't exist */
+                       /* but not because it didn't exist */
                        goto err_out;
                }
                
@@ -352,7 +352,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv
        if (!tdb_fetch_uint32(tdb, keystr, &val)) {
                /* It failed */
                if (tdb_error(tdb) != TDB_ERR_NOEXIST) { 
-                       /* and not becouse it didn't exist */
+                       /* and not because it didn't exist */
                        goto err_out;
                }
 
@@ -387,6 +387,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv
 size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 {
        va_list ap;
+       uint8 bt;
        uint16 w;
        uint32 d;
        int i;
@@ -402,44 +403,50 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 
        while (*fmt) {
                switch ((c = *fmt++)) {
-               case 'w':
+               case 'b': /* unsigned 8-bit integer */
+                       len = 1;
+                       bt = (uint8)va_arg(ap, int);
+                       if (bufsize && bufsize >= len)
+                               SSVAL(buf, 0, bt);
+                       break;
+               case 'w': /* unsigned 16-bit integer */
                        len = 2;
                        w = (uint16)va_arg(ap, int);
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                SSVAL(buf, 0, w);
                        break;
-               case 'd':
+               case 'd': /* signed 32-bit integer (standard int in most systems) */
                        len = 4;
                        d = va_arg(ap, uint32);
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                SIVAL(buf, 0, d);
                        break;
-               case 'p':
+               case 'p': /* pointer */
                        len = 4;
                        p = va_arg(ap, void *);
                        d = p?1:0;
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                SIVAL(buf, 0, d);
                        break;
-               case 'P':
+               case 'P': /* null-terminated string */
                        s = va_arg(ap,char *);
                        w = strlen(s);
                        len = w + 1;
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                memcpy(buf, s, len);
                        break;
-               case 'f':
+               case 'f': /* null-terminated string */
                        s = va_arg(ap,char *);
                        w = strlen(s);
                        len = w + 1;
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                memcpy(buf, s, len);
                        break;
-               case 'B':
+               case 'B': /* fixed-length string */
                        i = va_arg(ap, int);
                        s = va_arg(ap, char *);
                        len = 4+i;
-                       if (bufsize >= len) {
+                       if (bufsize && bufsize >= len) {
                                SIVAL(buf, 0, i);
                                memcpy(buf+4, s, i);
                        }
@@ -452,7 +459,10 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
                }
 
                buf += len;
-               bufsize -= len;
+               if (bufsize)
+                       bufsize -= len;
+               if (bufsize < 0)
+                       bufsize = 0;
        }
 
        va_end(ap);
@@ -471,6 +481,7 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
 {
        va_list ap;
+       uint8 *bt;
        uint16 *w;
        uint32 *d;
        int len;
@@ -486,6 +497,13 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
        
        while (*fmt) {
                switch ((c=*fmt++)) {
+               case 'b':
+                       len = 1;
+                       bt = va_arg(ap, uint8 *);
+                       if (bufsize < len)
+                               goto no_space;
+                       *bt = SVAL(buf, 0);
+                       break;
                case 'w':
                        len = 2;
                        w = va_arg(ap, uint16 *);
@@ -563,6 +581,67 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
        return -1;
 }
 
+
+/**
+ * Pack SID passed by pointer
+ *
+ * @param pack_buf pointer to buffer which is to be filled with packed data
+ * @param bufsize size of packing buffer
+ * @param sid pointer to sid to be packed
+ *
+ * @return length of the packed representation of the whole structure
+ **/
+size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid)
+{
+       int idx;
+       size_t len = 0;
+       
+       if (!sid || !pack_buf) return -1;
+       
+       len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
+                       sid->num_auths);
+       
+       for (idx = 0; idx < 6; idx++) {
+               len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]);
+       }
+       
+       for (idx = 0; idx < MAXSUBAUTHS; idx++) {
+               len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]);
+       }
+       
+       return len;
+}
+
+
+/**
+ * Unpack SID into a pointer
+ *
+ * @param pack_buf pointer to buffer with packed representation
+ * @param bufsize size of the buffer
+ * @param sid pointer to sid structure to be filled with unpacked data
+ *
+ * @return size of structure unpacked from buffer
+ **/
+size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid)
+{
+       int idx, len = 0;
+       
+       if (!sid || !pack_buf) return -1;
+
+       len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
+                         &sid->sid_rev_num, &sid->num_auths);
+                         
+       for (idx = 0; idx < 6; idx++) {
+               len += tdb_unpack(pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]);
+       }
+       
+       for (idx = 0; idx < MAXSUBAUTHS; idx++) {
+               len += tdb_unpack(pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]);
+       }
+       
+       return len;
+}
+
 /****************************************************************************
  Log tdb messages via DEBUG().
 ****************************************************************************/
@@ -665,7 +744,7 @@ TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern)
        
        return list;
 
-};
+}
 
 
 /**
@@ -679,9 +758,8 @@ void tdb_search_list_free(TDB_LIST_NODE* node)
        
        while (node) {
                next_node = node->next;
+               SAFE_FREE(node->node_key.dptr);
                SAFE_FREE(node);
                node = next_node;
-       };
-};
-
-
+       }
+}
diff --git a/source4/passdb/privileges.c b/source4/passdb/privileges.c
deleted file mode 100644 (file)
index c90bc47..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Unix SMB/CIFS implementation. 
- *
- * default privileges backend for passdb
- *
- * Copyright (C) Andrew Tridgell 2003
- * 
- * 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"
-
-/*
-  this is a local implementation of a privileges backend, with
-  privileges stored in a tdb. Most passdb implementations will
-  probably use this backend, although some (such as pdb_ldap) will
-  store the privileges in another manner.
-
-  The basic principle is that the backend should store a list of SIDs
-  associated with each right, where a right is a string name such as
-  'SeTakeOwnershipPrivilege'. The SIDs can be of any type, and do not
-  need to belong to the local domain.
-
-  The way this is used is that certain places in the code which
-  require access control will ask the privileges backend 'does this
-  user have the following privilege'. The 'user' will be a NT_TOKEN,
-  which is essentially just a list of SIDs. If any of those SIDs are
-  listed in the list of SIDs for that privilege then the answer will
-  be 'yes'. That will usually mean that the user gets unconditional
-  access to that functionality, regradless of any ACLs. In this way
-  privileges act in a similar fashion to unix setuid bits.
-*/
-
-/*
-  The terms 'right' and 'privilege' are used interchangably in this
-  file. This follows MSDN convention where the LSA calls are calls on
-  'rights', which really means privileges. My apologies for the
-  confusion.
-*/
-
-
-/* 15 seconds seems like an ample time for timeouts on the privileges db */
-#define LOCK_TIMEOUT 15
-
-
-/* the tdb handle for the privileges database */
-static TDB_CONTEXT *tdb;
-
-
-/* initialise the privilege database */
-BOOL privilege_init(void)
-{
-       TALLOC_CTX *mem_ctx;
-       
-       mem_ctx = talloc_init("privilege_init talloc");
-       if (!mem_ctx) {
-               DEBUG(0,("No memory to open privilege database\n"));
-               return False;
-       }
-       tdb = tdb_open_log(lock_path(mem_ctx, "privilege.tdb"), 0, TDB_DEFAULT, 
-                          O_RDWR|O_CREAT, 0600);
-       talloc_destroy(mem_ctx);
-       if (!tdb) {
-               DEBUG(0,("Failed to open privilege database\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/* 
-   lock the record for a particular privilege (write lock)
-*/
-static NTSTATUS privilege_lock_right(const char *right) 
-{
-       if (tdb_lock_bystring(tdb, right, LOCK_TIMEOUT) != 0) {
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-       return NT_STATUS_OK;
-}
-
-/* 
-   unlock the record for a particular privilege (write lock)
-*/
-static void privilege_unlock_right(const char *right) 
-{
-       tdb_unlock_bystring(tdb, right);
-}
-
-
-/* 
-   return a list of SIDs that have a particular right
-*/
-NTSTATUS privilege_enum_account_with_right(const char *right, 
-                                          uint32 *count, 
-                                          DOM_SID **sids)
-{
-       TDB_DATA data;
-       char *p;
-       int i;
-
-       if (!tdb) {
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       data = tdb_fetch_by_string(tdb, right);
-       if (!data.dptr) {
-               *count = 0;
-               *sids = NULL;
-               return NT_STATUS_OK;
-       }
-
-       /* count them */
-       for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
-               p += strlen(p) + 1;
-       }
-       *count = i;
-
-       /* allocate and parse */
-       *sids = malloc(sizeof(DOM_SID) * *count);
-       if (! *sids) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
-               if (!string_to_sid(&(*sids)[i], p)) {
-                       free(data.dptr);
-                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
-               }
-               p += strlen(p) + 1;
-       }
-       
-       free(data.dptr);
-
-       return NT_STATUS_OK;
-}
-
-/* 
-   set what accounts have a given right - this is an internal interface
-*/
-static NTSTATUS privilege_set_accounts_with_right(const char *right, 
-                                                 uint32 count, 
-                                                 DOM_SID *sids)
-{
-       TDB_DATA data;
-       char *p;
-       int i;
-
-       if (!tdb) {
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       /* allocate the maximum size that we might use */
-       data.dptr = malloc(count * ((MAXSUBAUTHS*11) + 30));
-       if (!data.dptr) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       p = data.dptr;
-
-       for (i=0;i<count;i++) {
-               sid_to_string(p, &sids[i]);
-               p += strlen(p) + 1;
-       }
-
-       data.dsize = PTR_DIFF(p, data.dptr);
-
-       if (tdb_store_by_string(tdb, right, data, TDB_REPLACE) != 0) {
-               free(data.dptr);
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       free(data.dptr);
-       return NT_STATUS_OK;
-}
-
-
-/* 
-   add a SID to the list of SIDs for a right
-*/
-NTSTATUS privilege_add_account_right(const char *right, 
-                                    DOM_SID *sid)
-{
-       NTSTATUS status;
-       DOM_SID *current_sids;
-       uint32 current_count;
-       int i;
-
-       status = privilege_lock_right(right);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = privilege_enum_account_with_right(right, &current_count, &current_sids);
-       if (!NT_STATUS_IS_OK(status)) {
-               privilege_unlock_right(right);
-               return status;
-       }       
-
-       /* maybe that SID is already listed? this is not an error */
-       for (i=0;i<current_count;i++) {
-               if (sid_equal(&current_sids[i], sid)) {
-                       privilege_unlock_right(right);
-                       free(current_sids);
-                       return NT_STATUS_OK;
-               }
-       }
-
-       /* add it in */
-       current_sids = Realloc(current_sids, sizeof(current_sids[0]) * (current_count+1));
-       if (!current_sids) {
-               privilege_unlock_right(right);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       sid_copy(&current_sids[current_count], sid);
-       current_count++;
-       
-       status = privilege_set_accounts_with_right(right, current_count, current_sids);
-
-       free(current_sids);
-       privilege_unlock_right(right);
-
-       return status;
-}
-
-
-/* 
-   remove a SID from the list of SIDs for a right
-*/
-NTSTATUS privilege_remove_account_right(const char *right, 
-                                       DOM_SID *sid)
-{
-       NTSTATUS status;
-       DOM_SID *current_sids;
-       uint32 current_count;
-       int i;
-
-       status = privilege_lock_right(right);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = privilege_enum_account_with_right(right, &current_count, &current_sids);
-       if (!NT_STATUS_IS_OK(status)) {
-               privilege_unlock_right(right);
-               return status;
-       }       
-
-       for (i=0;i<current_count;i++) {
-               if (sid_equal(&current_sids[i], sid)) {
-                       /* found it - so remove it */
-                       if (current_count-i > 1) {
-                               memmove(&current_sids[i], &current_sids[i+1],
-                                       sizeof(current_sids[0]) * ((current_count-i)-1));
-                       }
-                       current_count--;
-                       status = privilege_set_accounts_with_right(right, 
-                                                                  current_count, 
-                                                                  current_sids);
-                       free(current_sids);
-                       privilege_unlock_right(right);
-                       return status;
-               }
-       }
-
-       /* removing a right that you don't have is not an error */
-       
-       safe_free(current_sids);
-       privilege_unlock_right(right);
-       return NT_STATUS_OK;
-}
-
-
-/*
-  an internal function for checking if a SID has a right
-*/
-static BOOL privilege_sid_has_right(DOM_SID *sid, const char *right)
-{
-       NTSTATUS status;
-       uint32 count;
-       DOM_SID *sids;
-       int i;
-
-       status = privilege_enum_account_with_right(right, &count, &sids);
-       if (!NT_STATUS_IS_OK(status)) {
-               return False;
-       }
-       for (i=0;i<count;i++) {
-               if (sid_equal(sid, &sids[i])) {
-                       free(sids);
-                       return True;
-               }
-       }       
-
-       safe_free(sids);
-       return False;
-}
-
-/* 
-   list the rights for an account. This involves traversing the database
-*/
-NTSTATUS privilege_enum_account_rights(DOM_SID *sid,
-                                      uint32 *count,
-                                      char ***rights)
-{
-       TDB_DATA key, nextkey;
-       char *right;
-
-       if (!tdb) {
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       *rights = NULL;
-       *count = 0;
-
-       for (key = tdb_firstkey(tdb); key.dptr; key = nextkey) {
-               nextkey = tdb_nextkey(tdb, key);
-
-               right = key.dptr;
-               
-               if (privilege_sid_has_right(sid, right)) {
-                       (*rights) = (char **)Realloc(*rights,sizeof(char *) * ((*count)+1));
-                       if (! *rights) {
-                               safe_free(nextkey.dptr);
-                               free(key.dptr);
-                               return NT_STATUS_NO_MEMORY;
-                       }
-
-                       (*rights)[*count] = strdup(right);
-                       (*count)++;
-               }
-
-               free(key.dptr);
-       }
-
-       return NT_STATUS_OK;
-}
index 81c658af06d6fdc085ead5d2c18cc91063c620e5..3b2d1cf6332294184774e7c0ae08324a6db3646b 100644 (file)
@@ -817,10 +817,6 @@ void smbd_process_init(void)
        if (!init_change_notify())
                exit(1);
 
-       /* Setup privileges database */
-       if (!privilege_init())
-               exit(1);
-
        /* Setup the NTVFS subsystem */
        if (!ntvfs_init())
                exit(1);
index 2370ce3bdd93286d8c86e3f7c410a3e0ad1e37a4..3fddeafb2c1a3412a9d3d309c68a0242eafc9e86 100644 (file)
@@ -372,7 +372,7 @@ int tdb_create_rwlocks(int fd, unsigned int hash_size)
        unsigned size, i;
        tdb_rwlock_t *rwlocks;
 
-       size = (hash_size + 1) * sizeof(tdb_rwlock_t);
+       size = TDB_SPINLOCK_SIZE(hash_size);
        rwlocks = malloc(size);
        if (!rwlocks)
                return -1;
index d6a2ac6eb88a2a80de55d4e89cbc70a37876e8df..967fe37457fb9a69b754c3ef50fc860d729a7963 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __SPINLOCK_H__
 #define __SPINLOCK_H__
 
-#if HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
@@ -39,6 +39,8 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
 int tdb_create_rwlocks(int fd, unsigned int hash_size);
 int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
 
+#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t))
+
 #else /* !USE_SPINLOCKS */
 #if 0
 #define tdb_create_rwlocks(fd, hash_size) 0
@@ -50,6 +52,8 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
 int tdb_create_rwlocks(int fd, unsigned int hash_size);
 #endif
 int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+#define TDB_SPINLOCK_SIZE(hash_size) 0
+
 #endif
 
 #endif
index 513fbce5194f30def7f124708a37928ef4016607..fc210f42d4f51a5873466aa39a44b22118d31601 100644 (file)
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
+
+
+/* NOTE: If you use tdbs under valgrind, and in particular if you run
+ * tdbtorture, you may get spurious "uninitialized value" warnings.  I
+ * think this is because valgrind doesn't understand that the mmap'd
+ * area may be written to by other processes.  Memory can, from the
+ * point of view of the grinded process, spontaneously become
+ * initialized.
+ *
+ * I can think of a few solutions.  [mbp 20030311]
+ *
+ * 1 - Write suppressions for Valgrind so that it doesn't complain
+ * about this.  Probably the most reasonable but people need to
+ * remember to use them.
+ *
+ * 2 - Use IO not mmap when running under valgrind.  Not so nice.
+ *
+ * 3 - Use the special valgrind macros to mark memory as valid at the
+ * right time.  Probably too hard -- the process just doesn't know.
+ */ 
+
 #ifdef STANDALONE
 #if HAVE_CONFIG_H
 #include <config.h>
@@ -56,6 +77,8 @@
 #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
 #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
 #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off))
+#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size))
+
 
 /* NB assumes there is a local variable called "tdb" that is the
  * current context, also takes doubly-parenthesized print-style
@@ -214,10 +237,15 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
                                 tdb->fd, offset, rw_type, lck_type));
                }
                /* Was it an alarm timeout ? */
-               if (errno == EINTR && palarm_fired && *palarm_fired)
+               if (errno == EINTR && palarm_fired && *palarm_fired) {
+                       TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n", 
+                                tdb->fd, offset, rw_type, lck_type));
                        return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
+               }
                /* Otherwise - generic lock error. */
                /* errno set by fcntl */
+               TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", 
+                        tdb->fd, offset, rw_type, lck_type, strerror(errno)));
                return TDB_ERRCODE(TDB_ERR_LOCK, -1);
        }
        return 0;
@@ -642,10 +670,10 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
 left:
        /* Look left */
        left = offset - sizeof(tdb_off);
-       if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) {
+       if (left > TDB_DATA_START(tdb->header.hash_size)) {
                struct list_struct l;
                tdb_off leftsize;
-
+               
                /* Read in tailer and jump back to header */
                if (ofs_read(tdb, left, &leftsize) == -1) {
                        TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left));
@@ -994,12 +1022,11 @@ static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash)
 }
 
 /* As tdb_find, but if you succeed, keep the lock */
-static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype,
+static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype,
                             struct list_struct *rec)
 {
-       u32 hash, rec_ptr;
+       u32 rec_ptr;
 
-       hash = tdb_hash(&key);
        if (!tdb_keylocked(tdb, hash))
                return 0;
        if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
@@ -1040,13 +1067,13 @@ const char *tdb_errorstr(TDB_CONTEXT *tdb)
    on failure return -1.
 */
 
-static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
+static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf)
 {
        struct list_struct rec;
        tdb_off rec_ptr;
 
        /* find entry */
-       if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec)))
+       if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
                return -1;
 
        /* must be long enough key, data and tailer */
@@ -1080,9 +1107,11 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
        tdb_off rec_ptr;
        struct list_struct rec;
        TDB_DATA ret;
+       u32 hash;
 
        /* find which hash bucket it is in */
-       if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec)))
+       hash = tdb_hash(&key);
+       if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
                return tdb_null;
 
        if (rec.data_len)
@@ -1101,16 +1130,22 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
    this doesn't match the conventions in the rest of this module, but is
    compatible with gdbm
 */
-int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
+static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
 {
        struct list_struct rec;
        
-       if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0)
+       if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0)
                return 0;
        tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
        return 1;
 }
 
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+       u32 hash = tdb_hash(&key);
+       return tdb_exists_hash(tdb, key, hash);
+}
+
 /* record lock stops delete underneath */
 static int lock_record(TDB_CONTEXT *tdb, tdb_off off)
 {
@@ -1236,7 +1271,8 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
                        /* Try to clean dead ones from old traverses */
                        current = tlock->off;
                        tlock->off = rec->next;
-                       if (do_delete(tdb, current, rec) != 0)
+                       if (!tdb->read_only && 
+                           do_delete(tdb, current, rec) != 0)
                                goto fail;
                }
                tdb_unlock(tdb, tlock->hash, F_WRLCK);
@@ -1366,7 +1402,7 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
 
        if (!tdb->travlocks.off) {
                /* No previous element: do normal find, and lock record */
-               tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec);
+               tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb_hash(&oldkey), F_WRLCK, &rec);
                if (!tdb->travlocks.off)
                        return tdb_null;
                tdb->travlocks.hash = BUCKET(rec.full_hash);
@@ -1394,13 +1430,13 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
 }
 
 /* delete an entry in the database given a key */
-int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
+static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash)
 {
        tdb_off rec_ptr;
        struct list_struct rec;
        int ret;
 
-       if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
+       if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec)))
                return -1;
        ret = do_delete(tdb, rec_ptr, &rec);
        if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
@@ -1408,6 +1444,12 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
        return ret;
 }
 
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+       u32 hash = tdb_hash(&key);
+       return tdb_delete_hash(tdb, key, hash);
+}
+
 /* store an element in the database, replacing any existing element
    with the same key 
 
@@ -1430,13 +1472,13 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
 
        /* check for it existing, on insert. */
        if (flag == TDB_INSERT) {
-               if (tdb_exists(tdb, key)) {
+               if (tdb_exists_hash(tdb, key, hash)) {
                        tdb->ecode = TDB_ERR_EXISTS;
                        goto fail;
                }
        } else {
                /* first try in-place update, on modify or replace. */
-               if (tdb_update(tdb, key, dbuf) == 0)
+               if (tdb_update_hash(tdb, key, hash, dbuf) == 0)
                        goto out;
                if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST)
                        goto fail;
@@ -1448,7 +1490,7 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
            care.  Doing this first reduces fragmentation, and avoids
            coalescing with `allocated' block before it's updated. */
        if (flag != TDB_INSERT)
-               tdb_delete(tdb, key);
+               tdb_delete_hash(tdb, key, hash);
 
        /* Copy key+value *before* allocating free space in case malloc
           fails and we are left with a dead spot in the tdb. */
@@ -1497,13 +1539,13 @@ fail:
    is <= the old data size and the key exists.
    on failure return -1. Record must be locked before calling.
 */
-static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
+static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf)
 {
        struct list_struct rec;
        tdb_off rec_ptr;
 
        /* find entry */
-       if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec)))
+       if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
                return -1;
 
        /* Append of 0 is always ok. */
@@ -1545,7 +1587,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
                return -1;
 
        /* first try in-place. */
-       if (tdb_append_inplace(tdb, key, new_dbuf) == 0)
+       if (tdb_append_inplace(tdb, key, hash, new_dbuf) == 0)
                goto out;
 
        /* reset the error code potentially set by the tdb_append_inplace() */
@@ -1588,7 +1630,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf)
            care.  Doing this first reduces fragmentation, and avoids
            coalescing with `allocated' block before it's updated. */
 
-       tdb_delete(tdb, key);
+       tdb_delete_hash(tdb, key, hash);
 
        if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec)))
                goto fail;
@@ -1728,8 +1770,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
 
        if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
            || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
-           || tdb->header.version != TDB_VERSION
-           || (tdb->header.hash_size != hash_size
+           || (tdb->header.version != TDB_VERSION
                && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
                /* its not a valid database - possibly initialise it */
                if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
@@ -1934,6 +1975,8 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
 void tdb_unlockkeys(TDB_CONTEXT *tdb)
 {
        u32 i;
+       if (!tdb->lockedkeys)
+               return;
        for (i = 0; i < tdb->lockedkeys[0]; i++)
                tdb_unlock(tdb, tdb->lockedkeys[i+1], F_WRLCK);
        SAFE_FREE(tdb->lockedkeys);
index 7b344de6c45e716576fa4dc31254a18bc75e2ea4..1a0e1c1588fdc4affd532ae7c699c6f1e6a35d91 100644 (file)
 
  */
 
+#ifdef STANDALONE
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/time.h>
 #include <ctype.h>
 #include <signal.h>
-#include "tdb.h"
-
-static int failed;
-
-static char *add_suffix(const char *name, const char *suffix)
-{
-       char *ret;
-       int len = strlen(name) + strlen(suffix) + 1;
-       ret = malloc(len);
-       if (!ret) {
-               fprintf(stderr,"Out of memory!\n");
-               exit(1);
-       }
-       strncpy(ret, name, len);
-       strncat(ret, suffix, len);
-       return ret;
-}
-
-static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
-       TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
-
-       if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
-               fprintf(stderr,"Failed to insert into %s\n", tdb_new->name);
-               failed = 1;
-               return 1;
-       }
-       return 0;
-}
-
-
-static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
-       return 0;
-}
-
-/*
-  carefully backup a tdb, validating the contents and
-  only doing the backup if its OK
-  this function is also used for restore
-*/
-static int backup_tdb(const char *old_name, const char *new_name)
-{
-       TDB_CONTEXT *tdb;
-       TDB_CONTEXT *tdb_new;
-       char *tmp_name;
-       struct stat st;
-       int count1, count2;
-
-       tmp_name = add_suffix(new_name, ".tmp");
-
-       /* stat the old tdb to find its permissions */
-       if (stat(old_name, &st) != 0) {
-               perror(old_name);
-               return 1;
-       }
 
-       /* open the old tdb */
-       tdb = tdb_open(old_name, 0, 0, O_RDWR, 0);
-       if (!tdb) {
-               printf("Failed to open %s\n", old_name);
-               return 1;
-       }
-
-       /* create the new tdb */
-       unlink(tmp_name);
-       tdb_new = tdb_open(tmp_name, tdb->header.hash_size, 
-                          TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, 
-                          st.st_mode & 0777);
-       if (!tdb_new) {
-               perror(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       /* lock the old tdb */
-       if (tdb_lockall(tdb) != 0) {
-               fprintf(stderr,"Failed to lock %s\n", old_name);
-               tdb_close(tdb);
-               tdb_close(tdb_new);
-               unlink(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
+#else
 
-       failed = 0;
+#include "includes.h"
 
-       /* traverse and copy */
-       count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
-       if (count1 < 0 || failed) {
-               fprintf(stderr,"failed to copy %s\n", old_name);
-               tdb_close(tdb);
-               tdb_close(tdb_new);
-               unlink(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       /* close the old tdb */
-       tdb_close(tdb);
-
-       /* close the new tdb and re-open read-only */
-       tdb_close(tdb_new);
-       tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0);
-       if (!tdb_new) {
-               fprintf(stderr,"failed to reopen %s\n", tmp_name);
-               unlink(tmp_name);
-               perror(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-       
-       /* traverse the new tdb to confirm */
-       count2 = tdb_traverse(tdb_new, test_fn, 0);
-       if (count2 != count1) {
-               fprintf(stderr,"failed to copy %s\n", old_name);
-               tdb_close(tdb_new);
-               unlink(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       /* make sure the new tdb has reached stable storage */
-       fsync(tdb_new->fd);
-
-       /* close the new tdb and rename it to .bak */
-       tdb_close(tdb_new);
-       unlink(new_name);
-       if (rename(tmp_name, new_name) != 0) {
-               perror(new_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       printf("%s : %d records\n", old_name, count1);
-       free(tmp_name);
-
-       return 0;
-}
-
-
-
-/*
-  verify a tdb and if it is corrupt then restore from *.bak
-*/
-static int verify_tdb(const char *fname, const char *bak_name)
-{
-       TDB_CONTEXT *tdb;
-       int count = -1;
-
-       /* open the tdb */
-       tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
-
-       /* traverse the tdb, then close it */
-       if (tdb) {
-               count = tdb_traverse(tdb, test_fn, NULL);
-               tdb_close(tdb);
-       }
-
-       /* count is < 0 means an error */
-       if (count < 0) {
-               printf("restoring %s\n", fname);
-               return backup_tdb(bak_name, fname);
-       }
-
-       printf("%s : %d records\n", fname, count);
-
-       return 0;
-}
+#endif
 
+#include "tdb.h"
+#include "tdbback.h"
 
 /*
   see if one file is newer than another
@@ -245,7 +89,7 @@ static void usage(void)
        printf("Usage: tdbbackup [options] <fname...>\n\n");
        printf("   -h            this help message\n");
        printf("   -s suffix     set the backup suffix\n");
-       printf("   -v            veryify mode (restore if corrupt)\n");
+       printf("   -v            verify mode (restore if corrupt)\n");
 }
                
 
@@ -255,7 +99,7 @@ static void usage(void)
        int ret = 0;
        int c;
        int verify = 0;
-       char *suffix = ".bak";
+       const char *suffix = ".bak";
        extern int optind;
        extern char *optarg;
 
@@ -303,13 +147,3 @@ static void usage(void)
 
        return ret;
 }
-
-#ifdef VALGRIND
-size_t valgrind_strlen(const char *s)
-{
-       size_t count;
-       for(count = 0; *s++; count++)
-               ;
-       return count;
-}
-#endif
index f5e486be1458b3e9fdf57a947438e06b2c88225b..92009dcef48cbd435dfa2e28d4c629ad946486b8 100644 (file)
@@ -111,23 +111,24 @@ static void print_data(unsigned char *buf,int len)
 
 static void help(void)
 {
-       printf("
-tdbtool: 
-  create    dbname     : create a database
-  open      dbname     : open an existing database
-  erase                : erase the database
-  dump                 : dump the database as strings
-  insert    key  data  : insert a record
-  store     key  data  : store a record (replace)
-  show      key        : show a record by key
-  delete    key        : delete a record by key
-  list                 : print the database hash table and freelist
-  free                 : print the database freelist
-  1 | first            : print the first record
-  n | next             : print the next record
-  q | quit             : terminate
-  \\n                   : repeat 'next' command
-");
+       printf("\n"
+"tdbtool: \n"
+"  create    dbname     : create a database\n"
+"  open      dbname     : open an existing database\n"
+"  erase                : erase the database\n"
+"  dump                 : dump the database as strings\n"
+"  insert    key  data  : insert a record\n"
+"  move      key  file  : move a record to a destination tdb\n"
+"  store     key  data  : store a record (replace)\n"
+"  show      key        : show a record by key\n"
+"  delete    key        : delete a record by key\n"
+"  list                 : print the database hash table and freelist\n"
+"  free                 : print the database freelist\n"
+"  1 | first            : print the first record\n"
+"  n | next             : print the next record\n"
+"  q | quit             : terminate\n"
+"  \\n                   : repeat 'next' command\n"
+"\n");
 }
 
 static void terror(char *why)
@@ -251,16 +252,26 @@ static void show_tdb(void)
        }
 
        key.dptr = k;
-/*     key.dsize = strlen(k)+1;*/
-       key.dsize = strlen(k);
+       key.dsize = strlen(k)+1;
 
        dbuf = tdb_fetch(tdb, key);
        if (!dbuf.dptr) {
-               terror("fetch failed");
-               return;
+               /* maybe it is non-NULL terminated key? */
+               key.dsize = strlen(k); 
+               dbuf = tdb_fetch(tdb, key);
+               
+               if ( !dbuf.dptr ) {
+                       terror("fetch failed");
+                       return;
+               }
        }
+       
        /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
        print_rec(tdb, key, dbuf, NULL);
+       
+       free( dbuf.dptr );
+       
+       return;
 }
 
 static void delete_tdb(void)
@@ -281,6 +292,57 @@ static void delete_tdb(void)
        }
 }
 
+static void move_rec(void)
+{
+       char *k = get_token(1);
+       char *file = get_token(0);      
+       TDB_DATA key, dbuf;
+       TDB_CONTEXT *dst_tdb;
+
+       if (!k) {
+               help();
+               return;
+       }
+       
+       if ( !file ) {
+               terror("need destination tdb name");
+               return;
+       }
+
+       key.dptr = k;
+       key.dsize = strlen(k)+1;
+
+       dbuf = tdb_fetch(tdb, key);
+       if (!dbuf.dptr) {
+               /* maybe it is non-NULL terminated key? */
+               key.dsize = strlen(k); 
+               dbuf = tdb_fetch(tdb, key);
+               
+               if ( !dbuf.dptr ) {
+                       terror("fetch failed");
+                       return;
+               }
+       }
+       
+       print_rec(tdb, key, dbuf, NULL);
+       
+       dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600);
+       if ( !dst_tdb ) {
+               terror("unable to open destination tdb");
+               return;
+       }
+       
+       if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) {
+               terror("failed to move record");
+       }
+       else
+               printf("record moved\n");
+       
+       tdb_close( dst_tdb );
+       
+       return;
+}
+
 #if 0
 static int print_conn_key(TDB_DATA key)
 {
@@ -455,6 +517,9 @@ int main(int argc, char *argv[])
         } else if (strcmp(tok,"dump") == 0) {
             bIterate = 0;
             tdb_traverse(tdb, print_rec, NULL);
+        } else if (strcmp(tok,"move") == 0) {
+            bIterate = 0;
+            move_rec();
         } else if (strcmp(tok,"list") == 0) {
             tdb_dump_all(tdb);
         } else if (strcmp(tok, "free") == 0) {
index e27bbff9909bbf478214f3f72885ab9a00d02ff1..3f704e537ea90ebf768a887f3dc5911495632f9c 100644 (file)
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
index 0d8f6128cc5f8e7d0cec89d3b2822227026bdf7d..ce5188300cc5baf8dc0e1e43129712cbf9b247a4 100644 (file)
@@ -266,7 +266,7 @@ BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value)
  on failure.
 ****************************************************************************/
 
-int tdb_store_by_string(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags)
+int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags)
 {
        TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
        
@@ -278,7 +278,7 @@ int tdb_store_by_string(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int
  free() on the result dptr.
 ****************************************************************************/
 
-TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, const char *keystr)
+TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr)
 {
        TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
 
@@ -289,7 +289,7 @@ TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, const char *keystr)
  Delete an entry using a null terminated string key. 
 ****************************************************************************/
 
-int tdb_delete_by_string(TDB_CONTEXT *tdb, const char *keystr)
+int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr)
 {
        TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);
 
@@ -311,7 +311,7 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldva
        if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
                /* The lookup failed */
                if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
-                       /* but not becouse it didn't exist */
+                       /* but not because it didn't exist */
                        goto err_out;
                }
                
@@ -352,7 +352,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv
        if (!tdb_fetch_uint32(tdb, keystr, &val)) {
                /* It failed */
                if (tdb_error(tdb) != TDB_ERR_NOEXIST) { 
-                       /* and not becouse it didn't exist */
+                       /* and not because it didn't exist */
                        goto err_out;
                }
 
@@ -387,6 +387,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv
 size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 {
        va_list ap;
+       uint8 bt;
        uint16 w;
        uint32 d;
        int i;
@@ -402,44 +403,50 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 
        while (*fmt) {
                switch ((c = *fmt++)) {
-               case 'w':
+               case 'b': /* unsigned 8-bit integer */
+                       len = 1;
+                       bt = (uint8)va_arg(ap, int);
+                       if (bufsize && bufsize >= len)
+                               SSVAL(buf, 0, bt);
+                       break;
+               case 'w': /* unsigned 16-bit integer */
                        len = 2;
                        w = (uint16)va_arg(ap, int);
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                SSVAL(buf, 0, w);
                        break;
-               case 'd':
+               case 'd': /* signed 32-bit integer (standard int in most systems) */
                        len = 4;
                        d = va_arg(ap, uint32);
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                SIVAL(buf, 0, d);
                        break;
-               case 'p':
+               case 'p': /* pointer */
                        len = 4;
                        p = va_arg(ap, void *);
                        d = p?1:0;
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                SIVAL(buf, 0, d);
                        break;
-               case 'P':
+               case 'P': /* null-terminated string */
                        s = va_arg(ap,char *);
                        w = strlen(s);
                        len = w + 1;
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                memcpy(buf, s, len);
                        break;
-               case 'f':
+               case 'f': /* null-terminated string */
                        s = va_arg(ap,char *);
                        w = strlen(s);
                        len = w + 1;
-                       if (bufsize >= len)
+                       if (bufsize && bufsize >= len)
                                memcpy(buf, s, len);
                        break;
-               case 'B':
+               case 'B': /* fixed-length string */
                        i = va_arg(ap, int);
                        s = va_arg(ap, char *);
                        len = 4+i;
-                       if (bufsize >= len) {
+                       if (bufsize && bufsize >= len) {
                                SIVAL(buf, 0, i);
                                memcpy(buf+4, s, i);
                        }
@@ -452,7 +459,10 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
                }
 
                buf += len;
-               bufsize -= len;
+               if (bufsize)
+                       bufsize -= len;
+               if (bufsize < 0)
+                       bufsize = 0;
        }
 
        va_end(ap);
@@ -471,6 +481,7 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
 {
        va_list ap;
+       uint8 *bt;
        uint16 *w;
        uint32 *d;
        int len;
@@ -486,6 +497,13 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
        
        while (*fmt) {
                switch ((c=*fmt++)) {
+               case 'b':
+                       len = 1;
+                       bt = va_arg(ap, uint8 *);
+                       if (bufsize < len)
+                               goto no_space;
+                       *bt = SVAL(buf, 0);
+                       break;
                case 'w':
                        len = 2;
                        w = va_arg(ap, uint16 *);
@@ -563,6 +581,67 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
        return -1;
 }
 
+
+/**
+ * Pack SID passed by pointer
+ *
+ * @param pack_buf pointer to buffer which is to be filled with packed data
+ * @param bufsize size of packing buffer
+ * @param sid pointer to sid to be packed
+ *
+ * @return length of the packed representation of the whole structure
+ **/
+size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid)
+{
+       int idx;
+       size_t len = 0;
+       
+       if (!sid || !pack_buf) return -1;
+       
+       len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
+                       sid->num_auths);
+       
+       for (idx = 0; idx < 6; idx++) {
+               len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]);
+       }
+       
+       for (idx = 0; idx < MAXSUBAUTHS; idx++) {
+               len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]);
+       }
+       
+       return len;
+}
+
+
+/**
+ * Unpack SID into a pointer
+ *
+ * @param pack_buf pointer to buffer with packed representation
+ * @param bufsize size of the buffer
+ * @param sid pointer to sid structure to be filled with unpacked data
+ *
+ * @return size of structure unpacked from buffer
+ **/
+size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid)
+{
+       int idx, len = 0;
+       
+       if (!sid || !pack_buf) return -1;
+
+       len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
+                         &sid->sid_rev_num, &sid->num_auths);
+                         
+       for (idx = 0; idx < 6; idx++) {
+               len += tdb_unpack(pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]);
+       }
+       
+       for (idx = 0; idx < MAXSUBAUTHS; idx++) {
+               len += tdb_unpack(pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]);
+       }
+       
+       return len;
+}
+
 /****************************************************************************
  Log tdb messages via DEBUG().
 ****************************************************************************/
@@ -665,7 +744,7 @@ TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern)
        
        return list;
 
-};
+}
 
 
 /**
@@ -679,9 +758,8 @@ void tdb_search_list_free(TDB_LIST_NODE* node)
        
        while (node) {
                next_node = node->next;
+               SAFE_FREE(node->node_key.dptr);
                SAFE_FREE(node);
                node = next_node;
-       };
-};
-
-
+       }
+}
index 758cef48615874d3e779779aba0518e33c2930e0..de0a7f6a1418338fe6a43992fd75ec6d0b093720 100644 (file)
@@ -82,7 +82,7 @@ static BOOL test_one(struct cli_state *cli, const char *name)
        }
 
        /* see if the short name is already in the tdb */
-       data = tdb_fetch_by_string(tdb, shortname);
+       data = tdb_fetch_bystring(tdb, shortname);
        if (data.dptr) {
                /* maybe its a duplicate long name? */
                if (strcasecmp(name, data.dptr) != 0) {
@@ -98,7 +98,7 @@ static BOOL test_one(struct cli_state *cli, const char *name)
                /* store it for later */
                namedata.dptr = name;
                namedata.dsize = strlen(name)+1;
-               tdb_store_by_string(tdb, shortname, namedata, TDB_REPLACE);
+               tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
        }
 
        return True;
index 7b344de6c45e716576fa4dc31254a18bc75e2ea4..1a0e1c1588fdc4affd532ae7c699c6f1e6a35d91 100644 (file)
 
  */
 
+#ifdef STANDALONE
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/time.h>
 #include <ctype.h>
 #include <signal.h>
-#include "tdb.h"
-
-static int failed;
-
-static char *add_suffix(const char *name, const char *suffix)
-{
-       char *ret;
-       int len = strlen(name) + strlen(suffix) + 1;
-       ret = malloc(len);
-       if (!ret) {
-               fprintf(stderr,"Out of memory!\n");
-               exit(1);
-       }
-       strncpy(ret, name, len);
-       strncat(ret, suffix, len);
-       return ret;
-}
-
-static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
-       TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
-
-       if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
-               fprintf(stderr,"Failed to insert into %s\n", tdb_new->name);
-               failed = 1;
-               return 1;
-       }
-       return 0;
-}
-
-
-static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
-       return 0;
-}
-
-/*
-  carefully backup a tdb, validating the contents and
-  only doing the backup if its OK
-  this function is also used for restore
-*/
-static int backup_tdb(const char *old_name, const char *new_name)
-{
-       TDB_CONTEXT *tdb;
-       TDB_CONTEXT *tdb_new;
-       char *tmp_name;
-       struct stat st;
-       int count1, count2;
-
-       tmp_name = add_suffix(new_name, ".tmp");
-
-       /* stat the old tdb to find its permissions */
-       if (stat(old_name, &st) != 0) {
-               perror(old_name);
-               return 1;
-       }
 
-       /* open the old tdb */
-       tdb = tdb_open(old_name, 0, 0, O_RDWR, 0);
-       if (!tdb) {
-               printf("Failed to open %s\n", old_name);
-               return 1;
-       }
-
-       /* create the new tdb */
-       unlink(tmp_name);
-       tdb_new = tdb_open(tmp_name, tdb->header.hash_size, 
-                          TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, 
-                          st.st_mode & 0777);
-       if (!tdb_new) {
-               perror(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       /* lock the old tdb */
-       if (tdb_lockall(tdb) != 0) {
-               fprintf(stderr,"Failed to lock %s\n", old_name);
-               tdb_close(tdb);
-               tdb_close(tdb_new);
-               unlink(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
+#else
 
-       failed = 0;
+#include "includes.h"
 
-       /* traverse and copy */
-       count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
-       if (count1 < 0 || failed) {
-               fprintf(stderr,"failed to copy %s\n", old_name);
-               tdb_close(tdb);
-               tdb_close(tdb_new);
-               unlink(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       /* close the old tdb */
-       tdb_close(tdb);
-
-       /* close the new tdb and re-open read-only */
-       tdb_close(tdb_new);
-       tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0);
-       if (!tdb_new) {
-               fprintf(stderr,"failed to reopen %s\n", tmp_name);
-               unlink(tmp_name);
-               perror(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-       
-       /* traverse the new tdb to confirm */
-       count2 = tdb_traverse(tdb_new, test_fn, 0);
-       if (count2 != count1) {
-               fprintf(stderr,"failed to copy %s\n", old_name);
-               tdb_close(tdb_new);
-               unlink(tmp_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       /* make sure the new tdb has reached stable storage */
-       fsync(tdb_new->fd);
-
-       /* close the new tdb and rename it to .bak */
-       tdb_close(tdb_new);
-       unlink(new_name);
-       if (rename(tmp_name, new_name) != 0) {
-               perror(new_name);
-               free(tmp_name);
-               return 1;
-       }
-
-       printf("%s : %d records\n", old_name, count1);
-       free(tmp_name);
-
-       return 0;
-}
-
-
-
-/*
-  verify a tdb and if it is corrupt then restore from *.bak
-*/
-static int verify_tdb(const char *fname, const char *bak_name)
-{
-       TDB_CONTEXT *tdb;
-       int count = -1;
-
-       /* open the tdb */
-       tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
-
-       /* traverse the tdb, then close it */
-       if (tdb) {
-               count = tdb_traverse(tdb, test_fn, NULL);
-               tdb_close(tdb);
-       }
-
-       /* count is < 0 means an error */
-       if (count < 0) {
-               printf("restoring %s\n", fname);
-               return backup_tdb(bak_name, fname);
-       }
-
-       printf("%s : %d records\n", fname, count);
-
-       return 0;
-}
+#endif
 
+#include "tdb.h"
+#include "tdbback.h"
 
 /*
   see if one file is newer than another
@@ -245,7 +89,7 @@ static void usage(void)
        printf("Usage: tdbbackup [options] <fname...>\n\n");
        printf("   -h            this help message\n");
        printf("   -s suffix     set the backup suffix\n");
-       printf("   -v            veryify mode (restore if corrupt)\n");
+       printf("   -v            verify mode (restore if corrupt)\n");
 }
                
 
@@ -255,7 +99,7 @@ static void usage(void)
        int ret = 0;
        int c;
        int verify = 0;
-       char *suffix = ".bak";
+       const char *suffix = ".bak";
        extern int optind;
        extern char *optarg;
 
@@ -303,13 +147,3 @@ static void usage(void)
 
        return ret;
 }
-
-#ifdef VALGRIND
-size_t valgrind_strlen(const char *s)
-{
-       size_t count;
-       for(count = 0; *s++; count++)
-               ;
-       return count;
-}
-#endif
index f5e486be1458b3e9fdf57a947438e06b2c88225b..92009dcef48cbd435dfa2e28d4c629ad946486b8 100644 (file)
@@ -111,23 +111,24 @@ static void print_data(unsigned char *buf,int len)
 
 static void help(void)
 {
-       printf("
-tdbtool: 
-  create    dbname     : create a database
-  open      dbname     : open an existing database
-  erase                : erase the database
-  dump                 : dump the database as strings
-  insert    key  data  : insert a record
-  store     key  data  : store a record (replace)
-  show      key        : show a record by key
-  delete    key        : delete a record by key
-  list                 : print the database hash table and freelist
-  free                 : print the database freelist
-  1 | first            : print the first record
-  n | next             : print the next record
-  q | quit             : terminate
-  \\n                   : repeat 'next' command
-");
+       printf("\n"
+"tdbtool: \n"
+"  create    dbname     : create a database\n"
+"  open      dbname     : open an existing database\n"
+"  erase                : erase the database\n"
+"  dump                 : dump the database as strings\n"
+"  insert    key  data  : insert a record\n"
+"  move      key  file  : move a record to a destination tdb\n"
+"  store     key  data  : store a record (replace)\n"
+"  show      key        : show a record by key\n"
+"  delete    key        : delete a record by key\n"
+"  list                 : print the database hash table and freelist\n"
+"  free                 : print the database freelist\n"
+"  1 | first            : print the first record\n"
+"  n | next             : print the next record\n"
+"  q | quit             : terminate\n"
+"  \\n                   : repeat 'next' command\n"
+"\n");
 }
 
 static void terror(char *why)
@@ -251,16 +252,26 @@ static void show_tdb(void)
        }
 
        key.dptr = k;
-/*     key.dsize = strlen(k)+1;*/
-       key.dsize = strlen(k);
+       key.dsize = strlen(k)+1;
 
        dbuf = tdb_fetch(tdb, key);
        if (!dbuf.dptr) {
-               terror("fetch failed");
-               return;
+               /* maybe it is non-NULL terminated key? */
+               key.dsize = strlen(k); 
+               dbuf = tdb_fetch(tdb, key);
+               
+               if ( !dbuf.dptr ) {
+                       terror("fetch failed");
+                       return;
+               }
        }
+       
        /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
        print_rec(tdb, key, dbuf, NULL);
+       
+       free( dbuf.dptr );
+       
+       return;
 }
 
 static void delete_tdb(void)
@@ -281,6 +292,57 @@ static void delete_tdb(void)
        }
 }
 
+static void move_rec(void)
+{
+       char *k = get_token(1);
+       char *file = get_token(0);      
+       TDB_DATA key, dbuf;
+       TDB_CONTEXT *dst_tdb;
+
+       if (!k) {
+               help();
+               return;
+       }
+       
+       if ( !file ) {
+               terror("need destination tdb name");
+               return;
+       }
+
+       key.dptr = k;
+       key.dsize = strlen(k)+1;
+
+       dbuf = tdb_fetch(tdb, key);
+       if (!dbuf.dptr) {
+               /* maybe it is non-NULL terminated key? */
+               key.dsize = strlen(k); 
+               dbuf = tdb_fetch(tdb, key);
+               
+               if ( !dbuf.dptr ) {
+                       terror("fetch failed");
+                       return;
+               }
+       }
+       
+       print_rec(tdb, key, dbuf, NULL);
+       
+       dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600);
+       if ( !dst_tdb ) {
+               terror("unable to open destination tdb");
+               return;
+       }
+       
+       if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) {
+               terror("failed to move record");
+       }
+       else
+               printf("record moved\n");
+       
+       tdb_close( dst_tdb );
+       
+       return;
+}
+
 #if 0
 static int print_conn_key(TDB_DATA key)
 {
@@ -455,6 +517,9 @@ int main(int argc, char *argv[])
         } else if (strcmp(tok,"dump") == 0) {
             bIterate = 0;
             tdb_traverse(tdb, print_rec, NULL);
+        } else if (strcmp(tok,"move") == 0) {
+            bIterate = 0;
+            move_rec();
         } else if (strcmp(tok,"list") == 0) {
             tdb_dump_all(tdb);
         } else if (strcmp(tok, "free") == 0) {
index e27bbff9909bbf478214f3f72885ab9a00d02ff1..3f704e537ea90ebf768a887f3dc5911495632f9c 100644 (file)
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <sys/mman.h>
 #include <sys/stat.h>