On the GitHub CI machines for Cygwin, I'm seeing this test failure: FAIL: test-file-has-acl-2.sh ============================
file_has_acl("tmpfile0") returned yes, expected no FAIL test-file-has-acl-2.sh (exit status: 1) The cause is that in this situation, the current directory is not under the Cygwin / directory. Thus it belongs to a different Cygwin "mount" than the Cygwin / directory. I can reproduce the issue on a local Windows machine, by building under /cygdrive/c/Users/USERNAME/build/ rather than under /home/USER. In this situation, the "trivial" ACL is not user::rwx group::r-x other::r-x but instead user::rwx group::r-x group:SYSTEM:rwx group:Administrators:rwx mask::r-x other::r-x This patch modifies the acl_access_nontrivial function to ignore group:SYSTEM:* group:Administrators:* mask::* and thus file_has_acl("tmpfile0") then returns 'no'. I'm not entirely sure whether the permissions of the three entries should be ignored. Maybe someone more familiar with ACLs can elaborate on this? 2024-06-03 Bruno Haible <br...@clisp.org> acl-permissions: Fix test-file-has-acl-2.sh failure on Cygwin. * lib/acl-internal.c: Include <sys/types.h>, <grp.h>, <string.h>. (acl_access_nontrivial): On Cygwin, ignore group:SYSTEM:*, group:Administrators:*, mask::* entries. * doc/acl-resources.txt: Add one more reference. diff --git a/doc/acl-resources.txt b/doc/acl-resources.txt index e15226d992..233ec7c54e 100644 --- a/doc/acl-resources.txt +++ b/doc/acl-resources.txt @@ -7,6 +7,9 @@ POSIX ACLs Documents from POSIX.1e (headers & functions) and POSIX.2c (utilities): http://wt.tuxomania.net/publications/posix.1e/download.html +Explanation of mask: + https://unix.stackexchange.com/questions/475698/ + Linux ACLs diff --git a/lib/acl-internal.c b/lib/acl-internal.c index 68aead8de6..9ebb6e544b 100644 --- a/lib/acl-internal.c +++ b/lib/acl-internal.c @@ -23,6 +23,12 @@ #include "acl-internal.h" +#if defined __CYGWIN__ +# include <sys/types.h> +# include <grp.h> +# include <string.h> +#endif + #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ @@ -63,8 +69,58 @@ acl_access_nontrivial (acl_t acl) acl_tag_t tag; if (acl_get_tag_type (ace, &tag) < 0) return -1; - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) - return 1; + switch (tag) + { + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_OTHER: + break; +# ifdef __CYGWIN__ + /* On Cygwin, a trivial ACL inside the Cygwin file system consists of + e.g. + user::rwx + group::r-x + other::r-x + but a trivial ACL outside the Cygwin file system has more entries: + e.g. + user::rwx + group::r-x + group:SYSTEM:rwx + group:Administrators:rwx + mask::r-x + other::r-x + */ + case ACL_GROUP: + { + int ignorable = 0; + void *qualifier = acl_get_qualifier (ace); + if (qualifier != NULL) + { + gid_t group_id = *(gid_t const *) qualifier; + acl_free (qualifier); + struct group *group_details = getgrgid (group_id); + if (group_details != NULL) + { + const char *group_sid = group_details->gr_passwd; + /* Ignore the ace if the group_sid is one of + - S-1-5-18 (group "SYSTEM") + - S-1-5-32-544 (group "Administrators") + Cf. <https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids> */ + ignorable = (strcmp (group_sid, "S-1-5-18") == 0 + || strcmp (group_sid, "S-1-5-32-544") == 0); + } + } + if (!ignorable) + return 1; + } + break; + case ACL_MASK: + /* XXX Is it OK to ignore acl_get_permset (ace, ...) ? */ + break; +# endif + default: + return 1; + } } return got_one;