예제 #1
0
파일: nttrans.c 프로젝트: DavidMulder/samba
/*
  send a nttrans create reply
*/
static NTSTATUS nttrans_create_send(struct nttrans_op *op)
{
	union smb_open *io = talloc_get_type(op->op_info, union smb_open);
	uint8_t *params;
	NTSTATUS status;

	status = nttrans_setup_reply(op, op->trans, 69, 0, 0);
	NT_STATUS_NOT_OK_RETURN(status);
	params = op->trans->out.params.data;

	SSVAL(params,        0, io->ntcreatex.out.oplock_level);
	smbsrv_push_fnum(params, 2, io->ntcreatex.out.file.ntvfs);
	SIVAL(params,        4, io->ntcreatex.out.create_action);
	SIVAL(params,        8, 0); /* ea error offset */
	push_nttime(params, 12, io->ntcreatex.out.create_time);
	push_nttime(params, 20, io->ntcreatex.out.access_time);
	push_nttime(params, 28, io->ntcreatex.out.write_time);
	push_nttime(params, 36, io->ntcreatex.out.change_time);
	SIVAL(params,       44, io->ntcreatex.out.attrib);
	SBVAL(params,       48, io->ntcreatex.out.alloc_size);
	SBVAL(params,       56, io->ntcreatex.out.size);
	SSVAL(params,       64, io->ntcreatex.out.file_type);
	SSVAL(params,       66, io->ntcreatex.out.ipc_state);
	SCVAL(params,       68, io->ntcreatex.out.is_directory);

	return NT_STATUS_OK;
}
예제 #2
0
void server_id_put(uint8_t buf[24], const struct server_id id)
{
	SBVAL(buf, 0,  id.pid);
	SIVAL(buf, 8,  id.task_id);
	SIVAL(buf, 12, id.vnn);
	SBVAL(buf, 16, id.unique_id);
}
예제 #3
0
파일: session.c 프로젝트: 0x24bin/winexe-1
/**
  send a session setup request
*/
struct smb2_request *smb2_session_setup_send(struct smb2_session *session, 
					     struct smb2_session_setup *io)
{
	struct smb2_request *req;
	NTSTATUS status;
	
	req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, 
				0x18, true, io->in.secblob.length);
	if (req == NULL) return NULL;

	SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, session->uid);
	SCVAL(req->out.body, 0x02, io->in.vc_number);
	SCVAL(req->out.body, 0x03, io->in.security_mode);
	SIVAL(req->out.body, 0x04, io->in.capabilities);
	SIVAL(req->out.body, 0x08, io->in.channel);
	SBVAL(req->out.body, 0x10, io->in.previous_sessionid);

	req->session = session;

	status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(req);
		return NULL;
	}

	smb2_transport_send(req);

	return req;
}
예제 #4
0
static void smbd_smb2_request_oplock_break_done(struct tevent_req *subreq)
{
    struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
                                    struct smbd_smb2_request);
    const uint8_t *inbody;
    int i = req->current_idx;
    uint64_t in_file_id_persistent;
    uint64_t in_file_id_volatile;
    uint8_t out_oplock_level = 0;
    DATA_BLOB outbody;
    NTSTATUS status;
    NTSTATUS error; /* transport error */

    status = smbd_smb2_oplock_break_recv(subreq, &out_oplock_level);
    TALLOC_FREE(subreq);
    if (!NT_STATUS_IS_OK(status)) {
        error = smbd_smb2_request_error(req, status);
        if (!NT_STATUS_IS_OK(error)) {
            smbd_server_connection_terminate(req->sconn,
                                             nt_errstr(error));
            return;
        }
        return;
    }

    inbody = (const uint8_t *)req->in.vector[i+1].iov_base;

    in_file_id_persistent	= BVAL(inbody, 0x08);
    in_file_id_volatile	= BVAL(inbody, 0x10);

    outbody = data_blob_talloc(req->out.vector, NULL, 0x18);
    if (outbody.data == NULL) {
        error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
        if (!NT_STATUS_IS_OK(error)) {
            smbd_server_connection_terminate(req->sconn,
                                             nt_errstr(error));
            return;
        }
        return;
    }

    SSVAL(outbody.data, 0x00, 0x18);	/* struct size */
    SCVAL(outbody.data, 0x02,
          out_oplock_level);		/* SMB2 oplock level */
    SCVAL(outbody.data, 0x03, 0);		/* reserved */
    SIVAL(outbody.data, 0x04, 0);		/* reserved */
    SBVAL(outbody.data, 0x08,
          in_file_id_persistent);		/* file id (persistent) */
    SBVAL(outbody.data, 0x10,
          in_file_id_volatile);		/* file id (volatile) */

    error = smbd_smb2_request_done(req, outbody, NULL);
    if (!NT_STATUS_IS_OK(error)) {
        smbd_server_connection_terminate(req->sconn,
                                         nt_errstr(error));
        return;
    }
}
예제 #5
0
파일: negprot.c 프로젝트: rchicoli/samba
/*
 * reply to a SMB negprot request with dialect "SMB 2.002"
 */
