|
rpm-build |
0a0c83 |
/* Copy POSIX 1003.1e draft 17 (abandoned) ACLs between files. */
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* Copyright (C) 2002 Andreas Gruenbacher <agruen@suse.de>, SuSE Linux AG.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is free software; you can redistribute it and/or
|
|
rpm-build |
0a0c83 |
modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License as published by the Free Software Foundation; either
|
|
rpm-build |
0a0c83 |
version 2.1 of the License, or (at your option) any later version.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is distributed in the hope that it will be useful,
|
|
rpm-build |
0a0c83 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0a0c83 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0a0c83 |
Lesser General Public License for more details.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License along with this library; if not, write to the Free Software
|
|
rpm-build |
0a0c83 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if defined (HAVE_CONFIG_H)
|
|
rpm-build |
0a0c83 |
#include "config.h"
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
#if defined(HAVE_LIBACL_LIBACL_H)
|
|
rpm-build |
0a0c83 |
# include "libacl.h"
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#include <sys/types.h>
|
|
rpm-build |
0a0c83 |
#include <sys/stat.h>
|
|
rpm-build |
0a0c83 |
#include <unistd.h>
|
|
rpm-build |
0a0c83 |
#include <stdlib.h>
|
|
rpm-build |
0a0c83 |
#include <errno.h>
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if defined(HAVE_SYS_ACL_H)
|
|
rpm-build |
0a0c83 |
#include <sys/acl.h>
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if defined(HAVE_ACL_LIBACL_H)
|
|
rpm-build |
0a0c83 |
#include <acl/libacl.h>
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define ERROR_CONTEXT_MACROS
|
|
rpm-build |
0a0c83 |
#ifdef HAVE_ATTR_ERROR_CONTEXT_H
|
|
rpm-build |
0a0c83 |
#include <attr/error_context.h>
|
|
rpm-build |
0a0c83 |
#else
|
|
rpm-build |
0a0c83 |
#include "error_context.h"
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if !defined(ENOTSUP)
|
|
rpm-build |
0a0c83 |
# define ENOTSUP (-1)
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if !defined(HAVE_ACL_FREE)
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
acl_free(void *obj_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
free (obj_p);
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if !defined(HAVE_ACL_ENTRIES)
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
acl_entries(acl_t acl)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
# if defined(HAVE_ACL_GET_ENTRY)
|
|
rpm-build |
0a0c83 |
/* POSIX 1003.1e draft 17 (abandoned) compatible version. */
|
|
rpm-build |
0a0c83 |
acl_entry_t entry;
|
|
rpm-build |
0a0c83 |
int entries = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int entries = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
|
|
rpm-build |
0a0c83 |
if (entries > 0) {
|
|
rpm-build |
0a0c83 |
while (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) > 0)
|
|
rpm-build |
0a0c83 |
entries++;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return entries;
|
|
rpm-build |
0a0c83 |
# else
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
# endif
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#if !defined(HAVE_ACL_FROM_MODE) && defined(HAVE_ACL_FROM_TEXT)
|
|
rpm-build |
0a0c83 |
# define HAVE_ACL_FROM_MODE
|
|
rpm-build |
0a0c83 |
static acl_t
|
|
rpm-build |
0a0c83 |
acl_from_mode(mode_t mode)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char acl_text[] = "u::---,g::---,o::---";
|
|
rpm-build |
0a0c83 |
acl_t acl;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (mode & S_IRUSR) acl_text[ 3] = 'r';
|
|
rpm-build |
0a0c83 |
if (mode & S_IWUSR) acl_text[ 4] = 'w';
|
|
rpm-build |
0a0c83 |
if (mode & S_IXUSR) acl_text[ 5] = 'x';
|
|
rpm-build |
0a0c83 |
if (mode & S_IRGRP) acl_text[10] = 'r';
|
|
rpm-build |
0a0c83 |
if (mode & S_IWGRP) acl_text[11] = 'w';
|
|
rpm-build |
0a0c83 |
if (mode & S_IXGRP) acl_text[12] = 'x';
|
|
rpm-build |
0a0c83 |
if (mode & S_IROTH) acl_text[17] = 'r';
|
|
rpm-build |
0a0c83 |
if (mode & S_IWOTH) acl_text[18] = 'w';
|
|
rpm-build |
0a0c83 |
if (mode & S_IXOTH) acl_text[19] = 'x';
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
return acl_from_text (acl_text);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* Set the access control list of path to the permissions defined by mode. */
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
set_acl (char const *path, mode_t mode, struct error_context *ctx)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
int ret = 0;
|
|
rpm-build |
0a0c83 |
#if defined(HAVE_ACL_FROM_MODE) && defined(HAVE_ACL_SET_FILE)
|
|
rpm-build |
0a0c83 |
/* POSIX 1003.1e draft 17 (abandoned) specific version. */
|
|
rpm-build |
0a0c83 |
acl_t acl = acl_from_mode (mode);
|
|
rpm-build |
0a0c83 |
if (!acl) {
|
|
rpm-build |
0a0c83 |
error (ctx, "");
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (acl_set_file (path, ACL_TYPE_ACCESS, acl) != 0) {
|
|
rpm-build |
0a0c83 |
ret = -1;
|
|
rpm-build |
0a0c83 |
if (errno == ENOTSUP || errno == ENOSYS) {
|
|
rpm-build |
0a0c83 |
(void) acl_free (acl);
|
|
rpm-build |
0a0c83 |
goto chmod_only;
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, path);
|
|
rpm-build |
0a0c83 |
error (ctx, _("setting permissions for %s"), qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
(void) acl_free (acl);
|
|
rpm-build |
0a0c83 |
if (ret == 0 && S_ISDIR (mode)) {
|
|
rpm-build |
0a0c83 |
# if defined(HAVE_ACL_DELETE_DEF_FILE)
|
|
rpm-build |
0a0c83 |
ret = acl_delete_def_file (path);
|
|
rpm-build |
0a0c83 |
# else
|
|
rpm-build |
0a0c83 |
acl = acl_init (0);
|
|
rpm-build |
0a0c83 |
ret = acl_set_file (path, ACL_TYPE_DEFAULT, acl);
|
|
rpm-build |
0a0c83 |
(void) acl_free (acl);
|
|
rpm-build |
0a0c83 |
# endif
|
|
rpm-build |
0a0c83 |
if (ret != 0) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, path);
|
|
rpm-build |
0a0c83 |
error (ctx, _( "setting permissions for %s"), qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return ret;
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
chmod_only:
|
|
rpm-build |
0a0c83 |
ret = chmod (path, mode);
|
|
rpm-build |
0a0c83 |
if (ret != 0) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, path);
|
|
rpm-build |
0a0c83 |
error (ctx, _("setting permissions for %s"), qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return ret;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* Copy the permissions of src_path to dst_path. This includes the
|
|
rpm-build |
0a0c83 |
file mode permission bits and ACLs. File ownership is not copied.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
int
|
|
rpm-build |
0a0c83 |
perm_copy_file (const char *src_path, const char *dst_path,
|
|
rpm-build |
0a0c83 |
struct error_context *ctx)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
#if defined(HAVE_ACL_GET_FILE) && defined(HAVE_ACL_SET_FILE)
|
|
rpm-build |
0a0c83 |
acl_t acl;
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
struct stat st;
|
|
rpm-build |
0a0c83 |
int ret = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
ret = stat(src_path, &st);
|
|
rpm-build |
0a0c83 |
if (ret != 0) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, src_path);
|
|
rpm-build |
0a0c83 |
error (ctx, "%s", qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
#if defined(HAVE_ACL_GET_FILE) && defined(HAVE_ACL_SET_FILE)
|
|
rpm-build |
0a0c83 |
/* POSIX 1003.1e draft 17 (abandoned) specific version. */
|
|
rpm-build |
0a0c83 |
acl = acl_get_file (src_path, ACL_TYPE_ACCESS);
|
|
rpm-build |
0a0c83 |
if (acl == NULL) {
|
|
rpm-build |
0a0c83 |
ret = -1;
|
|
rpm-build |
0a0c83 |
if (errno == ENOSYS || errno == ENOTSUP)
|
|
rpm-build |
0a0c83 |
ret = set_acl (dst_path, st.st_mode, ctx);
|
|
rpm-build |
0a0c83 |
else {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, src_path);
|
|
rpm-build |
0a0c83 |
error (ctx, "%s", qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return ret;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl) != 0) {
|
|
rpm-build |
0a0c83 |
int saved_errno = errno;
|
|
rpm-build |
0a0c83 |
__apply_mask_to_mode(&st.st_mode, acl);
|
|
rpm-build |
0a0c83 |
ret = chmod (dst_path, st.st_mode);
|
|
rpm-build |
0a0c83 |
if ((errno != ENOSYS && errno != ENOTSUP) ||
|
|
rpm-build |
0a0c83 |
acl_entries (acl) != 3) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, dst_path);
|
|
rpm-build |
0a0c83 |
errno = saved_errno;
|
|
rpm-build |
0a0c83 |
error (ctx, _("preserving permissions for %s"), qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
ret = -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
(void) acl_free (acl);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (ret == 0 && S_ISDIR (st.st_mode)) {
|
|
rpm-build |
0a0c83 |
acl = acl_get_file (src_path, ACL_TYPE_DEFAULT);
|
|
rpm-build |
0a0c83 |
if (acl == NULL) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, src_path);
|
|
rpm-build |
0a0c83 |
error (ctx, "%s", qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
# if defined(HAVE_ACL_DELETE_DEF_FILE)
|
|
rpm-build |
0a0c83 |
if (acl_entries(acl) == 0)
|
|
rpm-build |
0a0c83 |
ret = acl_delete_def_file(dst_path);
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
ret = acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl);
|
|
rpm-build |
0a0c83 |
# else
|
|
rpm-build |
0a0c83 |
ret = acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl);
|
|
rpm-build |
0a0c83 |
# endif
|
|
rpm-build |
0a0c83 |
if (ret != 0) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, dst_path);
|
|
rpm-build |
0a0c83 |
error (ctx, _("preserving permissions for %s"), qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
(void) acl_free(acl);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return ret;
|
|
rpm-build |
0a0c83 |
#else
|
|
rpm-build |
0a0c83 |
/* POSIX.1 version. */
|
|
rpm-build |
0a0c83 |
ret = chmod (dst_path, st.st_mode);
|
|
rpm-build |
0a0c83 |
if (ret != 0) {
|
|
rpm-build |
0a0c83 |
const char *qpath = quote (ctx, dst_path);
|
|
rpm-build |
0a0c83 |
error (ctx, _("setting permissions for %s"), qpath);
|
|
rpm-build |
0a0c83 |
quote_free (ctx, qpath);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return ret;
|
|
rpm-build |
0a0c83 |
#endif
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|