Commit af34983e authored by Hyunchul Lee's avatar Hyunchul Lee Committed by Namjae Jeon

ksmbd: add user namespace support

For user namespace support, call vfs functions
with struct user_namespace got from struct path.

This patch have been tested mannually as below.

Create an id-mapped mount using the mount-idmapped utility
(https://github.com/brauner/mount-idmapped).
$ mount-idmapped --map-mount b:1003:1002:1 /home/foo <EXPORT DIR>/foo
(the user, "foo" is 1003, and the user "bar" is 1002).

And  mount the export directory using cifs with the user, "bar".
succeed to create/delete/stat/read/write files and directory in
the <EXPORT DIR>/foo. But fail with a bind mount for /home/foo.
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarHyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: default avatarNamjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent ef24c962
......@@ -222,7 +222,9 @@ static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl)
return 0;
}
int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
int ndr_encode_posix_acl(struct ndr *n,
struct user_namespace *user_ns,
struct inode *inode,
struct xattr_smb_acl *acl,
struct xattr_smb_acl *def_acl)
{
......@@ -250,8 +252,8 @@ int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
ndr_write_int32(n, 0);
}
ndr_write_int64(n, from_kuid(&init_user_ns, inode->i_uid));
ndr_write_int64(n, from_kgid(&init_user_ns, inode->i_gid));
ndr_write_int64(n, from_kuid(user_ns, inode->i_uid));
ndr_write_int64(n, from_kgid(user_ns, inode->i_gid));
ndr_write_int32(n, inode->i_mode);
if (acl) {
......
......@@ -14,8 +14,8 @@ struct ndr {
int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da);
int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da);
int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
struct xattr_smb_acl *acl,
int ndr_encode_posix_acl(struct ndr *n, struct user_namespace *user_ns,
struct inode *inode, struct xattr_smb_acl *acl,
struct xattr_smb_acl *def_acl);
int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl);
int ndr_encode_v3_ntacl(struct ndr *n, struct xattr_ntacl *acl);
......
......@@ -1612,9 +1612,9 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp)
buf->nlink = cpu_to_le32(inode->i_nlink);
buf->reparse_tag = cpu_to_le32(fp->volatile_id);
buf->mode = cpu_to_le32(inode->i_mode);
id_to_sid(from_kuid(&init_user_ns, inode->i_uid),
id_to_sid(from_kuid(file_mnt_user_ns(fp->filp), inode->i_uid),
SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]);
id_to_sid(from_kgid(&init_user_ns, inode->i_gid),
id_to_sid(from_kgid(file_mnt_user_ns(fp->filp), inode->i_gid),
SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]);
}
......
This diff is collapsed.
......@@ -274,6 +274,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
char *search_pattern,
int (*fn)(struct ksmbd_conn *, int,
struct ksmbd_dir_info *,
struct user_namespace *,
struct ksmbd_kstat *))
{
int i, rc = 0;
......@@ -300,9 +301,11 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
ksmbd_kstat.kstat = &kstat;
ksmbd_vfs_fill_dentry_attrs(work,
file_mnt_user_ns(dir->filp),
dir->filp->f_path.dentry->d_parent,
&ksmbd_kstat);
rc = fn(conn, info_level, d_info, &ksmbd_kstat);
rc = fn(conn, info_level, d_info,
file_mnt_user_ns(dir->filp), &ksmbd_kstat);
if (rc)
break;
if (d_info->out_buf_len <= 0)
......
......@@ -514,6 +514,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
int (*fn)(struct ksmbd_conn *,
int,
struct ksmbd_dir_info *,
struct user_namespace *,
struct ksmbd_kstat *));
int ksmbd_extract_shortname(struct ksmbd_conn *conn,
......
This diff is collapsed.
......@@ -189,11 +189,11 @@ struct posix_acl_state {
struct posix_ace_state_array *groups;
};
int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
struct smb_fattr *fattr);
int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
int addition_info, __u32 *secdesclen,
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 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);
int init_acl_state(struct posix_acl_state *state, int cnt);
void free_acl_state(struct posix_acl_state *state);
void posix_state_to_acl(struct posix_acl_state *state,
......
This diff is collapsed.
......@@ -108,8 +108,9 @@ struct ksmbd_kstat {
};
int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child);
int ksmbd_vfs_may_delete(struct dentry *dentry);
int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess);
int ksmbd_vfs_may_delete(struct user_namespace *user_ns, struct dentry *dentry);
int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
struct dentry *dentry, __le32 *daccess);
int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode);
int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode);
int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp,
......@@ -136,15 +137,20 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
unsigned int *chunk_size_written,
loff_t *total_size_written);
ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list);
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns,
struct dentry *dentry,
char *xattr_name,
char **xattr_buf);
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns,
struct dentry *dentry, char *attr_name,
int attr_name_len);
int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
int ksmbd_vfs_setxattr(struct user_namespace *user_ns,
struct dentry *dentry, const char *attr_name,
const void *attr_value, size_t attr_size, int flags);
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
size_t *xattr_stream_name_size, int s_type);
int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name);
int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
struct dentry *dentry, char *attr_name);
int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path,
bool caseless);
int ksmbd_vfs_empty_dir(struct ksmbd_file *fp);
......@@ -155,24 +161,37 @@ struct file_allocated_range_buffer;
int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
struct file_allocated_range_buffer *ranges,
int in_count, int *out_count);
int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry);
int ksmbd_vfs_unlink(struct user_namespace *user_ns,
struct dentry *dir, struct dentry *dentry);
void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat);
int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
struct user_namespace *user_ns,
struct dentry *dentry,
struct ksmbd_kstat *ksmbd_kstat);
int ksmbd_vfs_posix_lock_wait(struct file_lock *flock);
int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout);
void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock);
int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry);
int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry);
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns,
struct dentry *dentry);
int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns,
struct dentry *dentry);
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
struct user_namespace *user_ns,
struct dentry *dentry,
struct smb_ntsd *pntsd, int len);
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
struct user_namespace *user_ns,
struct dentry *dentry,
struct smb_ntsd **pntsd);
int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns,
struct dentry *dentry,
struct xattr_dos_attrib *da);
int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry,
int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns,
struct dentry *dentry,
struct xattr_dos_attrib *da);
int ksmbd_vfs_set_init_posix_acl(struct inode *inode);
int ksmbd_vfs_inherit_posix_acl(struct inode *inode,
int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns,
struct inode *inode);
int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns,
struct inode *inode,
struct inode *parent_inode);
#endif /* __KSMBD_VFS_H__ */
......@@ -251,7 +251,8 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
filp = fp->filp;
if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) {
ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
err = ksmbd_vfs_remove_xattr(filp->f_path.dentry,
err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp),
filp->f_path.dentry,
fp->stream.name);
if (err)
pr_err("remove xattr failed : %s\n",
......@@ -265,7 +266,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
dir = dentry->d_parent;
ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
write_unlock(&ci->m_lock);
ksmbd_vfs_unlink(dir, dentry);
ksmbd_vfs_unlink(file_mnt_user_ns(filp), dir, dentry);
write_lock(&ci->m_lock);
}
write_unlock(&ci->m_lock);
......
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