bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

acls on HP-UX


From: Bruno Haible
Subject: acls on HP-UX
Date: Mon, 13 Jun 2011 02:12:19 +0200
User-agent: KMail/1.9.9

On HP-UX 11.11 and newer, I'm seeing these test failures:

  file_has_acl("tmpfile0") returned no, expected yes
  FAIL: test-file-has-acl.sh

  FAIL: test-copy-acl.sh
  FAIL: test-copy-file.sh

It turns out that the support for HP-UX ACLs that I added on 2008-06-08
<http://lists.gnu.org/archive/html/bug-gnulib/2008-06/msg00127.html> was only
complete for HP-UX 11.00.

HP-UX 11.11 and newer has a new API, declared in <aclv.h>. And it's not
just a different API to read the same information in a different way. No.
It's a different API to read different kinds of ACLs that occur on different
file systems. So, on these systems, you have to try both APIs.

The same situation exists on the command-line: The programs 'lsacl' and 'chacl'
work only for the older kind of ACLs, and the new programs 'getacl' and
'setacl' work only for the newer kind of ACLs. Really, I wouldn't want to be
a sysadmin of HP-UX machines...

An additional quirk is that uses of the new API do not behave according to
its documentation:
  - In order to retrieve the number of ACLs set on a file, using a command
    ACL_CNT explicitly designed for this purpose, you have to pass a buffer.
    The buffer is not touched, but you cannot pass a NULL pointer.
  - On NFS the system call yields errno = EOPNOTSUPP, as documented, for
    HP-UX 11.11 and 11.23. But on HP-UX 11.31, the result is EINVAL.

This patch fixes it all. Tested on all 4 versions of HP-UX 11, both in /tmp
and on an NFS mounted file system.


2011-06-12  Bruno Haible  <address@hidden>

        acl: Add support for HP-UX >= 11.11 JFS ACLs.
        * doc/acl-resources.txt: Add info about the ACL APIs on HP-UX.
        * m4/acl.m4 (gl_FUNC_ACL): Also test for HP-UX 11.11 API.
        * lib/acl-internal.h [HP-UX 11.11]: Include <aclv.h>.
        (acl, aclsort): New declarations.
        (aclv_nontrivial): New declaration.
        * lib/file-has-acl.c (aclv_nontrivial) [HP-UX 11.11]: New function.
        (file_has_acl): Read also the second kind of HP-UX ACLs.
        * lib/set-mode-acl.c (qset_acl) [HP-UX 11.11]: Try to set the second
        kind of HP-UX ACLs if the first kind fails.
        * lib/copy-acl.c (qcopy_acl) [HP-UX 11.11]: Read and set also the
        second kind of HP-UX ACLs.
        * tests/test-sameacls.c [HP-UX 11.11]: Include <aclv.h>.
        (main) [HP-UX 11.11]: Test also whether the second kind of HP-UX ACLs
        agree.
        * tests/test-file-has-acl.sh (acl_flavor) [HP-UX 11.11]: Set to
        hpuxjfs.
        Handle hpuxjfs.
        * tests/test-set-mode-acl.sh (acl_flavor) [HP-UX 11.11]: Set to
        hpuxjfs.
        Handle hpuxjfs.
        * tests/test-copy-acl.sh (acl_flavor) [HP-UX 11.11]: Set to hpuxjfs.
        (func_test_same_acls): Use both lsacl and getacl.
        Handle hpuxjfs.
        * tests/test-copy-file.sh (acl_flavor) [HP-UX 11.11]: Set to hpuxjfs.
        (func_test_same_acls): Use both lsacl and getacl.
        Handle hpuxjfs.

--- doc/acl-resources.txt.orig  Mon Jun 13 01:32:47 2011
+++ doc/acl-resources.txt       Mon Jun 13 01:22:02 2011
@@ -243,15 +243,16 @@
   chmod
 
 
-HP-UX ACLs
+HP-UX 11.00 ACLs
 
