diff options
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r-- | source4/ntvfs/posix/config.mk | 11 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_acl.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_fileinfo.c | 7 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 44 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_qfileinfo.c | 9 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_resolve.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_streams.c | 7 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_xattr.c | 32 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 3 |
11 files changed, 78 insertions, 49 deletions
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 865a0ffd4a..0ee3e3be16 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -7,7 +7,7 @@ PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ -pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o +pvfs_acl_xattr_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_xattr.o ################################################ # Start MODULE pvfs_acl_nfs4 @@ -18,7 +18,7 @@ PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ -pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o +pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o ################################################ [MODULE::pvfs_aio] @@ -26,7 +26,7 @@ SUBSYSTEM = ntvfs PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ -pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o +pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o ################################################ # Start MODULE ntvfs_posix @@ -34,14 +34,13 @@ pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init -PRIVATE_PROTO_HEADER = vfs_posix_proto.h #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio \ LIBWBCLIENT # End MODULE ntvfs_posix ################################################ -ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ +ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ @@ -71,3 +70,5 @@ ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ xattr_system.o \ xattr_tdb.o) +$(eval $(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c))) + diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 2393a2e7a3..f1e469f790 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -135,7 +135,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } sd = *psd; - ids = talloc_array(sd, struct id_mapping, 2); + ids = talloc_zero_array(sd, struct id_mapping, 2); NT_STATUS_HAVE_NO_MEMORY(ids); ids[0].unixid = talloc(ids, struct unixid); diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 4c383ed45d..04f6ad78d0 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -58,6 +58,8 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, if (S_ISDIR(name->st.st_mode)) { name->st.st_size = 0; name->st.st_nlink = 1; + } else if (name->stream_id == 0) { + name->stream_name = NULL; } /* for now just use the simple samba mapping */ @@ -75,6 +77,11 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.alloc_size = pvfs_round_alloc_size(pvfs, name->st.st_size); name->dos.nlink = name->st.st_nlink; name->dos.ea_size = 4; + if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2) { + /* SMB2 represents a null EA with zero bytes */ + name->dos.ea_size = 0; + } + name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; name->dos.flags = 0; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 6e77cb7c75..926c99d37e 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -182,12 +182,19 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, bool del_on_close; uint32_t create_options; uint32_t share_access; + bool forced; create_options = io->generic.in.create_options; share_access = io->generic.in.share_access; + forced = (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)?true:false; + if (name->stream_name) { - return NT_STATUS_NOT_A_DIRECTORY; + if (forced) { + return NT_STATUS_NOT_A_DIRECTORY; + } else { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } } /* if the client says it must be a directory, and it isn't, @@ -262,7 +269,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->position = 0; f->handle->mode = 0; f->handle->oplock = NULL; - f->handle->sticky_write_time = false; f->handle->open_completed = false; if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && @@ -416,16 +422,6 @@ cleanup_delete: */ static int pvfs_handle_destructor(struct pvfs_file_handle *h) { - /* the write time is no longer sticky */ - if (h->sticky_write_time) { - NTSTATUS status; - status = pvfs_dosattrib_load(h->pvfs, h->name, h->fd); - if (NT_STATUS_IS_OK(status)) { - h->name->dos.flags &= ~XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - pvfs_dosattrib_save(h->pvfs, h->name, h->fd); - } - } - if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name) { NTSTATUS status; @@ -559,6 +555,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t oplock_level = OPLOCK_NONE, oplock_granted; bool allow_level_II_oplock = false; + if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } + if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; @@ -707,7 +707,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = true; - f->handle->sticky_write_time = false; f->handle->open_completed = false; status = odb_open_file(lck, f->handle, name->full_name, @@ -1129,6 +1128,20 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + /* if the client specified that it must not be a directory then + check that it isn't */ + if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (io->generic.in.create_options & NTCREATEX_OPTIONS_NON_DIRECTORY_FILE)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + /* if the client specified that it must be a directory then + check that it is */ + if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + /* directory opens are handled separately */ if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) || (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { @@ -1257,7 +1270,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = false; - f->handle->sticky_write_time = false; f->handle->open_completed = false; /* form the lock context used for byte range locking and @@ -1479,10 +1491,6 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, unix_times.actime = 0; unix_times.modtime = io->close.in.write_time; utime(f->handle->name->full_name, &unix_times); - } else if (f->handle->sticky_write_time) { - unix_times.actime = 0; - unix_times.modtime = nt_time_to_unix(f->handle->name->dos.write_time); - utime(f->handle->name->full_name, &unix_times); } talloc_free(f); diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 6bc21e5e3e..6e3092b744 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -301,7 +301,14 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, info->all_info2.out.access_mask = 0; /* only set by qfileinfo */ info->all_info2.out.position = 0; /* only set by qfileinfo */ info->all_info2.out.mode = 0; /* only set by qfileinfo */ - info->all_info2.out.fname.s = name->original_name; + /* windows wants the full path on disk for this + result, but I really don't want to expose that on + the wire, so I'll give the path with a share + prefix, which is a good approximation */ + info->all_info2.out.fname.s = talloc_asprintf(req, "\\%s\\%s", + pvfs->share_name, + name->original_name); + NT_STATUS_HAVE_NO_MEMORY(info->all_info2.out.fname.s); return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 325bc74f8f..2e97925c49 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -202,7 +202,13 @@ static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s) } *p = 0; if (strcmp(name->stream_name, "") == 0) { - name->stream_name = NULL; + /* + * we don't set stream_name to NULL, here + * as this would be wrong for directories + * + * pvfs_fill_dos_info() will set it to NULL + * if it's not a directory. + */ name->stream_id = 0; } else { name->stream_id = pvfs_name_hash(name->stream_name, diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index ad47fe90c9..0beca75ead 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -342,8 +342,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } if (!null_nttime(info->basic_info.in.write_time)) { newstats.dos.write_time = info->basic_info.in.write_time; - newstats.dos.flags |= XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - h->sticky_write_time = true; } if (!null_nttime(info->basic_info.in.change_time)) { newstats.dos.change_time = info->basic_info.in.change_time; diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 7e6173ef2f..3cd9952fd5 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -36,6 +36,13 @@ NTSTATUS pvfs_stream_information(struct pvfs_state *pvfs, int i; NTSTATUS status; + /* directories don't have streams */ + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + info->num_streams = 0; + info->streams = NULL; + return NT_STATUS_OK; + } + streams = talloc(mem_ctx, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 3043b80538..3cbbcbe92f 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -162,7 +162,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name struct xattr_DosAttrib attrib; TALLOC_CTX *mem_ctx = talloc_new(name); struct xattr_DosInfo1 *info1; - struct xattr_DosInfo2 *info2; + struct xattr_DosInfo2Old *info2; if (name->stream_name != NULL) { name->stream_exists = false; @@ -210,7 +210,11 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name break; case 2: - info2 = &attrib.info.info2; + /* + * Note: This is only used to parse existing values from disk + * We use xattr_DosInfo1 again for storing new values + */ + info2 = &attrib.info.oldinfo2; name->dos.attrib = pvfs_attrib_normalise(info2->attrib, name->st.st_mode); name->dos.ea_size = info2->ea_size; @@ -225,9 +229,6 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name name->dos.change_time = info2->change_time; } name->dos.flags = info2->flags; - if (name->dos.flags & XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME) { - name->dos.write_time = info2->write_time; - } break; default: @@ -250,26 +251,23 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { struct xattr_DosAttrib attrib; - struct xattr_DosInfo2 *info2; + struct xattr_DosInfo1 *info1; if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } - attrib.version = 2; - info2 = &attrib.info.info2; + attrib.version = 1; + info1 = &attrib.info.info1; name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib, name->st.st_mode); - info2->attrib = name->dos.attrib; - info2->ea_size = name->dos.ea_size; - info2->size = name->st.st_size; - info2->alloc_size = name->dos.alloc_size; - info2->create_time = name->dos.create_time; - info2->change_time = name->dos.change_time; - info2->write_time = name->dos.write_time; - info2->flags = name->dos.flags; - info2->name = ""; + info1->attrib = name->dos.attrib; + info1->ea_size = name->dos.ea_size; + info1->size = name->st.st_size; + info1->alloc_size = name->dos.alloc_size; + info1->create_time = name->dos.create_time; + info1->change_time = name->dos.change_time; return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ebc2d88e70..14b5210fd0 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -219,7 +219,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, pvfs->ntvfs->ctx->lp_ctx, - event_context_find(pvfs), + pvfs->ntvfs->ctx->event_ctx, pvfs->ntvfs->ctx->config); pvfs->wbc_ctx = wbc_init(pvfs, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 441424142f..c194698b64 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -169,9 +169,6 @@ struct pvfs_file_handle { /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; - /* have we set a sticky write time that we should remove on close */ - bool sticky_write_time; - /* the open went through to completion */ bool open_completed; }; |