@@ -353,7 +353,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_other_mask == other_mask &&
+ (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl)))
return acl;
clone = richacl_clone(acl);
@@ -364,6 +365,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;
}
@@ -521,6 +524,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;
}
@@ -212,9 +212,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,6 +47,15 @@ struct richacl {
_ace != _acl->a_entries - 1; \
_ace--)
+/* a_flags values */
+#define ACL4_AUTO_INHERIT 0x01
+#define ACL4_PROTECTED 0x02
+/*#define ACL4_DEFAULTED 0x04*/
+
+#define ACL4_VALID_FLAGS ( \
+ ACL4_AUTO_INHERIT | \
+ ACL4_PROTECTED)
+
/* e_type values */
#define ACE4_ACCESS_ALLOWED_ACE_TYPE 0x0000
#define ACE4_ACCESS_DENIED_ACE_TYPE 0x0001
@@ -61,6 +70,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
@@ -69,7 +79,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
@@ -162,6 +173,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.
@@ -240,7 +263,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);
}
/**