diff options
Diffstat (limited to 'source3/winbindd/winbindd_dual_srv.c')
-rw-r--r-- | source3/winbindd/winbindd_dual_srv.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 179a771066..f0bbee9f31 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -4,6 +4,7 @@ In-Child server implementation of the routines defined in wbint.idl Copyright (C) Volker Lendecke 2009 + Copyright (C) Guenther Deschner 2009 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 @@ -437,17 +438,78 @@ again: /* Pass back result code - zero for success, other values for specific failures. */ - DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(status) ? - "good" : "bad")); + DEBUG(3,("domain %s secret is %s\n", domain->name, + NT_STATUS_IS_OK(status) ? "good" : "bad")); done: DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2, - ("Checking the trust account password returned %s\n", - nt_errstr(status))); + ("Checking the trust account password for domain %s returned %s\n", + domain->name, nt_errstr(status))); return status; } +NTSTATUS _wbint_ChangeMachineAccount(pipes_struct *p, + struct wbint_ChangeMachineAccount *r) +{ + struct winbindd_domain *domain; + int num_retries = 0; + NTSTATUS status; + struct rpc_pipe_client *netlogon_pipe; + TALLOC_CTX *tmp_ctx; + +again: + domain = wb_child_domain(); + if (domain == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + invalidate_cm_connection(&domain->conn); + + { + status = cm_connect_netlogon(domain, &netlogon_pipe); + } + + /* There is a race condition between fetching the trust account + password and the periodic machine password change. So it's + possible that the trust account password has been changed on us. + We are returned NT_STATUS_ACCESS_DENIED if this happens. */ + +#define MAX_RETRIES 3 + + if ((num_retries < MAX_RETRIES) + && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + num_retries++; + goto again; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not open handle to NETLOGON pipe\n")); + goto done; + } + + tmp_ctx = talloc_new(p->mem_ctx); + + status = trust_pw_find_change_and_store_it(netlogon_pipe, + tmp_ctx, + domain->name); + talloc_destroy(tmp_ctx); + + /* Pass back result code - zero for success, other values for + specific failures. */ + + DEBUG(3,("domain %s secret %s\n", domain->name, + 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))); + + return status; +} + + NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r) { struct id_map map; |