Commit a6603398 authored by Steve French's avatar Steve French

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: default avatarSteve French <stfrench@microsoft.com>
Reviewed-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
parent 975221ec
...@@ -1000,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, ...@@ -1000,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
/* Convert permission bits from mode to equivalent CIFS ACL */ /* Convert permission bits from mode to equivalent CIFS ACL */
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, __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; int rc = 0;
__u32 dacloffset; __u32 dacloffset;
...@@ -1041,6 +1041,16 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ...@@ -1041,6 +1041,16 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
if (!nowner_sid_ptr) if (!nowner_sid_ptr)
return -ENOMEM; return -ENOMEM;
id = from_kuid(&init_user_ns, uid); id = from_kuid(&init_user_ns, uid);
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); rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
if (rc) { if (rc) {
cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n", cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
...@@ -1048,6 +1058,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ...@@ -1048,6 +1058,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(nowner_sid_ptr); kfree(nowner_sid_ptr);
return rc; return rc;
} }
}
cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
kfree(nowner_sid_ptr); kfree(nowner_sid_ptr);
*aclflag = CIFS_ACL_OWNER; *aclflag = CIFS_ACL_OWNER;
...@@ -1061,6 +1072,16 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ...@@ -1061,6 +1072,16 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
if (!ngroup_sid_ptr) if (!ngroup_sid_ptr)
return -ENOMEM; return -ENOMEM;
id = from_kgid(&init_user_ns, gid); id = from_kgid(&init_user_ns, gid);
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); rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
if (rc) { if (rc) {
cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n", cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
...@@ -1068,6 +1089,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ...@@ -1068,6 +1089,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(ngroup_sid_ptr); kfree(ngroup_sid_ptr);
return rc; return rc;
} }
}
cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
kfree(ngroup_sid_ptr); kfree(ngroup_sid_ptr);
*aclflag = CIFS_ACL_GROUP; *aclflag = CIFS_ACL_GROUP;
...@@ -1269,7 +1291,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, ...@@ -1269,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 cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
struct smb_version_operations *ops; struct smb_version_operations *ops;
bool mode_from_sid; bool mode_from_sid, id_from_sid;
if (IS_ERR(tlink)) if (IS_ERR(tlink))
return PTR_ERR(tlink); return PTR_ERR(tlink);
...@@ -1312,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, ...@@ -1312,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
else else
mode_from_sid = false; 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, 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); cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment