The branch, master has been updated
       via  c37fbfc winbindd: add retry to _winbind_SendToSam
       via  e608f05 winbindd: add retry to 
_winbind_DsrUpdateReadOnlyServerDnsRecords
       via  fcf8edf winbindd: add retry to _wbint_DsGetDcName
       via  c2cd2d3 winbindd: add retry to _wbint_LookupSids()
       via  6244a2b winbindd: use reset_cm_connection_on_error() instead of 
dcerpc_binding_handle_is_connected()
       via  08718af winbindd: fix logic calling 
dcerpc_binding_handle_is_connected()
       via  966ff37 winbindd: call dcerpc_binding_handle_is_connected() from 
reset_cm_connection_on_error()
       via  2d1f00c winbindd: force netlogon reauth for certain errors in 
reset_cm_connection_on_error()
       via  2837b79 winbindd: call reset_cm_connection_on_error() from 
reconnect_need_retry()
       via  17749a5 winbindd: make reset_cm_connection_on_error() public
       via  a33c1d2 winbindd: check for NT_STATUS_IO_DEVICE_ERROR in 
reset_cm_connection_on_error()
       via  a8d5e4d winbindd: add and use ldap_reconnect_need_retry() in 
winbindd_reconnect_ads.c
       via  4b7a9d5 winbind: Keep "force_reauth" in invalidate_cm_connection
       via  0af88b9 winbind: Add smbcontrol disconnect-dc
       via  bffae41 utils: Add destroy_netlogon_creds_cli
      from  20609aa s4: dsdb/password_hash: use UF_TRUST_ACCOUNT_MASK

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


- Log -----------------------------------------------------------------
commit c37fbfcb248e5a8d6088a28eb0c1a62423f94502
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 19:54:37 2018 +0100

    winbindd: add retry to _winbind_SendToSam
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>
    
    Autobuild-User(master): Ralph Böhme <[email protected]>
    Autobuild-Date(master): Thu Mar 15 20:57:44 CET 2018 on sn-devel-144

commit e608f058b8f2d2295e24498daa35852de3212b23
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 19:53:53 2018 +0100

    winbindd: add retry to _winbind_DsrUpdateReadOnlyServerDnsRecords
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit fcf8edf9b8cdf5f3897c1a63ed97c302a231742f
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 19:53:26 2018 +0100

    winbindd: add retry to _wbint_DsGetDcName
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit c2cd2d3f3137e27cd6e4cabd34f27b49251f078d
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 17:09:34 2018 +0100

    winbindd: add retry to _wbint_LookupSids()
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 6244a2beb184de8d050389e304f087ef153d61dd
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 16:53:49 2018 +0100

    winbindd: use reset_cm_connection_on_error() instead of 
dcerpc_binding_handle_is_connected()
    
    This catches more errors and triggers retry as appropriate.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 08718af36f3ed6cf2308beb3800abfb0414f94b9
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 16:15:02 2018 +0100

    winbindd: fix logic calling dcerpc_binding_handle_is_connected()
    
    The calls were missing the negation operator, a retry should be
    attempted is the binding handle got somehow disconnected behind the
    scenes and is NOT connected.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 966ff3793a867a5ffe1a49e48c8ab3ecb02f8359
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 16:11:37 2018 +0100

    winbindd: call dcerpc_binding_handle_is_connected() from 
reset_cm_connection_on_error()
    
    To consolidate the error handling for RPC calls, add the binding handle
    as an additional argument to reset_cm_connection_on_error().
    
    All callers pass NULL for now, so no change in behaviour up to here.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 2d1f00cc3ad77bed4e810dc910979e6cdf582216
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 13:39:59 2018 +0100

    winbindd: force netlogon reauth for certain errors in 
reset_cm_connection_on_error()
    
    NT_STATUS_RPC_SEC_PKG_ERROR is returned by the server if the server
    doesn't know the server-side netlogon credentials anymore, eg after a
    reboot. If this happens we must force a full netlogon reauth.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 2837b796af3e491b6bb34bd441758ae214f629ee
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 12:20:04 2018 +0100

    winbindd: call reset_cm_connection_on_error() from reconnect_need_retry()
    
    This ensures we use the same disconnect logic in the reconnect backend,
    which calls reconnect_need_retry(), and in the dual_srv frontend which
    calls reset_cm_connection_on_error.
    
    Both reset_cm_connection_on_error() and reconnect_need_retry() are very
    similar, both return a bool indicating whether a retry should be
    attempted, unfortunately the functions have a different default return,
    so I don't dare unifying them, but instead just call one from the other.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 17749a5d9fa08da1c61de45728656a2c9b85782d
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 11:29:22 2018 +0100

    winbindd: make reset_cm_connection_on_error() public
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit a33c1d25e0422483c903001dd246626f84c4cbc1
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 11:12:34 2018 +0100

    winbindd: check for NT_STATUS_IO_DEVICE_ERROR in 
reset_cm_connection_on_error()
    
    reconnect_need_retry() already checks for this error, it surfaces up
    from tstream_smbXcli_np as a mapping for EIO.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit a8d5e4d36768bc199c631626488b2d0acbd6e91a
Author: Ralph Boehme <[email protected]>
Date:   Mon Mar 12 13:30:01 2018 +0100

    winbindd: add and use ldap_reconnect_need_retry() in 
winbindd_reconnect_ads.c
    
    ldap_reconnect_need_retry() is a copy of reconnect_need_retry() minus
    the RPC connection invalidation.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 4b7a9d560a51b51ac88f30276c87edc097b00d0b
Author: Volker Lendecke <[email protected]>
Date:   Wed Feb 28 15:09:28 2018 +0000

    winbind: Keep "force_reauth" in invalidate_cm_connection
    
    Right now I don't see a way to actually force a re-serverauth
    from the client side as long as an entry in netlogon_creds_cli.tdb
    exists. cm_connect_netlogon goes through invalidate_cm_connection, and
    this wipes our wish to force a reauthenticatoin. Keep this intact until
    we actually did reauthenticate.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 0af88b98e7e1bba14827305257e77b63dc82d902
Author: Volker Lendecke <[email protected]>
Date:   Wed Feb 28 15:08:44 2018 +0000

    winbind: Add smbcontrol disconnect-dc
    
    Make a winbind child drop all DC connections
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit bffae41842fe218959fe6f8b43df694feec1589c
Author: Volker Lendecke <[email protected]>
Date:   Wed Feb 28 07:59:08 2018 +0000

    utils: Add destroy_netlogon_creds_cli
    
    This is a pure testing utility that will garble the netlogon_creds_cli
    session_key. This creates a similar effect to our schannel credentials
    as does a domain controller reboot.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13332
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

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

Summary of changes:
 librpc/idl/messaging.idl                   |   1 +
 source3/utils/destroy_netlogon_creds_cli.c | 137 +++++++++++++++++++++++++++
 source3/utils/smbcontrol.c                 |  14 +++
 source3/utils/wscript_build                |   9 ++
 source3/winbindd/winbindd.c                |   4 +
 source3/winbindd/winbindd_cm.c             |  18 +++-
 source3/winbindd/winbindd_dual.c           |  19 +++-
 source3/winbindd/winbindd_dual_srv.c       | 144 ++++++++++++++++++-----------
 source3/winbindd/winbindd_proto.h          |  15 +++
 source3/winbindd/winbindd_reconnect.c      |   8 +-
 source3/winbindd/winbindd_reconnect_ads.c  |  58 ++++++++++--
 11 files changed, 359 insertions(+), 68 deletions(-)
 create mode 100644 source3/utils/destroy_netlogon_creds_cli.c


Changeset truncated at 500 lines:

diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index 5468334..14a6f92 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -124,6 +124,7 @@ interface messaging
                MSG_WINBIND_DOMAIN_ONLINE       = 0x040B,
                MSG_WINBIND_DOMAIN_OFFLINE      = 0x040C,
                MSG_WINBIND_RELOAD_TRUSTED_DOMAINS = 0x040D,
