Example #1
0
/*
  aadvance to the next chained reply in a request
*/
NTSTATUS smbcli_chained_advance(struct smbcli_request *req)
{
	uint8_t *buffer;

	if (CVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE) {
		return NT_STATUS_NOT_FOUND;
	}

	buffer = req->in.hdr + SVAL(req->in.vwv, VWV(1));

	if (buffer + 3 > req->in.buffer + req->in.size) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}

	req->in.vwv = buffer + 1;
	req->in.wct = CVAL(buffer, 0);
	if (buffer + 3 + req->in.wct*2 > req->in.buffer + req->in.size) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	req->in.data = req->in.vwv + 2 + req->in.wct * 2;
	req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));

	/* fix the bufinfo */
	smb_setup_bufinfo(req);

	if (buffer + 3 + req->in.wct*2 + req->in.data_size > 
	    req->in.buffer + req->in.size) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}

	return NT_STATUS_OK;
}
Example #2
0
/****************************************************************************
 Close a file - async send
****************************************************************************/
_PUBLIC_ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms)
{
	struct smbcli_request *req = NULL; 

	switch (parms->generic.level) {
	case RAW_CLOSE_CLOSE:
		SETUP_REQUEST(SMBclose, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->close.in.file.fnum);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->close.in.write_time);
		break;

	case RAW_CLOSE_SPLCLOSE:
		SETUP_REQUEST(SMBsplclose, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum);
		SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
		break;

	case RAW_CLOSE_SMB2:
	case RAW_CLOSE_GENERIC:
		return NULL;
	}

	if (!req) return NULL;

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}

	return req;
}
Example #3
0
/****************************************************************************
 Old style search next.
****************************************************************************/
static NTSTATUS smb_raw_search_close_old(struct smbcli_tree *tree,
					 union smb_search_close *io)
{
	struct smbcli_request *req; 
	uint8_t var_block[21];

	req = smbcli_request_setup(tree, SMBfclose, 2, 0);
	if (!req) {
		return NT_STATUS_NO_MEMORY;
	}
	
	SSVAL(req->out.vwv, VWV(0), io->fclose.in.max_count);
	SSVAL(req->out.vwv, VWV(1), io->fclose.in.search_attrib);
	smbcli_req_append_ascii4(req, "", STR_TERMINATE);

	SCVAL(var_block,  0, io->fclose.in.id.reserved);
	memcpy(&var_block[1], io->fclose.in.id.name, 11);
	SCVAL(var_block, 12, io->fclose.in.id.handle);
	SIVAL(var_block, 13, io->fclose.in.id.server_cookie);
	SIVAL(var_block, 17, io->fclose.in.id.client_cookie);

	smbcli_req_append_var_block(req, var_block, 21);

	if (!smbcli_request_send(req) ||
	    !smbcli_request_receive(req)) {
		return smbcli_request_destroy(req);
	}

