summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/winbindd.c3
-rw-r--r--source3/winbindd/winbindd_check_machine_acct.c88
-rw-r--r--source3/winbindd/winbindd_domain.c4
-rw-r--r--source3/winbindd/winbindd_dual_srv.c52
-rw-r--r--source3/winbindd/winbindd_misc.c68
-rw-r--r--source3/winbindd/winbindd_proto.h6
6 files changed, 148 insertions, 73 deletions
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index e5468e38a9..7c1281247e 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -446,7 +446,6 @@ static struct winbindd_dispatch_table {
/* Miscellaneous */
- { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct, "CHECK_MACHACC" },
{ WINBINDD_INFO, winbindd_info, "INFO" },
{ WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
"INTERFACE_VERSION" },
@@ -537,6 +536,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
winbindd_list_users_send, winbindd_list_users_recv },
{ WINBINDD_LIST_GROUPS, "LIST_GROUPS",
winbindd_list_groups_send, winbindd_list_groups_recv },
+ { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
+ winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
{ 0, NULL, NULL, NULL }
};
diff --git a/source3/winbindd/winbindd_check_machine_acct.c b/source3/winbindd/winbindd_check_machine_acct.c
new file mode 100644
index 0000000000..e3505cb352
--- /dev/null
+++ b/source3/winbindd/winbindd_check_machine_acct.c
@@ -0,0 +1,88 @@
+/*
+ Unix SMB/CIFS implementation.
+ async implementation of WINBINDD_CHECK_MACHINE_ACCT
+ Copyright (C) Volker Lendecke 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
+ 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 "winbindd.h"
+#include "librpc/gen_ndr/cli_wbint.h"
+
+struct winbindd_check_machine_acct_state {
+ uint8_t dummy;
+};
+
+static void winbindd_check_machine_acct_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct winbindd_cli_state *cli,
+ struct winbindd_request *request)
+{
+ struct tevent_req *req, *subreq;
+ struct winbindd_check_machine_acct_state *state;
+ struct winbindd_domain *domain;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct winbindd_check_machine_acct_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ domain = find_our_domain();
+ if (domain->internal) {
+ /*
+ * Internal domains are passdb based, we can always
+ * contact them.
+ */
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = rpccli_wbint_CheckMachineAccount_send(state, ev,
+ domain->child.rpccli);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, winbindd_check_machine_acct_done, req);
+ return req;
+}
+
+static void winbindd_check_machine_acct_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct winbindd_check_machine_acct_state *state = tevent_req_data(
+ req, struct winbindd_check_machine_acct_state);
+ NTSTATUS status, result;
+
+ status = rpccli_wbint_CheckMachineAccount_recv(subreq, state, &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ tevent_req_nterror(req, result);
+ return;
+ }
+ tevent_req_done(req);
+}
+
+NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req,
+ struct winbindd_response *presp)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c
index 96cbf6f746..ad3d6d7916 100644
--- a/source3/winbindd/winbindd_domain.c
+++ b/source3/winbindd/winbindd_domain.c
@@ -75,10 +75,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
.struct_cmd = WINBINDD_PAM_CHAUTHTOK,
.struct_fn = winbindd_dual_pam_chauthtok,
},{
- .name = "CHECK_MACHACC",
- .struct_cmd = WINBINDD_CHECK_MACHACC,
- .struct_fn = winbindd_dual_check_machine_acct,
- },{
.name = "DUAL_USERINFO",
.struct_cmd = WINBINDD_DUAL_USERINFO,
.struct_fn = winbindd_dual_userinfo,
diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c
index 3b6107a398..b36bfbf93b 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -395,3 +395,55 @@ NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r)
r->out.names->principals = result;
return NT_STATUS_OK;
}
+
+NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p,
+ struct wbint_CheckMachineAccount *r)
+{
+ struct winbindd_domain *domain;
+ int num_retries = 0;
+ NTSTATUS status;
+
+again:
+ domain = wb_child_domain();
+ if (domain == NULL) {
+ return NT_STATUS_REQUEST_NOT_ACCEPTED;
+ }
+
+ invalidate_cm_connection(&domain->conn);
+
+ {
+ struct rpc_pipe_client *netlogon_pipe;
+ 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;
+ }
+
+ /* 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"));
+
+ done:
+ DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
+ ("Checking the trust account password returned %s\n",
+ nt_errstr(status)));
+
+ return status;
+}
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index 606a4e105b..9e62a1b102 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -26,74 +26,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
-/* Check the machine account password is valid */
-
-void winbindd_check_machine_acct(struct winbindd_cli_state *state)
-{
- DEBUG(3, ("[%5lu]: check machine account\n",
- (unsigned long)state->pid));
-
- sendto_domain(state, find_our_domain());
-}
-
-enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- int num_retries = 0;
- struct winbindd_domain *contact_domain;
-
- DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
-
- /* Get trust account password */
-
- again:
-
- contact_domain = find_our_domain();
-
- /* This call does a cli_nt_setup_creds() which implicitly checks
- the trust account password. */
-
- invalidate_cm_connection(&contact_domain->conn);
-
- {
- struct rpc_pipe_client *netlogon_pipe;
- result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
- goto done;
- }
-
- /* 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 8
-
- if ((num_retries < MAX_RETRIES) &&
- NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
- num_retries++;
- goto again;
- }
-
- /* Pass back result code - zero for success, other values for
- specific failures. */
-
- DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
- "good" : "bad"));
-
- done:
- set_auth_errors(state->response, result);
-
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n",
- state->response->data.auth.nt_status_string));
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
/* Constants and helper functions for determining domain trust types */
enum trust_type {
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 086fa52563..9675430ec2 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -962,5 +962,11 @@ struct tevent_req *winbindd_list_groups_send(TALLOC_CTX *mem_ctx,
NTSTATUS winbindd_list_groups_recv(struct tevent_req *req,
struct winbindd_response *response);
+struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct winbindd_cli_state *cli,
+ struct winbindd_request *request);
+NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req,
+ struct winbindd_response *presp);
#endif /* _WINBINDD_PROTO_H_ */