+               MSG_WINBIND_DISCONNECT_DC       = 0x040E,
 
                /* event messages */
                /* MSG_DUMP_EVENT_LIST          = 0x0500, Obsoleted */
diff --git a/source3/utils/destroy_netlogon_creds_cli.c 
b/source3/utils/destroy_netlogon_creds_cli.c
new file mode 100644
index 0000000..137ac83
--- /dev/null
+++ b/source3/utils/destroy_netlogon_creds_cli.c
@@ -0,0 +1,137 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Garble the netlogon_creds_cli key for testing purposes
+ * Copyright (C) Volker Lendecke 2018
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "system/filesys.h"
+#include <talloc.h>
+#include <tevent.h>
+#include "messages.h"
+#include "lib/util/talloc_stack.h"
+#include "popt_common.h"
+#include "lib/param/loadparm.h"
+#include "lib/param/param.h"
+#include "libcli/auth/netlogon_creds_cli.h"
+#include "lib/dbwrap/dbwrap.h"
+#include "lib/dbwrap/dbwrap_open.h"
+
+int main(int argc, const char *argv[])
+{
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+       struct tevent_context *ev;
+       struct messaging_context *msg_ctx;
+       struct loadparm_context *lp_ctx;
+       struct db_context *global_db;
+       struct netlogon_creds_cli_context *ctx;
+       struct netlogon_creds_CredentialState *creds;
+       NTSTATUS status;
+       int ret = 1;
+
+       smb_init_locale();
+
+       if (!lp_load_global(get_dyn_CONFIGFILE())) {
+               fprintf(stderr, "error opening config file %s. Error was %s\n",
+                       get_dyn_CONFIGFILE(), strerror(errno));
+               goto done;
+       }
+
+       if (argc != 4) {
+               fprintf(stderr, "usage: %s cli_computer domain dc\n", argv[0]);
+               goto done;
+       }
+
+       lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
+       if (lp_ctx == NULL) {
+               fprintf(stderr, "loadparm_init_s3 failed\n");
+               goto done;
+       }
+
+       ev = samba_tevent_context_init(mem_ctx);
+       if (ev == NULL) {
+               fprintf(stderr, "samba3_tevent_context_init failed\n");
+               goto done;
+       }
+       msg_ctx = messaging_init(mem_ctx, ev);
+       if (msg_ctx == NULL) {
+               fprintf(stderr, "messaging_init failed\n");
+               goto done;
+       }
+
+       global_db = db_open(
+               mem_ctx,
+               lpcfg_private_db_path(mem_ctx, lp_ctx, "netlogon_creds_cli"),
+               0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
+               O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
+               DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS);
+       if (global_db == NULL) {
+               fprintf(stderr, "db_open failed\n");
+               goto done;
+       }
+
+       status = netlogon_creds_cli_set_global_db(&global_db);
+       if (!NT_STATUS_IS_OK(status)) {
+               fprintf(stderr,
+                       "netlogon_creds_cli_set_global_db failed: %s\n",
+                       nt_errstr(status));
+               goto done;
+       }
+
+       status = netlogon_creds_cli_context_global(
+               lp_ctx,
+               msg_ctx,
+               talloc_asprintf(mem_ctx, "%s$", argv[1]),
+               SEC_CHAN_WKSTA,
+               argv[3],
+               argv[2],
+               "",
+               mem_ctx,
+               &ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               fprintf(stderr,
+                       "netlogon_creds_cli_context_global failed: %s\n",
+                       nt_errstr(status));
+               goto done;
+       }
+
+       status = netlogon_creds_cli_lock(ctx,
+                                        mem_ctx,
+                                        &creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               fprintf(stderr,
+                       "netlogon_creds_cli_get failed: %s\n",
+                       nt_errstr(status));
+               goto done;
+       }
+
+       creds->session_key[0]++;
+
+       status = netlogon_creds_cli_store(ctx, creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               fprintf(stderr,
+                       "netlogon_creds_cli_store failed: %s\n",
+                       nt_errstr(status));
+               goto done;
+       }
+
+       TALLOC_FREE(creds);
+
+       ret = 0;
+done:
+       TALLOC_FREE(mem_ctx);
+       return ret;
+}
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index 4ecfb3e..bd89b9e 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -1225,6 +1225,19 @@ static bool do_winbind_dump_domain_list(struct 
tevent_context *ev_ctx,
        return num_replies;
 }
 
