summaryrefslogtreecommitdiffstats
path: root/fs/ksmbd/smbacl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ksmbd/smbacl.c')
-rw-r--r--fs/ksmbd/smbacl.c99
1 files changed, 57 insertions, 42 deletions
diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c
index e0825d3771a1..4ee714b9b351 100644
--- a/fs/ksmbd/smbacl.c
+++ b/fs/ksmbd/smbacl.c
@@ -253,7 +253,8 @@ void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
ssid->num_subauth++;
}
-static int sid_to_id(struct smb_sid *psid, uint sidtype,
+static int sid_to_id(struct user_namespace *user_ns,
+ struct smb_sid *psid, uint sidtype,
struct smb_fattr *fattr)
{
int rc = -EINVAL;
@@ -274,8 +275,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
if (id > 0) {
- uid = make_kuid(&init_user_ns, id);
- if (uid_valid(uid) && kuid_has_mapping(&init_user_ns, uid)) {
+ uid = make_kuid(user_ns, id);
+ if (uid_valid(uid) && kuid_has_mapping(user_ns, uid)) {
fattr->cf_uid = uid;
rc = 0;
}
@@ -286,8 +287,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
if (id > 0) {
- gid = make_kgid(&init_user_ns, id);
- if (gid_valid(gid) && kgid_has_mapping(&init_user_ns, gid)) {
+ gid = make_kgid(user_ns, id);
+ if (gid_valid(gid) && kgid_has_mapping(user_ns, gid)) {
fattr->cf_gid = gid;
rc = 0;
}
@@ -362,7 +363,8 @@ void free_acl_state(struct posix_acl_state *state)
kfree(state->groups);
}
-static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+static void parse_dacl(struct user_namespace *user_ns,
+ struct smb_acl *pdacl, char *end_of_acl,
struct smb_sid *pownersid, struct smb_sid *pgrpsid,
struct smb_fattr *fattr)
{
@@ -474,7 +476,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
ppace[i]->type);
temp_fattr.cf_uid = INVALID_UID;
- ret = sid_to_id(&ppace[i]->sid, SIDOWNER, &temp_fattr);
+ ret = sid_to_id(user_ns, &ppace[i]->sid, SIDOWNER, &temp_fattr);
if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
pr_err("%s: Error %d mapping Owner SID to uid\n",
__func__, ret);
@@ -553,7 +555,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
free_acl_state(&default_acl_state);
}
-static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
+static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
+ struct smb_ace *pndace,
struct smb_fattr *fattr, u32 *num_aces,
u16 *size, u32 nt_aces_num)
{
@@ -577,14 +580,14 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
uid_t uid;
unsigned int sid_type = SIDOWNER;
- uid = from_kuid(&init_user_ns, pace->e_uid);
+ uid = from_kuid(user_ns, pace->e_uid);
if (!uid)
sid_type = SIDUNIX_USER;
id_to_sid(uid, sid_type, sid);
} else if (pace->e_tag == ACL_GROUP) {
gid_t gid;
- gid = from_kgid(&init_user_ns, pace->e_gid);
+ gid = from_kgid(user_ns, pace->e_gid);
id_to_sid(gid, SIDUNIX_GROUP, sid);
} else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
smb_copy_sid(sid, &sid_everyone);
@@ -643,12 +646,12 @@ posix_default_acl:
if (pace->e_tag == ACL_USER) {
uid_t uid;
- uid = from_kuid(&init_user_ns, pace->e_uid);
+ uid = from_kuid(user_ns, pace->e_uid);
id_to_sid(uid, SIDCREATOR_OWNER, sid);
} else if (pace->e_tag == ACL_GROUP) {
gid_t gid;
- gid = from_kgid(&init_user_ns, pace->e_gid);
+ gid = from_kgid(user_ns, pace->e_gid);
id_to_sid(gid, SIDCREATOR_GROUP, sid);
} else {
kfree(sid);
@@ -666,7 +669,9 @@ posix_default_acl:
}
}
-static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl,
+static void set_ntacl_dacl(struct user_namespace *user_ns,
+ struct smb_acl *pndacl,
+ struct smb_acl *nt_dacl,
const struct smb_sid *pownersid,
const struct smb_sid *pgrpsid,
struct smb_fattr *fattr)
@@ -687,12 +692,14 @@ static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl,
}
}
- set_posix_acl_entries_dacl(pndace, fattr, &num_aces, &size, nt_num_aces);
+ set_posix_acl_entries_dacl(user_ns, pndace, fattr,
+ &num_aces, &size, nt_num_aces);
pndacl->num_aces = cpu_to_le32(num_aces);
pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
}
-static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
+static void set_mode_dacl(struct user_namespace *user_ns,
+ struct smb_acl *pndacl, struct smb_fattr *fattr)
{
struct smb_ace *pace, *pndace;
u32 num_aces = 0;
@@ -703,12 +710,13 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
if (fattr->cf_acls) {
- set_posix_acl_entries_dacl(pndace, fattr, &num_aces, &size, num_aces);
+ set_posix_acl_entries_dacl(user_ns, pndace, fattr,
+ &num_aces, &size, num_aces);
goto out;
}
/* owner RID */
- uid = from_kuid(&init_user_ns, fattr->cf_uid);
+ uid = from_kuid(user_ns, fattr->cf_uid);
if (uid)
sid = &server_conf.domain_sid;
else
@@ -725,7 +733,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
pace->sid.sub_auth[pace->sid.num_subauth++] =
- cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
+ cpu_to_le32(from_kgid(user_ns, fattr->cf_gid));
pace->size = cpu_to_le16(ace_size + 4);
size += le16_to_cpu(pace->size);
pace = (struct smb_ace *)((char *)pndace + size);
@@ -771,8 +779,8 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl)
}
/* Convert CIFS ACL to POSIX form */
-int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
- struct smb_fattr *fattr)
+int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
+ int acl_len, struct smb_fattr *fattr)
{
int rc = 0;
struct smb_sid *owner_sid_ptr, *group_sid_ptr;
@@ -811,7 +819,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
return rc;
}
- rc = sid_to_id(owner_sid_ptr, SIDOWNER, fattr);
+ rc = sid_to_id(user_ns, owner_sid_ptr, SIDOWNER, fattr);
if (rc) {
pr_err("%s: Error %d mapping Owner SID to uid\n",
__func__, rc);
@@ -826,7 +834,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
__func__, rc);
return rc;
}
- rc = sid_to_id(group_sid_ptr, SIDUNIX_GROUP, fattr);
+ rc = sid_to_id(user_ns, group_sid_ptr, SIDUNIX_GROUP, fattr);
if (rc) {
pr_err("%s: Error %d mapping Group SID to gid\n",
__func__, rc);
@@ -841,15 +849,16 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
pntsd->type |= cpu_to_le16(DACL_PROTECTED);
if (dacloffset) {
- parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr,
- fattr);
+ parse_dacl(user_ns, dacl_ptr, end_of_acl,
+ owner_sid_ptr, group_sid_ptr, fattr);
}
return 0;
}
/* Convert permission bits from mode to equivalent CIFS ACL */
-int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
+int build_sec_desc(struct user_namespace *user_ns,
+ struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
int addition_info, __u32 *secdesclen,
struct smb_fattr *fattr)
{
@@ -866,7 +875,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
if (!nowner_sid_ptr)
return -ENOMEM;
- uid = from_kuid(&init_user_ns, fattr->cf_uid);
+ uid = from_kuid(user_ns, fattr->cf_uid);
if (!uid)
sid_type = SIDUNIX_USER;
id_to_sid(uid, sid_type, nowner_sid_ptr);
@@ -877,7 +886,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
return -ENOMEM;
}
- gid = from_kgid(&init_user_ns, fattr->cf_gid);
+ gid = from_kgid(user_ns, fattr->cf_gid);
id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
offset = sizeof(struct smb_ntsd);
@@ -909,7 +918,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
dacl_ptr->num_aces = 0;
if (!ppntsd) {
- set_mode_dacl(dacl_ptr, fattr);
+ set_mode_dacl(user_ns, dacl_ptr, fattr);
} else if (!ppntsd->dacloffset) {
goto out;
} else {
@@ -917,8 +926,8 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
ppdacl_ptr = (struct smb_acl *)((char *)ppntsd +
le32_to_cpu(ppntsd->dacloffset));
- set_ntacl_dacl(dacl_ptr, ppdacl_ptr, nowner_sid_ptr,
- ngroup_sid_ptr, fattr);
+ set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr,
+ nowner_sid_ptr, ngroup_sid_ptr, fattr);
}
pntsd->dacloffset = cpu_to_le32(offset);
offset += le16_to_cpu(dacl_ptr->size);
@@ -956,7 +965,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
char *aces_base;
bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
- acl_len = ksmbd_vfs_get_sd_xattr(conn, parent, &parent_pntsd);
+ acl_len = ksmbd_vfs_get_sd_xattr(conn, mnt_user_ns(path->mnt),
+ parent, &parent_pntsd);
if (acl_len <= 0)
return rc;
dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
@@ -1087,7 +1097,8 @@ pass:
pntsd_size += sizeof(struct smb_acl) + nt_size;
}
- ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, pntsd_size);
+ ksmbd_vfs_set_sd_xattr(conn, mnt_user_ns(path->mnt),
+ path->dentry, pntsd, pntsd_size);
kfree(pntsd);
rc = 0;
}
@@ -1128,7 +1139,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
char *end_of_acl;
ksmbd_debug(SMB, "check permission using windows acl\n");
- acl_size = ksmbd_vfs_get_sd_xattr(conn, path->dentry, &pntsd);
+ acl_size = ksmbd_vfs_get_sd_xattr(conn, mnt_user_ns(path->mnt),
+ path->dentry, &pntsd);
if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) {
kfree(pntsd);
return 0;
@@ -1209,9 +1221,11 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
pa_entry = posix_acls->a_entries;
for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
if (pa_entry->e_tag == ACL_USER)
- id = from_kuid(&init_user_ns, pa_entry->e_uid);
+ id = from_kuid(mnt_user_ns(path->mnt),
+ pa_entry->e_uid);
else if (pa_entry->e_tag == ACL_GROUP)
- id = from_kgid(&init_user_ns, pa_entry->e_gid);
+ id = from_kgid(mnt_user_ns(path->mnt),
+ pa_entry->e_gid);
else
continue;
@@ -1273,7 +1287,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
fattr.cf_gid = INVALID_GID;
fattr.cf_mode = inode->i_mode;
- rc = parse_sec_desc(pntsd, ntsd_len, &fattr);
+ rc = parse_sec_desc(mnt_user_ns(path->mnt), pntsd, ntsd_len, &fattr);
if (rc)
goto out;
@@ -1284,13 +1298,13 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
inode->i_gid = fattr.cf_gid;
mark_inode_dirty(inode);
- ksmbd_vfs_remove_acl_xattrs(path->dentry);
+ ksmbd_vfs_remove_acl_xattrs(mnt_user_ns(path->mnt), path->dentry);
/* Update posix acls */
if (fattr.cf_dacls) {
- rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS,
- fattr.cf_acls);
+ rc = set_posix_acl(mnt_user_ns(path->mnt), inode,
+ ACL_TYPE_ACCESS, fattr.cf_acls);
if (S_ISDIR(inode->i_mode) && fattr.cf_dacls)
- rc = set_posix_acl(&init_user_ns, inode,
+ rc = set_posix_acl(mnt_user_ns(path->mnt), inode,
ACL_TYPE_DEFAULT, fattr.cf_dacls);
}
@@ -1300,8 +1314,9 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
/* Update WinACL in xattr */
- ksmbd_vfs_remove_sd_xattrs(path->dentry);
- ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, ntsd_len);
+ ksmbd_vfs_remove_sd_xattrs(mnt_user_ns(path->mnt), path->dentry);
+ ksmbd_vfs_set_sd_xattr(conn, mnt_user_ns(path->mnt),
+ path->dentry, pntsd, ntsd_len);
}
out: