Пример #1
0
NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
				    const char *server,
				    struct sockaddr_storage *pss,
				    unsigned flags, struct cli_state **pcli)
{
	char *server_name = NULL;
	struct sockaddr_storage server_ss;
	struct cli_state *cli = NULL;
	NTSTATUS nt_status;

	if ( !server || !pss ) {
		if (!net_find_server(c, domain, flags, &server_ss,
				     &server_name)) {
			d_fprintf(stderr, _("Unable to find a suitable server "
				"for domain %s\n"), domain);
			nt_status = NT_STATUS_UNSUCCESSFUL;
			goto done;
		}
	} else {
		server_name = SMB_STRDUP( server );
		server_ss = *pss;
	}

	if (flags & NET_FLAGS_ANONYMOUS) {
		nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
						     server_name);
	} else {
		nt_status = connect_to_ipc(c, &cli, &server_ss,
					   server_name);
	}

	/* store the server in the affinity cache if it was a PDC */

	if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
		saf_store( cli->server_domain, cli->desthost );

	SAFE_FREE(server_name);
	if (!NT_STATUS_IS_OK(nt_status)) {
		d_fprintf(stderr, _("Connection failed: %s\n"),
			  nt_errstr(nt_status));
		cli = NULL;
	} else if (c->opt_request_timeout) {
		cli_set_timeout(cli, c->opt_request_timeout * 1000);
	}

done:
	if (pcli != NULL) {
		*pcli = cli;
	}
	return nt_status;
}
Пример #2
0
struct cli_state *net_make_ipc_connection_ex( const char *domain, const char *server,
                                              struct in_addr *ip, unsigned flags)
{
	char *server_name = NULL;
	struct in_addr server_ip;
	struct cli_state *cli = NULL;
	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;

	if ( !server || !ip ) {
		if (!net_find_server(domain, flags, &server_ip, &server_name)) {
			d_fprintf(stderr, "Unable to find a suitable server\n");
			return NULL;
		}
	} else {
		server_name = SMB_STRDUP( server );
		server_ip = *ip;
	}

	if (opt_user_name) {
		nt_status = connect_to_ipc(&cli, &server_ip, server_name);
		if (NT_STATUS_IS_OK(nt_status)) {
			goto connected;
		}
	}
	if (flags & NET_FLAGS_ANONYMOUS) {
		nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name);
		if (NT_STATUS_IS_OK(nt_status)) {
			goto connected;
		}
	}

	SAFE_FREE(server_name);
	d_fprintf(stderr, "Connection failed: %s\n",
		  nt_errstr(nt_status));
	return NULL;

 connected:
	/* store the server in the affinity cache if it was a PDC */

	if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
		saf_store( cli->server_domain, cli->desthost );

	return cli;
}
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
					const struct auth_usersupplied_info *user_info,
					const char *domain,
					uchar chal[8],
					struct auth_serversupplied_info **server_info,
					const char *dc_name,
					const struct sockaddr_storage *dc_ss)

{
	TALLOC_CTX *frame = talloc_stackframe();
	struct netr_SamInfo3 *info3 = NULL;
	struct cli_state *cli = NULL;
	struct rpc_pipe_client *netlogon_pipe = NULL;
	struct netlogon_creds_cli_context *netlogon_creds = NULL;
	NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
	int i;
	uint8_t authoritative = 0;
	uint32_t flags = 0;

	/*
	 * At this point, smb_apasswd points to the lanman response to
	 * the challenge in local_challenge, and smb_ntpasswd points to
	 * the NT response to the challenge in local_challenge. Ship
	 * these over the secure channel to a domain controller and
	 * see if they were valid.
	 */

	/* rety loop for robustness */

	for (i = 0; !NT_STATUS_IS_OK(nt_status) && (i < 3); i++) {
		nt_status = connect_to_domain_password_server(&cli,
							domain,
							dc_name,
							dc_ss,
							&netlogon_pipe,
							frame,
							&netlogon_creds);
	}

	if ( !NT_STATUS_IS_OK(nt_status) ) {
		DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
		TALLOC_FREE(frame);
		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
			return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE;
		}
		return nt_status;
	}

	/* store a successful connection */

	saf_store(domain, dc_name);

        /*
         * If this call succeeds, we now have lots of info about the user
         * in the info3 structure.  
         */

	nt_status = rpccli_netlogon_network_logon(netlogon_creds,
						  netlogon_pipe->binding_handle,
						  mem_ctx,
						  user_info->logon_parameters,         /* flags such as 'allow workstation logon' */
						  user_info->client.account_name,      /* user name logging on. */
						  user_info->client.domain_name,       /* domain name */
						  user_info->workstation_name,         /* workstation name */
						  chal,                                /* 8 byte challenge. */
						  user_info->password.response.lanman, /* lanman 24 byte response */
						  user_info->password.response.nt,     /* nt 24 byte response */
						  &authoritative,
						  &flags,
						  &info3);                             /* info3 out */

	/* Let go as soon as possible so we avoid any potential deadlocks
	   with winbind lookup up users or groups. */

	TALLOC_FREE(mutex);

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0,("domain_client_validate: unable to validate password "
                         "for user %s in domain %s to Domain controller %s. "
                         "Error was %s.\n", user_info->client.account_name,
                         user_info->client.domain_name, dc_name,
                         nt_errstr(nt_status)));

		/* map to something more useful */
		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) {
			nt_status = NT_STATUS_NO_LOGON_SERVERS;
		}
	} else {
		nt_status = make_server_info_info3(mem_ctx,
						   user_info->client.account_name,
						   domain,
						   server_info,
						   info3);

		if (NT_STATUS_IS_OK(nt_status)) {
			(*server_info)->nss_token |= user_info->was_mapped;
			netsamlogon_cache_store(user_info->client.account_name, info3);
			TALLOC_FREE(info3);
		}
	}

	/* Note - once the cli stream is shutdown the mem_ctx used
	   to allocate the other_sids and gids structures has been deleted - so
	   these pointers are no longer valid..... */

	cli_shutdown(cli);
	TALLOC_FREE(frame);
	return nt_status;
}