[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Sat Mar 6 03:31:01 UTC 2021


The branch, master has been updated
       via  b145434f24f smbXsrv_client: move the connection passing to smb2srv_client_mc_negprot_send/recv
       via  f1f5c36581a smbd: make sure that xconn is alive for the lifetime of smbXsrv_connection_shutdown_send/recv
       via  2a0626c32ae s4:torture/smb2: add smb2.lease.timeout-disconnect test
       via  638c4435a0e smbXsrv_session: set session->db_rec = NULL after session->db_rec = local_rec
       via  253a4de82bd smbXsrv_tcon: explicitly set tcon->db_rec = NULL after tcon->db_rec = local_rec
       via  2cf1628419f s4:torture/smb2: add a smb2.session.two_logoff test
       via  106121a91b5 smbd: introduce a smbXsrv_connection_destructor()
       via  c9ff08649f3 smbd: improve smbXsrv_connection_dbg() for debugging multi-channel problems
       via  c784f8c9aba selftest: enable 'server multi channel support = yes'
       via  a200769950d s4:torture/smb2: use %t (timestamp) instead of %R for lease.dynamic_share test
       via  18818dba00d smbd: let smbd_request_guid() use smb1req->xconn->channel_id
       via  927346d93e4 docs-xml: clarify "smb2 disable lock sequence checking" section
       via  e0426187eb3 dsdb: Fix CID 1473454: Null pointer dereferences
       via  84be21565c8 dsdb: Fix CID 1473453: Null pointer dereferences
       via  7d2faa2714f librpc: Lower dcesrv_call_dispatch_local() errors from DBG_ERR to DBG_INFO
       via  5fe7536145d winbind: Remove noisy error message in wb_open_internal_pipe()
      from  654c18a244f g_lock: Fix uninitalized variable reads

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


- Log -----------------------------------------------------------------
commit b145434f24f35a3d43d49980ef10bf59aae9243d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 6 17:27:05 2020 +0200

    smbXsrv_client: move the connection passing to smb2srv_client_mc_negprot_send/recv
    
    We need a full request/response pair in order to avoid races in
    the multichannel connection passing.
    
    smb2srv_client_mc_negprot_send/recv locks the
    db record for the given client_guid.
    
    If there's no entry found, we add ourself and
    return NT_STATUS_OK.
    
    If there's an existing process for that client guid
    we start messaging_filtered_read_send()
    dbwrap_watched_watch_send() before calling
    smb2srv_client_connection_pass().
    
    Then we release the lock and wait for either
    MSG_SMBXSRV_CONNECTION_PASSED to arrive or
    retry if dbwrap_watched_watch_recv signaled
    a change in the database.
    
    If we got MSG_SMBXSRV_CONNECTION_PASSED we'll
    return NT_STATUS_MESSAGE_RETRIEVED in order to
    signal that the other process will take care of
    the connection and we terminate the current process.
    
    All that is done completely async, which means that
    the IDLE_CLOSED_TIMEOUT (60 seconds) may trigger
    deadtime_fn(), which will send itself a MSG_SHUTDOWN.
    So the process that accepted the tcp connection
    exists if there was no MSG_SMBXSRV_CONNECTION_PASSED
    within 60 seconds.
    
    However the fd may still exists in the kernel (and
    the new connection may still be handed to the other
    process. If that process somehow exists before
    there's no way to prevent a connection termination
    for the client.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14433
    
    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): Sat Mar  6 03:30:06 UTC 2021 on sn-devel-184

commit f1f5c36581a942bcccd63ede4b023fdb1a1d3ed4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 13:07:20 2020 +0200

    smbd: make sure that xconn is alive for the lifetime of smbXsrv_connection_shutdown_send/recv
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14533
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2a0626c32ae2803cb6c478717c34bf30231dc3dc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 04:58:22 2020 +0200

    s4:torture/smb2: add smb2.lease.timeout-disconnect test
    
    This reproduces a problem that is triggered when
    smbd_server_connection_terminate() is called recursively.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14533
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 638c4435a0eeb110719dd2e799f2a12758667326
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 06:00:28 2020 +0200

    smbXsrv_session: set session->db_rec = NULL after session->db_rec = local_rec
    
    This actually fixes crashes due to stale pointers.
    
    With multi-channel and with 2 (or more) connections,
    we'll call smbXsrv_session_disconnect_xconn() when a connection
    gets disconnected, but we'll leave smbXsrv_client and all other
    connections in place.
    
    However smbXsrv_session_disconnect_xconn_callback() left
    a stale session->db_rec pointer in place, which means
    a following smbXsrv_session_logoff() will call
    dbwrap_record_delete(local_rec) on a stale pointer.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14532
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 253a4de82bd4e44586572b71e06762c3f6dbd795
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 11:24:46 2020 +0200

    smbXsrv_tcon: explicitly set tcon->db_rec = NULL after tcon->db_rec = local_rec
    
    There's no know problem that we fix for the
    smbXsrv_tcon_disconnect_all_callback() case,
    but it might prevent future problems.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14532
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2cf1628419f5035107d1be6d7ab1bf6533bad7a2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 13:49:27 2020 +0200

    s4:torture/smb2: add a smb2.session.two_logoff test
    
    This reproduces a bug where two SMB2_LOGOFF messages kill the whole
    client smbd when multi-channel is used, instead of just removing the
    logical session.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14532
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 106121a91b5108bfcc48f641385cd99e7dab7006
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 13:13:22 2020 +0200

    smbd: introduce a smbXsrv_connection_destructor()
    
    For now it only prints a debug message, but that's already very
    useful for multi-channel debugging.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14534
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit c9ff08649f3c9f8bb5896a0c0a70fbcdf856c9d5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 23 13:13:01 2020 +0200

    smbd: improve smbXsrv_connection_dbg() for debugging multi-channel problems
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14534
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit c784f8c9aba185bb803c23b166374bdce9550203
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jun 19 12:32:59 2020 +0200

    selftest: enable 'server multi channel support = yes'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14534
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a200769950dbf57f5d493e86b64ec1db964f00c7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 9 16:54:18 2021 +0100

    s4:torture/smb2: use %t (timestamp) instead of %R for lease.dynamic_share test
    
    This test should be independent of the protocol in order to be
    independent of multi-channel support of the server.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14534
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 18818dba00db4d9cfccf58f86ef0764145a654da
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jul 28 12:11:38 2020 +0200

    smbd: let smbd_request_guid() use smb1req->xconn->channel_id
    
    The unique identifier of a channel/connection is the channel_id,
    the pointer of 'xconn' can be reused.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14534
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 927346d93e4d241c588a22405038b8fa2ccc261d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 27 04:50:15 2020 +0200

    docs-xml: clarify "smb2 disable lock sequence checking" section
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14534
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e0426187eb3b5ef319c4ac8c5cf7442abbc0b0b5
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Mar 2 11:30:44 2021 +0100

    dsdb: Fix CID 1473454: Null pointer dereferences
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 84be21565c892289e133895da5999085f3641a17
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Mar 2 11:27:07 2021 +0100

    dsdb: Fix CID 1473453: Null pointer dereferences
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7d2faa2714f83998673bf2fb874ce8202a09879b
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Mon Mar 1 17:26:24 2021 +0100

    librpc: Lower dcesrv_call_dispatch_local() errors from DBG_ERR to DBG_INFO
    
    Before merging the s3 and s4 RPC servers the rpcint_dispatch function
    was not logging any error.
    
    This commit lowers from DBG_ERR to DBG_INFO the importance of error
    messages when dispatching local RPC calls. There are some situations
    where RPC functions return RPC faults and this is not a fatal condition.
    One example is _lsa_QueryInfoPolicy2.
    
    This change prevents a noisy error logged when winbindd tries to connect to
    its primary domain in the nt4_member and ad_member test environments:
    
    [2021/03/01 16:49:38.486111,  0, pid=12456] ../../librpc/rpc/dcesrv_core.c:2990(dcesrv_call_dispatch_local)
      dcesrv_call_dispatch_local: DCE/RPC fault in call lsarpc:2E - DCERPC_NCA_S_OP_RNG_ERROR
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5fe7536145dc2c29ec71f6077188d74f4e08abd6
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Mon Mar 1 15:56:06 2021 +0100

    winbind: Remove noisy error message in wb_open_internal_pipe()
    
    Before merging the s4 and s3 RPC servers the make_internal_rpc_pipe_p()
    function did not fail when the requested interface was not registered in
    the calling process because it did not check the return value of
    rpc_srv_get_pipe_cmds(). If the interface was not registed, the pointer
    to the interface functions was NULL and later, when dispatching a call,
    rpcint_dispatch() returned NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE in this
    case.
    
    After merging the RPC servers, the rpc_pipe_open_internal() function
    will return NT_STATUS_RPC_INTERFACE_NOT_FOUND if the interface is not
    registered in the calling process. This causes a noisy error message in
    winbind when it tries to open the dssetup pipe to the primary domain and
    it is not an AD domain.
    
    The callers of wb_open_internal_pipe() when connecting to the domain
    already logs the error at level greather or equal to five. This commit
    moves the dupplicated and noisy error message at level zero from
    wb_open_internal_pipe() to its callers outside winbindd_cm.c.
    
    This error can be seen in winbindd logs of ad_member and nt4_member test
    environments.
    
    [2021/03/01 16:49:38.486004,  0, pid=12456] ../../source3/winbindd/winbindd_cm.c:1893(wb_open_internal_pipe)
      open_internal_pipe: Could not connect to dssetup pipe: NT_STATUS_RPC_INTERFACE_NOT_FOUND
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 .../smb2_disable_lock_sequence_checking.xml        |   2 +-
 librpc/idl/messaging.idl                           |   1 +
 librpc/rpc/dcesrv_core.c                           |  32 +-
 selftest/knownfail                                 |   4 -
 selftest/knownfail.d/multichannel                  |   7 +
 selftest/target/Samba3.pm                          |  10 +-
 selftest/target/Samba4.pm                          |   4 +
 source3/librpc/idl/smbXsrv.idl                     |   8 +-
 source3/smbd/globals.c                             |   2 +-
 source3/smbd/globals.h                             |  12 +-
 source3/smbd/process.c                             |  20 +-
 source3/smbd/smb2_negprot.c                        | 110 +++--
 source3/smbd/smb2_server.c                         |  31 ++
 source3/smbd/smbXsrv_client.c                      | 471 ++++++++++++++++-----
 source3/smbd/smbXsrv_session.c                     |  10 +-
 source3/smbd/smbXsrv_tcon.c                        |   1 +
 source3/winbindd/winbindd_cm.c                     |   2 -
 source3/winbindd/winbindd_samr.c                   |   4 +
 source4/dsdb/samdb/ldb_modules/operational.c       |   4 +
 source4/dsdb/samdb/ldb_modules/rootdse.c           |  10 +-
 source4/torture/smb2/lease.c                       | 240 ++++++++---
 source4/torture/smb2/session.c                     |  43 ++
 22 files changed, 802 insertions(+), 226 deletions(-)
 create mode 100644 selftest/knownfail.d/multichannel


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/protocol/smb2_disable_lock_sequence_checking.xml b/docs-xml/smbdotconf/protocol/smb2_disable_lock_sequence_checking.xml
index 9ca7187fb51..3a33b8b1420 100644
--- a/docs-xml/smbdotconf/protocol/smb2_disable_lock_sequence_checking.xml
+++ b/docs-xml/smbdotconf/protocol/smb2_disable_lock_sequence_checking.xml
@@ -22,7 +22,7 @@
     in [MS-SMB2].</para>
 
     <para>By default Samba behaves according to the specification
-    and sends smb2 oplock break notification retries.</para>
+    and implements lock sequence checking when multi-channel is used.</para>
 
     <para>Warning: Only enable this option if existing clients can't
     handle lock sequence checking for handles without Open.IsResilient and Open.IsPersistent.
diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index 8160c76149c..06a72520f8b 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -136,6 +136,7 @@ interface messaging
 		/* smbXsrv messages */
 		MSG_SMBXSRV_SESSION_CLOSE	= 0x0600,
 		MSG_SMBXSRV_CONNECTION_PASS	= 0x0601,
+		MSG_SMBXSRV_CONNECTION_PASSED	= 0x0602,
 
 		/* source4 and NTVFS smb server messages */
 		MSG_BRL_RETRY                   = 0x0700,
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
index a51467c87c0..7a20ffe71a0 100644
--- a/librpc/rpc/dcesrv_core.c
+++ b/librpc/rpc/dcesrv_core.c
@@ -2978,19 +2978,19 @@ _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
 	/* unravel the NDR for the packet */
 	status = call->context->iface->ndr_pull(call, call, pull, &call->r);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n",
-			call->context->iface->name,
-			call->pkt.u.request.opnum,
-			dcerpc_errstr(call, call->fault_code));
+		DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
+			 call->context->iface->name,
+			 call->pkt.u.request.opnum,
+			 dcerpc_errstr(call, call->fault_code));
 		return dcerpc_fault_to_nt_status(call->fault_code);
 	}
 
 	status = call->context->iface->local(call, call, call->r);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n",
