[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