Subject: bug#20681: Build failure [MSYS2/MINGW64, OSX]

From: Eli Zaretskii <[email-masked]>
Date: Mon, 01 Jun 2015 18:05:07 +0300

> Date: Sun, 31 May 2015 21:18:37 +0200
> From: Andreas Grünbacher <[email-masked]>
> Cc: Nick Andryshak <[email-masked]>, [email-masked], 
> 	Paul Eggert <[email-masked]>, Angelo Graziosi <[email-masked]>
> 
> > Emacs built with MinGW has the same functionality on Windows as Emacs
> > does on Posix hosts: get a file's ACL as a text string, set a file's
> > ACL from text string description, and copy ACL from one file to
> > another.
> >
> > The relevant functions, acl_get_file, acl_set_file, acl_to_text,
> > acl_from_text, and acl_free are implemented as part of Emacs.
> 
> So those are the functions that gnulib is seeing? If so, then emacs
> could provide
> acl_delete_def_file as well, and everything will be fine again.

Everything is fine already: I removed set-permissions.c from the MinGW
build.

While acl_delete_def_file could be added, it would be a stub that
always fails, so I see no point in doing that, as long as Gnulib ACL
code is effectively ignored on Windows.

> But shouldn't Windows ACL support be added to get_permissions() and
> set_permissions() proper instead of emulating Windows ACL support through
> the POSIX draft ACL interface? The _to_text() and _from_text() functions
> could be modified to take a struct permission_context argument; they could
> be moved into gnulib or remain part of emacs.

What would be the benefit of doing that, though?  You will see in the
Emacs sources that currently acl_to_text produces the Windows-specific
SDDL string representation of the file's DACL security descriptor;
making that Posix-compliant in order for those functions to be able to
work with the likes of acl_from_mode is an extremely non-trivial and
thankless job.

> As a side effect of that, cp in coreutils would then also do the right thing on
> Windows (if someone made coreutils build there again).

If cp just copies the ACLs, it doesn't need all this machinery.  It
just need to handle ACLs as an opaque object understood only by
acl_get_file and acl_set_file.

> > E.g., why not do something like the following instead:
> >
> >   #    ifndef HAVE_ACL_DELETE_DEF_FILE
> >                     ret = -1;
> >                     errno = ENOSYS;
> >   #    else
> >                     ret = acl_delete_def_file (name);
> >
> >   #    endif
> 
> Nope, the call is really needed.

I believe you, but I still don't understand why this couldn't support
systems that don't have the notion of default ACL, or don't need to
remove it when the file in question is actually a directory.

You might have in mind Posix platforms that adhere to the relevant
Posix draft, in which case it's exactly my point: this code makes it
harder for non-Posix platforms to support these routines when it's
easy to emulate acl_get_file and acl_set_file, but supporting addition
or removal of the default ACL is hard or ineffective/pointless.

> > More generally, copying ACLs from one file to another does not need
> > any analysis of what's in the ACLs being copied: it could simply treat
> > the ACLs as an opaque object, something whose structure and semantics
> > are known only to the innards of acl_get_file and acl_set_file.  So
> > building qcopy_acl on top of get_permissions and set_permissions,
> > which are more flexible, and do require that knowledge, is IMO
> > fundamentally wrong, as it makes much harder to port this simple and
> > important Gnulib function to other platforms.
> 
> I disagree. Have a look at struct permission_context; acl_get_file() and
> acl_set_file() is part of the POSIX draft ACL API but other platforms
> have totally different data structures and interfaces. Windows ACLs
> should be implemented as another kind of ACLs, not disguised as
> POSIX ACLs.

See above: doing so is of course possible, but it's a lot of hassle
for very little, if any, benefits.  It is very easy to provide on
MS-Windows the minimum emulation of Posix interfaces that allows to
(a) copy ACLs from one file to another and (b) convert ACLs to and
from text representation for human consumption or for logging.  That's
all Emacs needs, and that's all most other programs will ever need.
Adding anything else to the soup raises the bar much higher, because
the semantics of Windows ACLs is very different.  For starters, where
Posix platforms have 3 rwx access bits, on Windows there are 7
standard access rights; mapping those 7 to the 3 Posix bits will at
best seriously limit what Windows programs can do with ACLs.  And then
there are the issues with the ordering of ACEs in an ACL, with
implicit access rights via group membership, etc. etc.

So I think the depth of compliance which is expected by
set-permissions.c is too much for Windows, way beyond the proverbial
80-20 point.

There's also the minor (but important for Emacs) point of supporting
file names with characters outside of the current system codepage,
which Gnulib can only provide in UTF-8 locales, something that doesn't
exist on Windows.

> > After all, copying ACLs from one file to another is much more frequent
> > and important an operation than setting ACLs from user-specified
> > arguments.
> 
> Probably, yes.
> 
> > What's more, the assumption that if acl_get_file and acl_set_file are
> > available, then so should be acl_delete_def_file is yet another
> > obstacle, IMO gratuitous one.
> 
> No, acl_get_file, acl_set_file, and acl_delete_def_file are all part of the
> POSIX ACL API, and acl_delete_def_file is needed for directories.

For Posix platforms, yes.  I was thinking about non-Posix ones, where
there's no such necessary linkage.

> >> If it has acl_get_file and acl_set_file, where can I find
> >> documentation about what those functions do on MinGW?
> >
> > They do what you'd expect, but support only ACL_TYPE_ACCESS.  They
> > know about ACL_TYPE_DEFAULT, but always return EINVAL for it, since
> > it's next to impossible (and not recommended) to have a directory on
> > Windows which has no default ACLs associated with it.
> >
> > You can see their sources in src/w32.c in the Emacs repository.
> 
> That's just wrong. Windows ACLs can contain effective as well as inheritable
> permissions; the split between types as with POSIX ACLs doesn't exist.

Not sure what you are saying here: which part of what I wrote is
"wrong", exactly?

If what you mean is that ACL_TYPE_ACCESS could or should include the
inheritance flags, then that's what is currently implemented in Emacs,
but reporting or adding/removing those flags is not supported.  IMO, a
general-purpose program such as Emacs should not futz with the
inheritance flags in Windows ACLs, because doing so makes it very easy
to inadvertently make directories and files inaccessible or exempt
from important operations like system-wide backup.  Fortunately, Emacs
doesn't need these capabilities, at least not explicitly on the
acl_get_file and acl_set_file level.

Once again, please don't take the above as some objection to your
work, or request to make any changes for MinGW.  They are just
observations of a bystander at this point.

Thanks.