diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/globals.h | 4 | ||||
-rw-r--r-- | source3/smbd/smbXsrv_tcon.c | 70 |
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; +} |