s3:rpc_client: use rpc_api_pipe_send() for auth3
[Samba/gebeck_regimport.git] / source3 / lib / dbwrap_tdb.c
blob4cdc1930eed2dcea2eb0598a6b687aa64540a3fb
1 /*
2 Unix SMB/CIFS implementation.
3 Database interface wrapper around tdb
4 Copyright (C) Volker Lendecke 2005-2007
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "dbwrap.h"
23 struct db_tdb_ctx {
24 struct tdb_wrap *wtdb;
27 static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag);
28 static NTSTATUS db_tdb_delete(struct db_record *rec);
30 static int db_tdb_record_destr(struct db_record* data)
32 struct db_tdb_ctx *ctx =
33 talloc_get_type_abort(data->private_data, struct db_tdb_ctx);
35 /* This hex_encode_talloc() call allocates memory on data context. By way how current
36 __talloc_free() code works, it is OK to allocate in the destructor as
37 the children of data will be freed after call to the destructor and this
38 new 'child' will be caught and freed correctly.
40 DEBUG(10, (DEBUGLEVEL > 10
41 ? "Unlocking key %s\n" : "Unlocking key %.20s\n",
42 hex_encode_talloc(data, (unsigned char *)data->key.dptr,
43 data->key.dsize)));
45 if (tdb_chainunlock(ctx->wtdb->tdb, data->key) != 0) {
46 DEBUG(0, ("tdb_chainunlock failed\n"));
47 return -1;
49 return 0;
52 struct tdb_fetch_locked_state {
53 TALLOC_CTX *mem_ctx;
54 struct db_record *result;
57 static int db_tdb_fetchlock_parse(TDB_DATA key, TDB_DATA data,
58 void *private_data)
60 struct tdb_fetch_locked_state *state =
61 (struct tdb_fetch_locked_state *)private_data;
63 state->result = (struct db_record *)talloc_size(
64 state->mem_ctx,
65 sizeof(struct db_record) + key.dsize + data.dsize);
67 if (state->result == NULL) {
68 return 0;
71 state->result->key.dsize = key.dsize;
72 state->result->key.dptr = ((uint8 *)state->result)
73 + sizeof(struct db_record);
74 memcpy(state->result->key.dptr, key.dptr, key.dsize);
76 state->result->value.dsize = data.dsize;
78 if (data.dsize > 0) {
79 state->result->value.dptr = state->result->key.dptr+key.dsize;
80 memcpy(state->result->value.dptr, data.dptr, data.dsize);
82 else {
83 state->result->value.dptr = NULL;
86 return 0;
89 static struct db_record *db_tdb_fetch_locked(struct db_context *db,
90 TALLOC_CTX *mem_ctx, TDB_DATA key)
92 struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data,
93 struct db_tdb_ctx);
94 struct tdb_fetch_locked_state state;
96 /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
97 if(DEBUGLEVEL >= 10) {
98 char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize);
99 DEBUG(10, (DEBUGLEVEL > 10
100 ? "Locking key %s\n" : "Locking key %.20s\n",
101 keystr));
102 TALLOC_FREE(keystr);
105 if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) {
106 DEBUG(3, ("tdb_chainlock failed\n"));
107 return NULL;
110 state.mem_ctx = mem_ctx;
111 state.result = NULL;
113 tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, &state);
115 if (state.result == NULL) {
116 db_tdb_fetchlock_parse(key, tdb_null, &state);
119 if (state.result == NULL) {
120 tdb_chainunlock(ctx->wtdb->tdb, key);
121 return NULL;
124 talloc_set_destructor(state.result, db_tdb_record_destr);
126 state.result->private_data = talloc_reference(state.result, ctx);
127 state.result->store = db_tdb_store;
128 state.result->delete_rec = db_tdb_delete;
130 DEBUG(10, ("Allocated locked data 0x%p\n", state.result));
132 return state.result;
135 struct tdb_fetch_state {
136 TALLOC_CTX *mem_ctx;
137 int result;
138 TDB_DATA data;
141 static int db_tdb_fetch_parse(TDB_DATA key, TDB_DATA data,
142 void *private_data)
144 struct tdb_fetch_state *state =
145 (struct tdb_fetch_state *)private_data;
147 state->data.dptr = (uint8 *)talloc_memdup(state->mem_ctx, data.dptr,
148 data.dsize);
149 if (state->data.dptr == NULL) {
150 state->result = -1;
151 return 0;
154 state->data.dsize = data.dsize;
155 return 0;
158 static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
159 TDB_DATA key, TDB_DATA *pdata)
161 struct db_tdb_ctx *ctx = talloc_get_type_abort(
162 db->private_data, struct db_tdb_ctx);
164 struct tdb_fetch_state state;
166 state.mem_ctx = mem_ctx;
167 state.result = 0;
168 state.data = tdb_null;
170 tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetch_parse, &state);
172 if (state.result == -1) {
173 return -1;
176 *pdata = state.data;
177 return 0;
180 static int db_tdb_parse(struct db_context *db, TDB_DATA key,
181 int (*parser)(TDB_DATA key, TDB_DATA data,
182 void *private_data),
183 void *private_data)
185 struct db_tdb_ctx *ctx = talloc_get_type_abort(
186 db->private_data, struct db_tdb_ctx);
188 return tdb_parse_record(ctx->wtdb->tdb, key, parser, private_data);
191 static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
193 struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
194 struct db_tdb_ctx);
197 * This has a bug: We need to replace rec->value for correct
198 * operation, but right now brlock and locking don't use the value
199 * anymore after it was stored.
202 return (tdb_store(ctx->wtdb->tdb, rec->key, data, flag) == 0) ?
203 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
206 static NTSTATUS db_tdb_delete(struct db_record *rec)
208 struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
209 struct db_tdb_ctx);
211 if (tdb_delete(ctx->wtdb->tdb, rec->key) == 0) {
212 return NT_STATUS_OK;
215 if (tdb_error(ctx->wtdb->tdb) == TDB_ERR_NOEXIST) {
216 return NT_STATUS_NOT_FOUND;
219 return NT_STATUS_UNSUCCESSFUL;
222 struct db_tdb_traverse_ctx {
223 struct db_context *db;
224 int (*f)(struct db_record *rec, void *private_data);
225 void *private_data;
228 static int db_tdb_traverse_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
229 void *private_data)
231 struct db_tdb_traverse_ctx *ctx =
232 (struct db_tdb_traverse_ctx *)private_data;
233 struct db_record rec;
235 rec.key = kbuf;
236 rec.value = dbuf;
237 rec.store = db_tdb_store;
238 rec.delete_rec = db_tdb_delete;
239 rec.private_data = ctx->db->private_data;
241 return ctx->f(&rec, ctx->private_data);
244 static int db_tdb_traverse(struct db_context *db,
245 int (*f)(struct db_record *rec, void *private_data),
246 void *private_data)
248 struct db_tdb_ctx *db_ctx =
249 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
250 struct db_tdb_traverse_ctx ctx;
252 ctx.db = db;
253 ctx.f = f;
254 ctx.private_data = private_data;
255 return tdb_traverse(db_ctx->wtdb->tdb, db_tdb_traverse_func, &ctx);
258 static NTSTATUS db_tdb_store_deny(struct db_record *rec, TDB_DATA data, int flag)
260 return NT_STATUS_MEDIA_WRITE_PROTECTED;
263 static NTSTATUS db_tdb_delete_deny(struct db_record *rec)
265 return NT_STATUS_MEDIA_WRITE_PROTECTED;
268 static int db_tdb_traverse_read_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
269 void *private_data)
271 struct db_tdb_traverse_ctx *ctx =
272 (struct db_tdb_traverse_ctx *)private_data;
273 struct db_record rec;
275 rec.key = kbuf;
276 rec.value = dbuf;
277 rec.store = db_tdb_store_deny;
278 rec.delete_rec = db_tdb_delete_deny;
279 rec.private_data = ctx->db->private_data;
281 return ctx->f(&rec, ctx->private_data);
284 static int db_tdb_traverse_read(struct db_context *db,
285 int (*f)(struct db_record *rec, void *private_data),
286 void *private_data)
288 struct db_tdb_ctx *db_ctx =
289 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
290 struct db_tdb_traverse_ctx ctx;
292 ctx.db = db;
293 ctx.f = f;
294 ctx.private_data = private_data;
295 return tdb_traverse_read(db_ctx->wtdb->tdb, db_tdb_traverse_read_func, &ctx);
298 static int db_tdb_get_seqnum(struct db_context *db)
301 struct db_tdb_ctx *db_ctx =
302 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
303 return tdb_get_seqnum(db_ctx->wtdb->tdb);
306 static int db_tdb_get_flags(struct db_context *db)
309 struct db_tdb_ctx *db_ctx =
310 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
311 return tdb_get_flags(db_ctx->wtdb->tdb);
314 static int db_tdb_transaction_start(struct db_context *db)
316 struct db_tdb_ctx *db_ctx =
317 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
318 return tdb_transaction_start(db_ctx->wtdb->tdb);
321 static int db_tdb_transaction_commit(struct db_context *db)
323 struct db_tdb_ctx *db_ctx =
324 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
325 return tdb_transaction_commit(db_ctx->wtdb->tdb);
328 static int db_tdb_transaction_cancel(struct db_context *db)
330 struct db_tdb_ctx *db_ctx =
331 talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
332 return tdb_transaction_cancel(db_ctx->wtdb->tdb);
335 struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
336 const char *name,
337 int hash_size, int tdb_flags,
338 int open_flags, mode_t mode)
340 struct db_context *result = NULL;
341 struct db_tdb_ctx *db_tdb;
343 result = TALLOC_ZERO_P(mem_ctx, struct db_context);
344 if (result == NULL) {
345 DEBUG(0, ("talloc failed\n"));
346 goto fail;
349 result->private_data = db_tdb = TALLOC_P(result, struct db_tdb_ctx);
350 if (db_tdb == NULL) {
351 DEBUG(0, ("talloc failed\n"));
352 goto fail;
355 db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, tdb_flags,
356 open_flags, mode);
357 if (db_tdb->wtdb == NULL) {
358 DEBUG(3, ("Could not open tdb: %s\n", strerror(errno)));
359 goto fail;
362 result->fetch_locked = db_tdb_fetch_locked;
363 result->fetch = db_tdb_fetch;
364 result->traverse = db_tdb_traverse;
365 result->traverse_read = db_tdb_traverse_read;
366 result->parse_record = db_tdb_parse;
367 result->get_seqnum = db_tdb_get_seqnum;
368 result->get_flags = db_tdb_get_flags;
369 result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
370 result->transaction_start = db_tdb_transaction_start;
371 result->transaction_commit = db_tdb_transaction_commit;
372 result->transaction_cancel = db_tdb_transaction_cancel;
373 return result;
375 fail:
376 if (result != NULL) {
377 TALLOC_FREE(result);
379 return NULL;