summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c29
-rw-r--r--source4/ntvfs/posix/pvfs_ioctl.c3
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c14
-rw-r--r--source4/ntvfs/posix/pvfs_open.c37
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c8
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c7
6 files changed, 76 insertions, 22 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
index 507c22f050..9a9200e4f0 100644
--- a/source4/ntvfs/posix/pvfs_acl.c
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -464,7 +464,11 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
return NT_STATUS_ACCESS_DENIED;
}
- *access_mask |= SEC_FILE_READ_ATTRIBUTE;
+ if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
+ /* on SMB, this bit is always granted, even if not
+ asked for */
+ *access_mask |= SEC_FILE_READ_ATTRIBUTE;
+ }
return NT_STATUS_OK;
}
@@ -496,7 +500,9 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
/* expand the generic access bits to file specific bits */
*access_mask = pvfs_translate_mask(*access_mask);
- *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
+ if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
+ *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
+ }
status = pvfs_acl_load(pvfs, name, -1, acl);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@@ -518,8 +524,11 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
/* check the acl against the required access mask */
status = sec_access_check(sd, token, *access_mask, access_mask);
- /* this bit is always granted, even if not asked for */
- *access_mask |= SEC_FILE_READ_ATTRIBUTE;
+ if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
+ /* on SMB, this bit is always granted, even if not
+ asked for */
+ *access_mask |= SEC_FILE_READ_ATTRIBUTE;
+ }
talloc_free(acl);
@@ -800,3 +809,15 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
return status;
}
+
+/*
+ return the maximum allowed access mask
+*/
+NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
+ struct ntvfs_request *req,
+ struct pvfs_filename *name,
+ uint32_t *maximal_access)
+{
+ *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
+ return pvfs_access_check(pvfs, req, name, maximal_access);
+}
diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c
index d0360e67ed..92d3eae061 100644
--- a/source4/ntvfs/posix/pvfs_ioctl.c
+++ b/source4/ntvfs/posix/pvfs_ioctl.c
@@ -73,7 +73,8 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs,
case RAW_IOCTL_SMB2:
case RAW_IOCTL_SMB2_NO_HANDLE:
- return NT_STATUS_FS_DRIVER_REQUIRED;
+ /* see WSPP SMB2 test 46 */
+ return NT_STATUS_INVALID_DEVICE_REQUEST;
}
return NT_STATUS_INVALID_LEVEL;
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index baa92880f1..822b28246a 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -68,13 +68,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs,
int i,
NTSTATUS status)
{
- /* in SMB2 mode we also try to unlock failing lock */
- if (req->ctx->protocol != PROTOCOL_SMB2) {
- i--;
- }
-
/* undo the locks we just did */
- for (;i>=0;i--) {
+ for (i--;i>=0;i--) {
brl_unlock(pvfs->brl_context,
f->brl_handle,
locks[i].pid,
@@ -390,12 +385,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
DLIST_ADD(f->pending_list, pending);
return NT_STATUS_OK;
}
- /* in SMB2 mode we also try to unlock failing lock */
- if (req->ctx->protocol != PROTOCOL_SMB2) {
- i--;
- }
+
/* undo the locks we just did */
- for (;i>=0;i--) {
+ for (i--;i>=0;i--) {
brl_unlock(pvfs->brl_context,
f->brl_handle,
locks[i].pid,
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 0f08136a79..dada9f503f 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -252,8 +252,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
} else {
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
}
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ if (io->generic.in.query_maximal_access) {
+ status = pvfs_access_maximal_allowed(pvfs, req, name,
+ &io->generic.out.maximal_access);
+ NT_STATUS_NOT_OK_RETURN(status);
}
f->ntvfs = h;
@@ -578,6 +582,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
NT_STATUS_NOT_OK_RETURN(status);
+ if (io->generic.in.query_maximal_access) {
+ status = pvfs_access_maximal_allowed(pvfs, req, name,
+ &io->generic.out.maximal_access);
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
+
/* check that the parent isn't opened with delete on close set */
status = pvfs_resolve_parent(pvfs, req, name, &parent);
if (NT_STATUS_IS_OK(status)) {
@@ -1122,6 +1132,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
uint32_t create_options;
uint32_t share_access;
uint32_t access_mask;
+ uint32_t create_action = NTCREATEX_ACTION_EXISTED;
bool del_on_close;
bool stream_existed, stream_truncate=false;
uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
@@ -1134,6 +1145,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return ntvfs_map_open(ntvfs, req, io);
}
+ ZERO_STRUCT(io->generic.out);
+
create_options = io->generic.in.create_options;
share_access = io->generic.in.share_access;
access_mask = io->generic.in.access_mask;
@@ -1169,6 +1182,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
+ /* we ignore some file_attr bits */
+ io->ntcreatex.in.file_attr &= ~(FILE_ATTRIBUTE_NONINDEXED |
+ FILE_ATTRIBUTE_COMPRESSED |
+ FILE_ATTRIBUTE_REPARSE_POINT |
+ FILE_ATTRIBUTE_SPARSE |
+ FILE_ATTRIBUTE_NORMAL);
+
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
PVFS_RESOLVE_STREAMS, &name);
@@ -1210,6 +1230,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
} else {
stream_truncate = true;
}
+ create_action = NTCREATEX_ACTION_TRUNCATED;
break;
case NTCREATEX_DISP_OPEN:
@@ -1228,6 +1249,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
} else {
stream_truncate = true;
}
+ create_action = NTCREATEX_ACTION_TRUNCATED;
break;
case NTCREATEX_DISP_CREATE:
@@ -1272,8 +1294,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
/* check the security descriptor */
status = pvfs_access_check(pvfs, req, name, &access_mask);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ if (io->generic.in.query_maximal_access) {
+ status = pvfs_access_maximal_allowed(pvfs, req, name,
+ &io->generic.out.maximal_access);
+ NT_STATUS_NOT_OK_RETURN(status);
}
status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
@@ -1487,7 +1513,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
io->generic.out.oplock_level = oplock_granted;
io->generic.out.file.ntvfs = h;
io->generic.out.create_action = stream_existed?
- NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED;
+ create_action:NTCREATEX_ACTION_CREATED;
+
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
io->generic.out.write_time = name->dos.write_time;
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index c663466985..3196cf2f8d 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -41,6 +41,10 @@ static uint32_t pvfs_fileinfo_access(union smb_fileinfo *info)
needed = 0;
break;
+ case RAW_FILEINFO_ACCESS_INFORMATION:
+ needed = 0;
+ break;
+
case RAW_FILEINFO_SEC_DESC:
needed = 0;
if (info->query_secdesc.in.secinfo_flags & (SECINFO_OWNER|SECINFO_GROUP)) {
@@ -216,6 +220,10 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs,
case RAW_FILEINFO_NAME_INFO:
case RAW_FILEINFO_NAME_INFORMATION:
+ if (req->ctx->protocol == PROTOCOL_SMB2) {
+ /* strange that SMB2 doesn't have this */
+ return NT_STATUS_NOT_SUPPORTED;
+ }
info->name_info.out.fname.s = name->original_name;
return NT_STATUS_OK;
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index 0beca75ead..1dd2c075d9 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -457,7 +457,12 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
/* possibly change the attribute */
if (newstats.dos.attrib != h->name->dos.attrib) {
- mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
+ mode_t mode;
+ if ((newstats.dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
+ !(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
if (fchmod(h->fd, mode) == -1) {
return pvfs_map_errno(pvfs, errno);