	return smbcli_request_destroy(req);
}
Example #4
0
/*
  setup a chained reply in req->out with the given word count and initial data buffer size. 
*/
static void req_setup_chain_reply(struct smbsrv_request *req, unsigned int wct, unsigned int buflen)
{
	uint32_t chain_base_size = req->out.size;

	/* we need room for the wct value, the words, the buffer length and the buffer */
	req->out.size += 1 + VWV(wct) + 2 + buflen;

	/* over allocate by a small amount */
	req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 

	req->out.buffer = talloc_realloc(req, req->out.buffer, 
					 uint8_t, req->out.allocated);
	if (!req->out.buffer) {
		smbsrv_terminate_connection(req->smb_conn, "allocation failed");
		return;
	}

	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.buffer + chain_base_size + 1;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.buffer, chain_base_size, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);
}
Example #5
0
/****************************************************************************
 Open a file using TRANSACT2_OPEN - async recv
****************************************************************************/
static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
{
	struct smbcli_transport *transport = req->transport;
	struct smb_trans2 t2;
	NTSTATUS status;

	status = smb_raw_trans2_recv(req, mem_ctx, &t2);
	if (!NT_STATUS_IS_OK(status)) return status;

	if (t2.out.params.length < 30) {
		return NT_STATUS_INFO_LENGTH_MISMATCH;
	}

	parms->t2open.out.file.fnum =   SVAL(t2.out.params.data, VWV(0));
	parms->t2open.out.attrib =      SVAL(t2.out.params.data, VWV(1));
	parms->t2open.out.write_time =  raw_pull_dos_date3(transport, t2.out.params.data + VWV(2));
	parms->t2open.out.size =        IVAL(t2.out.params.data, VWV(4));
	parms->t2open.out.access =      SVAL(t2.out.params.data, VWV(6));
	parms->t2open.out.ftype =       SVAL(t2.out.params.data, VWV(7));
	parms->t2open.out.devstate =    SVAL(t2.out.params.data, VWV(8));
	parms->t2open.out.action =      SVAL(t2.out.params.data, VWV(9));
	parms->t2open.out.file_id =     SVAL(t2.out.params.data, VWV(10));

	return NT_STATUS_OK;
}
Example #6
0
/*
  setup a SMB packet at transport level
*/
struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
						      uint8_t command, unsigned int wct, unsigned int buflen)
{
	struct smbcli_request *req;
	size_t size;

	size = NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen;

	req = talloc_zero(transport, struct smbcli_request);
	if (!req) {
		return NULL;
	}

	/* setup the request context */
	req->state = SMBCLI_REQUEST_INIT;
	req->transport = transport;
	req->out.size = size;

	/* over allocate by a small amount */
	req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 

	req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
	if (!req->out.buffer) {
		return NULL;
	}

	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.hdr + HDR_VWV;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.hdr, HDR_WCT, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	memcpy(req->out.hdr, "\377SMB", 4);
	SCVAL(req->out.hdr,HDR_COM,command);

	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
	SSVAL(req->out.hdr,HDR_FLG2, 0);

	/* copy the pid, uid and mid to the request */
	SSVAL(req->out.hdr, HDR_PID, 0);
	SSVAL(req->out.hdr, HDR_UID, 0);
	SSVAL(req->out.hdr, HDR_MID, 0);
	SSVAL(req->out.hdr, HDR_TID,0);
	SSVAL(req->out.hdr, HDR_PIDHIGH,0);
	SIVAL(req->out.hdr, HDR_RCLS, 0);
	memset(req->out.hdr+HDR_SS_FIELD, 0, 10);
	
	return req;
}
Example #7
0
/*
  send an oplock break request to a client
*/
NTSTATUS smbsrv_send_oplock_break(void *p, struct ntvfs_handle *ntvfs, uint8_t level)
{
	struct smbsrv_tcon *tcon = talloc_get_type(p, struct smbsrv_tcon);
	struct smbsrv_request *req;

	req = smbsrv_init_request(tcon->smb_conn);
	NT_STATUS_HAVE_NO_MEMORY(req);

	smbsrv_setup_reply(req, 8, 0);

	SCVAL(req->out.hdr,HDR_COM,SMBlockingX);
	SSVAL(req->out.hdr,HDR_TID,tcon->tid);
	SSVAL(req->out.hdr,HDR_PID,0xFFFF);
	SSVAL(req->out.hdr,HDR_UID,0);
	SSVAL(req->out.hdr,HDR_MID,0xFFFF);
	SCVAL(req->out.hdr,HDR_FLG,0);
	SSVAL(req->out.hdr,HDR_FLG2,0);

	SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
	SSVAL(req->out.vwv, VWV(1), 0);
	smbsrv_push_fnum(req->out.vwv, VWV(2), ntvfs);
	SCVAL(req->out.vwv, VWV(3), LOCKING_ANDX_OPLOCK_RELEASE);
	SCVAL(req->out.vwv, VWV(3)+1, level);
	SIVAL(req->out.vwv, VWV(4), 0);
	SSVAL(req->out.vwv, VWV(6), 0);
	SSVAL(req->out.vwv, VWV(7), 0);

	smbsrv_send_reply(req);
	return NT_STATUS_OK;
}
Example #8
0
/****************************************************************************
 raw echo interface (async recv)
****************************************************************************/
NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
			   struct smb_echo *p)
{
	if (!smbcli_request_receive(req) ||
	    smbcli_request_is_error(req)) {
		goto failed;
	}

