Setfacl mask management and executability
Matt McCutchen <[email protected]> Thu, 09 Mar 2006 18:19:46 -0500
| Newsgroups | gmane.linux.file-systems.acl.devel |
|---|---|
| Message-ID | <1141946386.2911.66.camel@mattlaptop> |
Dear ACL developers,
I use POSIX ACLs extensively on my system and on my school's server.
Mask entries seem to have two purposes: they set an upper bound on all
ACL-granted permissions to satisfy checks by programs such as qmail, and
they let a 0666 mode passed to open turn off executability for everyone
when a default ACL is inherited as an access ACL.
Setfacl's behavior of automatically recomputing mask entries when
mask-controlled entries change is great for the first purpose, but I
think it could use some tuning to handle executability better. I am a
perfectionist, so if I use setfacl to configure an existing ACL-free
directory containing a mix of executable and nonexecutable files with
access and default ACLs, I want the setfacl-ed files to look the same as
newly created files. That means I want mask-controlled entries on
setfacl-ed files that grant "r" to also grant "x", but I want the mask
entry set to block the "x".
With setfacl as it is now, I have to do the mask entry by hand because
there's no way to make it add rw- masks for some files and rwx masks for
others. Furthermore, if I grant a new user access to the directory (by
adding an entry "rwx" for that user to every ACL), I must remember to
tell setfacl not to recalculate the mask or it would turn on
executability.
A while ago, someone suggested a "setfacl -R -m g:users:rwX *" syntax,
and I think that's the right idea. Specifying a mask-controlled entry
with X should turn on x in that entry but should not cause x to be
turned on in the mask. (And this is mnemonic because getfacl --tabular
will list the g:users entry as rwX!) Specifying a non-mask-controlled
entry (or the mask itself) with X should turn x on if at least one x was
on beforehand, which is the same behavior as chmod.
There's another issue with mask recalculation. It makes sense for
setfacl to loosen a mask if it has been told to enable permissions that
the mask would otherwise block, but I don't think setfacl should loosen
the mask to accommodate existing mask-controlled permissions. If I set
a file up with ACL "u::rwx,g::rwx,m::---,o::---", then "setfacl -m
u::rw- file" will loosen the mask even though the entry I told it to
modify is not even mask-controlled.
There's yet another issue. Setfacl might need to loosen the mask to
accommodate a request to enable a permission in a mask-controlled entry,
but loosening the mask might also allow other permissions in
mask-controlled entries to unexpectedly take effect, breaking security.
Suppose I set up a file with "u::rwx,u:enemy:rwx,g::---,m::---,o::---"
and then run "setfacl -m u:friend:rwx file"; the enemy will gain access.
To stop this from happening, I think setfacl should knock out a
permission from mask-controlled entries it isn't changing before
enabling the permission in the mask.
In summary, I believe that the behavior of --mask (which is the default)
should be expanded from "update the mask entry" to "manage the mask
entry automatically by doing what the user probably expects". I propose
the following algorithm for "setfacl -m" when the --mask behavior is in
use. A mask management algorithm can adhere to one of two principles:
change as little as possible ("canonicalizing" only as much as is
appropriate given the requested changes) or "canonicalize" as much as
possible. My algorithm changes as little as possible.
(1) Apply changes to the user-owner and other entries, if any. Consider
"X" to be "x" if at least one existing permission-bit entry grants "x",
"-" otherwise (just like chmod).
(2) If the existing ACL has no mask and the -m entries include no named
user or named group entries, update the group-owner entry if requested
and stop. Again, consider "X" to be "x" if at least one existing
permission-bit entry grants "x", "-" otherwise.
(3) If the existing ACL has no mask, introduce a mask as follows. If
the -m entries contain a group-owner entry, drop the existing
group-owner entry and create a mask of "---". (This will be fixed
later.) Otherwise, create a mask equal to the group-owner entry, and
add "x" permission to the group-owner entry if the group-owner entry
already has "r" permission. (Compare to rsync's new --executability
option, whose behavior I designed: man page at
http://rsync.samba.org/ftp/rsync/nightly/rsync.html .)
(4) Find the union of the permissions in all the mask-controlled -m
entries; consider "X" to be "-" for this purpose. If there are
permissions in this union that are not in the current mask, enable those
permissions in the mask and disable them in all mask-controlled entries.
(5) Merge the mask-controlled -m entries into the ACL. Compare the
union of all mask-controlled ACL entries before and after the merge; if
any permissions dropped out of the union, drop them from the mask.
The only mask management change to -x that I propose is the following:
if the last named user or named group entry is deleted, replace the
group-owner and mask entries with a group-owner entry containing the
intersection of the permissions.
The mask-management rules should be the same for default ACLs except
that executability is not yet determined, so X should be equivalent to x
in all situations and the executability tweak in step 3 should be
skipped.
I might try to implement all of this and send a patch. Thanks for
considering my proposals.
--
Matt McCutchen
[email protected]
http://hashproduct.metaesthetics.net/
_______________________________________________
acl-devel mailing list
[email protected]
http://acl.bestbits.at/mailman/listinfo/acl-devel