[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Fri May 15 10:27:04 UTC 2020


The branch, master has been updated
       via  ddd8ae51f8c smb2_server: do async shutdown for pending multi-channel requests
       via  a90ac47d88d smbXsrv_session: add a smbXsrv_session_disconnect_xconn() helper
       via  de0e6dfdb84 smb2_server: call smbXsrv_connection_disconnect_transport() early on network errors
       via  26ba013e279 smb2_server: add and use a function that calculated the remaining channels
       via  a87c9a92df6 smb2_server: let smbd_server_connection_terminate_ex() call smbXsrv_connection_disconnect_transport()
       via  d8ab88e77f8 s3:smbd: split out smbXsrv_connection_disconnect_transport()
       via  0cec96526bf smb2_server: make sure we detect stale smbXsrv_connection pointers in smbXsrv_channel_global
       via  2ac0f835458 smb2_server: update inline comment for max channels
       via  e26b55a232b smbXsrv_client: make sure that we store a valid blob
       via  73cc25fa7b1 smbXsrv_client: fix debug message in smbXsrv_client_create()
      from  004e7a1fee7 s4/rpc_server/dnsserver: Allow parsing of dnsProperty to fail gracefully

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ddd8ae51f8c7a8f35754d0b281c74cb36e7d6bbd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 14:55:52 2019 +0200

    smb2_server: do async shutdown for pending multi-channel requests
    
    We have wait until all pending requests are done before we can
    TALLOC_FREE() the connection structure.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Fri May 15 10:26:29 UTC 2020 on sn-devel-184

commit a90ac47d88d08dfd396e956f9e24d9fcc0de3c5d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 12:11:00 2019 +0200

    smbXsrv_session: add a smbXsrv_session_disconnect_xconn() helper
    
    This removes the connection references from the session channel
    array for each session that's used on the connection.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit de0e6dfdb84cfe13b04d6ec7a09b18f001c61db4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 14:56:40 2019 +0200

    smb2_server: call smbXsrv_connection_disconnect_transport() early on network errors
    
    It's good to remember the first error we got and makes sure we don't try
    any further io on the connection.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 26ba013e279769b39e6bac510cb4b2d6d801ac98
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 14:49:59 2019 +0200

    smb2_server: add and use a function that calculated the remaining channels
    
    This is useful for debugging, but also simplies the following changes,
    where client->connections may hold disconnected connections until
    all pending requests are finished.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit a87c9a92df675173fc28404819d8dc0303eb81af
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 14:30:17 2019 +0200

    smb2_server: let smbd_server_connection_terminate_ex() call smbXsrv_connection_disconnect_transport()
    
    If the connection is broken mark it as invalid and close
    the socket.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit d8ab88e77f8bbd29d9222348eb4f9a290a4f3694
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 14:26:20 2019 +0200

    s3:smbd: split out smbXsrv_connection_disconnect_transport()
    
    It's good to have an isolated function that just disconnects the
    lower layer transport and remembers the first error status.
    
    This will be used in more placed in the following commits.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 0cec96526bf4d3209caf36c4a19632ff5d5dd112
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 4 10:02:56 2019 +0200

    smb2_server: make sure we detect stale smbXsrv_connection pointers in smbXsrv_channel_global
    
    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 2ac0f8354585ac2cd617d53bfc9678769c8698fc
Author: Günther Deschner <gd at samba.org>
Date:   Wed Jan 24 17:14:59 2018 +0100

    smb2_server: update inline comment for max channels
    
    All Windows versions have the limit of 32 channels.
    
    Signed-off-by: Guenther Deschner <gd at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit e26b55a232b1402b5d42ce0ab9e3d79b4f4319d9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu May 7 06:49:24 2020 -0700

    smbXsrv_client: make sure that we store a valid blob
    
    This fixes a regression introduced by
    14182350f8397d27d7642dae595dc52691f0acfe
    ("librpc ndr: ndr_pull_advance check for unsigned overflow.")
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14236
    
    ndr_push_smbXsrv_client_global0() is happy with
    pushing NULL pointers for r->{local_address,remote_address,remote_name},
    while the IDL doesn't allow it.
    In turn ndr_pull_smbXsrv_client_global0() no longer ignores the error.
    
    This means multi-channel connections were broken,
    and we paniced on a NULL pointer.
    It's really sad that we still don't have automated tests for it.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 73cc25fa7b126938fd161a01aef327c3fd85eef1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu May 7 06:54:37 2020 -0700

    smbXsrv_client: fix debug message in smbXsrv_client_create()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/librpc/idl/smbXsrv.idl |   3 +
 source3/smbd/globals.h         |   8 +-
 source3/smbd/process.c         |  26 +++++-
 source3/smbd/server_exit.c     |  28 +++---
 source3/smbd/smb2_server.c     | 201 +++++++++++++++++++++++++++++++++++++++--
 source3/smbd/smb2_sesssetup.c  |   1 +
 source3/smbd/smbXsrv_client.c  |  22 ++++-
 source3/smbd/smbXsrv_session.c | 141 ++++++++++++++++++++++++++++-
 8 files changed, 397 insertions(+), 33 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 4d9249fb3bb..bdab9345342 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -141,6 +141,7 @@ interface smbXsrv
 		 */
 		[ignore] struct smbXsrv_connection	*connections;
 		boolean8		server_multi_channel_enabled;
+		hyper			next_channel_id;
 	} smbXsrv_client;
 
 	typedef union {
@@ -200,6 +201,8 @@ interface smbXsrv
 
 	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[];
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 79086b3c81c..d3b6ac2ffe6 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -220,6 +220,8 @@ NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
 
 void smbd_notify_cancel_by_smbreq(const struct smb_request *smbreq);
 
+void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
+					     NTSTATUS status);
 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
 					 const char *reason,
 					 const char *location);