	SMBCLI_CHECK_WCT(req, 1);
	p->out.count++;
	p->out.sequence_number = SVAL(req->in.vwv, VWV(0));
	p->out.size = req->in.data_size;
	talloc_free(p->out.data);
	p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size);
	NT_STATUS_HAVE_NO_MEMORY(p->out.data);

	if (!smbcli_raw_pull_data(&req->in.bufinfo, req->in.data, p->out.size, p->out.data)) {
		req->status = NT_STATUS_BUFFER_TOO_SMALL;
	}

	if (p->out.count == p->in.repeat_count) {
		return smbcli_request_destroy(req);
	}

	return NT_STATUS_OK;

failed:
	return smbcli_request_destroy(req);
}
Example #9
0
/****************************************************************************
 Send a ulogoff (async send)
*****************************************************************************/
struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session)
{
	struct smbcli_request *req;

	SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0);

	SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
	SSVAL(req->out.vwv, VWV(1), 0);

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}

	return req;
}
Example #10
0
/****************************************************************************
 Query FS Info - SMBdskattr call (async recv)
****************************************************************************/
static NTSTATUS smb_raw_dskattr_recv(struct smbcli_request *req,
				     union smb_fsinfo *fsinfo)
{
	if (!smbcli_request_receive(req) ||
	    smbcli_request_is_error(req)) {
		goto failed;
	}

	SMBCLI_CHECK_WCT(req, 5);
	fsinfo->dskattr.out.units_total =     SVAL(req->in.vwv, VWV(0));
	fsinfo->dskattr.out.blocks_per_unit = SVAL(req->in.vwv, VWV(1));
	fsinfo->dskattr.out.block_size =      SVAL(req->in.vwv, VWV(2));
	fsinfo->dskattr.out.units_free =      SVAL(req->in.vwv, VWV(3));

failed:
	return smbcli_request_destroy(req);
}
Example #11
0
/****************************************************************************
 Open a file using TRANSACT2_OPEN - async send 
****************************************************************************/
static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, 
					       union smb_open *parms)
{
	struct smb_trans2 t2;
	uint16_t setup = TRANSACT2_OPEN;
	TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open");
	struct smbcli_request *req;
	uint16_t list_size;

	list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas);

	t2.in.max_param = 30;
	t2.in.max_data = 0;
	t2.in.max_setup = 0;
	t2.in.flags = 0;
	t2.in.timeout = 0;
	t2.in.setup_count = 1;
	t2.in.setup = &setup;
	t2.in.params = data_blob_talloc(mem_ctx, NULL, 28);
	t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size);

	SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
	SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
	SSVAL(t2.in.params.data, VWV(2), parms->t2open.in.search_attrs);
	SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
	raw_push_dos_date(tree->session->transport, 
			  t2.in.params.data, VWV(4), parms->t2open.in.write_time);
	SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
	SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
	SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
	SIVAL(t2.in.params.data, VWV(11), 0);
	SSVAL(t2.in.params.data, VWV(13), 0);

	smbcli_blob_append_string(tree->session, mem_ctx, 
				  &t2.in.params, parms->t2open.in.fname, 
				  STR_TERMINATE);

	ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);

	req = smb_raw_trans2_send(tree, &t2);

	talloc_free(mem_ctx);

	return req;
}
Example #12
0
/****************************************************************************
 Old style search next.
****************************************************************************/
static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree,
					TALLOC_CTX *mem_ctx,
					union smb_search_next *io, void *private_data,
					smbcli_search_callback callback)