+Present in HP-UX >= 11.00. On some machines, yields ENOSYS always.
 Manual pages:
-  http://docs.hp.com/en/B2355-60105/acl.2.html
-  http://docs.hp.com/en/B2355-60105/lsacl.1.html
-  http://docs.hp.com/en/B2355-60105/chacl.1.html
-  http://docs.hp.com/en/B2355-60105/getacl.1.html
+  getacl, fgetacl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02261503/c02261503.pdf
+  setacl, fsetacl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02267386/c02267386.pdf
+  lsacl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02261049/c02261049.pdf
+  chacl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c01921575/c01921575.pdf 
p. 125
 Includes:
-  <acl.h> or <sys/acl.h>, optionally <aclv.h>
+  <acl.h> or <sys/acl.h>
 Library:
   none needed
 Functions:
@@ -259,14 +260,31 @@
   fgetacl
   fsetacl
   setacl
-Functions only declared in <aclv.h>:
-  acl
 Utilities:
   lsacl
   chacl
+  chmod
+
+
+HP-UX 11.11 ACLs
+
+Present in HP-UX >= 11.11.
+Manual pages:
+  acl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02254861/c02254861.pdf
+  acl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c01921366/c01921366.pdf 
p. 27
+  aclsort: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02254876/c02254876.pdf
+  getacl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02261501/c02261501.pdf
+  setacl: 
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02267385/c02267385.pdf
+Includes:
+  <aclv.h>
+Library:
+  none needed
+Functions:
+  acl
+  aclsort
+Utilities:
   getacl
   setacl
-  chmod
 
 
 IRIX ACLs
--- lib/acl-internal.h.orig     Mon Jun 13 01:32:47 2011
+++ lib/acl-internal.h  Mon Jun 13 01:22:02 2011
@@ -35,6 +35,15 @@
 # include <acl/libacl.h>
 #endif
 
+/* On HP-UX >= 11.11, additional ACL API is available in <aclv.h>.  */
+#if HAVE_ACLV_H
+# include <sys/types.h>
+# include <aclv.h>
+/* HP-UX 11.11 lacks these declarations.  */
+extern int acl (char *, int, int, struct acl *);
+extern int aclsort (int, int, struct acl *);
+#endif
+
 #include "error.h"
 #include "quote.h"
 
@@ -206,6 +215,14 @@
    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
 extern int acl_nontrivial (int count, struct acl_entry *entries, struct stat 
*sb);
 
+#  if HAVE_ACLV_H /* HP-UX >= 11.11 */
+
+/* Return 1 if the given ACL is non-trivial.
+   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
+extern int aclv_nontrivial (int count, struct acl *entries);
+
+#  endif
+
 # elif HAVE_ACLX_GET && 0 /* AIX */
 
 /* TODO */
--- lib/copy-acl.c.orig Mon Jun 13 01:32:47 2011
+++ lib/copy-acl.c      Mon Jun 13 01:31:37 2011
@@ -410,6 +410,12 @@
 
   int count;
   struct acl_entry entries[NACLENTRIES];
+# if HAVE_ACLV_H
+  int aclv_count;
+  struct acl aclv_entries[NACLVENTRIES];
+# endif
+  int did_chmod;
+  int saved_errno;
   int ret;
 
   for (;;)
@@ -445,42 +451,107 @@
          Repeat.  */
     }
 
