Skip to content

Commit a660339

Browse files
committed
cifs: fix chown and chgrp when idsfromsid mount option enabled
idsfromsid was ignored in chown and chgrp causing it to fail when upcalls were not configured for lookup. idsfromsid allows mapping users when setting user or group ownership using "special SID" (reserved for this). Add support for chmod and chgrp when idsfromsid mount option is enabled. Signed-off-by: Steve French <[email protected]> Reviewed-by: Pavel Shilovsky <[email protected]>
1 parent 975221e commit a660339

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

fs/cifs/cifsacl.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
10001000
/* Convert permission bits from mode to equivalent CIFS ACL */
10011001
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
10021002
__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
1003-
bool mode_from_sid, int *aclflag)
1003+
bool mode_from_sid, bool id_from_sid, int *aclflag)
10041004
{
10051005
int rc = 0;
10061006
__u32 dacloffset;
@@ -1041,12 +1041,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
10411041
if (!nowner_sid_ptr)
10421042
return -ENOMEM;
10431043
id = from_kuid(&init_user_ns, uid);
1044-
rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1045-
if (rc) {
1046-
cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1047-
__func__, rc, id);
1048-
kfree(nowner_sid_ptr);
1049-
return rc;
1044+
if (id_from_sid) {
1045+
struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1046+
/* Populate the user ownership fields S-1-5-88-1 */
1047+
osid->Revision = 1;
1048+
osid->NumAuth = 3;
1049+
osid->Authority[5] = 5;
1050+
osid->SubAuthorities[0] = cpu_to_le32(88);
1051+
osid->SubAuthorities[1] = cpu_to_le32(1);
1052+
osid->SubAuthorities[2] = cpu_to_le32(id);
1053+
} else { /* lookup sid with upcall */
1054+
rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1055+
if (rc) {
1056+
cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1057+
__func__, rc, id);
1058+
kfree(nowner_sid_ptr);
1059+
return rc;
1060+
}
10501061
}
10511062
cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
10521063
kfree(nowner_sid_ptr);
@@ -1061,12 +1072,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
10611072
if (!ngroup_sid_ptr)
10621073
return -ENOMEM;
10631074
id = from_kgid(&init_user_ns, gid);
1064-
rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1065-
if (rc) {
1066-
cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1067-
__func__, rc, id);
1068-
kfree(ngroup_sid_ptr);
1069-
return rc;
1075+
if (id_from_sid) {
1076+
struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1077+
/* Populate the group ownership fields S-1-5-88-2 */
1078+
gsid->Revision = 1;
1079+
gsid->NumAuth = 3;
1080+
gsid->Authority[5] = 5;
1081+
gsid->SubAuthorities[0] = cpu_to_le32(88);
1082+
gsid->SubAuthorities[1] = cpu_to_le32(2);
1083+
gsid->SubAuthorities[2] = cpu_to_le32(id);
1084+
} else { /* lookup sid with upcall */
1085+
rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1086+
if (rc) {
1087+
cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1088+
__func__, rc, id);
1089+
kfree(ngroup_sid_ptr);
1090+
return rc;
1091+
}
10701092
}
10711093
cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
10721094
kfree(ngroup_sid_ptr);
@@ -1269,7 +1291,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
12691291
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
12701292
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
12711293
struct smb_version_operations *ops;
1272-
bool mode_from_sid;
1294+
bool mode_from_sid, id_from_sid;
12731295

12741296
if (IS_ERR(tlink))
12751297
return PTR_ERR(tlink);
@@ -1312,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
13121334
else
13131335
mode_from_sid = false;
13141336

1337+
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1338+
id_from_sid = true;
1339+
else
1340+
id_from_sid = false;
1341+
13151342
rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1316-
mode_from_sid, &aclflag);
1343+
mode_from_sid, id_from_sid, &aclflag);
13171344

13181345
cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
13191346

0 commit comments

Comments
 (0)