{
	struct smbcli_request *req; 
	uint8_t var_block[21];
	uint8_t op = SMBsearch;

	if (io->generic.level == RAW_SEARCH_FFIRST) {
		op = SMBffirst;
	}
	
	req = smbcli_request_setup(tree, op, 2, 0);
	if (!req) {
		return NT_STATUS_NO_MEMORY;
	}
	
	SSVAL(req->out.vwv, VWV(0), io->search_next.in.max_count);
	SSVAL(req->out.vwv, VWV(1), io->search_next.in.search_attrib);
	smbcli_req_append_ascii4(req, "", STR_TERMINATE);

	SCVAL(var_block,  0, io->search_next.in.id.reserved);
	memcpy(&var_block[1], io->search_next.in.id.name, 11);
	SCVAL(var_block, 12, io->search_next.in.id.handle);
	SIVAL(var_block, 13, io->search_next.in.id.server_cookie);
	SIVAL(var_block, 17, io->search_next.in.id.client_cookie);

	smbcli_req_append_var_block(req, var_block, 21);

	if (!smbcli_request_send(req) ||
	    !smbcli_request_receive(req)) {
		return smbcli_request_destroy(req);
	}

	if (NT_STATUS_IS_OK(req->status)) {
		io->search_next.out.count = SVAL(req->in.vwv, VWV(0));
		smb_raw_search_backend(req, mem_ctx, io->search_next.out.count, private_data, callback);
	}
	
	return smbcli_request_destroy(req);
}
Example #13
0
/*
  setup a chained reply in req->out with the given word count and
  initial data buffer size.
*/
NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req,
				      uint8_t command, 
				      unsigned int wct, size_t buflen)
{
	unsigned int new_size = 1 + (wct*2) + 2 + buflen;

	SSVAL(req->out.vwv, VWV(0), command);
	SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE);

	smbcli_req_grow_allocation(req, req->out.data_size + new_size);

	req->out.vwv = req->out.buffer + req->out.size + 1;
	SCVAL(req->out.vwv, -1, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	req->out.size += new_size;
	req->out.data_size += new_size;

	return NT_STATUS_OK;
}
Example #14
0
/*
  trans2 findnext send
*/
static NTSTATUS trans2_findnext_send(struct trans_op *op)
{
	struct smbsrv_request *req = op->req;
	struct smb_trans2 *trans = op->trans;
	union smb_search_next *search;
	struct find_state *state;
	uint8_t *param;

	TRANS2_CHECK_ASYNC_STATUS(state, struct find_state);
	search = talloc_get_type(state->search, union smb_search_next);

	/* fill in the findfirst reply header */
	param = trans->out.params.data;
	SSVAL(param, VWV(0), search->t2fnext.out.count);
	SSVAL(param, VWV(1), search->t2fnext.out.end_of_search);
	SSVAL(param, VWV(2), 0);
	SSVAL(param, VWV(3), state->last_entry_offset);
	
	return NT_STATUS_OK;
}
Example #15
0
/*
  setup a SMB packet at transport level
*/
struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
						      uint8_t command, unsigned int wct, unsigned int buflen)
{
	struct smbcli_request *req;

	req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen);

	if (!req) return NULL;
	
	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.hdr + HDR_VWV;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.hdr, HDR_WCT, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	memcpy(req->out.hdr, "\377SMB", 4);
	SCVAL(req->out.hdr,HDR_COM,command);

	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
	SSVAL(req->out.hdr,HDR_FLG2, 0);

	if (command != SMBtranss && command != SMBtranss2) {
		/* assign a mid */
		req->mid = smbcli_transport_next_mid(transport);
	}

	/* copy the pid, uid and mid to the request */
	SSVAL(req->out.hdr, HDR_PID, 0);
	SSVAL(req->out.hdr, HDR_UID, 0);
	SSVAL(req->out.hdr, HDR_MID, req->mid);
	SSVAL(req->out.hdr, HDR_TID,0);
	SSVAL(req->out.hdr, HDR_PIDHIGH,0);
	SIVAL(req->out.hdr, HDR_RCLS, 0);
	memset(req->out.hdr+HDR_SS_FIELD, 0, 10);
	
	return req;
}
Example #16
0
/*
  trans2 simple send
*/
static NTSTATUS trans2_simple_send(struct trans_op *op)
{
	struct smbsrv_request *req = op->req;
	struct smb_trans2 *trans = op->trans;

	TRANS2_CHECK_ASYNC_STATUS_SIMPLE;

	TRANS2_CHECK(trans2_setup_reply(trans, 2, 0, 0));

	SSVAL(trans->out.params.data, VWV(0), 0);

	return NT_STATUS_OK;
}
Example #17
0
/*
  handle oplock break requests from the server - return true if the request was
  an oplock break
*/
bool smbcli_handle_oplock_break(struct smbcli_transport *transport, unsigned int len, const uint8_t *hdr, const uint8_t *vwv)
{
	/* we must be very fussy about what we consider an oplock break to avoid
	   matching readbraw replies */
	if (len != MIN_SMB_SIZE + VWV(8) + NBT_HDR_SIZE ||
	    (CVAL(hdr, HDR_FLG) & FLAG_REPLY) ||
	    CVAL(hdr,HDR_COM) != SMBlockingX ||
	    SVAL(hdr, HDR_MID) != 0xFFFF ||
	    SVAL(vwv,VWV(6)) != 0 ||
	    SVAL(vwv,VWV(7)) != 0) {
		return false;
	}

	if (transport->oplock.handler) {
		uint16_t tid = SVAL(hdr, HDR_TID);
		uint16_t fnum = SVAL(vwv,VWV(2));
		uint8_t level = CVAL(vwv,VWV(3)+1);
		transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private_data);
	}

	return true;
}
Example #18
0
/*
  grow the data buffer portion of a reply packet. Note that as this
  can reallocate the packet buffer this invalidates any local pointers
  into the packet. 

  To cope with this req->out.ptr is supplied. This will be updated to
  point at the same offset into the packet as before this call
*/
static void smbcli_req_grow_data(struct smbcli_request *req, unsigned int new_size)
{
	int delta;

	smbcli_req_grow_allocation(req, new_size);

	delta = new_size - req->out.data_size;

	req->out.size += delta;
	req->out.data_size += delta;

	/* set the BCC to the new data size */
	SSVAL(req->out.vwv, VWV(req->out.wct), new_size);
}
Example #19
0
/****************************************************************************
 Old style search first.
****************************************************************************/
static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree,
					 TALLOC_CTX *mem_ctx,
					 union smb_search_first *io, void *private_data,
					 smbcli_search_callback callback)