-			call->context->iface->name,
-			call->pkt.u.request.opnum,
-			dcerpc_errstr(call, call->fault_code));
+		DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
+			 call->context->iface->name,
+			 call->pkt.u.request.opnum,
+			 dcerpc_errstr(call, call->fault_code));
 		return dcerpc_fault_to_nt_status(call->fault_code);
 	}
 
@@ -3000,10 +3000,10 @@ _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
 	/* call the reply function */
 	status = call->context->iface->reply(call, call, call->r);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n",
-			call->context->iface->name,
-			call->pkt.u.request.opnum,
-			dcerpc_errstr(call, call->fault_code));
+		DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
+			 call->context->iface->name,
+			 call->pkt.u.request.opnum,
+			 dcerpc_errstr(call, call->fault_code));
 		return dcerpc_fault_to_nt_status(call->fault_code);
 	}
 
@@ -3016,10 +3016,10 @@ _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
 
 	status = call->context->iface->ndr_push(call, call, push, call->r);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n",
-			call->context->iface->name,
-			call->pkt.u.request.opnum,
-			dcerpc_errstr(call, call->fault_code));
+		DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
+			 call->context->iface->name,
+			 call->pkt.u.request.opnum,
+			 dcerpc_errstr(call, call->fault_code));
 		return dcerpc_fault_to_nt_status(call->fault_code);
 	}
 
