]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
ncpfs: Support interacting with multiple user namespaces
authorEric W. Biederman <ebiederm@xmission.com>
Wed, 8 Feb 2012 00:28:28 +0000 (16:28 -0800)
committerEric W. Biederman <ebiederm@xmission.com>
Wed, 13 Feb 2013 14:15:13 +0000 (06:15 -0800)
ncpfs does not natively support uids and gids so this conversion was
simply a matter of updating the the type of the mounteduid, the uid
and the gid on the superblock. Fixing the ioctls that read them,
updating the mount option parser and the mount option printer.

Cc: Petr Vandrovec <petr@vandrovec.name>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
fs/ncpfs/inode.c
fs/ncpfs/ioctl.c
fs/ncpfs/ncp_fs_sb.h
init/Kconfig

index 1acdad7fcec7cda8ca5aa9e88b92cce45b960c37..e2be336d1c22da50b516a1926c7cabfaf0686ff8 100644 (file)
@@ -331,12 +331,15 @@ static int  ncp_show_options(struct seq_file *seq, struct dentry *root)
        struct ncp_server *server = NCP_SBP(root->d_sb);
        unsigned int tmp;
 
-       if (server->m.uid != 0)
-               seq_printf(seq, ",uid=%u", server->m.uid);
-       if (server->m.gid != 0)
-               seq_printf(seq, ",gid=%u", server->m.gid);
-       if (server->m.mounted_uid != 0)
-               seq_printf(seq, ",owner=%u", server->m.mounted_uid);
+       if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
+               seq_printf(seq, ",uid=%u",
+                          from_kuid_munged(&init_user_ns, server->m.uid));
+       if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
+               seq_printf(seq, ",gid=%u",
+                          from_kgid_munged(&init_user_ns, server->m.gid));
+       if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
+               seq_printf(seq, ",owner=%u",
+                          from_kuid_munged(&init_user_ns, server->m.mounted_uid));
        tmp = server->m.file_mode & S_IALLUGO;
        if (tmp != NCP_DEFAULT_FILE_MODE)
                seq_printf(seq, ",mode=0%o", tmp);
@@ -381,13 +384,13 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
 
        data->flags = 0;
        data->int_flags = 0;
-       data->mounted_uid = 0;
+       data->mounted_uid = GLOBAL_ROOT_UID;
        data->wdog_pid = NULL;
        data->ncp_fd = ~0;
        data->time_out = NCP_DEFAULT_TIME_OUT;
        data->retry_count = NCP_DEFAULT_RETRY_COUNT;
-       data->uid = 0;
-       data->gid = 0;
+       data->uid = GLOBAL_ROOT_UID;
+       data->gid = GLOBAL_ROOT_GID;
        data->file_mode = NCP_DEFAULT_FILE_MODE;
        data->dir_mode = NCP_DEFAULT_DIR_MODE;
        data->info_fd = -1;
@@ -399,13 +402,19 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
                        goto err;
                switch (optval) {
                        case 'u':
-                               data->uid = optint;
+                               data->uid = make_kuid(current_user_ns(), optint);
+                               if (!uid_valid(data->uid))
+                                       goto err;
                                break;
                        case 'g':
-                               data->gid = optint;
+                               data->gid = make_kgid(current_user_ns(), optint);
+                               if (!gid_valid(data->gid))
+                                       goto err;
                                break;
                        case 'o':
-                               data->mounted_uid = optint;
+                               data->mounted_uid = make_kuid(current_user_ns(), optint);
+                               if (!uid_valid(data->mounted_uid))
+                                       goto err;
                                break;
                        case 'm':
                                data->file_mode = optint;
@@ -480,13 +489,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 
                                data.flags = md->flags;
                                data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
-                               data.mounted_uid = md->mounted_uid;
+                               data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
                                data.wdog_pid = find_get_pid(md->wdog_pid);
                                data.ncp_fd = md->ncp_fd;
                                data.time_out = md->time_out;
                                data.retry_count = md->retry_count;
-                               data.uid = md->uid;
-                               data.gid = md->gid;
+                               data.uid = make_kuid(current_user_ns(), md->uid);
+                               data.gid = make_kgid(current_user_ns(), md->gid);
                                data.file_mode = md->file_mode;
                                data.dir_mode = md->dir_mode;
                                data.info_fd = -1;
@@ -499,13 +508,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
 
                                data.flags = md->flags;
-                               data.mounted_uid = md->mounted_uid;
+                               data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
                                data.wdog_pid = find_get_pid(md->wdog_pid);
                                data.ncp_fd = md->ncp_fd;
                                data.time_out = md->time_out;
                                data.retry_count = md->retry_count;
-                               data.uid = md->uid;
-                               data.gid = md->gid;
+                               data.uid = make_kuid(current_user_ns(), md->uid);
+                               data.gid = make_kgid(current_user_ns(), md->gid);
                                data.file_mode = md->file_mode;
                                data.dir_mode = md->dir_mode;
                                data.info_fd = -1;
@@ -520,6 +529,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                goto out;
                        break;
        }