{
	struct smbcli_request *req; 
	uint8_t op = SMBsearch;

	if (io->generic.level == RAW_SEARCH_FFIRST) {
		op = SMBffirst;
	} else if (io->generic.level == RAW_SEARCH_FUNIQUE) {
		op = SMBfunique;
	}

	req = smbcli_request_setup(tree, op, 2, 0);
	if (!req) {
		return NT_STATUS_NO_MEMORY;
	}
	
	SSVAL(req->out.vwv, VWV(0), io->search_first.in.max_count);
	SSVAL(req->out.vwv, VWV(1), io->search_first.in.search_attrib);
	smbcli_req_append_ascii4(req, io->search_first.in.pattern, STR_TERMINATE);
	smbcli_req_append_var_block(req, NULL, 0);

	if (!smbcli_request_send(req) || 
	    !smbcli_request_receive(req)) {
		return smbcli_request_destroy(req);
	}

	if (NT_STATUS_IS_OK(req->status)) {
		io->search_first.out.count = SVAL(req->in.vwv, VWV(0));	
		smb_raw_search_backend(req, mem_ctx, io->search_first.out.count, private_data, callback);
	}

	return smbcli_request_destroy(req);
}
Example #20
0
/****************************************************************************
 Rename a file - async interface
****************************************************************************/
struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree,
					union smb_rename *parms)
{
	struct smbcli_request *req = NULL; 
	struct smb_nttrans nt;
	TALLOC_CTX *mem_ctx;

	switch (parms->generic.level) {
	case RAW_RENAME_RENAME:
		SETUP_REQUEST(SMBmv, 1, 0);
		SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib);
		smbcli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE);
		smbcli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE);
		break;

	case RAW_RENAME_NTRENAME:
		SETUP_REQUEST(SMBntrename, 4, 0);
		SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib);
		SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags);
		SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size);
		smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE);
		smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE);
		break;

	case RAW_RENAME_NTTRANS:

		mem_ctx = talloc_new(tree);

		nt.in.max_setup = 0;
		nt.in.max_param = 0;
		nt.in.max_data = 0;
		nt.in.setup_count = 0;
		nt.in.setup = NULL;
		nt.in.function = NT_TRANSACT_RENAME;
		nt.in.params = data_blob_talloc(mem_ctx, NULL, 4);
		nt.in.data = data_blob(NULL, 0);

		SSVAL(nt.in.params.data, VWV(0), parms->nttrans.in.file.fnum);
		SSVAL(nt.in.params.data, VWV(1), parms->nttrans.in.flags);

		smbcli_blob_append_string(tree->session, mem_ctx,
					  &nt.in.params, parms->nttrans.in.new_name,
					  STR_TERMINATE);

		req = smb_raw_nttrans_send(tree, &nt);
		talloc_free(mem_ctx);
		return req;
	}

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}

	return req;
}
Example #21
0
/****************************************************************************
 Delete a file - async interface
****************************************************************************/
struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree,
					   union smb_unlink *parms)
{
	struct smbcli_request *req; 