-  if (count == 0)
-    return qset_acl (dst_name, dest_desc, mode);
-
-  ret = (dest_desc != -1
-         ? fsetacl (dest_desc, count, entries)
-         : setacl (dst_name, count, entries));
-  if (ret < 0)
+# if HAVE_ACLV_H
+  for (;;)
     {
-      int saved_errno = errno;
+      aclv_count = acl ((char *) src_name, ACL_CNT, NACLVENTRIES, 
aclv_entries);
 
-      if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
+      if (aclv_count < 0)
         {
-          struct stat source_statbuf;
-
-          if ((source_desc != -1
-               ? fstat (source_desc, &source_statbuf)
-               : stat (src_name, &source_statbuf)) == 0)
+          if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
             {
-              if (!acl_nontrivial (count, entries, &source_statbuf))
-                return chmod_or_fchmod (dst_name, dest_desc, mode);
+              count = 0;
+              break;
             }
           else
-            saved_errno = errno;
+            return -2;
         }
 
-      chmod_or_fchmod (dst_name, dest_desc, mode);
-      errno = saved_errno;
-      return -1;
+      if (aclv_count == 0)
+        break;
+
+      if (aclv_count > NACLVENTRIES)
+        /* If NACLVENTRIES cannot be trusted, use dynamic memory allocation.  
*/
+        abort ();
+
+      if (acl ((char *) src_name, ACL_GET, aclv_count, aclv_entries)
+          == aclv_count)
+        break;
+      /* Huh? The number of ACL entries changed since the last call.
+         Repeat.  */
+    }
+# endif
+
+  if (count == 0)
+# if HAVE_ACLV_H
+    if (aclv_count == 0)
+# endif
+      return qset_acl (dst_name, dest_desc, mode);
+
+  did_chmod = 0; /* set to 1 once the mode bits in 0777 have been set */
+  saved_errno = 0; /* the first non-ignorable error code */
+
+  if (count > 0)
+    {
+      ret = (dest_desc != -1
+             ? fsetacl (dest_desc, count, entries)
+             : setacl (dst_name, count, entries));
+      if (ret < 0 && saved_errno == 0)
+        {
+          saved_errno = errno;
+          if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
+            {
+              struct stat source_statbuf;
+
+              if ((source_desc != -1
+                   ? fstat (source_desc, &source_statbuf)
+                   : stat (src_name, &source_statbuf)) == 0)
+                {
+                  if (!acl_nontrivial (count, entries, &source_statbuf))
+                    saved_errno = 0;
+                }
+              else
+                saved_errno = errno;
+            }
+        }
+      else
+        did_chmod = 1;
+    }
+
+# if HAVE_ACLV_H
+  if (aclv_count > 0)
+    {
+      ret = acl ((char *) dst_name, ACL_SET, aclv_count, aclv_entries);
+      if (ret < 0 && saved_errno == 0)
+        {
+          saved_errno = errno;
+          if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
+            {
+              if (!aclv_nontrivial (aclv_count, aclv_entries))
+                saved_errno = 0;
+            }
+        }
+      else
+        did_chmod = 1;
     }
+# endif
 
-  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+  if (did_chmod <= ((mode & (S_ISUID | S_ISGID | S_ISVTX)) ? 1 : 0))
     {
-      /* We did not call chmod so far, and either the mode and the ACL are
-         separate or special bits are to be set which don't fit into ACLs.  */
+      /* We did not call chmod so far, and special bits are to be set which
+         don't fit into ACLs.  */
 
-      return chmod_or_fchmod (dst_name, dest_desc, mode);
+      if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
+        {
+          if (saved_errno == 0)
+            saved_errno = errno;
+        }
+    }
+
+  if (saved_errno)
+    {
+      errno = saved_errno;
+      return -1;
     }
   return 0;
 
--- lib/file-has-acl.c.orig     Mon Jun 13 01:32:47 2011
+++ lib/file-has-acl.c  Mon Jun 13 01:25:05 2011
@@ -234,6 +234,33 @@
   return 0;
 }
 
+# if HAVE_ACLV_H /* HP-UX >= 11.11 */
+
+/* Return 1 if the given ACL is non-trivial.
+   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
+int
+aclv_nontrivial (int count, struct acl *entries)
+{
+  int i;
+
+  for (i = 0; i < count; i++)
+    {
+      struct acl *ace = &entries[i];
+
+      /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
+         If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
+         We don't need to check ace->a_id in these cases.  */
+      if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
+            || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
+            || ace->a_type == CLASS_OBJ
+            || ace->a_type == OTHER_OBJ))
+        return 1;
+    }
+  return 0;
+}
+
+# endif
+
 #elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */
 
 /* Return 1 if the given ACL is non-trivial.
@@ -519,11 +546,11 @@
 
 # elif HAVE_GETACL /* HP-UX */
 
