aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/quota.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-02-16 03:44:50 -0500
committerJan Kara <jack@suse.cz>2010-03-04 18:20:22 -0500
commitc988afb5fa3fc450207c3dfc0ce535f4bfdae4d1 (patch)
treedcb9b4e11c4429ee79198ee3a7de43d734c1cbfe /fs/quota/quota.c
parent6ae09575b3c951ad77c07d068b8dbbc09031b2d1 (diff)
quota: simplify permission checking
Stop having complicated different routines for checking permissions for XQM vs "VFS" quotas. Instead do the checks for having sb->s_qcop and a valid type directly in do_quotactl, and munge the *quotactl_valid functions into a check_quotactl_permission helper that only checks for permissions. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/quota/quota.c')
-rw-r--r--fs/quota/quota.c92
1 files changed, 31 insertions, 61 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 9fde5cd84f8d..d0efe302b1c1 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -21,69 +21,30 @@
21#include <net/netlink.h> 21#include <net/netlink.h>
22#include <net/genetlink.h> 22#include <net/genetlink.h>
23 23
24/* Check validity of generic quotactl commands */ 24static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
25static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, 25 qid_t id)
26 qid_t id)
27{ 26{
28 if (type >= MAXQUOTAS) 27 switch (cmd) {
29 return -EINVAL; 28 /* these commands do not require any special privilegues */
30 if (!sb && cmd != Q_SYNC) 29 case Q_GETFMT:
31 return -ENODEV; 30 case Q_SYNC:
32 /* Is operation supported? */ 31 case Q_GETINFO:
33 if (sb && !sb->s_qcop) 32 case Q_XGETQSTAT:
34 return -ENOSYS; 33 case Q_XQUOTASYNC:
35 34 break;
36 /* Check privileges */ 35 /* allow to query information for dquots we "own" */
37 if (cmd == Q_GETQUOTA) { 36 case Q_GETQUOTA:
38 if (((type == USRQUOTA && current_euid() != id) || 37 case Q_XGETQUOTA:
39 (type == GRPQUOTA && !in_egroup_p(id))) && 38 if ((type == USRQUOTA && current_euid() == id) ||
40 !capable(CAP_SYS_ADMIN)) 39 (type == GRPQUOTA && in_egroup_p(id)))
41 return -EPERM; 40 break;
42 } 41 /*FALLTHROUGH*/
43 else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) 42 default:
44 if (!capable(CAP_SYS_ADMIN))
45 return -EPERM;
46
47 return 0;
48}
49
50/* Check validity of XFS Quota Manager commands */
51static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd,
52 qid_t id)
53{
54 if (type >= XQM_MAXQUOTAS)
55 return -EINVAL;
56 if (!sb)
57 return -ENODEV;
58 if (!sb->s_qcop)
59 return -ENOSYS;
60
61 /* Check privileges */
62 if (cmd == Q_XGETQUOTA) {
63 if (((type == XQM_USRQUOTA && current_euid() != id) ||
64 (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
65 !capable(CAP_SYS_ADMIN))
66 return -EPERM;
67 } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
68 if (!capable(CAP_SYS_ADMIN)) 43 if (!capable(CAP_SYS_ADMIN))
69 return -EPERM; 44 return -EPERM;
70 } 45 }
71 46
72 return 0; 47 return security_quotactl(cmd, type, id, sb);
73}
74
75static int check_quotactl_valid(struct super_block *sb, int type, int cmd,
76 qid_t id)
77{
78 int error;
79
80 if (XQM_COMMAND(cmd))
81 error = xqm_quotactl_valid(sb, type, cmd, id);
82 else
83 error = generic_quotactl_valid(sb, type, cmd, id);
84 if (!error)
85 error = security_quotactl(cmd, type, id, sb);
86 return error;
87} 48}
88 49
89#ifdef CONFIG_QUOTA 50#ifdef CONFIG_QUOTA
@@ -313,6 +274,17 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id,
313static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, 274static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
314 void __user *addr) 275 void __user *addr)
315{ 276{
277 int ret;
278
279 if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
280 return -EINVAL;
281 if (!sb->s_qcop)
282 return -ENOSYS;
283
284 ret = check_quotactl_permission(sb, type, cmd, id);
285 if (ret < 0)
286 return ret;
287
316 switch (cmd) { 288 switch (cmd) {
317 case Q_QUOTAON: 289 case Q_QUOTAON:
318 return quota_quotaon(sb, type, cmd, id, addr); 290 return quota_quotaon(sb, type, cmd, id, addr);
@@ -413,9 +385,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
413 if (IS_ERR(sb)) 385 if (IS_ERR(sb))
414 return PTR_ERR(sb); 386 return PTR_ERR(sb);
415 387
416 ret = check_quotactl_valid(sb, type, cmds, id); 388 ret = do_quotactl(sb, type, cmds, id, addr);
417 if (ret >= 0)
418 ret = do_quotactl(sb, type, cmds, id, addr);
419 389
420 drop_super(sb); 390 drop_super(sb);
421 return ret; 391 return ret;