winbindd: add dcname arg to ChangeMachineAccount request
authorRalph Boehme <slow@samba.org>
Tue, 22 Nov 2022 15:09:34 +0000 (16:09 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 21 Dec 2022 19:10:35 +0000 (19:10 +0000)
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
librpc/idl/winbind.idl
source3/winbindd/winbindd_change_machine_acct.c
source3/winbindd/winbindd_dual_srv.c

index 2adfc853835ca1ce15dba5c55d63ac2e40cf0cb8..de8fbc75c233d1ae37ab5cd1f02fd62fef83fbed 100644 (file)
@@ -162,6 +162,7 @@ interface winbind
        );
 
     NTSTATUS wbint_ChangeMachineAccount(
+               [in,unique,string,charset(UTF8)] char *dcname
        );
 
     NTSTATUS wbint_PingDc(
index 83eb99ba64ae7a10c24dadd0e0d0602250144c02..fe5b9bf8a920c0d67d11589a32b1b4b47c72dafc 100644 (file)
@@ -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);
        }
index ffa4ad95b29864216476166fa7b89a3f7e8037e5..aaa78a9cb6e6029053a3922acde682c9b2850304 100644 (file)
@@ -841,6 +841,22 @@ NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p,
                return NT_STATUS_REQUEST_NOT_ACCEPTED;
        }
 
+       if (r->in.dcname != NULL && r->in.dcname[0] != '\0') {
+               invalidate_cm_connection(domain);
+               TALLOC_FREE(domain->dcname);
+
+               domain->dcname = talloc_strdup(domain, r->in.dcname);
+               if (domain->dcname == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
+               domain->force_dc = true;
+
+               DBG_NOTICE("attempt connection to change trust account "
+                          "password for %s at %s\n",
+                          domain->name, domain->dcname);
+       }
+
        status = cm_connect_netlogon_secure(domain,
                                            &netlogon_pipe,
                                            &netlogon_creds_ctx);
@@ -863,9 +879,13 @@ NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p,
                NT_STATUS_IS_OK(status) ? "changed" : "unchanged"));
 
  done:
-       DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
-             ("Changing the trust account password for domain %s returned %s\n",
-              domain->name, nt_errstr(status)));
+       DEBUG(NT_STATUS_IS_OK(status) ? 5 :
+             domain->force_dc ? 0 : 2,
+             ("Changing the trust account password for domain %s at %s "
+              "(forced: %s) returned %s\n",
+              domain->name, domain->dcname, domain->force_dc ? "yes" : "no",
+              nt_errstr(status)));
+       domain->force_dc = false;
 
        return status;
 }