1# acl.m4 - check for access control list (ACL) primitives
2# serial 22
3
4# Copyright (C) 2002, 2004-2017 Free Software Foundation, Inc.
5# This file is free software; the Free Software Foundation
6# gives unlimited permission to copy and/or distribute it,
7# with or without modifications, as long as this notice is preserved.
8
9# Written by Paul Eggert and Jim Meyering.
10
11AC_DEFUN([gl_FUNC_ACL_ARG],
12[
13  gl_need_lib_has_acl=
14  AC_ARG_ENABLE([acl],
15    AS_HELP_STRING([--disable-acl], [do not support ACLs]),
16    , [enable_acl=auto])
17])
18
19
20AC_DEFUN([gl_FUNC_ACL],
21[
22  AC_REQUIRE([gl_FUNC_ACL_ARG])
23  AC_CHECK_FUNCS_ONCE([fchmod])
24  LIB_ACL=
25  use_acl=0
26  if test "$enable_acl" != no; then
27    dnl On all platforms, the ACL related API is declared in <sys/acl.h>.
28    AC_CHECK_HEADERS([sys/acl.h])
29    if test $ac_cv_header_sys_acl_h = yes; then
30      ac_save_LIBS=$LIBS
31
32      dnl Test for POSIX-draft-like API (GNU/Linux, FreeBSD, Mac OS X,
33      dnl IRIX, Tru64).  -lacl is needed on GNU/Linux, -lpacl on OSF/1.
34      if test $use_acl = 0; then
35        AC_SEARCH_LIBS([acl_get_file], [acl pacl],
36          [if test "$ac_cv_search_acl_get_file" != "none required"; then
37             LIB_ACL=$ac_cv_search_acl_get_file
38           fi
39           AC_CHECK_FUNCS(
40             [acl_get_file acl_get_fd acl_set_file acl_set_fd \
41              acl_free acl_from_mode acl_from_text \
42              acl_delete_def_file acl_extended_file \
43              acl_delete_fd_np acl_delete_file_np \
44              acl_copy_ext_native acl_create_entry_np \
45              acl_to_short_text acl_free_text])
46           # If the acl_get_file bug is detected, don't enable the ACL support.
47           gl_ACL_GET_FILE([use_acl=1], [])
48           if test $use_acl = 1; then
49             dnl On GNU/Linux, an additional API is declared in <acl/libacl.h>.
50             AC_CHECK_HEADERS([acl/libacl.h])
51             AC_REPLACE_FUNCS([acl_entries])
52             AC_CACHE_CHECK([for ACL_FIRST_ENTRY],
53               [gl_cv_acl_ACL_FIRST_ENTRY],
54               [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
55[[#include <sys/types.h>
56#include <sys/acl.h>
57int type = ACL_FIRST_ENTRY;]])],
58                  [gl_cv_acl_ACL_FIRST_ENTRY=yes],
59                  [gl_cv_acl_ACL_FIRST_ENTRY=no])])
60             if test $gl_cv_acl_ACL_FIRST_ENTRY = yes; then
61               AC_DEFINE([HAVE_ACL_FIRST_ENTRY], [1],
62                 [Define to 1 if the constant ACL_FIRST_ENTRY exists.])
63             fi
64             dnl On Mac OS X, other types of ACLs are supported.
65             AC_CACHE_CHECK([for ACL_TYPE_EXTENDED],
66               [gl_cv_acl_ACL_TYPE_EXTENDED],
67               [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
68[[#include <sys/types.h>
69#include <sys/acl.h>
70int type = ACL_TYPE_EXTENDED;]])],
71                  [gl_cv_acl_ACL_TYPE_EXTENDED=yes],
72                  [gl_cv_acl_ACL_TYPE_EXTENDED=no])])
73             if test $gl_cv_acl_ACL_TYPE_EXTENDED = yes; then
74               AC_DEFINE([HAVE_ACL_TYPE_EXTENDED], [1],
75                 [Define to 1 if the ACL type ACL_TYPE_EXTENDED exists.])
76             fi
77           else
78             LIB_ACL=
79           fi
80          ])
81      fi
82
83      dnl Test for Solaris API (Solaris, Cygwin).
84      if test $use_acl = 0; then
85        AC_CHECK_FUNCS([facl])
86        if test $ac_cv_func_facl = yes; then
87          AC_SEARCH_LIBS([acl_trivial], [sec],
88            [if test "$ac_cv_search_acl_trivial" != "none required"; then
89               LIB_ACL=$ac_cv_search_acl_trivial
90             fi
91            ])
92          AC_CHECK_FUNCS([acl_trivial])
93          use_acl=1
94        fi
95      fi
96
97      dnl Test for HP-UX API.
98      if test $use_acl = 0; then
99        AC_CHECK_FUNCS([getacl])
100        if test $ac_cv_func_getacl = yes; then
101          use_acl=1
102        fi
103        dnl Test for HP-UX 11.11 API.
104        AC_CHECK_HEADERS([aclv.h], [], [], [#include <sys/types.h>])
105      fi
106
107      dnl Test for AIX API (AIX 5.3 or newer).
108      if test $use_acl = 0; then
109        AC_CHECK_FUNCS([aclx_get])
110        if test $ac_cv_func_aclx_get = yes; then
111          use_acl=1
112        fi
113      fi
114
115      dnl Test for older AIX API.
116      if test $use_acl = 0 || test "$ac_cv_func_aclx_get" = yes; then
117        AC_CHECK_FUNCS([statacl])
118        if test $ac_cv_func_statacl = yes; then
119          use_acl=1
120        fi
121      fi
122
123      dnl Test for NonStop Kernel API.
124      if test $use_acl = 0; then
125        AC_CHECK_FUNCS([aclsort])
126        if test $ac_cv_func_aclsort = yes; then
127          use_acl=1
128        fi
129      fi
130
131      LIBS=$ac_save_LIBS
132    fi
133
134    if test "$enable_acl$use_acl" = yes0; then
135      AC_MSG_ERROR([ACLs enabled but support not detected])
136    elif test "$enable_acl$use_acl" = auto0; then
137      AC_MSG_WARN([libacl development library was not found or not usable.])
138      AC_MSG_WARN([AC_PACKAGE_NAME will be built without ACL support.])
139    fi
140  fi
141  test $gl_need_lib_has_acl && LIB_HAS_ACL=$LIB_ACL
142  AC_SUBST([LIB_ACL])
143  AC_DEFINE_UNQUOTED([USE_ACL], [$use_acl],
144    [Define to nonzero if you want access control list support.])
145  USE_ACL=$use_acl
146  AC_SUBST([USE_ACL])
147])
148
149# gl_ACL_GET_FILE(IF-WORKS, IF-NOT)
150# ---------------------------------
151# If 'acl_get_file' works (does not have a particular bug),
152# run IF-WORKS, otherwise, IF-NOT.
153# When building natively, test for a Darwin 8.7.0 bug, whereby acl_get_file
154# returns NULL, but sets errno = ENOENT for an existing file or directory.
155# When cross-compiling, assume that this old bug no longer applies.
156AC_DEFUN([gl_ACL_GET_FILE],
157[
158  AC_CACHE_CHECK([for working acl_get_file], [gl_cv_func_working_acl_get_file],
159    [gl_cv_func_working_acl_get_file=no
160     AC_LINK_IFELSE(
161       [AC_LANG_PROGRAM(
162          [[#include <sys/types.h>
163           #include <sys/acl.h>
164           #include <errno.h>
165          ]],
166          [[acl_t acl = acl_get_file (".", ACL_TYPE_ACCESS);
167            return acl ? acl_free (acl) != 0 : errno == ENOENT;
168          ]])],
169       [if test $cross_compiling = yes; then
170          gl_cv_func_working_acl_get_file="guessing yes"
171        elif ./conftest$ac_exeext; then
172          gl_cv_func_working_acl_get_file=yes
173        fi])])
174  AS_IF([test "$gl_cv_func_working_acl_get_file" != no], [$1], [$2])
175])
176
177# On GNU/Linux, testing if a file has an acl can be done with the getxattr
178# syscall which doesn't require linking against additional libraries.
179AC_DEFUN([gl_FILE_HAS_ACL],
180[
181  AC_REQUIRE([gl_FUNC_ACL_ARG])
182  if test "$enable_acl" != no; then
183    AC_CACHE_CHECK([for getxattr with XATTR_NAME_POSIX_ACL macros],
184      [gl_cv_getxattr_with_posix_acls],
185      [gl_cv_getxattr_with_posix_acls=no
186       AC_LINK_IFELSE(
187         [AC_LANG_PROGRAM(
188            [[#include <sys/types.h>
189              #include <sys/xattr.h>
190              #include <linux/xattr.h>
191            ]],
192            [[ssize_t a = getxattr (".", XATTR_NAME_POSIX_ACL_ACCESS, 0, 0);
193              ssize_t b = getxattr (".", XATTR_NAME_POSIX_ACL_DEFAULT, 0, 0);
194              return a < 0 || b < 0;
195            ]])],
196         [gl_cv_getxattr_with_posix_acls=yes])])
197  fi
198  if test "$gl_cv_getxattr_with_posix_acls" = yes; then
199    LIB_HAS_ACL=
200    AC_DEFINE([GETXATTR_WITH_POSIX_ACLS], 1,
201      [Define to 1 if getxattr works with XATTR_NAME_POSIX_ACL_ACCESS
202       and XATTR_NAME_POSIX_ACL_DEFAULT.])
203  else
204    dnl Set gl_need_lib_has_acl to a nonempty value, so that any
205    dnl later gl_FUNC_ACL call will set LIB_HAS_ACL=$LIB_ACL.
206    gl_need_lib_has_acl=1
207    LIB_HAS_ACL=$LIB_ACL
208  fi
209  AC_SUBST([LIB_HAS_ACL])
210])
211