예제 #1
0
void smb2srv_create_recv(struct smb2srv_request *req)
{
	union smb_open *io;
	DATA_BLOB blob;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x38, True);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_open);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_create_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_OPEN_SMB2;
	io->smb2.in.oplock_flags	= SVAL(req->in.body, 0x02);
	io->smb2.in.impersonation	= IVAL(req->in.body, 0x04);
	io->smb2.in.unknown3[0]		= IVAL(req->in.body, 0x08);
	io->smb2.in.unknown3[1]		= IVAL(req->in.body, 0x0C);
	io->smb2.in.unknown3[2]		= IVAL(req->in.body, 0x10);
	io->smb2.in.unknown3[3]		= IVAL(req->in.body, 0x14);
	io->smb2.in.access_mask		= IVAL(req->in.body, 0x18);
	io->smb2.in.file_attr		= IVAL(req->in.body, 0x1C);
	io->smb2.in.share_access	= IVAL(req->in.body, 0x20);
	io->smb2.in.open_disposition	= IVAL(req->in.body, 0x24);
	io->smb2.in.create_options	= IVAL(req->in.body, 0x28);
	SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x2C, &io->smb2.in.fname));
	SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x30, &blob));
	/* TODO: parse the blob */
	ZERO_STRUCT(io->smb2.in.eas);

	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, io));
}
예제 #2
0
void smb2srv_ioctl_recv(struct smb2srv_request *req)
{
	union smb_ioctl *io;
	struct smb2_handle h;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x38, True);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_ioctl);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_ioctl_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	/* TODO: avoid the memcpy */
	io->smb2.in._pad		= SVAL(req->in.body, 0x02);
	io->smb2.in.function		= IVAL(req->in.body, 0x04);
	/* file handle ... */
	SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x18, &io->smb2.in.out));
	io->smb2.in.unknown2		= IVAL(req->in.body, 0x20);
	SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x24, &io->smb2.in.in));
	io->smb2.in.max_response_size	= IVAL(req->in.body, 0x2C);
	io->smb2.in.flags		= BVAL(req->in.body, 0x30);

	smb2_pull_handle(req->in.body + 0x08, &h);
	if (h.data[0] == UINT64_MAX && h.data[1] == UINT64_MAX) {
		io->smb2.level		= RAW_IOCTL_SMB2_NO_HANDLE;
	} else {
		io->smb2.level		= RAW_IOCTL_SMB2;
		io->smb2.in.file.ntvfs	= smb2srv_pull_handle(req, req->in.body, 0x08);
		SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	}

	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_ioctl(req->ntvfs, io));
}
예제 #3
0
파일: fileio.c 프로젝트: AllardJ/Tomato
void smb2srv_lock_recv(struct smb2srv_request *req)
{
	union smb_lock *io;
	int i;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x30, false);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_lock);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_lock_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_LOCK_SMB2;
	io->smb2.in.lock_count		= SVAL(req->in.body, 0x02);
	io->smb2.in.reserved		= IVAL(req->in.body, 0x04);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x08);
	if (req->in.body_size < 24 + 24*(uint64_t)io->smb2.in.lock_count) {
		DEBUG(0,("%s: lock buffer too small\n", __location__));
		smb2srv_send_error(req,  NT_STATUS_FOOBAR);
		return;
	}
	io->smb2.in.locks = talloc_array(io, struct smb2_lock_element, 
					 io->smb2.in.lock_count);
	if (io->smb2.in.locks == NULL) {
		smb2srv_send_error(req, NT_STATUS_NO_MEMORY);
		return;
	}

	for (i=0;i<io->smb2.in.lock_count;i++) {
		io->smb2.in.locks[i].offset	= BVAL(req->in.body, 24 + i*24);
		io->smb2.in.locks[i].length	= BVAL(req->in.body, 32 + i*24);
		io->smb2.in.locks[i].flags	= IVAL(req->in.body, 40 + i*24);
		io->smb2.in.locks[i].reserved	= IVAL(req->in.body, 44 + i*24);
	}

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, io));
}
예제 #4
0
void smb2srv_read_recv(struct smb2srv_request *req)
{
	union smb_read *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x30, True);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_read);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_read_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_READ_SMB2;
	io->smb2.in._pad		= SVAL(req->in.body, 0x02);
	io->smb2.in.length		= IVAL(req->in.body, 0x04);
	io->smb2.in.offset		= BVAL(req->in.body, 0x08);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x10);
	io->smb2.in.unknown1		= BVAL(req->in.body, 0x20);
	io->smb2.in.unknown2		= BVAL(req->in.body, 0x28);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);

	/* preallocate the buffer for the backends */
	io->smb2.out.data = data_blob_talloc(io, NULL, io->smb2.in.length);
	if (io->smb2.out.data.length != io->smb2.in.length) {
		SMB2SRV_CHECK(NT_STATUS_NO_MEMORY);
	}

	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));
}
예제 #5
0
파일: fileio.c 프로젝트: AllardJ/Tomato
void smb2srv_read_recv(struct smb2srv_request *req)
{
	union smb_read *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x30, true);

	/* MS-SMB2 2.2.19 read must have a single byte of zero */
	if (req->in.body_size - req->in.body_fixed < 1) {
		smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
		return;
	}
	SMB2SRV_TALLOC_IO_PTR(io, union smb_read);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_read_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_READ_SMB2;
	io->smb2.in._pad		= SVAL(req->in.body, 0x02);
	io->smb2.in.length		= IVAL(req->in.body, 0x04);
	io->smb2.in.offset		= BVAL(req->in.body, 0x08);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x10);
	io->smb2.in.min_count		= IVAL(req->in.body, 0x20);
	io->smb2.in.channel		= IVAL(req->in.body, 0x24);
	io->smb2.in.remaining		= IVAL(req->in.body, 0x28);
	io->smb2.in.channel_offset      = SVAL(req->in.body, 0x2C);
	io->smb2.in.channel_length      = SVAL(req->in.body, 0x2E);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);

	/* preallocate the buffer for the backends */
	io->smb2.out.data = data_blob_talloc(io, NULL, io->smb2.in.length);
	if (io->smb2.out.data.length != io->smb2.in.length) {
		SMB2SRV_CHECK(NT_STATUS_NO_MEMORY);
	}

	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));
}
예제 #6
0
void smb2srv_close_recv(struct smb2srv_request *req)
{
	union smb_close *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x18, False);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_close);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_close_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_CLOSE_SMB2;
	io->smb2.in.flags		= SVAL(req->in.body, 0x02);
	io->smb2.in._pad		= IVAL(req->in.body, 0x04);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x08);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_close(req->ntvfs, io));
}
예제 #7
0
파일: fileio.c 프로젝트: AllardJ/Tomato
void smb2srv_flush_recv(struct smb2srv_request *req)
{
	union smb_flush *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x18, false);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_flush);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_flush_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_FLUSH_SMB2;
	io->smb2.in.reserved1		= SVAL(req->in.body, 0x02);
	io->smb2.in.reserved2		= IVAL(req->in.body, 0x04);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x08);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_flush(req->ntvfs, io));
}
예제 #8
0
파일: fileio.c 프로젝트: AllardJ/Tomato
void smb2srv_break_recv(struct smb2srv_request *req)
{
	union smb_lock *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x18, false);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_lock);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_break_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2_break.level		= RAW_LOCK_SMB2_BREAK;
	io->smb2_break.in.oplock_level	= CVAL(req->in.body, 0x02);
	io->smb2_break.in.reserved	= CVAL(req->in.body, 0x03);
	io->smb2_break.in.reserved2	= IVAL(req->in.body, 0x04);
	io->smb2_break.in.file.ntvfs	= smb2srv_pull_handle(req, req->in.body, 0x08);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2_break.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, io));
}
예제 #9
0
void smb2srv_notify_recv(struct smb2srv_request *req)
{
	union smb_notify *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x20, False);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_notify);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_notify_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_NOTIFY_SMB2;
	io->smb2.in.recursive		= SVAL(req->in.body, 0x02);
	io->smb2.in.buffer_size		= IVAL(req->in.body, 0x04);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x08);
	io->smb2.in.completion_filter	= IVAL(req->in.body, 0x18);
	io->smb2.in.unknown		= BVAL(req->in.body, 0x1C);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_notify(req->ntvfs, io));
}
예제 #10
0
void smb2srv_write_recv(struct smb2srv_request *req)
{
	union smb_write *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x30, True);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_write);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_write_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	/* TODO: avoid the memcpy */
	io->smb2.level			= RAW_WRITE_SMB2;
	SMB2SRV_CHECK(smb2_pull_o16s32_blob(&req->in, io, req->in.body+0x02, &io->smb2.in.data));
	io->smb2.in.offset		= BVAL(req->in.body, 0x08);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x10);
	io->smb2.in.unknown1		= BVAL(req->in.body, 0x20);
	io->smb2.in.unknown2		= BVAL(req->in.body, 0x28);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));
}
예제 #11
0
void smb2srv_lock_recv(struct smb2srv_request *req)
{
	union smb_lock *io;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x30, False);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_lock);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_lock_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	io->smb2.level			= RAW_LOCK_SMB2;

	io->smb2.in.unknown1		= SVAL(req->in.body, 0x02);
	io->smb2.in.unknown2		= IVAL(req->in.body, 0x04);
	io->smb2.in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x08);
	io->smb2.in.offset		= BVAL(req->in.body, 0x18);
	io->smb2.in.count		= BVAL(req->in.body, 0x20);
	io->smb2.in.unknown5		= IVAL(req->in.body, 0x24);
	io->smb2.in.flags		= IVAL(req->in.body, 0x28);

	SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, io));
}
예제 #12
0
파일: fileio.c 프로젝트: AllardJ/Tomato
void smb2srv_create_recv(struct smb2srv_request *req)
{
	union smb_open *io;
	DATA_BLOB blob;
	int i;

	SMB2SRV_CHECK_BODY_SIZE(req, 0x38, true);
	SMB2SRV_TALLOC_IO_PTR(io, union smb_open);
	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_create_send, NTVFS_ASYNC_STATE_MAY_ASYNC);

	ZERO_STRUCT(io->smb2.in);
	io->smb2.level			= RAW_OPEN_SMB2;
	io->smb2.in.security_flags	= CVAL(req->in.body, 0x02);
	io->smb2.in.oplock_level	= CVAL(req->in.body, 0x03);
	io->smb2.in.impersonation_level	= IVAL(req->in.body, 0x04);
	io->smb2.in.create_flags	= BVAL(req->in.body, 0x08);
	io->smb2.in.reserved		= BVAL(req->in.body, 0x10);
	io->smb2.in.desired_access	= IVAL(req->in.body, 0x18);
	io->smb2.in.file_attributes	= IVAL(req->in.body, 0x1C);
	io->smb2.in.share_access	= IVAL(req->in.body, 0x20);
	io->smb2.in.create_disposition	= IVAL(req->in.body, 0x24);
	io->smb2.in.create_options	= IVAL(req->in.body, 0x28);
	SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x2C, &io->smb2.in.fname));
	SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x30, &blob));
	SMB2SRV_CHECK(smb2_create_blob_parse(io, blob, &io->smb2.in.blobs));

	/* interpret the parsed tags that a server needs to respond to */
	for (i=0;i<io->smb2.in.blobs.num_blobs;i++) {
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_EXTA) == 0) {
			SMB2SRV_CHECK(ea_pull_list_chained(&io->smb2.in.blobs.blobs[i].data, io, 
							   &io->smb2.in.eas.num_eas,
							   &io->smb2.in.eas.eas));
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_SECD) == 0) {
			enum ndr_err_code ndr_err;
			io->smb2.in.sec_desc = talloc(io, struct security_descriptor);
			if (io->smb2.in.sec_desc == NULL) {
				smb2srv_send_error(req,  NT_STATUS_NO_MEMORY);
				return;
			}
			ndr_err = ndr_pull_struct_blob(&io->smb2.in.blobs.blobs[i].data, io, NULL,
						       io->smb2.in.sec_desc,
						       (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				smb2srv_send_error(req,  ndr_map_error2ntstatus(ndr_err));
				return;
			}
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_DHNQ) == 0) {
			io->smb2.in.durable_open = true;
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_DHNC) == 0) {
			if (io->smb2.in.blobs.blobs[i].data.length != 16) {
				smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
				return;				
			}
			io->smb2.in.durable_handle = talloc(io, struct smb2_handle);
			if (io->smb2.in.durable_handle == NULL) {
				smb2srv_send_error(req,  NT_STATUS_NO_MEMORY);
				return;
			}
			smb2_pull_handle(io->smb2.in.blobs.blobs[i].data.data, io->smb2.in.durable_handle);
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_ALSI) == 0) {
			if (io->smb2.in.blobs.blobs[i].data.length != 8) {
				smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
				return;				
			}
			io->smb2.in.alloc_size = BVAL(io->smb2.in.blobs.blobs[i].data.data, 0);
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
			io->smb2.in.query_maximal_access = true;
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_TWRP) == 0) {
			if (io->smb2.in.blobs.blobs[i].data.length != 8) {
				smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
				return;				
			}
			io->smb2.in.timewarp = BVAL(io->smb2.in.blobs.blobs[i].data.data, 0);			
		}
		if (strcmp(io->smb2.in.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
			io->smb2.in.query_on_disk_id = true;
		}
	}
		
	/* the VFS backend does not yet handle NULL filenames */
	if (io->smb2.in.fname == NULL) {
		io->smb2.in.fname = "";
	}

	SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, io));
}