[PATCHES] Retry ping-dc when session expires
Christof Schmitt
cs at samba.org
Fri Dec 19 15:16:32 MST 2014
The call to wbinfo --ping-dc can return an error when the underlying SMB
connection expires. Since the goal of --ping-dc is to test whether the
DC is available, temporary session status changes should not be returned
to the caller.
In a test, i have seen two instances where the call to ping-dc fails:
1) The RPC call LogonControl returns NT_STATUS_IO_DEVICE_ERROR when the session expires:
[2014/12/19 19:21:30.712908, 5, pid=2611671, effective(0, 0), real(0, 0), class=rpc_cli] rpc_client/cli_pipe.c:759(rpc_api_pipe_send)
rpc_api_pipe: host 2k12r2.virtual2.com
[2014/12/19 19:21:30.712966, 5, pid=2611671, effective(0, 0), real(0, 0)] ../libcli/smb/smb2_signing.c:92(smb2_signing_sign_pdu)
signed SMB2 message
[2014/12/19 19:21:30.713688, 5, pid=2611671, effective(0, 0), real(0, 0)] ../libcli/smb/smb2_signing.c:92(smb2_signing_sign_pdu)
signed SMB2 message
[2014/12/19 19:21:30.714281, 5, pid=2611671, effective(0, 0), real(0, 0), class=rpc_cli] rpc_client/cli_pipe.c:821(rpc_api_pipe_trans_done)
cli_api_pipe failed: NT_STATUS_IO_DEVICE_ERROR
[2014/12/19 19:21:30.714337, 2, pid=2611671, effective(0, 0), real(0, 0), class=winbind] winbindd/winbindd_dual_srv.c:723(_wbint_PingDc)
dcerpc_netr_LogonControl failed: NT_STATUS_IO_DEVICE_ERROR
[2014/12/19 19:21:30.714370, 1, pid=2611671, effective(0, 0), real(0, 0)] ../librpc/ndr/ndr.c:282(ndr_print_function_debug)
wbint_PingDc: struct wbint_PingDc
out: struct wbint_PingDc
dcname : *
dcname : *
dcname : '2k12r2.virtual2.com'
result : NT_STATUS_IO_DEVICE_ERROR
2) Opening the netlogon pipe can fail with NT_STATUS_NETWORK_SESSION_EXPIRED:
[2014/12/19 19:21:46.798170, 5, pid=2611671, effective(0, 0), real(0, 0)] ../libcli/smb/smb2_signing.c:92(smb2_signing_sign_pdu)
signed SMB2 message
[2014/12/19 19:21:46.798812, 3, pid=2611671, effective(0, 0), real(0, 0), class=winbind] winbindd/winbindd_cm.c:2869(cm_connect_netlogon)
Could not open schannel'ed NETLOGON pipe. Error was NT_STATUS_NETWORK_SESSION_EXPIRED
[2014/12/19 19:21:46.798932, 3, pid=2611671, effective(0, 0), real(0, 0), class=winbind] winbindd/winbindd_dual_srv.c:697(_wbint_PingDc)
could not open handle to NETLOGON pipe: NT_STATUS_NETWORK_SESSION_EXPIRED
The attached patches introduce a retry for these two cases, so that one attempt
is made to reestablish the session before returning an error to the caller of
wbinfo --ping-dc.
Christof
-------------- next part --------------
From c2d1e53f0f14f7c738d765d1add8ec3418f024f9 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 19 Dec 2014 12:24:53 -0700
Subject: [PATCH 1/2] winbind: Retry after SESSION_EXPIRED error in ping-dc
Trying to establish a netlogon connection when the service ticket
expires might fail with NT_STATUS_NETWORK_SESSION_EXPIRED. The
underlying client code already marks the session as invalid, so retry
the netlogon connect in this case.
Signed-off-by: Christof Schmit <cs at samba.org>
---
source3/winbindd/winbindd_dual_srv.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 108b201..769d8d5 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -675,6 +675,14 @@ NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r)
}
status = cm_connect_netlogon(domain, &netlogon_pipe);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+ /*
+ * Retry to open new connection with new kerberos ticket.
+ */
+ status = cm_connect_netlogon(domain, &netlogon_pipe);
+ }
+
reset_cm_connection_on_error(domain, status);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
--
1.7.1
From 427a19e56038d3f0fad9f0ebd0a7a47a367f0c1f Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 19 Dec 2014 13:43:33 -0700
Subject: [PATCH 2/2] winbind: Retry LogonControl RPC in ping-dc after session expiration
When the underlying session expires, the LogonControl RPC call used in
ping-dc returns NT_STATUS_IO_DEVICE_ERROR. Retry once in this case,
instead of returning the error to the caller.
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/winbindd/winbindd_dual_srv.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 769d8d5..1152836 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -668,12 +668,14 @@ NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r)
WERROR werr;
fstring logon_server;
struct dcerpc_binding_handle *b;
+ bool retry = false;
domain = wb_child_domain();
if (domain == NULL) {
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
+reconnect:
status = cm_connect_netlogon(domain, &netlogon_pipe);
if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
@@ -709,6 +711,14 @@ NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r)
logon_server, NETLOGON_CONTROL_QUERY,
2, &info, &werr);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ DEBUG(10, ("Session might have expired. "
+ "Reconnect and retry once.\n"));
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto reconnect;
+ }
+
reset_cm_connection_on_error(domain, status);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n",
--
1.7.1
More information about the samba-technical
mailing list