summaryrefslogtreecommitdiff
path: root/fs/cifs/cifsacl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-13 13:43:56 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-13 13:43:56 -0700
commitf82e7b57b5fc48199e2f26ffafe2f96f7338ad3d (patch)
tree600f2f00d844ce755d08ff154cc629eb4f842586 /fs/cifs/cifsacl.c
parent4f9b3a377549e2b585f5e1910c247913b49e6c83 (diff)
parenta7a519a4926214ba4161bc30109f4a8d69defb8d (diff)
Merge tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull more cifs updates from Steve French: "12 cifs/smb3 fixes, 2 for stable. - add support for idsfromsid on create and chgrp/chown allowing ability to save owner information more naturally for some workloads - improve query info (getattr) when SMB3.1.1 posix extensions are negotiated by using new query info level" * tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: smb3: Add debug message for new file creation with idsfromsid mount option cifs: fix chown and chgrp when idsfromsid mount option enabled smb3: allow uid and gid owners to be set on create with idsfromsid mount option smb311: Add tracepoints for new compound posix query info smb311: add support for using info level for posix extensions query smb311: Add support for lookup with posix extensions query info smb311: Add support for SMB311 query info (non-compounded) SMB311: Add support for query info using posix extensions (level 100) smb3: add indatalen that can be a non-zero value to calculation of credit charge in smb2 ioctl smb3: fix typo in mount options displayed in /proc/mounts cifs: Add get_security_type_str function to return sec type. smb3: extend fscache mount volume coherency check
Diffstat (limited to 'fs/cifs/cifsacl.c')
-rw-r--r--fs/cifs/cifsacl.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index ae421634aa42..6025d7fc7bbf 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -849,6 +849,28 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
return ace_size;
}
+unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
+{
+ int i;
+ unsigned int ace_size = 28;
+
+ pntace->type = ACCESS_ALLOWED_ACE_TYPE;
+ pntace->flags = 0x0;
+ pntace->access_req = cpu_to_le32(GENERIC_ALL);
+ pntace->sid.num_subauth = 3;
+ pntace->sid.revision = 1;
+ for (i = 0; i < NUM_AUTHS; i++)
+ pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
+
+ pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
+ pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
+ pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
+
+ /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
+ pntace->size = cpu_to_le16(ace_size);
+ return ace_size;
+}
+
static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
{
@@ -978,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
/* Convert permission bits from mode to equivalent CIFS ACL */
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
- bool mode_from_sid, int *aclflag)
+ bool mode_from_sid, bool id_from_sid, int *aclflag)
{
int rc = 0;
__u32 dacloffset;
@@ -1019,12 +1041,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
if (!nowner_sid_ptr)
return -ENOMEM;
id = from_kuid(&init_user_ns, uid);
- rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
- if (rc) {
- cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
- __func__, rc, id);
- kfree(nowner_sid_ptr);
- return rc;
+ if (id_from_sid) {
+ struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
+ /* Populate the user ownership fields S-1-5-88-1 */
+ osid->Revision = 1;
+ osid->NumAuth = 3;
+ osid->Authority[5] = 5;
+ osid->SubAuthorities[0] = cpu_to_le32(88);
+ osid->SubAuthorities[1] = cpu_to_le32(1);
+ osid->SubAuthorities[2] = cpu_to_le32(id);
+ } else { /* lookup sid with upcall */
+ rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
+ if (rc) {
+ cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
+ __func__, rc, id);
+ kfree(nowner_sid_ptr);
+ return rc;
+ }
}
cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
kfree(nowner_sid_ptr);
@@ -1039,12 +1072,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
if (!ngroup_sid_ptr)
return -ENOMEM;
id = from_kgid(&init_user_ns, gid);
- rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
- if (rc) {
- cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
- __func__, rc, id);
- kfree(ngroup_sid_ptr);
- return rc;
+ if (id_from_sid) {
+ struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
+ /* Populate the group ownership fields S-1-5-88-2 */
+ gsid->Revision = 1;
+ gsid->NumAuth = 3;
+ gsid->Authority[5] = 5;
+ gsid->SubAuthorities[0] = cpu_to_le32(88);
+ gsid->SubAuthorities[1] = cpu_to_le32(2);
+ gsid->SubAuthorities[2] = cpu_to_le32(id);
+ } else { /* lookup sid with upcall */
+ rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
+ if (rc) {
+ cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
+ __func__, rc, id);
+ kfree(ngroup_sid_ptr);
+ return rc;
+ }
}
cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
kfree(ngroup_sid_ptr);
@@ -1247,7 +1291,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
struct smb_version_operations *ops;
- bool mode_from_sid;
+ bool mode_from_sid, id_from_sid;
if (IS_ERR(tlink))
return PTR_ERR(tlink);
@@ -1290,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
else
mode_from_sid = false;
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
+ id_from_sid = true;
+ else
+ id_from_sid = false;
+
rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
- mode_from_sid, &aclflag);
+ mode_from_sid, id_from_sid, &aclflag);
cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);