-      int count;
-      struct acl_entry entries[NACLENTRIES];
-
       for (;;)
         {
+          int count;
+          struct acl_entry entries[NACLENTRIES];
+
           count = getacl (name, 0, NULL);
 
           if (count < 0)
@@ -532,7 +559,7 @@
                  EOPNOTSUPP is typically seen on NFS mounts.
                  ENOTSUP was seen on Quantum StorNext file systems (cvfs).  */
               if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
-                return 0;
+                break;
               else
                 return -1;
             }
@@ -563,6 +590,46 @@
              Repeat.  */
         }
 
+#  if HAVE_ACLV_H /* HP-UX >= 11.11 */
+
+      for (;;)
+        {
+          int count;
+          struct acl entries[NACLVENTRIES];
+
+          count = acl ((char *) name, ACL_CNT, NACLVENTRIES, entries);
+
+          if (count < 0)
+            {
+              /* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
+                 EINVAL is seen on NFS in HP-UX 11.31.  */
+              if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
+                break;
+              else
+                return -1;
+            }
+
+          if (count == 0)
+            return 0;
+
+          if (count > NACLVENTRIES)
+            /* If NACLVENTRIES cannot be trusted, use dynamic memory
+               allocation.  */
+            abort ();
+
+          /* If there are more than 4 entries, there cannot be only the
+             four base ACL entries.  */
+          if (count > 4)
+            return 1;
+
+          if (acl ((char *) name, ACL_GET, count, entries) == count)
+            return aclv_nontrivial (count, entries);
+          /* Huh? The number of ACL entries changed since the last call.
+             Repeat.  */
+        }
+
+#  endif
+
 # elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */
 
       acl_type_t type;
--- lib/set-mode-acl.c.orig     Mon Jun 13 01:32:47 2011
+++ lib/set-mode-acl.c  Mon Jun 13 01:28:21 2011
@@ -406,7 +406,6 @@
 # elif HAVE_GETACL /* HP-UX */
 
   struct stat statbuf;
-  struct acl_entry entries[3];
   int ret;
 
   if (desc != -1)
@@ -416,25 +415,68 @@
   if (ret < 0)
     return -1;
 
