X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=653e2a0d2f879f4bf95442275928ba69a4d129cb;hb=3b219f943e6b0b14c8f30176951b9339ae3ebaf4;hp=9897e82a61bd1d18c4c90743f236477516205ae0;hpb=cc40c57a37b1e443a5088fdda0fbb3687b1f4773;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index 9897e82..653e2a0 100644 --- a/src/extract.c +++ b/src/extract.c @@ -144,7 +144,7 @@ set_mode (char const *file_name, char typeflag) { mode_t mode; - bool failed; + int chmod_errno; if (0 < same_permissions_option && permstatus != INTERDIR_PERMSTATUS) @@ -187,18 +187,24 @@ set_mode (char const *file_name, 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. */ @@ -515,7 +521,7 @@ file_newer_p (const char *file_name, struct tar_stat_info *tar_stat) properly restored on returning RECOVER_NO. */ static int -maybe_recoverable (char *file_name, int *interdir_made) +maybe_recoverable (char *file_name, bool *interdir_made) { int e = errno; @@ -560,7 +566,7 @@ maybe_recoverable (char *file_name, int *interdir_made) errno = ENOENT; return RECOVER_NO; } - *interdir_made = 1; + *interdir_made = true; return RECOVER_OK; default: @@ -641,7 +647,7 @@ extract_dir (char *file_name, int typeflag) { int status; mode_t mode; - int interdir_made = 0; + bool interdir_made = false; /* Save 'root device' to avoid purging mount points. */ if (one_file_system_option && root_device == 0) @@ -772,7 +778,7 @@ extract_file (char *file_name, int typeflag) int status; size_t count; size_t written; - int interdir_made = 0; + bool interdir_made = false; mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask; mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; @@ -879,7 +885,7 @@ extract_file (char *file_name, int typeflag) process. */ static int -create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made) +create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made) { int fd; struct stat st; @@ -961,7 +967,7 @@ create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made) static int extract_link (char *file_name, int typeflag) { - int interdir_made = 0; + bool interdir_made = false; char const *link_name; int rc; @@ -1020,7 +1026,7 @@ static int extract_symlink (char *file_name, int typeflag) { #ifdef HAVE_SYMLINK - int interdir_made = 0; + bool interdir_made = false; if (! absolute_names_option && (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name) @@ -1062,7 +1068,7 @@ extract_symlink (char *file_name, int typeflag) static int extract_node (char *file_name, int typeflag) { - int interdir_made = 0; + bool interdir_made = false; mode_t mode = current_stat_info.stat.st_mode & ~ current_umask; mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; @@ -1093,7 +1099,7 @@ static int extract_fifo (char *file_name, int typeflag) { int status; - int interdir_made = 0; + bool interdir_made = false; mode_t mode = current_stat_info.stat.st_mode & ~ current_umask; mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; @@ -1271,9 +1277,6 @@ extract_archive (void) 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]