Example #1
0
NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
{
	prs_struct rbuf;
	prs_struct qbuf; 
	SHUTDOWN_Q_ABORT q_s;
	SHUTDOWN_R_ABORT r_s;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;

	ZERO_STRUCT (q_s);
	ZERO_STRUCT (r_s);

	prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
	
	/* Marshall data and send request */

	init_shutdown_q_abort(&q_s);

	if (!shutdown_io_q_abort("", &q_s, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_ABORT, &qbuf, &rbuf))
	    	goto done;
	
		/* Unmarshall response */
	
	if (shutdown_io_r_abort("", &r_s, &rbuf, 0))
		result = r_s.status;

done:
	prs_mem_free(&rbuf);
	prs_mem_free(&qbuf );

	return result;
}
Example #2
0
NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
			    WKS_INFO_100 *wks100)
{
	prs_struct buf;
	prs_struct rbuf;
	WKS_Q_QUERY_INFO q_o;
	WKS_R_QUERY_INFO r_o;

	if (cli == NULL || wks100 == NULL)
		return NT_STATUS_UNSUCCESSFUL;

	/* init rpc parse structures */
	prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	DEBUG(4, ("WksQueryInfo\n"));
	
	/* init query structure with rpc call arguments */
	init_wks_q_query_info(&q_o, cli->desthost, 100);
	
	/* marshall data */
	if (!wks_io_q_query_info("", &q_o, &buf, 0)) {
		prs_mem_free(&buf);
		prs_mem_free(&rbuf);
		return NT_STATUS_UNSUCCESSFUL;
	}
	
	/* actual rpc call over \PIPE\wkssvc */
	if (!rpc_api_pipe_req(cli, PI_WKSSVC, WKS_QUERY_INFO, &buf, &rbuf)) {
		prs_mem_free(&buf);
		prs_mem_free(&rbuf);
		return NT_STATUS_UNSUCCESSFUL;
	}
	
	prs_mem_free(&buf);

	r_o.wks100 = wks100;

	/* get call results from response buffer */
	if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
		prs_mem_free(&rbuf);
		return NT_STATUS_UNSUCCESSFUL;
	}
	
	/* check returnet status code */
	if (NT_STATUS_IS_ERR(r_o.status)) {
		/* report the error */
		DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status)));
		prs_mem_free(&rbuf);
		return r_o.status;
	}
	
	/* do clean up */
	prs_mem_free(&rbuf);
	
	return NT_STATUS_OK;
}
Example #3
0
/**********************************************************************
 Initialize a new spoolss buff for use by a client rpc
**********************************************************************/
void rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
{
	buffer->size = size;
	buffer->string_at_end = size;
	prs_init(&buffer->prs, size, ctx, MARSHALL);
	buffer->struct_start = prs_offset(&buffer->prs);
}
Example #4
0
static BOOL pipe_init_outgoing_data(pipes_struct *p)
{
	output_data *o_data = &p->out_data;

	/* Reset the offset counters. */
	o_data->data_sent_length = 0;
	o_data->current_pdu_len = 0;
	o_data->current_pdu_sent = 0;

	memset(o_data->current_pdu, '\0', sizeof(o_data->current_pdu));

	/* Free any memory in the current return data buffer. */
	prs_mem_free(&o_data->rdata);

	/*
	 * Initialize the outgoing RPC data buffer.
	 * we will use this as the raw data area for replying to rpc requests.
	 */	
	if(!prs_init(&o_data->rdata, RPC_MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
		DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
		return False;
	}

	return True;
}
Example #5
0
static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, 
				    struct winbindd_cli_state *state, 
				    NET_USER_INFO_3 *info3) 
{
	prs_struct ps;
	uint32 size;
	if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
		return NT_STATUS_NO_MEMORY;
	}
	if (!net_io_user_info3("", info3, &ps, 1, 3)) {
		prs_mem_free(&ps);
		return NT_STATUS_UNSUCCESSFUL;
	}

	size = prs_data_size(&ps);
	state->response.extra_data = malloc(size);
	if (!state->response.extra_data) {
		prs_mem_free(&ps);
		return NT_STATUS_NO_MEMORY;
	}
	memset( state->response.extra_data, '\0', size );
	prs_copy_all_data_out(state->response.extra_data, &ps);
	state->response.length += size;
	prs_mem_free(&ps);
	return NT_STATUS_OK;
}
Example #6
0
WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				 char *server, TIME_OF_DAY_INFO *tod)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_REMOTE_TOD q;
	SRV_R_NET_REMOTE_TOD r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_remote_tod(&q, cli->srv_name_slash);

	/* Marshall data and send request */

	if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	r.tod = tod;

	if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0))
		goto done;

	result = r.status;

	if (!W_ERROR_IS_OK(result))
		goto done;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;	
}
Example #7
0
WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli, 
				   TALLOC_CTX *mem_ctx,
				   uint32 switch_value, SRV_INFO_CTR *ctr)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SRV_GET_INFO q;
	SRV_R_NET_SRV_GET_INFO r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);

	/* Marshall data and send request */

	if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	r.ctr = ctr;

	if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0))
		goto done;

	result = r.status;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;
}
Example #8
0
/*******************************************************************
creates a new prs_struct containing a DATA_BLOB
********************************************************************/
bool prs_init_data_blob(prs_struct *prs, DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
{
	if (!prs_init( prs, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL ))
		return False;


	if (!prs_copy_data_in(prs, (char *)blob->data, blob->length))
		return False;

	return True;
}
Example #9
0
WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				const char *netname, uint32 type, 
				const char *remark, uint32 perms, 
				uint32 max_uses, uint32 num_uses, 
				const char *path, const char *passwd)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SHARE_ADD q;
	SRV_R_NET_SHARE_ADD r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark,
				 perms, max_uses, num_uses, path, passwd);

	/* Marshall data and send request */

	if (!srv_io_q_net_share_add("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	if (!srv_io_r_net_share_add("", &r, &rbuf, 0))
		goto done;

	result = r.status;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;	
}
Example #10
0
BOOL prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer)
{
	prs_debug(ps, depth, desc, "prs_rpcbuffer");
	depth++;

	/* reading */
	if (UNMARSHALLING(ps)) {
		buffer->size=0;
		buffer->string_at_end=0;
		
		if (!prs_uint32("size", ps, depth, &buffer->size))
			return False;
					
		/*
		 * JRA. I'm not sure if the data in here is in big-endian format if
		 * the client is big-endian. Leave as default (little endian) for now.
		 */

		if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
			return False;

		if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
			return False;

		if (!prs_set_offset(&buffer->prs, 0))
			return False;

		if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
			return False;

		buffer->string_at_end=buffer->size;
		
		return True;
	}
	else {
		BOOL ret = False;

		if (!prs_uint32("size", ps, depth, &buffer->size))
			goto out;

		if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
			goto out;

		ret = True;
	out:

		/* We have finished with the data in buffer->prs - free it. */
		prs_mem_free(&buffer->prs);

		return ret;
	}
}
Example #11
0
WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				const char *sharename)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SHARE_DEL q;
	SRV_R_NET_SHARE_DEL r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename);

	/* Marshall data and send request */

	if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
		goto done;

	result = r.status;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;
}
Example #12
0
NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
			   const char *msg, uint32 timeout, BOOL do_reboot,
			   BOOL force)
{
	prs_struct qbuf;
	prs_struct rbuf; 
	SHUTDOWN_Q_INIT q_s;
	SHUTDOWN_R_INIT r_s;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;

	if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;

	ZERO_STRUCT (q_s);
	ZERO_STRUCT (r_s);

	prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Marshall data and send request */

	init_shutdown_q_init(&q_s, msg, timeout, do_reboot, force);

	if (!shutdown_io_q_init("", &q_s, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_INIT, &qbuf, &rbuf))
		goto done;
	
	/* Unmarshall response */
	
	if(shutdown_io_r_init("", &r_s, &rbuf, 0))
		result = r_s.status;

done:
	prs_mem_free(&rbuf);
	prs_mem_free(&qbuf);

	return result;
}
Example #13
0
/* useful function to fetch a structure into rpc wire format */
int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *mem_ctx)
{
    TDB_DATA kbuf, dbuf;
    kbuf.dptr = keystr;
    kbuf.dsize = strlen(keystr)+1;

    dbuf = tdb_fetch(tdb, kbuf);
    if (!dbuf.dptr) return -1;

    ZERO_STRUCTP(ps);
    prs_init(ps, 0, mem_ctx, UNMARSHALL);
    prs_give_memory(ps, dbuf.dptr, dbuf.dsize, True);

    return 0;
} 
Example #14
0
/****************************************************************************
  query the security descriptor for a open file
 ****************************************************************************/
SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, 
			    TALLOC_CTX *mem_ctx)
{
	char param[8];
	char *rparam=NULL, *rdata=NULL;
	unsigned int rparam_count=0, rdata_count=0;
	prs_struct pd;
	SEC_DESC *psd = NULL;

	SIVAL(param, 0, fnum);
	SIVAL(param, 4, 0x7);

	if (!cli_send_nt_trans(cli, 
			       NT_TRANSACT_QUERY_SECURITY_DESC, 
			       0, 
			       NULL, 0, 0,
			       param, 8, 4,
			       NULL, 0, 0x10000)) {
		DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n"));
		goto cleanup;
	}


	if (!cli_receive_nt_trans(cli, 
				  &rparam, &rparam_count,
				  &rdata, &rdata_count)) {
		DEBUG(1,("Failed to recv NT_TRANSACT_QUERY_SECURITY_DESC\n"));
		goto cleanup;
	}

	prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL);
	prs_copy_data_in(&pd, rdata, rdata_count);
	prs_set_offset(&pd,0);

	if (!sec_io_desc("sd data", &psd, &pd, 1)) {
		DEBUG(1,("Failed to parse secdesc\n"));
		goto cleanup;
	}

 cleanup:

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	prs_mem_free(&pd);
	return psd;
}
Example #15
0
BOOL set_share_security(const char *share_name, SEC_DESC *psd)
{
	prs_struct ps;
	TALLOC_CTX *mem_ctx = NULL;
	fstring key;
	BOOL ret = False;

	if (!share_info_db_init()) {
		return False;
	}

	mem_ctx = talloc_init("set_share_security");
	if (mem_ctx == NULL)
		return False;

	prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
 
	if (!sec_io_desc("share_security", &psd, &ps, 1))
		goto out;
 
	slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
 
	if (tdb_prs_store(share_tdb, key, &ps)==0) {
		ret = True;
		DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
	} else {
		DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
	} 

	/* Free malloc'ed memory */
 
out:
 
	prs_mem_free(&ps);
	if (mem_ctx)
		talloc_destroy(mem_ctx);
	return ret;
}
Example #16
0
static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id)
{
	prs_struct rpc_out;
	ssize_t ret;

	prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ 
		 cli->mem_ctx, MARSHALL);

	if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id,
						  &rpc_out))) {
		return False;
	}

	if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out), 
			0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
		DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret));
		prs_mem_free(&rpc_out);
		return False;
	}

	prs_mem_free(&rpc_out);
	return True;
}
Example #17
0
static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
{
	uint8 *info3_ndr;
	size_t len = response->length - sizeof(struct winbindd_response);
	prs_struct ps;
	if (len > 0) {
		info3_ndr = response->extra_data;
		if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
			return NT_STATUS_NO_MEMORY;
		}
		prs_copy_data_in(&ps, (char *)info3_ndr, len);
		prs_set_offset(&ps,0);
		if (!net_io_user_info3("", info3, &ps, 1, 3)) {
			DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
			return NT_STATUS_UNSUCCESSFUL;
		}
		prs_mem_free(&ps);

		return NT_STATUS_OK;
	} else {
		DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}
}
Example #18
0
BOOL create_next_pdu(pipes_struct *p)
{
	RPC_HDR_RESP hdr_resp;
	BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
	BOOL auth_seal   = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
	uint32 ss_padding_len = 0;
	uint32 data_len;
	uint32 data_space_available;
	uint32 data_len_left;
	prs_struct outgoing_pdu;
	uint32 data_pos;

	/*
	 * If we're in the fault state, keep returning fault PDU's until
	 * the pipe gets closed. JRA.
	 */

	if(p->fault_state) {
		setup_fault_pdu(p, NT_STATUS(0x1c010002));
		return True;
	}

	memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));

	/* Change the incoming request header to a response. */
	p->hdr.pkt_type = RPC_RESPONSE;

	/* Set up rpc header flags. */
	if (p->out_data.data_sent_length == 0) {
		p->hdr.flags = RPC_FLG_FIRST;
	} else {
		p->hdr.flags = 0;
	}

	/*
	 * Work out how much we can fit in a single PDU.
	 */

	data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
	if(p->ntlmssp_auth_validated) {
		data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
	} else if(p->netsec_auth_validated) {
		data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN);
	}

	/*
	 * The amount we send is the minimum of the available
	 * space and the amount left to send.
	 */

	data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;

	/*
	 * Ensure there really is data left to send.
	 */

	if(!data_len_left) {
		DEBUG(0,("create_next_pdu: no data left to send !\n"));
		return False;
	}

	data_len = MIN(data_len_left, data_space_available);

	/*
	 * Set up the alloc hint. This should be the data left to
	 * send.
	 */

	hdr_resp.alloc_hint = data_len_left;

	/*
	 * Work out if this PDU will be the last.
	 */

	if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
		p->hdr.flags |= RPC_FLG_LAST;
		if ((auth_seal || auth_verify) && (data_len_left % 8)) {
			ss_padding_len = 8 - (data_len_left % 8);
			DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n",
				ss_padding_len ));
		}
	}

	/*
	 * Set up the header lengths.
	 */

	if (p->ntlmssp_auth_validated) {
		p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
			data_len + ss_padding_len +
			RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
		p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
	} else if (p->netsec_auth_validated) {
		p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
			data_len + ss_padding_len +
			RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
		p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
	} else {
		p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
		p->hdr.auth_len = 0;
	}

	/*
	 * Init the parse struct to point at the outgoing
	 * data.
	 */

	prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
	prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);

	/* Store the header in the data stream. */
	if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
		DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
		prs_mem_free(&outgoing_pdu);
		return False;
	}

	if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
		DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
		prs_mem_free(&outgoing_pdu);
		return False;
	}

	/* Store the current offset. */
	data_pos = prs_offset(&outgoing_pdu);

	/* Copy the data into the PDU. */

	if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
		DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
		prs_mem_free(&outgoing_pdu);
		return False;
	}

	/* Copy the sign/seal padding data. */
	if (ss_padding_len) {
		char pad[8];
		memset(pad, '\0', 8);
		if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
			DEBUG(0,("create_next_pdu: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
			prs_mem_free(&outgoing_pdu);
			return False;
		}
	}

	if (p->ntlmssp_auth_validated) {
		/*
		 * NTLMSSP processing. Mutually exclusive with Schannel.
		 */
		uint32 crc32 = 0;
		char *data;

		DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
			 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len + ss_padding_len, p->hdr.auth_len));

		/*
		 * Set data to point to where we copied the data into.
		 */

		data = prs_data_p(&outgoing_pdu) + data_pos;

		if (auth_seal) {
			crc32 = crc32_calc_buffer(data, data_len + ss_padding_len);
			NTLMSSPcalc_p(p, (uchar*)data, data_len + ss_padding_len);
		}

		if (auth_seal || auth_verify) {
			RPC_HDR_AUTH auth_info;

			init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE,
					auth_seal ? RPC_PIPE_AUTH_SEAL_LEVEL : RPC_PIPE_AUTH_SIGN_LEVEL,
					(auth_verify ? ss_padding_len : 0), (auth_verify ? 1 : 0));
			if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
				DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
				prs_mem_free(&outgoing_pdu);
				return False;
			}
		}

		if (auth_verify) {
			RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
			char *auth_data = prs_data_p(&outgoing_pdu);

			p->ntlmssp_seq_num++;
			init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
					crc32, p->ntlmssp_seq_num++);
			auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
			if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
				DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
				prs_mem_free(&outgoing_pdu);
				return False;
			}
			NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
		}
	} else if (p->netsec_auth_validated) {
		/*
		 * Schannel processing. Mutually exclusive with NTLMSSP.
		 */
		int auth_type, auth_level;
		char *data;
		RPC_HDR_AUTH auth_info;

		RPC_AUTH_NETSEC_CHK verf;
		prs_struct rverf;
		prs_struct rauth;

		data = prs_data_p(&outgoing_pdu) + data_pos;
		/* Check it's the type of reply we were expecting to decode */

		get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level);
		init_rpc_hdr_auth(&auth_info, auth_type, auth_level, 
				  ss_padding_len, 1);

		if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
			DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
			prs_mem_free(&outgoing_pdu);
			return False;
		}

		prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
		prs_init(&rauth, 0, p->mem_ctx, MARSHALL);

		netsec_encode(&p->netsec_auth, 
			      p->netsec_auth.auth_flags,
			      SENDER_IS_ACCEPTOR,
			      &verf, data, data_len + ss_padding_len);

		smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, 
			&verf, &outgoing_pdu, 0);

		p->netsec_auth.seq_num++;
	}

	/*
	 * Setup the counts for this PDU.
	 */

	p->out_data.data_sent_length += data_len;
	p->out_data.current_pdu_len = p->hdr.frag_len;
	p->out_data.current_pdu_sent = 0;

	prs_mem_free(&outgoing_pdu);
	return True;
}
Example #19
0
static ssize_t unmarshall_rpc_header(pipes_struct *p)
{
	/*
	 * Unmarshall the header to determine the needed length.
	 */

	prs_struct rpc_in;

	if(p->in_data.pdu_received_len != RPC_HEADER_LEN) {
		DEBUG(0,("unmarshall_rpc_header: assert on rpc header length failed.\n"));
		set_incoming_fault(p);
		return -1;
	}

	prs_init( &rpc_in, 0, 4, UNMARSHALL);
	prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
					p->in_data.pdu_received_len, False);

	/*
	 * Unmarshall the header as this will tell us how much
	 * data we need to read to get the complete pdu.
	 */

	if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
		DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
		set_incoming_fault(p);
		return -1;
	}

	/*
	 * Validate the RPC header.
	 */

	if(p->hdr.major != 5 && p->hdr.minor != 0) {
		DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
		set_incoming_fault(p);
		return -1;
	}

	/*
	 * If there is no data in the incoming buffer and it's a requst pdu then
	 * ensure that the FIRST flag is set. If not then we have
	 * a stream missmatch.
	 */

	if((p->hdr.pkt_type == RPC_REQUEST) && (prs_offset(&p->in_data.data) == 0) && !(p->hdr.flags & RPC_FLG_FIRST)) {
		DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
		set_incoming_fault(p);
		return -1;
	}

	/*
	 * Ensure that the pdu length is sane.
	 */

	if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > MAX_PDU_FRAG_LEN)) {
		DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
		set_incoming_fault(p);
		return -1;
	}

	DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
			(unsigned int)p->hdr.flags ));

	/*
	 * Adjust for the header we just ate.
	 */
	p->in_data.pdu_received_len = 0;
	p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;

	/*
	 * Null the data we just ate.
	 */

	memset((char *)&p->in_data.current_in_pdu[0], '\0', RPC_HEADER_LEN);

	return 0; /* No extra data processed. */
}
Example #20
0
static int read_block( REGF_FILE *file, prs_struct *ps, uint32 file_offset, 
		       uint32 block_size )
{
  const int hdr_size = 0x20;
  int bytes_read, returned;
  char *buffer;
  SMB_STRUCT_STAT sbuf;

  /* check for end of file */

/* Rohan: no fstat available need some other work around
  if ( fstat( file->fd, &sbuf ) ) {
    / *DEBUG(0,("read_block: stat() failed! (%s)\n", strerror(errno)));* /
    return -1;
  }

  if ( (size_t)file_offset >= sbuf.st_size )
    return -1;
	
*/

  /* if block_size == 0, we are parsnig HBIN records and need 
     to read some of the header to get the block_size from there */
	   
  if ( block_size == 0 ) {
    uint8 hdr[0x20];

    if ( file->lseek( file->fd, file_offset, SEEK_SET ) == -1 ) {
      /*DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) ));*/
      return -1;
    }

    bytes_read = returned = 0;
    while (bytes_read < hdr_size)
    {
      returned = file->read(file->fd, hdr + bytes_read, hdr_size - bytes_read);
      if(returned == -1 && errno != EINTR && errno != EAGAIN)
      {
	/*DEBUG(0,("read_block: read of hdr failed (%s)\n",strerror(errno)));*/
	return -1;
      }

      if(returned == 0)
	return -1;

      bytes_read += returned;
    }

    /* make sure this is an hbin header */

    if ( strncmp( (char*)hdr, "hbin", HBIN_HDR_SIZE ) != 0 ) {
      /*DEBUG(0,("read_block: invalid block header!\n"));*/
      return -1;
    }

    block_size = IVAL( hdr, 0x08 );
  }

  /*DEBUG(10,("read_block: block_size == 0x%x\n", block_size ));*/

  /* set the offset, initialize the buffer, and read the block from disk */

  if ( file->lseek( file->fd, file_offset, SEEK_SET ) == -1 ) {
    /*DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) ));*/
    return -1;
  }
	
  prs_init( ps, block_size, file->mem_ctx, UNMARSHALL );
  buffer = ps->data_p;
  bytes_read = returned = 0;

  while ( bytes_read < block_size ) 
  {
    returned = file->read(file->fd, buffer+bytes_read, block_size-bytes_read);
    if(returned == -1 && errno != EINTR && errno != EAGAIN)
    {
      /*DEBUG(0,("read_block: read() failed (%s)\n", strerror(errno) ));*/
      return -1;
    }

    if ((returned == 0) && (bytes_read < block_size)) 
    {
      /*DEBUG(0,("read_block: not a vald registry file ?\n" ));*/
      return -1;
    }	

    bytes_read += returned;
  }
	
  return bytes_read;
}
Example #21
0
BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                      prs_struct *data, prs_struct *rdata)
{
	uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent;
	NTSTATUS nt_status;
	BOOL ret = False;
	uint32 callid = 0;
	fstring dump_name;

	auth_len = 0;
	real_auth_len = 0;
	auth_hdr_len = 0;

	if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {	
		if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {	
			auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
		}
		if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {	
			auth_len = RPC_AUTH_NETSEC_CHK_LEN;
		}
		auth_hdr_len = RPC_HDR_AUTH_LEN;
	}

	/*
	 * calc how much actual data we can send in a PDU fragment
	 */
	max_data = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
		auth_hdr_len - auth_len - 8;
	
	for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) {
		prs_struct outgoing_packet;
		prs_struct sec_blob;
		uint32 data_len, send_size;
		uint8 flags = 0;
		uint32 auth_padding = 0;
		DATA_BLOB sign_blob;

		/*
		 * how much will we send this time
		 */
		send_size = MIN(data_left, max_data);

		if (!prs_init(&sec_blob, send_size, /* will need at least this much */
			      cli->mem_ctx, MARSHALL)) {
			DEBUG(0,("Could not malloc %u bytes",
				 send_size+auth_padding));
			return False;
		}

		if(!prs_append_some_prs_data(&sec_blob, data, 
					     data_sent, send_size)) {
			DEBUG(0,("Failed to append data to netsec blob\n"));
			prs_mem_free(&sec_blob);
			return False;
		}

		/*
		 * NT expects the data that is sealed to be 8-byte
		 * aligned. The padding must be encrypted as well and
		 * taken into account when generating the
		 * authentication verifier. The amount of padding must
		 * be stored in the auth header.
		 */

		if (cli->pipe_auth_flags) {
			size_t data_and_padding_size;
			int auth_type;
			int auth_level;
			prs_align_uint64(&sec_blob);

			get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);

			data_and_padding_size = prs_offset(&sec_blob);
			auth_padding = data_and_padding_size - send_size;

			/* insert the auth header */
			
			if(!create_auth_hdr(&sec_blob, auth_type, auth_level, auth_padding)) {
				prs_mem_free(&sec_blob);
				return False;
			}
			
			/* create an NTLMSSP signature */
			if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
				/*
				 * Seal the outgoing data if requested.
				 */
				if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
					
					nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state,
									       (unsigned char*)prs_data_p(&sec_blob),
									       data_and_padding_size,
									       &sign_blob);
					if (!NT_STATUS_IS_OK(nt_status)) {
						prs_mem_free(&sec_blob);
						return False;
					}
				} 
				else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
					
					nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state,
									       (unsigned char*)prs_data_p(&sec_blob),
									       data_and_padding_size, &sign_blob);
					if (!NT_STATUS_IS_OK(nt_status)) {
						prs_mem_free(&sec_blob);
						return False;
					}
				}
				

				/* write auth footer onto the packet */
				real_auth_len = sign_blob.length;
				
				prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length);
				data_blob_free(&sign_blob);

			}
			else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {	
				size_t parse_offset_marker;
				RPC_AUTH_NETSEC_CHK verf;
				DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
				
				netsec_encode(&cli->auth_info, 
					      cli->pipe_auth_flags,
					      SENDER_IS_INITIATOR,
					      &verf,
					      prs_data_p(&sec_blob),
					      data_and_padding_size);

				cli->auth_info.seq_num++;

				/* write auth footer onto the packet */
				
				parse_offset_marker = prs_offset(&sec_blob);
				if (!smb_io_rpc_auth_netsec_chk("", &verf,
								&sec_blob, 0)) {
					prs_mem_free(&sec_blob);
					return False;
				}
				real_auth_len = prs_offset(&sec_blob) - parse_offset_marker;
			}
		}

		data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(&sec_blob);

		/*
		 * Malloc parse struct to hold it (and enough for alignments).
		 */
		if(!prs_init(&outgoing_packet, data_len + 8, 
			     cli->mem_ctx, MARSHALL)) {
			DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len ));
			return False;
		}

		if (data_left == prs_offset(data))
			flags |= RPC_FLG_FIRST;

		if (data_left <= max_data)
			flags |= RPC_FLG_LAST;
		/*
		 * Write out the RPC header and the request header.
		 */
		if(!(callid = create_rpc_request(&outgoing_packet, op_num, 
						 data_len, real_auth_len, flags, 
						 callid, data_left))) {
			DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n"));
			prs_mem_free(&outgoing_packet);
			prs_mem_free(&sec_blob);
			return False;
		}

		prs_append_prs_data(&outgoing_packet, &sec_blob);
		prs_mem_free(&sec_blob);

		DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, 
			   prs_offset(&outgoing_packet)));
		
		if (flags & RPC_FLG_LAST)
			ret = rpc_api_pipe(cli, &outgoing_packet, 
					   rdata, RPC_RESPONSE);
		else {
			cli_write(cli, cli->nt_pipe_fnum, 0x0008,
				   prs_data_p(&outgoing_packet),
				   data_sent, data_len);
		}
		prs_mem_free(&outgoing_packet);
		data_sent += send_size;
		data_left -= send_size;
	}
	/* Also capture received data */
	slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s",
		 cli_pipe_get_name(cli));
	prs_dump(dump_name, op_num, rdata);

	return ret;
}
Example #22
0
static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
			  uint32 fragment_start, int len, int auth_len, uint8 pkt_type,
			  int *pauth_padding_len)
{
	
	/*
	 * The following is that length of the data we must sign or seal.
	 * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
	 * preceeding the auth_data.
	 */

	int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;

	/*
	 * The start of the data to sign/seal is just after the RPC headers.
	 */
	char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;

	RPC_HDR_AUTH rhdr_auth; 

	char *dp = prs_data_p(rdata) + fragment_start + len -
		RPC_HDR_AUTH_LEN - auth_len;
	prs_struct auth_verf;

	*pauth_padding_len = 0;

	if (auth_len == 0) {
		if (cli->pipe_auth_flags == 0) {
			/* move along, nothing to see here */
			return True;
		}

		DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\n"));
		return False;
	}

	DEBUG(5,("rpc_auth_pipe: pkt_type: %d len: %d auth_len: %d NTLMSSP %s schannel %s sign %s seal %s \n",
		 pkt_type, len, auth_len, 
		 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP), 
		 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NETSEC), 
		 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), 
		 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL)));

	if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
		DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
		return False;
	}

	DEBUG(10,("rpc_auth_pipe: packet:\n"));
	dump_data(100, dp, auth_len);

	prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
	
	/* The endinness must be preserved. JRA. */
	prs_set_endian_data( &auth_verf, rdata->bigendian_data);
	
	/* Point this new parse struct at the auth section of the main 
	   parse struct - rather than copying it.  Avoids needing to
	   free it on every error
	*/
	prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */);
	prs_set_offset(&auth_verf, 0);

	{
		int auth_type;
		int auth_level;
		if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) {
			DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n"));
			return False;
		}

		/* Let the caller know how much padding at the end of the data */
		*pauth_padding_len = rhdr_auth.padding;
		
		/* Check it's the type of reply we were expecting to decode */

		get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
		if (rhdr_auth.auth_type != auth_type) {
			DEBUG(0, ("BAD auth type %d (should be %d)\n",
				  rhdr_auth.auth_type, auth_type));
			return False;
		}
		
		if (rhdr_auth.auth_level != auth_level) {
			DEBUG(0, ("BAD auth level %d (should be %d)\n", 
				  rhdr_auth.auth_level, auth_level));
			return False;
		}
	}

	if (pkt_type == RPC_BINDACK) {
		if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
			/* copy the next auth_len bytes into a buffer for 
			   later use */

			DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
			BOOL store_ok;

			/* save the reply away, for use a little later */
			prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);

			store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, 
									   ntlmssp_verf)));

			data_blob_free(&ntlmssp_verf);
			return store_ok;
		} 
		else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
			/* nothing to do here - we don't seem to be able to 
			   validate the bindack based on VL's comments */
			return True;
		}
	}
	
	if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
		NTSTATUS nt_status;
		DATA_BLOB sig;
		if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) ||
		    (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) {
			if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) {
				DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len));
				return False;
			}
			sig = data_blob(NULL, auth_len);
			prs_copy_data_out((char *)sig.data, &auth_verf, auth_len);
		}
	
		/*
		 * Unseal any sealed data in the PDU, not including the
		 * 8 byte auth_header or the auth_data.
		 */

		/*
		 * Now unseal and check the auth verifier in the auth_data at
		 * the end of the packet. 
		 */

		if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
			if (data_len < 0) {
				DEBUG(1, ("Can't unseal - data_len < 0!!\n"));
				return False;
			}
			nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, 
								 (unsigned char *)reply_data, data_len,
								 &sig);
		} 
		else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
			nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, 
								(const unsigned char *)reply_data, data_len,
								&sig);
		}

		data_blob_free(&sig);

		if (!NT_STATUS_IS_OK(nt_status)) {
			DEBUG(0, ("rpc_auth_pipe: could not validate "
				  "incoming NTLMSSP packet!\n"));
			return False;
		}
	}

	if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
		RPC_AUTH_NETSEC_CHK chk;

		if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
			DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len));
			return False;
		}

		if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", 
						&chk, &auth_verf, 0)) {
			DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling "
				  "RPC_AUTH_NETSECK_CHK failed\n"));
			return False;
		}

		if (!netsec_decode(&cli->auth_info,
				   cli->pipe_auth_flags,
				   SENDER_IS_ACCEPTOR,
				   &chk, reply_data, data_len)) {
			DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
			return False;
		}

		cli->auth_info.seq_num++;

	}
	return True;
}
Example #23
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;
}
Example #24
0
static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
        const struct ndr_syntax_id *syntax,
        const char *client_address,
        struct auth_serversupplied_info *server_info)
{
    pipes_struct *p;

