char typeflag)
{
mode_t mode;
- bool failed;
+ int chmod_errno;
if (0 < same_permissions_option
&& permstatus != INTERDIR_PERMSTATUS)
mode = cur_info->st_mode ^ invert_permissions;
}
- failed = chmod (file_name, mode) != 0;
- if (failed && errno == EPERM)
+ chmod_errno = chmod (file_name, mode) == 0 ? 0 : errno;
+ if (chmod_errno == EPERM && (mode & S_ISUID) != 0)
{
- /* On Solaris, chmod may fail if we don't have PRIV_ALL. */
+ /* On Solaris, chmod may fail if we don't have PRIV_ALL, because
+ setuid-root files would otherwise be a backdoor. See
+ http://opensolaris.org/jive/thread.jspa?threadID=95826
+ (2009-09-03). */
if (priv_set_restore_linkdir () == 0)
{
- failed = chmod (file_name, mode) != 0;
+ chmod_errno = chmod (file_name, mode) == 0 ? 0 : errno;
priv_set_remove_linkdir ();
}
}
- if (failed)
- chmod_error_details (file_name, mode);
+ if (chmod_errno)
+ {
+ errno = chmod_errno;
+ chmod_error_details (file_name, mode);
+ }
}
/* Check time after successfully setting FILE_NAME's time stamp to T. */
fatal_exit_hook = extract_finish;
- /* Try to disable the ability to unlink a directory. */
- priv_set_remove_linkdir ();
-
set_next_block_after (current_header);
if (!current_stat_info.file_name[0]
/* System-dependent calls for tar.
Copyright (C) 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
+ 2008, 2010 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
#include <system.h>
#include "common.h"
+#include <priv-set.h>
#include <rmt.h>
#include <signal.h>
child = xfork ();
if (child == 0)
{
+ priv_set_restore_linkdir ();
execlp (shell, "-sh", "-i", (char *) 0);
exec_fatal (shell);
}
}
xdup2 (archive, STDOUT_FILENO);
}
+ priv_set_restore_linkdir ();
execlp (use_compress_program_option, use_compress_program_option, NULL);
exec_fatal (use_compress_program_option);
}
xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
xclose (child_pipe[PREAD]);
+ priv_set_restore_linkdir ();
execlp (use_compress_program_option, use_compress_program_option,
(char *) 0);
exec_fatal (use_compress_program_option);
if (archive < 0)
open_fatal (archive_name_array[0]);
xdup2 (archive, STDIN_FILENO);
+ priv_set_restore_linkdir ();
execlp (use_compress_program_option, use_compress_program_option,
"-d", (char *) 0);
exec_fatal (use_compress_program_option);
xdup2 (child_pipe[PREAD], STDIN_FILENO);
xclose (child_pipe[PWRITE]);
+ priv_set_restore_linkdir ();
execlp (use_compress_program_option, use_compress_program_option,
"-d", (char *) 0);
exec_fatal (use_compress_program_option);
argv[2] = to_command_option;
argv[3] = NULL;
+ priv_set_restore_linkdir ();
execv ("/bin/sh", argv);
exec_fatal (file_name);
argv[2] = (char *) info_script_option;
argv[3] = NULL;
+ priv_set_restore_linkdir ();
execv (argv[0], argv);
exec_fatal (info_script_option);
argv[2] = (char *) script_name;
argv[3] = NULL;
+ priv_set_restore_linkdir ();
execv (argv[0], argv);
exec_fatal (script_name);