summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/globals.h4
-rw-r--r--source3/smbd/smbXsrv_tcon.c70
2 files changed, 74 insertions, 0 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 6509dda37c..4a86697d48 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -427,6 +427,10 @@ NTSTATUS smb2srv_tcon_lookup(struct smbXsrv_session *session,
uint32_t tree_id, NTTIME now,
struct smbXsrv_tcon **tcon);
NTSTATUS smb2srv_tcon_disconnect_all(struct smbXsrv_session *session);
+struct smbXsrv_tcon_global0;
+NTSTATUS smbXsrv_tcon_global_traverse(
+ int (*fn)(struct smbXsrv_tcon_global0 *, void *),
+ void *private_data);
NTSTATUS smbXsrv_open_global_init(void);
NTSTATUS smbXsrv_open_create(struct smbXsrv_connection *conn,
diff --git a/source3/smbd/smbXsrv_tcon.c b/source3/smbd/smbXsrv_tcon.c
index 9f8162a6a6..49da84ddfe 100644
--- a/source3/smbd/smbXsrv_tcon.c
+++ b/source3/smbd/smbXsrv_tcon.c
@@ -1164,3 +1164,73 @@ NTSTATUS smb2srv_tcon_disconnect_all(struct smbXsrv_session *session)
return smbXsrv_tcon_disconnect_all(session->tcon_table, vuid);
}
+
+struct smbXsrv_tcon_global_traverse_state {
+ int (*fn)(struct smbXsrv_tcon_global0 *, void *);
+ void *private_data;
+};
+
+static int smbXsrv_tcon_global_traverse_fn(struct db_record *rec, void *data)
+{
+ int ret = -1;
+ struct smbXsrv_tcon_global_traverse_state *state =
+ (struct smbXsrv_tcon_global_traverse_state*)data;
+ TDB_DATA key = dbwrap_record_get_key(rec);
+ TDB_DATA val = dbwrap_record_get_value(rec);
+ DATA_BLOB blob = data_blob_const(val.dptr, val.dsize);
+ struct smbXsrv_tcon_globalB global_blob;
+ enum ndr_err_code ndr_err;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ ndr_err = ndr_pull_struct_blob(&blob, frame, &global_blob,
+ (ndr_pull_flags_fn_t)ndr_pull_smbXsrv_tcon_globalB);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(1,("Invalid record in smbXsrv_tcon_global.tdb:"
+ "key '%s' ndr_pull_struct_blob - %s\n",
+ hex_encode_talloc(frame, key.dptr, key.dsize),
+ ndr_errstr(ndr_err)));
+ goto done;
+ }
+
+ if (global_blob.version != SMBXSRV_VERSION_0) {
+ DEBUG(1,("Invalid record in smbXsrv_tcon_global.tdb:"
+ "key '%s' unsuported version - %d\n",
+ hex_encode_talloc(frame, key.dptr, key.dsize),
+ (int)global_blob.version));
+ goto done;
+ }
+
+ ret = state->fn(global_blob.info.info0, state->private_data);
+done:
+ TALLOC_FREE(frame);
+ return ret;
+}
+
+NTSTATUS smbXsrv_tcon_global_traverse(
+ int (*fn)(struct smbXsrv_tcon_global0 *, void *),
+ void *private_data)
+{
+ NTSTATUS status;
+ int count = 0;
+ struct smbXsrv_tcon_global_traverse_state state = {
+ .fn = fn,
+ .private_data = private_data,
+ };
+
+ become_root();
+ status = smbXsrv_tcon_global_init();
+ if (!NT_STATUS_IS_OK(status)) {
+ unbecome_root();
+ DEBUG(0, ("Failed to initialize tcon_global: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ status = dbwrap_traverse_read(smbXsrv_tcon_global_db_ctx,
+ smbXsrv_tcon_global_traverse_fn,
+ &state,
+ &count);
+ unbecome_root();
+
+ return status;
+}