Пример #1
0
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:
	state->response.data.auth.nt_status = NT_STATUS_V(result);
	fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
	fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
	state->response.data.auth.pam_error = nt_status_to_pam(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;
}
Пример #2
0
enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
					     struct winbindd_cli_state *state)
{
	fstring dcname_slash;
	char *p;
	struct rpc_pipe_client *netlogon_pipe;
	NTSTATUS result;
	WERROR werr;
	unsigned int orig_timeout;

	state->request.domain_name
		[sizeof(state->request.domain_name)-1] = '\0';

	DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
		  state->request.domain_name));

	result = cm_connect_netlogon(domain, &netlogon_pipe);

	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
		return WINBINDD_ERROR;
	}

	/* This call can take a long time - allow the server to time out.
	   35 seconds should do it. */

	orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);

	werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, domain->dcname,
					    state->request.domain_name,
					    dcname_slash);
	/* And restore our original timeout. */
	cli_set_timeout(netlogon_pipe->cli, orig_timeout);

	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(5, ("Error requesting DCname: %s\n", dos_errstr(werr)));
		return WINBINDD_ERROR;
	}

	p = dcname_slash;
	if (*p == '\\') {
		p+=1;
	}
	if (*p == '\\') {
		p+=1;
	}

	fstrcpy(state->response.data.dc_name, p);
	return WINBINDD_OK;
}
Пример #3
0
enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
					     struct winbindd_cli_state *state)
{
	const char *dcname_slash = NULL;
	const char *p;
	struct rpc_pipe_client *netlogon_pipe;
	NTSTATUS result;
	WERROR werr;
	unsigned int orig_timeout;
	struct winbindd_domain *req_domain;

	state->request->domain_name
		[sizeof(state->request->domain_name)-1] = '\0';

	DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
		  state->request->domain_name));

	result = cm_connect_netlogon(domain, &netlogon_pipe);

	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
		return WINBINDD_ERROR;
	}

	/* This call can take a long time - allow the server to time out.
	   35 seconds should do it. */

	orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);

	req_domain = find_domain_from_name_noinit(state->request->domain_name);
	if (req_domain == domain) {
		result = rpccli_netr_GetDcName(netlogon_pipe,
					       state->mem_ctx,
					       domain->dcname,
					       state->request->domain_name,
					       &dcname_slash,
					       &werr);
	} else {
		result = rpccli_netr_GetAnyDCName(netlogon_pipe,
						  state->mem_ctx,
						  domain->dcname,
						  state->request->domain_name,
						  &dcname_slash,
						  &werr);
	}
	/* And restore our original timeout. */
	rpccli_set_timeout(netlogon_pipe, orig_timeout);

	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(5,("Error requesting DCname for domain %s: %s\n",
			state->request->domain_name, nt_errstr(result)));
		return WINBINDD_ERROR;
	}

	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(5, ("Error requesting DCname for domain %s: %s\n",
			state->request->domain_name, win_errstr(werr)));
		return WINBINDD_ERROR;
	}

	p = dcname_slash;
	if (*p == '\\') {
		p+=1;
	}
	if (*p == '\\') {
		p+=1;
	}

	fstrcpy(state->response->data.dc_name, p);
	return WINBINDD_OK;
}