From 227b08bbf68b66e8d7cd4da5c1a6f0ebf5a5d9e8 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 13 Jun 2011 02:11:03 +0200 Subject: [PATCH] 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 . (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 . (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. --- ChangeLog | 30 ++++++++++++ doc/acl-resources.txt | 36 ++++++++++---- lib/acl-internal.h | 17 +++++++ lib/copy-acl.c | 119 ++++++++++++++++++++++++++++++++++++--------- lib/file-has-acl.c | 75 ++++++++++++++++++++++++++-- lib/set-mode-acl.c | 76 ++++++++++++++++++++++------- m4/acl.m4 | 4 +- tests/test-copy-acl.sh | 79 +++++++++++++++++++++++++++++- tests/test-copy-file.sh | 79 +++++++++++++++++++++++++++++- tests/test-file-has-acl.sh | 26 ++++++++-- tests/test-sameacls.c | 78 +++++++++++++++++++++++++++++ tests/test-set-mode-acl.sh | 15 +++++- 12 files changed, 570 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a0d7af5c..7af3f05bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,35 @@ 2011-06-12 Bruno Haible + 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 . + (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 . + (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. + +2011-06-12 Bruno Haible + acl: Complete the 2010-08-10 fix. * lib/file-has-acl.c (file_has_acl) [HP-UX]: Also test against ENOTSUP. * lib/set-mode-acl.c (qset_acl) [HP-UX]: Likewise. diff --git a/doc/acl-resources.txt b/doc/acl-resources.txt index d01e2d678..06fd118f4 100644 --- a/doc/acl-resources.txt +++ b/doc/acl-resources.txt @@ -243,15 +243,16 @@ Utilities: 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: - or , optionally + or Library: none needed Functions: @@ -259,14 +260,31 @@ Functions: fgetacl fsetacl setacl -Functions only declared in : - 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: + +Library: + none needed +Functions: + acl + aclsort +Utilities: getacl setacl - chmod IRIX ACLs diff --git a/lib/acl-internal.h b/lib/acl-internal.h index 0eb11bc30..b3160a71c 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -35,6 +35,15 @@ # include #endif +/* On HP-UX >= 11.11, additional ACL API is available in . */ +#if HAVE_ACLV_H +# include +# include +/* 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 @@ extern int acl_ace_nontrivial (int count, ace_t *entries); 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 */ diff --git a/lib/copy-acl.c b/lib/copy-acl.c index d933fa2fa..4f2ea06a6 100644 --- a/lib/copy-acl.c +++ b/lib/copy-acl.c @@ -410,6 +410,12 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, 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 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, 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 (mode & (S_ISUID | S_ISGID | S_ISVTX)) + 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) { - /* 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. */ + 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; + } - return chmod_or_fchmod (dst_name, dest_desc, mode); +# 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 (did_chmod <= ((mode & (S_ISUID | S_ISGID | S_ISVTX)) ? 1 : 0)) + { + /* We did not call chmod so far, and special bits are to be set which + don't fit into ACLs. */ + + 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; diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 03decf46b..3d4d5c16f 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -234,6 +234,33 @@ acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb) 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 @@ file_has_acl (char const *name, struct stat const *sb) # 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 @@ file_has_acl (char const *name, struct stat const *sb) 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 @@ file_has_acl (char const *name, struct stat const *sb) 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; diff --git a/lib/set-mode-acl.c b/lib/set-mode-acl.c index 1392378fd..5ba86a5bc 100644 --- a/lib/set-mode-acl.c +++ b/lib/set-mode-acl.c @@ -406,7 +406,6 @@ qset_acl (char const *name, int desc, mode_t mode) # elif HAVE_GETACL /* HP-UX */ struct stat statbuf; - struct acl_entry entries[3]; int ret; if (desc != -1) @@ -416,25 +415,68 @@ qset_acl (char const *name, int desc, mode_t mode) 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]; + + 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 (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)) diff --git a/m4/acl.m4 b/m4/acl.m4 index a01382db6..d6a448aab 100644 --- a/m4/acl.m4 +++ b/m4/acl.m4 @@ -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 @@ int type = ACL_TYPE_EXTENDED;]])], 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 ]) fi dnl Test for AIX API (AIX 5.3 or newer). diff --git a/tests/test-copy-acl.sh b/tests/test-copy-acl.sh index 1452c8085..4111bbcc2 100755 --- a/tests/test-copy-acl.sh +++ b/tests/test-copy-acl.sh @@ -60,7 +60,7 @@ cd "$builddir" || # 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 @@ cd "$builddir" || 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 @@ cd "$builddir" || 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 () { @@ -366,6 +385,62 @@ cd "$builddir" || ;; + 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) # Set an ACL for a user. diff --git a/tests/test-copy-file.sh b/tests/test-copy-file.sh index c63f380dd..fecf9bc30 100755 --- a/tests/test-copy-file.sh +++ b/tests/test-copy-file.sh @@ -54,7 +54,7 @@ cd "$builddir" || # 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 @@ cd "$builddir" || 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 @@ cd "$builddir" || 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 () { @@ -360,6 +379,62 @@ cd "$builddir" || ;; + 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) # Set an ACL for a user. diff --git a/tests/test-file-has-acl.sh b/tests/test-file-has-acl.sh index 3f49e8d9e..053246ac9 100755 --- a/tests/test-file-has-acl.sh +++ b/tests/test-file-has-acl.sh @@ -60,7 +60,7 @@ cd "$builddir" || # 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 @@ cd "$builddir" || 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 @@ cd "$builddir" || fi ;; - hpux) + hpux | hpuxjfs) # Set an ACL for a user. orig=`lsacl tmpfile0 | sed -e 's/ tmpfile0$//'` @@ -269,6 +275,20 @@ cd "$builddir" || 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 ;; diff --git a/tests/test-sameacls.c b/tests/test-sameacls.c index 661a9266a..3fafa3c20 100644 --- a/tests/test-sameacls.c +++ b/tests/test-sameacls.c @@ -28,6 +28,10 @@ # include # include #endif +#if HAVE_ACLV_H +# include +# include +#endif #include "progname.h" #include "read-file.h" @@ -426,6 +430,80 @@ main (int argc, char *argv[]) } } } + +# 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]; diff --git a/tests/test-set-mode-acl.sh b/tests/test-set-mode-acl.sh index 56fde29e5..24ce00302 100755 --- a/tests/test-set-mode-acl.sh +++ b/tests/test-set-mode-acl.sh @@ -60,7 +60,7 @@ cd "$builddir" || # 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 @@ cd "$builddir" || 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 @@ cd "$builddir" || 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 ;; -- 2.11.0