-  entries[0].uid = statbuf.st_uid;
-  entries[0].gid = ACL_NSGROUP;
-  entries[0].mode = (mode >> 6) & 7;
-  entries[1].uid = ACL_NSUSER;
-  entries[1].gid = statbuf.st_gid;
-  entries[1].mode = (mode >> 3) & 7;
-  entries[2].uid = ACL_NSUSER;
-  entries[2].gid = ACL_NSGROUP;
-  entries[2].mode = mode & 7;
+  {
+    struct acl_entry entries[3];
 
-  if (desc != -1)
-    ret = fsetacl (desc, sizeof (entries) / sizeof (struct acl_entry), 
entries);
-  else
-    ret = setacl (name, sizeof (entries) / sizeof (struct acl_entry), entries);
+    entries[0].uid = statbuf.st_uid;
+    entries[0].gid = ACL_NSGROUP;
+    entries[0].mode = (mode >> 6) & 7;
+    entries[1].uid = ACL_NSUSER;
+    entries[1].gid = statbuf.st_gid;
+    entries[1].mode = (mode >> 3) & 7;
+    entries[2].uid = ACL_NSUSER;
+    entries[2].gid = ACL_NSGROUP;
+    entries[2].mode = mode & 7;
+
+    if (desc != -1)
+      ret = fsetacl (desc, sizeof (entries) / sizeof (struct acl_entry), 
entries);
+    else
+      ret = setacl (name, sizeof (entries) / sizeof (struct acl_entry), 
entries);
+  }
   if (ret < 0)
     {
-      if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
-        return chmod_or_fchmod (name, desc, mode);
-      return -1;
+      if (!(errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
+        return -1;
+
+#  if HAVE_ACLV_H /* HP-UX >= 11.11 */
+      {
+        struct acl entries[4];
+
+        entries[0].a_type = USER_OBJ;
+        entries[0].a_id = 0; /* irrelevant */
+        entries[0].a_perm = (mode >> 6) & 7;
+        entries[1].a_type = GROUP_OBJ;
+        entries[1].a_id = 0; /* irrelevant */
+        entries[1].a_perm = (mode >> 3) & 7;
+        entries[2].a_type = CLASS_OBJ;
+        entries[2].a_id = 0;
+        entries[2].a_perm = (mode >> 3) & 7;
+        entries[3].a_type = OTHER_OBJ;
+        entries[3].a_id = 0;
+        entries[3].a_perm = mode & 7;
+
+        ret = aclsort (sizeof (entries) / sizeof (struct acl), 1, entries);
+        if (ret > 0)
+          abort ();
+        if (ret < 0)
+          {
+            if (0)
+              return chmod_or_fchmod (name, desc, mode);
+            return -1;
+          }
+
+        ret = acl ((char *) name, ACL_SET,
+                   sizeof (entries) / sizeof (struct acl), entries);
+        if (ret < 0)
+          {
+            if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
+              return chmod_or_fchmod (name, desc, mode);
+            return -1;
+          }
+      }
+#  else
+      return chmod_or_fchmod (name, desc, mode);
+#  endif
     }
 
   if (mode & (S_ISUID | S_ISGID | S_ISVTX))
--- m4/acl.m4.orig      Mon Jun 13 01:32:47 2011
+++ m4/acl.m4   Mon Jun 13 01:22:02 2011
@@ -1,5 +1,5 @@
 # acl.m4 - check for access control list (ACL) primitives
-# serial 12
+# serial 13
 
 # Copyright (C) 2002, 2004-2011 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -94,6 +94,8 @@
         if test $ac_cv_func_getacl = yes; then
           use_acl=1
         fi
+        dnl Test for HP-UX 11.11 API.
+        AC_CHECK_HEADERS([aclv.h], [], [], [#include <sys/types.h>])
       fi
 
       dnl Test for AIX API (AIX 5.3 or newer).
--- tests/test-copy-acl.sh.orig Mon Jun 13 01:32:47 2011
+++ tests/test-copy-acl.sh      Mon Jun 13 01:22:02 2011
@@ -60,7 +60,7 @@
   # Classification of the platform according to the programs available for
   # manipulating ACLs.
   # Possible values are:
-  #   linux, cygwin, freebsd, solaris, hpux, osf1, aix, macosx, irix, none.
+  #   linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, 
none.
   # TODO: Support also native Win32 platforms (mingw).
   acl_flavor=none
   if (getfacl tmpfile0 >/dev/null) 2>/dev/null; then
@@ -88,7 +88,13 @@
     if (lsacl / >/dev/null) 2>/dev/null; then
       # Platforms with the lsacl and chacl programs.
       # HP-UX, sometimes also IRIX.
-      acl_flavor=hpux
+      if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
+        # HP-UX 11.11 or newer.
+        acl_flavor=hpuxjfs
+      else
+        # HP-UX 11.00.
+        acl_flavor=hpux
+      fi
     else
       if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
         # Tru64, NonStop Kernel.
@@ -138,6 +144,19 @@
         cmp tmpaclout1 tmpaclout2 > /dev/null
       }
       ;;
+    hpuxjfs)
+      func_test_same_acls ()
+      {
+        { lsacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
+          lsacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
+          cmp tmpaclout1 tmpaclout2 > /dev/null
+        } &&
+        { getacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
+          getacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
+          cmp tmpaclout1 tmpaclout2 > /dev/null
+        }
+      }
+      ;;
     osf1 | nsk)
       func_test_same_acls ()
       {
@@ -364,6 +383,62 @@
 
         func_test_copy tmpfile0 tmpfile9
 
+        ;;
+
+      hpuxjfs)
+
+        # Set an ACL for a user.
+        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+        chacl -r "${orig}($auid.%,--x)" tmpfile0 \
+          || setacl -m user:$auid:1 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile2
+
+        # Set an ACL for a group.
+        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+        chacl -r "${orig}(%.$agid,r--)" tmpfile0 \
+          || setacl -m group:$agid:4 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile3
+
+        # Set an ACL for other.
+        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+        chacl -r "${orig}(%.%,r--)" tmpfile0 \
+          || setacl -m other:4 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile4
+
+        # Remove the ACL for the user.
+        chacl -d "($auid.%,--x)" tmpfile0 \
+          || setacl -d user:$auid tmpfile0
+
+        func_test_copy tmpfile0 tmpfile5
+
+        # Remove the ACL for the group.
+        chacl -d "(%.$agid,r--)" tmpfile0 \
+          || setacl -d group:$agid tmpfile0
+
+        func_test_copy tmpfile0 tmpfile6
+
+        # Delete all optional ACLs.
+        chacl -z tmpfile0 \
+          || { setacl -m user:$auid:1 tmpfile0
+               setacl -s user::6,group::0,class:7,other:0 tmpfile0
+             }
+
+        func_test_copy tmpfile0 tmpfile8
+
+        # Copy ACLs from a file that has no ACLs.
+        echo > tmpfile9
+        chmod a+x tmpfile9
+        orig=`lsacl tmpfile9 | sed -e 's/ tmpfile9$//'`
+        getacl tmpfile9 > tmpaclout0
+        rm -f tmpfile9
+        chacl -r "${orig}" tmpfile0 \
+          || setacl -f tmpaclout0 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile9
+
         ;;
 
       osf1)
