X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fxattrs.c;h=307ee380fab183f8b02915f1d585ba80b1d0684b;hb=7fe7adcbb985e78aaf9f78051fa26167779be1f6;hp=5a4bf7215b7ca97f78fcba0e0d8dbdf267f23aa0;hpb=3c4e51fad6dbd595a2fb1e34f11e5a804b9b33ab;p=chaz%2Ftar diff --git a/src/xattrs.c b/src/xattrs.c index 5a4bf72..307ee38 100644 --- a/src/xattrs.c +++ b/src/xattrs.c @@ -1,23 +1,23 @@ /* Support for extended attributes. - Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software - Foundation, Inc. + Copyright (C) 2006-2014 Free Software Foundation, Inc. - Written by James Antill, on 2006-07-27. + This file is part of GNU tar. - 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. + GNU tar 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 3 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. + GNU tar 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. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Written by James Antill, on 2006-07-27. */ #include #include @@ -58,9 +58,10 @@ static struct #ifdef HAVE_POSIX_ACLS /* acl-at wrappers, TODO: move to gnulib in future? */ -acl_t acl_get_file_at (int dirfd, const char *file, acl_type_t type); -int acl_set_file_at (int dirfd, const char *file, acl_type_t type, acl_t acl); -int file_has_acl_at (int dirfd, char const *, struct stat const *); +static acl_t acl_get_file_at (int, const char *, acl_type_t); +static int acl_set_file_at (int, const char *, acl_type_t, acl_t); +static int file_has_acl_at (int, char const *, struct stat const *); +static int acl_delete_def_file_at (int, char const *); /* acl_get_file_at */ #define AT_FUNC_NAME acl_get_file_at @@ -88,6 +89,17 @@ int file_has_acl_at (int dirfd, char const *, struct stat const *); #undef AT_FUNC_POST_FILE_PARAM_DECLS #undef AT_FUNC_POST_FILE_ARGS +/* acl_delete_def_file_at */ +#define AT_FUNC_NAME acl_delete_def_file_at +#define AT_FUNC_F1 acl_delete_def_file +#define AT_FUNC_POST_FILE_PARAM_DECLS +#define AT_FUNC_POST_FILE_ARGS +#include "at-func.c" +#undef AT_FUNC_NAME +#undef AT_FUNC_F1 +#undef AT_FUNC_POST_FILE_PARAM_DECLS +#undef AT_FUNC_POST_FILE_ARGS + /* gnulib file_has_acl_at */ #define AT_FUNC_NAME file_has_acl_at #define AT_FUNC_F1 file_has_acl @@ -137,7 +149,7 @@ static char * skip_to_ext_fields (char *ptr) { /* skip tag name (user/group/default/mask) */ - ptr += strcspn (ptr, ":,\n"); + ptr += strcspn (ptr, ":,\n"); if (*ptr != ':') return ptr; @@ -187,27 +199,36 @@ fixup_extra_acl_fields (char *ptr) return ptr; } -/* "system.posix_acl_access" */ +/* Set the "system.posix_acl_access/system.posix_acl_default" extended + attribute. Called only when acls_option > 0. */ static void xattrs__acls_set (struct tar_stat_info const *st, char const *file_name, int type, char *ptr, size_t len, bool def) -{ +{ acl_t acl; if (ptr) { /* assert (strlen (ptr) == len); */ ptr = fixup_extra_acl_fields (ptr); - acl = acl_from_text (ptr); - acls_option = 1; } - else if (acls_option > 0) - acl = perms2acl (st->stat.st_mode); + else if (def) + { + /* No "default" IEEE 1003.1e ACL set for directory. At this moment, + FILE_NAME may already have inherited default acls from parent + directory; clean them up. */ + if (acl_delete_def_file_at (chdir_fd, file_name)) + WARNOPT (WARN_XATTR_WRITE, + (0, errno, + _("acl_delete_def_file_at: Cannot drop default POSIX ACLs " + "for file '%s'"), + file_name)); + return; + } else - return; /* don't call acl functions unless we first hit an ACL, or - --acls was passed explicitly */ + acl = perms2acl (st->stat.st_mode); if (!acl) { @@ -229,7 +250,7 @@ static void xattrs__acls_get_a (int parentfd, const char *file_name, struct tar_stat_info *st, char **ret_ptr, size_t * ret_len) -{ +{ char *val = NULL; ssize_t len; acl_t acl; @@ -261,7 +282,7 @@ static void xattrs__acls_get_d (int parentfd, char const *file_name, struct tar_stat_info *st, char **ret_ptr, size_t * ret_len) -{ +{ char *val = NULL; ssize_t len; acl_t acl; @@ -407,7 +428,7 @@ clear_mask_map (struct xattrs_mask_map *mask_map) } void -xattrs_clear_setup () +xattrs_clear_setup (void) { clear_mask_map (&xattrs_setup.incl); clear_mask_map (&xattrs_setup.excl); @@ -484,6 +505,7 @@ xattrs_xattrs_get (int parentfd, char const *file_name, } } +#ifdef HAVE_XATTRS static void xattrs__fd_set (struct tar_stat_info const *st, char const *file_name, char typeflag, @@ -509,6 +531,7 @@ xattrs__fd_set (struct tar_stat_info const *st, sysname, attr, file_name)); } } +#endif /* lgetfileconat is called against FILE_NAME iff the FD parameter is set to zero, otherwise the fgetfileconat is used against correct file descriptor */ @@ -614,7 +637,7 @@ static bool xattrs_masked_out (const char *kw, bool archiving) { return xattrs_kw_included (kw, archiving) ? - xattrs_kw_excluded (kw, archiving) : true; + xattrs_kw_excluded (kw, archiving) : true; } void @@ -693,7 +716,7 @@ xattrs_print_char (struct tar_stat_info const *st, char *output) if (selinux_context_option > 0 && st->cntx_name) *output = '.'; - if (acls_option && (st->acls_a_len || st->acls_d_len)) + if (acls_option > 0 && (st->acls_a_len || st->acls_d_len)) *output = '+'; } @@ -704,11 +727,11 @@ xattrs_print (struct tar_stat_info const *st) return; /* selinux */ - if (selinux_context_option && st->cntx_name) + if (selinux_context_option > 0 && st->cntx_name) fprintf (stdlis, " s: %s\n", st->cntx_name); /* acls */ - if (acls_option && (st->acls_a_len || st->acls_d_len)) + if (acls_option > 0 && (st->acls_a_len || st->acls_d_len)) { fprintf (stdlis, " a: "); acls_one_line ("", ',', st->acls_a_ptr, st->acls_a_len); @@ -717,10 +740,10 @@ xattrs_print (struct tar_stat_info const *st) } /* xattrs */ - if (xattrs_option && st->xattr_map_size) + if (xattrs_option > 0 && st->xattr_map_size) { int i; - + for (i = 0; i < st->xattr_map_size; ++i) { char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr.");