125 lines
3.8 KiB
Diff
125 lines
3.8 KiB
Diff
|
From: Andreas Gruenbacher <agruen@suse.de>
|
||
|
Subject: Implement those parts of Automatic Inheritance (AI) which are safe under POSIX
|
||
|
Patch-mainline: not yet
|
||
|
|
||
|
If AI is disabled for a directory (ACL4_AUTO_INHERIT
|
||
|
not set), nothing changes. If AI is enabled for a directory, the
|
||
|
create-time inheritance algorithm changes as follows:
|
||
|
|
||
|
* All inherited ACEs will have the ACE4_INHERITED_ACE flag set.
|
||
|
|
||
|
* The create mode is applied to the ACL (by setting the file masks),
|
||
|
which means that the ACL must no longer be subject to AI permission
|
||
|
propagation, and so the ACL4_PROTECTED is set.
|
||
|
|
||
|
By itelf, this is relatively useless because it will not allow
|
||
|
permissions to propagate, but AI aware applications can clear the
|
||
|
ACL4_PROTECTED flag when they know what they are doing, and this will
|
||
|
enable AI permission propagation.
|
||
|
|
||
|
It would be nice if AI aware applications could indicate this fact to
|
||
|
the kernel so that the kernel can avoid setting the ACL4_PROTECTED flag
|
||
|
in the first place, but there is no such user-space interface at this
|
||
|
point.
|
||
|
|
||
|
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||
|
|
||
|
---
|
||
|
fs/nfs4acl_base.c | 12 ++++++++++--
|
||
|
include/linux/nfs4acl.h | 26 +++++++++++++++++++++++---
|
||
|
2 files changed, 33 insertions(+), 5 deletions(-)
|
||
|
|
||
|
--- a/fs/nfs4acl_base.c
|
||
|
+++ b/fs/nfs4acl_base.c
|
||
|
@@ -152,7 +152,8 @@ nfs4acl_chmod(struct nfs4acl *acl, 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 &&
|
||
|
+ (!nfs4acl_is_auto_inherit(acl) || nfs4acl_is_protected(acl)))
|
||
|
return acl;
|
||
|
|
||
|
clone = nfs4acl_clone(acl);
|
||
|
@@ -163,6 +164,8 @@ nfs4acl_chmod(struct nfs4acl *acl, mode_
|
||
|
clone->a_owner_mask = owner_mask;
|
||
|
clone->a_group_mask = group_mask;
|
||
|
clone->a_other_mask = other_mask;
|
||
|
+ if (nfs4acl_is_auto_inherit(clone))
|
||
|
+ clone->a_flags |= ACL4_PROTECTED;
|
||
|
|
||
|
if (nfs4acl_write_through(&clone)) {
|
||
|
nfs4acl_put(clone);
|
||
|
@@ -559,7 +562,12 @@ nfs4acl_inherit(const struct nfs4acl *di
|
||
|
return ERR_PTR(-ENOMEM);
|
||
|
}
|
||
|
|
||
|
- acl->a_flags = (dir_acl->a_flags & ACL4_WRITE_THROUGH);
|
||
|
+ acl->a_flags = (dir_acl->a_flags & ~ACL4_PROTECTED);
|
||
|
+ if (nfs4acl_is_auto_inherit(acl)) {
|
||
|
+ nfs4acl_for_each_entry(ace, acl)
|
||
|
+ ace->e_flags |= ACE4_INHERITED_ACE;
|
||
|
+ acl->a_flags |= ACL4_PROTECTED;
|
||
|
+ }
|
||
|
|
||
|
return acl;
|
||
|
}
|
||
|
--- a/include/linux/nfs4acl.h
|
||
|
+++ b/include/linux/nfs4acl.h
|
||
|
@@ -32,10 +32,16 @@ struct nfs4acl {
|
||
|
_ace--)
|
||
|
|
||
|
/* a_flags values */
|
||
|
+#define ACL4_AUTO_INHERIT 0x01
|
||
|
+#define ACL4_PROTECTED 0x02
|
||
|
+#define ACL4_DEFAULTED 0x04
|
||
|
#define ACL4_WRITE_THROUGH 0x40
|
||
|
|
||
|
-#define ACL4_VALID_FLAGS \
|
||
|
- ACL4_WRITE_THROUGH
|
||
|
+#define ACL4_VALID_FLAGS ( \
|
||
|
+ ACL4_AUTO_INHERIT | \
|
||
|
+ ACL4_PROTECTED | \
|
||
|
+ ACL4_DEFAULTED | \
|
||
|
+ ACL4_WRITE_THROUGH )
|
||
|
|
||
|
/* e_type values */
|
||
|
#define ACE4_ACCESS_ALLOWED_ACE_TYPE 0x0000
|
||
|
@@ -51,6 +57,7 @@ struct nfs4acl {
|
||
|
/*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG 0x0010*/
|
||
|
/*#define ACE4_FAILED_ACCESS_ACE_FLAG 0x0020*/
|
||
|
#define ACE4_IDENTIFIER_GROUP 0x0040
|
||
|
+#define ACE4_INHERITED_ACE 0x0080
|
||
|
#define ACE4_SPECIAL_WHO 0x4000 /* in-memory representation only */
|
||
|
|
||
|
#define ACE4_VALID_FLAGS ( \
|
||
|
@@ -58,7 +65,8 @@ struct nfs4acl {
|
||
|
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
|
||
|
@@ -128,6 +136,18 @@ extern const char nfs4ace_group_who[];
|
||
|
extern const char nfs4ace_everyone_who[];
|
||
|
|
||
|
static inline int
|
||
|
+nfs4acl_is_auto_inherit(const struct nfs4acl *acl)
|
||
|
+{
|
||
|
+ return acl->a_flags & ACL4_AUTO_INHERIT;
|
||
|
+}
|
||
|
+
|
||
|
+static inline int
|
||
|
+nfs4acl_is_protected(const struct nfs4acl *acl)
|
||
|
+{
|
||
|
+ return acl->a_flags & ACL4_PROTECTED;
|
||
|
+}
|
||
|
+
|
||
|
+static inline int
|
||
|
nfs4ace_is_owner(const struct nfs4ace *ace)
|
||
|
{
|
||
|
return (ace->e_flags & ACE4_SPECIAL_WHO) &&
|