summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c46
-rw-r--r--xlators/system/posix-acl/src/posix-acl.h1
2 files changed, 46 insertions, 1 deletions
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c
index 3e2f7f212..4658cad49 100644
--- a/xlators/system/posix-acl/src/posix-acl.c
+++ b/xlators/system/posix-acl/src/posix-acl.c
@@ -186,7 +186,7 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want)
ace = acl->entries;
- if (acl->count > 3)
+ if (acl->count > POSIX_ACL_MINIMAL_ACE_COUNT)
acl_present = 1;
for (i = 0; i < acl->count; i++) {
@@ -663,7 +663,12 @@ int
posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)
{
struct posix_acl_ctx *ctx = NULL;
+ struct posix_acl *acl = NULL;
+ struct posix_ace *ace = NULL;
+ struct posix_ace *mask_ce = NULL;
+ struct posix_ace *group_ce = NULL;
int ret = 0;
+ int i = 0;
ctx = posix_acl_ctx_get (inode, this);
if (!ctx) {
@@ -676,7 +681,46 @@ posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)
ctx->uid = buf->ia_uid;
ctx->gid = buf->ia_gid;
ctx->perm = st_mode_from_ia (buf->ia_prot, buf->ia_type);
+
+ acl = ctx->acl_access;
+ if (!acl || !(acl->count > POSIX_ACL_MINIMAL_ACE_COUNT))
+ goto unlock;
+
+ /* This is an extended ACL (not minimal acl). In case we
+ are only refreshing from iatt and not ACL xattrs (for
+ e.g. from postattributes of setattr() call, we need to
+ update the corresponding ACEs as well.
+ */
+ ace = acl->entries;
+ for (i = 0; i < acl->count; i++) {
+ switch (ace->tag) {
+ case POSIX_ACL_USER_OBJ:
+ ace->perm = (ctx->perm & S_IRWXU) >> 6;
+ break;
+ case POSIX_ACL_USER:
+ case POSIX_ACL_GROUP:
+ break;
+ case POSIX_ACL_GROUP_OBJ:
+ group_ce = ace;
+ break;
+ case POSIX_ACL_MASK:
+ mask_ce = ace;
+ break;
+ case POSIX_ACL_OTHER:
+ ace->perm = (ctx->perm & S_IRWXO);
+ break;
+ }
+ ace++;
+ }
+
+ if (mask_ce)
+ mask_ce->perm = (ctx->perm & S_IRWXG) >> 3;
+ else if (group_ce)
+ group_ce->perm = (ctx->perm & S_IRWXG) >> 3;
+ else
+ ret = -1;
}
+unlock:
UNLOCK(&inode->lock);
out:
return ret;
diff --git a/xlators/system/posix-acl/src/posix-acl.h b/xlators/system/posix-acl/src/posix-acl.h
index 6ac2c6a84..f85757106 100644
--- a/xlators/system/posix-acl/src/posix-acl.h
+++ b/xlators/system/posix-acl/src/posix-acl.h
@@ -17,6 +17,7 @@
#include "common-utils.h"
#include "byte-order.h"
+#define POSIX_ACL_MINIMAL_ACE_COUNT 3
#define POSIX_ACL_READ (0x04)
#define POSIX_ACL_WRITE (0x02)