diff options
Diffstat (limited to 'source4/ntvfs')
-rw-r--r-- | source4/ntvfs/ntvfs_generic.c | 49 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 37 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 8 |
3 files changed, 85 insertions, 9 deletions
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index ed41b3d4d2..370463c41d 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -149,6 +149,13 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, union smb_setfileinfo *sf; uint_t state; + /* this is really strange, but matches w2k3 */ + if (io->generic.level == RAW_OPEN_T2OPEN && + io->t2open.in.open_func != OPENX_OPEN_FUNC_OPEN && + NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + return NT_STATUS_ACCESS_DENIED; + } + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -159,7 +166,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->openold.out.attrib = io2->generic.out.attrib; io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openold.out.size = io2->generic.out.size; - io->openold.out.rmode = DOS_OPEN_RDWR; + io->openold.out.rmode = io->openold.in.flags; break; case RAW_OPEN_OPENX: @@ -181,6 +188,18 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, } break; + case RAW_OPEN_T2OPEN: + io->t2open.out.fnum = io2->openx.out.fnum; + io->t2open.out.attrib = io2->openx.out.attrib; + io->t2open.out.write_time = 0; + io->t2open.out.size = io2->openx.out.size; + io->t2open.out.access = io->t2open.in.open_mode; + io->t2open.out.ftype = io2->openx.out.ftype; + io->t2open.out.devstate = io2->openx.out.devstate; + io->t2open.out.action = io2->openx.out.action; + io->t2open.out.unknown = 0; + break; + case RAW_OPEN_MKNEW: case RAW_OPEN_CREATE: io->mknew.out.fnum = io2->generic.out.fnum; @@ -191,7 +210,6 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->ctemp.out.fnum = io2->generic.out.fnum; io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + strlen(io->ctemp.in.directory) + 1); - write_time = io->ctemp.in.write_time; break; default: @@ -217,7 +235,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, sf = talloc_p(req, union smb_setfileinfo); 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; + sf->end_of_file_info.in.size = set_size; status = ntvfs->ops->setfileinfo(ntvfs, req, sf); if (NT_STATUS_IS_OK(status)) { io->openx.out.size = io->openx.in.size; @@ -262,17 +280,17 @@ 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; + io2->generic.in.access_mask = STANDARD_RIGHTS_READ_ACCESS; io->openx.out.access = OPENX_MODE_ACCESS_READ; break; case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = STANDARD_RIGHTS_WRITE_ACCESS; 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; + io2->generic.in.access_mask = STANDARD_RIGHTS_ALL_ACCESS; io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; default: @@ -402,8 +420,10 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; break; - case 0x70: /* FCB mode */ - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + case OPEN_FLAGS_DENY_MASK: + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; break; default: DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", @@ -415,6 +435,19 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, status = ntvfs->ops->openfile(ntvfs, req, io2); break; + case RAW_OPEN_T2OPEN: + io2->generic.level = RAW_OPEN_OPENX; + io2->openx.in.flags = io->t2open.in.flags; + io2->openx.in.open_mode = io->t2open.in.open_mode; + io2->openx.in.search_attrs = 0; + io2->openx.in.file_attrs = io->t2open.in.file_attrs; + io2->openx.in.write_time = io->t2open.in.write_time; + io2->openx.in.open_func = OPENX_OPEN_FUNC_OPEN; + io2->openx.in.size = io->t2open.in.size; + io2->openx.in.timeout = io->t2open.in.timeout; + io2->openx.in.fname = io->t2open.in.fname; + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; case RAW_OPEN_MKNEW: io2->generic.in.file_attr = io->mknew.in.attrib; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 2430f9becb..6f1fb1c87f 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -539,6 +539,39 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, } /* + special handling for t2open +*/ +static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_filename *name; + NTSTATUS status; + + status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (io->t2open.in.open_func & OPENX_OPEN_FUNC_CREATE) { + if (!name->exists) return NT_STATUS_ACCESS_DENIED; + } + if (io->t2open.in.open_func & OPENX_OPEN_FUNC_TRUNC) { + if (name->exists) return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if ((io->t2open.in.open_func & 0xF) == OPENX_OPEN_FUNC_FAIL) { + if (!name->exists) return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + talloc_free(name); + + return ntvfs_map_open(req, io, ntvfs); +} + +/* open a file */ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, @@ -555,6 +588,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t share_access; uint32_t access_mask; + if (io->generic.level == RAW_OPEN_T2OPEN) { + return pvfs_open_t2open(ntvfs, req, io); + } + /* use the generic mapping code to avoid implementing all the different open calls. This won't allow openx to work perfectly as the mapping code has no way of knowing if two diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index e570743aba..22997be94d 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -188,10 +188,16 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file size */ if (newstats.st.st_size != f->name->st.st_size) { + int ret; if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (ftruncate(f->fd, newstats.st.st_size) == -1) { + if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + ret = ftruncate(f->fd, newstats.st.st_size); + } else { + ret = truncate(f->name->full_name, newstats.st.st_size); + } + if (ret == -1) { return pvfs_map_errno(pvfs, errno); } } |