void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
{
	struct smb2srv_request *req;
	uint32_t body_fixed_size = 0x26;

	req = talloc_zero(smb_req->smb_conn, struct smb2srv_request);
	if (!req) goto nomem;
	req->smb_conn		= smb_req->smb_conn;
	req->request_time	= smb_req->request_time;
	talloc_steal(req, smb_req);

	req->in.size      = NBT_HDR_SIZE+SMB2_HDR_BODY+body_fixed_size;
	req->in.allocated = req->in.size;
	req->in.buffer    = talloc_array(req, uint8_t, req->in.allocated);
	if (!req->in.buffer) goto nomem;
	req->in.hdr       = req->in.buffer + NBT_HDR_SIZE;
	req->in.body      = req->in.hdr + SMB2_HDR_BODY;
	req->in.body_size = body_fixed_size;
	req->in.dynamic   = NULL;

	smb2srv_setup_bufinfo(req);

	SIVAL(req->in.hdr, 0,				SMB2_MAGIC);
	SSVAL(req->in.hdr, SMB2_HDR_LENGTH,		SMB2_HDR_BODY);
	SSVAL(req->in.hdr, SMB2_HDR_EPOCH,		0);
	SIVAL(req->in.hdr, SMB2_HDR_STATUS,		0);
	SSVAL(req->in.hdr, SMB2_HDR_OPCODE,		SMB2_OP_NEGPROT);
	SSVAL(req->in.hdr, SMB2_HDR_CREDIT,		0);
	SIVAL(req->in.hdr, SMB2_HDR_FLAGS,		0);
	SIVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND,	0);
	SBVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID,		0);
	SIVAL(req->in.hdr, SMB2_HDR_PID,		0);
	SIVAL(req->in.hdr, SMB2_HDR_TID,		0);
	SBVAL(req->in.hdr, SMB2_HDR_SESSION_ID,		0);
	memset(req->in.hdr+SMB2_HDR_SIGNATURE, 0, 16);

	/* this seems to be a bug, they use 0x24 but the length is 0x26 */
	SSVAL(req->in.body, 0x00, 0x24);

	SSVAL(req->in.body, 0x02, 1);
	memset(req->in.body+0x04, 0, 32);
	SSVAL(req->in.body, 0x24, SMB2_DIALECT_REVISION_202);

	smb2srv_negprot_recv(req);
	return;
nomem:
	smbsrv_terminate_connection(smb_req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY));
	talloc_free(req);
	return;
}
예제 #6
0
/*
 * reply to a SMB negprot request with dialect "SMB 2.001"
 */
