#include "lib/tdb_wrap/tdb_wrap.h"
#include "lib/util/util_tdb.h"
#include "system/filesys.h"
+#include "lib/param/param.h"
+#include "libcli/util/error.h"
struct db_tdb_ctx {
struct tdb_wrap *wtdb;
} id;
};
-static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag);
+static NTSTATUS db_tdb_storev(struct db_record *rec,
+ const TDB_DATA *dbufs, int num_dbufs, int flag);
static NTSTATUS db_tdb_delete(struct db_record *rec);
static void db_tdb_log_key(const char *prefix, TDB_DATA key)
{
size_t len;
char *keystr;
-
+ TALLOC_CTX *frame;
if (DEBUGLEVEL < 10) {
return;
}
+ frame = talloc_stackframe();
len = key.dsize;
if (DEBUGLEVEL == 10) {
/*
*/
len = MIN(10, key.dsize);
}
- keystr = hex_encode_talloc(talloc_tos(), (unsigned char *)(key.dptr),
+ keystr = hex_encode_talloc(frame, (unsigned char *)(key.dptr),
len);
DEBUG(10, ("%s key %s\n", prefix, keystr));
- TALLOC_FREE(keystr);
+ TALLOC_FREE(frame);
}
static int db_tdb_record_destr(struct db_record* data)
talloc_set_destructor(state.result, db_tdb_record_destr);
- state.result->private_data = talloc_reference(state.result, ctx);
- state.result->store = db_tdb_store;
+ state.result->private_data = ctx;
+ state.result->storev = db_tdb_storev;
state.result->delete_rec = db_tdb_delete;
DEBUG(10, ("Allocated locked data 0x%p\n", state.result));
return db_tdb_fetch_locked_internal(db, mem_ctx, key);
}
+static NTSTATUS db_tdb_do_locked(struct db_context *db, TDB_DATA key,
+ void (*fn)(struct db_record *rec,
+ void *private_data),
+ void *private_data)
+{
+ struct db_tdb_ctx *ctx = talloc_get_type_abort(
+ db->private_data, struct db_tdb_ctx);
+ uint8_t *buf = NULL;
+ struct db_record rec;
+ int ret;
+
+ ret = tdb_chainlock(ctx->wtdb->tdb, key);
+ if (ret == -1) {
+ enum TDB_ERROR err = tdb_error(ctx->wtdb->tdb);
+ DBG_DEBUG("tdb_chainlock failed: %s\n",
+ tdb_errorstr(ctx->wtdb->tdb));
+ return map_nt_error_from_tdb(err);
+ }
+
+ ret = tdb_fetch_talloc(ctx->wtdb->tdb, key, ctx, &buf);
+
+ if ((ret != 0) && (ret != ENOENT)) {
+ DBG_DEBUG("tdb_fetch_talloc failed: %s\n",
+ strerror(errno));
+ tdb_chainunlock(ctx->wtdb->tdb, key);
+ return map_nt_error_from_unix_common(ret);
+ }
+
+ rec = (struct db_record) {
+ .db = db, .key = key,
+ .value = (struct TDB_DATA) { .dptr = buf,
+ .dsize = talloc_get_size(buf) },
+ .storev = db_tdb_storev, .delete_rec = db_tdb_delete,
+ .private_data = ctx
+ };
+
+ fn(&rec, private_data);
+
+ talloc_free(buf);
+
+ tdb_chainunlock(ctx->wtdb->tdb, key);
+
+ return NT_STATUS_OK;
+}
static int db_tdb_exists(struct db_context *db, TDB_DATA key)
{
return tdb_wipe_all(ctx->wtdb->tdb);
}
+static int db_tdb_check(struct db_context *db)
+{
+ struct db_tdb_ctx *ctx = talloc_get_type_abort(
+ db->private_data, struct db_tdb_ctx);
+ return tdb_check(ctx->wtdb->tdb, NULL, NULL);
+}
+
struct db_tdb_parse_state {
void (*parser)(TDB_DATA key, TDB_DATA data,
void *private_data);
return NT_STATUS_OK;
}
-static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
+static NTSTATUS db_tdb_storev(struct db_record *rec,
+ const TDB_DATA *dbufs, int num_dbufs, int flag)
{
struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
struct db_tdb_ctx);
+ int ret;
/*
* This has a bug: We need to replace rec->value for correct
* anymore after it was stored.
*/
- return (tdb_store(ctx->wtdb->tdb, rec->key, data, flag) == 0) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ ret = tdb_storev(ctx->wtdb->tdb, rec->key, dbufs, num_dbufs, flag);
+ return (ret == 0) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
static NTSTATUS db_tdb_delete(struct db_record *rec)
rec.key = kbuf;
rec.value = dbuf;
- rec.store = db_tdb_store;
+ rec.storev = db_tdb_storev;
rec.delete_rec = db_tdb_delete;
rec.private_data = ctx->db->private_data;
rec.db = ctx->db;
return tdb_traverse(db_ctx->wtdb->tdb, db_tdb_traverse_func, &ctx);
}
-static NTSTATUS db_tdb_store_deny(struct db_record *rec, TDB_DATA data, int flag)
+static NTSTATUS db_tdb_storev_deny(struct db_record *rec,
+ const TDB_DATA *dbufs, int num_dbufs,
+ int flag)
{
return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
rec.key = kbuf;
rec.value = dbuf;
- rec.store = db_tdb_store_deny;
+ rec.storev = db_tdb_storev_deny;
rec.delete_rec = db_tdb_delete_deny;
rec.private_data = ctx->db->private_data;
rec.db = ctx->db;
return tdb_transaction_start(db_ctx->wtdb->tdb) ? -1 : 0;
}
+static NTSTATUS db_tdb_transaction_start_nonblock(struct db_context *db)
+{
+ struct db_tdb_ctx *db_ctx =
+ talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+ int ret;
+
+ ret = tdb_transaction_start_nonblock(db_ctx->wtdb->tdb);
+ if (ret != 0) {
+ return map_nt_error_from_tdb(tdb_error(db_ctx->wtdb->tdb));
+ }
+ return NT_STATUS_OK;
+}
+
static int db_tdb_transaction_commit(struct db_context *db)
{
struct db_tdb_ctx *db_ctx =
return 0;
}
-static void db_tdb_id(struct db_context *db, const uint8_t **id, size_t *idlen)
+static size_t db_tdb_id(struct db_context *db, uint8_t *id, size_t idlen)
{
struct db_tdb_ctx *db_ctx =
talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
- *id = (uint8_t *)&db_ctx->id;
- *idlen = sizeof(db_ctx->id);
+
+ if (idlen >= sizeof(db_ctx->id)) {
+ memcpy(id, &db_ctx->id, sizeof(db_ctx->id));
+ }
+
+ return sizeof(db_ctx->id);
}
struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
- struct loadparm_context *lp_ctx,
const char *name,
int hash_size, int tdb_flags,
int open_flags, mode_t mode,
- enum dbwrap_lock_order lock_order)
+ enum dbwrap_lock_order lock_order,
+ uint64_t dbwrap_flags)
{
struct db_context *result = NULL;
struct db_tdb_ctx *db_tdb;
result->lock_order = lock_order;
db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, tdb_flags,
- open_flags, mode, lp_ctx);
+ open_flags, mode);
if (db_tdb->wtdb == NULL) {
DEBUG(3, ("Could not open tdb: %s\n", strerror(errno)));
goto fail;
result->fetch_locked = db_tdb_fetch_locked;
result->try_fetch_locked = db_tdb_try_fetch_locked;
+ result->do_locked = db_tdb_do_locked;
result->traverse = db_tdb_traverse;
result->traverse_read = db_tdb_traverse_read;
result->parse_record = db_tdb_parse;
result->get_seqnum = db_tdb_get_seqnum;
result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
result->transaction_start = db_tdb_transaction_start;
+ result->transaction_start_nonblock = db_tdb_transaction_start_nonblock;
result->transaction_commit = db_tdb_transaction_commit;
result->transaction_cancel = db_tdb_transaction_cancel;
result->exists = db_tdb_exists;
result->wipe = db_tdb_wipe;
result->id = db_tdb_id;
- result->stored_callback = NULL;
+ result->check = db_tdb_check;
+ result->name = tdb_name(db_tdb->wtdb->tdb);
return result;
fail:
- if (result != NULL) {
- TALLOC_FREE(result);
- }
+ TALLOC_FREE(result);
return NULL;
}