From ef1e66cfbf607b3b0c04cf32bff5e2dc7c32be03 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 3 Sep 2014 12:44:05 +0000 Subject: [PATCH] * setfacl.c (addmissing): New function to add missing acl entries to a modified acl per the rules set by aclcheck. (setfacl): Call addmissing unless action is Delete. --- winsup/utils/ChangeLog | 6 ++++ winsup/utils/setfacl.c | 65 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index fbea1f11f..9e0e82342 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,9 @@ +2014-09-03 Corinna Vinschen + + * setfacl.c (addmissing): New function to add missing acl entries to + a modified acl per the rules set by aclcheck. + (setfacl): Call addmissing unless action is Delete. + 2014-09-03 Corinna Vinschen * setfacl.c (getaclentry): Fix previous fix again. Allow lone 'm' as diff --git a/winsup/utils/setfacl.c b/winsup/utils/setfacl.c index 867838d73..16fa81a27 100644 --- a/winsup/utils/setfacl.c +++ b/winsup/utils/setfacl.c @@ -266,6 +266,70 @@ modacl (aclent_t *tgt, int tcnt, aclent_t *src, int scnt) return tcnt; } +int +addmissing (aclent_t *tgt, int tcnt) +{ + int t; + int types = 0, def_types = 0; + int perm = 0, def_perm = 0; + + /* Check if we have all the required entries now. */ + for (t = 0; t < tcnt; ++t) + if (tgt[t].a_type & ACL_DEFAULT) + { + def_types |= tgt[t].a_type; + if (tgt[t].a_type & (USER | GROUP | GROUP_OBJ)) + def_perm |= tgt[t].a_perm; + } + else + { + types |= tgt[t].a_type; + if (tgt[t].a_type & (USER | GROUP | GROUP_OBJ)) + perm |= tgt[t].a_perm; + } + /* Add missing CLASS_OBJ */ + if ((types & (USER | GROUP)) && !(types & CLASS_OBJ)) + { + tgt[tcnt].a_type = CLASS_OBJ; + tgt[tcnt].a_id = (uid_t) -1; + tgt[tcnt++].a_perm = perm; + } + if (def_types) + { + /* Add missing default entries. */ + if (!(def_types & USER_OBJ) && tcnt < MAX_ACL_ENTRIES) + { + t = searchace (tgt, tcnt, USER_OBJ, -1); + tgt[tcnt].a_type = DEF_USER_OBJ; + tgt[tcnt].a_id = (uid_t) -1; + tgt[tcnt++].a_perm = t >= 0 ? tgt[t].a_perm : S_IRWXO; + } + if (!(def_types & GROUP_OBJ) && tcnt < MAX_ACL_ENTRIES) + { + t = searchace (tgt, tcnt, GROUP_OBJ, -1); + tgt[tcnt].a_type = DEF_GROUP_OBJ; + tgt[tcnt].a_id = (uid_t) -1; + tgt[tcnt].a_perm = t >= 0 ? tgt[t].a_perm : (S_IROTH | S_IXOTH); + def_perm |= tgt[tcnt++].a_perm; + } + if (!(def_types & OTHER_OBJ) && tcnt < MAX_ACL_ENTRIES) + { + t = searchace (tgt, tcnt, OTHER_OBJ, -1); + tgt[tcnt].a_type = DEF_OTHER_OBJ; + tgt[tcnt].a_id = (uid_t) -1; + tgt[tcnt++].a_perm = t >= 0 ? tgt[t].a_perm : (S_IROTH | S_IXOTH); + } + /* Add missing DEF_CLASS_OBJ */ + if ((def_types & (USER | GROUP)) && !(def_types & CLASS_OBJ)) + { + tgt[tcnt].a_type = DEF_CLASS_OBJ; + tgt[tcnt].a_id = (uid_t) -1; + tgt[tcnt++].a_perm = def_perm; + } + } + return tcnt; +} + int setfacl (action_t action, char *path, aclent_t *acls, int cnt) { @@ -283,6 +347,7 @@ setfacl (action_t action, char *path, aclent_t *acls, int cnt) } else if ((lcnt = acl (path, GETACL, MAX_ACL_ENTRIES, lacl)) < 0 || (lcnt = modacl (lacl, lcnt, acls, cnt)) < 0 + || (action != Delete && (lcnt = addmissing (lacl, lcnt)) < 0) || (lcnt = acl (path, SETACL, lcnt, lacl)) < 0) { perror (prog_name);