+       error = -EINVAL;
+       if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
+           !gid_valid(data.gid))
+               goto out;
        error = -EBADF;
        ncp_filp = fget(data.ncp_fd);
        if (!ncp_filp)
@@ -886,12 +899,10 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                goto out;
 
        result = -EPERM;
-       if (((attr->ia_valid & ATTR_UID) &&
-            (attr->ia_uid != server->m.uid)))
+       if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
                goto out;
 
-       if (((attr->ia_valid & ATTR_GID) &&
-            (attr->ia_gid != server->m.gid)))
+       if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
                goto out;
 
        if (((attr->ia_valid & ATTR_MODE) &&
index 6958adfaff084e71fa66a1f7e10a00ad82fd8f60..d44318d275049c1dbe0971c23e0ca4876ad6b1ae 100644 (file)
@@ -45,7 +45,7 @@ ncp_get_fs_info(struct ncp_server * server, struct inode *inode,
                return -EINVAL;
        }
        /* TODO: info.addr = server->m.serv_addr; */
-       SET_UID(info.mounted_uid, server->m.mounted_uid);
+       SET_UID(info.mounted_uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
        info.connection         = server->connection;
        info.buffer_size        = server->buffer_size;
        info.volume_number      = NCP_FINFO(inode)->volNumber;
@@ -69,7 +69,7 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct inode *inode,
                DPRINTK("info.version invalid: %d\n", info2.version);
                return -EINVAL;
        }
-       info2.mounted_uid   = server->m.mounted_uid;
+       info2.mounted_uid   = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
        info2.connection    = server->connection;
        info2.buffer_size   = server->buffer_size;
        info2.volume_number = NCP_FINFO(inode)->volNumber;
@@ -135,7 +135,7 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct inode *inode,
                DPRINTK("info.version invalid: %d\n", info2.version);
                return -EINVAL;
        }
-       info2.mounted_uid   = server->m.mounted_uid;
+       info2.mounted_uid   = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
        info2.connection    = server->connection;
        info2.buffer_size   = server->buffer_size;
        info2.volume_number = NCP_FINFO(inode)->volNumber;
@@ -348,22 +348,25 @@ static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg
                {
                        u16 uid;
 
-                       SET_UID(uid, server->m.mounted_uid);
+                       SET_UID(uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
                        if (put_user(uid, (u16 __user *)argp))
                                return -EFAULT;
                        return 0;
                }
        case NCP_IOC_GETMOUNTUID32:
-               if (put_user(server->m.mounted_uid,
-                            (u32 __user *)argp))
+       {
+               uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
+               if (put_user(uid, (u32 __user *)argp))
                        return -EFAULT;
                return 0;
+       }
        case NCP_IOC_GETMOUNTUID64:
-               if (put_user(server->m.mounted_uid,
-                            (u64 __user *)argp))
+       {
+               uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
+               if (put_user(uid, (u64 __user *)argp))
                        return -EFAULT;
                return 0;
-
+       }
        case NCP_IOC_GETROOT:
                {
                        struct ncp_setroot_ioctl sr;
@@ -810,7 +813,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = filp->f_dentry->d_inode;
        struct ncp_server *server = NCP_SERVER(inode);
-       uid_t uid = current_uid();
+       kuid_t uid = current_uid();
        int need_drop_write = 0;
        long ret;
 
@@ -824,7 +827,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                }
                break;
        }
-       if (server->m.mounted_uid != uid) {
+       if (!uid_eq(server->m.mounted_uid, uid)) {
                switch (cmd) {
                /*
                 * Only mount owner can issue these ioctls.  Information
index 54cc0cdb3dcbda111e24a3a67e7953e5173dd07e..c51b2c54353971f785020570ee6773e60058bef0 100644 (file)
@@ -23,15 +23,15 @@ struct ncp_mount_data_kernel {
        unsigned long    flags;         /* NCP_MOUNT_* flags */
        unsigned int     int_flags;     /* internal flags */
 #define NCP_IMOUNT_LOGGEDIN_POSSIBLE   0x0001
-       uid_t            mounted_uid;   /* Who may umount() this filesystem? */
+       kuid_t           mounted_uid;   /* Who may umount() this filesystem? */
        struct pid      *wdog_pid;      /* Who cares for our watchdog packets? */
        unsigned int     ncp_fd;        /* The socket to the ncp port */
        unsigned int     time_out;      /* How long should I wait after
                                           sending a NCP request? */
        unsigned int     retry_count;   /* And how often should I retry? */
        unsigned char    mounted_vol[NCP_VOLNAME_LEN + 1];
-       uid_t            uid;
-       gid_t            gid;
+       kuid_t           uid;
+       kgid_t           gid;
        umode_t          file_mode;
        umode_t          dir_mode;
        int              info_fd;
index 591fc75710b313ac7f4c6e29103d3853b4277802..b526f4c35b95c8c8bb49eaa5190b18f37a00bda8 100644 (file)
@@ -1072,7 +1072,6 @@ config UIDGID_CONVERTED
 
        # Filesystems
        depends on CIFS = n
-       depends on NCP_FS = n
        depends on NFSD = n
        depends on NFS_FS = n
        depends on XFS_FS = n