Subject: bug#17669: Solaris acl woes

From: Ben Walton <[email-masked]>
Date: Mon, 2 Jun 2014 13:38:29 +0100

Hi All,

I've hit a "bug" in the coreutils test suite when exercising acl code
from gnulib. I'm cross-posting to both lists, I hope that's ok.
(Please apply the cluebat gently if not...)

When running tests involving cp -a (in /tmp for this example), I see
errors like:

+ cp -a --parents d/a/b/c e
cp: preserving permissions for 'e/d/a/b/c': Operation not applicable
cp: preserving permissions for 'e/d/a/b': Operation not applicable
+ fail=1
+ cp -a --parents sym/b/c g
cp: preserving permissions for 'g/sym/b/c': Operation not applicable
cp: preserving permissions for 'g/sym/b': Operation not applicable

The code that results in this error in in lib/qcopy-acl.c:
# ifdef ACE_GETACL
  if (ace_count > 0)
    {
      ret = (dest_desc != -1
             ? facl (dest_desc, ACE_SETACL, ace_count, ace_entries)
             : acl (dst_name, ACE_SETACL, ace_count, ace_entries));
      if (ret < 0 && saved_errno == 0)
        {
          saved_errno = errno;
          if ((errno == ENOSYS || errno == EINVAL || errno == ENOTSUP)
              && !acl_ace_nontrivial (ace_count, ace_entries))
            saved_errno = 0;
        }
    }
  free (ace_entries);
# endif

The error returned is ENOSYS, but acl_ace_nontrivial fires and thus
the saved_errno isn't reset to 0.

The lib/file-has-acl.c:acl_ace_nontrivial code that returns 1 is:
      switch ((access_masks[0] | access_masks[1])
              & ~(NEW_ACE_READ_NAMED_ATTRS
                  | NEW_ACE_READ_ATTRIBUTES
                  | NEW_ACE_READ_ACL
                  | NEW_ACE_SYNCHRONIZE))
        {
        case 0:
        case NEW_ACE_READ_DATA:
        case                     NEW_ACE_WRITEA_DATA:
        case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
        case                                           NEW_ACE_EXECUTE:
        case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
        case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
        case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
          break;
        default:
          return 1;
        }

It seems as though the $getacl calls succeed but $setacl calls fail.
We are able to retrieve what we consider complex acl information but
cannot subsequently set it.

You can see similar behaviour by doing:

$ pwd
/tmp/coreutils-8.22

$ getfacl README

# file: README
# owner: bwalton
# group: csw
user::rw-
group::r--              #effective:r--
mask:rwx
other:r--

$ getfacl README | setfacl -f - README
README: failed to set acl entries
setacl error: Operation not applicable

Other than this issue, which affects 6 tests identically, all tests pass.

I'm not sure what the best way to fix this is. I'm happy to supply
complete test logs if they'd help and will run any commands/gather any
additional info you need.

(Note: I'm only running this in /tmp to isolate some other issues that
seem to be nfs related - I'll report on those separately when I've
debugged far enough to provide something useful.)

Thanks
-Ben
-- 
---------------------------------------------------------------------------------------------------------------------------
Take the risk of thinking for yourself.  Much more happiness,
truth, beauty and wisdom will come to you that way.

-Christopher Hitchens
---------------------------------------------------------------------------------------------------------------------------