summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r--source4/ntvfs/posix/config.mk29
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c2
-rw-r--r--source4/ntvfs/posix/pvfs_fileinfo.c7
-rw-r--r--source4/ntvfs/posix/pvfs_open.c44
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c9
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c8
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_streams.c7
-rw-r--r--source4/ntvfs/posix/pvfs_xattr.c32
-rw-r--r--source4/ntvfs/posix/vfs_posix.c2
-rw-r--r--source4/ntvfs/posix/vfs_posix.h3
11 files changed, 89 insertions, 56 deletions
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index 88048c2af7..0ee3e3be16 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -3,38 +3,44 @@
[MODULE::pvfs_acl_xattr]
INIT_FUNCTION = pvfs_acl_xattr_init
SUBSYSTEM = ntvfs
-OBJ_FILES = \
- pvfs_acl_xattr.o
PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix
# End MODULE pvfs_acl_xattr
################################################
+pvfs_acl_xattr_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_xattr.o
+
################################################
# Start MODULE pvfs_acl_nfs4
[MODULE::pvfs_acl_nfs4]
INIT_FUNCTION = pvfs_acl_nfs4_init
SUBSYSTEM = ntvfs
-OBJ_FILES = \
- pvfs_acl_nfs4.o
PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix
# End MODULE pvfs_acl_nfs4
################################################
+pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o
+
################################################
[MODULE::pvfs_aio]
SUBSYSTEM = ntvfs
-OBJ_FILES = pvfs_aio.o
PRIVATE_DEPENDENCIES = LIBAIO_LINUX
################################################
+pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o
+
################################################
# Start MODULE ntvfs_posix
[MODULE::ntvfs_posix]
SUBSYSTEM = ntvfs
OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = ntvfs_posix_init
-PRIVATE_PROTO_HEADER = vfs_posix_proto.h
-OBJ_FILES = \
+#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 $(ntvfssrcdir)/posix/, \
vfs_posix.o \
pvfs_util.o \
pvfs_search.o \
@@ -62,8 +68,7 @@ OBJ_FILES = \
pvfs_acl.o \
pvfs_notify.o \
xattr_system.o \
- xattr_tdb.o
-#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4
-PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio
-# End MODULE ntvfs_posix
-################################################
+ 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;
};