diff options
author | Christoph Hellwig <hch@lst.de> | 2006-02-01 06:06:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-01 11:53:25 -0500 |
commit | ec191574b9c3cb7bfb95e4f803b63f7c8dc52690 (patch) | |
tree | 3fea2eb0fb84e0d793ac0185e1a85121a1835d4f /fs/reiserfs/xattr.c | |
parent | c87d0c07ea198db1ce451421904edd60b7d385ee (diff) |
[PATCH] reiserfs: use generic_permission
Use the generic_permission code with a proper wrapper and callback instead
of having a local copy.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <mason@suse.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r-- | fs/reiserfs/xattr.c | 103 |
1 files changed, 26 insertions, 77 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 2f085845f670..ffb79c48c5bf 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -1319,95 +1319,44 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
1319 | return err; | 1319 | return err; |
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) | 1322 | static int reiserfs_check_acl(struct inode *inode, int mask) |
1323 | { | 1323 | { |
1324 | umode_t mode = inode->i_mode; | 1324 | struct posix_acl *acl; |
1325 | 1325 | int error = -EAGAIN; /* do regular unix permission checks by default */ | |
1326 | if (mask & MAY_WRITE) { | ||
1327 | /* | ||
1328 | * Nobody gets write access to a read-only fs. | ||
1329 | */ | ||
1330 | if (IS_RDONLY(inode) && | ||
1331 | (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) | ||
1332 | return -EROFS; | ||
1333 | |||
1334 | /* | ||
1335 | * Nobody gets write access to an immutable file. | ||
1336 | */ | ||
1337 | if (IS_IMMUTABLE(inode)) | ||
1338 | return -EACCES; | ||
1339 | } | ||
1340 | |||
1341 | /* We don't do permission checks on the internal objects. | ||
1342 | * Permissions are determined by the "owning" object. */ | ||
1343 | if (is_reiserfs_priv_object(inode)) | ||
1344 | return 0; | ||
1345 | |||
1346 | if (current->fsuid == inode->i_uid) { | ||
1347 | mode >>= 6; | ||
1348 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
1349 | } else if (reiserfs_posixacl(inode->i_sb) && | ||
1350 | get_inode_sd_version(inode) != STAT_DATA_V1) { | ||
1351 | struct posix_acl *acl; | ||
1352 | |||
1353 | /* ACL can't contain additional permissions if | ||
1354 | the ACL_MASK entry is 0 */ | ||
1355 | if (!(mode & S_IRWXG)) | ||
1356 | goto check_groups; | ||
1357 | 1326 | ||
1358 | reiserfs_read_lock_xattr_i(inode); | 1327 | reiserfs_read_lock_xattr_i(inode); |
1359 | reiserfs_read_lock_xattrs(inode->i_sb); | 1328 | reiserfs_read_lock_xattrs(inode->i_sb); |
1360 | |||
1361 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); | ||
1362 | 1329 | ||
1363 | reiserfs_read_unlock_xattrs(inode->i_sb); | 1330 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); |
1364 | reiserfs_read_unlock_xattr_i(inode); | ||
1365 | 1331 | ||
1366 | if (IS_ERR(acl)) { | 1332 | reiserfs_read_unlock_xattrs(inode->i_sb); |
1367 | if (PTR_ERR(acl) == -ENODATA) | 1333 | reiserfs_read_unlock_xattr_i(inode); |
1368 | goto check_groups; | ||
1369 | return PTR_ERR(acl); | ||
1370 | } | ||
1371 | 1334 | ||
1372 | if (acl) { | 1335 | if (acl) { |
1373 | int err = posix_acl_permission(inode, acl, mask); | 1336 | if (!IS_ERR(acl)) { |
1337 | error = posix_acl_permission(inode, acl, mask); | ||
1374 | posix_acl_release(acl); | 1338 | posix_acl_release(acl); |
1375 | if (err == -EACCES) { | 1339 | } else if (PTR_ERR(acl) != -ENODATA) |
1376 | goto check_capabilities; | 1340 | error = PTR_ERR(acl); |
1377 | } | ||
1378 | return err; | ||
1379 | } else { | ||
1380 | goto check_groups; | ||
1381 | } | ||
1382 | #endif | ||
1383 | } else { | ||
1384 | check_groups: | ||
1385 | if (in_group_p(inode->i_gid)) | ||
1386 | mode >>= 3; | ||
1387 | } | 1341 | } |
1388 | 1342 | ||
1389 | /* | 1343 | return error; |
1390 | * If the DACs are ok we don't need any capability check. | 1344 | } |
1391 | */ | ||
1392 | if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask)) | ||
1393 | return 0; | ||
1394 | 1345 | ||
1395 | check_capabilities: | 1346 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) |
1347 | { | ||
1396 | /* | 1348 | /* |
1397 | * Read/write DACs are always overridable. | 1349 | * We don't do permission checks on the internal objects. |
1398 | * Executable DACs are overridable if at least one exec bit is set. | 1350 | * Permissions are determined by the "owning" object. |
1399 | */ | 1351 | */ |
1400 | if (!(mask & MAY_EXEC) || | 1352 | if (is_reiserfs_priv_object(inode)) |
1401 | (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) | 1353 | return 0; |
1402 | if (capable(CAP_DAC_OVERRIDE)) | ||
1403 | return 0; | ||
1404 | 1354 | ||
1405 | /* | 1355 | /* |
1406 | * Searching includes executable on directories, else just read. | 1356 | * Stat data v1 doesn't support ACLs. |
1407 | */ | 1357 | */ |
1408 | if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) | 1358 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
1409 | if (capable(CAP_DAC_READ_SEARCH)) | 1359 | return generic_permission(inode, mask, NULL); |
1410 | return 0; | 1360 | else |
1411 | 1361 | return generic_permission(inode, mask, reiserfs_check_acl); | |
1412 | return -EACCES; | ||
1413 | } | 1362 | } |