Ejemplo n.º 1
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));
}
Ejemplo n.º 2
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));
}
Ejemplo n.º 3
0
/*
  recv a create reply
*/
NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io)
{
	NTSTATUS status;

	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x58, True);

	io->out.oplock_flags   = SVAL(req->in.body, 0x02);
	io->out.create_action  = IVAL(req->in.body, 0x04);
	io->out.create_time    = smbcli_pull_nttime(req->in.body, 0x08);
	io->out.access_time    = smbcli_pull_nttime(req->in.body, 0x10);
	io->out.write_time     = smbcli_pull_nttime(req->in.body, 0x18);
	io->out.change_time    = smbcli_pull_nttime(req->in.body, 0x20);
	io->out.alloc_size     = BVAL(req->in.body, 0x28);
	io->out.size           = BVAL(req->in.body, 0x30);
	io->out.file_attr      = IVAL(req->in.body, 0x38);
	io->out._pad           = IVAL(req->in.body, 0x3C);
	smb2_pull_handle(req->in.body+0x40, &io->out.file.handle);
	status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	return smb2_request_destroy(req);
}
Ejemplo n.º 4
0
/*
  recv a create reply
*/
NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io)
{
	NTSTATUS status;
	DATA_BLOB blob;
	int i;

	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x58, true);
	ZERO_STRUCT(io->out);
	io->out.oplock_level   = CVAL(req->in.body, 0x02);
	io->out.reserved       = CVAL(req->in.body, 0x03);
	io->out.create_action  = IVAL(req->in.body, 0x04);
	io->out.create_time    = smbcli_pull_nttime(req->in.body, 0x08);
	io->out.access_time    = smbcli_pull_nttime(req->in.body, 0x10);
	io->out.write_time     = smbcli_pull_nttime(req->in.body, 0x18);
	io->out.change_time    = smbcli_pull_nttime(req->in.body, 0x20);
	io->out.alloc_size     = BVAL(req->in.body, 0x28);
	io->out.size           = BVAL(req->in.body, 0x30);
	io->out.file_attr      = IVAL(req->in.body, 0x38);
	io->out.reserved2      = IVAL(req->in.body, 0x3C);
	smb2_pull_handle(req->in.body+0x40, &io->out.file.handle);
	status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &blob);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	status = smb2_create_blob_parse(mem_ctx, blob, &io->out.blobs);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	/* pull out the parsed blobs */
	for (i=0;i<io->out.blobs.num_blobs;i++) {
		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
			/* TODO: this also contains a status field in
			   first 4 bytes */
			if (io->out.blobs.blobs[i].data.length != 8) {
				smb2_request_destroy(req);
				return NT_STATUS_INVALID_NETWORK_RESPONSE;
			}
			io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4);
		}
		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
			if (io->out.blobs.blobs[i].data.length != 32) {
				smb2_request_destroy(req);
				return NT_STATUS_INVALID_NETWORK_RESPONSE;
			}
			memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32);
		}
		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) {
			uint8_t *data;
			if (io->out.blobs.blobs[i].data.length != 32) {
				smb2_request_destroy(req);
				return NT_STATUS_INVALID_NETWORK_RESPONSE;
			}

			data = io->out.blobs.blobs[i].data.data;
			memcpy(&io->out.lease_response.lease_key, data, 16);
			io->out.lease_response.lease_state = IVAL(data, 16);
			io->out.lease_response.lease_flags = IVAL(data, 20);
			io->out.lease_response.lease_duration = BVAL(data, 24);
		}
	}

	data_blob_free(&blob);

	return smb2_request_destroy(req);
}
Ejemplo n.º 5
0
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));
}