From: Gregor Beck Date: Mon, 3 Sep 2012 09:13:16 +0000 (+0200) Subject: s3:lib/conn_tdb: implement connections_forall_read() based on smbXsrv_*_global_traverse() X-Git-Tag: ldb-1.1.14~192 X-Git-Url: http://git.samba.org/samba.git/?p=metze%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=0ccbf89bda71cdbe8d216bab0aa6aacd98cf95df s3:lib/conn_tdb: implement connections_forall_read() based on smbXsrv_*_global_traverse() Signed-off-by: Stefan Metzmacher Signed-off-by: Michael Adam --- diff --git a/source3/lib/conn_tdb.c b/source3/lib/conn_tdb.c index 0a622de1c66..3930e2736a5 100644 --- a/source3/lib/conn_tdb.c +++ b/source3/lib/conn_tdb.c @@ -22,8 +22,10 @@ #include "smbd/globals.h" #include "dbwrap/dbwrap.h" #include "dbwrap/dbwrap_open.h" +#include "dbwrap/dbwrap_rbt.h" #include "messages.h" #include "lib/conn_tdb.h" +#include "util_tdb.h" static struct db_context *connections_db_ctx(bool rw) { @@ -81,31 +83,88 @@ struct db_record *connections_fetch_entry(TALLOC_CTX *mem_ctx, return connections_fetch_entry_ext(mem_ctx, id, conn->cnum, name); } -struct conn_traverse_read_state { +struct connections_forall_state { + struct db_context *session_by_pid; int (*fn)(const struct connections_key *key, const struct connections_data *data, void *private_data); void *private_data; + int count; +}; + +struct connections_forall_session { + uid_t uid; + gid_t gid; + char machine[FSTRING_LEN]; + char addr[FSTRING_LEN]; }; -static int connections_forall_read_fn(struct db_record *rec, - void *private_data) +static int collect_sessions_fn(struct smbXsrv_session_global0 *global, + void *connections_forall_state) { - TDB_DATA key; - TDB_DATA value; - struct conn_traverse_read_state *state = - (struct conn_traverse_read_state *)private_data; + NTSTATUS status; + struct connections_forall_state *state = + (struct connections_forall_state*)connections_forall_state; + + uint32_t id = global->session_global_id; + struct connections_forall_session sess; + + sess.uid = global->auth_session_info->unix_token->uid; + sess.gid = global->auth_session_info->unix_token->gid; + strncpy(sess.machine, global->channels[0].remote_name, sizeof(sess.machine)); + strncpy(sess.addr, global->channels[0].remote_address, sizeof(sess.addr)); + + status = dbwrap_store(state->session_by_pid, + make_tdb_data((void*)&id, sizeof(id)), + make_tdb_data((void*)&sess, sizeof(sess)), + TDB_INSERT); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to store record: %s\n", nt_errstr(status))); + } + return 0; +} + +static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global, + void *connections_forall_state) +{ + NTSTATUS status; + struct connections_forall_state *state = + (struct connections_forall_state*)connections_forall_state; + + struct connections_key key; + struct connections_data data; - key = dbwrap_record_get_key(rec); - value = dbwrap_record_get_value(rec); + uint32_t sess_id = global->session_global_id; + struct connections_forall_session sess = { + .uid = -1, + .gid = -1, + }; - if ((key.dsize != sizeof(struct connections_key)) - || (value.dsize != sizeof(struct connections_data))) { - return 0; + TDB_DATA val = tdb_null; + + status = dbwrap_fetch(state->session_by_pid, state, + make_tdb_data((void*)&sess_id, sizeof(sess_id)), + &val); + if (NT_STATUS_IS_OK(status)) { + memcpy((uint8_t *)&sess, val.dptr, val.dsize); } - return state->fn((const struct connections_key *)key.dptr, - (const struct connections_data *)value.dptr, - state->private_data); + + ZERO_STRUCT(key); + ZERO_STRUCT(data); + + key.pid = data.pid = global->server_id; + key.cnum = data.cnum = global->tcon_global_id; + strncpy(key.name, global->share_name, sizeof(key.name)); + strncpy(data.servicename, global->share_name, sizeof(data.servicename)); + data.uid = sess.uid; + data.gid = sess.gid; + strncpy(data.addr, sess.addr, sizeof(data.addr)); + strncpy(data.machine, sess.machine, sizeof(data.machine)); + data.start = nt_time_to_unix(global->creation_time); + + state->count++; + + return state->fn(&key, &data, state->private_data); } int connections_forall_read(int (*fn)(const struct connections_key *key, @@ -113,27 +172,32 @@ int connections_forall_read(int (*fn)(const struct connections_key *key, void *private_data), void *private_data) { - struct db_context *ctx; - struct conn_traverse_read_state state; + TALLOC_CTX *frame = talloc_stackframe(); + struct connections_forall_state *state = + talloc_zero(talloc_tos(), struct connections_forall_state); NTSTATUS status; - int count; + int ret = -1; - ctx = connections_db_ctx(false); - if (ctx == NULL) { - return -1; + state->session_by_pid = db_open_rbt(state); + state->fn = fn; + state->private_data = private_data; + status = smbXsrv_session_global_traverse(collect_sessions_fn, state); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to traverse sessions: %s\n", + nt_errstr(status))); + goto done; } - state.fn = fn; - state.private_data = private_data; - - status = dbwrap_traverse_read(ctx, connections_forall_read_fn, - (void *)&state, &count); - + status = smbXsrv_tcon_global_traverse(traverse_tcon_fn, state); if (!NT_STATUS_IS_OK(status)) { - return -1; + DEBUG(0, ("Failed to traverse tree connects: %s\n", + nt_errstr(status))); + goto done; } - - return count; + ret = state->count; +done: + talloc_free(frame); + return ret; } bool connections_init(bool rw) diff --git a/source3/lib/conn_tdb.h b/source3/lib/conn_tdb.h index 180a5e23fd6..2f45281a819 100644 --- a/source3/lib/conn_tdb.h +++ b/source3/lib/conn_tdb.h @@ -25,21 +25,14 @@ struct connections_key { }; struct connections_data { - int magic; struct server_id pid; int cnum; uid_t uid; gid_t gid; char servicename[FSTRING_LEN]; - char addr[24]; + char addr[FSTRING_LEN]; char machine[FSTRING_LEN]; time_t start; - - /* - * This field used to hold the msg_flags. For compatibility reasons, - * keep the data structure in the tdb file the same. - */ - uint32 unused_compatitibility_field; }; /* The following definitions come from lib/conn_tdb.c */