]>
Commit | Line | Data |
---|---|---|
8f69975d BS |
1 | From: Andreas Gruenbacher <agruen@suse.de> |
2 | Subject: Implement those parts of Automatic Inheritance (AI) which are safe under POSIX | |
3 | ||
4 | If AI is disabled for a directory (ACL4_AUTO_INHERIT | |
5 | not set), nothing changes. If AI is enabled for a directory, the | |
6 | create-time inheritance algorithm changes as follows: | |
7 | ||
8 | * All inherited ACEs will have the ACE4_INHERITED_ACE flag set. | |
9 | ||
10 | * The create mode is applied to the ACL (by setting the file masks), | |
11 | which means that the ACL must no longer be subject to AI permission | |
12 | propagation, and so the ACL4_PROTECTED is set. | |
13 | ||
14 | By itelf, this is relatively useless because it will not allow | |
15 | permissions to propagate, but AI aware applications can clear the | |
16 | ACL4_PROTECTED flag when they know what they are doing, and this will | |
17 | enable AI permission propagation. | |
18 | ||
19 | It would be nice if AI aware applications could indicate this fact to | |
20 | the kernel so that the kernel can avoid setting the ACL4_PROTECTED flag | |
21 | in the first place, but there is no such user-space interface at this | |
22 | point. | |
23 | ||
24 | Signed-off-by: Andreas Gruenbacher <agruen@suse.de> | |
25 | ||
26 | --- | |
27 | fs/nfs4acl_base.c | 12 ++++++++++-- | |
28 | include/linux/nfs4acl.h | 26 +++++++++++++++++++++++--- | |
29 | 2 files changed, 33 insertions(+), 5 deletions(-) | |
30 | ||
31 | --- a/fs/nfs4acl_base.c | |
32 | +++ b/fs/nfs4acl_base.c | |
33 | @@ -151,7 +151,8 @@ nfs4acl_chmod(struct nfs4acl *acl, mode_ | |
34 | ||
35 | if (acl->a_owner_mask == owner_mask && | |
36 | acl->a_group_mask == group_mask && | |
37 | - acl->a_other_mask == other_mask) | |
38 | + acl->a_other_mask == other_mask && | |
39 | + (!nfs4acl_is_auto_inherit(acl) || nfs4acl_is_protected(acl))) | |
40 | return acl; | |
41 | ||
42 | clone = nfs4acl_clone(acl); | |
43 | @@ -162,6 +163,8 @@ nfs4acl_chmod(struct nfs4acl *acl, mode_ | |
44 | clone->a_owner_mask = owner_mask; | |
45 | clone->a_group_mask = group_mask; | |
46 | clone->a_other_mask = other_mask; | |
47 | + if (nfs4acl_is_auto_inherit(clone)) | |
48 | + clone->a_flags |= ACL4_PROTECTED; | |
49 | ||
50 | if (nfs4acl_write_through(&clone)) { | |
51 | nfs4acl_put(clone); | |
52 | @@ -558,7 +561,12 @@ nfs4acl_inherit(const struct nfs4acl *di | |
53 | return ERR_PTR(-ENOMEM); | |
54 | } | |
55 | ||
56 | - acl->a_flags = (dir_acl->a_flags & ACL4_WRITE_THROUGH); | |
57 | + acl->a_flags = (dir_acl->a_flags & ~ACL4_PROTECTED); | |
58 | + if (nfs4acl_is_auto_inherit(acl)) { | |
59 | + nfs4acl_for_each_entry(ace, acl) | |
60 | + ace->e_flags |= ACE4_INHERITED_ACE; | |
61 | + acl->a_flags |= ACL4_PROTECTED; | |
62 | + } | |
63 | ||
64 | return acl; | |
65 | } | |
66 | --- a/include/linux/nfs4acl.h | |
67 | +++ b/include/linux/nfs4acl.h | |
68 | @@ -32,10 +32,16 @@ struct nfs4acl { | |
69 | _ace--) | |
70 | ||
71 | /* a_flags values */ | |
72 | +#define ACL4_AUTO_INHERIT 0x01 | |
73 | +#define ACL4_PROTECTED 0x02 | |
74 | +#define ACL4_DEFAULTED 0x04 | |
75 | #define ACL4_WRITE_THROUGH 0x40 | |
76 | ||
77 | -#define ACL4_VALID_FLAGS \ | |
78 | - ACL4_WRITE_THROUGH | |
79 | +#define ACL4_VALID_FLAGS ( \ | |
80 | + ACL4_AUTO_INHERIT | \ | |
81 | + ACL4_PROTECTED | \ | |
82 | + ACL4_DEFAULTED | \ | |
83 | + ACL4_WRITE_THROUGH ) | |
84 | ||
85 | /* e_type values */ | |
86 | #define ACE4_ACCESS_ALLOWED_ACE_TYPE 0x0000 | |
87 | @@ -51,6 +57,7 @@ struct nfs4acl { | |
88 | /*#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG 0x0010*/ | |
89 | /*#define ACE4_FAILED_ACCESS_ACE_FLAG 0x0020*/ | |
90 | #define ACE4_IDENTIFIER_GROUP 0x0040 | |
91 | +#define ACE4_INHERITED_ACE 0x0080 | |
92 | #define ACE4_SPECIAL_WHO 0x4000 /* in-memory representation only */ | |
93 | ||
94 | #define ACE4_VALID_FLAGS ( \ | |
95 | @@ -58,7 +65,8 @@ struct nfs4acl { | |
96 | ACE4_DIRECTORY_INHERIT_ACE | \ | |
97 | ACE4_NO_PROPAGATE_INHERIT_ACE | \ | |
98 | ACE4_INHERIT_ONLY_ACE | \ | |
99 | - ACE4_IDENTIFIER_GROUP ) | |
100 | + ACE4_IDENTIFIER_GROUP | \ | |
101 | + ACE4_INHERITED_ACE ) | |
102 | ||
103 | /* e_mask bitflags */ | |
104 | #define ACE4_READ_DATA 0x00000001 | |
105 | @@ -128,6 +136,18 @@ extern const char nfs4ace_group_who[]; | |
106 | extern const char nfs4ace_everyone_who[]; | |
107 | ||
108 | static inline int | |
109 | +nfs4acl_is_auto_inherit(const struct nfs4acl *acl) | |
110 | +{ | |
111 | + return acl->a_flags & ACL4_AUTO_INHERIT; | |
112 | +} | |
113 | + | |
114 | +static inline int | |
115 | +nfs4acl_is_protected(const struct nfs4acl *acl) | |
116 | +{ | |
117 | + return acl->a_flags & ACL4_PROTECTED; | |
118 | +} | |
119 | + | |
120 | +static inline int | |
121 | nfs4ace_is_owner(const struct nfs4ace *ace) | |
122 | { | |
123 | return (ace->e_flags & ACE4_SPECIAL_WHO) && |