Yesterday, Nelson Beebe tested coreutils-6.8+. I replied: > "Nelson H. F. Beebe" <[EMAIL PROTECTED]> wrote: > ... > > I have a question, however. Since 6.8 got installed, I've been > > seeing a + at the end of the permission field, e.g., on abajo: > > > > % ls -l /usr/local/share/man/man3cw/urcw4.3cw > > -rw-rw-r--+ 1 beebe wheel 1638 2007-02-26 22:57 > > /usr/local/share/man/man3cw/urcw4.3cw > > > > This is not documented in the man page for ls, but a search > > Remember that coreutils man pages are usually little more than > massaged --help output. In the real documenatation (info coreutils), > this is documented: > > Following the permission bits is a single character that specifies > whether an alternate access method applies to the file. When that > character is a space, there is no alternate access method. When it > is a printing character (e.g., `+'), then there is such a method. > > > of the source code shows that the + is attached when there > > is an ACL. The thing is, there should be no ACLs on these > > files. Here is what the ACL utility reports: > > > > % getfacl /usr/local/share/man/man3cw/urcw4.3cw > > getfacl: Removing leading '/' from absolute path names > > # file: usr/local/share/man/man3cw/urcw4.3cw > > # owner: beebe > > # group: wheel > > user::rw- > > group::rw- > > mask::rwx > > other::r-- > > I'm glad you noticed that. It is a bug. > What's changed is that now Solaris includes the "mask:" field. > Coreutils calls acl_get_file, then acl_entries > to count the entries. It used the heuristic that > more than 3 entries indicates an ACL. > Now there are always 4, even on files without an ACL. > > I hope there's an efficient way to implement has_acl, now. > We'll see. > > I see that Solaris provides the acl_trivial function, with a > const-incorrect prototype (it should be a "char const *" parameter). > > SYNOPSIS > cc [ flag... ] file... -lsec [ library... ] > #include <sys/acl.h> > > int acl_trivial(char *path); > > DESCRIPTION > The acl_trivial() function is used to determine whether a file > has a trivial ACL. Whether an ACL is trivial depends on the type > of the ACL. A POSIX draft ACL is trivial if it has greater than > MIN_ACL_ENTRIES. An NFSv4/ZFS-style ACL is trivial if it either > has entries other than owner@, group@, and everyone@, has inheri- > tance flags set, or is not ordered in a manner that meets POSIX > access control requirements. > > But that won't help non-Solaris systems that mount a ZFS file system. > > My first reflex was to just use MIN_ACL_ENTRIES in place of "3" > here, in lib/acl.c: > > ret = (3 < acl_entries (acl)); > > But it can't work. On a non-Solaris system like abajo, > the number to compare against is 3 on e.g., local ext3 file systems > but 4 on remote-mounted ZFS file systems. > > > The other peculiar thing is that when I do a "make install" > > to install the man pages from abajo, I get reports like this: > > > > cp: setting permissions for `/usr/local/man/cat3cw/ldexp.3cw': Invalid > > argument > > > > This too seems to be new with coreutils-6.8. > > This is due to the same underlying problem. > strace shows that the failing syscall is fsetxattr, with EINVAL. > cp thinks there's an ACL and is trying to preserve it.
Here's a possible solution: If the presence of the "mask:" entry is a reliable indicator that MIN_ACL_ENTRIES is 4, then we could implement something whereby for one file per distinct file system (st_dev value) we'd examine ACL entries looking for a "mask:" one, and maintain a table mapping st_dev value to the MIN_ACL_ENTRIES value for that file system. Call it pre-optimization, but somehow, I think performing all of those ACL-related syscalls and string compares for each and every file processed would be too much of a performance hit.