The branch, master has been updated via a1187bb dbwrap: Remove talloc from dbwrap_watch_record_stored() via 1a8750a dbwrap: Convert dbwrap_record_watchers_key to not use talloc via 2e0e06c dbwrap: Simplify dbwrap_record_watchers_key() via 9964d60 dbwrap: Make dbwrap_db_id return size_t via 71a407e dbwrap: Remove talloc_reference() via 225cba6 dbwrap: Remove unused dbwrap_hash_size() via 5d12eb8 dbwrap: Remove loadparm_context from db_open_tdb from 1399198 build: improve stack protector check
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit a1187bb873009ea673b039bc7152c31f831f6366 Author: Volker Lendecke <v...@samba.org> Date: Sun Sep 20 18:25:20 2015 +0200 dbwrap: Remove talloc from dbwrap_watch_record_stored() This happens on every store to locking.tdb for example, so we should make it cheap. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> Autobuild-User(master): Ralph Böhme <s...@samba.org> Autobuild-Date(master): Tue Sep 22 07:50:58 CEST 2015 on sn-devel-104 commit 1a8750a2c619ca3ab44c49e186a89893742f435f Author: Volker Lendecke <v...@samba.org> Date: Sun Sep 20 17:32:24 2015 +0200 dbwrap: Convert dbwrap_record_watchers_key to not use talloc Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 2e0e06c3c51fc57bd021f24850e85e2394b3fa1c Author: Volker Lendecke <v...@samba.org> Date: Sun Sep 20 17:06:22 2015 +0200 dbwrap: Simplify dbwrap_record_watchers_key() It took a bit for me to figure out what the rec_key parameter to dbwrap_record_watchers_key does. I think it's simpler to parse the watcher key in dbwrap_record_watch_recv to retrieve the watched record key than to store it Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 9964d60e3e3a779bc2a6e72f4d677a72c59e09e4 Author: Volker Lendecke <v...@samba.org> Date: Sun Sep 20 16:26:06 2015 +0200 dbwrap: Make dbwrap_db_id return size_t This will make an on-stack db-id easier Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 71a407edad9f3fc1cd1719d87123862698f12f2f Author: Volker Lendecke <v...@samba.org> Date: Mon Sep 21 12:32:47 2015 +0200 dbwrap: Remove talloc_reference() We want to know (by crashing) when we free the database with records still around. This would be a serious violation of our data structure hierarchies. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 225cba6e413758dcaff2ba275fa81b37485922f2 Author: Volker Lendecke <v...@samba.org> Date: Sun Sep 20 20:25:53 2015 +0200 dbwrap: Remove unused dbwrap_hash_size() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 5d12eb890880c4d7e23a266f6817e40636fc81e6 Author: Volker Lendecke <v...@samba.org> Date: Mon Sep 21 12:28:20 2015 +0200 dbwrap: Remove loadparm_context from db_open_tdb Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/dbwrap/dbwrap.c | 9 +- lib/dbwrap/dbwrap.h | 3 +- lib/dbwrap/dbwrap_cache.c | 8 +- lib/dbwrap/dbwrap_local_open.c | 9 +- lib/dbwrap/dbwrap_private.h | 4 +- lib/dbwrap/dbwrap_rbt.c | 8 +- lib/dbwrap/dbwrap_tdb.c | 21 ++-- lib/dbwrap/dbwrap_tdb.h | 1 - source3/lib/dbwrap/dbwrap_ctdb.c | 10 +- source3/lib/dbwrap/dbwrap_watch.c | 189 +++++++++++++++---------------- source4/ntvfs/posix/python/pyxattr_tdb.c | 15 ++- 11 files changed, 137 insertions(+), 140 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/dbwrap/dbwrap.c b/lib/dbwrap/dbwrap.c index d75c714..a1b98c3 100644 --- a/lib/dbwrap/dbwrap.c +++ b/lib/dbwrap/dbwrap.c @@ -395,11 +395,6 @@ int dbwrap_wipe(struct db_context *db) return db->wipe(db); } -int dbwrap_hash_size(struct db_context *db) -{ - return db->hash_size; -} - int dbwrap_check(struct db_context *db) { if (db->check == NULL) { @@ -454,9 +449,9 @@ int dbwrap_transaction_cancel(struct db_context *db) return db->transaction_cancel(db); } -void dbwrap_db_id(struct db_context *db, const uint8_t **id, size_t *idlen) +size_t dbwrap_db_id(struct db_context *db, uint8_t *id, size_t idlen) { - db->id(db, id, idlen); + return db->id(db, id, idlen); } bool dbwrap_is_persistent(struct db_context *db) diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h index e081e18..0a5c918 100644 --- a/lib/dbwrap/dbwrap.h +++ b/lib/dbwrap/dbwrap.h @@ -83,12 +83,11 @@ int dbwrap_wipe(struct db_context *db); int dbwrap_check(struct db_context *db); int dbwrap_get_seqnum(struct db_context *db); /* Returns 0 if unknown. */ -int dbwrap_hash_size(struct db_context *db); int dbwrap_transaction_start(struct db_context *db); NTSTATUS dbwrap_transaction_start_nonblock(struct db_context *db); int dbwrap_transaction_commit(struct db_context *db); int dbwrap_transaction_cancel(struct db_context *db); -void dbwrap_db_id(struct db_context *db, const uint8_t **id, size_t *idlen); +size_t dbwrap_db_id(struct db_context *db, uint8_t *id, size_t idlen); bool dbwrap_is_persistent(struct db_context *db); const char *dbwrap_name(struct db_context *db); diff --git a/lib/dbwrap/dbwrap_cache.c b/lib/dbwrap/dbwrap_cache.c index 724389e..e4cee55 100644 --- a/lib/dbwrap/dbwrap_cache.c +++ b/lib/dbwrap/dbwrap_cache.c @@ -179,12 +179,13 @@ static int dbwrap_cache_exists(struct db_context *db, TDB_DATA key) return dbwrap_exists(ctx->backing, key); } -static void dbwrap_cache_id(struct db_context *db, const uint8_t **id, - size_t *idlen) +static size_t dbwrap_cache_id(struct db_context *db, uint8_t *id, + size_t idlen) { struct db_cache_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_cache_ctx); - dbwrap_db_id(ctx->backing, id, idlen); + + return dbwrap_db_id(ctx->backing, id, idlen); } struct db_context *db_open_cache(TALLOC_CTX *mem_ctx, @@ -222,6 +223,5 @@ struct db_context *db_open_cache(TALLOC_CTX *mem_ctx, db->exists = dbwrap_cache_exists; db->id = dbwrap_cache_id; db->name = dbwrap_name(ctx->backing); - db->hash_size = dbwrap_hash_size(ctx->backing); return db; } diff --git a/lib/dbwrap/dbwrap_local_open.c b/lib/dbwrap/dbwrap_local_open.c index 6509ff9..c350fd3e 100644 --- a/lib/dbwrap/dbwrap_local_open.c +++ b/lib/dbwrap/dbwrap_local_open.c @@ -34,8 +34,13 @@ struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx, { struct db_context *db = NULL; - db = db_open_tdb(mem_ctx, lp_ctx, name, hash_size, - tdb_flags, open_flags, mode, + if (hash_size == 0) { + hash_size = lpcfg_tdb_hash_size(lp_ctx, name); + } + + db = db_open_tdb(mem_ctx, name, hash_size, + lpcfg_tdb_flags(lp_ctx, tdb_flags), + open_flags, mode, lock_order, dbwrap_flags); return db; diff --git a/lib/dbwrap/dbwrap_private.h b/lib/dbwrap/dbwrap_private.h index a6bad04..6a52850 100644 --- a/lib/dbwrap/dbwrap_private.h +++ b/lib/dbwrap/dbwrap_private.h @@ -58,9 +58,9 @@ struct db_context { int (*exists)(struct db_context *db,TDB_DATA key); int (*wipe)(struct db_context *db); int (*check)(struct db_context *db); - void (*id)(struct db_context *db, const uint8_t **id, size_t *idlen); + size_t (*id)(struct db_context *db, uint8_t *id, size_t idlen); + const char *name; - int hash_size; void *private_data; enum dbwrap_lock_order lock_order; bool persistent; diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c index 03f2f57..0764a2c 100644 --- a/lib/dbwrap/dbwrap_rbt.c +++ b/lib/dbwrap/dbwrap_rbt.c @@ -497,10 +497,12 @@ static int db_rbt_trans_dummy(struct db_context *db) return 0; } -static void db_rbt_id(struct db_context *db, const uint8_t **id, size_t *idlen) +static size_t db_rbt_id(struct db_context *db, uint8_t *id, size_t idlen) { - *id = (uint8_t *)db; - *idlen = sizeof(struct db_context *); + if (idlen >= sizeof(struct db_context *)) { + memcpy(id, &db, sizeof(struct db_context *)); + } + return sizeof(struct db_context *); } struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx) diff --git a/lib/dbwrap/dbwrap_tdb.c b/lib/dbwrap/dbwrap_tdb.c index 2bc123e..0e54449 100644 --- a/lib/dbwrap/dbwrap_tdb.c +++ b/lib/dbwrap/dbwrap_tdb.c @@ -136,7 +136,7 @@ static struct db_record *db_tdb_fetch_locked_internal( talloc_set_destructor(state.result, db_tdb_record_destr); - state.result->private_data = talloc_reference(state.result, ctx); + state.result->private_data = ctx; state.result->store = db_tdb_store; state.result->delete_rec = db_tdb_delete; @@ -388,16 +388,19 @@ static int db_tdb_transaction_cancel(struct db_context *db) 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, @@ -421,12 +424,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, } result->lock_order = lock_order; - if (hash_size == 0) { - hash_size = lpcfg_tdb_hash_size(lp_ctx, name); - } - - db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, - lpcfg_tdb_flags(lp_ctx, tdb_flags), + db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, tdb_flags, open_flags, mode); if (db_tdb->wtdb == NULL) { DEBUG(3, ("Could not open tdb: %s\n", strerror(errno))); @@ -458,7 +456,6 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, result->id = db_tdb_id; result->check = db_tdb_check; result->name = tdb_name(db_tdb->wtdb->tdb); - result->hash_size = hash_size; return result; fail: diff --git a/lib/dbwrap/dbwrap_tdb.h b/lib/dbwrap/dbwrap_tdb.h index 93ee09c..d5f49c7 100644 --- a/lib/dbwrap/dbwrap_tdb.h +++ b/lib/dbwrap/dbwrap_tdb.h @@ -25,7 +25,6 @@ struct db_context; 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, diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index f37bfd8..3b68338 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -1517,14 +1517,16 @@ static int db_ctdb_get_seqnum(struct db_context *db) return tdb_get_seqnum(ctx->wtdb->tdb); } -static void db_ctdb_id(struct db_context *db, const uint8_t **id, - size_t *idlen) +static size_t db_ctdb_id(struct db_context *db, uint8_t *id, size_t idlen) { struct db_ctdb_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_ctdb_ctx); - *id = (uint8_t *)&ctx->db_id; - *idlen = sizeof(ctx->db_id); + if (idlen >= sizeof(ctx->db_id)) { + memcpy(id, &ctx->db_id, sizeof(ctx->db_id)); + } + + return sizeof(ctx->db_id); } struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, diff --git a/source3/lib/dbwrap/dbwrap_watch.c b/source3/lib/dbwrap/dbwrap_watch.c index da1a9cc..426fe77 100644 --- a/source3/lib/dbwrap/dbwrap_watch.c +++ b/source3/lib/dbwrap/dbwrap_watch.c @@ -45,33 +45,29 @@ static struct db_context *dbwrap_record_watchers_db(void) return watchers_db; } -static TDB_DATA dbwrap_record_watchers_key(TALLOC_CTX *mem_ctx, - struct db_context *db, - struct db_record *rec, - TDB_DATA *rec_key) +static size_t dbwrap_record_watchers_key(struct db_context *db, + struct db_record *rec, + uint8_t *wkey, size_t wkey_len) { - const uint8_t *db_id; - size_t db_id_len; - TDB_DATA key, wkey; + size_t db_id_len = dbwrap_db_id(db, NULL, 0); + uint8_t db_id[db_id_len]; + size_t needed; + TDB_DATA key; + + dbwrap_db_id(db, db_id, db_id_len); - dbwrap_db_id(db, &db_id, &db_id_len); key = dbwrap_record_get_key(rec); - wkey.dsize = sizeof(uint32_t) + db_id_len + key.dsize; - wkey.dptr = talloc_array(mem_ctx, uint8_t, wkey.dsize); - if (wkey.dptr == NULL) { - return make_tdb_data(NULL, 0); - } - SIVAL(wkey.dptr, 0, db_id_len); - memcpy(wkey.dptr + sizeof(uint32_t), db_id, db_id_len); - memcpy(wkey.dptr + sizeof(uint32_t) + db_id_len, key.dptr, key.dsize); + needed = sizeof(uint32_t) + db_id_len + key.dsize; - if (rec_key != NULL) { - rec_key->dptr = wkey.dptr + sizeof(uint32_t) + db_id_len; - rec_key->dsize = key.dsize; + if (wkey_len >= needed) { + SIVAL(wkey, 0, db_id_len); + memcpy(wkey + sizeof(uint32_t), db_id, db_id_len); + memcpy(wkey + sizeof(uint32_t) + db_id_len, + key.dptr, key.dsize); } - return wkey; + return needed; } static bool dbwrap_record_watchers_key_parse( @@ -89,10 +85,16 @@ static bool dbwrap_record_watchers_key_parse( "db_id_len=%d\n", (int)wkey.dsize, (int)db_id_len)); return false; } - *p_db_id = wkey.dptr + sizeof(uint32_t); - *p_db_id_len = db_id_len; - key->dptr = wkey.dptr + sizeof(uint32_t) + db_id_len; - key->dsize = wkey.dsize - sizeof(uint32_t) - db_id_len; + if (p_db_id != NULL) { + *p_db_id = wkey.dptr + sizeof(uint32_t); + } + if (p_db_id_len != NULL) { + *p_db_id_len = db_id_len; + } + if (key != NULL) { + key->dptr = wkey.dptr + sizeof(uint32_t) + db_id_len; + key->dsize = wkey.dsize - sizeof(uint32_t) - db_id_len; + } return true; } @@ -191,53 +193,11 @@ done: return status; } -static NTSTATUS dbwrap_record_get_watchers(struct db_context *db, - struct db_record *rec, - TALLOC_CTX *mem_ctx, - struct server_id **p_ids, - size_t *p_num_ids) -{ - struct db_context *w_db; - TDB_DATA key = { 0, }; - TDB_DATA value = { 0, }; - struct server_id *ids; - NTSTATUS status; - - key = dbwrap_record_watchers_key(talloc_tos(), db, rec, NULL); - if (key.dptr == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - w_db = dbwrap_record_watchers_db(); - if (w_db == NULL) { - status = NT_STATUS_INTERNAL_ERROR; - goto fail; - } - status = dbwrap_fetch(w_db, mem_ctx, key, &value); - TALLOC_FREE(key.dptr); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - if ((value.dsize % sizeof(struct server_id)) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - ids = (struct server_id *)value.dptr; - *p_ids = talloc_move(mem_ctx, &ids); - *p_num_ids = value.dsize / sizeof(struct server_id); - return NT_STATUS_OK; -fail: - TALLOC_FREE(key.dptr); - TALLOC_FREE(value.dptr); - return status; -} - struct dbwrap_record_watch_state { struct tevent_context *ev; struct db_context *db; struct tevent_req *req; struct messaging_context *msg; - TDB_DATA key; TDB_DATA w_key; }; @@ -273,11 +233,15 @@ struct tevent_req *dbwrap_record_watch_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - state->w_key = dbwrap_record_watchers_key(state, state->db, rec, - &state->key); + state->w_key.dsize = dbwrap_record_watchers_key( + state->db, rec, NULL, 0); + + state->w_key.dptr = talloc_array(state, uint8_t, state->w_key.dsize); if (tevent_req_nomem(state->w_key.dptr, req)) { return tevent_req_post(req, ev); } + dbwrap_record_watchers_key( + state->db, rec, state->w_key.dptr, state->w_key.dsize); subreq = messaging_filtered_read_send( state, ev, state->msg, dbwrap_record_watch_filter, state); @@ -324,48 +288,67 @@ static int dbwrap_record_watch_state_destructor( return 0; } +static void dbwrap_watch_record_stored_fn(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct messaging_context *msg = private_data; + size_t i, num_ids; + + if ((data.dsize % sizeof(struct server_id)) != 0) { + DBG_WARNING("%s: Invalid data size: %zu\n", __func__, + data.dsize); + return; + } + num_ids = data.dsize / sizeof(struct server_id); + + for (i=0; i<num_ids; i++) { + struct server_id dst; + NTSTATUS status; + + memcpy(&dst, data.dptr + i * sizeof(struct server_id), + sizeof(struct server_id)); + + status = messaging_send_buf(msg, dst, MSG_DBWRAP_MODIFIED, + key.dptr, key.dsize); + if (!NT_STATUS_IS_OK(status)) { + struct server_id_buf tmp; + DBG_WARNING("%s: messaging_send to %s failed: %s\n", + __func__, server_id_str_buf(dst, &tmp), + nt_errstr(status)); + } + } +} + static void dbwrap_watch_record_stored(struct db_context *db, struct db_record *rec, void *private_data) { struct messaging_context *msg = talloc_get_type_abort( private_data, struct messaging_context); - struct server_id *ids = NULL; - size_t num_ids = 0; - TDB_DATA w_key = { 0, }; + struct db_context *watchers_db; + + size_t wkey_len = dbwrap_record_watchers_key(db, rec, NULL, 0); + uint8_t wkey_buf[wkey_len]; + TDB_DATA wkey = { .dptr = wkey_buf, .dsize = wkey_len }; + NTSTATUS status; - uint32_t i; - status = dbwrap_record_get_watchers(db, rec, talloc_tos(), - &ids, &num_ids); + watchers_db = dbwrap_record_watchers_db(); + if (watchers_db == NULL) { + return; + } + + dbwrap_record_watchers_key(db, rec, wkey_buf, wkey_len); + + status = dbwrap_parse_record(watchers_db, wkey, + dbwrap_watch_record_stored_fn, msg); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - goto done; + return; } if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("dbwrap_record_get_watchers failed: %s\n", - nt_errstr(status))); - goto done; - } - w_key = dbwrap_record_watchers_key(talloc_tos(), db, rec, NULL); - if (w_key.dptr == NULL) { - DEBUG(1, ("dbwrap_record_watchers_key failed\n")); - goto done; - } - - for (i=0; i<num_ids; i++) { - status = messaging_send_buf(msg, ids[i], MSG_DBWRAP_MODIFIED, - w_key.dptr, w_key.dsize); - if (!NT_STATUS_IS_OK(status)) { - struct server_id_buf tmp; - DEBUG(1, ("messaging_send to %s failed: %s\n", - server_id_str_buf(ids[i], &tmp), - nt_errstr(status))); - } + DBG_WARNING("%s: dbwrap_parse_record failed: %s\n", + __func__, nt_errstr(status)); } -done: - TALLOC_FREE(w_key.dptr); - TALLOC_FREE(ids); - return; } void dbwrap_watch_db(struct db_context *db, struct messaging_context *msg) @@ -396,7 +379,9 @@ NTSTATUS dbwrap_record_watch_recv(struct tevent_req *req, struct dbwrap_record_watch_state *state = tevent_req_data( req, struct dbwrap_record_watch_state); NTSTATUS status; + TDB_DATA key; struct db_record *rec; + bool ok; if (tevent_req_is_nterror(req, &status)) { return status; @@ -404,7 +389,13 @@ NTSTATUS dbwrap_record_watch_recv(struct tevent_req *req, if (prec == NULL) { return NT_STATUS_OK; } - rec = dbwrap_fetch_locked(state->db, mem_ctx, state->key); + + ok = dbwrap_record_watchers_key_parse(state->w_key, NULL, NULL, &key); + if (!ok) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + rec = dbwrap_fetch_locked(state->db, mem_ctx, key); if (rec == NULL) { return NT_STATUS_INTERNAL_DB_ERROR; } diff --git a/source4/ntvfs/posix/python/pyxattr_tdb.c b/source4/ntvfs/posix/python/pyxattr_tdb.c index d3390a3..84ef426 100644 --- a/source4/ntvfs/posix/python/pyxattr_tdb.c +++ b/source4/ntvfs/posix/python/pyxattr_tdb.c -- Samba Shared Repository