aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ncpfs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-07 19:28:28 -0500
committerEric W. Biederman <ebiederm@xmission.com>2013-02-13 09:15:13 -0500
commit1ac7fd8190b79c822631ed537186fb8b2d9e9b74 (patch)
treede88733bf16f6ed670e0de354dded191ae844717 /fs/ncpfs
parent0f07bd3753e25c80fe24428273c791f350b3a1eb (diff)
ncpfs: Support interacting with multiple user namespaces
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>
Diffstat (limited to 'fs/ncpfs')
-rw-r--r--fs/ncpfs/inode.c55
-rw-r--r--fs/ncpfs/ioctl.c25
-rw-r--r--fs/ncpfs/ncp_fs_sb.h6
3 files changed, 50 insertions, 36 deletions
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 1acdad7fcec7..e2be336d1c22 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -331,12 +331,15 @@ static int ncp_show_options(struct seq_file *seq, struct dentry *root)
331 struct ncp_server *server = NCP_SBP(root->d_sb); 331 struct ncp_server *server = NCP_SBP(root->d_sb);
332 unsigned int tmp; 332 unsigned int tmp;
333 333
334 if (server->m.uid != 0) 334 if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
335 seq_printf(seq, ",uid=%u", server->m.uid); 335 seq_printf(seq, ",uid=%u",
336 if (server->m.gid != 0) 336 from_kuid_munged(&init_user_ns, server->m.uid));
337 seq_printf(seq, ",gid=%u", server->m.gid); 337 if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
338 if (server->m.mounted_uid != 0) 338 seq_printf(seq, ",gid=%u",
339 seq_printf(seq, ",owner=%u", server->m.mounted_uid); 339 from_kgid_munged(&init_user_ns, server->m.gid));
340 if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
341 seq_printf(seq, ",owner=%u",
342 from_kuid_munged(&init_user_ns, server->m.mounted_uid));
340 tmp = server->m.file_mode & S_IALLUGO; 343 tmp = server->m.file_mode & S_IALLUGO;
341 if (tmp != NCP_DEFAULT_FILE_MODE) 344 if (tmp != NCP_DEFAULT_FILE_MODE)
342 seq_printf(seq, ",mode=0%o", tmp); 345 seq_printf(seq, ",mode=0%o", tmp);
@@ -381,13 +384,13 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
381 384
382 data->flags = 0; 385 data->flags = 0;
383 data->int_flags = 0; 386 data->int_flags = 0;
384 data->mounted_uid = 0; 387 data->mounted_uid = GLOBAL_ROOT_UID;
385 data->wdog_pid = NULL; 388 data->wdog_pid = NULL;
386 data->ncp_fd = ~0; 389 data->ncp_fd = ~0;
387 data->time_out = NCP_DEFAULT_TIME_OUT; 390 data->time_out = NCP_DEFAULT_TIME_OUT;
388 data->retry_count = NCP_DEFAULT_RETRY_COUNT; 391 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
389 data->uid = 0; 392 data->uid = GLOBAL_ROOT_UID;
390 data->gid = 0; 393 data->gid = GLOBAL_ROOT_GID;
391 data->file_mode = NCP_DEFAULT_FILE_MODE; 394 data->file_mode = NCP_DEFAULT_FILE_MODE;
392 data->dir_mode = NCP_DEFAULT_DIR_MODE; 395 data->dir_mode = NCP_DEFAULT_DIR_MODE;
393 data->info_fd = -1; 396 data->info_fd = -1;
@@ -399,13 +402,19 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
399 goto err; 402 goto err;
400 switch (optval) { 403 switch (optval) {
401 case 'u': 404 case 'u':
402 data->uid = optint; 405 data->uid = make_kuid(current_user_ns(), optint);
406 if (!uid_valid(data->uid))
407 goto err;
403 break; 408 break;
404 case 'g': 409 case 'g':
405 data->gid = optint; 410 data->gid = make_kgid(current_user_ns(), optint);
411 if (!gid_valid(data->gid))
412 goto err;
406 break; 413 break;
407 case 'o': 414 case 'o':
408 data->mounted_uid = optint; 415 data->mounted_uid = make_kuid(current_user_ns(), optint);
416 if (!uid_valid(data->mounted_uid))
417 goto err;
409 break; 418 break;
410 case 'm': 419 case 'm':
411 data->file_mode = optint; 420 data->file_mode = optint;
@@ -480,13 +489,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
480 489
481 data.flags = md->flags; 490 data.flags = md->flags;
482 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; 491 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
483 data.mounted_uid = md->mounted_uid; 492 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
484 data.wdog_pid = find_get_pid(md->wdog_pid); 493 data.wdog_pid = find_get_pid(md->wdog_pid);
485 data.ncp_fd = md->ncp_fd; 494 data.ncp_fd = md->ncp_fd;
486 data.time_out = md->time_out; 495 data.time_out = md->time_out;
487 data.retry_count = md->retry_count; 496 data.retry_count = md->retry_count;
488 data.uid = md->uid; 497 data.uid = make_kuid(current_user_ns(), md->uid);
489 data.gid = md->gid; 498 data.gid = make_kgid(current_user_ns(), md->gid);
490 data.file_mode = md->file_mode; 499 data.file_mode = md->file_mode;
491 data.dir_mode = md->dir_mode; 500 data.dir_mode = md->dir_mode;
492 data.info_fd = -1; 501 data.info_fd = -1;
@@ -499,13 +508,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
499 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; 508 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
500 509
501 data.flags = md->flags; 510 data.flags = md->flags;
502 data.mounted_uid = md->mounted_uid; 511 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
503 data.wdog_pid = find_get_pid(md->wdog_pid); 512 data.wdog_pid = find_get_pid(md->wdog_pid);
504 data.ncp_fd = md->ncp_fd; 513 data.ncp_fd = md->ncp_fd;
505 data.time_out = md->time_out; 514 data.time_out = md->time_out;
506 data.retry_count = md->retry_count; 515 data.retry_count = md->retry_count;
507 data.uid = md->uid; 516 data.uid = make_kuid(current_user_ns(), md->uid);
508 data.gid = md->gid; 517 data.gid = make_kgid(current_user_ns(), md->gid);
509 data.file_mode = md->file_mode; 518 data.file_mode = md->file_mode;
510 data.dir_mode = md->dir_mode; 519 data.dir_mode = md->dir_mode;
511 data.info_fd = -1; 520 data.info_fd = -1;
@@ -520,6 +529,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
520 goto out; 529 goto out;
521 break; 530 break;
522 } 531 }
532 error = -EINVAL;
533 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
534 !gid_valid(data.gid))
535 goto out;
523 error = -EBADF; 536 error = -EBADF;
524 ncp_filp = fget(data.ncp_fd); 537 ncp_filp = fget(data.ncp_fd);
525 if (!ncp_filp) 538 if (!ncp_filp)
@@ -886,12 +899,10 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
886 goto out; 899 goto out;
887 900
888 result = -EPERM; 901 result = -EPERM;
889 if (((attr->ia_valid & ATTR_UID) && 902 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
890 (attr->ia_uid != server->m.uid)))
891 goto out; 903 goto out;
892 904
893 if (((attr->ia_valid & ATTR_GID) && 905 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
894 (attr->ia_gid != server->m.gid)))
895 goto out; 906 goto out;
896 907
897 if (((attr->ia_valid & ATTR_MODE) && 908 if (((attr->ia_valid & ATTR_MODE) &&
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 6958adfaff08..d44318d27504 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -45,7 +45,7 @@ ncp_get_fs_info(struct ncp_server * server, struct inode *inode,
45 return -EINVAL; 45 return -EINVAL;
46 } 46 }
47 /* TODO: info.addr = server->m.serv_addr; */ 47 /* TODO: info.addr = server->m.serv_addr; */
48 SET_UID(info.mounted_uid, server->m.mounted_uid); 48 SET_UID(info.mounted_uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
49 info.connection = server->connection; 49 info.connection = server->connection;
50 info.buffer_size = server->buffer_size; 50 info.buffer_size = server->buffer_size;
51 info.volume_number = NCP_FINFO(inode)->volNumber; 51 info.volume_number = NCP_FINFO(inode)->volNumber;
@@ -69,7 +69,7 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct inode *inode,
69 DPRINTK("info.version invalid: %d\n", info2.version); 69 DPRINTK("info.version invalid: %d\n", info2.version);
70 return -EINVAL; 70 return -EINVAL;
71 } 71 }
72 info2.mounted_uid = server->m.mounted_uid; 72 info2.mounted_uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
73 info2.connection = server->connection; 73 info2.connection = server->connection;
74 info2.buffer_size = server->buffer_size; 74 info2.buffer_size = server->buffer_size;
75 info2.volume_number = NCP_FINFO(inode)->volNumber; 75 info2.volume_number = NCP_FINFO(inode)->volNumber;
@@ -135,7 +135,7 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct inode *inode,
135 DPRINTK("info.version invalid: %d\n", info2.version); 135 DPRINTK("info.version invalid: %d\n", info2.version);
136 return -EINVAL; 136 return -EINVAL;
137 } 137 }
138 info2.mounted_uid = server->m.mounted_uid; 138 info2.mounted_uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
139 info2.connection = server->connection; 139 info2.connection = server->connection;
140 info2.buffer_size = server->buffer_size; 140 info2.buffer_size = server->buffer_size;
141 info2.volume_number = NCP_FINFO(inode)->volNumber; 141 info2.volume_number = NCP_FINFO(inode)->volNumber;
@@ -348,22 +348,25 @@ static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg
348 { 348 {
349 u16 uid; 349 u16 uid;
350 350
351 SET_UID(uid, server->m.mounted_uid); 351 SET_UID(uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
352 if (put_user(uid, (u16 __user *)argp)) 352 if (put_user(uid, (u16 __user *)argp))
353 return -EFAULT; 353 return -EFAULT;
354 return 0; 354 return 0;
355 } 355 }
356 case NCP_IOC_GETMOUNTUID32: 356 case NCP_IOC_GETMOUNTUID32:
357 if (put_user(server->m.mounted_uid, 357 {
358 (u32 __user *)argp)) 358 uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
359 if (put_user(uid, (u32 __user *)argp))
359 return -EFAULT; 360 return -EFAULT;
360 return 0; 361 return 0;
362 }
361 case NCP_IOC_GETMOUNTUID64: 363 case NCP_IOC_GETMOUNTUID64:
362 if (put_user(server->m.mounted_uid, 364 {
363 (u64 __user *)argp)) 365 uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
366 if (put_user(uid, (u64 __user *)argp))
364 return -EFAULT; 367 return -EFAULT;
365 return 0; 368 return 0;
366 369 }
367 case NCP_IOC_GETROOT: 370 case NCP_IOC_GETROOT:
368 { 371 {
369 struct ncp_setroot_ioctl sr; 372 struct ncp_setroot_ioctl sr;
@@ -810,7 +813,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
810{ 813{
811 struct inode *inode = filp->f_dentry->d_inode; 814 struct inode *inode = filp->f_dentry->d_inode;
812 struct ncp_server *server = NCP_SERVER(inode); 815 struct ncp_server *server = NCP_SERVER(inode);
813 uid_t uid = current_uid(); 816 kuid_t uid = current_uid();
814 int need_drop_write = 0; 817 int need_drop_write = 0;
815 long ret; 818 long ret;
816 819
@@ -824,7 +827,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
824 } 827 }
825 break; 828 break;
826 } 829 }
827 if (server->m.mounted_uid != uid) { 830 if (!uid_eq(server->m.mounted_uid, uid)) {
828 switch (cmd) { 831 switch (cmd) {
829 /* 832 /*
830 * Only mount owner can issue these ioctls. Information 833 * Only mount owner can issue these ioctls. Information
diff --git a/fs/ncpfs/ncp_fs_sb.h b/fs/ncpfs/ncp_fs_sb.h
index 54cc0cdb3dcb..c51b2c543539 100644
--- a/fs/ncpfs/ncp_fs_sb.h
+++ b/fs/ncpfs/ncp_fs_sb.h
@@ -23,15 +23,15 @@ struct ncp_mount_data_kernel {
23 unsigned long flags; /* NCP_MOUNT_* flags */ 23 unsigned long flags; /* NCP_MOUNT_* flags */
24 unsigned int int_flags; /* internal flags */ 24 unsigned int int_flags; /* internal flags */
25#define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 25#define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001
26 uid_t mounted_uid; /* Who may umount() this filesystem? */ 26 kuid_t mounted_uid; /* Who may umount() this filesystem? */
27 struct pid *wdog_pid; /* Who cares for our watchdog packets? */ 27 struct pid *wdog_pid; /* Who cares for our watchdog packets? */
28 unsigned int ncp_fd; /* The socket to the ncp port */ 28 unsigned int ncp_fd; /* The socket to the ncp port */
29 unsigned int time_out; /* How long should I wait after 29 unsigned int time_out; /* How long should I wait after
30 sending a NCP request? */ 30 sending a NCP request? */
31 unsigned int retry_count; /* And how often should I retry? */ 31 unsigned int retry_count; /* And how often should I retry? */
32 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; 32 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
33 uid_t uid; 33 kuid_t uid;
34 gid_t gid; 34 kgid_t gid;
35 umode_t file_mode; 35 umode_t file_mode;
36 umode_t dir_mode; 36 umode_t dir_mode;
37 int info_fd; 37 int info_fd;