diff --git a/selftest/knownfail b/selftest/knownfail
index 6c005d1f4de..6a760d6c6e0 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -213,14 +213,10 @@
 ^samba3.smb2.session.*reauth5 # some special anonymous checks?
 ^samba3.smb2.compound.interim2 # wrong return code (STATUS_CANCELLED)
 ^samba3.smb2.compound.aio.interim2 # wrong return code (STATUS_CANCELLED)
-^samba3.smb2.replay.replay3 # This requires multi-chanel
-^samba3.smb2.replay.replay4 # This requires multi-chanel
-^samba3.smb2.lock.replay_smb3_specification_multi # This requires multi-chanel
 ^samba3.smb2.lock.replay_smb3_specification_durable\(nt4_dc\) # Requires durable handles
 ^samba3.smb2.lock.*replay_broken_windows # This tests the windows behaviour
 ^samba3.smb2.lease.statopen3
 ^samba3.smb2.lease.unlink # we currently do not downgrade RH lease to R after unlink
-^samba3.smb2.multichannel
 ^samba4.smb2.ioctl.compress_notsup.*\(ad_dc_ntvfs\)
 ^samba3.raw.session.*reauth2 # maybe fix this?
 ^samba3.rpc.lsa.secrets.seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY
diff --git a/selftest/knownfail.d/multichannel b/selftest/knownfail.d/multichannel
new file mode 100644
index 00000000000..6c91b552c0d
--- /dev/null
+++ b/selftest/knownfail.d/multichannel
@@ -0,0 +1,7 @@
+^samba3.smb2.multichannel.oplocks.test2.nt4_dc              # expects windows behavior => smb2 disable oplock break retry = yes
+^samba3.smb2.multichannel.oplocks.test3_windows.nt4_dc      # expects windows behavior => smb2 disable oplock break retry = yes
+^samba3.smb2.multichannel.oplocks.test3_specification.ad_dc # expects samba (MS-SMB2) behavior
+^samba3.smb2.multichannel.leases.test1.ad_dc                # requires lease support
+^samba3.smb2.multichannel.leases.test2.ad_dc                # requires lease support
+^samba3.smb2.multichannel.leases.test3.ad_dc                # requires lease support
+^samba3.smb2.multichannel.leases.test4.ad_dc                # requires lease support
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index b0910433940..a0c43aa842e 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -2075,12 +2075,9 @@ sub provision($$)
 	my $badnames_shrdir="$shrdir/badnames";
 	push(@dirs,$badnames_shrdir);
 
