Beispiel #1
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));
}
Beispiel #2
0
NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
					enum smb_setfileinfo_level level,
					union smb_setfileinfo *st,
					const DATA_BLOB *blob,
					int default_str_flags,
					struct request_bufinfo *bufinfo)
{
	uint32_t len, ofs;
	DATA_BLOB str_blob;

	switch (level) {
	case SMB_SFILEINFO_BASIC_INFORMATION:
		BLOB_CHECK_MIN_SIZE(blob, 40);

		st->basic_info.in.create_time = pull_nttime(blob->data,  0);
		st->basic_info.in.access_time = pull_nttime(blob->data,  8);
		st->basic_info.in.write_time =  pull_nttime(blob->data, 16);
		st->basic_info.in.change_time = pull_nttime(blob->data, 24);
		st->basic_info.in.attrib      = IVAL(blob->data,        32);
		st->basic_info.in.reserved    = IVAL(blob->data,        36);

		return NT_STATUS_OK;

	case SMB_SFILEINFO_DISPOSITION_INFORMATION:
		BLOB_CHECK_MIN_SIZE(blob, 1);

		st->disposition_info.in.delete_on_close = CVAL(blob->data, 0);

		return NT_STATUS_OK;

	case SMB_SFILEINFO_ALLOCATION_INFORMATION:
		BLOB_CHECK_MIN_SIZE(blob, 8);

		st->allocation_info.in.alloc_size = BVAL(blob->data, 0);

		return NT_STATUS_OK;				

	case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
		BLOB_CHECK_MIN_SIZE(blob, 8);

		st->end_of_file_info.in.size = BVAL(blob->data, 0);

		return NT_STATUS_OK;

	case RAW_SFILEINFO_RENAME_INFORMATION:
		if (!bufinfo) {
			return NT_STATUS_INTERNAL_ERROR;
		}
		BLOB_CHECK_MIN_SIZE(blob, 12);
		st->rename_information.in.overwrite = CVAL(blob->data, 0);
		st->rename_information.in.root_fid  = IVAL(blob->data, 4);
		len                                 = IVAL(blob->data, 8);
		ofs                                 = 12;
		str_blob = *blob;
		str_blob.length = MIN(str_blob.length, ofs+len);
		smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
					&st->rename_information.in.new_name,
					STR_UNICODE);
		if (st->rename_information.in.new_name == NULL) {
			return NT_STATUS_FOOBAR;
		}

		return NT_STATUS_OK;


	case RAW_SFILEINFO_LINK_INFORMATION:
		if (!bufinfo) {
			return NT_STATUS_INTERNAL_ERROR;
		}
		BLOB_CHECK_MIN_SIZE(blob, 20);
		st->link_information.in.overwrite = CVAL(blob->data, 0);
		st->link_information.in.root_fid  = IVAL(blob->data, 8);
		len                                 = IVAL(blob->data, 16);
		ofs                                 = 20;
		str_blob = *blob;
		str_blob.length = MIN(str_blob.length, ofs+len);
		smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
					&st->link_information.in.new_name,
					STR_UNICODE);
		if (st->link_information.in.new_name == NULL) {
			return NT_STATUS_FOOBAR;
		}

		return NT_STATUS_OK;

	case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
		/* SMB2 uses a different format for rename information */
		if (!bufinfo) {
			return NT_STATUS_INTERNAL_ERROR;
		}
		BLOB_CHECK_MIN_SIZE(blob, 20);
		st->rename_information.in.overwrite = CVAL(blob->data, 0);
		st->rename_information.in.root_fid  = BVAL(blob->data, 8);
		len                                 = IVAL(blob->data,16);
		ofs                                 = 20;			
		str_blob = *blob;
		str_blob.length = MIN(str_blob.length, ofs+len);
		smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
					&st->rename_information.in.new_name,
					STR_UNICODE);
		if (st->rename_information.in.new_name == NULL) {
			return NT_STATUS_FOOBAR;
		}

		return NT_STATUS_OK;

	case RAW_SFILEINFO_POSITION_INFORMATION:
		BLOB_CHECK_MIN_SIZE(blob, 8);

		st->position_information.in.position = BVAL(blob->data, 0);

		return NT_STATUS_OK;

	case RAW_SFILEINFO_FULL_EA_INFORMATION:
		return ea_pull_list_chained(blob,
					    mem_ctx,
					&st->full_ea_information.in.eas.num_eas,
					&st->full_ea_information.in.eas.eas);

	case RAW_SFILEINFO_MODE_INFORMATION:
		BLOB_CHECK_MIN_SIZE(blob, 4);

		st->mode_information.in.mode = IVAL(blob->data, 0);

		return NT_STATUS_OK;

	default:
		return NT_STATUS_INVALID_LEVEL;
	}
}