|
Radek Brich |
c94c071 |
Redhat-bugzilla: 430835
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
* revert make_path code to previous state, which worked better
|
|
Radek Brich |
c94c071 |
* this can be dropped when permission issues are solved in upstream
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
diff -up cpio-2.9/src/extern.h.dir_perm cpio-2.9/src/extern.h
|
|
Radek Brich |
c94c071 |
--- cpio-2.9/src/extern.h.dir_perm 2007-06-28 14:59:38.000000000 +0200
|
|
Radek Brich |
c94c071 |
+++ cpio-2.9/src/extern.h 2008-03-03 11:57:43.000000000 +0100
|
|
Radek Brich |
c94c071 |
@@ -140,8 +140,8 @@ void process_args (int argc, char *argv[
|
|
Radek Brich |
c94c071 |
void initialize_buffers (void);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
/* makepath.c */
|
|
Radek Brich |
c94c071 |
-int make_path (char *argpath, uid_t owner, gid_t group,
|
|
Radek Brich |
c94c071 |
- const char *verbose_fmt_string);
|
|
Radek Brich |
c94c071 |
+int make_path (char *argpath, int mode, int parent_mode,
|
|
Radek Brich |
c94c071 |
+ uid_t owner, gid_t group, char *verbose_fmt_string);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
/* tar.c */
|
|
Radek Brich |
c94c071 |
void write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des);
|
|
Radek Brich |
c94c071 |
diff -up cpio-2.9/src/util.c.dir_perm cpio-2.9/src/util.c
|
|
Radek Brich |
c94c071 |
--- cpio-2.9/src/util.c.dir_perm 2007-06-28 15:04:51.000000000 +0200
|
|
Radek Brich |
c94c071 |
+++ cpio-2.9/src/util.c 2008-03-03 11:45:00.000000000 +0100
|
|
Radek Brich |
c94c071 |
@@ -618,14 +618,7 @@ create_all_directories (char *name)
|
|
Radek Brich |
c94c071 |
error (2, 0, _("virtual memory exhausted"));
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
if (dir[0] != '.' || dir[1] != '\0')
|
|
Radek Brich |
c94c071 |
- {
|
|
Radek Brich |
c94c071 |
- const char *fmt;
|
|
Radek Brich |
c94c071 |
- if (warn_option & CPIO_WARN_INTERDIR)
|
|
Radek Brich |
c94c071 |
- fmt = _("Creating intermediate directory `%s'");
|
|
Radek Brich |
c94c071 |
- else
|
|
Radek Brich |
c94c071 |
- fmt = NULL;
|
|
Radek Brich |
c94c071 |
- make_path (dir, -1, -1, fmt);
|
|
Radek Brich |
c94c071 |
- }
|
|
Radek Brich |
c94c071 |
+ make_path (dir, mode, 0700, -1, -1, (char *) NULL);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
free (dir);
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
diff -up cpio-2.9/src/copyin.c.dir_perm cpio-2.9/src/copyin.c
|
|
Radek Brich |
c94c071 |
--- cpio-2.9/src/copyin.c.dir_perm 2008-03-03 11:45:00.000000000 +0100
|
|
Radek Brich |
c94c071 |
+++ cpio-2.9/src/copyin.c 2008-03-03 11:45:00.000000000 +0100
|
|
Radek Brich |
c94c071 |
@@ -186,12 +186,11 @@ list_file(struct cpio_file_stat* file_hd
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
static int
|
|
Radek Brich |
c94c071 |
try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des,
|
|
Radek Brich |
c94c071 |
- int *existing_dir, mode_t *existing_mode)
|
|
Radek Brich |
c94c071 |
+ int *existing_dir)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
struct stat file_stat;
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
*existing_dir = false;
|
|
Radek Brich |
c94c071 |
- *existing_mode = 0;
|
|
Radek Brich |
c94c071 |
if (lstat (file_hdr->c_name, &file_stat) == 0)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
if (S_ISDIR (file_stat.st_mode)
|
|
Radek Brich |
c94c071 |
@@ -201,7 +200,6 @@ try_existing_file (struct cpio_file_stat
|
|
Radek Brich |
c94c071 |
we are trying to create, don't complain about
|
|
Radek Brich |
c94c071 |
it. */
|
|
Radek Brich |
c94c071 |
*existing_dir = true;
|
|
Radek Brich |
c94c071 |
- *existing_mode = file_stat.st_mode;
|
|
Radek Brich |
c94c071 |
return 0;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
else if (!unconditional_flag
|
|
Radek Brich |
c94c071 |
@@ -569,7 +567,7 @@ copyin_regular_file (struct cpio_file_st
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
static void
|
|
Radek Brich |
c94c071 |
-copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir, mode_t existing_mode)
|
|
Radek Brich |
c94c071 |
+copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir)
|
|
Radek Brich |
e95f529 |
{
|
|
Radek Brich |
e95f529 |
int res; /* Result of various function calls. */
|
|
Radek Brich |
e95f529 |
#ifdef HPUX_CDF
|
|
Radek Brich |
c94c071 |
@@ -612,22 +610,14 @@ copyin_directory (struct cpio_file_stat
|
|
Radek Brich |
c94c071 |
cdf_flag = 1;
|
|
Radek Brich |
e95f529 |
}
|
|
Radek Brich |
c94c071 |
#endif
|
|
Radek Brich |
c94c071 |
- res = mkdir (file_hdr->c_name, file_hdr->c_mode & ~077);
|
|
Radek Brich |
c94c071 |
+ res = mkdir (file_hdr->c_name, file_hdr->c_mode);
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
else
|
|
Radek Brich |
c94c071 |
- {
|
|
Radek Brich |
c94c071 |
- if (!no_chown_flag && (existing_mode & 077) != 0
|
|
Radek Brich |
c94c071 |
- && chmod (file_hdr->c_name, existing_mode & 07700) < 0)
|
|
Radek Brich |
c94c071 |
- {
|
|
Radek Brich |
c94c071 |
- error (0, errno, "%s: chmod", file_hdr->c_name);
|
|
Radek Brich |
c94c071 |
- return;
|
|
Radek Brich |
c94c071 |
- }
|
|
Radek Brich |
c94c071 |
- res = 0;
|
|
Radek Brich |
c94c071 |
- }
|
|
Radek Brich |
c94c071 |
+ res = 0;
|
|
Radek Brich |
c94c071 |
if (res < 0 && create_dir_flag)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
create_all_directories (file_hdr->c_name);
|
|
Radek Brich |
c94c071 |
- res = mkdir (file_hdr->c_name, file_hdr->c_mode & ~077);
|
|
Radek Brich |
c94c071 |
+ res = mkdir (file_hdr->c_name, file_hdr->c_mode);
|
|
Radek Brich |
e95f529 |
}
|
|
Radek Brich |
c94c071 |
if (res < 0)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
@@ -702,12 +692,12 @@ copyin_device (struct cpio_file_stat* fi
|
|
Radek Brich |
c94c071 |
return;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
- res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077,
|
|
Radek Brich |
c94c071 |
+ res = mknod (file_hdr->c_name, file_hdr->c_mode,
|
|
Radek Brich |
c94c071 |
makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
|
|
Radek Brich |
c94c071 |
if (res < 0 && create_dir_flag)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
create_all_directories (file_hdr->c_name);
|
|
Radek Brich |
c94c071 |
- res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077,
|
|
Radek Brich |
c94c071 |
+ res = mknod (file_hdr->c_name, file_hdr->c_mode,
|
|
Radek Brich |
c94c071 |
makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
if (res < 0)
|
|
Radek Brich |
c94c071 |
@@ -782,10 +772,9 @@ static void
|
|
Radek Brich |
c94c071 |
copyin_file (struct cpio_file_stat* file_hdr, int in_file_des)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
int existing_dir;
|
|
Radek Brich |
c94c071 |
- mode_t existing_mode;
|
|
Radek Brich |
e95f529 |
|
|
Radek Brich |
c94c071 |
if (!to_stdout_option
|
|
Radek Brich |
c94c071 |
- && try_existing_file (file_hdr, in_file_des, &existing_dir, &existing_mode) < 0)
|
|
Radek Brich |
c94c071 |
+ && try_existing_file (file_hdr, in_file_des, &existing_dir) < 0)
|
|
Radek Brich |
c94c071 |
return;
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
/* Do the real copy or link. */
|
|
Radek Brich |
c94c071 |
@@ -796,7 +785,7 @@ copyin_file (struct cpio_file_stat* file
|
|
Radek Brich |
c94c071 |
break;
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
case CP_IFDIR:
|
|
Radek Brich |
c94c071 |
- copyin_directory(file_hdr, existing_dir, existing_mode);
|
|
Radek Brich |
c94c071 |
+ copyin_directory (file_hdr, existing_dir);
|
|
Radek Brich |
c94c071 |
break;
|
|
Radek Brich |
e95f529 |
|
|
Radek Brich |
c94c071 |
case CP_IFCHR:
|
|
Radek Brich |
c94c071 |
@@ -1573,8 +1562,6 @@ process_copy_in ()
|
|
Radek Brich |
c94c071 |
if (dot_flag)
|
|
Radek Brich |
c94c071 |
fputc ('\n', stderr);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
- apply_delayed_set_stat ();
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
if (append_flag)
|
|
Radek Brich |
c94c071 |
return;
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
diff -up cpio-2.9/src/makepath.c.dir_perm cpio-2.9/src/makepath.c
|
|
Radek Brich |
c94c071 |
--- cpio-2.9/src/makepath.c.dir_perm 2007-06-28 15:09:47.000000000 +0200
|
|
Radek Brich |
c94c071 |
+++ cpio-2.9/src/makepath.c 2008-03-03 11:45:00.000000000 +0100
|
|
Radek Brich |
c94c071 |
@@ -1,9 +1,9 @@
|
|
Radek Brich |
c94c071 |
/* makepath.c -- Ensure that a directory path exists.
|
|
Radek Brich |
c94c071 |
- Copyright (C) 1990, 2006, 2007 Free Software Foundation, Inc.
|
|
Radek Brich |
c94c071 |
+ Copyright (C) 1990, 2006 Free Software Foundation, Inc.
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
This program is free software; you can redistribute it and/or modify
|
|
Radek Brich |
c94c071 |
it under the terms of the GNU General Public License as published by
|
|
Radek Brich |
c94c071 |
- the Free Software Foundation; either version 3, or (at your option)
|
|
Radek Brich |
c94c071 |
+ the Free Software Foundation; either version 2, or (at your option)
|
|
Radek Brich |
c94c071 |
any later version.
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
This program is distributed in the hope that it will be useful,
|
|
Radek Brich |
c94c071 |
@@ -29,15 +29,14 @@
|
|
Radek Brich |
c94c071 |
#include <stdio.h>
|
|
Radek Brich |
c94c071 |
#include <sys/types.h>
|
|
Radek Brich |
c94c071 |
#include <sys/stat.h>
|
|
Radek Brich |
c94c071 |
-#include "cpiohdr.h"
|
|
Radek Brich |
c94c071 |
-#include "dstring.h"
|
|
Radek Brich |
c94c071 |
-#include "extern.h"
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
/* Ensure that the directory ARGPATH exists.
|
|
Radek Brich |
c94c071 |
Remove any trailing slashes from ARGPATH before calling this function.
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
- Make all directory components that don't already exist with
|
|
Radek Brich |
c94c071 |
- permissions 700.
|
|
Radek Brich |
c94c071 |
+ Make any leading directories that don't already exist, with
|
|
Radek Brich |
c94c071 |
+ permissions PARENT_MODE.
|
|
Radek Brich |
c94c071 |
+ If the last element of ARGPATH does not exist, create it as
|
|
Radek Brich |
c94c071 |
+ a new directory with permissions MODE.
|
|
Radek Brich |
c94c071 |
If OWNER and GROUP are non-negative, make them the UID and GID of
|
|
Radek Brich |
c94c071 |
created directories.
|
|
Radek Brich |
c94c071 |
If VERBOSE_FMT_STRING is nonzero, use it as a printf format
|
|
Radek Brich |
c94c071 |
@@ -49,26 +48,48 @@
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
int
|
|
Radek Brich |
c94c071 |
make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
+ int mode,
|
|
Radek Brich |
c94c071 |
+ int parent_mode,
|
|
Radek Brich |
c94c071 |
uid_t owner,
|
|
Radek Brich |
c94c071 |
gid_t group,
|
|
Radek Brich |
c94c071 |
- const char *verbose_fmt_string)
|
|
Radek Brich |
c94c071 |
+ char *verbose_fmt_string)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
char *dirpath; /* A copy we can scribble NULs on. */
|
|
Radek Brich |
c94c071 |
struct stat stats;
|
|
Radek Brich |
c94c071 |
int retval = 0;
|
|
Radek Brich |
c94c071 |
- mode_t tmpmode;
|
|
Radek Brich |
c94c071 |
- mode_t invert_permissions;
|
|
Radek Brich |
c94c071 |
- int we_are_root = getuid () == 0;
|
|
Radek Brich |
c94c071 |
+ int oldmask = umask (0);
|
|
Radek Brich |
c94c071 |
dirpath = alloca (strlen (argpath) + 1);
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
strcpy (dirpath, argpath);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
if (stat (dirpath, &stats))
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
- tmpmode = MODE_RWX & ~ newdir_umask;
|
|
Radek Brich |
c94c071 |
- invert_permissions = we_are_root ? 0 : MODE_WXUSR & ~ tmpmode;
|
|
Radek Brich |
c94c071 |
+ char *slash;
|
|
Radek Brich |
c94c071 |
+ int tmp_mode; /* Initial perms for leading dirs. */
|
|
Radek Brich |
c94c071 |
+ int re_protect; /* Should leading dirs be unwritable? */
|
|
Radek Brich |
c94c071 |
+ struct ptr_list
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ char *dirname_end;
|
|
Radek Brich |
c94c071 |
+ struct ptr_list *next;
|
|
Radek Brich |
c94c071 |
+ };
|
|
Radek Brich |
c94c071 |
+ struct ptr_list *p, *leading_dirs = NULL;
|
|
Radek Brich |
e95f529 |
+
|
|
Radek Brich |
c94c071 |
+ /* If leading directories shouldn't be writable or executable,
|
|
Radek Brich |
c94c071 |
+ or should have set[ug]id or sticky bits set and we are setting
|
|
Radek Brich |
c94c071 |
+ their owners, we need to fix their permissions after making them. */
|
|
Radek Brich |
c94c071 |
+ if (((parent_mode & 0300) != 0300)
|
|
Radek Brich |
c94c071 |
+ || (owner != (uid_t) -1 && group != (gid_t) -1
|
|
Radek Brich |
c94c071 |
+ && (parent_mode & 07000) != 0))
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ tmp_mode = 0700;
|
|
Radek Brich |
c94c071 |
+ re_protect = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+ else
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ tmp_mode = parent_mode;
|
|
Radek Brich |
c94c071 |
+ re_protect = 0;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
- char *slash = dirpath;
|
|
Radek Brich |
c94c071 |
+ slash = dirpath;
|
|
Radek Brich |
c94c071 |
while (*slash == '/')
|
|
Radek Brich |
c94c071 |
slash++;
|
|
Radek Brich |
c94c071 |
while ((slash = strchr (slash, '/')))
|
|
Radek Brich |
c94c071 |
@@ -91,9 +112,10 @@ make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
*(slash -1) = '\0';
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
e95f529 |
#endif
|
|
Radek Brich |
c94c071 |
- if (mkdir (dirpath, tmpmode ^ invert_permissions))
|
|
Radek Brich |
c94c071 |
+ if (mkdir (dirpath, tmp_mode))
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
error (0, errno, _("cannot make directory `%s'"), dirpath);
|
|
Radek Brich |
c94c071 |
+ umask (oldmask);
|
|
Radek Brich |
c94c071 |
return 1;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
else
|
|
Radek Brich |
c94c071 |
@@ -101,18 +123,24 @@ make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
if (verbose_fmt_string != NULL)
|
|
Radek Brich |
c94c071 |
error (0, 0, verbose_fmt_string, dirpath);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
- if (stat (dirpath, &stats))
|
|
Radek Brich |
c94c071 |
- stat_error (dirpath);
|
|
Radek Brich |
c94c071 |
- else
|
|
Radek Brich |
c94c071 |
+ if (owner != (uid_t) -1 && group != (gid_t) -1
|
|
Radek Brich |
c94c071 |
+ && chown (dirpath, owner, group)
|
|
Radek Brich |
c94c071 |
+#ifdef AFS
|
|
Radek Brich |
c94c071 |
+ && errno != EPERM
|
|
Radek Brich |
c94c071 |
+#endif
|
|
Radek Brich |
c94c071 |
+ )
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ chown_error_details (dirpath, owner, group);
|
|
Radek Brich |
c94c071 |
+ retval = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+ if (re_protect)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
- if (owner != -1)
|
|
Radek Brich |
c94c071 |
- stats.st_uid = owner;
|
|
Radek Brich |
c94c071 |
- if (group != -1)
|
|
Radek Brich |
c94c071 |
- stats.st_gid = group;
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
- delay_set_stat (dirpath, &stats, invert_permissions);
|
|
Radek Brich |
c94c071 |
+ struct ptr_list *new = (struct ptr_list *)
|
|
Radek Brich |
c94c071 |
+ alloca (sizeof (struct ptr_list));
|
|
Radek Brich |
c94c071 |
+ new->dirname_end = slash;
|
|
Radek Brich |
c94c071 |
+ new->next = leading_dirs;
|
|
Radek Brich |
c94c071 |
+ leading_dirs = new;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
#ifdef HPUX_CDF
|
|
Radek Brich |
c94c071 |
if (iscdf)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
@@ -129,6 +157,7 @@ make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
else if (!S_ISDIR (stats.st_mode))
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
error (0, 0, _("`%s' exists but is not a directory"), dirpath);
|
|
Radek Brich |
c94c071 |
+ umask (oldmask);
|
|
Radek Brich |
c94c071 |
return 1;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
@@ -143,7 +172,7 @@ make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
/* We're done making leading directories.
|
|
Radek Brich |
c94c071 |
Make the final component of the path. */
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
- if (mkdir (dirpath, tmpmode ^ invert_permissions))
|
|
Radek Brich |
c94c071 |
+ if (mkdir (dirpath, mode))
|
|
Radek Brich |
e95f529 |
{
|
|
Radek Brich |
c94c071 |
/* In some cases, if the final component in dirpath was `.' then we
|
|
Radek Brich |
c94c071 |
just got an EEXIST error from that last mkdir(). If that's
|
|
Radek Brich |
c94c071 |
@@ -153,24 +182,51 @@ make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
(!S_ISDIR (stats.st_mode) ) )
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
error (0, errno, _("cannot make directory `%s'"), dirpath);
|
|
Radek Brich |
c94c071 |
+ umask (oldmask);
|
|
Radek Brich |
c94c071 |
return 1;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
e95f529 |
}
|
|
Radek Brich |
c94c071 |
- else if (stat (dirpath, &stats))
|
|
Radek Brich |
c94c071 |
- stat_error (dirpath);
|
|
Radek Brich |
c94c071 |
- else
|
|
Radek Brich |
c94c071 |
- {
|
|
Radek Brich |
c94c071 |
- if (owner != -1)
|
|
Radek Brich |
c94c071 |
- stats.st_uid = owner;
|
|
Radek Brich |
c94c071 |
- if (group != -1)
|
|
Radek Brich |
c94c071 |
- stats.st_gid = group;
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
- delay_set_stat (dirpath, &stats, invert_permissions);
|
|
Radek Brich |
c94c071 |
- }
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
if (verbose_fmt_string != NULL)
|
|
Radek Brich |
c94c071 |
error (0, 0, verbose_fmt_string, dirpath);
|
|
Radek Brich |
e95f529 |
|
|
Radek Brich |
c94c071 |
+ if (owner != (uid_t) -1 && group != (gid_t) -1)
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ if (chown (dirpath, owner, group)
|
|
Radek Brich |
c94c071 |
+#ifdef AFS
|
|
Radek Brich |
c94c071 |
+ && errno != EPERM
|
|
Radek Brich |
c94c071 |
+#endif
|
|
Radek Brich |
c94c071 |
+ )
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ chown_error_details (dirpath, owner, group);
|
|
Radek Brich |
c94c071 |
+ retval = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+ /* chown may have turned off some permission bits we wanted. */
|
|
Radek Brich |
c94c071 |
+ if ((mode & 07000) != 0 && chmod (dirpath, mode))
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ chmod_error_details (dirpath, mode);
|
|
Radek Brich |
c94c071 |
+ retval = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+
|
|
Radek Brich |
c94c071 |
+ /* If the mode for leading directories didn't include owner "wx"
|
|
Radek Brich |
c94c071 |
+ privileges, we have to reset their protections to the correct
|
|
Radek Brich |
c94c071 |
+ value. */
|
|
Radek Brich |
c94c071 |
+ for (p = leading_dirs; p != NULL; p = p->next)
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ *p->dirname_end = '\0';
|
|
Radek Brich |
c94c071 |
+#if 0
|
|
Radek Brich |
c94c071 |
+ /* cpio always calls make_path with parent mode 0700, so
|
|
Radek Brich |
c94c071 |
+ we don't have to do this. If we ever do have to do this,
|
|
Radek Brich |
c94c071 |
+ we have to stat the directory first to get the setuid
|
|
Radek Brich |
c94c071 |
+ bit so we don't break HP CDF's. */
|
|
Radek Brich |
c94c071 |
+ if (chmod (dirpath, parent_mode))
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ chmod_error_details (dirpath, parent_mode);
|
|
Radek Brich |
c94c071 |
+ retval = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+#endif
|
|
Radek Brich |
c94c071 |
+
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
else
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
@@ -179,10 +235,33 @@ make_path (char *argpath,
|
|
Radek Brich |
c94c071 |
if (!S_ISDIR (stats.st_mode))
|
|
Radek Brich |
e95f529 |
{
|
|
Radek Brich |
c94c071 |
error (0, 0, _("`%s' exists but is not a directory"), dirpath);
|
|
Radek Brich |
c94c071 |
+ umask (oldmask);
|
|
Radek Brich |
c94c071 |
return 1;
|
|
Radek Brich |
e95f529 |
}
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
+ /* chown must precede chmod because on some systems,
|
|
Radek Brich |
c94c071 |
+ chown clears the set[ug]id bits for non-superusers,
|
|
Radek Brich |
c94c071 |
+ resulting in incorrect permissions.
|
|
Radek Brich |
c94c071 |
+ On System V, users can give away files with chown and then not
|
|
Radek Brich |
c94c071 |
+ be able to chmod them. So don't give files away. */
|
|
Radek Brich |
c94c071 |
+
|
|
Radek Brich |
c94c071 |
+ if (owner != (uid_t) -1 && group != (gid_t) -1
|
|
Radek Brich |
c94c071 |
+ && chown (dirpath, owner, group)
|
|
Radek Brich |
c94c071 |
+#ifdef AFS
|
|
Radek Brich |
c94c071 |
+ && errno != EPERM
|
|
Radek Brich |
c94c071 |
+#endif
|
|
Radek Brich |
c94c071 |
+ )
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ chown_error_details (dirpath, owner, group);
|
|
Radek Brich |
c94c071 |
+ retval = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
c94c071 |
+ if (chmod (dirpath, mode))
|
|
Radek Brich |
c94c071 |
+ {
|
|
Radek Brich |
c94c071 |
+ chmod_error_details (dirpath, mode);
|
|
Radek Brich |
c94c071 |
+ retval = 1;
|
|
Radek Brich |
c94c071 |
+ }
|
|
Radek Brich |
e95f529 |
}
|
|
Radek Brich |
e95f529 |
|
|
Radek Brich |
c94c071 |
+ umask (oldmask);
|
|
Radek Brich |
c94c071 |
return retval;
|
|
Radek Brich |
e95f529 |
}
|
|
Radek Brich |
c94c071 |
diff -up cpio-2.9/src/copypass.c.dir_perm cpio-2.9/src/copypass.c
|
|
Radek Brich |
c94c071 |
--- cpio-2.9/src/copypass.c.dir_perm 2008-03-03 11:45:00.000000000 +0100
|
|
Radek Brich |
c94c071 |
+++ cpio-2.9/src/copypass.c 2008-03-03 11:45:00.000000000 +0100
|
|
Radek Brich |
c94c071 |
@@ -239,23 +239,15 @@ process_copy_pass ()
|
|
Radek Brich |
c94c071 |
cdf_flag = 1;
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
#endif
|
|
Radek Brich |
c94c071 |
- res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077);
|
|
Radek Brich |
c94c071 |
+ res = mkdir (output_name.ds_string, in_file_stat.st_mode);
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
else
|
|
Radek Brich |
c94c071 |
- {
|
|
Radek Brich |
c94c071 |
- if (!no_chown_flag && (out_file_stat.st_mode & 077) != 0
|
|
Radek Brich |
c94c071 |
- && chmod (output_name.ds_string, out_file_stat.st_mode & 07700) < 0)
|
|
Radek Brich |
c94c071 |
- {
|
|
Radek Brich |
c94c071 |
- error (0, errno, "%s: chmod", output_name.ds_string);
|
|
Radek Brich |
c94c071 |
- continue;
|
|
Radek Brich |
c94c071 |
- }
|
|
Radek Brich |
c94c071 |
- res = 0;
|
|
Radek Brich |
c94c071 |
- }
|
|
Radek Brich |
c94c071 |
+ res = 0;
|
|
Radek Brich |
c94c071 |
if (res < 0 && create_dir_flag)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
create_all_directories (output_name.ds_string);
|
|
Radek Brich |
c94c071 |
- res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077);
|
|
Radek Brich |
c94c071 |
+ res = mkdir (output_name.ds_string, in_file_stat.st_mode);
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
if (res < 0)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
@@ -298,12 +290,12 @@ process_copy_pass ()
|
|
Radek Brich |
c94c071 |
|
|
Radek Brich |
c94c071 |
if (link_res < 0)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
- res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077,
|
|
Radek Brich |
c94c071 |
+ res = mknod (output_name.ds_string, in_file_stat.st_mode,
|
|
Radek Brich |
c94c071 |
in_file_stat.st_rdev);
|
|
Radek Brich |
c94c071 |
if (res < 0 && create_dir_flag)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
create_all_directories (output_name.ds_string);
|
|
Radek Brich |
c94c071 |
- res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077,
|
|
Radek Brich |
c94c071 |
+ res = mknod (output_name.ds_string, in_file_stat.st_mode,
|
|
Radek Brich |
c94c071 |
in_file_stat.st_rdev);
|
|
Radek Brich |
c94c071 |
}
|
|
Radek Brich |
c94c071 |
if (res < 0)
|
|
Radek Brich |
c94c071 |
@@ -373,8 +365,6 @@ process_copy_pass ()
|
|
Radek Brich |
c94c071 |
if (dot_flag)
|
|
Radek Brich |
c94c071 |
fputc ('\n', stderr);
|
|
Radek Brich |
e95f529 |
|
|
Radek Brich |
c94c071 |
- apply_delayed_set_stat ();
|
|
Radek Brich |
c94c071 |
-
|
|
Radek Brich |
c94c071 |
if (!quiet_flag)
|
|
Radek Brich |
c94c071 |
{
|
|
Radek Brich |
c94c071 |
size_t blocks = (output_bytes + io_block_size - 1) / io_block_size;
|