--- tests/test-copy-file.sh.orig        Mon Jun 13 01:32:47 2011
+++ tests/test-copy-file.sh     Mon Jun 13 01:22:02 2011
@@ -54,7 +54,7 @@
   # Classification of the platform according to the programs available for
   # manipulating ACLs.
   # Possible values are:
-  #   linux, cygwin, freebsd, solaris, hpux, osf1, aix, macosx, irix, none.
+  #   linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, 
none.
   # TODO: Support also native Win32 platforms (mingw).
   acl_flavor=none
   if (getfacl tmpfile0 >/dev/null) 2>/dev/null; then
@@ -82,7 +82,13 @@
     if (lsacl / >/dev/null) 2>/dev/null; then
       # Platforms with the lsacl and chacl programs.
       # HP-UX, sometimes also IRIX.
-      acl_flavor=hpux
+      if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
+        # HP-UX 11.11 or newer.
+        acl_flavor=hpuxjfs
+      else
+        # HP-UX 11.00.
+        acl_flavor=hpux
+      fi
     else
       if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
         # Tru64, NonStop Kernel.
@@ -132,6 +138,19 @@
         cmp tmpaclout1 tmpaclout2 > /dev/null
       }
       ;;
+    hpuxjfs)
+      func_test_same_acls ()
+      {
+        { lsacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
+          lsacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
+          cmp tmpaclout1 tmpaclout2 > /dev/null
+        } &&
+        { getacl "$1" | sed -e "s/$1/FILENAME/g" > tmpaclout1
+          getacl "$2" | sed -e "s/$2/FILENAME/g" > tmpaclout2
+          cmp tmpaclout1 tmpaclout2 > /dev/null
+        }
+      }
+      ;;
     osf1 | nsk)
       func_test_same_acls ()
       {
@@ -358,6 +377,62 @@
 
         func_test_copy tmpfile0 tmpfile9
 
+        ;;
+
+      hpuxjfs)
+
+        # Set an ACL for a user.
+        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+        chacl -r "${orig}($auid.%,--x)" tmpfile0 \
+          || setacl -m user:$auid:1 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile2
+
+        # Set an ACL for a group.
+        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+        chacl -r "${orig}(%.$agid,r--)" tmpfile0 \
+          || setacl -m group:$agid:4 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile3
+
+        # Set an ACL for other.
+        orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+        chacl -r "${orig}(%.%,r--)" tmpfile0 \
+          || setacl -m other:4 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile4
+
+        # Remove the ACL for the user.
+        chacl -d "($auid.%,--x)" tmpfile0 \
+          || setacl -d user:$auid tmpfile0
+
+        func_test_copy tmpfile0 tmpfile5
+
+        # Remove the ACL for the group.
+        chacl -d "(%.$agid,r--)" tmpfile0 \
+          || setacl -d group:$agid tmpfile0
+
+        func_test_copy tmpfile0 tmpfile6
+
+        # Delete all optional ACLs.
+        chacl -z tmpfile0 \
+          || { setacl -m user:$auid:1 tmpfile0
+               setacl -s user::6,group::0,class:7,other:0 tmpfile0
+             }
+
+        func_test_copy tmpfile0 tmpfile8
+
+        # Copy ACLs from a file that has no ACLs.
+        echo > tmpfile9
+        chmod a+x tmpfile9
+        orig=`lsacl tmpfile9 | sed -e 's/ tmpfile9$//'`
+        getacl tmpfile9 > tmpaclout0
+        rm -f tmpfile9
+        chacl -r "${orig}" tmpfile0 \
+          || setacl -f tmpaclout0 tmpfile0
+
+        func_test_copy tmpfile0 tmpfile9
+
         ;;
 
       osf1)