-	my $lease1_shrdir="$shrdir/SMB2_10";
+	my $lease1_shrdir="$shrdir/dynamic";
 	push(@dirs,$lease1_shrdir);
 
-	my $lease2_shrdir="$shrdir/SMB3_00";
-	push(@dirs,$lease2_shrdir);
-
 	my $manglenames_shrdir="$shrdir/manglenames";
 	push(@dirs,$manglenames_shrdir);
 
@@ -2287,6 +2284,8 @@ sub provision($$)
 	client min protocol = SMB2_02
 	server min protocol = SMB2_02
 
+	server multi channel support = yes
+
 	workgroup = $domain
 
 	private dir = $privatedir
@@ -2652,8 +2651,9 @@ sub provision($$)
 	guest ok = yes
 
 [dynamic_share]
-	path = $shrdir/%R
+	path = $shrdir/dynamic/%t
 	guest ok = yes
+	root preexec = mkdir %P
 
 [widelinks_share]
 	path = $widelinks_shrdir
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index dff9d042be9..61e9eb61422 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -763,6 +763,8 @@ sub provision_raw_step1($$)
 	tls crlfile = ${crlfile}
 	tls verify peer = no_check
 	panic action = $RealBin/gdb_backtrace \%d
+	smbd:suicide mode = yes
+	smbd:FSCTL_SMBTORTURE = yes
 	wins support = yes
 	server role = $ctx->{server_role}
 	server services = +echo $services
