X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fxattrs.c;h=307ee380fab183f8b02915f1d585ba80b1d0684b;hb=4aa85f09e755fc827cd5ab6225f20c83cd42245d;hp=dac15f38133b447130cc35c4e2cc266f2a4b5096;hpb=eb3ba7cb06fdd0f8627b8f117d8453e297e18b64;p=debian%2Ftar diff --git a/src/xattrs.c b/src/xattrs.c index dac15f38..307ee380 100644 --- a/src/xattrs.c +++ b/src/xattrs.c @@ -1,6 +1,6 @@ /* Support for extended attributes. - Copyright (C) 2006-2013 Free Software Foundation, Inc. + Copyright (C) 2006-2014 Free Software Foundation, Inc. This file is part of GNU tar. @@ -61,6 +61,7 @@ static struct 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 @@ static int file_has_acl_at (int, 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 @@ -187,7 +199,8 @@ 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, @@ -199,15 +212,23 @@ xattrs__acls_set (struct tar_stat_info const *st, { /* 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) { @@ -695,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 = '+'; } @@ -706,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); @@ -719,7 +740,7 @@ 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;