void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
{
	struct smb2srv_request *req;
	uint32_t body_fixed_size = 0x26;

	/* create a fake SMB2 negprot request */
	req = talloc_zero(smb_req->smb_conn, struct smb2srv_request);
	if (!req) goto nomem;
	req->smb_conn		= smb_req->smb_conn;
	req->request_time	= smb_req->request_time;
	talloc_steal(req, smb_req);

	req->in.size      = NBT_HDR_SIZE+SMB2_HDR_BODY+body_fixed_size;
	req->in.allocated = req->in.size;
	req->in.buffer    = talloc_size(req, req->in.allocated);
	if (!req->in.buffer) goto nomem;
	req->in.hdr       = req->in.buffer + NBT_HDR_SIZE;
	req->in.body      = req->in.hdr + SMB2_HDR_BODY;
	req->in.body_size = body_fixed_size;
	req->in.dynamic   = NULL;

	SIVAL(req->in.hdr, 0,				SMB2_MAGIC);
	SSVAL(req->in.hdr, SMB2_HDR_LENGTH,		SMB2_HDR_BODY);
	SSVAL(req->in.hdr, SMB2_HDR_PAD1,		0);
	SIVAL(req->in.hdr, SMB2_HDR_STATUS,		0);
	SSVAL(req->in.hdr, SMB2_HDR_OPCODE,		SMB2_OP_NEGPROT);
	SSVAL(req->in.hdr, SMB2_HDR_UNKNOWN1,		0);
	SIVAL(req->in.hdr, SMB2_HDR_FLAGS,		0);
	SIVAL(req->in.hdr, SMB2_HDR_CHAIN_OFFSET,	0);
	SBVAL(req->in.hdr, SMB2_HDR_SEQNUM,		0);
	SIVAL(req->in.hdr, SMB2_HDR_PID,		0);
	SIVAL(req->in.hdr, SMB2_HDR_TID,		0);
	SBVAL(req->in.hdr, SMB2_HDR_UID,		0);
	memset(req->in.hdr+SMB2_HDR_SIG, 0, 16);

	/* this seems to be a bug, they use 0x24 but the length is 0x26 */
	SSVAL(req->in.body, 0x00, 0x24);

	SSVAL(req->in.body, 0x02, 1);
	memset(req->in.body+0x04, 0, 32);
	SSVAL(req->in.body, 0x24, 0);

	smb2srv_negprot_recv(req);
	return;
nomem:
	smbsrv_terminate_connection(smb_req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY));
	talloc_free(req);
	return;
}
예제 #7
0
파일: smbXsrv_open.c 프로젝트: hef/samba
uint32_t smbXsrv_open_hash(struct smbXsrv_open *_open)
{
    uint8_t buf[8+8+8];
    uint32_t ret;

    SBVAL(buf,  0, _open->global->open_persistent_id);
    SBVAL(buf,  8, _open->global->open_volatile_id);
    SBVAL(buf, 16, _open->global->open_time);

    ret = hash(buf, sizeof(buf), 0);

    if (ret == 0) {
        ret = 1;
    }

    return ret;
}
예제 #8
0
void smb2srv_push_handle(uint8_t *base, uint_t offset, struct ntvfs_handle *ntvfs)
{
	struct smbsrv_handle *handle = talloc_get_type(ntvfs->frontend_data.private_data,
				       struct smbsrv_handle);

	/* 
	 * the handle is 128 bit on the wire
	 */
	SBVAL(base, offset,	handle->hid);
	SIVAL(base, offset + 8,	handle->tcon->tid);
	SIVAL(base, offset + 12,UINT32_MAX);
}
예제 #9
0
static void smb2srv_create_send(struct ntvfs_request *ntvfs)
{
	struct smb2srv_request *req;
	union smb_open *io;

	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);
	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, True, io->smb2.out.blob.length));

	SSVAL(req->out.body,	0x02,	io->smb2.out.oplock_flags);
	SIVAL(req->out.body,	0x04,	io->smb2.out.create_action);
	SBVAL(req->out.body,	0x08,	io->smb2.out.create_time);
	SBVAL(req->out.body,	0x10,	io->smb2.out.access_time);
	SBVAL(req->out.body,	0x18,	io->smb2.out.write_time);
	SBVAL(req->out.body,	0x20,	io->smb2.out.change_time);
	SBVAL(req->out.body,	0x28,	io->smb2.out.alloc_size);
	SBVAL(req->out.body,	0x30,	io->smb2.out.size);
	SIVAL(req->out.body,	0x38,	io->smb2.out.file_attr);
	SIVAL(req->out.body,	0x3C,	io->smb2.out._pad);
	smb2srv_push_handle(req->out.body, 0x40, io->smb2.out.file.ntvfs);
	SMB2SRV_CHECK(smb2_push_o32s32_blob(&req->out, 0x50, io->smb2.out.blob));

	/* also setup the chained file handle */
	req->chained_file_handle = req->_chained_file_handle;
	smb2srv_push_handle(req->chained_file_handle, 0, io->smb2.out.file.ntvfs);

	smb2srv_send_reply(req);
}
예제 #10
0
static void smb2srv_read_send(struct ntvfs_request *ntvfs)
{
	struct smb2srv_request *req;
	union smb_read *io;

	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_read);
	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, True, io->smb2.out.data.length));

	/* TODO: avoid the memcpy */
	SMB2SRV_CHECK(smb2_push_o16s32_blob(&req->out, 0x02, io->smb2.out.data));
	SBVAL(req->out.body,	0x08,	io->smb2.out.unknown1);

	smb2srv_send_reply(req);
}
예제 #11
0
static void smb2srv_write_send(struct ntvfs_request *ntvfs)
{
	struct smb2srv_request *req;
	union smb_write *io;

	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_write);
	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, True, 0));

	SSVAL(req->out.body,	0x02,	io->smb2.out._pad);
	SIVAL(req->out.body,	0x04,	io->smb2.out.nwritten);
	SBVAL(req->out.body,	0x08,	io->smb2.out.unknown1);

	smb2srv_send_reply(req);
}
예제 #12
0
파일: write.c 프로젝트: AIdrifter/samba
/*
  send a write request
*/
struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write *io)
{
	NTSTATUS status;
	struct smb2_request *req;

	req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, true, io->in.data.length);
	if (req == NULL) return NULL;

	status = smb2_push_o16s32_blob(&req->out, 0x02, io->in.data);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(req);
		return NULL;
	}

	SBVAL(req->out.body, 0x08, io->in.offset);
	smb2_push_handle(req->out.body+0x10, &io->in.file.handle);

	SBVAL(req->out.body, 0x20, io->in.unknown1);
	SBVAL(req->out.body, 0x28, io->in.unknown2);

	smb2_transport_send(req);

	return req;
}
예제 #13
0
/*
    initialise a smb2 request for tree operations
*/
struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode,
					    uint16_t body_fixed_size, BOOL body_dynamic_present,
					    uint32_t body_dynamic_size)
{
	struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, 
						     body_fixed_size, body_dynamic_present,
						     body_dynamic_size);
	if (req == NULL) return NULL;

	SBVAL(req->out.hdr,  SMB2_HDR_UID, tree->session->uid);
	SIVAL(req->out.hdr,  SMB2_HDR_TID, tree->tid);
	req->session = tree->session;
	req->tree = tree;

	return req;	
}
예제 #14
0
/*
  Send a Lease Break Acknowledgement
*/
struct smb2_request *smb2_lease_break_ack_send(struct smb2_tree *tree,
                                               struct smb2_lease_break_ack *io)
{
	struct smb2_request *req;

	req = smb2_request_init_tree(tree, SMB2_OP_BREAK, 0x24, false, 0);
	if (req == NULL) return NULL;

	SIVAL(req->out.body, 0x02, io->in.reserved);
	SIVAL(req->out.body, 0x04, io->in.lease.lease_flags);
	memcpy(req->out.body+0x8, &io->in.lease.lease_key,
	    sizeof(struct smb2_lease_key));
	SIVAL(req->out.body, 0x18, io->in.lease.lease_state);
	SBVAL(req->out.body, 0x1C, io->in.lease.lease_duration);

	smb2_transport_send(req);

	return req;
}
예제 #15
0
파일: scripts.c 프로젝트: samba-team/samba
static NTSTATUS generate_gp_registry_entry(TALLOC_CTX *mem_ctx,
					   const char *key,
					   const char *value,
					   uint32_t data_type,
					   const void *data_p,
					   enum gp_reg_action action,
					   struct gp_registry_entry **entry_out)
{
	struct gp_registry_entry *entry = NULL;
	struct registry_value *data = NULL;

	entry = talloc_zero(mem_ctx, struct gp_registry_entry);
	NT_STATUS_HAVE_NO_MEMORY(entry);