@@ -1905,6 +1907,8 @@ sub provision_ad_dc($$$$$$$)
 	kernel oplocks = no
 	kernel change notify = no
 	smb2 leases = no
+	smb2 disable oplock break retry = yes
+	server multi channel support = yes
 
 	logging = file
 	printing = bsd
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 78fc3644d2f..09e3ca351f3 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -167,11 +167,15 @@ interface smbXsrv
 
 	/*
 	 * smbXsrv_connection_pass is used in the MSG_SMBXSRV_CONNECTION_PASS
-	 * message
+	 * message and echo'ed as MSG_SMBXSRV_CONNECTION_PASSED message with
+	 * negotiate_request.length = 0.
 	 */
 	typedef struct {
-		NTTIME					initial_connect_time;
 		GUID					client_guid;
+		server_id				src_server_id;
+		NTTIME					xconn_connect_time;
+		server_id				dst_server_id;
+		NTTIME					client_connect_time;
 		DATA_BLOB 				negotiate_request;
 	} smbXsrv_connection_pass0;
 
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index c0fafecd2eb..4d4553649c0 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -120,7 +120,7 @@ struct GUID smbd_request_guid(struct smb_request *smb1req, uint16_t idx)
 		v.time_mid = (uint16_t)(uintptr_t)smb1req->vwv;
 	}
 
