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 | |
| 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>
| -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 | } |