	SETUP_REQUEST(SMBunlink, 1, 0);

	SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib);
	smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE);

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}
	return req;
}
Example #22
0
/*
  grow the data buffer portion of a reply packet. Note that as this
  can reallocate the packet buffer this invalidates any local pointers
  into the packet. 

  To cope with this req->out.ptr is supplied. This will be updated to
  point at the same offset into the packet as before this call
*/
void req_grow_data(struct smbsrv_request *req, size_t new_size)
{
	int delta;

	if (!(req->control_flags & SMBSRV_REQ_CONTROL_LARGE) && new_size > req_max_data(req)) {
		smb_panic("reply buffer too large!");
	}

	req_grow_allocation(req, new_size);

	delta = new_size - req->out.data_size;

	req->out.size += delta;
	req->out.data_size += delta;

	/* set the BCC to the new data size */
	SSVAL(req->out.vwv, VWV(req->out.wct), new_size);
}
Example #23
0
/*
  trans2 open implementation
*/
static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op)
{
	struct smb_trans2 *trans = op->trans;
	union smb_open *io;

	/* make sure we got enough parameters */
	if (trans->in.params.length < 29) {
		return NT_STATUS_FOOBAR;
	}

	io = talloc(op, union smb_open);
	NT_STATUS_HAVE_NO_MEMORY(io);

	io->t2open.level           = RAW_OPEN_T2OPEN;
	io->t2open.in.flags        = SVAL(trans->in.params.data, VWV(0));
	io->t2open.in.open_mode    = SVAL(trans->in.params.data, VWV(1));
	io->t2open.in.search_attrs = SVAL(trans->in.params.data, VWV(2));
	io->t2open.in.file_attrs   = SVAL(trans->in.params.data, VWV(3));
	io->t2open.in.write_time   = srv_pull_dos_date(req->smb_conn, 
						    trans->in.params.data + VWV(4));
	io->t2open.in.open_func    = SVAL(trans->in.params.data, VWV(6));
	io->t2open.in.size         = IVAL(trans->in.params.data, VWV(7));
	io->t2open.in.timeout      = IVAL(trans->in.params.data, VWV(9));
	io->t2open.in.num_eas      = 0;
	io->t2open.in.eas          = NULL;

	smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 28, &io->t2open.in.fname, 0);
	if (io->t2open.in.fname == NULL) {
		return NT_STATUS_FOOBAR;
	}

	TRANS2_CHECK(ea_pull_list(&trans->in.data, io, &io->t2open.in.num_eas, &io->t2open.in.eas));

	op->op_info = io;
	op->send_fn = trans2_open_send;

	return ntvfs_open(req->ntvfs, io);
}
Example #24
0
/****************************************************************************
 Send an SMBecho (async send)
*****************************************************************************/
_PUBLIC_ struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport,
					 struct smb_echo *p)
{
	struct smbcli_request *req;

	req = smbcli_request_setup_transport(transport, SMBecho, 1, p->in.size);
	if (!req) return NULL;

	SSVAL(req->out.vwv, VWV(0), p->in.repeat_count);

	memcpy(req->out.data, p->in.data, p->in.size);

	ZERO_STRUCT(p->out);

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}

	return req;
}
Example #25
0
/* 
   Implements trans2findclose2
 */
NTSTATUS smb_raw_search_close(struct smbcli_tree *tree,
			      union smb_search_close *io)
{
	struct smbcli_request *req;

	if (io->generic.level == RAW_FINDCLOSE_FCLOSE) {
		return smb_raw_search_close_old(tree, io);
	}
	
	req = smbcli_request_setup(tree, SMBfindclose, 1, 0);
	if (!req) {
		return NT_STATUS_NO_MEMORY;
	}

	SSVAL(req->out.vwv, VWV(0), io->findclose.in.handle);

	if (smbcli_request_send(req)) {
		(void) smbcli_request_receive(req);
	}

