@@ -377,7 +377,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
if (acl->a_owner_mask == owner_mask &&
acl->a_group_mask == group_mask &&
acl->a_other_mask == other_mask &&
- (acl->a_flags & ACL4_MASKED))
+ (acl->a_flags & ACL4_MASKED) &&
+ (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl)))
return acl;
clone = richacl_clone(acl);
@@ -389,6 +390,8 @@ richacl_chmod(struct richacl *acl, mode_t mode)
clone->a_owner_mask = owner_mask;
clone->a_group_mask = group_mask;
clone->a_other_mask = other_mask;
+ if (richacl_is_auto_inherit(clone))
+ clone->a_flags |= ACL4_PROTECTED;
return clone;
}
@@ -558,6 +561,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir)
ace++;
}
}
+ if (richacl_is_auto_inherit(dir_acl)) {
+ acl->a_flags = ACL4_AUTO_INHERIT;
+ richacl_for_each_entry(ace, acl)
+ ace->e_flags |= ACE4_INHERITED_ACE;
+ }
return acl;
}
@@ -37,9 +37,14 @@ richacl_inherit_inode(const struct richacl *dir_acl, struct inode *inode)
acl = richacl_inherit(dir_acl, S_ISDIR(inode->i_mode));
if (acl) {
+ /*
+ * We need to set ACL4_PROTECTED because we are
+ * doing an implicit chmod
+ */
+ if (richacl_is_auto_inherit(acl))
+ acl->a_flags |= ACL4_PROTECTED;
richacl_compute_max_masks(acl);
-
/*
* Ensure that the acl will not grant any permissions beyond
* the create mode.
@@ -47,10 +47,16 @@ struct richacl {
_ace != _acl->a_entries - 1; \
_ace--)
+/* a_flags values */
+#define ACL4_AUTO_INHERIT 0x01
+#define ACL4_PROTECTED 0x02
+/* #define ACL4_DEFAULTED 0x04 */
/* Flag values defined by rich-acl */
#define ACL4_MASKED 0x80
#define ACL4_VALID_FLAGS ( \
+ ACL4_AUTO_INHERIT | \
+ ACL4_PROTECTED | \
ACL4_MASKED)
/* e_type values */
@@ -67,6 +73,7 @@ struct richacl {
/*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG 0x0010*/
/*#define ACE4_FAILED_ACCESS_ACE_FLAG 0x0020*/
#define ACE4_IDENTIFIER_GROUP 0x0040
+#define ACE4_INHERITED_ACE 0x0080
/* in-memory representation only */
#define ACE4_SPECIAL_WHO 0x4000
@@ -75,7 +82,8 @@ struct richacl {
ACE4_DIRECTORY_INHERIT_ACE | \
ACE4_NO_PROPAGATE_INHERIT_ACE | \
ACE4_INHERIT_ONLY_ACE | \
- ACE4_IDENTIFIER_GROUP)
+ ACE4_IDENTIFIER_GROUP | \
+ ACE4_INHERITED_ACE)
/* e_mask bitflags */
#define ACE4_READ_DATA 0x00000001
@@ -181,6 +189,18 @@ richacl_put(struct richacl *acl)
kfree(acl);
}
+static inline int
+richacl_is_auto_inherit(const struct richacl *acl)
+{
+ return acl->a_flags & ACL4_AUTO_INHERIT;
+}
+
+static inline int
+richacl_is_protected(const struct richacl *acl)
+{
+ return acl->a_flags & ACL4_PROTECTED;
+}
+
/*
* Special e_who identifiers: we use these pointer values in comparisons
* instead of doing a strcmp.
@@ -259,7 +279,8 @@ richace_clear_inheritance_flags(struct richace *ace)
ace->e_flags &= ~(ACE4_FILE_INHERIT_ACE |
ACE4_DIRECTORY_INHERIT_ACE |
ACE4_NO_PROPAGATE_INHERIT_ACE |
- ACE4_INHERIT_ONLY_ACE);
+ ACE4_INHERIT_ONLY_ACE |
+ ACE4_INHERITED_ACE);
}
/**