	data = talloc_zero(mem_ctx, struct registry_value);
	NT_STATUS_HAVE_NO_MEMORY(data);

	data->type = data_type;
	switch (data->type) {
		case REG_QWORD:
			data->data = data_blob_talloc(mem_ctx, NULL, 8);
			SBVAL(data->data.data, 0, *(uint64_t *)data_p);
			break;
		case REG_SZ:
			if (!push_reg_sz(mem_ctx, &data->data, (const char *)data_p)) {
				return NT_STATUS_NO_MEMORY;
			}
			break;
		default:
			return NT_STATUS_NOT_SUPPORTED;
	}

	entry->key = key;
	entry->data = data;
	entry->action = action;
	entry->value = talloc_strdup(mem_ctx, value);
	NT_STATUS_HAVE_NO_MEMORY(entry->value);

	*entry_out = entry;

	return NT_STATUS_OK;
}
예제 #16
0
static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb, 
						const struct dsdb_schema *schema,
						const struct dsdb_attribute *attr,
						const struct ldb_message_element *in,
						TALLOC_CTX *mem_ctx,
						struct drsuapi_DsReplicaAttribute *out)
{
	uint32_t i;
	DATA_BLOB *blobs;

	if (attr->attributeID_id == 0xFFFFFFFF) {
		return WERR_FOOBAR;
	}

	out->attid			= attr->attributeID_id;
	out->value_ctr.num_values	= in->num_values;
	out->value_ctr.values		= talloc_array(mem_ctx,
						       struct drsuapi_DsAttributeValue,
						       in->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);

	blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
	W_ERROR_HAVE_NO_MEMORY(blobs);

	for (i=0; i < in->num_values; i++) {
		NTTIME v;
		time_t t;

		out->value_ctr.values[i].blob	= &blobs[i];

		blobs[i] = data_blob_talloc(blobs, NULL, 8);
		W_ERROR_HAVE_NO_MEMORY(blobs[i].data);

		t = ldb_string_to_time((const char *)in->values[i].data);
		unix_to_nt_time(&v, t);
		v /= 10000000;

		SBVAL(blobs[i].data, 0, v);
	}

