s3:winbind: BUG 9386: Failover if netlogon pipe is not available.
authorAndreas Schneider <asn@samba.org>
Fri, 9 Nov 2012 14:33:09 +0000 (15:33 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 12 Nov 2012 17:57:18 +0000 (18:57 +0100)
Samba continues to query a broken DC while the DC did not finish to
rebuild Sysvol (after a Windows crash, for example). It causes end users
to received strange codes while trying to authenticate, even if there is
a secondary DC available.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Mon Nov 12 18:57:18 CET 2012 on sn-devel-104

source3/winbindd/winbindd_pam.c

index 5b6b77b48c73eac1692127e23074ab99fc31238f..b23d421fcda1a2fee1fcd2637f68543946980151 100644 (file)
@@ -1175,6 +1175,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                                            struct netr_SamInfo3 **info3)
 {
        int attempts = 0;
+       int netr_attempts = 0;
        bool retry = false;
        NTSTATUS result;
 
@@ -1189,22 +1190,47 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                result = cm_connect_netlogon(domain, &netlogon_pipe);
 
                if (!NT_STATUS_IS_OK(result)) {
-                       DEBUG(3,("could not open handle to NETLOGON pipe (error: %s)\n",
-                                 nt_errstr(result)));
-                       if (NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT)) {
-                               if (attempts > 0) {
-                                       DEBUG(3, ("This is the second problem for this "
-                                               "particular call, forcing the close of "
-                                               "this connection\n"));
-                                       invalidate_cm_connection(&domain->conn);
-                               } else {
-                                       DEBUG(3, ("First call to cm_connect_netlogon "
-                                               "has timed out, retrying\n"));
-                                       continue;
-                               }
+                       DEBUG(3,("Could not open handle to NETLOGON pipe "
+                                "(error: %s, attempts: %d)\n",
+                                 nt_errstr(result), netr_attempts));
+
+                       /* After the first retry always close the connection */
+                       if (netr_attempts > 0) {
+                               DEBUG(3, ("This is again a problem for this "
+                                         "particular call, forcing the close "
+                                         "of this connection\n"));
+                               invalidate_cm_connection(&domain->conn);
+                       }
+
+                       /* After the second retry failover to the next DC */
+                       if (netr_attempts > 1) {
+                               /*
+                                * If the netlogon server is not reachable then
+                                * it is possible that the DC is rebuilding
+                                * sysvol and shutdown netlogon for that time.
+                                * We should failover to the next dc.
+                                */
+                               DEBUG(3, ("This is the third problem for this "
+                                         "particular call, adding DC to the "
+                                         "negative cache list\n"));
+                               add_failed_connection_entry(domain->name,
+                                                           domain->dcname,
+                                                           result);
+                               saf_delete(domain->name);
+                       }
+
+                       /* Only allow 3 retries */
+                       if (netr_attempts < 3) {
+                               DEBUG(3, ("The connection to netlogon "
+                                         "failed, retrying\n"));
+                               netr_attempts++;
+                               retry = true;
+                               continue;
                        }
                        return result;
                }
+               netr_attempts = 0;
+
                auth = netlogon_pipe->auth;
                if (netlogon_pipe->dc) {
                        neg_flags = netlogon_pipe->dc->negotiate_flags;