diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/dbwrap_tdb.c | 88 |
1 files changed, 53 insertions, 35 deletions
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index b24fd0618a..cce987d789 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -43,33 +43,50 @@ static int db_tdb_record_destr(struct db_record* data) return 0; } -static struct db_record *db_tdb_fetch_locked(struct db_context *db, - TALLOC_CTX *mem_ctx, TDB_DATA key) -{ - struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_tdb_ctx); +struct tdb_fetch_locked_state { + TALLOC_CTX *mem_ctx; struct db_record *result; - TDB_DATA value; +}; - result = TALLOC_P(mem_ctx, struct db_record); - if (result == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; +static int db_tdb_fetchlock_parse(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct tdb_fetch_locked_state *state = + (struct tdb_fetch_locked_state *)private_data; + + state->result = (struct db_record *)talloc_size( + state->mem_ctx, + sizeof(struct db_record) + key.dsize + data.dsize); + + if (state->result == NULL) { + return 0; } - result->key.dsize = key.dsize; - result->key.dptr = (uint8 *)talloc_memdup(result, key.dptr, key.dsize); - if (result->key.dptr == NULL) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; + state->result->key.dsize = key.dsize; + state->result->key.dptr = ((uint8 *)state->result) + + sizeof(struct db_record); + memcpy(state->result->key.dptr, key.dptr, key.dsize); + + state->result->value.dsize = data.dsize; + + if (data.dsize > 0) { + state->result->value.dptr = state->result->key.dptr + key.dsize; + memcpy(state->result->value.dptr, data.dptr, data.dsize); } + else { + state->result->value.dptr = NULL; + } + + return 0; +} - result->value.dptr = NULL; - result->value.dsize = 0; - result->private_data = talloc_reference(result, ctx); - result->store = db_tdb_store; - result->delete_rec = db_tdb_delete; +static struct db_record *db_tdb_fetch_locked(struct db_context *db, + TALLOC_CTX *mem_ctx, TDB_DATA key) +{ + struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, + struct db_tdb_ctx); + struct tdb_fetch_locked_state state; + int res; if (DEBUGLEVEL >= 10) { char *keystr = hex_encode(NULL, key.dptr, key.dsize); @@ -81,32 +98,33 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) { DEBUG(3, ("tdb_chainlock failed\n")); - TALLOC_FREE(result); return NULL; } - talloc_set_destructor(result, db_tdb_record_destr); + state.mem_ctx = mem_ctx; + state.result = NULL; - value = tdb_fetch(ctx->wtdb->tdb, key); + res = tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, + &state); - if (value.dptr == NULL) { - return result; + if (state.result == NULL) { + db_tdb_fetchlock_parse(key, tdb_null, &state); } - result->value.dsize = value.dsize; - result->value.dptr = (uint8 *)talloc_memdup(result, value.dptr, - value.dsize); - if (result->value.dptr == NULL) { - DEBUG(3, ("talloc failed\n")); - TALLOC_FREE(result); + if (state.result == NULL) { + tdb_chainunlock(ctx->wtdb->tdb, key); return NULL; } - SAFE_FREE(value.dptr); + talloc_set_destructor(state.result, db_tdb_record_destr); - DEBUG(10, ("Allocated locked data 0x%p\n", result)); + state.result->private_data = talloc_reference(state.result, ctx); + state.result->store = db_tdb_store; + state.result->delete_rec = db_tdb_delete; - return result; + DEBUG(10, ("Allocated locked data 0x%p\n", state.result)); + + return state.result; } static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, |