    DEBUG(4,("Create pipe requested %s\n",
             get_pipe_name_from_iface(syntax)));

    p = TALLOC_ZERO_P(mem_ctx, struct pipes_struct);

    if (!p) {
        DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
        return NULL;
    }

    if ((p->mem_ctx = talloc_init("pipe %s %p",
                                  get_pipe_name_from_iface(syntax),
                                  p)) == NULL) {
        DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
        TALLOC_FREE(p);
        return NULL;
    }

    if (!init_pipe_handle_list(p, syntax)) {
        DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
        talloc_destroy(p->mem_ctx);
        TALLOC_FREE(p);
        return NULL;
    }

    /*
     * Initialize the incoming RPC data buffer with one PDU worth of memory.
     * We cheat here and say we're marshalling, as we intend to add incoming
     * data directly into the prs_struct and we want it to auto grow. We will
     * change the type to UNMARSALLING before processing the stream.
     */

    if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
        DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
        talloc_destroy(p->mem_ctx);
        close_policy_by_pipe(p);
        TALLOC_FREE(p);
        return NULL;
    }

    p->server_info = copy_serverinfo(p, server_info);
    if (p->server_info == NULL) {
        DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
        talloc_destroy(p->mem_ctx);
        close_policy_by_pipe(p);
        TALLOC_FREE(p);
        return NULL;
    }

    DLIST_ADD(InternalPipes, p);

    memcpy(p->client_address, client_address, sizeof(p->client_address));

    p->endian = RPC_LITTLE_ENDIAN;

    /*
     * Initialize the outgoing RPC data buffer with no memory.
     */
    prs_init_empty(&p->out_data.rdata, p->mem_ctx, MARSHALL);

    p->syntax = *syntax;

    DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
             get_pipe_name_from_iface(syntax), pipes_open));

    talloc_set_destructor(p, close_internal_rpc_pipe_hnd);

    return p;
}
Example #25
0
static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values )
{
	DEVICEMODE	*devmode;
	prs_struct	prs;
	uint32		offset;
	UNISTR2		data;
	char 		*p;
	uint32 printer_status = PRINTER_STATUS_OK;
	
	regval_ctr_addvalue( values, "Attributes",       REG_DWORD, (char*)&info2->attributes,       sizeof(info2->attributes) );
	regval_ctr_addvalue( values, "Priority",         REG_DWORD, (char*)&info2->priority,         sizeof(info2->attributes) );
	regval_ctr_addvalue( values, "ChangeID",         REG_DWORD, (char*)&info2->changeid,         sizeof(info2->changeid) );
	regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
	
	/* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
	regval_ctr_addvalue( values, "Status",           REG_DWORD, (char*)&printer_status,          sizeof(info2->status) );

	regval_ctr_addvalue( values, "StartTime",        REG_DWORD, (char*)&info2->starttime,        sizeof(info2->starttime) );
	regval_ctr_addvalue( values, "UntilTime",        REG_DWORD, (char*)&info2->untiltime,        sizeof(info2->untiltime) );

	/* strip the \\server\ from this string */
	if ( !(p = strrchr( info2->printername, '\\' ) ) )
		p = info2->printername;
	else
		p++;
	init_unistr2( &data, p, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Print Processor",  REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

	init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
	regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );

		
	/* use a prs_struct for converting the devmode and security 
	   descriptor to REG_BINARY */
	
	prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL);

	/* stream the device mode */
		
	if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) {
		if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) {
			offset = prs_offset( &prs );
			regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
		}
	}
		
	prs_mem_clear( &prs );
	prs_set_offset( &prs, 0 );
		
	/* stream the printer security descriptor */
	
	if ( info2->secdesc_buf && info2->secdesc_buf->len )  {
		if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) {
			offset = prs_offset( &prs );
			regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset );
		}
	}

	prs_mem_free( &prs );

	return;		
}
Example #26
0
pipes_struct *open_rpc_pipe_p(char *pipe_name, 
			      connection_struct *conn, uint16 vuid)
{
	int i;
	pipes_struct *p;
	static int next_pipe;

	DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
		 pipe_name, pipes_open));
	
	/* not repeating pipe numbers makes it easier to track things in 
	   log files and prevents client bugs where pipe numbers are reused
	   over connection restarts */
	if (next_pipe == 0)
		next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;

	i = bitmap_find(bmap, next_pipe);

	if (i == -1) {
		DEBUG(0,("ERROR! Out of pipe structures\n"));
		return NULL;
	}

	next_pipe = (i+1) % MAX_OPEN_PIPES;

	for (p = Pipes; p; p = p->next)
		DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  

	p = (pipes_struct *)malloc(sizeof(*p));

	if (!p)
		return NULL;

	ZERO_STRUCTP(p);

	DLIST_ADD(Pipes, p);

	/*
	 * Initialize the incoming RPC data buffer with one PDU worth of memory.
	 * We cheat here and say we're marshalling, as we intend to add incoming
	 * data directly into the prs_struct and we want it to auto grow. We will
	 * change the type to UNMARSALLING before processing the stream.
	 */

	if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, 4, MARSHALL)) {
		DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
		return NULL;
	}

	bitmap_set(bmap, i);
	i += pipe_handle_offset;

	pipes_open++;

	p->pnum = i;

	p->open = True;
	p->device_state = 0;
	p->priority = 0;
	p->conn = conn;
	p->vuid  = vuid;

	p->max_trans_reply = 0;
	
	p->ntlmssp_chal_flags = 0;
	p->ntlmssp_auth_validated = False;
	p->ntlmssp_auth_requested = False;

	p->pipe_bound = False;
	p->fault_state = False;

	/*
	 * Initialize the incoming RPC struct.
	 */

	p->in_data.pdu_needed_len = 0;
	p->in_data.pdu_received_len = 0;

	/*
	 * Initialize the outgoing RPC struct.
	 */

	p->out_data.current_pdu_len = 0;
	p->out_data.current_pdu_sent = 0;
	p->out_data.data_sent_length = 0;

	/*
	 * Initialize the outgoing RPC data buffer with no memory.
	 */	
	prs_init(&p->out_data.rdata, 0, 4, MARSHALL);
	
	p->uid = (uid_t)-1;
	p->gid = (gid_t)-1;
	
	fstrcpy(p->name, pipe_name);
	
	DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
		 pipe_name, i, pipes_open));
	
	chain_p = p;
	
	/* OVERWRITE p as a temp variable, to display all open pipes */ 
	for (p = Pipes; p; p = p->next)
		DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  

	return chain_p;
}
Example #27
0
static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata,
			 uint8 expected_pkt_type)
{
	uint32 len;
	char *rparam = NULL;
	uint32 rparam_len = 0;
	uint16 setup[2];
	BOOL first = True;
	BOOL last  = True;
	RPC_HDR rhdr;
	char *pdata = data ? prs_data_p(data) : NULL;
	uint32 data_len = data ? prs_offset(data) : 0;
	char *prdata = NULL;
	uint32 rdata_len = 0;
	uint32 current_offset = 0;
	uint32 fragment_start = 0;
	uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024;
	int auth_padding_len = 0;

	/* Create setup parameters - must be in native byte order. */

	setup[0] = TRANSACT_DCERPCCMD; 
	setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */

	DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum));

	/* Send the RPC request and receive a response.  For short RPC
	   calls (about 1024 bytes or so) the RPC request and response
	   appears in a SMBtrans request and response.  Larger RPC
	   responses are received further on. */

	if (!cli_api_pipe(cli, "\\PIPE\\",
	          setup, 2, 0,                     /* Setup, length, max */
	          NULL, 0, 0,                      /* Params, length, max */
	          pdata, data_len, max_data,   	   /* data, length, max */
	          &rparam, &rparam_len,            /* return params, len */
	          &prdata, &rdata_len))            /* return data, len */
	{
		DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
		return False;
	}

	/* Throw away returned params - we know we won't use them. */

	SAFE_FREE(rparam);

	if (prdata == NULL) {
		DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n",
			(int)cli->nt_pipe_fnum));
		return False;
	}

	/*
	 * Give this memory as dynamically allocated to the return parse
	 * struct.  
	 */

	prs_give_memory(rdata, prdata, rdata_len, True);
	current_offset = rdata_len;

	/* This next call sets the endian bit correctly in rdata. */

	if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) {
		prs_mem_free(rdata);
		return False;
	}

	if (rhdr.pkt_type == RPC_BINDACK) {
		if (!last && !first) {
			DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n"));
			first = True;
			last = True;
		}
	}

	if (rhdr.pkt_type == RPC_BINDNACK) {
		DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum));
		prs_mem_free(rdata);
		return False;
	}

	if (rhdr.pkt_type == RPC_RESPONSE) {
		RPC_HDR_RESP rhdr_resp;
		if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) {
			DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n"));
			prs_mem_free(rdata);
			return False;
		}
	}

	if (rhdr.pkt_type != expected_pkt_type) {
		DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type));
		prs_mem_free(rdata);
		return False;
	}

	DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
	          (unsigned int)len, (unsigned int)rdata_len ));

	/* check if data to be sent back was too large for one SMBtrans */
	/* err status is only informational: the _real_ check is on the
           length */

	if (len > 0) { 
		/* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */

		/* Read the remaining part of the first response fragment */

		if (!rpc_read(cli, rdata, len, &current_offset)) {
			prs_mem_free(rdata);
			return False;
		}
	}

	/*
	 * Now we have a complete PDU, check the auth struct if any was sent.
	 */

	if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
			  rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
		prs_mem_free(rdata);
		return False;
	}

	if (rhdr.auth_len != 0) {
		/*
		 * Drop the auth footers from the current offset.
		 * We need this if there are more fragments.
		 * The auth footers consist of the auth_data and the
		 * preceeding 8 byte auth_header.
		 */
		current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
	}
	
	/* 
	 * Only one rpc fragment, and it has been read.
	 */

	if (first && last) {
		DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
		return True;
	}

	/*
	 * Read more fragments using SMBreadX until we get one with the
	 * last bit set.
	 */

	while (!last) {
		RPC_HDR_RESP rhdr_resp;
		int num_read;
		char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN];
		prs_struct hps;
		uint8 eclass;
		uint32 ecode;
		
		/*
		 * First read the header of the next PDU.
		 */

		prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL);
		prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);

		num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
		if (cli_is_dos_error(cli)) {
                        cli_dos_error(cli, &eclass, &ecode);
                        if (eclass != ERRDOS && ecode != ERRmoredata) {
                                DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode));
                                return False;
                        }
		}

		DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));

		if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) {
			DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n",
				RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read ));
			return False;
		}

		/* This call sets the endianness in hps. */

		if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
			return False;

		/* Ensure the endianness in rdata is set correctly - must be same as hps. */

		if (hps.bigendian_data != rdata->bigendian_data) {
			DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
				rdata->bigendian_data ? "big" : "little",
				hps.bigendian_data ? "big" : "little" ));
			return False;
		}

		if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) {
			DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n"));
			return False;
		}

		if (first) {
			DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n"));
			return False;
		}

		/*
		 * Now read the rest of the PDU.
		 */

		if (!rpc_read(cli, rdata, len, &current_offset)) {
			prs_mem_free(rdata);
			return False;
		}

		fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;

		/*
		 * Verify any authentication footer.
		 */

		
		if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
				  rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
			prs_mem_free(rdata);
			return False;
		}
		
		if (rhdr.auth_len != 0 ) {
			
			/*
			 * Drop the auth footers from the current offset.
			 * The auth footers consist of the auth_data and the
			 * preceeding 8 byte auth_header.
			 * We need this if there are more fragments.
			 */
			current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
		}
	}

	return True;
}
Example #28
0
static void process_complete_pdu(pipes_struct *p)
{
	prs_struct rpc_in;
	size_t data_len = p->in_data.pdu_received_len - RPC_HEADER_LEN;
	char *data_p = (char *)&p->in_data.current_in_pdu[RPC_HEADER_LEN];
	BOOL reply = False;

	if(p->fault_state) {
		DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
			p->name ));
		set_incoming_fault(p);
		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
		return;
	}

	prs_init( &rpc_in, 0, p->mem_ctx, UNMARSHALL);

	/*
	 * Ensure we're using the corrent endianness for both the 
	 * RPC header flags and the raw data we will be reading from.
	 */

	prs_set_endian_data( &rpc_in, p->endian);
	prs_set_endian_data( &p->in_data.data, p->endian);

	prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);

	DEBUG(10,("process_complete_pdu: processing packet type %u\n",
			(unsigned int)p->hdr.pkt_type ));

	switch (p->hdr.pkt_type) {
		case RPC_REQUEST:
			reply = process_request_pdu(p, &rpc_in);
			break;

		case RPC_PING: /* CL request - ignore... */
			DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
				(unsigned int)p->hdr.pkt_type, p->name));
			break;

		case RPC_RESPONSE: /* No responses here. */
			DEBUG(0,("process_complete_pdu: Error. RPC_RESPONSE received from client on pipe %s.\n",
				p->name ));
			break;

		case RPC_FAULT:
		case RPC_WORKING: /* CL request - reply to a ping when a call in process. */
		case RPC_NOCALL: /* CL - server reply to a ping call. */
		case RPC_REJECT:
		case RPC_ACK:
		case RPC_CL_CANCEL:
		case RPC_FACK:
		case RPC_CANCEL_ACK:
			DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
				(unsigned int)p->hdr.pkt_type, p->name));
			break;

		case RPC_BIND:
			/*
			 * We assume that a pipe bind is only in one pdu.
			 */
			if(pipe_init_outgoing_data(p)) {
				reply = api_pipe_bind_req(p, &rpc_in);
			}
			break;

		case RPC_BINDACK:
		case RPC_BINDNACK:
			DEBUG(0,("process_complete_pdu: Error. RPC_BINDACK/RPC_BINDNACK packet type %u received on pipe %s.\n",
				(unsigned int)p->hdr.pkt_type, p->name));
			break;


		case RPC_ALTCONT:
			/*
			 * We assume that a pipe bind is only in one pdu.
			 */
			if(pipe_init_outgoing_data(p)) {
				reply = api_pipe_alter_context(p, &rpc_in);
			}
			break;

		case RPC_ALTCONTRESP:
			DEBUG(0,("process_complete_pdu: Error. RPC_ALTCONTRESP on pipe %s: Should only be server -> client.\n",
				p->name));
			break;

		case RPC_AUTH3:
			/*
			 * The third packet in an NTLMSSP auth exchange.
			 */
			if(pipe_init_outgoing_data(p)) {
				reply = api_pipe_bind_auth3(p, &rpc_in);
			}
			break;

		case RPC_SHUTDOWN:
			DEBUG(0,("process_complete_pdu: Error. RPC_SHUTDOWN on pipe %s: Should only be server -> client.\n",
				p->name));
			break;

		case RPC_CO_CANCEL:
			/* For now just free all client data and continue processing. */
			DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
			/* As we never do asynchronous RPC serving, we can never cancel a
			   call (as far as I know). If we ever did we'd have to send a cancel_ack
			   reply. For now, just free all client data and continue processing. */
			reply = True;
			break;
