diff options
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_cmn_setfile.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_common_open.c | 6 |
2 files changed, 20 insertions, 2 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_cmn_setfile.c b/usr/src/uts/common/fs/smbsrv/smb_cmn_setfile.c index 1b9ed07060..c5369eae4f 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_cmn_setfile.c +++ b/usr/src/uts/common/fs/smbsrv/smb_cmn_setfile.c @@ -231,8 +231,9 @@ smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *si) uint32_t smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *si) { - smb_node_t *node = si->si_node; - smb_ofile_t *of = sr->fid_ofile; + smb_attr_t *attr = &si->si_attr; + smb_node_t *node = si->si_node; + smb_ofile_t *of = sr->fid_ofile; uint8_t mark_delete; uint32_t status; uint32_t flags = 0; @@ -249,6 +250,17 @@ smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *si) } /* + * MS-FSA 2.1.5.14.3 FileDispositionInformation + * If dosattr READONLY, STATUS_CANNOT_DELETE. + */ + attr->sa_mask = SMB_AT_DOSATTR; + status = smb2_ofile_getattr(sr, of, attr); + if (status != 0) + return (status); + if ((attr->sa_dosattr & FILE_ATTRIBUTE_READONLY) != 0) + return (NT_STATUS_CANNOT_DELETE); + + /* * Break any oplock handle caching. */ status = smb_oplock_break_SETINFO(node, of, diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_open.c b/usr/src/uts/common/fs/smbsrv/smb_common_open.c index 688bac53d8..894affa2a5 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c +++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c @@ -945,6 +945,12 @@ create: goto errout; } + if ((op->dattr & FILE_ATTRIBUTE_READONLY) != 0 && + (op->create_options & FILE_DELETE_ON_CLOSE) != 0) { + status = NT_STATUS_CANNOT_DELETE; + goto errout; + } + if ((op->desired_access & ACCESS_SYSTEM_SECURITY) != 0 && !smb_user_has_security_priv(sr->uid_user, sr->user_cr)) { status = NT_STATUS_ACCESS_DENIED; |