@@ -231,7 +233,7 @@ bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
 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);
@@ -347,6 +349,8 @@ struct smbXsrv_connection {
 
 	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;
@@ -547,7 +551,9 @@ NTSTATUS smbXsrv_session_create(struct smbXsrv_connection *conn,
 				struct smbXsrv_session **_session);
 NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
 				     struct smbXsrv_connection *conn,
+				     NTTIME now,
 				     struct smbXsrv_channel_global0 **_c);
+NTSTATUS smbXsrv_session_disconnect_xconn(struct smbXsrv_connection *xconn);
 NTSTATUS smbXsrv_session_update(struct smbXsrv_session *session);
 struct smbXsrv_channel_global0;
 NTSTATUS smbXsrv_session_find_channel(const struct smbXsrv_session *session,
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 955f13938b4..161672bd516 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3720,7 +3720,7 @@ const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
 }
 
 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;
@@ -3750,6 +3750,10 @@ NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 		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);
@@ -3994,7 +3998,7 @@ void smbd_process(struct tevent_context *ev_ctx,
 		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
@@ -4024,6 +4028,24 @@ void smbd_process(struct tevent_context *ev_ctx,
 		exit_server_cleanly("tsocket_strdup() failed");
 	}
 
+	client->global->local_address =
+		tsocket_address_string(sconn->local_address,
+				       client->global);
+	if (client->global->local_address == NULL) {
+		exit_server_cleanly("tsocket_address_string() failed");
+	}
+	client->global->remote_address =
+		tsocket_address_string(sconn->remote_address,
+				       client->global);
+	if (client->global->remote_address == NULL) {
+		exit_server_cleanly("tsocket_address_string() failed");
+	}
+	client->global->remote_name =
+		talloc_strdup(client->global, sconn->remote_hostname);
+	if (client->global->remote_name == NULL) {
+		exit_server_cleanly("tsocket_strdup() failed");
+	}
+
 	if (tsocket_address_is_inet(sconn->local_address, "ip")) {
 		locaddr = tsocket_address_inet_addr_string(
 				sconn->local_address,
diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c
index f361aaf0bb7..e3efa993159 100644
--- a/source3/smbd/server_exit.c
+++ b/source3/smbd/server_exit.c
@@ -81,6 +81,17 @@ static void exit_server_common(enum server_exit_reason how,
 	struct smbXsrv_connection *xconn = NULL;
 	struct smbd_server_connection *sconn = NULL;
 	struct messaging_context *msg_ctx = global_messaging_context();
+	NTSTATUS disconnect_status;
+
+	switch (how) {
+	case SERVER_EXIT_NORMAL:
+		disconnect_status = NT_STATUS_LOCAL_DISCONNECT;
+		break;
+	case SERVER_EXIT_ABNORMAL:
+	default:
+		disconnect_status = NT_STATUS_INTERNAL_ERROR;
+		break;
+	}
 
 	if (client != NULL) {
 		sconn = client->sconn;
@@ -100,19 +111,12 @@ static void exit_server_common(enum server_exit_reason how,
 	for (; xconn != NULL; xconn = xconn->next) {
 		/*
 		 * This is typically the disconnect for the only
-		 * (or with multi-channel last) connection of the client
+		 * (or with multi-channel last) connection of the client.
+		 *
+		 * smbXsrv_connection_disconnect_transport() might be called already,
+		 * but calling it again is a no-op.
 		 */
-		if (NT_STATUS_IS_OK(xconn->transport.status)) {
-			switch (how) {
-			case SERVER_EXIT_ABNORMAL:
-				xconn->transport.status = NT_STATUS_INTERNAL_ERROR;
-				break;
-			case SERVER_EXIT_NORMAL:
-				xconn->transport.status = NT_STATUS_LOCAL_DISCONNECT;
-				break;
-			}
-		}
-		DO_PROFILE_INC(disconnect);
+		smbXsrv_connection_disconnect_transport(xconn, disconnect_status);
 	}
 
 	change_to_root_user();
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 718f0941532..c11cc66a710 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1106,20 +1106,190 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
 	return NT_STATUS_OK;
 }
 
+void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
+					     NTSTATUS status)
+{
+	if (!NT_STATUS_IS_OK(xconn->transport.status)) {
+		return;
+	}
+
+	xconn->transport.status = status;
+	TALLOC_FREE(xconn->transport.fde);
+	if (xconn->transport.sock != -1) {
+		xconn->transport.sock = -1;
+	}
+	DO_PROFILE_INC(disconnect);
+}
+
+static size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
+{
+	struct smbXsrv_connection *xconn = NULL;
+	size_t num_ok = 0;
+
+	for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
+		if (NT_STATUS_IS_OK(xconn->transport.status)) {
+			num_ok++;
+		}
+	}
+
+	return num_ok;
+}
+
+struct smbXsrv_connection_shutdown_state {
+	struct tevent_queue *wait_queue;
+};
+
+static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
+
+static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					struct smbXsrv_connection *xconn)
+{
+	struct tevent_req *req = NULL;
+	struct smbXsrv_connection_shutdown_state *state = NULL;
+	struct tevent_req *subreq = NULL;
+	size_t len = 0;
+	struct smbd_smb2_request *preq = NULL;
+	NTSTATUS status;
+
+	/*
+	 * The caller should have called
+	 * smbXsrv_connection_disconnect_transport() before.
+	 */
+	SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct smbXsrv_connection_shutdown_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	status = smbXsrv_session_disconnect_xconn(xconn);
+	if (tevent_req_nterror(req, status)) {
+		return tevent_req_post(req, ev);
+	}
+
+	state->wait_queue = tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
+	if (tevent_req_nomem(state->wait_queue, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
+		/*
+		 * The connection is gone so we
+		 * don't need to take care of
+		 * any crypto
+		 */
+		preq->session = NULL;
+		preq->do_signing = false;
+		preq->do_encryption = false;
+		preq->preauth = NULL;
+
+		if (preq->subreq != NULL) {
+			tevent_req_cancel(preq->subreq);
+		}
+
+		/*
+		 * Now wait until the request is finished.
+		 *
+		 * We don't set a callback, as we just want to block the
+		 * wait queue and the talloc_free() of the request will
+		 * remove the item from the wait queue.
+		 */
+		subreq = tevent_queue_wait_send(preq, ev, state->wait_queue);
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+	}
+
+	len = tevent_queue_length(state->wait_queue);
+	if (len == 0) {
+		tevent_req_done(req);
+		return tevent_req_post(req, ev);
+	}
+
+	/*
+	 * Now we add our own waiter to the end of the queue,
+	 * this way we get notified when all pending requests are finished
+	 * and send to the socket.
+	 */
+	subreq = tevent_queue_wait_send(state, ev, state->wait_queue);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
+
+	return req;
+}
+
+static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req =
+		tevent_req_callback_data(subreq,
+		struct tevent_req);
+
+	tevent_queue_wait_recv(subreq);
+	TALLOC_FREE(subreq);
+
+	tevent_req_done(req);
+}
+
+static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
+{
+	return tevent_req_simple_recv_ntstatus(req);
+}
+
+static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
+{
+	struct smbXsrv_connection *xconn =
+		tevent_req_callback_data(subreq,
+		struct smbXsrv_connection);
+	struct smbXsrv_client *client = xconn->client;
+	NTSTATUS status;
+
+	status = smbXsrv_connection_shutdown_recv(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		exit_server("smbXsrv_connection_shutdown_recv failed");
+	}
+
+	DLIST_REMOVE(client->connections, xconn);
+	TALLOC_FREE(xconn);
+}
+
 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
 					 const char *reason,
 					 const char *location)
 {
 	struct smbXsrv_client *client = xconn->client;
+	size_t num_ok = 0;
+
+	/*
+	 * Make sure that no new request will be able to use this session.
+	 *
+	 * smbXsrv_connection_disconnect_transport() might be called already,
+	 * but calling it again is a no-op.
+	 */
+	smbXsrv_connection_disconnect_transport(xconn,
+					NT_STATUS_CONNECTION_DISCONNECTED);
+
+	num_ok = smbXsrv_client_valid_connections(client);
+
+	DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
+		  smbXsrv_connection_dbg(xconn), num_ok,
+		  reason, location);
 
-	DEBUG(10,("smbd_server_connection_terminate_ex: conn[%s] reason[%s] at %s\n",
-		  smbXsrv_connection_dbg(xconn), reason, location));
+	if (num_ok != 0) {
+		struct tevent_req *subreq = NULL;
 
-	if (client->connections->next != NULL) {
-		/* TODO: cancel pending requests */
-		DLIST_REMOVE(client->connections, xconn);
-		TALLOC_FREE(xconn);
-		DO_PROFILE_INC(disconnect);
+		subreq = smbXsrv_connection_shutdown_send(client,
+							  client->raw_ev_ctx,
+							  xconn);
+		if (subreq == NULL) {
+			exit_server("smbXsrv_connection_shutdown_send failed");
+		}
+		tevent_req_set_callback(subreq,
+					smbd_server_connection_terminate_done,
+					xconn);
 		return;
 	}
 
@@ -3794,6 +3964,8 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
 			talloc_free(e->mem_ctx);
 
 			if (!NT_STATUS_IS_OK(status)) {
+				smbXsrv_connection_disconnect_transport(xconn,
+									status);
 				return status;
 			}
 			continue;
@@ -3816,7 +3988,10 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
 			return NT_STATUS_OK;
 		}
 		if (err != 0) {
-			return map_nt_error_from_unix_common(err);
+			status = map_nt_error_from_unix_common(err);
+			smbXsrv_connection_disconnect_transport(xconn,
+								status);
+			return status;
 		}
 
 		ok = iov_advance(&e->vector, &e->count, ret);
@@ -3903,7 +4078,10 @@ again:
 	ret = recvmsg(xconn->transport.sock, &msg, 0);
 	if (ret == 0) {
 		/* propagate end of file */
-		return NT_STATUS_END_OF_FILE;
+		status = NT_STATUS_END_OF_FILE;
+		smbXsrv_connection_disconnect_transport(xconn,
+							status);
+		return status;
 	}
 	err = socket_error_from_errno(ret, errno, &retry);
 	if (retry) {
@@ -3912,7 +4090,10 @@ again:
 		return NT_STATUS_OK;
 	}
 	if (err != 0) {
-		return map_nt_error_from_unix_common(err);
+		status = map_nt_error_from_unix_common(err);
+		smbXsrv_connection_disconnect_transport(xconn,
+							status);
+		return status;
 	}
 
 	if (ret < state->vector.iov_len) {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 3fa1a15910e..f9c8819327c 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -912,6 +912,7 @@ static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
 
 		status = smbXsrv_session_add_channel(smb2req->session,
 						     smb2req->xconn,
+						     now,
 						     &c);
 		if (!NT_STATUS_IS_OK(status)) {
 			tevent_req_nterror(req, status);
diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c
index 02754a88dd5..c6114d4b8dc 100644
--- a/source3/smbd/smbXsrv_client.c
+++ b/source3/smbd/smbXsrv_client.c
@@ -294,6 +294,13 @@ NTSTATUS smb2srv_client_lookup_global(struct smbXsrv_client *client,
 		return NT_STATUS_OBJECTID_NOT_FOUND;
 	}
 
+	if (global == NULL) {
+		/*
+		 * most likely ndr_pull_struct_blob() failed
+		 */
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
 	*_global = global;
 	return NT_STATUS_OK;
 }
@@ -375,6 +382,10 @@ static NTSTATUS smbXsrv_client_global_store(struct smbXsrv_client_global0 *globa
 	 * store the information in the old format.
 	 */
 
+	SMB_ASSERT(global->local_address != NULL);
+	SMB_ASSERT(global->remote_address != NULL);
+	SMB_ASSERT(global->remote_name != NULL);
+
 	if (global->db_rec == NULL) {
 		return NT_STATUS_INTERNAL_ERROR;
 	}
@@ -512,7 +523,9 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 	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;
 
@@ -539,7 +552,7 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 		};
 		struct GUID_txt_buf buf;
 
-		DBG_DEBUG("client_guid[%s] stored\n",
+		DBG_DEBUG("client_guid[%s] created\n",
 			  GUID_buf_string(&global->client_guid, &buf));
 		NDR_PRINT_DEBUG(smbXsrv_clientB, &client_blob);
 	}
@@ -662,7 +675,10 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
 
 	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;
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c
index ba542702213..8eaa9fdcbab 100644
--- a/source3/smbd/smbXsrv_session.c
+++ b/source3/smbd/smbXsrv_session.c
@@ -1293,7 +1293,7 @@ NTSTATUS smbXsrv_session_create(struct smbXsrv_connection *conn,
 	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;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list