	return smbcli_request_destroy(req);
}
Example #26
0
/****************************************************************************
 create a directory  using TRANSACT2_MKDIR - async interface
****************************************************************************/
static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, 
						union smb_mkdir *parms)
{
	struct smb_trans2 t2;
	uint16_t setup = TRANSACT2_MKDIR;
	TALLOC_CTX *mem_ctx;
	struct smbcli_request *req;
	uint16_t data_total;

	mem_ctx = talloc_init("t2mkdir");

	data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);

	t2.in.max_param = 2;
	t2.in.max_data = 0;
	t2.in.max_setup = 0;
	t2.in.flags = 0;
	t2.in.timeout = 0;
	t2.in.setup_count = 1;
	t2.in.setup = &setup;
	t2.in.params = data_blob_talloc(mem_ctx, NULL, 4);
	t2.in.data = data_blob_talloc(mem_ctx, NULL, data_total);

	SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */

	smbcli_blob_append_string(tree->session, mem_ctx, 
				  &t2.in.params, parms->t2mkdir.in.path, STR_TERMINATE);

	ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);

	req = smb_raw_trans2_send(tree, &t2);

	talloc_free(mem_ctx);

	return req;
}
Example #27
0
/****************************************************************************
 raw write interface (async recv)
****************************************************************************/
NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms)
{
	if (!smbcli_request_receive(req) ||
	    !NT_STATUS_IS_OK(req->status)) {
		goto failed;
	}

	switch (parms->generic.level) {
	case RAW_WRITE_WRITEUNLOCK:
		SMBCLI_CHECK_WCT(req, 1);		
		parms->writeunlock.out.nwritten = SVAL(req->in.vwv, VWV(0));
		break;
	case RAW_WRITE_WRITE:
		SMBCLI_CHECK_WCT(req, 1);
		parms->write.out.nwritten = SVAL(req->in.vwv, VWV(0));
		break;
	case RAW_WRITE_WRITECLOSE:
		SMBCLI_CHECK_WCT(req, 1);
		parms->writeclose.out.nwritten = SVAL(req->in.vwv, VWV(0));
		break;
	case RAW_WRITE_WRITEX:
		SMBCLI_CHECK_WCT(req, 6);
		parms->writex.out.nwritten  = SVAL(req->in.vwv, VWV(2));
		parms->writex.out.nwritten += (CVAL(req->in.vwv, VWV(4)) << 16);
		parms->writex.out.remaining = SVAL(req->in.vwv, VWV(3));
		break;
	case RAW_WRITE_SPLWRITE:
		break;
	case RAW_WRITE_SMB2:
		req->status = NT_STATUS_INTERNAL_ERROR;
		break;
	}

failed:
	return smbcli_request_destroy(req);
}
Example #28
0
/****************************************************************************
 Perform a session setup (async send)
****************************************************************************/
struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session, 
					      union smb_sesssetup *parms) 
{
	struct smbcli_request *req = NULL;

	switch (parms->old.level) {
	case RAW_SESSSETUP_OLD:
		SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize);
		SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max);
		SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
		SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
		SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
		SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
		smbcli_req_append_blob(req, &parms->old.in.password);
		smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
		smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
		smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE);
		smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE);
		break;

	case RAW_SESSSETUP_NT1:
		SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize);
		SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max);
		SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num);
		SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey);
		SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length);
		SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length);
		SIVAL(req->out.vwv, VWV(9), 0); /* reserved */
		SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities);
		smbcli_req_append_blob(req, &parms->nt1.in.password1);
		smbcli_req_append_blob(req, &parms->nt1.in.password2);
		smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE);
		smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER);
		smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE);
		smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE);
		break;

	case RAW_SESSSETUP_SPNEGO:
		SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize);
		SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max);
		SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num);
		SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey);
		SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length);
		SIVAL(req->out.vwv, VWV(8), 0); /* reserved */
		SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities);
		smbcli_req_append_blob(req, &parms->spnego.in.secblob);
		smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
		smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
		smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE);
		break;

	case RAW_SESSSETUP_SMB2:
		return NULL;
	}

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}

	return req;
}
Example #29
0
/****************************************************************************
 Perform a session setup (async recv)
****************************************************************************/
NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, 
				TALLOC_CTX *mem_ctx, 
				union smb_sesssetup *parms) 
{
	uint16_t len;
	uint8_t *p;

