diff options
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r-- | source4/ntvfs/posix/pvfs_acl.c | 29 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_ioctl.c | 3 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_lock.c | 14 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 37 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_qfileinfo.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 7 |
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); |