aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r--fs/reiserfs/xattr.c103
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
1322int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) 1322static 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: 1346int 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}