--- tests/test-file-has-acl.sh.orig     Mon Jun 13 01:32:47 2011
+++ tests/test-file-has-acl.sh  Mon Jun 13 01:22:02 2011
@@ -60,7 +60,7 @@
   # Classification of the platform according to the programs available for
   # manipulating ACLs.
   # Possible values are:
-  #   linux, cygwin, freebsd, solaris, hpux, osf1, aix, macosx, irix, none.
+  #   linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, 
none.
   # TODO: Support also native Win32 platforms (mingw).
   acl_flavor=none
   if (getfacl tmpfile0 >/dev/null) 2>/dev/null; then
@@ -88,7 +88,13 @@
     if (lsacl / >/dev/null) 2>/dev/null; then
       # Platforms with the lsacl and chacl programs.
       # HP-UX, sometimes also IRIX.
-      acl_flavor=hpux
+      if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
+        # HP-UX 11.11 or newer.
+        acl_flavor=hpuxjfs
+      else
+        # HP-UX 11.00.
+        acl_flavor=hpux
+      fi
     else
       if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
         # Tru64, NonStop Kernel.
@@ -256,7 +262,7 @@
         fi
         ;;
 
-      hpux)
+      hpux | hpuxjfs)
 
         # Set an ACL for a user.
         orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
@@ -269,6 +275,20 @@
 
           func_test_has_acl tmpfile0 no
 
+        else
+          if test $acl_flavor = hpuxjfs; then
+
+            # Set an ACL for a user.
+            setacl -m user:$auid:1 tmpfile0
+
+            func_test_has_acl tmpfile0 yes
+
+            # Remove the ACL for the user.
+            setacl -d user:$auid tmpfile0
+
+            func_test_has_acl tmpfile0 no
+
+          fi
         fi
         ;;
 
--- tests/test-sameacls.c.orig  Mon Jun 13 01:32:47 2011
+++ tests/test-sameacls.c       Mon Jun 13 01:27:25 2011
@@ -28,6 +28,10 @@
 # include <sys/types.h>
 # include <sys/acl.h>
 #endif
+#if HAVE_ACLV_H
+# include <sys/types.h>
+# include <aclv.h>
+#endif
 
 #include "progname.h"
 #include "read-file.h"
@@ -426,6 +430,80 @@
             }
         }
     }
