r->out.result = WINBIND_STATUS_OK;
}
+static void ndr_child_trust_compat_check_machcc(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state,
+ struct winbind_trust *r)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ int num_retries = 0;
+ struct winbindd_domain *contact_domain;
+
+ DEBUG(3, ("check machine account\n"));
+
+ /* 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:
+
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("Checking the trust account password returned %s\n",
+ nt_errstr(result)));
+
+ if (NT_STATUS_IS_OK(result)) {
+ r->out.result = WINBIND_STATUS_OK;
+ } else {
+ r->out.result = WINBIND_STATUS_FOOBAR;
+ }
+}
+
void winbindd_ndr_domain_child_trust(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
case WINBIND_TRUST_LEVEL_COMPAT_LIST:
ndr_child_trust_compat_list(domain, state, r);
return;
+ case WINBIND_TRUST_LEVEL_COMPAT_CHECK_MACHCC:
+ ndr_child_trust_compat_check_machcc(domain, state, r);
+ return;
}
r->out.result = WINBIND_STATUS_UNKNOWN_LEVEL;