[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