+static bool do_msg_disconnect_dc(struct tevent_context *ev_ctx,
+                                struct messaging_context *msg_ctx,
+                                const struct server_id pid,
+                                const int argc, const char **argv)
+{
+       if (argc != 1) {
+               fprintf(stderr, "Usage: smbcontrol <dest> disconnect-dc\n");
+               return False;
+       }
+
+       return send_message(msg_ctx, pid, MSG_WINBIND_DISCONNECT_DC, NULL, 0);
+}
+
 static void winbind_validate_cache_cb(struct messaging_context *msg,
                                      void *private_data,
                                      uint32_t msg_type,
@@ -1402,6 +1415,7 @@ static const struct {
        { "validate-cache" , do_winbind_validate_cache,
          "Validate winbind's credential cache" },
        { "dump-domain-list", do_winbind_dump_domain_list, "Dump winbind domain 
list"},
+       { "disconnect-dc", do_msg_disconnect_dc },
        { "notify-cleanup", do_notify_cleanup },
        { "num-children", do_num_children,
          "Print number of smbd child processes" },
diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build
index 04eaf07..8b4d890 100644
--- a/source3/utils/wscript_build
+++ b/source3/utils/wscript_build
@@ -257,3 +257,12 @@ bld.SAMBA3_BINARY('mvxattr',
                  popt_samba3
                  ''',
                  enabled=bld.env.build_mvxattr)
+
+bld.SAMBA3_BINARY('destroy_netlogon_creds_cli',
+                  source='destroy_netlogon_creds_cli.c',
+                  deps = '''
+                      talloc
+                      popt_samba3
+                      NETLOGON_CREDS_CLI
+                  ''',
+                  install=False)
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 81b86df..8821f39 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1346,6 +1346,10 @@ static void winbindd_register_handlers(struct 
messaging_context *msg_ctx,
                           MSG_DEBUG,
                           winbind_msg_debug);
 
+       messaging_register(msg_ctx, NULL,
+                          MSG_WINBIND_DISCONNECT_DC,
+                          winbind_disconnect_dc_parent);
+
        netsamlogon_cache_init(); /* Non-critical */
 
        /* clear the cached list of trusted domains */
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 1e44e9b..bf5a2b4 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -2081,7 +2081,6 @@ void invalidate_cm_connection(struct winbindd_domain 
*domain)
        }
 
        conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
-       conn->netlogon_force_reauth = false;
        TALLOC_FREE(conn->netlogon_creds_ctx);
 
        if (conn->cli) {
@@ -3368,6 +3367,7 @@ static NTSTATUS cm_connect_netlogon_transport(struct 
winbindd_domain *domain,
                conn->cli, transport,
                conn->netlogon_creds_ctx, conn->netlogon_force_reauth, creds,
                &conn->netlogon_pipe);
+       conn->netlogon_force_reauth = false;
        if (!NT_STATUS_IS_OK(result)) {
                DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
                          nt_errstr(result));
@@ -3509,3 +3509,19 @@ void winbind_msg_ip_dropped(struct messaging_context 
*msg_ctx,
        }
        TALLOC_FREE(freeit);
 }
+
+void winbind_msg_disconnect_dc(struct messaging_context *msg_ctx,
+                              void *private_data,
+                              uint32_t msg_type,
+                              struct server_id server_id,
+                              DATA_BLOB *data)
+{
+       struct winbindd_domain *domain;
+
+       for (domain = domain_list(); domain; domain = domain->next) {
+               if (domain->internal) {
+                       continue;
+               }
+               invalidate_cm_connection(domain);
+       }
+}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 2a4950b..5ae5bbd 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -882,6 +882,21 @@ void winbind_msg_debug(struct messaging_context *msg_ctx,
        forall_children(winbind_msg_relay_fn, &state);
 }
 
+void winbind_disconnect_dc_parent(struct messaging_context *msg_ctx,
+                                 void *private_data,
+                                 uint32_t msg_type,
+                                 struct server_id server_id,
+                                 DATA_BLOB *data)
+{
+       struct winbind_msg_relay_state state = {
+               .msg_ctx = msg_ctx, .msg_type = msg_type, .data = data
+       };
+
+       DBG_DEBUG("Got disconnect_dc message\n");
+
+       forall_children(winbind_msg_relay_fn, &state);
+}
+
 /* Set our domains as offline and forward the offline message to our children. 
*/
 
 struct winbind_msg_on_offline_state {
@@ -1710,7 +1725,9 @@ static bool fork_domain_child(struct winbindd_child 
*child)
        messaging_register(server_messaging_context(), NULL,
                           MSG_WINBIND_IP_DROPPED,
                           winbind_msg_ip_dropped);
-
+       messaging_register(server_messaging_context(), NULL,
+                          MSG_WINBIND_DISCONNECT_DC,
+                          winbind_msg_disconnect_dc);
 
        primary_domain = find_our_domain();
 
diff --git a/source3/winbindd/winbindd_dual_srv.c 
b/source3/winbindd/winbindd_dual_srv.c
index 66b4ee8..4cea73f 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -41,14 +41,31 @@ void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping 
*r)
        *r->out.out_data = r->in.in_data;
 }
 
-static bool reset_cm_connection_on_error(struct winbindd_domain *domain,
-                                       NTSTATUS status)
+bool reset_cm_connection_on_error(struct winbindd_domain *domain,
+                                 struct dcerpc_binding_handle *b,
+                                 NTSTATUS status)
 {
-       if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
+               invalidate_cm_connection(domain);
+               domain->conn.netlogon_force_reauth = true;
+               return true;
+       }
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR))
+       {
                invalidate_cm_connection(domain);
                /* We invalidated the connection. */
                return true;
        }
+
+       if (b != NULL && !dcerpc_binding_handle_is_connected(b)) {
+               invalidate_cm_connection(domain);
+               return true;
+       }
+
        return false;
 }
 
@@ -66,7 +83,7 @@ NTSTATUS _wbint_LookupSid(struct pipes_struct *p, struct 
wbint_LookupSid *r)
 
        status = wb_cache_sid_to_name(domain, p->mem_ctx, r->in.sid,
                                      &dom_name, &name, &type);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -82,6 +99,7 @@ NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct 
wbint_LookupSids *r)
        struct winbindd_domain *domain = wb_child_domain();
        struct lsa_RefDomainList *domains = r->out.domains;
        NTSTATUS status;
+       bool retry = false;
 
        if (domain == NULL) {
                return NT_STATUS_REQUEST_NOT_ACCEPTED;
@@ -93,6 +111,7 @@ NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct 
wbint_LookupSids *r)
         * and winbindd_ad call into lsa_lookupsids anyway. Caching is
         * done at the wbint RPC layer.
         */
+again:
        status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids,
                                 &domains, &r->out.names);
 
@@ -100,7 +119,11 @@ NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct 
wbint_LookupSids *r)
                r->out.domains = domains;
        }
 
-       reset_cm_connection_on_error(domain, status);
+       if (!retry && reset_cm_connection_on_error(domain, NULL, status)) {
+               retry = true;
+               goto again;
+       }
+
        return status;
 }
 
@@ -116,7 +139,7 @@ NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct 
wbint_LookupName *r)
        status = wb_cache_name_to_sid(domain, p->mem_ctx, r->in.domain,
                                      r->in.name, r->in.flags,
                                      r->out.sid, r->out.type);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        return status;
 }
 
@@ -304,7 +327,7 @@ NTSTATUS _wbint_LookupUserAliases(struct pipes_struct *p,
                                             r->in.sids->sids,
                                             &r->out.rids->num_rids,
                                             &r->out.rids->rids);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        return status;
 }
 
@@ -321,7 +344,7 @@ NTSTATUS _wbint_LookupUserGroups(struct pipes_struct *p,
        status = wb_cache_lookup_usergroups(domain, p->mem_ctx, r->in.sid,
                                            &r->out.sids->num_sids,
                                            &r->out.sids->sids);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        return status;
 }
 
@@ -336,7 +359,7 @@ NTSTATUS _wbint_QuerySequenceNumber(struct pipes_struct *p,
        }
 
        status = wb_cache_sequence_number(domain, r->out.sequence);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        return status;
 }
 
@@ -357,7 +380,7 @@ NTSTATUS _wbint_LookupGroupMembers(struct pipes_struct *p,
        status = wb_cache_lookup_groupmem(domain, p->mem_ctx, r->in.sid,
                                          r->in.type, &num_names, &sid_mem,
                                          &names, &name_types);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -424,7 +447,7 @@ NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
                status = wb_cache_enum_local_groups(domain, frame,
                                                    &num_local_groups,
                                                    &local_groups);
-               reset_cm_connection_on_error(domain, status);
+               reset_cm_connection_on_error(domain, NULL, status);
                if (!NT_STATUS_IS_OK(status)) {
                        goto out;
                }
@@ -433,7 +456,7 @@ NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
        status = wb_cache_enum_dom_groups(domain, frame,
                                          &num_dom_groups,
                                          &dom_groups);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
        }
@@ -504,7 +527,7 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p,
 
        status = wb_cache_query_user_list(domain, p->mem_ctx,
                                          &r->out.rids->rids);
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
 
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -524,6 +547,8 @@ NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct 
wbint_DsGetDcName *r)
        WERROR werr;
        unsigned int orig_timeout;
        struct dcerpc_binding_handle *b;
+       bool retry = false;
+       bool try_dsrgetdcname = false;
 
        if (domain == NULL) {
                return dsgetdcname(p->mem_ctx, server_messaging_context(),
@@ -533,9 +558,14 @@ NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct 
wbint_DsGetDcName *r)
                                   r->out.dc_info);
        }
 
+       if (domain->active_directory) {
+               try_dsrgetdcname = true;
+       }
+
+reconnect:
        status = cm_connect_netlogon(domain, &netlogon_pipe);
 
-       reset_cm_connection_on_error(domain, status);
+       reset_cm_connection_on_error(domain, NULL, status);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
                return status;
@@ -548,7 +578,7 @@ NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct 
wbint_DsGetDcName *r)
 
        orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
 
-       if (domain->active_directory) {
+       if (try_dsrgetdcname) {
                status = dcerpc_netr_DsRGetDCName(b,
                        p->mem_ctx, domain->dcname,
                        r->in.domain_name, NULL, r->in.domain_guid,
@@ -556,23 +586,14 @@ NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, 
struct wbint_DsGetDcName *r)
                if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) {
                        goto done;
                }
-               if (reset_cm_connection_on_error(domain, status)) {
-                       /* Re-initialize. */
-                       status = cm_connect_netlogon(domain, &netlogon_pipe);
-
-                       reset_cm_connection_on_error(domain, status);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               DEBUG(10, ("Can't contact the NETLOGON 
pipe\n"));
-                               return status;
-                       }
-
-                       b = netlogon_pipe->binding_handle;
-
-                       /* This call can take a long time - allow the server to 
time out.
-                          35 seconds should do it. */
-
-                       orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
+               if (!retry &&


-- 
Samba Shared Repository

Reply via email to