	return WERR_OK;
}
예제 #17
0
파일: sesssetup.c 프로젝트: aixoss/samba
static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io)
{
	if (NT_STATUS_IS_OK(req->status)) {
		/* nothing */
	} else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		/* nothing */
	} else {
		smb2srv_send_error(req, req->status);
		return;
	}

	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, io->smb2.out.secblob.length));

	SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID,	io->smb2.out.uid);

	SSVAL(req->out.body, 0x02, io->smb2.out.session_flags);
	SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x04, io->smb2.out.secblob));

	smb2srv_send_reply(req);
}
예제 #18
0
static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io)
{
	uint16_t unknown1;

	if (NT_STATUS_IS_OK(req->status)) {
		unknown1 = 0x0003;
	} else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		unknown1 = 0x0002;
	} else {
		smb2srv_send_error(req, req->status);
		return;
	}

	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, True, io->smb2.out.secblob.length));

	SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,	unknown1);
	SBVAL(req->out.hdr, SMB2_HDR_UID,	io->smb2.out.uid);

	SSVAL(req->out.body, 0x02, io->smb2.out._pad);
	SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x04, io->smb2.out.secblob));

	smb2srv_send_reply(req);
}
예제 #19
0
파일: read.c 프로젝트: AIdrifter/samba
/*
  send a read request
*/
struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io)
{
	struct smb2_request *req;

	req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x30, true, 0);
	if (req == NULL) return NULL;

	SCVAL(req->out.body, 0x02, 0); /* pad */
	SCVAL(req->out.body, 0x03, 0); /* reserved */
	SIVAL(req->out.body, 0x04, io->in.length);
	SBVAL(req->out.body, 0x08, io->in.offset);
	smb2_push_handle(req->out.body+0x10, &io->in.file.handle);
	SIVAL(req->out.body, 0x20, io->in.min_count);
	SIVAL(req->out.body, 0x24, io->in.channel);
	SIVAL(req->out.body, 0x28, io->in.remaining);
	SSVAL(req->out.body, 0x2C, io->in.channel_offset);
	SSVAL(req->out.body, 0x2E, io->in.channel_length);

	req->credit_charge = (MAX(io->in.length, 1) - 1)/ 65536 + 1;

	smb2_transport_send(req);

	return req;
}
예제 #20
0
파일: fileio.c 프로젝트: AllardJ/Tomato
static void smb2srv_create_send(struct ntvfs_request *ntvfs)
{
	struct smb2srv_request *req;
	union smb_open *io;
	DATA_BLOB blob;

	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);

	/* setup the blobs we should give in the reply */
	if (io->smb2.out.maximal_access != 0) {
		uint32_t data[2];
		SIVAL(data, 0, 0);
		SIVAL(data, 4, io->smb2.out.maximal_access);
		SMB2SRV_CHECK(smb2_create_blob_add(req, &io->smb2.out.blobs,
						   SMB2_CREATE_TAG_MXAC, 
						   data_blob_const(data, 8)));
	}
	

	SMB2SRV_CHECK(smb2_create_blob_push(req, &blob, io->smb2.out.blobs));
	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, blob.length));

	SCVAL(req->out.body,	0x02,	io->smb2.out.oplock_level);
	SCVAL(req->out.body,	0x03,	io->smb2.out.reserved);
	SIVAL(req->out.body,	0x04,	io->smb2.out.create_action);
	SBVAL(req->out.body,	0x08,	io->smb2.out.create_time);
	SBVAL(req->out.body,	0x10,	io->smb2.out.access_time);
	SBVAL(req->out.body,	0x18,	io->smb2.out.write_time);
	SBVAL(req->out.body,	0x20,	io->smb2.out.change_time);
	SBVAL(req->out.body,	0x28,	io->smb2.out.alloc_size);
	SBVAL(req->out.body,	0x30,	io->smb2.out.size);
	SIVAL(req->out.body,	0x38,	io->smb2.out.file_attr);
	SIVAL(req->out.body,	0x3C,	io->smb2.out.reserved2);
	smb2srv_push_handle(req->out.body, 0x40, io->smb2.out.file.ntvfs);
	SMB2SRV_CHECK(smb2_push_o32s32_blob(&req->out, 0x50, blob));

	/* also setup the chained file handle */
	req->chained_file_handle = req->_chained_file_handle;
	smb2srv_push_handle(req->chained_file_handle, 0, io->smb2.out.file.ntvfs);

	smb2srv_send_reply(req);
}
예제 #21
0
static void smb2srv_close_send(struct ntvfs_request *ntvfs)
{
	struct smb2srv_request *req;
	union smb_close *io;

	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_close);
	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x3C, False, 0));

	SSVAL(req->out.body,	0x02,	io->smb2.out.flags);
	SIVAL(req->out.body,	0x04,	io->smb2.out._pad);
	SBVAL(req->out.body,	0x08,	io->smb2.out.create_time);
	SBVAL(req->out.body,	0x10,	io->smb2.out.access_time);
	SBVAL(req->out.body,	0x18,	io->smb2.out.write_time);
	SBVAL(req->out.body,	0x20,	io->smb2.out.change_time);
	SBVAL(req->out.body,	0x28,	io->smb2.out.alloc_size);
	SBVAL(req->out.body,	0x30,	io->smb2.out.size);
	SIVAL(req->out.body,	0x38,	io->smb2.out.file_attr);

	smb2srv_send_reply(req);
}
예제 #22
0
파일: fileio.c 프로젝트: AllardJ/Tomato
static void smb2srv_close_send(struct ntvfs_request *ntvfs)
{
	struct smb2srv_request *req;
	union smb_close *io;

	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_close);
	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x3C, false, 0));

	SSVAL(req->out.body,	0x02,	io->smb2.out.flags);
	SIVAL(req->out.body,	0x04,	io->smb2.out._pad);
	SBVAL(req->out.body,	0x08,	io->smb2.out.create_time);
	SBVAL(req->out.body,	0x10,	io->smb2.out.access_time);
	SBVAL(req->out.body,	0x18,	io->smb2.out.write_time);
	SBVAL(req->out.body,	0x20,	io->smb2.out.change_time);
	SBVAL(req->out.body,	0x28,	io->smb2.out.alloc_size);
	SBVAL(req->out.body,	0x30,	io->smb2.out.size);
	SIVAL(req->out.body,	0x38,	io->smb2.out.file_attr);

	/* also destroy the chained file handle */
	req->chained_file_handle = NULL;
	memset(req->_chained_file_handle, 0, sizeof(req->_chained_file_handle));

	smb2srv_send_reply(req);
}
예제 #23
0
static void smbd_smb2_request_close_done(struct tevent_req *subreq)
{
	struct smbd_smb2_request *req =
		tevent_req_callback_data(subreq,
		struct smbd_smb2_request);
	DATA_BLOB outbody;
	uint16_t out_flags = 0;
	connection_struct *conn = req->tcon->compat;
	struct timespec out_creation_ts = { 0, };
	struct timespec out_last_access_ts = { 0, };
	struct timespec out_last_write_ts = { 0, };
	struct timespec out_change_ts = { 0, };
	uint64_t out_allocation_size = 0;
	uint64_t out_end_of_file = 0;
	uint32_t out_file_attributes = 0;
	NTSTATUS status;
	NTSTATUS error;

	status = smbd_smb2_close_recv(subreq,
				      &out_flags,
				      &out_creation_ts,
				      &out_last_access_ts,
				      &out_last_write_ts,
				      &out_change_ts,
				      &out_allocation_size,
				      &out_end_of_file,
				      &out_file_attributes);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status)) {
		error = smbd_smb2_request_error(req, status);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->xconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	outbody = smbd_smb2_generate_outbody(req, 0x3C);
	if (outbody.data == NULL) {
		error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->xconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	SSVAL(outbody.data, 0x00, 0x3C);	/* struct size */
	SSVAL(outbody.data, 0x02, out_flags);
	SIVAL(outbody.data, 0x04, 0);		/* reserved */
	put_long_date_timespec(conn->ts_res,
		(char *)outbody.data + 0x08, out_creation_ts);
	put_long_date_timespec(conn->ts_res,
		(char *)outbody.data + 0x10, out_last_access_ts);
	put_long_date_timespec(conn->ts_res,
		(char *)outbody.data + 0x18, out_last_write_ts);
	put_long_date_timespec(conn->ts_res,
		(char *)outbody.data + 0x20, out_change_ts);
	SBVAL(outbody.data, 0x28, out_allocation_size);
	SBVAL(outbody.data, 0x30, out_end_of_file);
	SIVAL(outbody.data, 0x38, out_file_attributes);

	error = smbd_smb2_request_done(req, outbody, NULL);
	if (!NT_STATUS_IS_OK(error)) {
		smbd_server_connection_terminate(req->xconn,
						 nt_errstr(error));
		return;
	}
}
예제 #24
0
파일: request.c 프로젝트: AIdrifter/samba
/*
  push a file handle into a buffer
*/
void smb2_push_handle(uint8_t *data, struct smb2_handle *h)
{
	SBVAL(data, 0, h->data[0]);
	SBVAL(data, 8, h->data[1]);
}
예제 #25
0
파일: request.c 프로젝트: AIdrifter/samba
/*
  initialise a smb2 request
*/
struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode,
				       uint16_t body_fixed_size, bool body_dynamic_present,
				       uint32_t body_dynamic_size)
{
	struct smb2_request *req;
	uint32_t hdr_offset;
	bool compound = false;

	if (body_dynamic_present) {
		if (body_dynamic_size == 0) {
			body_dynamic_size = 1;
		}
	} else {
		body_dynamic_size = 0;
	}

	req = talloc_zero(transport, struct smb2_request);
	if (req == NULL) return NULL;

	req->state     = SMB2_REQUEST_INIT;
	req->transport = transport;

	hdr_offset = NBT_HDR_SIZE;

	req->out.size      = hdr_offset + SMB2_HDR_BODY + body_fixed_size;
	req->out.allocated = req->out.size + body_dynamic_size;

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

	req->out.hdr       = req->out.buffer + hdr_offset;
	req->out.body      = req->out.hdr + SMB2_HDR_BODY;
	req->out.body_fixed= body_fixed_size;
	req->out.body_size = body_fixed_size;
	req->out.dynamic   = (body_dynamic_size ? req->out.body + body_fixed_size : NULL);

	SIVAL(req->out.hdr, 0,				SMB2_MAGIC);
	SSVAL(req->out.hdr, SMB2_HDR_LENGTH,		SMB2_HDR_BODY);
	SSVAL(req->out.hdr, SMB2_HDR_CREDIT_CHARGE,	0);
	SIVAL(req->out.hdr, SMB2_HDR_STATUS,		0);
	SSVAL(req->out.hdr, SMB2_HDR_OPCODE,		opcode);
	SSVAL(req->out.hdr, SMB2_HDR_CREDIT,		0);
	SIVAL(req->out.hdr, SMB2_HDR_FLAGS,		0);
	SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND,	0);
	SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID,	0);
	SIVAL(req->out.hdr, SMB2_HDR_PID,		0);
	SIVAL(req->out.hdr, SMB2_HDR_TID,		0);
	SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID,		0);
	memset(req->out.hdr+SMB2_HDR_SIGNATURE, 0, 16);

	/* set the length of the fixed body part and +1 if there's a dynamic part also */
	SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0));

	/* 
	 * if we have a dynamic part, make sure the first byte
	 * which is always be part of the packet is initialized
	 */
	if (body_dynamic_size && !compound) {
		req->out.size += 1;
		SCVAL(req->out.dynamic, 0, 0);
	}

	return req;
}
예제 #26
0
/*
  initialise a smb2 request
*/
struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode,
				       uint16_t body_fixed_size, BOOL body_dynamic_present,
				       uint32_t body_dynamic_size)
{
	struct smb2_request *req;
	uint64_t seqnum;

	if (body_dynamic_present) {
		if (body_dynamic_size == 0) {
			body_dynamic_size = 1;
		}
	} else {
		body_dynamic_size = 0;
	}

	req = talloc(transport, struct smb2_request);
	if (req == NULL) return NULL;

	seqnum = transport->seqnum++;
	if (seqnum == UINT64_MAX) {
		seqnum = transport->seqnum++;
	}

	req->state     = SMB2_REQUEST_INIT;
	req->transport = transport;
	req->session   = NULL;
	req->tree      = NULL;
	req->seqnum    = seqnum;
	req->status    = NT_STATUS_OK;
	req->async.fn  = NULL;
	req->next = req->prev = NULL;

	ZERO_STRUCT(req->cancel);
	ZERO_STRUCT(req->in);

	req->out.size      = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size;

	req->out.allocated = req->out.size + body_dynamic_size;
	req->out.buffer    = talloc_size(req, req->out.allocated);
	if (req->out.buffer == NULL) {
		talloc_free(req);
		return NULL;
	}

	req->out.hdr       = req->out.buffer + NBT_HDR_SIZE;
	req->out.body      = req->out.hdr + SMB2_HDR_BODY;
	req->out.body_fixed= body_fixed_size;
	req->out.body_size = body_fixed_size;
	req->out.dynamic   = (body_dynamic_size ? req->out.body + body_fixed_size : NULL);

	SIVAL(req->out.hdr, 0,				SMB2_MAGIC);
	SSVAL(req->out.hdr, SMB2_HDR_LENGTH,		SMB2_HDR_BODY);
	SSVAL(req->out.hdr, SMB2_HDR_PAD1,		0);
	SIVAL(req->out.hdr, SMB2_HDR_STATUS,		0);
	SSVAL(req->out.hdr, SMB2_HDR_OPCODE,		opcode);
	SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,		0);
	SIVAL(req->out.hdr, SMB2_HDR_FLAGS,		0);
	SIVAL(req->out.hdr, SMB2_HDR_CHAIN_OFFSET,	0);
	SBVAL(req->out.hdr, SMB2_HDR_SEQNUM,		req->seqnum);
	SIVAL(req->out.hdr, SMB2_HDR_PID,		0);
	SIVAL(req->out.hdr, SMB2_HDR_TID,		0);
	SBVAL(req->out.hdr, SMB2_HDR_UID,		0);
	memset(req->out.hdr+SMB2_HDR_SIG, 0, 16);

	/* set the length of the fixed body part and +1 if there's a dynamic part also */
	SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0));

	/* 
	 * if we have a dynamic part, make sure the first byte
	 * which is always be part of the packet is initialized
	 */
	if (body_dynamic_size) {
		req->out.size += 1;
		SCVAL(req->out.dynamic, 0, 0);
	}

	return req;
}
예제 #27
0
파일: rawrequest.c 프로젝트: Arkhont/samba
/*
  put a NTTIME into a packet
*/
void smbcli_push_nttime(void *base, uint16_t offset, NTTIME t)
{
	SBVAL(base, offset, t);
}
예제 #28
0
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
{
	const uint8_t *inbody;
	const uint8_t *indyn = NULL;
	int i = req->current_idx;
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	DATA_BLOB negprot_spnego_blob;
	uint16_t security_offset;
	DATA_BLOB security_buffer;
	size_t expected_body_size = 0x24;
	size_t body_size;
	size_t expected_dyn_size = 0;
	size_t c;
	uint16_t security_mode;
	uint16_t dialect_count;
	uint16_t dialect = 0;
	uint32_t capabilities;

/* TODO: drop the connection with INVALI_PARAMETER */

	if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	inbody = (const uint8_t *)req->in.vector[i+1].iov_base;

	body_size = SVAL(inbody, 0x00);
	if (body_size != expected_body_size) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	dialect_count = SVAL(inbody, 0x02);
	if (dialect_count == 0) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	expected_dyn_size = dialect_count * 2;
	if (req->in.vector[i+2].iov_len < expected_dyn_size) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}
	indyn = (const uint8_t *)req->in.vector[i+2].iov_base;

	for (c=0; c < dialect_count; c++) {
		dialect = SVAL(indyn, c*2);
		if (dialect == SMB2_DIALECT_REVISION_202) {
			break;
		}
	}

	if (dialect != SMB2_DIALECT_REVISION_202) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	set_Protocol(PROTOCOL_SMB2);

	if (get_remote_arch() != RA_SAMBA) {
		set_remote_arch(RA_VISTA);
	}

	/* negprot_spnego() returns a the server guid in the first 16 bytes */
	negprot_spnego_blob = negprot_spnego();
	if (negprot_spnego_blob.data == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
	}
	talloc_steal(req, negprot_spnego_blob.data);

	if (negprot_spnego_blob.length < 16) {
		return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
	}

	security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
	if (lp_server_signing() == Required) {
		security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
	}

	capabilities = 0;
	if (lp_host_msdfs()) {
		capabilities |= SMB2_CAP_DFS;
	}

	security_offset = SMB2_HDR_BODY + 0x40;

