Index: kioslave/file/file.cc =================================================================== --- kioslave/file/file.cc (revision 462925) +++ kioslave/file/file.cc (working copy) @@ -43,8 +43,12 @@ #ifdef USE_POSIX_ACL #include +#ifdef Q_OS_LINUX #include +#else +#include #endif +#endif #include #include @@ -65,6 +69,7 @@ #include #include +#include #include #include #include @@ -151,8 +156,7 @@ acl = acl_from_text( ACLString.latin1() ); if ( acl_valid( acl ) == 0 ) { // let's be safe ret == acl_set_file( path, ACL_TYPE_ACCESS, acl ); - ssize_t size = acl_size( acl ); - kdDebug(7101) << "Set ACL on: " << path << " to: " << acl_to_text( acl, &size ) << endl; + kdDebug(7101) << "Set ACL on: " << path << " to: " << KACL::asString( acl ) << endl; } acl_free( acl ); if ( ret != 0 ) return ret; // better stop trying right away @@ -166,8 +170,7 @@ acl_t acl = acl_from_text( defaultACLString.latin1() ); if ( acl_valid( acl ) == 0 ) { // let's be safe ret += acl_set_file( path, ACL_TYPE_DEFAULT, acl ); - ssize_t size = acl_size( acl ); - kdDebug(7101) << "Set Default ACL on: " << path << " to: " << acl_to_text( acl, &size ) << endl; + kdDebug(7101) << "Set Default ACL on: " << path << " to: " << KACL::asString( acl ) << endl; } acl_free( acl ); } @@ -1697,25 +1700,27 @@ static void appendACLAtoms( const QCString & path, UDSEntry& entry, mode_t type, bool withACL ) { // first check for a noop +#ifdef Q_OS_LINUX if ( acl_extended_file( path.data() ) == 0 ) return; +#endif acl_t acl = 0; acl_t defaultAcl = 0; UDSAtom atom; bool isDir = S_ISDIR( type ); // do we have an acl for the file, and/or a default acl for the dir, if it is one? - acl = acl_get_file( path.data(), ACL_TYPE_ACCESS ); + if ( acl = acl_get_file( path.data(), ACL_TYPE_ACCESS ) ) { + if ( !isExtendedACL( acl ) ) { + acl_free( acl ); + acl = 0; + } + } + /* Sadly libacl does not provided a means of checking for extended ACL and default * ACL separately. Since a directory can have both, we need to check again. */ - if ( isDir ) { - if ( acl ) { - if ( !isExtendedACL( acl ) ) { - acl_free( acl ); - acl = 0; - } - } + if ( isDir ) defaultAcl = acl_get_file( path.data(), ACL_TYPE_DEFAULT ); - } + if ( acl || defaultAcl ) { kdDebug(7101) << path.data() << " has extended ACL entries " << endl; atom.m_uds = KIO::UDS_EXTENDED_ACL; @@ -1724,16 +1729,14 @@ } if ( withACL ) { if ( acl ) { - ssize_t size = acl_size( acl ); atom.m_uds = KIO::UDS_ACL_STRING; - atom.m_str = QString::fromLatin1( acl_to_text( acl, &size ) ); + atom.m_str = KACL::asString( acl ); entry.append( atom ); kdDebug(7101) << path.data() << "ACL: " << atom.m_str << endl; } if ( defaultAcl ) { - ssize_t size = acl_size( defaultAcl ); atom.m_uds = KIO::UDS_DEFAULT_ACL_STRING; - atom.m_str = QString::fromLatin1( acl_to_text( defaultAcl, &size ) ); + atom.m_str = KACL::asString( defaultAcl ); entry.append( atom ); kdDebug(7101) << path.data() << "DEFAULT ACL: " << atom.m_str << endl; } Index: kio/kfile/kpropertiesdialog.cpp =================================================================== --- kio/kfile/kpropertiesdialog.cpp (revision 462925) +++ kio/kfile/kpropertiesdialog.cpp (working copy) @@ -74,10 +74,17 @@ #include #ifdef USE_POSIX_ACL +#ifdef Q_OS_FREEBSD extern "C" { +#include +#include +} +#else +extern "C" { # include } #endif +#endif #include #include @@ -2052,8 +2059,13 @@ // FIXME make it work with partial entries if ( properties->items().count() == 1 ) { QCString pathCString = QFile::encodeName( properties->item()->url().path() ); +#ifdef Q_OS_FREEBSD + struct statfs buf; + fileSystemSupportsACLs = ( statfs( pathCString.data(), &buf ) == 0 ) && ( buf.f_flags & MNT_ACLS ); +#else fileSystemSupportsACLs = getxattr( pathCString.data(), "system.posix_acl_access", NULL, 0 ) >= 0 || errno == ENODATA; +#endif } if ( fileSystemSupportsACLs ) { std::for_each( theNotSpecials.begin(), theNotSpecials.end(), std::mem_fun( &QWidget::hide ) ); Index: kio/tests/kacltest.cpp =================================================================== --- kio/tests/kacltest.cpp (revision 462925) +++ kio/tests/kacltest.cpp (working copy) @@ -79,10 +79,24 @@ return 0; // success. The exit(1) in check() is what happens in case of failure. } -static const QString s_testACL( "user::rw-\nuser:bin:rwx\ngroup::rw-\nmask::rwx\nother::r--\n" ); -static const QString s_testACL2( "user::rwx\nuser:bin:rwx\ngroup::rw-\ngroup:users:r--\ngroup:audio:--x\nmask::r-x\nother::r--\n" ); -static const QString s_testACLEffective("user::rwx\nuser:bin:rwx #effective:r-x\ngroup::rw- #effective:r--\ngroup:audio:--x\ngroup:users:r--\nmask::r-x\nother::r--\n"); +#ifdef Q_OS_FREEBSD +static const QString s_group1 = QString::fromLatin1("staff"); +static const QString s_group2 = QString::fromLatin1("guest"); +#else +static const QString s_group1 = QString::fromLatin1("audio"); +static const QString s_group2 = QString::fromLatin1("users"); +#endif +static const QString s_testACL = QString::fromLatin1( "user::rw-\nuser:bin:rwx\ngroup::rw-\nmask::rwx\nother::r--\n" ); +static const QString s_testACL2 = QString::fromLatin1( "user::rwx\nuser:bin:rwx\ngroup::rw-\n") + + QString::fromLatin1( "group:" ) + s_group1 + QString::fromLatin1( ":--x\n" ) + + QString::fromLatin1( "group:" ) + s_group2 + QString::fromLatin1( ":r--\n" ) + + QString::fromLatin1( "mask::r-x\nother::r--\n" ); +static const QString s_testACLEffective = QString::fromLatin1( "user::rwx\nuser:bin:rwx #effective:r-x\ngroup::rw- #effective:r--\n" ) + + QString::fromLatin1( "group:" ) + s_group1 + QString::fromLatin1( ":--x\n" ) + + QString::fromLatin1( "group:" ) + s_group2 + QString::fromLatin1( ":r--\n" ) + + QString::fromLatin1( "mask::r-x\nother::r--\n" ); + KACLTest::KACLTest() :m_acl( s_testACL ) { @@ -120,13 +134,13 @@ void KACLTest::testAsString() { - check( "asString: ", s_testACL, m_acl.asString() ); + check( "asString: ", m_acl.asString(), s_testACL ); } void KACLTest::testSetACL() { m_acl.setACL( s_testACL2 ); - check( "setACL: ", s_testACLEffective.simplifyWhiteSpace(), m_acl.asString().simplifyWhiteSpace() ); + check( "setACL: ", m_acl.asString().simplifyWhiteSpace().remove(" "), s_testACLEffective.simplifyWhiteSpace().remove(" ") ); } void KACLTest::testGetOwnerPermissions() @@ -182,10 +196,10 @@ permissions = ( *it ).second; // setACL sorts them alphabetically ... if ( count == 0 ) { - check( "All groups name: ", name, "audio" ); + check( "All groups name: ", name, s_group1 ); check( "All groups permissions: ", QString::number( permissions ), "1" ); } else if ( count == 1 ) { - check( "All groups name: ", name, "users" ); + check( "All groups name: ", name, s_group2 ); check( "All groups permissions: ", QString::number( permissions ), "4" ); } ++it; @@ -249,26 +263,27 @@ // groups, all and named - const QString expected2( "user::rw-\nuser:bin:rwx\ngroup::rw-\ngroup:audio:-wx\ngroup:users:r--\nmask::rwx\nother::r--\n" ); + const QString expected2 = QString::fromLatin1( "user::rw-\nuser:bin:rwx\ngroup::rw-\ngroup:" ) + s_group1 + + QString::fromLatin1( ":-wx\ngroup:" ) + s_group2 + QString::fromLatin1(":r--\nmask::rwx\nother::r--\n" ); CharlesII.setACL( s_testACL ); // reset ACLGroupPermissionsList groups; - ACLGroupPermissions group = qMakePair( QString( "audio" ), ( unsigned short )3 ); + ACLGroupPermissions group = qMakePair( s_group1, ( unsigned short )3 ); groups.append( group ); - group = qMakePair( QString( "users" ), ( unsigned short )4 ); + group = qMakePair( s_group2, ( unsigned short )4 ); groups.append( group ); CharlesII.setAllGroupPermissions( groups ); check( "setAllGroupPermissions: ", CharlesII.asString(), expected2 ); CharlesII.setACL( s_testACL ); // reset - CharlesII.setNamedGroupPermissions( QString( "audio" ), 3 ); - CharlesII.setNamedGroupPermissions( QString( "users" ), 4 ); + CharlesII.setNamedGroupPermissions( s_group1, 3 ); + CharlesII.setNamedGroupPermissions( s_group2, 4 ); check( "setNamedGroupPermissions: ", CharlesII.asString(), expected2 ); } void KACLTest::testSettingErrorHandling() { KACL foo( s_testACL ); - bool v = foo.setNamedGroupPermissions( "audio", 7 ); // existing group + bool v = foo.setNamedGroupPermissions( s_group1, 7 ); // existing group check( "Existing group: ", v, true ); v = foo.setNamedGroupPermissions( "jongel", 7 ); // non-existing group check( "Non-existing group: ", v, false ); Index: kio/kio/kacl.cpp =================================================================== --- kio/kio/kacl.cpp (revision 462925) +++ kio/kio/kacl.cpp (working copy) @@ -27,9 +27,12 @@ #include #include #ifdef USE_POSIX_ACL -#include +#ifdef Q_OS_LINUX #include +#else +#include #endif +#endif #include #include @@ -166,8 +169,7 @@ static void printACL( acl_t acl, const QString &comment ) { - ssize_t size = acl_size( acl ); - kdDebug() << comment << acl_to_text( acl, &size ) << endl; + kdDebug() << comment << KACL::asString( acl ) << endl; } static int getUidForName( const QString& name ) @@ -550,6 +552,9 @@ { bool ret = false; #ifdef USE_POSIX_ACL + if ( aclStr.isEmpty() ) + return false; + acl_t temp = acl_from_text( aclStr.latin1() ); if ( acl_valid( temp ) != 0 ) { // TODO errno is set, what to do with it here? @@ -566,9 +571,16 @@ QString KACL::asString() const { + return asString( d->m_acl ); +} + +QString KACL::asString(const acl_t acl) +{ #ifdef USE_POSIX_ACL - ssize_t size = acl_size( d->m_acl ); - return QString::fromLatin1( acl_to_text( d->m_acl, &size ) ); + char *aclString = acl_to_text( acl, 0 ); + QString ret = QString::fromLatin1( aclString ); + acl_free( (void*)aclString ); + return ret; #else return QString::null; #endif Index: kio/kio/posixacladdons.h =================================================================== --- kio/kio/posixacladdons.h (revision 0) +++ kio/kio/posixacladdons.h (revision 0) @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2005 by Markus Brueffer * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef __posixacladdons_h__ +#define __posixacladdons_h__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#if defined(USE_POSIX_ACL) && !defined(Q_OS_LINUX) + +#include + +#ifdef Q_OS_FREEBSD +#define acl_get_perm acl_get_perm_np +#endif + +int acl_cmp(acl_t acl1, acl_t acl2); +acl_t acl_from_mode(mode_t mode); +int acl_equiv_mode(acl_t acl, mode_t *mode_p); + +#endif // USE_POSIX_ACL + +#endif // __posixacladdons_h__ Index: kio/kio/posixacladdons.cpp =================================================================== --- kio/kio/posixacladdons.cpp (revision 0) +++ kio/kio/posixacladdons.cpp (revision 0) @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005 by Markus Brueffer * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "posixacladdons.h" + +#if defined(USE_POSIX_ACL) && !defined(Q_OS_LINUX) + +#include +#include + +#include + +class SortedEntryList : public QPtrList +{ +protected: + int compareItems( QPtrCollection::Item i1, + QPtrCollection::Item i2 ) + { + acl_entry_t *e1 = static_cast( i1 ); + acl_entry_t *e2 = static_cast( i2 ); + + acl_tag_t tag1, tag2; + uid_t uid1 = 0, uid2 = 0; + + acl_get_tag_type( *e1, &tag1 ); + acl_get_tag_type( *e2, &tag2 ); + + if ( tag1 == ACL_USER || tag1 == ACL_GROUP ) + uid1 = *( (uid_t*) acl_get_qualifier( *e1 ) ); + + if ( tag2 == ACL_USER || tag2 == ACL_GROUP ) + uid2 = *( (uid_t*) acl_get_qualifier( *e2 ) ); + + if ( tag1 < tag2 ) + return -1; + else if ( tag1 > tag2 ) + return 1; + + if ( uid1 < uid2 ) + return -1; + else if ( uid1 > uid2 ) + return 1; + + return 0; + } +}; + +int acl_cmp(acl_t acl1, acl_t acl2) +{ + if ( !acl1 || !acl2 ) + return -1; + + SortedEntryList entries1, entries2; + entries1.setAutoDelete( true ); + entries2.setAutoDelete( true ); + + /* Add ACL entries to vectors */ + acl_entry_t *entry = new acl_entry_t; + int ret = acl_get_entry( acl1, ACL_FIRST_ENTRY, entry ); + while( ret == 1 ) { + entries1.append( entry ); + entry = new acl_entry_t; + ret = acl_get_entry( acl1, ACL_NEXT_ENTRY, entry ); + } + delete entry; + + entry = new acl_entry_t; + ret = acl_get_entry( acl2, ACL_FIRST_ENTRY, entry ); + while ( ret == 1 ) { + entries2.append( entry ); + entry = new acl_entry_t; + ret = acl_get_entry( acl2, ACL_NEXT_ENTRY, entry ); + } + delete entry; + + /* If the entry count differs, we are done */ + if ( entries1.count() != entries2.count() ) + return 1; + + /* Sort vectors */ + entries1.sort(); + entries2.sort(); + + /* Compare all entries */ + acl_permset_t permset1, permset2; + acl_tag_t tag1, tag2; + uid_t uid1, uid2; + acl_entry_t *e1, *e2; + + for ( e1 = entries1.first(), e2 = entries2.first(); e1; e1 = entries1.next(), e2 = entries2.next() ) { + /* Compare tag */ + if ( acl_get_tag_type( *e1, &tag1 ) != 0 ) return 1; + if ( acl_get_tag_type( *e2, &tag2 ) != 0 ) return 1; + if ( tag1 != tag2 ) return 1; + + /* Compare permissions */ + if ( acl_get_permset( *e1, &permset1 ) != 0 ) return 1; + if ( acl_get_permset( *e2, &permset2 ) != 0 ) return 1; + if ( *permset1 != *permset2) return 1; + + /* Compare uid */ + switch( tag1 ) { + case ACL_USER: + case ACL_GROUP: + uid1 = *( (uid_t*) acl_get_qualifier( *e1 ) ); + uid2 = *( (uid_t*) acl_get_qualifier( *e2 ) ); + if ( uid1 != uid2 ) return 1; + } + } + + return 0; +} + +acl_t acl_from_mode(mode_t mode) +{ + acl_t newACL = acl_init( 3 ); + acl_entry_t entry; + acl_permset_t permset; + int error = 0; + + /* Add owner entry */ + if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0 ) { + /* Set owner permissions */ + acl_set_tag_type( entry, ACL_USER_OBJ ); + acl_get_permset( entry, &permset ); + acl_clear_perms( permset ); + if ( mode & S_IRUSR ) acl_add_perm( permset, ACL_READ ); + if ( mode & S_IWUSR ) acl_add_perm( permset, ACL_WRITE ); + if ( mode & S_IXUSR ) acl_add_perm( permset, ACL_EXECUTE ); + acl_set_permset( entry, permset ); + + /* Add group entry */ + if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0 ) { + /* Set group permissions */ + acl_set_tag_type( entry, ACL_GROUP_OBJ ); + acl_get_permset( entry, &permset ); + acl_clear_perms( permset ); + if ( mode & S_IRGRP ) acl_add_perm( permset, ACL_READ ); + if ( mode & S_IWGRP ) acl_add_perm( permset, ACL_WRITE ); + if ( mode & S_IXGRP ) acl_add_perm( permset, ACL_EXECUTE ); + acl_set_permset( entry, permset ); + + /* Add other entry */ + if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0) { + /* Set other permissions */ + acl_set_tag_type( entry, ACL_OTHER ); + acl_get_permset( entry, &permset ); + acl_clear_perms( permset ); + if ( mode & S_IROTH ) acl_add_perm( permset, ACL_READ ); + if ( mode & S_IWOTH ) acl_add_perm( permset, ACL_WRITE ); + if ( mode & S_IXOTH ) acl_add_perm( permset, ACL_EXECUTE ); + acl_set_permset( entry, permset ); + } + } + } + + if ( error ) { + acl_free ( &newACL ); + return NULL; + } + + return newACL; +} + +int acl_equiv_mode(acl_t acl, mode_t *mode_p) +{ + acl_entry_t entry; + acl_tag_t tag; + acl_permset_t permset; + mode_t mode = 0; + int notEquiv = 0; + + if ( !acl ) + return -1; + + int ret = acl_get_entry( acl, ACL_FIRST_ENTRY, &entry ); + while ( ret == 1 ) { + acl_get_tag_type( entry, &tag ); + acl_get_permset( entry, &permset ); + + switch( tag ) { + case ACL_USER_OBJ: + if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IRUSR; + if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWUSR; + if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXUSR; + break; + + case ACL_GROUP_OBJ: + if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IRGRP; + if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWGRP; + if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXGRP; + break; + + case ACL_OTHER: + if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IROTH; + if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWOTH; + if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXOTH; + break; + + case ACL_USER: + case ACL_GROUP: + case ACL_MASK: + notEquiv = 1; + break; + + default: + errno = EINVAL; + return -1; + } + + ret = acl_get_entry( acl, ACL_NEXT_ENTRY, &entry ); + } + + if (mode_p) + *mode_p = mode; + + return notEquiv; +} + +#endif // USE_POSIX_ACL Index: kio/kio/kacl.h =================================================================== --- kio/kio/kacl.h (revision 462925) +++ kio/kio/kacl.h (working copy) @@ -20,10 +20,16 @@ #ifndef __kacl_h__ #define __kacl_h__ +#ifdef HAVE_CONFIG_H +#include +#endif #include #include +#ifdef USE_POSIX_ACL +#include +#endif typedef QPair ACLUserPermissions; typedef QValueList ACLUserPermissionsList; @@ -139,7 +145,8 @@ * exists. @param exists is set to true if a matching entry exists and * to false otherwise. * @return the permissions for a user entry with the name in @p name */ - unsigned short namedUserPermissions( const QString& name, bool *exits ) const; + unsigned short namedUserPermissions( const QString& name, bool *exists ) const; + /** Set the permissions for a user with the name @p name. Will fail * if the user doesn't exist, in which case the ACL will be unchanged. * @return success or failure. */ @@ -192,6 +199,12 @@ * to take such strings as input. */ QString asString() const; + /** Return a string representation of an ACL. + * @return a string version of @param acl in the format compatible with libacl and + * POSIX 1003.1e. Implementations conforming to that standard should be able + * to take such strings as input. */ + static QString asString( const acl_t acl ); + protected: virtual void virtual_hook( int id, void* data ); private: Index: kio/kio/Makefile.am =================================================================== --- kio/kio/Makefile.am (revision 462925) +++ kio/kio/Makefile.am (working copy) @@ -43,7 +43,7 @@ kfilemetainfo.cpp kdcopservicestarter.cpp \ dataslave.cpp dataprotocol.cpp #if USE_POSIX_ACL - libksycoca_la_SOURCES += kacl.cpp + libksycoca_la_SOURCES += kacl.cpp posixacladdons.cpp #endif include_HEADERS = \ @@ -111,6 +111,9 @@ kimageiofactory.h kdirwatch_p.h kdirlister_p.h \ renamedlg.h skipdlg.h dataslave.h dataprotocol.h \ kservice_p.h +#if USE_POSIX_ACL +noinst_HEADERS += posixacladdons.h +#endif parserfiles = yacc.y lex.l Index: configure.in.in =================================================================== --- configure.in.in (revision 462925) +++ configure.in.in (working copy) @@ -50,14 +50,21 @@ USE_POSIX_ACL="yes" ACL_LIBS="" -KDE_CHECK_HEADER(attr/libattr.h, ,[USE_POSIX_ACL="no"]) -KDE_CHECK_HEADER(sys/xattr.h, ,[USE_POSIX_ACL="no"]) KDE_CHECK_HEADER(sys/acl.h, ,[USE_POSIX_ACL="no"]) -KDE_CHECK_HEADER(acl/libacl.h, ,[USE_POSIX_ACL="no"]) -KDE_CHECK_LIB(acl,acl_init, ,[USE_POSIX_ACL="no"]) +case $host in + *-*-freebsd*) + KDE_CHECK_LIB(c,acl_init,[ACL_LIBS="-lc"],[USE_POSIX_ACL="no"]) + ;; + *) + KDE_CHECK_HEADER(attr/libattr.h, ,[USE_POSIX_ACL="no"]) + KDE_CHECK_HEADER(sys/xattr.h, ,[USE_POSIX_ACL="no"]) + KDE_CHECK_HEADER(acl/libacl.h, ,[USE_POSIX_ACL="no"]) + KDE_CHECK_LIB(acl,acl_init,[ACL_LIBS="-lacl -lattr"],[USE_POSIX_ACL="no"]) + ;; +esac + if test $USE_POSIX_ACL = "yes" ; then - ACL_LIBS="-lacl -lattr" AC_DEFINE([USE_POSIX_ACL], 1, [Define if system has POSIX ACL support.]) fi AC_SUBST(ACL_LIBS)