	if (!smbcli_request_receive(req)) {
		return smbcli_request_destroy(req);
	}
	
	if (!NT_STATUS_IS_OK(req->status) &&
	    !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		return smbcli_request_destroy(req);
	}

	switch (parms->old.level) {
	case RAW_SESSSETUP_OLD:
		SMBCLI_CHECK_WCT(req, 3);
		ZERO_STRUCT(parms->old.out);
		parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID);
		parms->old.out.action = SVAL(req->in.vwv, VWV(2));
		p = req->in.data;
		if (p) {
			p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
			p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
			p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
		}
		break;

	case RAW_SESSSETUP_NT1:
		SMBCLI_CHECK_WCT(req, 3);
		ZERO_STRUCT(parms->nt1.out);
		parms->nt1.out.vuid   = SVAL(req->in.hdr, HDR_UID);
		parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
		p = req->in.data;
		if (p) {
			p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
			p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
			if (p < (req->in.data + req->in.data_size)) {
				p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
			}
		}
		break;

	case RAW_SESSSETUP_SPNEGO:
		SMBCLI_CHECK_WCT(req, 4);
		ZERO_STRUCT(parms->spnego.out);
		parms->spnego.out.vuid   = SVAL(req->in.hdr, HDR_UID);
		parms->spnego.out.action = SVAL(req->in.vwv, VWV(2));
		len                      = SVAL(req->in.vwv, VWV(3));
		p = req->in.data;
		if (!p) {
			break;
		}

		parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
		p += parms->spnego.out.secblob.length;
		p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
		p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
		p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
		break;

	case RAW_SESSSETUP_SMB2:
		req->status = NT_STATUS_INTERNAL_ERROR;
		break;
	}

failed:
	return smbcli_request_destroy(req);
}
Example #30
0
/*
  setup a chained reply in req->out with the given word count and
  initial data buffer size.
*/
NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req,
				      uint8_t command, 
				      unsigned int wct, size_t buflen)
{
	size_t wct_ofs;
	size_t size;

	/*
	 * here we only support one chained command
	 * If someone needs longer chains, the low
	 * level code should be used directly.
	 */
	if (req->subreqs[0] != NULL) {
		return NT_STATUS_INVALID_PARAMETER_MIX;
	}
	if (req->subreqs[1] != NULL) {
		return NT_STATUS_INVALID_PARAMETER_MIX;
	}

	req->subreqs[0] = smbcli_transport_setup_subreq(req);
	if (req->subreqs[0] == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	wct_ofs = smb1cli_req_wct_ofs(req->subreqs, 1);

	size = NBT_HDR_SIZE + wct_ofs + 1 + VWV(wct) + 2 + buflen;

	req->out.size = size;

	/* over allocate by a small amount */
	req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;

	req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
	if (!req->out.buffer) {
		return NT_STATUS_NO_MEMORY;
	}

	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.hdr + wct_ofs;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.hdr, HDR_WCT, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	memcpy(req->out.hdr, "\377SMB", 4);
	SCVAL(req->out.hdr,HDR_COM,command);

	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
	SSVAL(req->out.hdr,HDR_FLG2, 0);

	/* copy the pid, uid and mid to the request */
	SSVAL(req->out.hdr, HDR_PID, 0);
	SSVAL(req->out.hdr, HDR_UID, 0);
	SSVAL(req->out.hdr, HDR_MID, 0);
	SSVAL(req->out.hdr, HDR_TID,0);
	SSVAL(req->out.hdr, HDR_PIDHIGH,0);
	SIVAL(req->out.hdr, HDR_RCLS, 0);
	memset(req->out.hdr+HDR_SS_FIELD, 0, 10);

	if (req->session != NULL) {
		SSVAL(req->out.hdr, HDR_FLG2, req->session->flags2);
		SSVAL(req->out.hdr, HDR_PID, req->session->pid & 0xFFFF);
		SSVAL(req->out.hdr, HDR_PIDHIGH, req->session->pid >> 16);
		SSVAL(req->out.hdr, HDR_UID, req->session->vuid);
	}