summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2020-01-02 11:42:05 +0100
committerJeremy Allison <jra@samba.org>2020-01-13 19:41:36 +0000
commit18b43aeb5747f0982e4296960f23986a5f536960 (patch)
tree3a802b37410f1590205d0ffd00c29ef60123d005
parentd2b5f85d221626ce505143c7c129c41603dcb24a (diff)
downloadsamba-18b43aeb5747f0982e4296960f23986a5f536960.tar.gz
smbd: add smbXsrv_session_local_traverse()
Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/smbd/globals.h5
-rw-r--r--source3/smbd/smbXsrv_session.c71
2 files changed, 76 insertions, 0 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 57300dd02ae..72edd28b68c 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -586,6 +586,11 @@ NTSTATUS smb2srv_session_lookup_client(struct smbXsrv_client *client,
NTSTATUS get_valid_smbXsrv_session(struct smbXsrv_client *client,
uint64_t session_wire_id,
struct smbXsrv_session **session);
+NTSTATUS smbXsrv_session_local_traverse(
+ struct smbXsrv_client *client,
+ int (*caller_cb)(struct smbXsrv_session *session,
+ void *caller_data),
+ void *caller_data);
struct smbXsrv_session_global0;
NTSTATUS smbXsrv_session_global_traverse(
int (*fn)(struct smbXsrv_session_global0 *, void *),
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c
index b2d36d380be..77c285d741b 100644
--- a/source3/smbd/smbXsrv_session.c
+++ b/source3/smbd/smbXsrv_session.c
@@ -1830,6 +1830,77 @@ static int smbXsrv_session_logoff_all_callback(struct db_record *local_rec,
return 0;
}
+struct smbXsrv_session_local_trav_state {
+ NTSTATUS status;
+ int (*caller_cb)(struct smbXsrv_session *session,
+ void *caller_data);
+ void *caller_data;
+};
+
+static int smbXsrv_session_local_traverse_cb(struct db_record *local_rec,
+ void *private_data);
+
+NTSTATUS smbXsrv_session_local_traverse(
+ struct smbXsrv_client *client,
+ int (*caller_cb)(struct smbXsrv_session *session,
+ void *caller_data),
+ void *caller_data)
+{
+ struct smbXsrv_session_table *table = client->session_table;
+ struct smbXsrv_session_local_trav_state state;
+ NTSTATUS status;
+ int count = 0;
+
+ state = (struct smbXsrv_session_local_trav_state) {
+ .status = NT_STATUS_OK,
+ .caller_cb = caller_cb,
+ .caller_data = caller_data,
+ };
+
+ if (table == NULL) {
+ DBG_DEBUG("empty session_table, nothing to do.\n");
+ return NT_STATUS_OK;
+ }
+
+ status = dbwrap_traverse(table->local.db_ctx,
+ smbXsrv_session_local_traverse_cb,
+ &state,
+ &count);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("dbwrap_traverse() failed: %s\n", nt_errstr(status));
+ return status;
+ }
+ if (!NT_STATUS_IS_OK(state.status)) {
+ DBG_ERR("count[%d] status[%s]\n",
+ count, nt_errstr(state.status));
+ return state.status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static int smbXsrv_session_local_traverse_cb(struct db_record *local_rec,
+ void *private_data)
+{
+ struct smbXsrv_session_local_trav_state *state =
+ (struct smbXsrv_session_local_trav_state *)private_data;
+ TDB_DATA val;
+ void *ptr = NULL;
+ struct smbXsrv_session *session = NULL;
+
+ val = dbwrap_record_get_value(local_rec);
+ if (val.dsize != sizeof(ptr)) {
+ state->status = NT_STATUS_INTERNAL_ERROR;
+ return -1;
+ }
+
+ memcpy(&ptr, val.dptr, val.dsize);
+ session = talloc_get_type_abort(ptr, struct smbXsrv_session);
+ session->db_rec = local_rec;
+
+ return state->caller_cb(session, state->caller_data);
+}
+
NTSTATUS smb1srv_session_table_init(struct smbXsrv_connection *conn)
{
/*