Commit 43205ca7 authored by Christian Brauner's avatar Christian Brauner Committed by Steve French

ksmbd: fix translation in ksmbd_acls_fattr()

When creating new filesystem objects ksmbd translates between k*ids and
s*ids. For this it often uses struct smb_fattr and stashes the k*ids in
cf_uid and cf_gid. Let cf_uid and cf_gid always contain the final
information taking any potential idmapped mounts into account. When
finally translation cf_*id into s*ids translate them into the user
namespace of ksmbd since that is the relevant user namespace here.

Cc: Steve French <stfrench@microsoft.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Namjae Jeon <namjae.jeon@samsung.com>
Cc: Hyunchul Lee <hyc.lee@gmail.com>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: linux-cifs@vger.kernel.org
Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 3cdc20e7
...@@ -2381,10 +2381,12 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work, ...@@ -2381,10 +2381,12 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work,
le32_to_cpu(sd_buf->ccontext.DataLength), true); le32_to_cpu(sd_buf->ccontext.DataLength), true);
} }
static void ksmbd_acls_fattr(struct smb_fattr *fattr, struct inode *inode) static void ksmbd_acls_fattr(struct smb_fattr *fattr,
struct user_namespace *mnt_userns,
struct inode *inode)
{ {
fattr->cf_uid = inode->i_uid; fattr->cf_uid = i_uid_into_mnt(mnt_userns, inode);
fattr->cf_gid = inode->i_gid; fattr->cf_gid = i_gid_into_mnt(mnt_userns, inode);
fattr->cf_mode = inode->i_mode; fattr->cf_mode = inode->i_mode;
fattr->cf_acls = NULL; fattr->cf_acls = NULL;
fattr->cf_dacls = NULL; fattr->cf_dacls = NULL;
...@@ -2893,7 +2895,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2893,7 +2895,7 @@ int smb2_open(struct ksmbd_work *work)
struct smb_ntsd *pntsd; struct smb_ntsd *pntsd;
int pntsd_size, ace_num = 0; int pntsd_size, ace_num = 0;
ksmbd_acls_fattr(&fattr, inode); ksmbd_acls_fattr(&fattr, user_ns, inode);
if (fattr.cf_acls) if (fattr.cf_acls)
ace_num = fattr.cf_acls->a_count; ace_num = fattr.cf_acls->a_count;
if (fattr.cf_dacls) if (fattr.cf_dacls)
...@@ -5006,7 +5008,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work, ...@@ -5006,7 +5008,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
user_ns = file_mnt_user_ns(fp->filp); user_ns = file_mnt_user_ns(fp->filp);
inode = file_inode(fp->filp); inode = file_inode(fp->filp);
ksmbd_acls_fattr(&fattr, inode); ksmbd_acls_fattr(&fattr, user_ns, inode);
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR)) KSMBD_SHARE_FLAG_ACL_XATTR))
......
...@@ -723,7 +723,7 @@ static void set_mode_dacl(struct user_namespace *user_ns, ...@@ -723,7 +723,7 @@ static void set_mode_dacl(struct user_namespace *user_ns,
} }
/* owner RID */ /* owner RID */
uid = from_kuid(user_ns, fattr->cf_uid); uid = from_kuid(&init_user_ns, fattr->cf_uid);
if (uid) if (uid)
sid = &server_conf.domain_sid; sid = &server_conf.domain_sid;
else else
...@@ -739,7 +739,7 @@ static void set_mode_dacl(struct user_namespace *user_ns, ...@@ -739,7 +739,7 @@ static void set_mode_dacl(struct user_namespace *user_ns,
ace_size = fill_ace_for_sid(pace, &sid_unix_groups, ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
ACCESS_ALLOWED, 0, fattr->cf_mode, 0070); ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
pace->sid.sub_auth[pace->sid.num_subauth++] = pace->sid.sub_auth[pace->sid.num_subauth++] =
cpu_to_le32(from_kgid(user_ns, fattr->cf_gid)); cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
pace->size = cpu_to_le16(ace_size + 4); pace->size = cpu_to_le16(ace_size + 4);
size += le16_to_cpu(pace->size); size += le16_to_cpu(pace->size);
pace = (struct smb_ace *)((char *)pndace + size); pace = (struct smb_ace *)((char *)pndace + size);
...@@ -880,7 +880,7 @@ int build_sec_desc(struct user_namespace *user_ns, ...@@ -880,7 +880,7 @@ int build_sec_desc(struct user_namespace *user_ns,
if (!nowner_sid_ptr) if (!nowner_sid_ptr)
return -ENOMEM; return -ENOMEM;
uid = from_kuid(user_ns, fattr->cf_uid); uid = from_kuid(&init_user_ns, fattr->cf_uid);
if (!uid) if (!uid)
sid_type = SIDUNIX_USER; sid_type = SIDUNIX_USER;
id_to_sid(uid, sid_type, nowner_sid_ptr); id_to_sid(uid, sid_type, nowner_sid_ptr);
...@@ -891,7 +891,7 @@ int build_sec_desc(struct user_namespace *user_ns, ...@@ -891,7 +891,7 @@ int build_sec_desc(struct user_namespace *user_ns,
return -ENOMEM; return -ENOMEM;
} }
gid = from_kgid(user_ns, fattr->cf_gid); gid = from_kgid(&init_user_ns, fattr->cf_gid);
id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr); id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
offset = sizeof(struct smb_ntsd); offset = sizeof(struct smb_ntsd);
......
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