1/* Test whether a file has a nontrivial access control list. 2 3 Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 Written by Paul Eggert and Andreas Gruenbacher. */ 19 20#include <config.h> 21 22#include "acl.h" 23 24#include "acl-internal.h" 25 26/* Return 1 if NAME has a nontrivial access control list, 0 if NAME 27 only has no or a base access control list, and -1 (setting errno) 28 on error. SB must be set to the stat buffer of FILE. */ 29 30int 31file_has_acl (char const *name, struct stat const *sb) 32{ 33 if (! S_ISLNK (sb->st_mode)) 34 { 35#if USE_ACL && HAVE_ACL_TRIVIAL 36 37 /* Solaris 10, which also has NFSv4 and ZFS style ACLs. */ 38 return acl_trivial (name); 39 40#elif USE_ACL && HAVE_ACL && defined GETACLCNT 41 42 /* Solaris 2.5 through Solaris 9, and contemporaneous versions of 43 HP-UX and Unixware. */ 44 int n = acl (name, GETACLCNT, 0, NULL); 45 return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n); 46 47#elif USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_FREE 48 49 /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ 50 int ret; 51 52 if (HAVE_ACL_EXTENDED_FILE) 53 ret = acl_extended_file (name); 54 else 55 { 56 acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS); 57 if (acl) 58 { 59 ret = (3 < acl_entries (acl)); 60 acl_free (acl); 61 if (ret == 0 && S_ISDIR (sb->st_mode)) 62 { 63 acl = acl_get_file (name, ACL_TYPE_DEFAULT); 64 if (acl) 65 { 66 ret = (0 < acl_entries (acl)); 67 acl_free (acl); 68 } 69 else 70 ret = -1; 71 } 72 } 73 else 74 ret = -1; 75 } 76 if (ret < 0) 77 return ACL_NOT_WELL_SUPPORTED (errno) ? 0 : -1; 78 return ret; 79#endif 80 } 81 82 /* FIXME: Add support for AIX, Irix, and Tru64. Please see Samba's 83 source/lib/sysacls.c file for fix-related ideas. */ 84 85 return 0; 86} 87