mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-09-01 02:34:55 +00:00
Add limited support for Solaris 10 ZFS-style ACLs: just enough to
handle file_has_acl. * lib/acl-internal.h, lib/acl_entries.c, lib/file-has-acl.c: New files. * lib/acl.c: Move header inclusions and related macro defns into lib/acl-internal.h. (S_ISLNK): Remove defn, since that's now done for us. (file_has_acl): Move to lib/file-has-acl.c. Call acl_trivial if available. This is the crucial part of the fix. (acl_entries): Move to lib/acl_entries.c. Now extern, since it's shared within the library. Rewrite a bit, partly to make it compatible with the GNU coding style. * m4/acl.m4 (AC_FUNC_ACL): Add AC_LIBOBJ([file-has-acl]). Remove unnecessary double-quotes. Don't test for acl_to_text; the build will catch that. Replace acl_entries if it doesn't exist and it is needed. Check for -lsec and acl_trivial (as used on Solaris 10). * modules/acl (Files): Add lib/acl-internal.h, lib/acl_entries.c, lib/file-has-acl.c. (Depends-on): Add sys_stat, for S_ISLNK.
This commit is contained in:
@@ -1,3 +1,25 @@
|
||||
2007-03-19 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Add limited support for Solaris 10 ZFS-style ACLs: just enough to
|
||||
handle file_has_acl.
|
||||
* lib/acl-internal.h, lib/acl_entries.c, lib/file-has-acl.c: New files.
|
||||
* lib/acl.c: Move header inclusions and related macro defns into
|
||||
lib/acl-internal.h.
|
||||
(S_ISLNK): Remove defn, since that's now done for us.
|
||||
(file_has_acl): Move to lib/file-has-acl.c.
|
||||
Call acl_trivial if available. This is the crucial part of the fix.
|
||||
(acl_entries): Move to lib/acl_entries.c. Now extern, since it's
|
||||
shared within the library. Rewrite a bit, partly to make it compatible
|
||||
with the GNU coding style.
|
||||
* m4/acl.m4 (AC_FUNC_ACL): Add AC_LIBOBJ([file-has-acl]).
|
||||
Remove unnecessary double-quotes.
|
||||
Don't test for acl_to_text; the build will catch that.
|
||||
Replace acl_entries if it doesn't exist and it is needed.
|
||||
Check for -lsec and acl_trivial (as used on Solaris 10).
|
||||
* modules/acl (Files): Add lib/acl-internal.h, lib/acl_entries.c,
|
||||
lib/file-has-acl.c.
|
||||
(Depends-on): Add sys_stat, for S_ISLNK.
|
||||
|
||||
2007-03-19 Ben Pfaff <blp@gnu.org>
|
||||
|
||||
* doc/gnulib.texi: Fix typos.
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* Internal implementation of access control lists.
|
||||
|
||||
Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Written by Paul Eggert and Andreas Gruenbacher. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
# include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
#include "quote.h"
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef ENOSYS
|
||||
# define ENOSYS (-1)
|
||||
#endif
|
||||
#ifndef ENOTSUP
|
||||
# define ENOTSUP (-1)
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FCHMOD
|
||||
# define HAVE_FCHMOD false
|
||||
# define fchmod(fd, mode) (-1)
|
||||
#endif
|
||||
|
||||
#ifndef MIN_ACL_ENTRIES
|
||||
# define MIN_ACL_ENTRIES 4
|
||||
#endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
#ifndef HAVE_ACL_GET_FD
|
||||
# define HAVE_ACL_GET_FD false
|
||||
# define acl_get_fd(fd) (NULL)
|
||||
#endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
#ifndef HAVE_ACL_SET_FD
|
||||
# define HAVE_ACL_SET_FD false
|
||||
# define acl_set_fd(fd, acl) (-1)
|
||||
#endif
|
||||
|
||||
/* Linux-specific */
|
||||
#ifndef HAVE_ACL_EXTENDED_FILE
|
||||
# define HAVE_ACL_EXTENDED_FILE false
|
||||
# define acl_extended_file(name) (-1)
|
||||
#endif
|
||||
|
||||
/* Linux-specific */
|
||||
#ifndef HAVE_ACL_FROM_MODE
|
||||
# define HAVE_ACL_FROM_MODE false
|
||||
# define acl_from_mode(mode) (NULL)
|
||||
#endif
|
||||
|
||||
#define ACL_NOT_WELL_SUPPORTED(Errno) \
|
||||
(Errno == ENOTSUP || Errno == ENOSYS || Errno == EINVAL)
|
||||
|
||||
/* Define a replacement for acl_entries if needed. */
|
||||
#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_FREE && !HAVE_ACL_ENTRIES
|
||||
# define acl_entries rpl_acl_entries
|
||||
int acl_entries (acl_t);
|
||||
#endif
|
||||
@@ -22,97 +22,7 @@
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef S_ISLNK
|
||||
# define S_ISLNK(Mode) 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
# include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
#include "quote.h"
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef ENOSYS
|
||||
# define ENOSYS (-1)
|
||||
#endif
|
||||
#ifndef ENOTSUP
|
||||
# define ENOTSUP (-1)
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FCHMOD
|
||||
# define HAVE_FCHMOD false
|
||||
# define fchmod(fd, mode) (-1)
|
||||
#endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
#ifndef HAVE_ACL_GET_FD
|
||||
# define HAVE_ACL_GET_FD false
|
||||
# define acl_get_fd(fd) (NULL)
|
||||
#endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
#ifndef HAVE_ACL_SET_FD
|
||||
# define HAVE_ACL_SET_FD false
|
||||
# define acl_set_fd(fd, acl) (-1)
|
||||
#endif
|
||||
|
||||
/* Linux-specific */
|
||||
#ifndef HAVE_ACL_EXTENDED_FILE
|
||||
# define HAVE_ACL_EXTENDED_FILE false
|
||||
# define acl_extended_file(name) (-1)
|
||||
#endif
|
||||
|
||||
/* Linux-specific */
|
||||
#ifndef HAVE_ACL_FROM_MODE
|
||||
# define HAVE_ACL_FROM_MODE false
|
||||
# define acl_from_mode(mode) (NULL)
|
||||
#endif
|
||||
|
||||
#define ACL_NOT_WELL_SUPPORTED(Errno) \
|
||||
(Errno == ENOTSUP || Errno == ENOSYS || Errno == EINVAL)
|
||||
|
||||
/* We detect the presence of POSIX 1003.1e (draft 17 -- abandoned) support
|
||||
by checking for HAVE_ACL_GET_FILE, HAVE_ACL_SET_FILE, and HAVE_ACL_FREE.
|
||||
Systems that have acl_get_file, acl_set_file, and acl_free must also
|
||||
have acl_to_text, acl_from_text, and acl_delete_def_file (all defined
|
||||
in the draft); systems that don't would hit #error statements here. */
|
||||
|
||||
#if USE_ACL && HAVE_ACL_GET_FILE && !HAVE_ACL_ENTRIES
|
||||
# ifndef HAVE_ACL_TO_TEXT
|
||||
# error Must have acl_to_text (see POSIX 1003.1e draft 17).
|
||||
# endif
|
||||
|
||||
/* Return the number of entries in ACL. Linux implements acl_entries
|
||||
as a more efficient extension than using this workaround. */
|
||||
|
||||
static int
|
||||
acl_entries (acl_t acl)
|
||||
{
|
||||
char *text = acl_to_text (acl, NULL), *t;
|
||||
int entries;
|
||||
if (text == NULL)
|
||||
return -1;
|
||||
for (entries = 0, t = text; ; t++, entries++) {
|
||||
t = strchr (t, '\n');
|
||||
if (t == NULL)
|
||||
break;
|
||||
}
|
||||
acl_free (text);
|
||||
return entries;
|
||||
}
|
||||
#endif
|
||||
#include "acl-internal.h"
|
||||
|
||||
/* If DESC is a valid file descriptor use fchmod to change the
|
||||
file's mode to MODE on systems that have fchown. On systems
|
||||
@@ -128,69 +38,6 @@ chmod_or_fchmod (const char *name, int desc, mode_t mode)
|
||||
return chmod (name, mode);
|
||||
}
|
||||
|
||||
/* Return 1 if NAME has a nontrivial access control list, 0 if
|
||||
NAME only has no or a base access control list, and -1 on
|
||||
error. SB must be set to the stat buffer of FILE. */
|
||||
|
||||
int
|
||||
file_has_acl (char const *name, struct stat const *sb)
|
||||
{
|
||||
#if USE_ACL && HAVE_ACL && defined GETACLCNT
|
||||
/* This implementation should work on recent-enough versions of HP-UX,
|
||||
Solaris, and Unixware. */
|
||||
|
||||
# ifndef MIN_ACL_ENTRIES
|
||||
# define MIN_ACL_ENTRIES 4
|
||||
# endif
|
||||
|
||||
if (! S_ISLNK (sb->st_mode))
|
||||
{
|
||||
int n = acl (name, GETACLCNT, 0, NULL);
|
||||
return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
|
||||
}
|
||||
#elif USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_FREE
|
||||
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
||||
|
||||
if (! S_ISLNK (sb->st_mode))
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (HAVE_ACL_EXTENDED_FILE)
|
||||
ret = acl_extended_file (name);
|
||||
else
|
||||
{
|
||||
acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
|
||||
if (acl)
|
||||
{
|
||||
ret = (3 < acl_entries (acl));
|
||||
acl_free (acl);
|
||||
if (ret == 0 && S_ISDIR (sb->st_mode))
|
||||
{
|
||||
acl = acl_get_file (name, ACL_TYPE_DEFAULT);
|
||||
if (acl)
|
||||
{
|
||||
ret = (0 < acl_entries (acl));
|
||||
acl_free (acl);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ACL_NOT_WELL_SUPPORTED (errno) ? 0 : -1;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FIXME: Add support for AIX, Irix, and Tru64. Please see Samba's
|
||||
source/lib/sysacls.c file for fix-related ideas. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy access control lists from one file to another. If SOURCE_DESC is
|
||||
a valid file descriptor, use file descriptor operations, else use
|
||||
filename based operations on SRC_NAME. Likewise for DEST_DESC and
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* Return the number of entries in an ACL.
|
||||
|
||||
Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Written by Paul Eggert and Andreas Gruenbacher. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
/* Return the number of entries in ACL. */
|
||||
|
||||
int
|
||||
acl_entries (acl_t acl)
|
||||
{
|
||||
char *t;
|
||||
int entries = 0;
|
||||
char *text = acl_to_text (acl, NULL);
|
||||
if (! text)
|
||||
return -1;
|
||||
for (t = text; *t; t++)
|
||||
entries += (*t == '\n');
|
||||
acl_free (text);
|
||||
return entries;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Test whether a file has a nontrivial access control list.
|
||||
|
||||
Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Written by Paul Eggert and Andreas Gruenbacher. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
/* Return 1 if NAME has a nontrivial access control list, 0 if NAME
|
||||
only has no or a base access control list, and -1 (setting errno)
|
||||
on error. SB must be set to the stat buffer of FILE. */
|
||||
|
||||
int
|
||||
file_has_acl (char const *name, struct stat const *sb)
|
||||
{
|
||||
if (! S_ISLNK (sb->st_mode))
|
||||
{
|
||||
#if USE_ACL && HAVE_ACL_TRIVIAL
|
||||
|
||||
/* Solaris 10, which also has NFSv4 and ZFS style ACLs. */
|
||||
return acl_trivial (name);
|
||||
|
||||
#elif USE_ACL && HAVE_ACL && defined GETACLCNT
|
||||
|
||||
/* Solaris 2.5 through Solaris 9, and contemporaneous versions of
|
||||
HP-UX and Unixware. */
|
||||
int n = acl (name, GETACLCNT, 0, NULL);
|
||||
return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
|
||||
|
||||
#elif USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_FREE
|
||||
|
||||
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
||||
int ret;
|
||||
|
||||
if (HAVE_ACL_EXTENDED_FILE)
|
||||
ret = acl_extended_file (name);
|
||||
else
|
||||
{
|
||||
acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
|
||||
if (acl)
|
||||
{
|
||||
ret = (3 < acl_entries (acl));
|
||||
acl_free (acl);
|
||||
if (ret == 0 && S_ISDIR (sb->st_mode))
|
||||
{
|
||||
acl = acl_get_file (name, ACL_TYPE_DEFAULT);
|
||||
if (acl)
|
||||
{
|
||||
ret = (0 < acl_entries (acl));
|
||||
acl_free (acl);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ACL_NOT_WELL_SUPPORTED (errno) ? 0 : -1;
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIXME: Add support for AIX, Irix, and Tru64. Please see Samba's
|
||||
source/lib/sysacls.c file for fix-related ideas. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# acl.m4 - check for access control list (ACL) primitives
|
||||
|
||||
# Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
@@ -10,6 +10,7 @@
|
||||
AC_DEFUN([AC_FUNC_ACL],
|
||||
[
|
||||
AC_LIBOBJ([acl])
|
||||
AC_LIBOBJ([file-has-acl])
|
||||
|
||||
dnl Prerequisites of lib/acl.c.
|
||||
AC_CHECK_HEADERS(sys/acl.h)
|
||||
@@ -21,18 +22,33 @@ AC_DEFUN([AC_FUNC_ACL],
|
||||
AC_SUBST(LIB_ACL)
|
||||
AC_CHECK_HEADERS(acl/libacl.h)
|
||||
AC_CHECK_FUNCS(acl_get_file acl_get_fd acl_set_file acl_set_fd \
|
||||
acl_free acl_from_mode acl_from_text acl_to_text \
|
||||
acl_delete_def_file acl_entries acl_extended_file)
|
||||
if test "$ac_cv_header_sys_acl_h" = yes; then
|
||||
acl_free acl_from_mode acl_from_text \
|
||||
acl_delete_def_file acl_extended_file)
|
||||
if test $ac_cv_header_sys_acl_h = yes; then
|
||||
use_acl=1
|
||||
if test "$ac_cv_func_acl_get_file" = yes; then
|
||||
if test $ac_cv_func_acl_get_file = yes; then
|
||||
# If we detect the acl_get_file bug, disable ACL support altogether.
|
||||
gl_ACL_GET_FILE( , [use_acl=0])
|
||||
fi
|
||||
else
|
||||
use_acl=0
|
||||
fi
|
||||
if test $use_acl = 1 &&
|
||||
test $ac_cv_func_acl_get_file = yes &&
|
||||
test $ac_cv_func_acl_free = yes; then
|
||||
AC_REPLACE_FUNCS([acl_entries])
|
||||
fi
|
||||
LIBS="$ac_save_LIBS"
|
||||
if test $use_acl = 1; then
|
||||
ac_save_LIBS="$LIBS"
|
||||
AC_SEARCH_LIBS([acl_trivial], [sec],
|
||||
[AC_DEFINE([HAVE_ACL_TRIVIAL], 1,
|
||||
[Define to 1 if you have the `acl_trivial' function.])
|
||||
test "$ac_cv_search_acl_trivial" = "none required" ||
|
||||
LIB_ACL_TRIVIAL="$ac_cv_search_acl_trivial"])
|
||||
AC_SUBST([LIB_ACL_TRIVIAL])
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(USE_ACL, $use_acl,
|
||||
[Define if you want access control list support.])
|
||||
])
|
||||
|
||||
@@ -4,11 +4,15 @@ Access control lists of files. (Unportable.)
|
||||
Files:
|
||||
lib/acl.h
|
||||
lib/acl.c
|
||||
lib/acl-internal.h
|
||||
lib/acl_entries.c
|
||||
lib/file-has-acl.c
|
||||
m4/acl.m4
|
||||
|
||||
Depends-on:
|
||||
error
|
||||
quote
|
||||
sys_stat
|
||||
|
||||
configure.ac:
|
||||
AC_FUNC_ACL
|
||||
|
||||
Reference in New Issue
Block a user