[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Sep 2 21:00:02 UTC 2022


The branch, master has been updated
       via  8591d942437 smbXsrv_client: notify a different node to drop a connection by client guid.
       via  21ef01e7b83 smbXsrv_client: correctly check in negotiate_request.length smbXsrv_client_connection_pass[ed]_*
       via  0efcfaa49c3 s3:tests: add test_smbXsrv_client_cross_node.sh
       via  3fd18a0d5b7 s3:tests: let test_smbXsrv_client_dead_rec.sh cleanup the correct files
      from  2643b7b5746 Cleanup and bug fixes in vxfs vfs code.

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


- Log -----------------------------------------------------------------
commit 8591d9424371e173b079d5c8a267ea4c2cb266ad
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Aug 30 20:45:50 2022 +0200

    smbXsrv_client: notify a different node to drop a connection by client guid.
    
    If a client disconnected all its interfaces and reconnects when
    the come back, it will likely start from any ip address returned
    dns, which means it can try to connect to a different ctdb node.
    The old node may not have noticed the disconnect and still holds
    the client_guid based smbd.
    
    Up unil now the new node returned NT_STATUS_NOT_SUPPORTED to
    the SMB2 Negotiate request, as messaging_send_iov[_from]() will
    return -1/ENOSYS if a file descriptor os passed to a process on
    a different node.
    
    Now we tell the other node to teardown all client connections
    belonging to the client-guid.
    
    Note that this is not authenticated, but if an attacker can
    capture the client-guid, he can also inject TCP resets anyway,
    to get the same effect.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15159
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Sep  2 20:59:15 UTC 2022 on sn-devel-184

commit 21ef01e7b8368caa050ed82b9d787d1679220b2b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Aug 30 16:56:12 2022 +0200

    smbXsrv_client: correctly check in negotiate_request.length smbXsrv_client_connection_pass[ed]_*
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15159
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0efcfaa49c3d61f2c8116ebafd55b72d3277d0d8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 31 14:04:10 2022 +0200

    s3:tests: add test_smbXsrv_client_cross_node.sh
    
    This demonstrates that a client-guid connected to ctdb node 0
    caused a connection with the same client-guid to be rejected by
    ctdb node 1. Node 1 rejects the SMB2 Negotiate with
    NT_STATUS_NOT_SUPPORTED, because passing the multi-channel connection
    to a different node is not supported.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15159
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3fd18a0d5b77a9f78c595852c342d4c8c33fac61
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 31 13:55:19 2022 +0200

    s3:tests: let test_smbXsrv_client_dead_rec.sh cleanup the correct files
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15159
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 librpc/idl/messaging.idl                           |   1 +
 source3/librpc/idl/smbXsrv.idl                     |  28 +++
 .../script/tests/test_smbXsrv_client_cross_node.sh |  95 ++++++++
 .../script/tests/test_smbXsrv_client_dead_rec.sh   |   2 +-
 source3/selftest/tests.py                          |   7 +
 source3/smbd/smbXsrv_client.c                      | 266 +++++++++++++++++++--
 6 files changed, 375 insertions(+), 24 deletions(-)
 create mode 100755 source3/script/tests/test_smbXsrv_client_cross_node.sh


Changeset truncated at 500 lines:

diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index d6929c799ad..5d217c03f5b 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -138,6 +138,7 @@ interface messaging
 		MSG_SMBXSRV_SESSION_CLOSE	= 0x0600,
 		MSG_SMBXSRV_CONNECTION_PASS	= 0x0601,
 		MSG_SMBXSRV_CONNECTION_PASSED	= 0x0602,
+		MSG_SMBXSRV_CONNECTION_DROP	= 0x0603,
 
 		/* source4 and NTVFS smb server messages */
 		MSG_BRL_RETRY                   = 0x0700,
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index fc502009b3b..ec65a5c1a61 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -143,6 +143,7 @@ interface smbXsrv
 		boolean8		server_multi_channel_enabled;
 		hyper			next_channel_id;
 		[ignore] struct tevent_req		*connection_pass_subreq;
+		[ignore] struct tevent_req		*connection_drop_subreq;
 
 		/*
 		 * A List of pending breaks.
@@ -194,6 +195,33 @@ interface smbXsrv
 		[in] smbXsrv_connection_passB blob
 		);
 
+	/*
+	 * smbXsrv_connection_drop is used in the MSG_SMBXSRV_CONNECTION_DROP
+	 * message as reaction the record is deleted.
+	 */
+	typedef struct {
+		GUID					client_guid;
+		server_id				src_server_id;
+		NTTIME					xconn_connect_time;
+		server_id				dst_server_id;
+		NTTIME					client_connect_time;
+	} smbXsrv_connection_drop0;
+
+	typedef union {
+		[case(0)] smbXsrv_connection_drop0	*info0;
+		[default] hyper				*dummy;
+	} smbXsrv_connection_dropU;
+
+	typedef [public] struct {
+		smbXsrv_version_values			version;
+		[value(0)] uint32			reserved;
+		[switch_is(version)] smbXsrv_connection_dropU	info;
+	} smbXsrv_connection_dropB;
+
+	void smbXsrv_connection_drop_decode(
+		[in] smbXsrv_connection_dropB blob
+		);
+
 	/* sessions */
 
 	typedef [public,bitmap8bit] bitmap {
diff --git a/source3/script/tests/test_smbXsrv_client_cross_node.sh b/source3/script/tests/test_smbXsrv_client_cross_node.sh
new file mode 100755
index 00000000000..ff826924b49
--- /dev/null
+++ b/source3/script/tests/test_smbXsrv_client_cross_node.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+#
+# Test smbd let cluster node 0 destroy the connection,
+# if the client with a specific client-guid connections to node 1
+#
+
+if [ $# -lt 4 ]; then
+	echo Usage: test_smbXsrv_client_cross_node.sh SERVERCONFFILE NODE0 NODE1 SHARENAME
+	exit 1
+fi
+
+CONF=$1
+NODE0=$2
+NODE1=$3
+SHARE=$4
+
+SMBCLIENT="$BINDIR/smbclient"
+SMBSTATUS="$BINDIR/smbstatus"
+
+incdir=$(dirname "$0")/../../../testprogs/blackbox
+. "$incdir"/subunit.sh
+
+failed=0
+
+test_smbclient()
+{
+	name="$1"
+	server="$2"
+	share="$3"
+	cmd="$4"
+	shift
+	shift
+	subunit_start_test "$name"
+	output=$($VALGRIND $SMBCLIENT //$server/$share -c "$cmd" "$@" 2>&1)
+	status=$?
+	if [ x$status = x0 ]; then
+		subunit_pass_test "$name"
+	else
+		echo "$output" | subunit_fail_test "$name"
+	fi
+	return $status
+}
+
+cd "$SELFTEST_TMPDIR" || exit 1
+
+# Create the smbclient communication pipes.
+rm -f smbclient-stdin smbclient-stdout smbclient-stderr
+mkfifo smbclient-stdin smbclient-stdout smbclient-stderr
+
+UID_WRAPPER_ROOT=1
+export UID_WRAPPER_ROOT
+
+smbstatus_num_sessions()
+{
+	UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 "$SMBSTATUS" "$CONF" --json | jq -M '.sessions | length'
+}
+
+testit_grep "step1: smbstatus 0 sessions" '^0$' smbstatus_num_sessions || failed=$(expr $failed + 1)
+
+test_smbclient "smbclient against node0[${NODE0}]" "${NODE0}" "${SHARE}" "ls" -U"${DC_USERNAME}"%"${DC_PASSWORD}" \
+	--option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4" \
+	|| failed=$(expr $failed + 1)
+
+testit_grep "step2: smbstatus 0 sessions" '^0$' smbstatus_num_sessions || failed=$(expr $failed + 1)
+
+CLI_FORCE_INTERACTIVE=1
+export CLI_FORCE_INTERACTIVE
+
+testit "start backgroup smbclient against node0[${NODE0}]" true || failed=$(expr $failed + 1)
+
+# Connect a first time
+${SMBCLIENT} //"${NODE0}"/"${SHARE}" -U"${DC_USERNAME}"%"${DC_PASSWORD}" \
+	--option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4" \
+	<smbclient-stdin >smbclient-stdout 2>smbclient-stderr &
+CLIENT_PID=$!
+
+exec 100>smbclient-stdin 101<smbclient-stdout 102<smbclient-stderr
+
+testit "sleep 1 second" true || failed=$(expr $failed + 1)
+sleep 1
+
+testit_grep "step3: smbstatus 1 session" '^1$' smbstatus_num_sessions || failed=$(expr $failed + 1)
+
+# Connect a second time
+unset CLI_FORCE_INTERACTIVE
+test_smbclient "smbclient against node1[${NODE1}]" "${NODE1}" "${SHARE}" "ls" -U"${DC_USERNAME}"%"${DC_PASSWORD}" \
+	--option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4" \
+	|| failed=$(expr $failed + 1)
+
+kill $CLIENT_PID
+rm -f smbclient-stdin smbclient-stdout smbclient-stderr
+
+testit_grep "step24: smbstatus 0 sessions" '^0$' smbstatus_num_sessions || failed=$(expr $failed + 1)
+
+testok "$0" "$failed"
diff --git a/source3/script/tests/test_smbXsrv_client_dead_rec.sh b/source3/script/tests/test_smbXsrv_client_dead_rec.sh
index a29350878bd..0a287370944 100755
--- a/source3/script/tests/test_smbXsrv_client_dead_rec.sh
+++ b/source3/script/tests/test_smbXsrv_client_dead_rec.sh
@@ -62,7 +62,7 @@ ${SMBCLIENT} //"${SERVER}"/"${SHARE}" -U"${USER}"%"${PASSWORD}" \
 	--option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4" \
 	-c exit
 
-rm -f smbclient-stdin smbclient-stdout aio_outstanding_testfile
+rm -f smbclient-stdin smbclient-stdout smbclient-stderr
 
 #
 # Ensure the panic count didn't change.
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 3dc3105c057..4b192cf4ad5 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -1419,6 +1419,13 @@ plantestsuite("samba3.blackbox.smbXsrv_client_dead_rec", "fileserver:local",
                '$SERVER_IP',
                "tmp"])
 
+plantestsuite("samba3.blackbox.smbXsrv_client_cross_node", "clusteredmember:local",
+              [os.path.join(samba3srcdir,
+                            "script/tests/test_smbXsrv_client_cross_node.sh"),
+               configuration,
+               'ctdb0', 'ctdb1',
+               "tmp"])
+
 env = 'fileserver'
 plantestsuite("samba3.blackbox.virus_scanner", "%s:local" % (env),
               [os.path.join(samba3srcdir,
diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c
index 079ca80ad12..d7a6fa35bf0 100644
--- a/source3/smbd/smbXsrv_client.c
+++ b/source3/smbd/smbXsrv_client.c
@@ -346,6 +346,55 @@ static NTSTATUS smb2srv_client_connection_pass(struct smbd_smb2_request *smb2req
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS smb2srv_client_connection_drop(struct smbd_smb2_request *smb2req,
+					       struct smbXsrv_client_global0 *global)
+{
+	DATA_BLOB blob;
+	enum ndr_err_code ndr_err;
+	NTSTATUS status;
+	struct smbXsrv_connection_drop0 drop_info0;
+	struct smbXsrv_connection_dropB drop_blob;
+	struct iovec iov;
+
+	drop_info0 = (struct smbXsrv_connection_drop0) {
+		.client_guid = global->client_guid,
+		.src_server_id = smb2req->xconn->client->global->server_id,
+		.xconn_connect_time = smb2req->xconn->client->global->initial_connect_time,
+		.dst_server_id = global->server_id,
+		.client_connect_time = global->initial_connect_time,
+	};
+
+	ZERO_STRUCT(drop_blob);
+	drop_blob.version = smbXsrv_version_global_current();
+	drop_blob.info.info0 = &drop_info0;
+
+	if (DEBUGLVL(DBGLVL_DEBUG)) {
+		NDR_PRINT_DEBUG(smbXsrv_connection_dropB, &drop_blob);
+	}
+
+	ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &drop_blob,
+			(ndr_push_flags_fn_t)ndr_push_smbXsrv_connection_dropB);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	iov.iov_base = blob.data;
+	iov.iov_len = blob.length;
+
+	status = messaging_send_iov(smb2req->xconn->client->msg_ctx,
+				    global->server_id,
+				    MSG_SMBXSRV_CONNECTION_DROP,
+				    &iov, 1,
+				    NULL, 0);
+	data_blob_free(&blob);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
 static NTSTATUS smbXsrv_client_global_store(struct smbXsrv_client_global0 *global)
 {
 	struct smbXsrv_client_globalB global_blob;
@@ -552,15 +601,17 @@ static void smb2srv_client_mc_negprot_next(struct tevent_req *req)
 		return;
 	}
 
-	subreq = messaging_filtered_read_send(state,
-					      state->ev,
-					      client->msg_ctx,
-					      smb2srv_client_mc_negprot_filter,
-					      NULL);
-	if (tevent_req_nomem(subreq, req)) {
-		return;
+	if (procid_is_local(&global->server_id)) {
+		subreq = messaging_filtered_read_send(state,
+						      state->ev,
+						      client->msg_ctx,
+						      smb2srv_client_mc_negprot_filter,
+						      NULL);
+		if (tevent_req_nomem(subreq, req)) {
+			return;
+		}
+		tevent_req_set_callback(subreq, smb2srv_client_mc_negprot_done, req);
 	}
-	tevent_req_set_callback(subreq, smb2srv_client_mc_negprot_done, req);
 
 	/*
 	 * If the record changed, but we are not happy with the change yet,
@@ -593,11 +644,20 @@ static void smb2srv_client_mc_negprot_next(struct tevent_req *req)
 	}
 	tevent_req_set_callback(subreq, smb2srv_client_mc_negprot_watched, req);
 
-	status = smb2srv_client_connection_pass(state->smb2req,
-						global);
-	TALLOC_FREE(global);
-	if (tevent_req_nterror(req, status)) {
-		return;
+	if (procid_is_local(&global->server_id)) {
+		status = smb2srv_client_connection_pass(state->smb2req,
+							global);
+		TALLOC_FREE(global);
+		if (tevent_req_nterror(req, status)) {
+			return;
+		}
+	} else {
+		status = smb2srv_client_connection_drop(state->smb2req,
+							global);
+		TALLOC_FREE(global);
+		if (tevent_req_nterror(req, status)) {
+			return;
+		}
 	}
 
 	TALLOC_FREE(state->db_rec);
@@ -614,10 +674,6 @@ static bool smb2srv_client_mc_negprot_filter(struct messaging_rec *rec, void *pr
 		return false;
 	}
 
-	if (rec->buf.length < SMB2_HDR_BODY) {
-		return false;
-	}
-
 	return true;
 }
 
@@ -707,6 +763,14 @@ static void smb2srv_client_mc_negprot_done(struct tevent_req *subreq)
 		return;
 	}
 
+	if (passed_info0->negotiate_request.length != 0) {
+		DBG_ERR("negotiate_request.length[%zu]\n",
+			passed_info0->negotiate_request.length);
+		NDR_PRINT_DEBUG(smbXsrv_connection_passB, &passed_blob);
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+
 	tevent_req_nterror(req, NT_STATUS_MESSAGE_RETRIEVED);
 }
 
@@ -788,6 +852,8 @@ static int smbXsrv_client_destructor(struct smbXsrv_client *client)
 
 static bool smbXsrv_client_connection_pass_filter(struct messaging_rec *rec, void *private_data);
 static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq);
+static bool smbXsrv_client_connection_drop_filter(struct messaging_rec *rec, void *private_data);
+static void smbXsrv_client_connection_drop_loop(struct tevent_req *subreq);
 
 NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 			       struct tevent_context *ev_ctx,
@@ -870,6 +936,18 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 	tevent_req_set_callback(subreq, smbXsrv_client_connection_pass_loop, client);
 	client->connection_pass_subreq = subreq;
 
+	subreq = messaging_filtered_read_send(client,
+					client->raw_ev_ctx,
+					client->msg_ctx,
+					smbXsrv_client_connection_drop_filter,
+					client);
+	if (subreq == NULL) {
+		TALLOC_FREE(client);
+		return NT_STATUS_NO_MEMORY;
+	}
+	tevent_req_set_callback(subreq, smbXsrv_client_connection_drop_loop, client);
+	client->connection_drop_subreq = subreq;
+
 	*_client = client;
 	return NT_STATUS_OK;
 }
@@ -931,12 +1009,6 @@ static bool smbXsrv_client_connection_pass_filter(struct messaging_rec *rec, voi
 		return false;
 	}
 
-	if (rec->buf.length < SMB2_HDR_BODY) {
-		return false;
-	}
-
-	/* TODO: verify client_guid...? */
-
 	return true;
 }
 
@@ -1029,6 +1101,15 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
 		goto next;
 	}
 
+	if (pass_info0->negotiate_request.length < SMB2_HDR_BODY) {
+		DBG_WARNING("negotiate_request.length[%zu]\n",
+			    pass_info0->negotiate_request.length);
+		if (DEBUGLVL(DBGLVL_WARNING)) {
+			NDR_PRINT_DEBUG(smbXsrv_connection_passB, &pass_blob);
+		}
+		goto next;
+	}
+
 	status = smb2srv_client_connection_passed(client, pass_info0);
 	if (!NT_STATUS_IS_OK(status)) {
 		const char *r = "smb2srv_client_connection_passed() failed";
@@ -1092,6 +1173,144 @@ next:
 	client->connection_pass_subreq = subreq;
 }
 
+static bool smbXsrv_client_connection_drop_filter(struct messaging_rec *rec, void *private_data)
+{
+	if (rec->msg_type != MSG_SMBXSRV_CONNECTION_DROP) {
+		return false;
+	}
+
+	if (rec->num_fds != 0) {
+		return false;
+	}
+
+	return true;
+}
+
+static void smbXsrv_client_connection_drop_loop(struct tevent_req *subreq)
+{
+	struct smbXsrv_client *client =
+		tevent_req_callback_data(subreq,
+		struct smbXsrv_client);
+	int ret;
+	struct messaging_rec *rec = NULL;
+	struct smbXsrv_connection_dropB drop_blob;
+	enum ndr_err_code ndr_err;
+	struct smbXsrv_connection_drop0 *drop_info0 = NULL;
+	struct server_id_buf src_server_id_buf = {};
+	NTSTATUS status;
+
+	client->connection_drop_subreq = NULL;
+
+	ret = messaging_filtered_read_recv(subreq, talloc_tos(), &rec);
+	TALLOC_FREE(subreq);
+	if (ret != 0) {
+		goto next;
+	}
+
+	if (rec->num_fds != 0) {
+		DBG_ERR("MSG_SMBXSRV_CONNECTION_DROP: num_fds[%u]\n",
+			rec->num_fds);
+		goto next;
+	}
+
+	ndr_err = ndr_pull_struct_blob(&rec->buf, rec, &drop_blob,
+			(ndr_pull_flags_fn_t)ndr_pull_smbXsrv_connection_dropB);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		DBG_WARNING("ndr_pull_struct_blob - %s\n", nt_errstr(status));
+		goto next;
+	}
+
+	if (DEBUGLVL(DBGLVL_DEBUG)) {
+		NDR_PRINT_DEBUG(smbXsrv_connection_dropB, &drop_blob);
+	}
+
+	if (drop_blob.version != SMBXSRV_VERSION_0) {
+		DBG_ERR("ignore invalid version %u\n", drop_blob.version);
+		NDR_PRINT_DEBUG(smbXsrv_connection_dropB, &drop_blob);
+		goto next;
+	}
+
+	drop_info0 = drop_blob.info.info0;
+	if (drop_info0 == NULL) {
+		DBG_ERR("ignore NULL info %u\n", drop_blob.version);
+		NDR_PRINT_DEBUG(smbXsrv_connection_dropB, &drop_blob);
+		goto next;
+	}
+
+	if (!GUID_equal(&client->global->client_guid, &drop_info0->client_guid))
+	{
+		struct GUID_txt_buf buf1, buf2;
+
+		DBG_WARNING("client's client_guid [%s] != droped guid [%s]\n",
+			    GUID_buf_string(&client->global->client_guid,
+					    &buf1),
+			    GUID_buf_string(&drop_info0->client_guid,
+					    &buf2));
+		if (DEBUGLVL(DBGLVL_WARNING)) {
+			NDR_PRINT_DEBUG(smbXsrv_connection_dropB, &drop_blob);
+		}
+		goto next;
+	}
+
+	if (client->global->initial_connect_time !=
+	    drop_info0->client_connect_time)
+	{
+		DBG_WARNING("client's initial connect time [%s] (%llu) != "
+			"droped initial connect time [%s] (%llu)\n",
+			nt_time_string(talloc_tos(),
+				       client->global->initial_connect_time),
+			(unsigned long long)client->global->initial_connect_time,
+			nt_time_string(talloc_tos(),
+				       drop_info0->client_connect_time),
+			(unsigned long long)drop_info0->client_connect_time);
+		if (DEBUGLVL(DBGLVL_WARNING)) {
+			NDR_PRINT_DEBUG(smbXsrv_connection_dropB, &drop_blob);
+		}
+		goto next;
+	}
+
+	/*
+	 * Disconnect all client connections, which means we will tear down all
+	 * sessions, tcons and non-durable opens. At the end we will remove our
+	 * smbXsrv_client_global.tdb record, which will wake up the watcher on
+	 * the other node in order to let it take over the client.
+	 *
+	 * The client will have to reopen all sessions, tcons and durable opens.
+	 */
+	smbd_server_disconnect_client(client,
+		server_id_str_buf(drop_info0->src_server_id, &src_server_id_buf));
+	return;
+
+next:
+	if (rec != NULL) {


-- 
Samba Shared Repository



More information about the samba-cvs mailing list