Ejemplo n.º 1
0
/****************************************************************************
establishes a connection right up to doing tconX, reading in a password.
****************************************************************************/
BOOL cli_establish_connection(struct cli_state *cli,
			      char *dest_host, struct in_addr *dest_ip,
			      struct nmb_name *calling,
			      struct nmb_name *called, char *service,
			      char *service_type, BOOL do_shutdown,
			      BOOL do_tcon)
{
	cli->dbg(5,
		 "cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
		 nmb_namestr(calling), nmb_namestr(called),
		 inet_ntoa(*dest_ip), cli->user_name, cli->domain);

	/* establish connection */

	if ((!cli->initialised))
	{
		return False;
	}

	if (!cli_connect(cli, dest_host, dest_ip))
	{
		cli->dbg(1,
			 "cli_establish_connection: failed to connect to %s (%s)\n",
			 nmb_namestr(calling), inet_ntoa(*dest_ip));
		return False;
	}

	if (!cli_session_request(cli, calling, called))
	{
		cli->dbg(1, "failed session request\n");
		if (do_shutdown)
			cli_shutdown(cli);
		return False;
	}

	if (!cli_negprot(cli))
	{
		cli->dbg(1, "failed negprot\n");
		if (do_shutdown)
			cli_shutdown(cli);
		return False;
	}

	if (cli->pwd.cleartext || cli->pwd.null_pwd)
	{
		fstring passwd;
		int pass_len;

		if (cli->pwd.null_pwd)
		{
			/* attempt null session */
			passwd[0] = 0;
			pass_len = 1;
		}
		else
		{
			/* attempt clear-text session */
			pwd_get_cleartext(&(cli->pwd), passwd);
			pass_len = strlen(passwd);
		}

		/* attempt clear-text session */
		if (!cli_session_setup(cli, cli->user_name,
				       passwd, pass_len,
				       NULL, 0, cli->domain))
		{
			cli->dbg(1, "failed session setup\n");
			if (do_shutdown)
			{
				cli_shutdown(cli);
			}
			return False;
		}
		if (do_tcon)
		{
			if (!cli_send_tconX(cli, service, service_type,
					    (char *)passwd, strlen(passwd)))
			{
				cli->dbg(1, "failed tcon_X\n");
				if (do_shutdown)
				{
					cli_shutdown(cli);
				}
				return False;
			}
		}
	}
	else
	{
		/* attempt encrypted session */
		unsigned char nt_sess_pwd[24];
		unsigned char lm_sess_pwd[24];

		/* creates (storing a copy of) and then obtains a 24 byte password OWF */
		pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
		pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);

		/* attempt encrypted session */
		if (!cli_session_setup(cli, cli->user_name,
				       (char *)lm_sess_pwd,
				       sizeof(lm_sess_pwd),
				       (char *)nt_sess_pwd,
				       sizeof(nt_sess_pwd), cli->domain))
		{
			cli->dbg(1, "failed session setup\n");
			if (do_shutdown)
				cli_shutdown(cli);
			return False;
		}

		if (do_tcon)
		{
			if (!cli_send_tconX(cli, service, service_type,
					    (char *)nt_sess_pwd,
					    sizeof(nt_sess_pwd)))
			{
				cli->dbg(1, "failed tcon_X\n");
				if (do_shutdown)
					cli_shutdown(cli);
				return False;
			}
		}
	}

	if (do_shutdown)
		cli_shutdown(cli);

	return True;
}
Ejemplo n.º 2
0
static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name)
{
	RPC_IFACE abstract;
	RPC_IFACE transfer;
	prs_struct rpc_out;
	prs_struct rdata;
	uint32 rpc_call_id;
	char buffer[MAX_PDU_FRAG_LEN];

	if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) )
		return False;

	DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_names[pipe_idx].client_pipe));

	if (!valid_pipe_name(pipe_idx, &abstract, &transfer))
		return False;

	prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL);

	/*
	 * Use the MAX_PDU_FRAG_LEN buffer to store the bind request.
	 */

	prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);

	rpc_call_id = get_rpc_call_id();

	if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
		NTSTATUS nt_status;
		fstring password;

		DEBUG(5, ("NTLMSSP authenticated pipe selected\n"));

		nt_status = ntlmssp_client_start(&cli->ntlmssp_pipe_state);
		
		if (!NT_STATUS_IS_OK(nt_status))
			return False;

		/* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */

		cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;

		nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, 
						 cli->user_name);
		if (!NT_STATUS_IS_OK(nt_status))
			return False;

		nt_status = ntlmssp_set_domain(cli->ntlmssp_pipe_state, 
					       cli->domain);	
		if (!NT_STATUS_IS_OK(nt_status))
			return False;

		if (cli->pwd.null_pwd) {
			nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, 
							 NULL);
			if (!NT_STATUS_IS_OK(nt_status))
				return False;
		} else {
			pwd_get_cleartext(&cli->pwd, password);
			nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, 
							 password);
			if (!NT_STATUS_IS_OK(nt_status))
				return False;
		}

		if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
			cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
		}

		if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
			cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
		}
	} else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
		cli->auth_info.seq_num = 0;
	}

	/* Marshall the outgoing data. */
	create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
	                    &abstract, &transfer,
	                    global_myname(), cli->domain);

	/* Initialize the incoming data struct. */
	prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);

	/* send data on \PIPE\.  receive a response */
	if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) {
		RPC_HDR_BA   hdr_ba;

		DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n"));

		if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0)) {
			DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
			prs_mem_free(&rdata);
			return False;
		}

		if(!check_bind_response(&hdr_ba, pipe_idx, &transfer)) {
			DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
			prs_mem_free(&rdata);
			return False;
		}

		cli->max_xmit_frag = hdr_ba.bba.max_tsize;
		cli->max_recv_frag = hdr_ba.bba.max_rsize;

		/*
		 * If we're doing NTLMSSP auth we need to send a reply to
		 * the bind-ack to complete the 3-way challenge response
		 * handshake.
		 */

		if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) 
		    && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
			DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n"));
			prs_mem_free(&rdata);
			return False;
		}
		prs_mem_free(&rdata);
		return True;
	}

	return False;
}