Fix Solaris bug where chmod fails if we don't have PRIV_SYS_LINKDIR
* gnulib.modules: Add priv-set. * src/extract.c (set_mode, extract_archive): Restore PRIV_SYS_LINKDIR on chmod failure. * src/tar.c (main): Drop PRIV_SYS_LINKDIR on startup.
This commit is contained in:
committed by
Sergey Poznyakoff
parent
0d6720288b
commit
b216fed634
@@ -31,6 +31,7 @@ localcharset
|
||||
mkdtemp
|
||||
modechange
|
||||
obstack
|
||||
priv-set
|
||||
quote
|
||||
quotearg
|
||||
rpmatch
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <utimens.h>
|
||||
#include <errno.h>
|
||||
#include <xgetcwd.h>
|
||||
#include <priv-set.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -144,7 +145,8 @@ set_mode (char const *file_name,
|
||||
char typeflag)
|
||||
{
|
||||
mode_t mode;
|
||||
|
||||
bool failed;
|
||||
|
||||
if (0 < same_permissions_option
|
||||
&& permstatus != INTERDIR_PERMSTATUS)
|
||||
{
|
||||
@@ -186,7 +188,17 @@ set_mode (char const *file_name,
|
||||
mode = cur_info->st_mode ^ invert_permissions;
|
||||
}
|
||||
|
||||
if (chmod (file_name, mode) != 0)
|
||||
failed = chmod (file_name, mode) != 0;
|
||||
if (failed && errno == EPERM)
|
||||
{
|
||||
/* On Solaris, chmod may fail if we don't have PRIV_ALL. */
|
||||
if (priv_set_restore_linkdir () == 0)
|
||||
{
|
||||
failed = chmod (file_name, mode) != 0;
|
||||
priv_set_remove_linkdir ();
|
||||
}
|
||||
}
|
||||
if (failed)
|
||||
chmod_error_details (file_name, mode);
|
||||
}
|
||||
|
||||
@@ -1218,6 +1230,9 @@ extract_archive (void)
|
||||
char typeflag;
|
||||
tar_extractor_t fun;
|
||||
|
||||
/* Try to disable the ability to unlink a directory. */
|
||||
priv_set_remove_linkdir ();
|
||||
|
||||
set_next_block_after (current_header);
|
||||
decode_header (current_header, ¤t_stat_info, ¤t_format, 1);
|
||||
if (!current_stat_info.file_name[0]
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <version-etc.h>
|
||||
#include <xstrtol.h>
|
||||
#include <stdopen.h>
|
||||
#include <priv-set.h>
|
||||
|
||||
/* Local declarations. */
|
||||
|
||||
@@ -2459,6 +2460,9 @@ main (int argc, char **argv)
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
|
||||
/* Try to disable the ability to unlink a directory. */
|
||||
priv_set_remove_linkdir ();
|
||||
|
||||
/* Decode options. */
|
||||
|
||||
decode_options (argc, argv);
|
||||
|
||||
Reference in New Issue
Block a user