#if 0
			/* Enable this if we're doing async rpc. */
			/* We must check the call-id matches the outstanding callid. */
			if(pipe_init_outgoing_data(p)) {
				/* Send a cancel_ack PDU reply. */
				/* We should probably check the auth-verifier here. */
				reply = setup_cancel_ack_reply(p, &rpc_in);
			}
			break;
#endif

		case RPC_ORPHANED:
			/* We should probably check the auth-verifier here.
			   For now just free all client data and continue processing. */
			DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
			reply = True;
			break;

		default:
			DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
			break;
	}

	/* Reset to little endian. Probably don't need this but it won't hurt. */
	prs_set_endian_data( &p->in_data.data, RPC_LITTLE_ENDIAN);

	if (!reply) {
		DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name));
		set_incoming_fault(p);
		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
		prs_mem_free(&rpc_in);
	} else {
		/*
		 * Reset the lengths. We're ready for a new pdu.
		 */
		p->in_data.pdu_needed_len = 0;
		p->in_data.pdu_received_len = 0;
	}

	prs_mem_free(&rpc_in);
}
Example #29
0
/****************************************************************************
  set the security descriptor for a open file
 ****************************************************************************/
BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
{
	char param[8];
	char *rparam=NULL, *rdata=NULL;
	unsigned int rparam_count=0, rdata_count=0;
	uint32 sec_info = 0;
	TALLOC_CTX *mem_ctx;
	prs_struct pd;
	BOOL ret = False;

	if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) {
		DEBUG(0,("talloc_init failed.\n"));
		goto cleanup;
	}

	prs_init(&pd, 0, mem_ctx, MARSHALL);
	prs_give_memory(&pd, NULL, 0, True);

	if (!sec_io_desc("sd data", &sd, &pd, 1)) {
		DEBUG(1,("Failed to marshall secdesc\n"));
		goto cleanup;
	}

	SIVAL(param, 0, fnum);

	if (sd->off_dacl)
		sec_info |= DACL_SECURITY_INFORMATION;
	if (sd->off_owner_sid)
		sec_info |= OWNER_SECURITY_INFORMATION;
	if (sd->off_grp_sid)
		sec_info |= GROUP_SECURITY_INFORMATION;
	SSVAL(param, 4, sec_info);

	if (!cli_send_nt_trans(cli, 
			       NT_TRANSACT_SET_SECURITY_DESC, 
			       0, 
			       NULL, 0, 0,
			       param, 8, 0,
			       prs_data_p(&pd), prs_offset(&pd), 0)) {
		DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n"));
		goto cleanup;
	}


	if (!cli_receive_nt_trans(cli, 
				  &rparam, &rparam_count,
				  &rdata, &rdata_count)) {
		DEBUG(1,("NT_TRANSACT_SET_SECURITY_DESC failed\n"));
		goto cleanup;
	}

	ret = True;

  cleanup:

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	talloc_destroy(mem_ctx);

	prs_mem_free(&pd);
	return ret;
}
Example #30
0
static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, 
				    uint32 rpc_call_id,
				    RPC_IFACE *abstract, RPC_IFACE *transfer,
				    const char *my_name, const char *domain)
{
	RPC_HDR hdr;
	RPC_HDR_RB hdr_rb;
	RPC_HDR_AUTH hdr_auth;
	int auth_len = 0;
	int auth_type, auth_level;
	size_t saved_hdr_offset = 0;

	prs_struct auth_info;
	prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */
		prs_get_mem_context(rpc_out), MARSHALL);

	if (cli->pipe_auth_flags) {
		get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
		
		/*
		 * Create the auth structs we will marshall.
		 */
		
		init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0x00, 1);
		
		/*
		 * Now marshall the data into the temporary parse_struct.
		 */
		
		if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
			DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n"));
			prs_mem_free(&auth_info);
			return NT_STATUS_NO_MEMORY;
		}
		saved_hdr_offset = prs_offset(&auth_info);
	}
	
	if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {

		NTSTATUS nt_status;
		DATA_BLOB null_blob = data_blob(NULL, 0);
		DATA_BLOB request;

		DEBUG(5, ("Processing NTLMSSP Negotiate\n"));
		nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
					   null_blob,
					   &request);

		if (!NT_STATUS_EQUAL(nt_status, 
				     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
			prs_mem_free(&auth_info);
			return nt_status;
		}

		/* Auth len in the rpc header doesn't include auth_header. */
		auth_len = request.length;
		prs_copy_data_in(&auth_info, (char *)request.data, request.length);

		DEBUG(5, ("NTLMSSP Negotiate:\n"));
		dump_data(5, (const char *)request.data, request.length);

		data_blob_free(&request);

	} else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
		RPC_AUTH_NETSEC_NEG netsec_neg;

		/* Use lp_workgroup() if domain not specified */

		if (!domain || !domain[0]) {
			DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n"));
			domain = lp_workgroup();
		}

		init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name);

		/*
		 * Now marshall the data into the temporary parse_struct.
		 */

		if(!smb_io_rpc_auth_netsec_neg("netsec_neg",
					       &netsec_neg, &auth_info, 0)) {
			DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n"));
			prs_mem_free(&auth_info);
			return NT_STATUS_NO_MEMORY;
		}

		/* Auth len in the rpc header doesn't include auth_header. */
		auth_len = prs_offset(&auth_info) - saved_hdr_offset;
	}

	/* Create the request RPC_HDR */
	init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, 
		RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
		auth_len);

	if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
		DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n"));
		prs_mem_free(&auth_info);
		return NT_STATUS_NO_MEMORY;
	}

	/* create the bind request RPC_HDR_RB */
	init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0,
			0x1, 0x0, 0x1, abstract, transfer);

	/* Marshall the bind request data */
	if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
		DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n"));
		prs_mem_free(&auth_info);
		return NT_STATUS_NO_MEMORY;
	}

	/*
	 * Grow the outgoing buffer to store any auth info.
	 */

	if(auth_len != 0) {
		if(!prs_append_prs_data( rpc_out, &auth_info)) {
			DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
			prs_mem_free(&auth_info);
			return NT_STATUS_NO_MEMORY;
		}
	}
	prs_mem_free(&auth_info);
	return NT_STATUS_OK;
}