#include <linux/sched.h>
#include <linux/fs.h>
-#include <linux/namei.h>
#include <linux/quotaops.h>
#include "jfs_incore.h"
#include "jfs_xattr.h"
return rc;
}
-int jfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+/*
+ * jfs_permission()
+ *
+ * modified vfs_permission to check posix acl
+ */
+int jfs_permission(struct inode * inode, int mask, struct nameidata *nd)
{
- int mode = inode->i_mode;
+ umode_t mode = inode->i_mode;
+ struct jfs_inode_info *ji = JFS_IP(inode);
+
+ if (mask & MAY_WRITE) {
+ /*
+ * Nobody gets write access to a read-only fs.
+ */
+ if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+ return -EROFS;
+
+ /*
+ * Nobody gets write access to an immutable file.
+ */
+ if (IS_IMMUTABLE(inode))
+ return -EACCES;
+ }
+
+ if (current->fsuid == inode->i_uid) {
+ mode >>= 6;
+ goto check_mode;
+ }
+ /*
+ * ACL can't contain additional permissions if the ACL_MASK entry
+ * is zero.
+ */
+ if (!(mode & S_IRWXG))
+ goto check_groups;
+
+ if (ji->i_acl == JFS_ACL_NOT_CACHED) {
+ struct posix_acl *acl;
+
+ acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
+
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ posix_acl_release(acl);
+ }
+
+ if (ji->i_acl) {
+ int rc = posix_acl_permission(inode, ji->i_acl, mask);
+ if (rc == -EACCES)
+ goto check_capabilities;
+ return rc;
+ }
+
+check_groups:
+ if (in_group_p(inode->i_gid))
+ mode >>= 3;
+
+check_mode:
+ /*
+ * If the DACs are ok we don't need any capability check.
+ */
+ if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask))
+ return 0;
+
+check_capabilities:
+ /*
+ * Read/write DACs are always overridable.
+ * Executable DACs are overridable if at least one exec bit is set.
+ */
+ if (!(mask & MAY_EXEC) ||
+ (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
+ if (capable(CAP_DAC_OVERRIDE))
+ return 0;
-#warning MEF Need new BME patch for 2.6.10
- /* Nobody gets write access to a read-only fs */
- if ((mask & MAY_WRITE) && (IS_RDONLY(inode) ||
- (nd && MNT_IS_RDONLY(nd->mnt))) &&
- (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
- return -EROFS;
+ /*
+ * Searching includes executable on directories, else just read.
+ */
+ if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
+ if (capable(CAP_DAC_READ_SEARCH))
+ return 0;
- return generic_permission(inode, mask, 0);
+ return -EACCES;
}
int jfs_init_acl(struct inode *inode, struct inode *dir)