-	SBVAL((uint8_t *)&v, 8, (uintptr_t)smb1req->xconn);
+	SBVAL((uint8_t *)&v, 8, smb1req->xconn->channel_id);
 
 	return v;
 }
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 4685b6971d3..d1a2c6204ba 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -367,6 +367,7 @@ struct smbXsrv_connection {
 
 	struct {
 		NTSTATUS status;
+		bool terminating;
 		int sock;
 		struct tevent_fd *fde;
 
@@ -549,14 +550,11 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
 			       struct messaging_context *msg_ctx,
 			       NTTIME now,
 			       struct smbXsrv_client **_client);
-NTSTATUS smbXsrv_client_update(struct smbXsrv_client *client);
 NTSTATUS smbXsrv_client_remove(struct smbXsrv_client *client);
-NTSTATUS smb2srv_client_lookup_global(struct smbXsrv_client *client,
-				      struct GUID client_guid,
-				      TALLOC_CTX *mem_ctx,
-				      struct smbXsrv_client_global0 **_pass);
-NTSTATUS smb2srv_client_connection_pass(struct smbd_smb2_request *smb2req,
-					struct smbXsrv_client_global0 *global);
+struct tevent_req *smb2srv_client_mc_negprot_send(TALLOC_CTX *mem_ctx,
+						  struct tevent_context *ev,
+						  struct smbd_smb2_request *smb2req);
+NTSTATUS smb2srv_client_mc_negprot_recv(struct tevent_req *req);
 
 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
 					enum protocol_types protocol);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 9e861554fa7..03409742752 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3745,19 +3745,32 @@ static void smbd_tevent_trace_callback(enum tevent_trace_point point,
 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
 {
 	const char *ret;
-
+	char *addr;
 	/*
 	 * TODO: this can be improved later
 	 * maybe including the client guid or more
 	 */
-	ret = tsocket_address_string(xconn->remote_address, talloc_tos());
-	if (ret == NULL) {
+	addr = tsocket_address_string(xconn->remote_address, talloc_tos());
+	if (addr == NULL) {
 		return "<tsocket_address_string() failed>";
 	}
 
+	ret = talloc_asprintf(talloc_tos(), "ptr=%p,id=%llu,addr=%s",
+			      xconn, (unsigned long long)xconn->channel_id, addr);
+	TALLOC_FREE(addr);
+	if (ret == NULL) {
+		return "<talloc_asprintf() failed>";
+	}
+
 	return ret;
 }
 
+static int smbXsrv_connection_destructor(struct smbXsrv_connection *xconn)
+{
+	DBG_DEBUG("xconn[%s]\n", smbXsrv_connection_dbg(xconn));
+	return 0;
+}
+
 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 			     NTTIME now, struct smbXsrv_connection **_xconn)
 {
@@ -3788,6 +3801,7 @@ NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 		TALLOC_FREE(frame);
 		return NT_STATUS_NO_MEMORY;
 	}
+	talloc_set_destructor(xconn, smbXsrv_connection_destructor);
 	talloc_steal(frame, xconn);
 	xconn->client = client;
 	xconn->connect_time = now;
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 99303f1b07b..0cd093d1eba 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -127,10 +127,19 @@ enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
 	return PROTOCOL_NONE;
 }
 
+struct smbd_smb2_request_process_negprot_state {
+	struct smbd_smb2_request *req;
+	DATA_BLOB outbody;
+	DATA_BLOB outdyn;
+};
+
+static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq);
+
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 {
+	struct smbd_smb2_request_process_negprot_state *state = NULL;
 	struct smbXsrv_connection *xconn = req->xconn;
-	struct smbXsrv_client_global0 *global0 = NULL;
+	struct tevent_req *subreq = NULL;
 	NTSTATUS status;
 	const uint8_t *inbody;
 	const uint8_t *indyn = NULL;
@@ -675,38 +684,83 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 		return smbd_smb2_request_done(req, outbody, &outdyn);
 	}
 
-	status = smb2srv_client_lookup_global(xconn->client,
-					      xconn->smb2.client.guid,
-					      req, &global0);
-	/*
-	 * TODO: check for races...
-	 */
-	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECTID_NOT_FOUND)) {
+	state = talloc_zero(req, struct smbd_smb2_request_process_negprot_state);
+	if (state == NULL) {
+		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+	}
+	*state = (struct smbd_smb2_request_process_negprot_state) {
+		.req = req,
+		.outbody = outbody,
+		.outdyn = outdyn,
+	};
+
+	subreq = smb2srv_client_mc_negprot_send(state,
+						req->xconn->client->raw_ev_ctx,
+						req);
+	if (subreq == NULL) {
+		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+	}
+	tevent_req_set_callback(subreq,
+				smbd_smb2_request_process_negprot_mc_done,
+				state);
+	return NT_STATUS_OK;
+}
+
+static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
+{
+	struct smbd_smb2_request_process_negprot_state *state =
+		tevent_req_callback_data(subreq,
+		struct smbd_smb2_request_process_negprot_state);
+	struct smbd_smb2_request *req = state->req;
+	struct smbXsrv_connection *xconn = req->xconn;
+	NTSTATUS status;
+
+	status = smb2srv_client_mc_negprot_recv(subreq);
+	TALLOC_FREE(subreq);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_MESSAGE_RETRIEVED)) {
 		/*
-		 * This stores the new client information in
-		 * smbXsrv_client_global.tdb
+		 * The connection was passed to another process
 		 */
-		xconn->client->global->client_guid =
-			xconn->smb2.client.guid;
-		status = smbXsrv_client_update(xconn->client);
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
+		smbd_server_connection_terminate(xconn,
+						 "passed connection");
+		/*
+		 * smbd_server_connection_terminate() should not return!
+		 */
+		smb_panic(__location__);
+		return;
+	}
+	if (!NT_STATUS_IS_OK(status)) {
+		status = smbd_smb2_request_error(req, status);
+		if (NT_STATUS_IS_OK(status)) {
+			return;
 		}
 
-		xconn->smb2.client.guid_verified = true;
-	} else if (NT_STATUS_IS_OK(status)) {
-		status = smb2srv_client_connection_pass(req,
-							global0);
-		if (!NT_STATUS_IS_OK(status)) {
-			return smbd_smb2_request_error(req, status);
-		}
+		/*
+		 * The connection was passed to another process
+		 */
+		smbd_server_connection_terminate(xconn, nt_errstr(status));
+		/*
+		 * smbd_server_connection_terminate() should not return!
+		 */
+		smb_panic(__location__);
+		return;
+	}
 