#if 1
	/* Try SPNEGO auth... */
	security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
					  negprot_spnego_blob.length - 16);
#else
	/* for now we want raw NTLMSSP */
	security_buffer = data_blob_const(NULL, 0);
#endif

	outbody = data_blob_talloc(req->out.vector, NULL, 0x40);
	if (outbody.data == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
	}

	SSVAL(outbody.data, 0x00, 0x40 + 1);	/* struct size */
	SSVAL(outbody.data, 0x02,
	      security_mode);			/* security mode */
	SSVAL(outbody.data, 0x04, dialect);	/* dialect revision */
	SSVAL(outbody.data, 0x06, 0);		/* reserved */
	memcpy(outbody.data + 0x08,
	       negprot_spnego_blob.data, 16);	/* server guid */
	SIVAL(outbody.data, 0x18,
	      capabilities);			/* capabilities */
	SIVAL(outbody.data, 0x1C, 0x00010000);	/* max transact size */
	SIVAL(outbody.data, 0x20, 0x00010000);	/* max read size */
	SIVAL(outbody.data, 0x24, 0x00010000);	/* max write size */
	SBVAL(outbody.data, 0x28, 0);		/* system time */
	SBVAL(outbody.data, 0x30, 0);		/* server start time */
	SSVAL(outbody.data, 0x38,
	      security_offset);			/* security buffer offset */
	SSVAL(outbody.data, 0x3A,
	      security_buffer.length);		/* security buffer length */
	SIVAL(outbody.data, 0x3C, 0);		/* reserved */

	outdyn = security_buffer;

	return smbd_smb2_request_done(req, outbody, &outdyn);
}
예제 #29
0
static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
{
	struct smbd_smb2_request *smb2req =
		tevent_req_callback_data(subreq,
		struct smbd_smb2_request);
	uint8_t *outhdr;
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	uint16_t out_session_flags = 0;
	uint64_t out_session_id = 0;
	uint16_t out_security_offset;
	DATA_BLOB out_security_buffer = data_blob_null;
	NTSTATUS status;
	NTSTATUS error; /* transport error */

	status = smbd_smb2_session_setup_wrap_recv(subreq,
						   &out_session_flags,
						   smb2req,
						   &out_security_buffer,
						   &out_session_id);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status) &&
	    !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		status = nt_status_squash(status);
		error = smbd_smb2_request_error(smb2req, status);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(smb2req->xconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	out_security_offset = SMB2_HDR_BODY + 0x08;

	outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);

	outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
	if (outbody.data == NULL) {
		error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(smb2req->xconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);

	SSVAL(outbody.data, 0x00, 0x08 + 1);	/* struct size */
	SSVAL(outbody.data, 0x02,
	      out_session_flags);		/* session flags */
	SSVAL(outbody.data, 0x04,
	      out_security_offset);		/* security buffer offset */
	SSVAL(outbody.data, 0x06,
	      out_security_buffer.length);	/* security buffer length */

	outdyn = out_security_buffer;

	error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
					   __location__);
	if (!NT_STATUS_IS_OK(error)) {
		smbd_server_connection_terminate(smb2req->xconn,
						 nt_errstr(error));
		return;
	}
}
예제 #30
0
파일: rawfile.c 프로젝트: AIdrifter/samba
/****************************************************************************
 Open a file - async send
****************************************************************************/
_PUBLIC_ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms)
{
	int len;
	struct smbcli_request *req = NULL; 
	bool bigoffset = false;

	switch (parms->generic.level) {
	case RAW_OPEN_T2OPEN:
		return smb_raw_t2open_send(tree, parms);

	case RAW_OPEN_OPEN:
		SETUP_REQUEST(SMBopen, 2, 0);
		SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode);
		SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
		smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
		break;
		
	case RAW_OPEN_OPENX:
		SETUP_REQUEST(SMBopenX, 15, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
		SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
		SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
		SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(6), parms->openx.in.write_time);
		SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
		SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
		SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
		SIVAL(req->out.vwv, VWV(13),0); /* reserved */
		smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
		break;
		
	case RAW_OPEN_MKNEW:
		SETUP_REQUEST(SMBmknew, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->mknew.in.write_time);
		smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
		break;

	case RAW_OPEN_CREATE:
		SETUP_REQUEST(SMBcreate, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->create.in.write_time);
		smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE);
		break;
		
	case RAW_OPEN_CTEMP:
		SETUP_REQUEST(SMBctemp, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->ctemp.in.write_time);
		smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
		break;
		
	case RAW_OPEN_SPLOPEN:
		SETUP_REQUEST(SMBsplopen, 2, 0);
		SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
		SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
		break;
		
	case RAW_OPEN_NTCREATEX:
		SETUP_REQUEST(SMBntcreateX, 24, 0);
		SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1),0);
		SCVAL(req->out.vwv, VWV(2),0); /* padding */
		SIVAL(req->out.vwv,  7, parms->ntcreatex.in.flags);
		SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid.fnum);
		SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
		SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
		SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
		SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
		SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
		SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
		SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
		SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
		
		smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
		SSVAL(req->out.vwv, 5, len);
		break;

	case RAW_OPEN_NTTRANS_CREATE:
		return smb_raw_nttrans_create_send(tree, parms);


	case RAW_OPEN_OPENX_READX:
		SETUP_REQUEST(SMBopenX, 15, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags);
		SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode);
		SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs);
		SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(6), parms->openxreadx.in.write_time);
		SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func);
		SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size);
		SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout);
		SIVAL(req->out.vwv, VWV(13),0);
		smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE);

		if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
			bigoffset = true;
		}

		smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);

		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), 0);
		SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset);
		SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF);
		SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt);
		SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16);
		SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining);
		if (bigoffset) {
			SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32);
		}
		break;

	case RAW_OPEN_NTCREATEX_READX:
		SETUP_REQUEST(SMBntcreateX, 24, 0);
		SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1),0);
		SCVAL(req->out.vwv, VWV(2),0); /* padding */
		SIVAL(req->out.vwv,  7, parms->ntcreatexreadx.in.flags);
		SIVAL(req->out.vwv, 11, parms->ntcreatexreadx.in.root_fid.fnum);
		SIVAL(req->out.vwv, 15, parms->ntcreatexreadx.in.access_mask);
		SBVAL(req->out.vwv, 19, parms->ntcreatexreadx.in.alloc_size);
		SIVAL(req->out.vwv, 27, parms->ntcreatexreadx.in.file_attr);
		SIVAL(req->out.vwv, 31, parms->ntcreatexreadx.in.share_access);
		SIVAL(req->out.vwv, 35, parms->ntcreatexreadx.in.open_disposition);
		SIVAL(req->out.vwv, 39, parms->ntcreatexreadx.in.create_options);
		SIVAL(req->out.vwv, 43, parms->ntcreatexreadx.in.impersonation);
		SCVAL(req->out.vwv, 47, parms->ntcreatexreadx.in.security_flags);

		smbcli_req_append_string_len(req, parms->ntcreatexreadx.in.fname, STR_TERMINATE, &len);
		SSVAL(req->out.vwv, 5, len);

		if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
			bigoffset = true;
		}

		smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);

		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), 0);
		SIVAL(req->out.vwv, VWV(3), parms->ntcreatexreadx.in.offset);
		SSVAL(req->out.vwv, VWV(5), parms->ntcreatexreadx.in.maxcnt & 0xFFFF);
		SSVAL(req->out.vwv, VWV(6), parms->ntcreatexreadx.in.mincnt);
		SIVAL(req->out.vwv, VWV(7), parms->ntcreatexreadx.in.maxcnt >> 16);
		SSVAL(req->out.vwv, VWV(9), parms->ntcreatexreadx.in.remaining);
		if (bigoffset) {
			SIVAL(req->out.vwv, VWV(10),parms->ntcreatexreadx.in.offset>>32);
		}
		break;

	case RAW_OPEN_SMB2:
		return NULL;
	}

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

	return req;
}