summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ntvfs/ntvfs_generic.c56
-rw-r--r--source4/ntvfs/posix/pvfs_fileinfo.c11
-rw-r--r--source4/ntvfs/posix/pvfs_open.c7
3 files changed, 53 insertions, 21 deletions
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index ceb7900935..452273cbdb 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;
diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c
index 4fa2c1601b..2e2acb2c82 100644
--- a/source4/ntvfs/posix/pvfs_fileinfo.c
+++ b/source4/ntvfs/posix/pvfs_fileinfo.c
@@ -57,12 +57,6 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st)
if (S_ISDIR(st->st_mode))
result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
-#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE)
- if (st->st_size > st->st_blocks * (off_t)st->st_blksize) {
- result |= FILE_ATTRIBUTE_SPARSE;
- }
-#endif
-
if (!(result &
(FILE_ATTRIBUTE_READONLY|
FILE_ATTRIBUTE_ARCHIVE|
@@ -82,6 +76,11 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st)
*/
NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name)
{
+ /* make directories appear as size 0 */
+ if (S_ISDIR(name->st.st_mode)) {
+ name->st.st_size = 0;
+ }
+
/* for now just use the simple samba mapping */
unix_to_nt_time(&name->dos.create_time, name->st.st_ctime);
unix_to_nt_time(&name->dos.access_time, name->st.st_atime);
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 4844521c45..5e162ad147 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -180,8 +180,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
io->generic.out.write_time = name->dos.write_time;
io->generic.out.change_time = name->dos.change_time;
io->generic.out.attrib = name->dos.attrib;
- io->generic.out.alloc_size = 0;
- io->generic.out.size = 0;
+ io->generic.out.alloc_size = name->dos.alloc_size;
+ io->generic.out.size = name->st.st_size;
io->generic.out.file_type = FILE_TYPE_DISK;
io->generic.out.ipc_state = 0;
io->generic.out.is_directory = 1;
@@ -457,9 +457,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_SUPERSEDE:
- if (!name->exists) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
flags = O_TRUNC;
break;