Pointer values can be reused (yes, I hit that during my testing!).
Introduce a channel_id to identify connections and also add
some timestamps to make debugging easier.
This makes smbXsrv_session_find_channel() much more robust.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
*/
[ignore] struct smbXsrv_connection *connections;
boolean8 server_multi_channel_enabled;
*/
[ignore] struct smbXsrv_connection *connections;
boolean8 server_multi_channel_enabled;
} smbXsrv_client;
typedef union {
} smbXsrv_client;
typedef union {
typedef struct {
server_id server_id;
typedef struct {
server_id server_id;
+ hyper channel_id;
+ NTTIME creation_time;
[charset(UTF8),string] char local_address[];
[charset(UTF8),string] char remote_address[];
[charset(UTF8),string] char remote_name[];
[charset(UTF8),string] char local_address[];
[charset(UTF8),string] char remote_address[];
[charset(UTF8),string] char remote_name[];
bool smbd_smb2_is_compound(const struct smbd_smb2_request *req);
NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
bool smbd_smb2_is_compound(const struct smbd_smb2_request *req);
NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
- struct smbXsrv_connection **_xconn);
+ NTTIME now, struct smbXsrv_connection **_xconn);
NTSTATUS reply_smb2002(struct smb_request *req, uint16_t choice);
NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice);
NTSTATUS reply_smb2002(struct smb_request *req, uint16_t choice);
NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice);
struct smbXsrv_client *client;
struct smbXsrv_client *client;
+ NTTIME connect_time;
+ uint64_t channel_id;
const struct tsocket_address *local_address;
const struct tsocket_address *remote_address;
const char *remote_hostname;
const struct tsocket_address *local_address;
const struct tsocket_address *remote_address;
const char *remote_hostname;
struct smbXsrv_session **_session);
NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
struct smbXsrv_connection *conn,
struct smbXsrv_session **_session);
NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
struct smbXsrv_connection *conn,
struct smbXsrv_channel_global0 **_c);
NTSTATUS smbXsrv_session_update(struct smbXsrv_session *session);
struct smbXsrv_channel_global0;
struct smbXsrv_channel_global0 **_c);
NTSTATUS smbXsrv_session_update(struct smbXsrv_session *session);
struct smbXsrv_channel_global0;
}
NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
}
NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
- struct smbXsrv_connection **_xconn)
+ NTTIME now, struct smbXsrv_connection **_xconn)
{
TALLOC_CTX *frame = talloc_stackframe();
struct smbXsrv_connection *xconn;
{
TALLOC_CTX *frame = talloc_stackframe();
struct smbXsrv_connection *xconn;
return NT_STATUS_NO_MEMORY;
}
talloc_steal(frame, xconn);
return NT_STATUS_NO_MEMORY;
}
talloc_steal(frame, xconn);
+ xconn->connect_time = now;
+ if (client->next_channel_id != 0) {
+ xconn->channel_id = client->next_channel_id++;
+ }
xconn->transport.sock = sock_fd;
smbd_echo_init(xconn);
xconn->transport.sock = sock_fd;
smbd_echo_init(xconn);
smbd_setup_sig_hup_handler(sconn);
}
smbd_setup_sig_hup_handler(sconn);
}
- status = smbd_add_connection(client, sock_fd, &xconn);
+ status = smbd_add_connection(client, sock_fd, now, &xconn);
if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
/*
* send a negative session response "not listening on calling
if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
/*
* send a negative session response "not listening on calling
status = smbXsrv_session_add_channel(smb2req->session,
smb2req->xconn,
status = smbXsrv_session_add_channel(smb2req->session,
smb2req->xconn,
&c);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
&c);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
client->msg_ctx = msg_ctx;
client->server_multi_channel_enabled = lp_server_multi_channel_support();
client->msg_ctx = msg_ctx;
client->server_multi_channel_enabled = lp_server_multi_channel_support();
+ if (client->server_multi_channel_enabled) {
+ client->next_channel_id = 1;
+ }
client->table = talloc_move(client, &table);
table = client->table;
client->table = talloc_move(client, &table);
table = client->table;
DBG_ERR("got connection sockfd[%d]\n", sock_fd);
NDR_PRINT_DEBUG(smbXsrv_connection_passB, &pass_blob);
DBG_ERR("got connection sockfd[%d]\n", sock_fd);
NDR_PRINT_DEBUG(smbXsrv_connection_passB, &pass_blob);
- status = smbd_add_connection(client, sock_fd, &xconn);
+ status = smbd_add_connection(client,
+ sock_fd,
+ pass_info0->initial_connect_time,
+ &xconn);
if (!NT_STATUS_IS_OK(status)) {
close(sock_fd);
sock_fd = -1;
if (!NT_STATUS_IS_OK(status)) {
close(sock_fd);
sock_fd = -1;
global->creation_time = now;
global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
global->creation_time = now;
global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
- status = smbXsrv_session_add_channel(session, conn, &channel);
+ status = smbXsrv_session_add_channel(session, conn, now, &channel);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
struct smbXsrv_connection *conn,
NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
struct smbXsrv_connection *conn,
struct smbXsrv_channel_global0 **_c)
{
struct smbXsrv_session_global0 *global = session->global;
struct smbXsrv_channel_global0 **_c)
{
struct smbXsrv_session_global0 *global = session->global;
ZERO_STRUCTP(c);
c->server_id = messaging_server_id(conn->client->msg_ctx);
ZERO_STRUCTP(c);
c->server_id = messaging_server_id(conn->client->msg_ctx);
+ c->channel_id = conn->channel_id;
+ c->creation_time = now;
c->local_address = tsocket_address_string(conn->local_address,
global->channels);
if (c->local_address == NULL) {
c->local_address = tsocket_address_string(conn->local_address,
global->channels);
if (c->local_address == NULL) {
for (i=0; i < session->global->num_channels; i++) {
struct smbXsrv_channel_global0 *c = &session->global->channels[i];
for (i=0; i < session->global->num_channels; i++) {
struct smbXsrv_channel_global0 *c = &session->global->channels[i];
- if (c->connection == conn) {
- *_c = c;
- return NT_STATUS_OK;
+ if (c->channel_id != conn->channel_id) {
+ continue;
+ }
+
+ if (c->connection != conn) {
+ continue;
+
+ *_c = c;
+ return NT_STATUS_OK;
}
return NT_STATUS_USER_SESSION_DELETED;
}
return NT_STATUS_USER_SESSION_DELETED;