summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-11-06 07:58:45 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:33 -0500
commit439c1524fba3b58abe9e353f9ff2bd7f103f3d12 (patch)
tree0b824442f7c57ee4a2653fbcbb280987cb582e01 /source4/ntvfs
parent4c06ac06a13eaff5b314ad97cce824d615c06f9a (diff)
downloadsamba-439c1524fba3b58abe9e353f9ff2bd7f103f3d12.tar.gz
samba-439c1524fba3b58abe9e353f9ff2bd7f103f3d12.tar.bz2
samba-439c1524fba3b58abe9e353f9ff2bd7f103f3d12.zip
r3573: added trans2open support to smbd and pvfs, and fine-tuned the open->generic ntvfs mapping code.
(This used to be commit ed844192d7f7ed487290f719df65f256a5b0b9bc)
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/ntvfs_generic.c49
-rw-r--r--source4/ntvfs/posix/pvfs_open.c37
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c8
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);
}
}