From 2fefd924209f5d0872eb42559246c75dea38961d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 2 Oct 2012 12:21:20 +0200 Subject: [PATCH 01/20] tdb: Fix a typo Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Tue Oct 2 19:52:16 CEST 2012 on sn-devel-104 (cherry picked from commit a168a7c791a4be1730a370d059b3a1073fbb0bdd) --- lib/tdb/common/lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tdb/common/lock.c b/lib/tdb/common/lock.c index 88a52e9..260fab6 100644 --- a/lib/tdb/common/lock.c +++ b/lib/tdb/common/lock.c @@ -562,7 +562,7 @@ int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, /* We cover two kinds of locks: * 1) Normal chain locks. Taken for almost all operations. - * 3) Individual records locks. Taken after normal or free + * 2) Individual records locks. Taken after normal or free * chain locks. * * It is (1) which cause the starvation problem, so we're only -- 1.7.9.5 From f8868edeaf41d6887ce04927666a5e4e31ae0831 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Oct 2012 09:04:19 +0930 Subject: [PATCH 02/20] tdb: add tdb_rescue() This allows for an emergency best-effort dump. It's a little better than strings(1). Signed-off-by: Rusty Russell (cherry picked from commit 90f463b25f7bb0bc944732773c56e356834ea203) --- lib/tdb/ABI/tdb-1.2.11.sigs | 67 +++++++ lib/tdb/common/rescue.c | 349 ++++++++++++++++++++++++++++++++++ lib/tdb/include/tdb.h | 22 +++ lib/tdb/libtdb.m4 | 2 +- lib/tdb/test/run-rescue-find_entry.c | 50 +++++ lib/tdb/test/run-rescue.c | 126 ++++++++++++ lib/tdb/wscript | 10 +- 7 files changed, 622 insertions(+), 4 deletions(-) create mode 100644 lib/tdb/ABI/tdb-1.2.11.sigs create mode 100644 lib/tdb/common/rescue.c create mode 100644 lib/tdb/test/run-rescue-find_entry.c create mode 100644 lib/tdb/test/run-rescue.c diff --git a/lib/tdb/ABI/tdb-1.2.11.sigs b/lib/tdb/ABI/tdb-1.2.11.sigs new file mode 100644 index 0000000..d727f21 --- /dev/null +++ b/lib/tdb/ABI/tdb-1.2.11.sigs @@ -0,0 +1,67 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/lib/tdb/common/rescue.c b/lib/tdb/common/rescue.c new file mode 100644 index 0000000..03ae8d6 --- /dev/null +++ b/lib/tdb/common/rescue.c @@ -0,0 +1,349 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library, rescue attempt code. + + Copyright (C) Rusty Russell 2012 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#include "tdb_private.h" +#include + + +struct found { + tdb_off_t head; /* 0 -> invalid. */ + struct tdb_record rec; + TDB_DATA key; + bool in_hash; + bool in_free; +}; + +struct found_table { + /* As an ordered array (by head offset). */ + struct found *arr; + unsigned int num, max; +}; + +static bool looks_like_valid_record(struct tdb_context *tdb, + tdb_off_t off, + const struct tdb_record *rec, + TDB_DATA *key) +{ + unsigned int hval; + + if (rec->magic != TDB_MAGIC) + return false; + + if (rec->key_len + rec->data_len > rec->rec_len) + return false; + + if (rec->rec_len % TDB_ALIGNMENT) + return false; + + /* Next pointer must make some sense. */ + if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->header.hash_size)) + return false; + + if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 1)) + return false; + + key->dsize = rec->key_len; + key->dptr = tdb_alloc_read(tdb, off + sizeof(*rec), key->dsize); + if (!key->dptr) + return false; + + hval = tdb->hash_fn(key); + if (hval != rec->full_hash) { + free(key->dptr); + return false; + } + + /* Caller frees up key->dptr */ + return true; +} + +static bool add_to_table(struct found_table *found, + tdb_off_t off, + struct tdb_record *rec, + TDB_DATA key) +{ + if (found->num + 1 > found->max) { + struct found *new; + found->max = (found->max ? found->max * 2 : 128); + new = realloc(found->arr, found->max * sizeof(found->arr[0])); + if (!new) + return false; + found->arr = new; + } + + found->arr[found->num].head = off; + found->arr[found->num].rec = *rec; + found->arr[found->num].key = key; + found->arr[found->num].in_hash = false; + found->arr[found->num].in_free = false; + + found->num++; + return true; +} + +static bool walk_record(struct tdb_context *tdb, + const struct found *f, + void (*walk)(TDB_DATA, TDB_DATA, void *private_data), + void *private_data) +{ + TDB_DATA data; + + data.dsize = f->rec.data_len; + data.dptr = tdb_alloc_read(tdb, + f->head + sizeof(f->rec) + f->rec.key_len, + data.dsize); + if (!data.dptr) { + if (tdb->ecode == TDB_ERR_OOM) + return false; + /* I/O errors are expected. */ + return true; + } + + walk(f->key, data, private_data); + free(data.dptr); + return true; +} + +/* First entry which has offset >= this one. */ +static unsigned int find_entry(struct found_table *found, tdb_off_t off) +{ + unsigned int start = 0, end = found->num; + + while (start < end) { + /* We can't overflow here. */ + unsigned int mid = (start + end) / 2; + + if (off < found->arr[mid].head) { + end = mid; + } else if (off > found->arr[mid].head) { + start = mid + 1; + } else { + return mid; + } + } + + assert(start == end); + return end; +} + +static void found_in_hashchain(struct found_table *found, tdb_off_t head) +{ + unsigned int match; + + match = find_entry(found, head); + if (match < found->num && found->arr[match].head == head) { + found->arr[match].in_hash = true; + } +} + +static void mark_free_area(struct found_table *found, tdb_off_t head, + tdb_len_t len) +{ + unsigned int match; + + match = find_entry(found, head); + /* Mark everything within this free entry. */ + while (match < found->num) { + if (found->arr[match].head >= head + len) { + break; + } + found->arr[match].in_free = true; + match++; + } +} + +static int cmp_key(const void *a, const void *b) +{ + const struct found *fa = a, *fb = b; + + if (fa->key.dsize < fb->key.dsize) { + return -1; + } else if (fa->key.dsize > fb->key.dsize) { + return 1; + } + return memcmp(fa->key.dptr, fb->key.dptr, fa->key.dsize); +} + +static bool key_eq(TDB_DATA a, TDB_DATA b) +{ + return a.dsize == b.dsize + && memcmp(a.dptr, b.dptr, a.dsize) == 0; +} + +static void free_table(struct found_table *found) +{ + unsigned int i; + + for (i = 0; i < found->num; i++) { + free(found->arr[i].key.dptr); + } + free(found->arr); +} + +static void logging_suppressed(struct tdb_context *tdb, + enum tdb_debug_level level, const char *fmt, ...) +{ +} + +_PUBLIC_ int tdb_rescue(struct tdb_context *tdb, + void (*walk)(TDB_DATA, TDB_DATA, void *private_data), + void *private_data) +{ + struct found_table found = { NULL, 0, 0 }; + tdb_off_t h, off, i; + tdb_log_func oldlog = tdb->log.log_fn; + struct tdb_record rec; + TDB_DATA key; + bool locked; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return -1; + locked = true; + } + + /* Make sure we know true size of the underlying file. */ + tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); + + /* Suppress logging, since we anticipate errors. */ + tdb->log.log_fn = logging_suppressed; + + /* Now walk entire db looking for records. */ + for (off = TDB_DATA_START(tdb->header.hash_size); + off < tdb->map_size; + off += TDB_ALIGNMENT) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == -1) + continue; + + if (looks_like_valid_record(tdb, off, &rec, &key)) { + if (!add_to_table(&found, off, &rec, key)) { + goto oom; + } + } + } + + /* Walk hash chains to positive vet. */ + for (h = 0; h < 1+tdb->header.hash_size; h++) { + bool slow_chase = false; + tdb_off_t slow_off = FREELIST_TOP + h*sizeof(tdb_off_t); + + if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), + &off) == -1) + continue; + + while (off && off != slow_off) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) != 0) { + break; + } + + /* 0 is the free list, rest are hash chains. */ + if (h == 0) { + /* Don't mark garbage as free. */ + if (rec.magic != TDB_FREE_MAGIC) { + break; + } + mark_free_area(&found, off, + sizeof(rec) + rec.rec_len); + } else { + found_in_hashchain(&found, off); + } + + off = rec.next; + + /* Loop detection using second pointer at half-speed */ + if (slow_chase) { + /* First entry happens to be next ptr */ + tdb_ofs_read(tdb, slow_off, &slow_off); + } + slow_chase = !slow_chase; + } + } + + /* Recovery area: must be marked as free, since it often has old + * records in there! */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off) == 0 && off != 0) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == 0) { + mark_free_area(&found, off, sizeof(rec) + rec.rec_len); + } + } + + /* Now sort by key! */ + qsort(found.arr, found.num, sizeof(found.arr[0]), cmp_key); + + for (i = 0; i < found.num; ) { + unsigned int num, num_in_hash = 0; + + /* How many are identical? */ + for (num = 0; num < found.num - i; num++) { + if (!key_eq(found.arr[i].key, found.arr[i+num].key)) { + break; + } + if (found.arr[i+num].in_hash) { + if (!walk_record(tdb, &found.arr[i+num], + walk, private_data)) + goto oom; + num_in_hash++; + } + } + assert(num); + + /* If none were in the hash, we print any not in free list. */ + if (num_in_hash == 0) { + unsigned int j; + + for (j = i; j < i + num; j++) { + if (!found.arr[j].in_free) { + if (!walk_record(tdb, &found.arr[j], + walk, private_data)) + goto oom; + } + } + } + + i += num; + } + + tdb->log.log_fn = oldlog; + if (locked) { + tdb_unlockall_read(tdb); + } + return 0; + +oom: + tdb->log.log_fn = oldlog; + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_rescue: failed allocating\n")); + free_table(&found); + if (locked) { + tdb_unlockall_read(tdb); + } + return -1; +} diff --git a/lib/tdb/include/tdb.h b/lib/tdb/include/tdb.h index 5eb9562..d19439e 100644 --- a/lib/tdb/include/tdb.h +++ b/lib/tdb/include/tdb.h @@ -814,6 +814,28 @@ int tdb_check(struct tdb_context *tdb, int (*check) (TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); +/** + * @brief Dump all possible records in a corrupt database. + * + * This is the only way to get data out of a database where tdb_check() fails. + * It will call walk() with anything which looks like a database record; this + * may well include invalid, incomplete or duplicate records. + * + * @param[in] tdb The database to check. + * + * @param[in] walk The walk function to use. + * + * @param[in] private_data the private data to pass to the walk function. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_rescue(struct tdb_context *tdb, + void (*walk) (TDB_DATA key, TDB_DATA data, void *private_data), + void *private_data); + /* @} ******************************************************************/ /* Low level locking functions: use with care */ diff --git a/lib/tdb/libtdb.m4 b/lib/tdb/libtdb.m4 index b5164fc..47f098e 100644 --- a/lib/tdb/libtdb.m4 +++ b/lib/tdb/libtdb.m4 @@ -13,7 +13,7 @@ if test x"$tdbdir" = "x"; then AC_MSG_ERROR([cannot find tdb source in $tdbpaths]) fi TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" -TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o common/check.o common/hash.o common/summary.o" +TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o common/check.o common/hash.o common/summary.o common/rescue.o" AC_SUBST(TDB_OBJ) AC_SUBST(LIBREPLACEOBJ) diff --git a/lib/tdb/test/run-rescue-find_entry.c b/lib/tdb/test/run-rescue-find_entry.c new file mode 100644 index 0000000..25f4f1c --- /dev/null +++ b/lib/tdb/test/run-rescue-find_entry.c @@ -0,0 +1,50 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/rescue.c" +#include "tap-interface.h" +#include +#include "logging.h" + +#define NUM 20 + +/* Binary searches are deceptively simple: easy to screw up! */ +int main(int argc, char *argv[]) +{ + unsigned int i, j, n; + struct found f[NUM+1]; + struct found_table table; + + /* Set up array for searching. */ + for (i = 0; i < NUM+1; i++) { + f[i].head = i * 3; + } + table.arr = f; + + for (i = 0; i < NUM; i++) { + table.num = i; + for (j = 0; j < (i + 2) * 3; j++) { + n = find_entry(&table, j); + ok1(n <= i); + + /* If we were searching for something too large... */ + if (j > i*3) + ok1(n == i); + else { + /* It must give us something after j */ + ok1(f[n].head >= j); + ok1(n == 0 || f[n-1].head < j); + } + } + } + + return exit_status(); +} diff --git a/lib/tdb/test/run-rescue.c b/lib/tdb/test/run-rescue.c new file mode 100644 index 0000000..a26c493 --- /dev/null +++ b/lib/tdb/test/run-rescue.c @@ -0,0 +1,126 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/rescue.c" +#include "tap-interface.h" +#include +#include "logging.h" + +struct walk_data { + TDB_DATA key; + TDB_DATA data; + bool fail; + unsigned count; +}; + +static inline bool tdb_deq(TDB_DATA a, TDB_DATA b) +{ + return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; +} + +static inline TDB_DATA tdb_mkdata(const void *p, size_t len) +{ + TDB_DATA d; + d.dptr = (void *)p; + d.dsize = len; + return d; +} + +static void walk(TDB_DATA key, TDB_DATA data, void *_wd) +{ + struct walk_data *wd = _wd; + + if (!tdb_deq(key, wd->key)) { + wd->fail = true; + } + + if (!tdb_deq(data, wd->data)) { + wd->fail = true; + } + wd->count++; +} + +static void count_records(TDB_DATA key, TDB_DATA data, void *_wd) +{ + struct walk_data *wd = _wd; + + if (!tdb_deq(key, wd->key) || !tdb_deq(data, wd->data)) + diag("%.*s::%.*s\n", + (int)key.dsize, key.dptr, (int)data.dsize, data.dptr); + wd->count++; +} + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + unsigned int *count = tdb_get_logging_private(tdb); + (*count)++; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + struct walk_data wd; + unsigned int i, size, log_count = 0; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + + plan_tests(8); + tdb = tdb_open_ex("run-rescue.tdb", 1, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &log_ctx, NULL); + + wd.key.dsize = strlen("hi"); + wd.key.dptr = (void *)"hi"; + wd.data.dsize = strlen("world"); + wd.data.dptr = (void *)"world"; + wd.count = 0; + wd.fail = false; + + ok1(tdb_store(tdb, wd.key, wd.data, TDB_INSERT) == 0); + + ok1(tdb_rescue(tdb, walk, &wd) == 0); + ok1(!wd.fail); + ok1(wd.count == 1); + + /* Corrupt the database, walk should either get it or not. */ + size = tdb->map_size; + for (i = sizeof(struct tdb_header); i < size; i++) { + char c; + if (tdb->methods->tdb_read(tdb, i, &c, 1, false) != 0) + fail("Reading offset %i", i); + if (tdb->methods->tdb_write(tdb, i, "X", 1) != 0) + fail("Writing X at offset %i", i); + + wd.count = 0; + if (tdb_rescue(tdb, count_records, &wd) != 0) { + wd.fail = true; + break; + } + /* Could be 0 or 1. */ + if (wd.count > 1) { + wd.fail = true; + break; + } + if (tdb->methods->tdb_write(tdb, i, &c, 1) != 0) + fail("Restoring offset %i", i); + } + ok1(log_count == 0); + ok1(!wd.fail); + tdb_close(tdb); + + /* Now try our known-corrupt db. */ + tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + wd.count = 0; + ok1(tdb_rescue(tdb, count_records, &wd) == 0); + ok1(wd.count == 1627); + tdb_close(tdb); + + return exit_status(); +} diff --git a/lib/tdb/wscript b/lib/tdb/wscript index f4faceb..7a3d0fa 100644 --- a/lib/tdb/wscript +++ b/lib/tdb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tdb' -VERSION = '1.2.10' +VERSION = '1.2.11' blddir = 'bin' @@ -65,7 +65,7 @@ def build(bld): COMMON_SRC = bld.SUBDIR('common', '''check.c error.c tdb.c traverse.c freelistcheck.c lock.c dump.c freelist.c - io.c open.c transaction.c hash.c summary.c''') + io.c open.c transaction.c hash.c summary.c rescue.c''') if bld.env.standalone_tdb: bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' @@ -143,6 +143,10 @@ def build(bld): 'replace tdb-test-helpers', includes='include', install=False) bld.SAMBA_BINARY('tdb1-run-readonly-check', 'test/run-readonly-check.c', 'replace tdb-test-helpers', includes='include', install=False) + bld.SAMBA_BINARY('tdb1-run-rescue', 'test/run-rescue.c', + 'replace tdb-test-helpers', includes='include', install=False) + bld.SAMBA_BINARY('tdb1-run-rescue-find_entry', 'test/run-rescue-find_entry.c', + 'replace tdb-test-helpers', includes='include', install=False) bld.SAMBA_BINARY('tdb1-run-rwlock-check', 'test/run-rwlock-check.c', 'replace tdb-test-helpers', includes='include', install=False) bld.SAMBA_BINARY('tdb1-run-summary', 'test/run-summary.c', @@ -185,7 +189,7 @@ def testonly(ctx): if not os.path.exists(link): os.symlink(os.path.abspath(os.path.join(env.cwd, 'test')), link) - for f in 'tdb1-run-3G-file', 'tdb1-run-bad-tdb-header', 'tdb1-run', 'tdb1-run-check', 'tdb1-run-corrupt', 'tdb1-run-die-during-transaction', 'tdb1-run-endian', 'tdb1-run-incompatible', 'tdb1-run-nested-transactions', 'tdb1-run-nested-traverse', 'tdb1-run-no-lock-during-traverse', 'tdb1-run-oldhash', 'tdb1-run-open-during-transaction', 'tdb1-run-readonly-check', 'tdb1-run-rwlock-check', 'tdb1-run-summary', 'tdb1-run-transaction-expand', 'tdb1-run-traverse-in-transaction', 'tdb1-run-wronghash-fail', 'tdb1-run-zero-append': + for f in 'tdb1-run-3G-file', 'tdb1-run-bad-tdb-header', 'tdb1-run', 'tdb1-run-check', 'tdb1-run-corrupt', 'tdb1-run-die-during-transaction', 'tdb1-run-endian', 'tdb1-run-incompatible', 'tdb1-run-nested-transactions', 'tdb1-run-nested-traverse', 'tdb1-run-no-lock-during-traverse', 'tdb1-run-oldhash', 'tdb1-run-open-during-transaction', 'tdb1-run-readonly-check', 'tdb1-run-rescue', 'tdb1-run-rescue-find_entry', 'tdb1-run-rwlock-check', 'tdb1-run-summary', 'tdb1-run-transaction-expand', 'tdb1-run-traverse-in-transaction', 'tdb1-run-wronghash-fail', 'tdb1-run-zero-append': cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(Utils.g_module.blddir, f)) + " > test-output 2>&1" print("..." + f) ret = samba_utils.RUN_COMMAND(cmd) -- 1.7.9.5 From 26a02fa195e0b343da39b5dc29ece35a8f9b6c8b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Oct 2012 09:04:23 +0930 Subject: [PATCH 03/20] tdb: tdbdump should log errors, and fail in that case. Dumping a corrupt database should not exit silently with 0 status! Signed-off-by: Rusty Russell (cherry picked from commit ffde8678910ae838588ab380b48a544333f81241) --- lib/tdb/tools/tdbdump.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/tdb/tools/tdbdump.c b/lib/tdb/tools/tdbdump.c index 027fda3..bb11200 100644 --- a/lib/tdb/tools/tdbdump.c +++ b/lib/tdb/tools/tdbdump.c @@ -51,19 +51,55 @@ static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *stat return 0; } +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + char *ptr = NULL; + int debuglevel = 0; + int ret; + const char *name = tdb_name(tdb); + const char *prefix = ""; + + if (!name) + name = "unnamed"; + + switch (level) { + case TDB_DEBUG_ERROR: + prefix = "ERROR: "; + break; + case TDB_DEBUG_WARNING: + prefix = "WARNING: "; + break; + case TDB_DEBUG_TRACE: + return; + + default: + case TDB_DEBUG_FATAL: + prefix = "FATAL: "; + break; + } + + va_start(ap, fmt); + fprintf(stderr, "tdb(%s): %s", name, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + static int dump_tdb(const char *fname, const char *keyname) { TDB_CONTEXT *tdb; TDB_DATA key, value; + struct tdb_logging_context logfn = { log_stderr }; - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); if (!tdb) { printf("Failed to open %s\n", fname); return 1; } if (!keyname) { - tdb_traverse(tdb, traverse_fn, NULL); + return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; } else { key.dptr = discard_const_p(uint8_t, keyname); key.dsize = strlen(keyname); -- 1.7.9.5 From dcdef9f1315560556096a5a9649011cf0b734378 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Oct 2012 09:04:23 +0930 Subject: [PATCH 04/20] tdb: add -e option to tdbdump (and docment it). This allows for an emergency best-effort dump. It's a little better than strings(1). Signed-off-by: Rusty Russell Autobuild-User(master): Rusty Russell Autobuild-Date(master): Thu Oct 4 03:16:06 CEST 2012 on sn-devel-104 (cherry picked from commit 100d38d6e0fae1dc666ae43941570c9f106b73c2) --- lib/tdb/man/tdbdump.8.xml | 31 +++++++++++++++++++++++++++++++ lib/tdb/tools/tdbdump.c | 25 ++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/tdb/man/tdbdump.8.xml b/lib/tdb/man/tdbdump.8.xml index 025da2d..25fd432 100644 --- a/lib/tdb/man/tdbdump.8.xml +++ b/lib/tdb/man/tdbdump.8.xml @@ -19,6 +19,9 @@ tdbdump + -k keyname + -e + -h filename @@ -39,6 +42,34 @@ + + OPTIONS + + + + + -h + + Get help information. + + + + + -k keyname + + The -k option restricts dumping to a single key, if found. + + + + + -e + + The -e tries to dump out from a corrupt database. Naturally, such a dump is unreliable, at best. + + + + + VERSION diff --git a/lib/tdb/tools/tdbdump.c b/lib/tdb/tools/tdbdump.c index bb11200..bcd395f 100644 --- a/lib/tdb/tools/tdbdump.c +++ b/lib/tdb/tools/tdbdump.c @@ -86,7 +86,18 @@ static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, va_end(ap); } -static int dump_tdb(const char *fname, const char *keyname) +static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) +{ + if (keyname) { + if (key.dsize != strlen(keyname)) + return; + if (memcmp(key.dptr, keyname, key.dsize) != 0) + return; + } + traverse_fn(NULL, key, dbuf, NULL); +} + +static int dump_tdb(const char *fname, const char *keyname, bool emergency) { TDB_CONTEXT *tdb; TDB_DATA key, value; @@ -98,6 +109,9 @@ static int dump_tdb(const char *fname, const char *keyname) return 1; } + if (emergency) { + return tdb_rescue(tdb, emergency_walk, keyname) == 0; + } if (!keyname) { return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; } else { @@ -120,11 +134,13 @@ static void usage( void) printf( "Usage: tdbdump [options] \n\n"); printf( " -h this help message\n"); printf( " -k keyname dumps value of keyname\n"); + printf( " -e emergency dump, for corrupt databases\n"); } int main(int argc, char *argv[]) { char *fname, *keyname=NULL; + bool emergency = false; int c; if (argc < 2) { @@ -132,7 +148,7 @@ static void usage( void) exit(1); } - while ((c = getopt( argc, argv, "hk:")) != -1) { + while ((c = getopt( argc, argv, "hk:e")) != -1) { switch (c) { case 'h': usage(); @@ -140,6 +156,9 @@ static void usage( void) case 'k': keyname = optarg; break; + case 'e': + emergency = true; + break; default: usage(); exit( 1); @@ -148,5 +167,5 @@ static void usage( void) fname = argv[optind]; - return dump_tdb(fname, keyname); + return dump_tdb(fname, keyname, emergency); } -- 1.7.9.5 From cf7b872ded84eb195021e7a579ab39676f614a7d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Oct 2012 10:21:42 +1100 Subject: [PATCH 05/20] ldb: Change ltdb_unpack_data to take an ldb_context It always de-references the module to find the ldb anyway. Andrew Bartlett (cherry picked from commit cc6d0decc7980028293168aee267e7610752fc80) --- lib/ldb/ldb_tdb/ldb_index.c | 2 +- lib/ldb/ldb_tdb/ldb_pack.c | 4 +--- lib/ldb/ldb_tdb/ldb_search.c | 6 +++--- lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- lib/ldb/ldb_tdb/ldb_tdb.h | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index d2ef4b8..50c6ded 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -1509,7 +1509,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * return -1; } - ret = ltdb_unpack_data(module, &data, msg); + ret = ltdb_unpack_data(ldb, &data, msg); if (ret != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", ldb_dn_get_linearized(msg->dn)); diff --git a/lib/ldb/ldb_tdb/ldb_pack.c b/lib/ldb/ldb_tdb/ldb_pack.c index 7c13065..003be15 100644 --- a/lib/ldb/ldb_tdb/ldb_pack.c +++ b/lib/ldb/ldb_tdb/ldb_pack.c @@ -154,18 +154,16 @@ int ltdb_pack_data(struct ldb_module *module, Free with ltdb_unpack_data_free() */ -int ltdb_unpack_data(struct ldb_module *module, +int ltdb_unpack_data(struct ldb_context *ldb, const TDB_DATA *data, struct ldb_message *message) { - struct ldb_context *ldb; uint8_t *p; unsigned int remaining; unsigned int i, j; unsigned format; size_t len; - ldb = ldb_module_get_ctx(module); message->elements = NULL; p = data->dptr; diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c index 703ad6a..4fb8510 100644 --- a/lib/ldb/ldb_tdb/ldb_search.c +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -244,9 +244,9 @@ static int ltdb_parse_data_unpack(TDB_DATA key, TDB_DATA data, { struct ltdb_parse_data_unpack_ctx *ctx = private_data; - int ret = ltdb_unpack_data(ctx->module, &data, ctx->msg); + struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); + int ret = ltdb_unpack_data(ldb, &data, ctx->msg); if (ret == -1) { - struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n", (int)key.dsize, (int)key.dsize, key.dptr); return LDB_ERR_OPERATIONS_ERROR; @@ -440,7 +440,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi } /* unpack the record */ - ret = ltdb_unpack_data(ac->module, &data, msg); + ret = ltdb_unpack_data(ldb, &data, msg); if (ret == -1) { talloc_free(msg); return -1; diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 3c18150..0e7c74c 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -693,7 +693,7 @@ int ltdb_modify_internal(struct ldb_module *module, goto done; } - ret = ltdb_unpack_data(module, &tdb_data, msg2); + ret = ltdb_unpack_data(ldb_module_get_ctx(module), &tdb_data, msg2); free(tdb_data.dptr); if (ret == -1) { ret = LDB_ERR_OTHER; diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h index c89dd7f..ea85ca1 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -99,7 +99,7 @@ int ltdb_pack_data(struct ldb_module *module, TDB_DATA *data); void ltdb_unpack_data_free(struct ldb_module *module, struct ldb_message *message); -int ltdb_unpack_data(struct ldb_module *module, +int ltdb_unpack_data(struct ldb_context *ldb, const TDB_DATA *data, struct ldb_message *message); -- 1.7.9.5 From da2ab98d3bb5c0e9db189c9f2ad1cd260a49b829 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Oct 2012 10:22:28 +1100 Subject: [PATCH 06/20] ldb: Remove no-longer-existing ltdb_unpack_data_free from ldb_tdb.h (cherry picked from commit 4b2f3c6dec997b0dd4bcafeae662a71ebd34e12b) --- lib/ldb/ldb_tdb/ldb_tdb.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h index ea85ca1..dd71626 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -97,8 +97,6 @@ int ltdb_index_transaction_cancel(struct ldb_module *module); int ltdb_pack_data(struct ldb_module *module, const struct ldb_message *message, TDB_DATA *data); -void ltdb_unpack_data_free(struct ldb_module *module, - struct ldb_message *message); int ltdb_unpack_data(struct ldb_context *ldb, const TDB_DATA *data, struct ldb_message *message); -- 1.7.9.5 From 5caa3bac79d4712a21d66ed0544868a0ffe94cd8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Oct 2012 15:41:27 +1100 Subject: [PATCH 07/20] ldb: Add ldbdump, based on tdbdump This uses a tdb_traverse or (more usefully) the tdb_rescue API, like tdbdump. The difference here is that it uses ldb helper functions to further eliminate faulty records, which avoids creating duplicates in the output. (The duplicates come from parts of records that are left in blank space in the db, which tdb_rescue finds, but which are not actually a full record). Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Tue Oct 30 23:56:11 CET 2012 on sn-devel-104 (cherry picked from commit a71ad96bd046f1199e67b4fe8fc7783cbd8dd771) --- lib/ldb/tools/ldbdump.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++ lib/ldb/wscript | 4 + 2 files changed, 223 insertions(+) create mode 100644 lib/ldb/tools/ldbdump.c diff --git a/lib/ldb/tools/ldbdump.c b/lib/ldb/tools/ldbdump.c new file mode 100644 index 0000000..7a2ba3d --- /dev/null +++ b/lib/ldb/tools/ldbdump.c @@ -0,0 +1,219 @@ +/* + Unix SMB/CIFS implementation. + simple ldb tdb dump util + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2012 + + 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 3 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, see . +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include +#include +#include "../ldb_tdb/ldb_tdb.h" + +static struct ldb_context *ldb; +bool show_index = false; +bool validate_contents = false; + +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + int ret, i, j; + struct ldb_dn *dn = state; + struct ldb_message *msg = talloc_zero(NULL, struct ldb_message); + struct ldb_ldif ldif = { + .msg = msg, + .changetype = LDB_CHANGETYPE_NONE + }; + if (!msg) { + return -1; + } + ret = ltdb_unpack_data(ldb, &dbuf, msg); + if (ret != 0) { + fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr); + TALLOC_FREE(msg); + return 0; + } + + if (dn && ldb_dn_compare(msg->dn, dn) != 0) { + TALLOC_FREE(msg); + return 0; + } + + if (!show_index && ldb_dn_is_special(msg->dn)) { + const char *dn_lin = ldb_dn_get_linearized(msg->dn); + if ((strcmp(dn_lin, LTDB_BASEINFO) == 0) || (strncmp(dn_lin, LTDB_INDEX ":", strlen( LTDB_INDEX ":")) == 0)) { + TALLOC_FREE(msg); + return 0; + } + } + + if (!validate_contents || ldb_dn_is_special(msg->dn)) { + ldb_ldif_write_file(ldb, stdout, &ldif); + TALLOC_FREE(msg); + return 0; + } + + for (i=0;inum_elements;i++) { + const struct ldb_schema_attribute *a; + + a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); + for (j=0;jelements[i].num_values;j++) { + struct ldb_val v; + ret = a->syntax->ldif_write_fn(ldb, msg, &msg->elements[i].values[j], &v); + if (ret != 0) { + v = msg->elements[i].values[j]; + if (ldb_should_b64_encode(ldb, &v)) { + v.data = (uint8_t *)ldb_base64_encode(ldb, (char *)v.data, v.length); + v.length = strlen((char *)v.data); + } + fprintf(stderr, "On %s element %s value %d (%*.*s) failed to convert to LDIF correctly, skipping possibly corrupt record\n", + ldb_dn_get_linearized(msg->dn), + msg->elements[i].name, + j, (int)v.length, (int)v.length, + v.data); + TALLOC_FREE(msg); + return 0; + } + } + } + ldb_ldif_write_file(ldb, stdout, &ldif); + TALLOC_FREE(msg); + + return 0; +} + +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + const char *prefix = ""; + + if (!name) + name = "unnamed"; + + switch (level) { + case TDB_DEBUG_ERROR: + prefix = "ERROR: "; + break; + case TDB_DEBUG_WARNING: + prefix = "WARNING: "; + break; + case TDB_DEBUG_TRACE: + return; + + default: + case TDB_DEBUG_FATAL: + prefix = "FATAL: "; + break; + } + + va_start(ap, fmt); + fprintf(stderr, "tdb(%s): %s", name, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) +{ + traverse_fn(NULL, key, dbuf, keyname); +} + +static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency) +{ + TDB_CONTEXT *tdb; + struct tdb_logging_context logfn = { log_stderr }; + + tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); + if (!tdb) { + fprintf(stderr, "Failed to open %s\n", fname); + return 1; + } + + if (emergency) { + return tdb_rescue(tdb, emergency_walk, dn) == 0; + } + return tdb_traverse(tdb, traverse_fn, dn) == -1 ? 1 : 0; +} + +static void usage( void) +{ + printf( "Usage: tdbdump [options] \n\n"); + printf( " -h this help message\n"); + printf( " -d DN dumps DN only\n"); + printf( " -e emergency dump, for corrupt databases\n"); + printf( " -i include index and @BASEINFO records in dump\n"); + printf( " -c validate contents of the records\n"); +} + + int main(int argc, char *argv[]) +{ + bool emergency = false; + int c, rc; + char *fname; + struct ldb_dn *dn = NULL; + + ldb = ldb_init(NULL, NULL); + if (ldb == NULL) { + fprintf(stderr, "ldb: ldb_init failed()"); + exit(1); + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); + exit(1); + } + + if (argc < 2) { + printf("Usage: ldbdump \n"); + exit(1); + } + + while ((c = getopt( argc, argv, "hd:ec")) != -1) { + switch (c) { + case 'h': + usage(); + exit( 0); + case 'd': + dn = ldb_dn_new(ldb, ldb, optarg); + if (!dn) { + fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); + exit(1); + } + break; + case 'e': + emergency = true; + break; + case 'i': + show_index = true; + break; + case 'c': + validate_contents = true; + break; + default: + usage(); + exit( 1); + } + } + + fname = argv[optind]; + + return dump_tdb(fname, dn, emergency); +} diff --git a/lib/ldb/wscript b/lib/ldb/wscript index 566c05e..66fa24b 100755 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -253,6 +253,10 @@ def build(bld): bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb', install=False) + # ldbdump doesn't get installed + bld.SAMBA_BINARY('ldbdump', 'tools/ldbdump.c ldb_tdb/ldb_pack.c', deps='ldb-cmdline ldb', + install=False) + bld.SAMBA_LIBRARY('ldb-cmdline', source='tools/ldbutil.c tools/cmdline.c', deps='ldb dl popt', -- 1.7.9.5 From 21a965b8a1e5b9a7b9f9466b89a561de787f5677 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 31 Oct 2012 15:39:09 +1100 Subject: [PATCH 08/20] ldb: move ldb_pack.c into common this code should not be tied to the ldb_tdb backend, both because it could be used for any record oriented backend, and because it should be exposed for use by diagnosis/repair tools such as the recently added ldbdump tool Pair-Programmed-With: Andrew Bartlett (cherry picked from commit fc47b0d03c577730ce0ef9e09092f80c0712d5d0) --- lib/ldb/common/ldb_pack.c | 290 ++++++++++++++++++++++++++++++++++++++++++++ lib/ldb/ldb_tdb/ldb_pack.c | 290 -------------------------------------------- 2 files changed, 290 insertions(+), 290 deletions(-) create mode 100644 lib/ldb/common/ldb_pack.c delete mode 100644 lib/ldb/ldb_tdb/ldb_pack.c diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c new file mode 100644 index 0000000..03e0ec1 --- /dev/null +++ b/lib/ldb/common/ldb_pack.c @@ -0,0 +1,290 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb pack/unpack + * + * Description: pack/unpack routines for ldb messages as key/value blobs + * + * Author: Andrew Tridgell + */ + +#include "ldb_tdb.h" + +/* change this if the data format ever changes */ +#define LTDB_PACKING_FORMAT 0x26011967 + +/* old packing formats */ +#define LTDB_PACKING_FORMAT_NODN 0x26011966 + +/* use a portable integer format */ +static void put_uint32(uint8_t *p, int ofs, unsigned int val) +{ + p += ofs; + p[0] = val&0xFF; + p[1] = (val>>8) & 0xFF; + p[2] = (val>>16) & 0xFF; + p[3] = (val>>24) & 0xFF; +} + +static unsigned int pull_uint32(uint8_t *p, int ofs) +{ + p += ofs; + return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); +} + +static int attribute_storable_values(const struct ldb_message_element *el) +{ + if (el->num_values == 0) return 0; + + if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; + + return el->num_values; +} + +/* + pack a ldb message into a linear buffer in a TDB_DATA + + note that this routine avoids saving elements with zero values, + as these are equivalent to having no element + + caller frees the data buffer after use +*/ +int ltdb_pack_data(struct ldb_module *module, + const struct ldb_message *message, + TDB_DATA *data) +{ + struct ldb_context *ldb; + unsigned int i, j, real_elements=0; + size_t size; + const char *dn; + uint8_t *p; + size_t len; + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_get_linearized(message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + + /* work out how big it needs to be */ + size = 8; + + size += 1 + strlen(dn); + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + real_elements++; + + size += 1 + strlen(message->elements[i].name) + 4; + for (j=0;jelements[i].num_values;j++) { + size += 4 + message->elements[i].values[j].length + 1; + } + } + + /* allocate it */ + data->dptr = talloc_array(ldb, uint8_t, size); + if (!data->dptr) { + errno = ENOMEM; + return -1; + } + data->dsize = size; + + p = data->dptr; + put_uint32(p, 0, LTDB_PACKING_FORMAT); + put_uint32(p, 4, real_elements); + p += 8; + + /* the dn needs to be packed so we can be case preserving + while hashing on a case folded dn */ + len = strlen(dn); + memcpy(p, dn, len+1); + p += len + 1; + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + len = strlen(message->elements[i].name); + memcpy(p, message->elements[i].name, len+1); + p += len + 1; + put_uint32(p, 0, message->elements[i].num_values); + p += 4; + for (j=0;jelements[i].num_values;j++) { + put_uint32(p, 0, message->elements[i].values[j].length); + memcpy(p+4, message->elements[i].values[j].data, + message->elements[i].values[j].length); + p[4+message->elements[i].values[j].length] = 0; + p += 4 + message->elements[i].values[j].length + 1; + } + } + + return 0; +} + +/* + unpack a ldb message from a linear buffer in TDB_DATA + + Free with ltdb_unpack_data_free() +*/ +int ltdb_unpack_data(struct ldb_context *ldb, + const TDB_DATA *data, + struct ldb_message *message) +{ + uint8_t *p; + unsigned int remaining; + unsigned int i, j; + unsigned format; + size_t len; + + message->elements = NULL; + + p = data->dptr; + if (data->dsize < 8) { + errno = EIO; + goto failed; + } + + format = pull_uint32(p, 0); + message->num_elements = pull_uint32(p, 4); + p += 8; + + remaining = data->dsize - 8; + + switch (format) { + case LTDB_PACKING_FORMAT_NODN: + message->dn = NULL; + break; + + case LTDB_PACKING_FORMAT: + len = strnlen((char *)p, remaining); + if (len == remaining) { + errno = EIO; + goto failed; + } + message->dn = ldb_dn_new(message, ldb, (char *)p); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + break; + + default: + errno = EIO; + goto failed; + } + + if (message->num_elements == 0) { + return 0; + } + + if (message->num_elements > remaining / 6) { + errno = EIO; + goto failed; + } + + message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); + if (!message->elements) { + errno = ENOMEM; + goto failed; + } + + memset(message->elements, 0, + message->num_elements * sizeof(struct ldb_message_element)); + + for (i=0;inum_elements;i++) { + if (remaining < 10) { + errno = EIO; + goto failed; + } + len = strnlen((char *)p, remaining-6); + if (len == remaining-6) { + errno = EIO; + goto failed; + } + if (len == 0) { + errno = EIO; + goto failed; + } + message->elements[i].flags = 0; + message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); + if (message->elements[i].name == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + message->elements[i].num_values = pull_uint32(p, 0); + message->elements[i].values = NULL; + if (message->elements[i].num_values != 0) { + message->elements[i].values = talloc_array(message->elements, + struct ldb_val, + message->elements[i].num_values); + if (!message->elements[i].values) { + errno = ENOMEM; + goto failed; + } + } + p += 4; + remaining -= 4; + for (j=0;jelements[i].num_values;j++) { + len = pull_uint32(p, 0); + if (len > remaining-5) { + errno = EIO; + goto failed; + } + + message->elements[i].values[j].length = len; + message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); + if (message->elements[i].values[j].data == NULL) { + errno = ENOMEM; + goto failed; + } + memcpy(message->elements[i].values[j].data, p+4, len); + message->elements[i].values[j].data[len] = 0; + + remaining -= len+4+1; + p += len+4+1; + } + } + + if (remaining != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: %d bytes unread in ltdb_unpack_data", remaining); + } + + return 0; + +failed: + talloc_free(message->elements); + return -1; +} diff --git a/lib/ldb/ldb_tdb/ldb_pack.c b/lib/ldb/ldb_tdb/ldb_pack.c deleted file mode 100644 index 003be15..0000000 --- a/lib/ldb/ldb_tdb/ldb_pack.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb pack/unpack - * - * Description: pack/unpack routines for ldb messages as key/value blobs - * - * Author: Andrew Tridgell - */ - -#include "ldb_tdb.h" - -/* change this if the data format ever changes */ -#define LTDB_PACKING_FORMAT 0x26011967 - -/* old packing formats */ -#define LTDB_PACKING_FORMAT_NODN 0x26011966 - -/* use a portable integer format */ -static void put_uint32(uint8_t *p, int ofs, unsigned int val) -{ - p += ofs; - p[0] = val&0xFF; - p[1] = (val>>8) & 0xFF; - p[2] = (val>>16) & 0xFF; - p[3] = (val>>24) & 0xFF; -} - -static unsigned int pull_uint32(uint8_t *p, int ofs) -{ - p += ofs; - return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); -} - -static int attribute_storable_values(const struct ldb_message_element *el) -{ - if (el->num_values == 0) return 0; - - if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; - - return el->num_values; -} - -/* - pack a ldb message into a linear buffer in a TDB_DATA - - note that this routine avoids saving elements with zero values, - as these are equivalent to having no element - - caller frees the data buffer after use -*/ -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - TDB_DATA *data) -{ - struct ldb_context *ldb; - unsigned int i, j, real_elements=0; - size_t size; - const char *dn; - uint8_t *p; - size_t len; - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_get_linearized(message->dn); - if (dn == NULL) { - errno = ENOMEM; - return -1; - } - - /* work out how big it needs to be */ - size = 8; - - size += 1 + strlen(dn); - - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - - real_elements++; - - size += 1 + strlen(message->elements[i].name) + 4; - for (j=0;jelements[i].num_values;j++) { - size += 4 + message->elements[i].values[j].length + 1; - } - } - - /* allocate it */ - data->dptr = talloc_array(ldb, uint8_t, size); - if (!data->dptr) { - errno = ENOMEM; - return -1; - } - data->dsize = size; - - p = data->dptr; - put_uint32(p, 0, LTDB_PACKING_FORMAT); - put_uint32(p, 4, real_elements); - p += 8; - - /* the dn needs to be packed so we can be case preserving - while hashing on a case folded dn */ - len = strlen(dn); - memcpy(p, dn, len+1); - p += len + 1; - - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - len = strlen(message->elements[i].name); - memcpy(p, message->elements[i].name, len+1); - p += len + 1; - put_uint32(p, 0, message->elements[i].num_values); - p += 4; - for (j=0;jelements[i].num_values;j++) { - put_uint32(p, 0, message->elements[i].values[j].length); - memcpy(p+4, message->elements[i].values[j].data, - message->elements[i].values[j].length); - p[4+message->elements[i].values[j].length] = 0; - p += 4 + message->elements[i].values[j].length + 1; - } - } - - return 0; -} - -/* - unpack a ldb message from a linear buffer in TDB_DATA - - Free with ltdb_unpack_data_free() -*/ -int ltdb_unpack_data(struct ldb_context *ldb, - const TDB_DATA *data, - struct ldb_message *message) -{ - uint8_t *p; - unsigned int remaining; - unsigned int i, j; - unsigned format; - size_t len; - - message->elements = NULL; - - p = data->dptr; - if (data->dsize < 8) { - errno = EIO; - goto failed; - } - - format = pull_uint32(p, 0); - message->num_elements = pull_uint32(p, 4); - p += 8; - - remaining = data->dsize - 8; - - switch (format) { - case LTDB_PACKING_FORMAT_NODN: - message->dn = NULL; - break; - - case LTDB_PACKING_FORMAT: - len = strnlen((char *)p, remaining); - if (len == remaining) { - errno = EIO; - goto failed; - } - message->dn = ldb_dn_new(message, ldb, (char *)p); - if (message->dn == NULL) { - errno = ENOMEM; - goto failed; - } - remaining -= len + 1; - p += len + 1; - break; - - default: - errno = EIO; - goto failed; - } - - if (message->num_elements == 0) { - return 0; - } - - if (message->num_elements > remaining / 6) { - errno = EIO; - goto failed; - } - - message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); - if (!message->elements) { - errno = ENOMEM; - goto failed; - } - - memset(message->elements, 0, - message->num_elements * sizeof(struct ldb_message_element)); - - for (i=0;inum_elements;i++) { - if (remaining < 10) { - errno = EIO; - goto failed; - } - len = strnlen((char *)p, remaining-6); - if (len == remaining-6) { - errno = EIO; - goto failed; - } - if (len == 0) { - errno = EIO; - goto failed; - } - message->elements[i].flags = 0; - message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); - if (message->elements[i].name == NULL) { - errno = ENOMEM; - goto failed; - } - remaining -= len + 1; - p += len + 1; - message->elements[i].num_values = pull_uint32(p, 0); - message->elements[i].values = NULL; - if (message->elements[i].num_values != 0) { - message->elements[i].values = talloc_array(message->elements, - struct ldb_val, - message->elements[i].num_values); - if (!message->elements[i].values) { - errno = ENOMEM; - goto failed; - } - } - p += 4; - remaining -= 4; - for (j=0;jelements[i].num_values;j++) { - len = pull_uint32(p, 0); - if (len > remaining-5) { - errno = EIO; - goto failed; - } - - message->elements[i].values[j].length = len; - message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); - if (message->elements[i].values[j].data == NULL) { - errno = ENOMEM; - goto failed; - } - memcpy(message->elements[i].values[j].data, p+4, len); - message->elements[i].values[j].data[len] = 0; - - remaining -= len+4+1; - p += len+4+1; - } - } - - if (remaining != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %d bytes unread in ltdb_unpack_data", remaining); - } - - return 0; - -failed: - talloc_free(message->elements); - return -1; -} -- 1.7.9.5 From 4b4f372457f45bbdd84312596101d3182bbbf86d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 31 Oct 2012 16:06:03 +1100 Subject: [PATCH 09/20] ldb: fixed callers for ldb_pack_data() and ldb_unpack_data() with ltdb_pack_data() and ltdb_unpack_data() now moved into common, we need to increase the minor version and fixup callers of the API Note that this relies on struct ldb_val being the same shape as TDB_DATA, in much the same way as we rely on ldb_val and DATA_BLOB being the same shape. Pair-Programmed-With: Andrew Bartlett (cherry picked from commit 30ffdda45bd3ae602b453c9c1bbdb77ea3de8a8d) --- lib/ldb/ABI/ldb-1.1.14.sigs | 262 ++++++++++++++++++++++++++++++++++++ lib/ldb/ABI/pyldb-util-1.1.14.sigs | 2 + lib/ldb/common/ldb_pack.c | 49 ++++--- lib/ldb/include/ldb_private.h | 11 ++ lib/ldb/ldb_tdb/ldb_index.c | 3 +- lib/ldb/ldb_tdb/ldb_search.c | 5 +- lib/ldb/ldb_tdb/ldb_tdb.c | 5 +- lib/ldb/ldb_tdb/ldb_tdb.h | 9 -- lib/ldb/tools/ldbdump.c | 15 ++- lib/ldb/wscript | 8 +- 10 files changed, 321 insertions(+), 48 deletions(-) create mode 100644 lib/ldb/ABI/ldb-1.1.14.sigs create mode 100644 lib/ldb/ABI/pyldb-util-1.1.14.sigs diff --git a/lib/ldb/ABI/ldb-1.1.14.sigs b/lib/ldb/ABI/ldb-1.1.14.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/lib/ldb/ABI/ldb-1.1.14.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/pyldb-util-1.1.14.sigs b/lib/ldb/ABI/pyldb-util-1.1.14.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util-1.1.14.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c index 03e0ec1..4382d5b 100644 --- a/lib/ldb/common/ldb_pack.c +++ b/lib/ldb/common/ldb_pack.c @@ -31,13 +31,13 @@ * Author: Andrew Tridgell */ -#include "ldb_tdb.h" +#include "ldb_private.h" /* change this if the data format ever changes */ -#define LTDB_PACKING_FORMAT 0x26011967 +#define LDB_PACKING_FORMAT 0x26011967 /* old packing formats */ -#define LTDB_PACKING_FORMAT_NODN 0x26011966 +#define LDB_PACKING_FORMAT_NODN 0x26011966 /* use a portable integer format */ static void put_uint32(uint8_t *p, int ofs, unsigned int val) @@ -65,26 +65,23 @@ static int attribute_storable_values(const struct ldb_message_element *el) } /* - pack a ldb message into a linear buffer in a TDB_DATA + pack a ldb message into a linear buffer in a ldb_val note that this routine avoids saving elements with zero values, as these are equivalent to having no element caller frees the data buffer after use */ -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - TDB_DATA *data) +int ldb_pack_data(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data) { - struct ldb_context *ldb; unsigned int i, j, real_elements=0; size_t size; const char *dn; uint8_t *p; size_t len; - ldb = ldb_module_get_ctx(module); - dn = ldb_dn_get_linearized(message->dn); if (dn == NULL) { errno = ENOMEM; @@ -110,15 +107,15 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = talloc_array(ldb, uint8_t, size); - if (!data->dptr) { + data->data = talloc_array(ldb, uint8_t, size); + if (!data->data) { errno = ENOMEM; return -1; } - data->dsize = size; + data->length = size; - p = data->dptr; - put_uint32(p, 0, LTDB_PACKING_FORMAT); + p = data->data; + put_uint32(p, 0, LDB_PACKING_FORMAT); put_uint32(p, 4, real_elements); p += 8; @@ -150,13 +147,13 @@ int ltdb_pack_data(struct ldb_module *module, } /* - unpack a ldb message from a linear buffer in TDB_DATA + unpack a ldb message from a linear buffer in ldb_val - Free with ltdb_unpack_data_free() + Free with ldb_unpack_data_free() */ -int ltdb_unpack_data(struct ldb_context *ldb, - const TDB_DATA *data, - struct ldb_message *message) +int ldb_unpack_data(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message) { uint8_t *p; unsigned int remaining; @@ -166,8 +163,8 @@ int ltdb_unpack_data(struct ldb_context *ldb, message->elements = NULL; - p = data->dptr; - if (data->dsize < 8) { + p = data->data; + if (data->length < 8) { errno = EIO; goto failed; } @@ -176,14 +173,14 @@ int ltdb_unpack_data(struct ldb_context *ldb, message->num_elements = pull_uint32(p, 4); p += 8; - remaining = data->dsize - 8; + remaining = data->length - 8; switch (format) { - case LTDB_PACKING_FORMAT_NODN: + case LDB_PACKING_FORMAT_NODN: message->dn = NULL; break; - case LTDB_PACKING_FORMAT: + case LDB_PACKING_FORMAT: len = strnlen((char *)p, remaining); if (len == remaining) { errno = EIO; @@ -279,7 +276,7 @@ int ltdb_unpack_data(struct ldb_context *ldb, if (remaining != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %d bytes unread in ltdb_unpack_data", remaining); + "Error: %d bytes unread in ldb_unpack_data", remaining); } return 0; diff --git a/lib/ldb/include/ldb_private.h b/lib/ldb/include/ldb_private.h index 7de5ab7..526bf5e 100644 --- a/lib/ldb/include/ldb_private.h +++ b/lib/ldb/include/ldb_private.h @@ -194,4 +194,15 @@ struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif); +/* + * these pack/unpack functions are exposed in the library for use by + * ldb tools like ldbdump, but are not part of the public API + */ +int ldb_pack_data(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data); +int ldb_unpack_data(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message); + #endif diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 50c6ded..d79417f 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "ldb_private.h" struct dn_list { unsigned int count; @@ -1509,7 +1510,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * return -1; } - ret = ltdb_unpack_data(ldb, &data, msg); + ret = ldb_unpack_data(ldb, (struct ldb_val *)&data, msg); if (ret != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", ldb_dn_get_linearized(msg->dn)); diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c index 4fb8510..26296c7 100644 --- a/lib/ldb/ldb_tdb/ldb_search.c +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "ldb_private.h" #include /* @@ -245,7 +246,7 @@ static int ltdb_parse_data_unpack(TDB_DATA key, TDB_DATA data, struct ltdb_parse_data_unpack_ctx *ctx = private_data; struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); - int ret = ltdb_unpack_data(ldb, &data, ctx->msg); + int ret = ldb_unpack_data(ldb, (struct ldb_val *)&data, ctx->msg); if (ret == -1) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n", (int)key.dsize, (int)key.dsize, key.dptr); @@ -440,7 +441,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi } /* unpack the record */ - ret = ltdb_unpack_data(ldb, &data, msg); + ret = ldb_unpack_data(ldb, (struct ldb_val *)&data, msg); if (ret == -1) { talloc_free(msg); return -1; diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 0e7c74c..860ee14 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -50,6 +50,7 @@ */ #include "ldb_tdb.h" +#include "ldb_private.h" #include /* @@ -264,7 +265,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg return LDB_ERR_OTHER; } - ret = ltdb_pack_data(module, msg, &tdb_data); + ret = ldb_pack_data(module, msg, (struct ldb_val *)&tdb_data); if (ret == -1) { talloc_free(tdb_key.dptr); return LDB_ERR_OTHER; @@ -693,7 +694,7 @@ int ltdb_modify_internal(struct ldb_module *module, goto done; } - ret = ltdb_unpack_data(ldb_module_get_ctx(module), &tdb_data, msg2); + ret = ldb_unpack_data(ldb_module_get_ctx(module), (struct ldb_val *)&tdb_data, msg2); free(tdb_data.dptr); if (ret == -1) { ret = LDB_ERR_OTHER; diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h index dd71626..b9aa36c 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -92,15 +92,6 @@ int ltdb_index_transaction_start(struct ldb_module *module); int ltdb_index_transaction_commit(struct ldb_module *module); int ltdb_index_transaction_cancel(struct ldb_module *module); -/* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */ - -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - TDB_DATA *data); -int ltdb_unpack_data(struct ldb_context *ldb, - const TDB_DATA *data, - struct ldb_message *message); - /* The following definitions come from lib/ldb/ldb_tdb/ldb_search.c */ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, diff --git a/lib/ldb/tools/ldbdump.c b/lib/ldb/tools/ldbdump.c index 7a2ba3d..edf7b5e 100644 --- a/lib/ldb/tools/ldbdump.c +++ b/lib/ldb/tools/ldbdump.c @@ -25,7 +25,7 @@ #include "system/wait.h" #include #include -#include "../ldb_tdb/ldb_tdb.h" +#include static struct ldb_context *ldb; bool show_index = false; @@ -43,7 +43,8 @@ static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *stat if (!msg) { return -1; } - ret = ltdb_unpack_data(ldb, &dbuf, msg); + + ret = ldb_unpack_data(ldb, &dbuf, msg); if (ret != 0) { fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr); TALLOC_FREE(msg); @@ -57,7 +58,13 @@ static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *stat if (!show_index && ldb_dn_is_special(msg->dn)) { const char *dn_lin = ldb_dn_get_linearized(msg->dn); - if ((strcmp(dn_lin, LTDB_BASEINFO) == 0) || (strncmp(dn_lin, LTDB_INDEX ":", strlen( LTDB_INDEX ":")) == 0)) { + if ((strcmp(dn_lin, "@BASEINFO") == 0) || (strncmp(dn_lin, "@INDEX:", strlen("@INDEX:")) == 0)) { + /* + the user has asked not to show index + records. Also exclude BASEINFO as it + contains meta-data which will be re-created + if this database is restored + */ TALLOC_FREE(msg); return 0; } @@ -154,7 +161,7 @@ static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency) static void usage( void) { - printf( "Usage: tdbdump [options] \n\n"); + printf( "Usage: ldbdump [options] \n\n"); printf( " -h this help message\n"); printf( " -d DN dumps DN only\n"); printf( " -e emergency dump, for corrupt databases\n"); diff --git a/lib/ldb/wscript b/lib/ldb/wscript index 66fa24b..8a36b5d 100755 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.1.13' +VERSION = '1.1.14' blddir = 'bin' @@ -89,7 +89,7 @@ def build(bld): COMMON_SRC = bld.SUBDIR('common', '''ldb_modules.c ldb_ldif.c ldb_parse.c ldb_msg.c ldb_utf8.c - ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c + ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c ldb_pack.c ldb_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', @@ -228,7 +228,7 @@ def build(bld): bld.SAMBA_MODULE('ldb_tdb', bld.SUBDIR('ldb_tdb', - '''ldb_tdb.c ldb_pack.c ldb_search.c ldb_index.c + '''ldb_tdb.c ldb_search.c ldb_index.c ldb_cache.c ldb_tdb_wrap.c'''), init_function='ldb_tdb_init', module_init_name='ldb_init_module', @@ -254,7 +254,7 @@ def build(bld): install=False) # ldbdump doesn't get installed - bld.SAMBA_BINARY('ldbdump', 'tools/ldbdump.c ldb_tdb/ldb_pack.c', deps='ldb-cmdline ldb', + bld.SAMBA_BINARY('ldbdump', 'tools/ldbdump.c', deps='ldb-cmdline ldb', install=False) bld.SAMBA_LIBRARY('ldb-cmdline', -- 1.7.9.5 From b41069133852e56cd44be4343b2b46878a365622 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 28 Nov 2012 21:55:47 +0100 Subject: [PATCH 10/20] ldb: fix a typo in the comment for ldb_req_is_untrusted() Signed-off-by: Michael Adam Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Fri Nov 30 15:44:46 CET 2012 on sn-devel-104 (cherry picked from commit 8f3f38ece4981d0047024019c6fc8dfde3fffed0) --- lib/ldb/common/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ldb/common/ldb.c b/lib/ldb/common/ldb.c index 49eccb9..7a997f7 100644 --- a/lib/ldb/common/ldb.c +++ b/lib/ldb/common/ldb.c @@ -1980,7 +1980,7 @@ uint32_t ldb_req_get_custom_flags(struct ldb_request *req) /** - return true is a request is untrusted + * return true if a request is untrusted */ bool ldb_req_is_untrusted(struct ldb_request *req) { -- 1.7.9.5 From 47b1637934ecb589766c3d6f79d66cd8fbf55c25 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Wed, 2 Jan 2013 11:22:16 -0500 Subject: [PATCH 11/20] ldb: Move doxygen comments for ldb_connect to the right place Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Mon Jan 14 16:21:02 CET 2013 on sn-devel-104 (cherry picked from commit 813bd0353fda0eb6d7c78392d5abd3002115da96) --- lib/ldb/include/ldb.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h index b60fc9b..748def9 100644 --- a/lib/ldb/include/ldb.h +++ b/lib/ldb/include/ldb.h @@ -1033,6 +1033,18 @@ int ldb_global_init(void); */ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); +typedef void (*ldb_async_timeout_fn) (void *); +typedef bool (*ldb_async_callback_fn) (void *); +typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn); +typedef int (*ldb_async_ctx_wait_op_fn)(void *); + +void ldb_async_ctx_set_private_data(struct ldb_context *ldb, + void *private_data); +void ldb_async_ctx_set_add_op(struct ldb_context *ldb, + ldb_async_ctx_add_op_fn add_op); +void ldb_async_ctx_set_wait_op(struct ldb_context *ldb, + ldb_async_ctx_wait_op_fn wait_op); + /** Connect to a database. @@ -1056,19 +1068,6 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) (that is, with LDB_FLG_RDONLY). However in read-write mode, the database will be created if it does not exist. */ - -typedef void (*ldb_async_timeout_fn) (void *); -typedef bool (*ldb_async_callback_fn) (void *); -typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn); -typedef int (*ldb_async_ctx_wait_op_fn)(void *); - -void ldb_async_ctx_set_private_data(struct ldb_context *ldb, - void *private_data); -void ldb_async_ctx_set_add_op(struct ldb_context *ldb, - ldb_async_ctx_add_op_fn add_op); -void ldb_async_ctx_set_wait_op(struct ldb_context *ldb, - ldb_async_ctx_wait_op_fn wait_op); - int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]); /* -- 1.7.9.5 From 505e1496b30723eef1c5bf06ef70bd715459db7a Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:50:00 +0100 Subject: [PATCH 12/20] docs: ldb.3.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher (cherry picked from commit 7d56b9401129c18a948bbd0bb4fea547d4b3a7c4) --- lib/ldb/man/ldb.3.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ldb/man/ldb.3.xml b/lib/ldb/man/ldb.3.xml index 37c4e80..b93d532 100644 --- a/lib/ldb/man/ldb.3.xml +++ b/lib/ldb/man/ldb.3.xml @@ -5,9 +5,9 @@ ldb 3 - Samba + LDB System Administration tools - 4.0 + 1.1 -- 1.7.9.5 From eb7d20e0d3dd4df1f6a5f1da3ac2a8807d127f47 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:50:26 +0100 Subject: [PATCH 13/20] docs: ldbadd.1.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher (cherry picked from commit 1d4346d4b7c7afc4f578afb3b8d0e08e36812b39) --- lib/ldb/man/ldbadd.1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ldb/man/ldbadd.1.xml b/lib/ldb/man/ldbadd.1.xml index 19d2171..3a3ed2c 100644 --- a/lib/ldb/man/ldbadd.1.xml +++ b/lib/ldb/man/ldbadd.1.xml @@ -5,9 +5,9 @@ ldbadd 1 - Samba + LDB System Administration tools - 4.0 + 1.1 @@ -78,7 +78,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. -- 1.7.9.5 From 2e0d0f4c0bf327ac524f6d5b7a61979ffc507064 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:50:55 +0100 Subject: [PATCH 14/20] docs: ldbdel.1.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher (cherry picked from commit 918057bd11e9ed1457cf0119f4c0c1f9c418c566) --- lib/ldb/man/ldbdel.1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ldb/man/ldbdel.1.xml b/lib/ldb/man/ldbdel.1.xml index e136955..d57cf2a 100644 --- a/lib/ldb/man/ldbdel.1.xml +++ b/lib/ldb/man/ldbdel.1.xml @@ -5,9 +5,9 @@ ldbdel 1 - Samba + LDB System Administration tools - 4.0 + 1.1 @@ -76,7 +76,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. -- 1.7.9.5 From f2b95d02f4bf184f6bbce377ad9bb5e1fabfce5f Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:51:28 +0100 Subject: [PATCH 15/20] docs: ldbedit.1.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher (cherry picked from commit f585052d888a3bb4f9c81d9a9512eca7f7867c98) --- lib/ldb/man/ldbedit.1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ldb/man/ldbedit.1.xml b/lib/ldb/man/ldbedit.1.xml index 334a1a1..fd98c60 100644 --- a/lib/ldb/man/ldbedit.1.xml +++ b/lib/ldb/man/ldbedit.1.xml @@ -5,9 +5,9 @@ ldbedit 1 - Samba + LDB System Administration tools - 4.0 + 1.1 @@ -169,7 +169,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. -- 1.7.9.5 From 53e0e32331122a5cb6ef229b01ad73961b23ff61 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:51:49 +0100 Subject: [PATCH 16/20] docs: ldbmodify.1.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher (cherry picked from commit 25cc400c64958e2e2e2e812a0d34064f1957d0c4) --- lib/ldb/man/ldbmodify.1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ldb/man/ldbmodify.1.xml b/lib/ldb/man/ldbmodify.1.xml index f7632b3..5d6b468 100644 --- a/lib/ldb/man/ldbmodify.1.xml +++ b/lib/ldb/man/ldbmodify.1.xml @@ -5,9 +5,9 @@ ldbmodify 1 - Samba + LDB System Administration tools - 4.0 + 1.1 @@ -66,7 +66,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. -- 1.7.9.5 From 3eea1dfdcb9ca6eb4d409fcc261b926826a8f4d0 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:52:15 +0100 Subject: [PATCH 17/20] docs: ldbrename.1.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher (cherry picked from commit 99e2a63a0c64de4c3c26e66984a6c542052e97ba) --- lib/ldb/man/ldbrename.1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ldb/man/ldbrename.1.xml b/lib/ldb/man/ldbrename.1.xml index e0436ab..1fa13e6 100644 --- a/lib/ldb/man/ldbrename.1.xml +++ b/lib/ldb/man/ldbrename.1.xml @@ -5,9 +5,9 @@ ldbrename 1 - Samba + LDB System Administration tools - 4.0 + 1.1 @@ -80,7 +80,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. -- 1.7.9.5 From 7f9d67e417d4cb28b9fdfb0831592eef15296306 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 24 Jan 2013 11:52:37 +0100 Subject: [PATCH 18/20] docs: ldbsearch.1.xml: Correct meta data. Signed-off-by: Karolin Seeger Karolin Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Thu Jan 24 16:09:37 CET 2013 on sn-devel-104 (cherry picked from commit 875a1721ae014cbb580d9596344675e890cf9964) --- lib/ldb/man/ldbsearch.1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ldb/man/ldbsearch.1.xml b/lib/ldb/man/ldbsearch.1.xml index 4946cb2..e693a290 100644 --- a/lib/ldb/man/ldbsearch.1.xml +++ b/lib/ldb/man/ldbsearch.1.xml @@ -5,9 +5,9 @@ ldbsearch 1 - Samba + LDB System Administration tools - 4.0 + 1.1 @@ -92,7 +92,7 @@ VERSION - This man page is correct for version 4.0 of the Samba suite. + This man page is correct for version 1.1 of LDB. -- 1.7.9.5 From 78ebe2adb9a5731e61c71cd0a40241cce820b2eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jan 2013 14:21:51 +0100 Subject: [PATCH 19/20] ldb: fix a warning by converting from TDB_DATA to struct ldb_val Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 1ea6fabcde6cbd57aed06926193ac68f5887e96b) --- lib/ldb/tools/ldbdump.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/ldb/tools/ldbdump.c b/lib/ldb/tools/ldbdump.c index edf7b5e..3197d19 100644 --- a/lib/ldb/tools/ldbdump.c +++ b/lib/ldb/tools/ldbdump.c @@ -31,11 +31,15 @@ static struct ldb_context *ldb; bool show_index = false; bool validate_contents = false; -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state) { int ret, i, j; struct ldb_dn *dn = state; struct ldb_message *msg = talloc_zero(NULL, struct ldb_message); + struct ldb_val dbuf = { + .data = _dbuf.dptr, + .length = _dbuf.dsize, + }; struct ldb_ldif ldif = { .msg = msg, .changetype = LDB_CHANGETYPE_NONE -- 1.7.9.5 From e53806414ac6ebaa7204b1b498465afc50b3b6b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Jan 2013 09:35:21 +1100 Subject: [PATCH 20/20] ldb: Ensure to decrement the transaction_active whenever we delete a transaction This is in the error path for prepare_commit, which rarely fails, but when it does we need to ensure that when a new transaction is opened, that it really starts a new transaction. We bump the version to recognise critical fix for the AD DC Without this fix, a single invalid inbound replicated link disables all subsequent replication as we operate without a transaction (which is refused by ldb_tdb). Andrew Bartlett Reviewed-by: Matthieu Patou Reviewed-by: Stefan Metzmacher (cherry picked from commit 1d1ea72574cfa22ee6207d0e9787d0271db3b5c2) --- lib/ldb/ABI/ldb-1.1.15.sigs | 262 ++++++++++++++++++++++++++++++++++++ lib/ldb/ABI/pyldb-util-1.1.15.sigs | 2 + lib/ldb/common/ldb.c | 1 + lib/ldb/wscript | 2 +- 4 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 lib/ldb/ABI/ldb-1.1.15.sigs create mode 100644 lib/ldb/ABI/pyldb-util-1.1.15.sigs diff --git a/lib/ldb/ABI/ldb-1.1.15.sigs b/lib/ldb/ABI/ldb-1.1.15.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/lib/ldb/ABI/ldb-1.1.15.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/pyldb-util-1.1.15.sigs b/lib/ldb/ABI/pyldb-util-1.1.15.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util-1.1.15.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/lib/ldb/common/ldb.c b/lib/ldb/common/ldb.c index 7a997f7..3dc6d87 100644 --- a/lib/ldb/common/ldb.c +++ b/lib/ldb/common/ldb.c @@ -408,6 +408,7 @@ int ldb_transaction_prepare_commit(struct ldb_context *ldb) status = module->ops->prepare_commit(module); if (status != LDB_SUCCESS) { + ldb->transaction_active--; /* if a module fails the prepare then we need to call the end transaction for everyone */ FIRST_OP(ldb, del_transaction); diff --git a/lib/ldb/wscript b/lib/ldb/wscript index 8a36b5d..1ae5438 100755 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.1.14' +VERSION = '1.1.15' blddir = 'bin' -- 1.7.9.5