The branch, master has been updated
       via  6ec24883876 CI: add a test for wbinfo --change-secret-at=DC
       via  b907013053a CI: join ad_member_s3_join to vampire_dc
       via  52cdf1d93a2 wbinfo: Add --change-secret-at=dcname
       via  682216aa29e libwbclient: add wbc[Ctx]ChangeTrustCredentialsAt()
       via  eb1d1f19a23 winbindd: add dcname arg to ChangeMachineAccount request
       via  4a74748d329 winbindd: Add force_dc to bypass cached connection and 
DC lookup
       via  0fcf00121af winbindd: More simplification of cm_open_connection()
       via  7315c5f4a5d winbindd: simplify cm_open_connection()
       via  ccb6b75482c winbindd: simplify find_new_dc()
       via  2e496efe8c2 winbindd: do an early exit in cm_open_connection()
      from  94b70d1ed92 gp: Don't hide managed/recommended directories

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


- Log -----------------------------------------------------------------
commit 6ec2488387635b61a5c1559240019df3a5052850
Author: Ralph Boehme <s...@samba.org>
Date:   Wed Nov 23 14:14:45 2022 +0100

    CI: add a test for wbinfo --change-secret-at=DC
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Wed Dec 21 20:05:59 UTC 2022 on sn-devel-184

commit b907013053a4fc68a8fd55c444472ea382b4d5ef
Author: Ralph Boehme <s...@samba.org>
Date:   Wed Nov 23 14:10:36 2022 +0100

    CI: join ad_member_s3_join to vampire_dc
    
    Currently ad_member_s3_join is only used for testing samba-tool join and 
that'll
    work just fine being joined to vampire_dc instead of ad_dc.
    
    vampire_dc is an additional DC in the SAMBADOMAIN "started" by ad_dc_ntvfs, 
so
    by joining ad_member_s3_join to the SAMBADOMAIN, it is member of a domain 
with
    more then one DC.
    
    Subsequently I'll add a test that needs such an environment.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 52cdf1d93a24a6e5cbdf4e23a28e05971ea5adc3
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Nov 22 14:40:07 2022 +0100

    wbinfo: Add --change-secret-at=dcname
    
    Add WHATSNEW.txt entry and update wbinfo man page.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 682216aa29eda70885c7756927ebfbe88d655aa4
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Nov 22 12:00:14 2022 +0100

    libwbclient: add wbc[Ctx]ChangeTrustCredentialsAt()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit eb1d1f19a23807c9951dd178b93f3cfd94f68146
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Nov 22 16:09:34 2022 +0100

    winbindd: add dcname arg to ChangeMachineAccount request
    
    Existing callers will pass an empty string, later a new caller will pass an
    explicit DC name taken from the wbinfo command line.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 4a74748d329083e3e31201ecaf49f1fb1f2721c8
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Nov 22 14:23:21 2022 +0100

    winbindd: Add force_dc to bypass cached connection and DC lookup
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 0fcf00121afd0d67c3e0eee11f8490c32e2f58a7
Author: Ralph Boehme <s...@samba.org>
Date:   Thu Nov 24 12:17:32 2022 +0100

    winbindd: More simplification of cm_open_connection()
    
    This basically moves the functionality to connect the socket to the 
currently
    preferred DC to a new helper function connect_preferred_dc() that is called 
from
    the renamed function find_new_dc().
    
    find_dc() now either returns a connected to the preferred DC or a new DC 
until
    all possible DCs are exhausted and cm_open_connection() can just call 
find_dc()
    to get a connected socket and pass it to cm_prepare_connection().
    
    While at it reorder the args of find_dc() and make the only real out arg 
"fd"
    the last one.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 7315c5f4a5dd08216885f4a7588f57753de6038d
Author: Ralph Boehme <s...@samba.org>
Date:   Thu Nov 24 15:18:23 2022 +0100

    winbindd: simplify cm_open_connection()
    
    Simplify to retry logic: if cm_prepare_connection() succeeded just exit the
    retry loop, only if it failed check the "retry" variable.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit ccb6b75482c80572862ca7a189bfe26565f23b45
Author: Ralph Boehme <s...@samba.org>
Date:   Thu Nov 24 12:15:13 2022 +0100

    winbindd: simplify find_new_dc()
    
    Remove the dcname and pss args from find_new_dc(). The caller passes in the
    domain anyway, so let's fill in domain->dcname and domain->dcaddr directly.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 2e496efe8c29dc0342ddd09cb61e253132fe17f9
