diff options
Diffstat (limited to 'source4/ntvfs/ntvfs_generic.c')
-rw-r--r-- | source4/ntvfs/ntvfs_generic.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index ceb7900935d..452273cbdb2 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -90,14 +90,20 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io->openx.out.access = OPENX_MODE_ACCESS_READ; break; case OPENX_MODE_ACCESS_WRITE: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_WRITE; break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: + case OPENX_MODE_ACCESS_EXEC: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; } switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { @@ -129,12 +135,11 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, case OPENX_MODE_DENY_FCB: io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; } switch (io->openx.in.open_func) { - case (OPENX_OPEN_FUNC_FAIL): - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; case (OPENX_OPEN_FUNC_OPEN): io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; break; @@ -150,8 +155,17 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; break; + default: + /* this one is very strange */ + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_EXEC) { + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + } + return NT_STATUS_INVALID_LOCK_SEQUENCE; } - io2->generic.in.alloc_size = io->openx.in.size; + + io2->generic.in.alloc_size = 0; io2->generic.in.file_attr = io->openx.in.file_attrs; io2->generic.in.fname = io->openx.in.fname; @@ -159,13 +173,35 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, if (!NT_STATUS_IS_OK(status)) { return status; } + + io->openx.out.fnum = io2->generic.out.fnum; + io->openx.out.attrib = io2->generic.out.attrib; + io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openx.out.size = io2->generic.out.size; + io->openx.out.ftype = 0; + io->openx.out.devstate = 0; + io->openx.out.action = io2->generic.out.create_action; + io->openx.out.unique_fid = 0; + io->openx.out.access_mask = io2->generic.in.access_mask; + io->openx.out.unknown = 0; - ZERO_STRUCT(io->openx.out); - io->openx.out.fnum = io2->generic.out.fnum; - io->openx.out.attrib = io2->generic.out.attrib; - io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); - io->openx.out.size = io2->generic.out.size; - + /* we need to extend the file to the requested size if + it was newly created */ + if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && + io->openx.in.size != 0) { + union smb_setfileinfo *sf; + sf = talloc_p(req, union smb_setfileinfo); + if (sf != NULL) { + sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + sf->generic.file.fnum = io2->generic.out.fnum; + sf->end_of_file_info.in.size = io->openx.in.size; + status = ntvfs->ops->setfileinfo(ntvfs, req, sf); + if (NT_STATUS_IS_OK(status)) { + io->openx.out.size = io->openx.in.size; + } + } + } + return NT_STATUS_OK; |