-		smbd_server_connection_terminate(xconn,
-						 "passed connection");
-		return NT_STATUS_OBJECTID_EXISTS;
-	} else {
-		return smbd_smb2_request_error(req, status);
+	/*
+	 * We're the first connection...
+	 */
+	status = smbd_smb2_request_done(req, state->outbody, &state->outdyn);
+	if (NT_STATUS_IS_OK(status)) {
+		return;
 	}
 
-	return smbd_smb2_request_done(req, outbody, &outdyn);
+	/*
+	 * The connection was passed to another process
+	 */
+	smbd_server_connection_terminate(xconn, nt_errstr(status));
+	/*
+	 * smbd_server_connection_terminate() should not return!
+	 */
+	smb_panic(__location__);
+	return;
 }
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 1322cf3ba08..bd0eab00606 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1500,6 +1500,7 @@ size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
 
 struct smbXsrv_connection_shutdown_state {
 	struct tevent_queue *wait_queue;
+	struct smbXsrv_connection *xconn;
 };
 
 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
@@ -1520,6 +1521,7 @@ static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
 	 * smbXsrv_connection_disconnect_transport() before.
 	 */
 	SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
+	SMB_ASSERT(xconn->transport.terminating);
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smbXsrv_connection_shutdown_state);
@@ -1527,6 +1529,9 @@ static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+	state->xconn = xconn;
+	tevent_req_defer_callback(req, ev);
+
 	status = smbXsrv_session_disconnect_xconn(xconn);
 	if (tevent_req_nterror(req, status)) {
 		return tevent_req_post(req, ev);
@@ -1590,15 +1595,33 @@ static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
 	struct tevent_req *req =
 		tevent_req_callback_data(subreq,
 		struct tevent_req);
+	struct smbXsrv_connection_shutdown_state *state =
+		tevent_req_data(req,
+		struct smbXsrv_connection_shutdown_state);
+	struct smbXsrv_connection *xconn = state->xconn;
 
 	tevent_queue_wait_recv(subreq);
 	TALLOC_FREE(subreq);
 
 	tevent_req_done(req);
+	/*
+	 * make sure the xconn pointer is still valid,
+	 * it should as we used tevent_req_defer_callback()
+	 */
+	SMB_ASSERT(xconn->transport.terminating);
 }
 
 static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
 {
+	struct smbXsrv_connection_shutdown_state *state =
+		tevent_req_data(req,
+		struct smbXsrv_connection_shutdown_state);
+	struct smbXsrv_connection *xconn = state->xconn;
+	/*
+	 * make sure the xconn pointer is still valid,
+	 * it should as we used tevent_req_defer_callback()
+	 */
+	SMB_ASSERT(xconn->transport.terminating);
 	return tevent_req_simple_recv_ntstatus(req);
 }
 
@@ -1637,6 +1660,14 @@ void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
 
 	num_ok = smbXsrv_client_valid_connections(client);
 
+	if (xconn->transport.terminating) {
+		DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
+			  smbXsrv_connection_dbg(xconn), num_ok,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list