Author: Ralph Boehme <s...@samba.org>
Date:   Thu Nov 24 11:54:14 2022 +0100

    winbindd: do an early exit in cm_open_connection()
    
    Best viewed with git show -w. No change in behaviour.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

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

Summary of changes:
 WHATSNEW.txt                                       |   6 +
 docs-xml/manpages/wbinfo.1.xml                     |   8 +
 librpc/idl/winbind.idl                             |   1 +
 .../ABI/{wbclient-0.15.sigs => wbclient-0.16.sigs} |   2 +
 nsswitch/libwbclient/wbc_pam.c                     |  27 +-
 nsswitch/libwbclient/wbclient.h                    |  37 ++-
 nsswitch/libwbclient/wscript                       |   2 +-
 nsswitch/wbinfo.c                                  |  53 +++-
 selftest/target/Samba3.pm                          |   2 +-
 source3/script/tests/test_net_cred_change_at.sh    |  33 +++
 source3/selftest/tests.py                          |   2 +
 source3/winbindd/winbindd.h                        |   1 +
 source3/winbindd/winbindd_change_machine_acct.c    |   8 +-
 source3/winbindd/winbindd_cm.c                     | 285 ++++++++++++---------
 source3/winbindd/winbindd_dual_srv.c               |  26 +-
 15 files changed, 355 insertions(+), 138 deletions(-)
 copy nsswitch/libwbclient/ABI/{wbclient-0.15.sigs => wbclient-0.16.sigs} (97%)
 create mode 100755 source3/script/tests/test_net_cred_change_at.sh


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 94ced206dbb..4a40b7147dd 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -74,7 +74,13 @@ disable colour output. See https://no-color.org/ for a 
description of
 this variable. `samba-tool --color=always` will use colour regardless
 of NO_COLOR.
 
+New wbinfo option --change-secret-at
+------------------------------------
 
+The wbinfo command has a new option, --change-secret-at=<DOMAIN CONTROLLER>
+which forces the trust account password to be changed at a specified domain
+controller. If the specified domain controller cannot be contacted the
+password change fails rather than trying other DCs.
 
 
 REMOVED FEATURES
diff --git a/docs-xml/manpages/wbinfo.1.xml b/docs-xml/manpages/wbinfo.1.xml
index ddd1e27e02b..0426a0454c6 100644
--- a/docs-xml/manpages/wbinfo.1.xml
+++ b/docs-xml/manpages/wbinfo.1.xml
@@ -143,6 +143,14 @@
                </para></listitem>
                </varlistentry>
 
+               <varlistentry>
+               <term>--change-secret-at 
<replaceable>domain-controller</replaceable></term>
+               <listitem><para>Change the trust account password at a specific
+               domain controller. Fails if the specificied domain controller
+               cannot be contacted.
+               </para></listitem>
+               </varlistentry>
+
                <varlistentry>
                <term>--ccache-save 
<replaceable>username%password</replaceable></term>
                <listitem><para>Store user and password for ccache.
diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl
index 2adfc853835..de8fbc75c23 100644
--- a/librpc/idl/winbind.idl
+++ b/librpc/idl/winbind.idl
@@ -162,6 +162,7 @@ interface winbind
        );
 
     NTSTATUS wbint_ChangeMachineAccount(
+               [in,unique,string,charset(UTF8)] char *dcname
        );
 
     NTSTATUS wbint_PingDc(
diff --git a/nsswitch/libwbclient/ABI/wbclient-0.15.sigs 
b/nsswitch/libwbclient/ABI/wbclient-0.16.sigs
similarity index 97%
copy from nsswitch/libwbclient/ABI/wbclient-0.15.sigs
copy to nsswitch/libwbclient/ABI/wbclient-0.16.sigs
index a3019b5c68a..f30c8650fff 100644
--- a/nsswitch/libwbclient/ABI/wbclient-0.15.sigs
+++ b/nsswitch/libwbclient/ABI/wbclient-0.16.sigs
@@ -6,6 +6,7 @@ wbcAllocateUid: wbcErr (uid_t *)
 wbcAuthenticateUser: wbcErr (const char *, const char *)
 wbcAuthenticateUserEx: wbcErr (const struct wbcAuthUserParams *, struct 
wbcAuthUserInfo **, struct wbcAuthErrorInfo **)
 wbcChangeTrustCredentials: wbcErr (const char *, struct wbcAuthErrorInfo **)
+wbcChangeTrustCredentialsAt: wbcErr (const char *, const char *, struct 
wbcAuthErrorInfo **)
 wbcChangeUserPassword: wbcErr (const char *, const char *, const char *)
 wbcChangeUserPasswordEx: wbcErr (const struct wbcChangePasswordParams *, 
struct wbcAuthErrorInfo **, enum wbcPasswordChangeRejectReason *, struct 
wbcUserPasswordPolicyInfo **)
 wbcCheckTrustCredentials: wbcErr (const char *, struct wbcAuthErrorInfo **)
@@ -16,6 +17,7 @@ wbcCtxAllocateUid: wbcErr (struct wbcContext *, uid_t *)
 wbcCtxAuthenticateUser: wbcErr (struct wbcContext *, const char *, const char 
*)
 wbcCtxAuthenticateUserEx: wbcErr (struct wbcContext *, const struct 
wbcAuthUserParams *, struct wbcAuthUserInfo **, struct wbcAuthErrorInfo **)
 wbcCtxChangeTrustCredentials: wbcErr (struct wbcContext *, const char *, 
struct wbcAuthErrorInfo **)
+wbcCtxChangeTrustCredentialsAt: wbcErr (struct wbcContext *, const char *, 
const char *, struct wbcAuthErrorInfo **)
 wbcCtxChangeUserPassword: wbcErr (struct wbcContext *, const char *, const 
char *, const char *)
 wbcCtxChangeUserPasswordEx: wbcErr (struct wbcContext *, const struct 
wbcChangePasswordParams *, struct wbcAuthErrorInfo **, enum 
wbcPasswordChangeRejectReason *, struct wbcUserPasswordPolicyInfo **)
 wbcCtxCheckTrustCredentials: wbcErr (struct wbcContext *, const char *, struct 
wbcAuthErrorInfo **)
diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c
index 4df0ffe2eb5..aed9c05fa71 100644
--- a/nsswitch/libwbclient/wbc_pam.c
+++ b/nsswitch/libwbclient/wbc_pam.c
@@ -623,8 +623,10 @@ wbcErr wbcCheckTrustCredentials(const char *domain,
 
 /* Trigger a change of the trust credentials for a specific domain */
 _PUBLIC_
-wbcErr wbcCtxChangeTrustCredentials(struct wbcContext *ctx, const char *domain,
-                                   struct wbcAuthErrorInfo **error)
+wbcErr wbcCtxChangeTrustCredentialsAt(struct wbcContext *ctx,
+                                     const char *domain,
+                                     const char *dcname,
+                                     struct wbcAuthErrorInfo **error)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -638,6 +640,11 @@ wbcErr wbcCtxChangeTrustCredentials(struct wbcContext 
*ctx, const char *domain,
                        sizeof(request.domain_name)-1);
        }
 
+       if (dcname != NULL) {
+               strncpy(request.data.init_conn.dcname, dcname,
+                       sizeof(request.data.init_conn.dcname)-1);
+       }
+
        /* Send request */
 
        wbc_status = wbcRequestResponsePriv(ctx, WINBINDD_CHANGE_MACHACC,
@@ -658,6 +665,22 @@ wbcErr wbcCtxChangeTrustCredentials(struct wbcContext 
*ctx, const char *domain,
        return wbc_status;
 }
 
+_PUBLIC_
+wbcErr wbcChangeTrustCredentialsAt(const char *domain,
+                                const char *dcname,
+                                struct wbcAuthErrorInfo **error)
+{
+       return wbcCtxChangeTrustCredentialsAt(NULL, domain, dcname, error);
+}
+
+_PUBLIC_
+wbcErr wbcCtxChangeTrustCredentials(struct wbcContext *ctx,
+                                   const char *domain,
+                                   struct wbcAuthErrorInfo **error)
+{
+       return wbcCtxChangeTrustCredentialsAt(ctx, domain, NULL, error);
+}
+
 _PUBLIC_
 wbcErr wbcChangeTrustCredentials(const char *domain,
                                 struct wbcAuthErrorInfo **error)
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index 05cf8a14b80..98ed5fde6c9 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -77,9 +77,10 @@ const char *wbcErrorString(wbcErr error);
  *  0.14: Added "authoritative" to wbcAuthErrorInfo
  *        Added WBC_SID_NAME_LABEL
  *  0.15: Added wbcSetClientProcessName()
+ *  0.16: Added wbcChangeTrustCredentialsAt()
  **/
 #define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 15
+#define WBCLIENT_MINOR_VERSION 16
 #define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
 struct wbcLibraryDetails {
        uint16_t major_version;
@@ -1969,6 +1970,40 @@ wbcErr wbcCtxChangeTrustCredentials(struct wbcContext 
*ctx, const char *domain,
 wbcErr wbcChangeTrustCredentials(const char *domain,
                                 struct wbcAuthErrorInfo **error);
 
+/**
+ * @brief Trigger a change of the trust credentials for a specific domain
+ *        on the optionally given domain controller
+ *
+ * @param *ctx         wbclient Context
+ * @param *domain      The name of the domain.
+ * @param *dcname      The host name of the domain controller.
+ * @param error        Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ *
+ * @see wbcCtxChangeTrustCredentials()
+ **/
+wbcErr wbcCtxChangeTrustCredentialsAt(struct wbcContext *ctx,
+                                     const char *domain,
+                                     const char *dcname,
+                                     struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Trigger a change of the trust credentials for a specific domain
+ *        on the optionally given domain controller
+ *
+ * @param *domain      The name of the domain.
+ * @param *dcname      The host name of the domain controller.
+ * @param error        Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ *
+ * @see wbcChangeTrustCredentials()
+ **/
+wbcErr wbcChangeTrustCredentialsAt(const char *domain,
+                                  const char *dcname,
+                                  struct wbcAuthErrorInfo **error);
+
 /**
  * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost
  *        version of wbcCheckTrustCredentials
diff --git a/nsswitch/libwbclient/wscript b/nsswitch/libwbclient/wscript
index ad1d321bb42..51c662bac45 100644
--- a/nsswitch/libwbclient/wscript
+++ b/nsswitch/libwbclient/wscript
@@ -3,7 +3,7 @@
 from waflib import Options, Logs
 
 # Remember to also update wbclient.h
-VERSION="0.15"
+VERSION="0.16"
 
 # It may be useful at some point to allow Samba to build against a
 # system libwbclient, such as the one provided by Likewise.  To to
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index 55b9e268c39..de54373afe8 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -849,6 +849,43 @@ static bool wbinfo_change_secret(const char *domain)
        return true;
 }
 
+/* Change trust account password chose Domain Controller */
+
+static bool wbinfo_change_secret_at(const char *domain,
+                                   const char *domain_controller)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcAuthErrorInfo *error = NULL;
+       const char *domain_name;
+
+       if (domain) {
+               domain_name = domain;
+       } else {
+               domain_name = get_winbind_domain();
+       }
+
+       wbc_status = wbcChangeTrustCredentialsAt(
+               domain_name, domain_controller,  &error);
+
+       d_printf("changing the trust secret for domain %s via RPC calls %s\n",
+               domain_name,
+               WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
+
+       if (wbc_status == WBC_ERR_AUTH_ERROR) {
+               d_fprintf(stderr, "wbcChangeTrustCredentials(%s): "
+                         "error code was %s (0x%x)\n",
+                         domain_name, error->nt_string, error->nt_status);
+               wbcFreeMemory(error);
+       }
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               d_fprintf(stderr, "failed to call wbcChangeTrustCredentials: "
+                         "%s\n", wbcErrorString(wbc_status));
+               return false;
+       }
+
+       return true;
+}
+
 /* Check DC connection */
 
 static bool wbinfo_ping_dc(const char *domain)
@@ -2291,7 +2328,8 @@ enum {
        OPT_LOGOFF_USER,
        OPT_LOGOFF_UID,
        OPT_LANMAN,
-       OPT_KRB5CCNAME
+       OPT_KRB5CCNAME,
+       OPT_CHANGE_SECRET_AT
 };
 
 int main(int argc, const char **argv, char **envp)
@@ -2507,6 +2545,13 @@ int main(int argc, const char **argv, char **envp)
                        .val        = 'c',
                        .descrip    = "Change shared secret",
                },
+               {
+                       .longName   = "change-secret-at",
+                       .shortName  = 0,
+                       .argInfo    = POPT_ARG_STRING,
+                       .arg        = &string_arg,
+                       .val        = OPT_CHANGE_SECRET_AT,
+                       .descrip    = "Change shared secret at Domain 
Controler" },
                {
                        .longName   = "ping-dc",
                        .shortName  = 'P',
@@ -3034,6 +3079,12 @@ int main(int argc, const char **argv, char **envp)
                                goto done;
                        }
                        break;
+               case OPT_CHANGE_SECRET_AT:
+                       if (!wbinfo_change_secret_at(opt_domain_name, 
string_arg)) {
+                               d_fprintf(stderr, "Could not change secret\n");
+                               goto done;
+                       }
+                       break;
                case 'P':
                        if (!wbinfo_ping_dc(opt_domain_name)) {
                                goto done;
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 3ec0776e654..a20f2fa3365 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -253,7 +253,7 @@ sub check_env($$)
        ad_member_offlogon  => ["ad_dc"],
        ad_member_oneway    => ["fl2000dc"],
        ad_member_idmap_nss => ["ad_dc"],
-       ad_member_s3_join   => ["ad_dc"],
+       ad_member_s3_join   => ["vampire_dc"],
 
        clusteredmember => ["nt4_dc"],
 );
diff --git a/source3/script/tests/test_net_cred_change_at.sh 
b/source3/script/tests/test_net_cred_change_at.sh
new file mode 100755
index 00000000000..75456928530
--- /dev/null
+++ b/source3/script/tests/test_net_cred_change_at.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+if [ $# -lt 2 ]; then
+       cat <<EOF
+Usage: test_net_cred_change_at.sh CONFIGURATION
+EOF
+       exit 1
+fi
+
+incdir=$(dirname "$0")/../../../testprogs/blackbox
+# shellcheck source=/dev/null
+. "$incdir/subunit.sh"
+
+test_change_machine_secret_at() {
+    local DC_SERVER
+    local REPL_TARGET
+
+    out=$("$BINDIR/wbinfo" --dc-info SAMBADOMAIN) || return 1
+    echo "$out"
+    echo "$out" | grep localdc && DC_SERVER=localvampiredc && 
REPL_TARGET=localdc
+    echo "$out" | grep localvampiredc && DC_SERVER=localdc && 
REPL_TARGET=localvampiredc
+    if [ -z $DC_SERVER ] ; then return 1 ; fi
+
+    $VALGRIND "$BINDIR/wbinfo" --change-secret-at=$DC_SERVER || return 1
+
+    # Force replication
+    $VALGRIND "$BINDIR/samba-tool" drs replicate -U Administrator%locDCpass1 
$REPL_TARGET $DC_SERVER DC=samba,DC=example,DC=com
+}
+
+testit "change machine secret at" test_change_machine_secret_at || 
failed=$(("$failed" + 1))
+testit "validate secret" $VALGRIND "$BINDIR/net rpc testjoin" "$@" || 
failed=$(("$failed" + 1))
+
+testok "$0" "$failed"
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index a1379e8080e..82038321d1b 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -566,6 +566,8 @@ plantestsuite("samba3.blackbox.smbclient_auth.plain.ipv6", 
env, [os.path.join(sa
 for env in ["nt4_member", "ad_member"]:
     plantestsuite("samba3.blackbox.net_cred_change", "%s:local" % env, 
[os.path.join(samba3srcdir, "script/tests/test_net_cred_change.sh"), 
configuration])
 
+plantestsuite("samba3.blackbox.net_cred_change_at", "ad_member_s3_join:local", 
[os.path.join(samba3srcdir, "script/tests/test_net_cred_change_at.sh"), 
configuration, '$DC_SERVER'])
+
 env = "ad_member"
 t = "--krb5auth=$DOMAIN/$DC_USERNAME%$DC_PASSWORD"
 plantestsuite("samba3.wbinfo_simple.%s" % t, "%s:local" % env, 
[os.path.join(srcdir(), "nsswitch/tests/test_wbinfo_simple.sh"), t])
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 5044fee0c68..8a40208e378 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -153,6 +153,7 @@ struct winbindd_domain {
        } backend_data;
 
        /* A working DC */
+       bool force_dc;
        char *dcname;
        const char *ping_dcname;
        struct sockaddr_storage dcaddr;
diff --git a/source3/winbindd/winbindd_change_machine_acct.c 
b/source3/winbindd/winbindd_change_machine_acct.c
index 83eb99ba64a..fe5b9bf8a92 100644
--- a/source3/winbindd/winbindd_change_machine_acct.c
+++ b/source3/winbindd/winbindd_change_machine_acct.c
@@ -36,6 +36,7 @@ struct tevent_req 
*winbindd_change_machine_acct_send(TALLOC_CTX *mem_ctx,
        struct tevent_req *req, *subreq;
        struct winbindd_change_machine_acct_state *state;
        struct winbindd_domain *domain;
+       const char *dcname = NULL;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct winbindd_change_machine_acct_state);
@@ -43,6 +44,10 @@ struct tevent_req 
*winbindd_change_machine_acct_send(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
+       if (request->data.init_conn.dcname[0] != '\0') {
+               dcname = request->data.init_conn.dcname;
+       }
+
        domain = find_domain_from_name(request->domain_name);
        if (domain == NULL) {
                tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
@@ -62,7 +67,8 @@ struct tevent_req 
*winbindd_change_machine_acct_send(TALLOC_CTX *mem_ctx,
        }
 
        subreq = dcerpc_wbint_ChangeMachineAccount_send(state, ev,
-                                                       
dom_child_handle(domain));
+                                                       
dom_child_handle(domain),
+                                                       dcname);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index e774bf90511..264fc1368d6 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -1391,21 +1391,105 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct 
winbindd_domain *domain,
        return True;
 }
 
+static bool connect_preferred_dc(TALLOC_CTX *mem_ctx,
+                                struct winbindd_domain *domain,
+                                uint32_t request_flags,
+                                int *fd)
+{
+       char *saf_servername = NULL;
+       NTSTATUS status;
+       bool ok;
+
+       /*
+        * We have to check the server affinity cache here since later we select
+        * a DC based on response time and not preference.
+        */
+       if (domain->force_dc) {
+               saf_servername = domain->dcname;
+       } else {
+               saf_servername = saf_fetch(mem_ctx, domain->name);
+       }
+
+       /*
+        * Check the negative connection cache before talking to it. It going
+        * down may have triggered the reconnection.
+        */
+       status = check_negative_conn_cache(domain->name, saf_servername);
+       if (!NT_STATUS_IS_OK(status)) {
+               saf_servername = NULL;
+       }
+
+       if (saf_servername != NULL) {
+               DBG_DEBUG("saf_servername is '%s' for domain %s\n",
+                         saf_servername, domain->name);
+
+               /* convert an ip address to a name */
+               if (is_ipaddress(saf_servername)) {
+                       ok = interpret_string_addr(&domain->dcaddr,
+                                                  saf_servername,
+                                                  AI_NUMERICHOST);
+                       if (!ok) {
+                               return false;
+                       }
+               } else {
+                       ok = resolve_name(saf_servername,
+                                         &domain->dcaddr,
+                                         0x20,
+                                         true);
+                       if (!ok) {
+                               goto fail;
+                       }
+               }
+
+               TALLOC_FREE(domain->dcname);
+               ok = dcip_check_name(domain,
+                                    domain,
+                                    &domain->dcaddr,
+                                    &domain->dcname,
+                                    request_flags);
+               if (!ok) {
+                       goto fail;
+               }
+       }
+
+       if (domain->dcname == NULL) {
+               return false;
+       }
+
+       status = check_negative_conn_cache(domain->name, domain->dcname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+
+       status = smbsock_connect(&domain->dcaddr, 0,
+                                NULL, -1, NULL, -1,
+                                fd, NULL, 10);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto fail;
+       }
+       return true;
+
+fail:
+       winbind_add_failed_connection_entry(domain,
+                                           saf_servername,
+                                           NT_STATUS_UNSUCCESSFUL);
+       return false;
+
+}
+
 /*******************************************************************
  Find and make a connection to a DC in the given domain.
 
  @param[in] mem_ctx talloc memory context to allocate from
  @param[in] domain domain to find a dc in
- @param[out] dcname NetBIOS or FQDN of DC that's connected to
- @param[out] pss DC Internet address and port
  @param[out] fd fd of the open socket connected to the newly found dc
  @return true when a DC connection is made, false otherwise
 *******************************************************************/
 
-static bool find_new_dc(TALLOC_CTX *mem_ctx,
-                       struct winbindd_domain *domain,
-                       char **dcname, struct sockaddr_storage *pss, int *fd,
-                       uint32_t request_flags)
+static bool find_dc(TALLOC_CTX *mem_ctx,
+                   struct winbindd_domain *domain,


-- 
Samba Shared Repository

Reply via email to