+
+# if HAVE_ACLV_H /* HP-UX >= 11.11 */
+  {
+    struct acl dummy_entries[NACLVENTRIES];
+
+    count1 = acl ((char *) file1, ACL_CNT, NACLVENTRIES, dummy_entries);
+    if (count1 < 0
+        && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
+      count1 = 0;
+    count2 = acl ((char *) file2, ACL_CNT, NACLVENTRIES, dummy_entries);
+    if (count2 < 0
+        && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
+      count2 = 0;
+  }
+
+  if (count1 < 0)
+    {
+      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
+      fflush (stderr);
+      abort ();
+    }
+  if (count2 < 0)
+    {
+      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
+      fflush (stderr);
+      abort ();
+    }
+  if (count1 != count2)
+    {
+      fprintf (stderr, "files %s and %s have different number of ACLs: %d and 
%d\n",
+               file1, file2, count1, count2);
+      return 1;
+    }
+  else if (count1 > 0)
+    {
+      struct acl *entries1 = XNMALLOC (count1, struct acl);
+      struct acl *entries2 = XNMALLOC (count2, struct acl);
+      int i;
+
+      if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
+        {
+          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
+          fflush (stderr);
+          abort ();
+        }
+      if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
+        {
+          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
+          fflush (stderr);
+          abort ();
+        }
+      for (i = 0; i < count1; i++)
+        {
+          if (entries1[i].a_type != entries2[i].a_type)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: 
different types %d and %d\n",
+                       file1, file2, i, entries1[i].a_type, 
entries2[i].a_type);
+              return 1;
+            }
+          if (entries1[i].a_id != entries2[i].a_id)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: 
different ids %d and %d\n",
+                       file1, file2, i, (int)entries1[i].a_id, 
(int)entries2[i].a_id);
+              return 1;
+            }
+          if (entries1[i].a_perm != entries2[i].a_perm)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: 
different permissions %03o and %03o\n",
+                       file1, file2, i, (unsigned int) entries1[i].a_perm, 
(unsigned int) entries2[i].a_perm);
+              return 1;
+            }
+        }
+    }
+# endif
 #elif HAVE_ACLX_GET /* AIX */
   acl_type_t type1;
   char acl1[1000];
--- tests/test-set-mode-acl.sh.orig     Mon Jun 13 01:32:47 2011
+++ tests/test-set-mode-acl.sh  Mon Jun 13 01:22:02 2011
@@ -60,7 +60,7 @@
   # Classification of the platform according to the programs available for
   # manipulating ACLs.
   # Possible values are:
-  #   linux, cygwin, freebsd, solaris, hpux, osf1, aix, macosx, irix, none.
+  #   linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, 
none.
   # TODO: Support also native Win32 platforms (mingw).
   acl_flavor=none
   if (getfacl tmpfile0 >/dev/null) 2>/dev/null; then
@@ -88,7 +88,13 @@
     if (lsacl / >/dev/null) 2>/dev/null; then
       # Platforms with the lsacl and chacl programs.
       # HP-UX, sometimes also IRIX.
-      acl_flavor=hpux
+      if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
+        # HP-UX 11.11 or newer.
+        acl_flavor=hpuxjfs
+      else
+        # HP-UX 11.00.
+        acl_flavor=hpux
+      fi
     else
       if (getacl tmpfile0 >/dev/null) 2>/dev/null; then
         # Tru64, NonStop Kernel.
@@ -178,6 +184,11 @@
             orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
             chacl -r "${orig}($auid.%,--x)" tmpfile0
             ;;
+          hpuxjfs)
+            orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'`
+            chacl -r "${orig}($auid.%,--x)" tmpfile0 \
+              || setacl -m user:$auid:1 tmpfile0
+            ;;
           osf1)
             setacl -u user:$auid:1 tmpfile0
             ;;

-- 
In memoriam Medgar Evers <http://en.wikipedia.org/wiki/Medgar_Evers>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]