diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-02-07 19:28:28 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2013-02-13 09:15:13 -0500 |
commit | 1ac7fd8190b79c822631ed537186fb8b2d9e9b74 (patch) | |
tree | de88733bf16f6ed670e0de354dded191ae844717 | |
parent | 0f07bd3753e25c80fe24428273c791f350b3a1eb (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>
-rw-r--r-- | fs/ncpfs/inode.c | 55 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 25 | ||||
-rw-r--r-- | fs/ncpfs/ncp_fs_sb.h | 6 | ||||
-rw-r--r-- | init/Kconfig | 1 |
4 files changed, 50 insertions, 37 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; |
diff --git a/init/Kconfig b/init/Kconfig index 591fc75710b3..b526f4c35b95 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1072,7 +1072,6 @@ config UIDGID_CONVERTED | |||
1072 | 1072 | ||
1073 | # Filesystems | 1073 | # Filesystems |
1074 | depends on CIFS = n | 1074 | depends on CIFS = n |
1075 | depends on NCP_FS = n | ||
1076 | depends on NFSD = n | 1075 | depends on NFSD = n |
1077 | depends on NFS_FS = n | 1076 | depends on NFS_FS = n |
1078 | depends on XFS_FS = n | 1077 | depends on XFS_FS = n |