summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--doc/ChangeLog2
-rw-r--r--doc/coreutils.texi4
-rw-r--r--src/chgrp.c10
-rw-r--r--src/chown-core.c3
-rw-r--r--src/chown.c10
-rwxr-xr-xtests/chown/preserve-root18
7 files changed, 35 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index e2b8c464e..385de5878 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2006-12-14 Jim Meyering <jim@meyering.net>
+ * src/chgrp.c (main): Don't prohibit -RLh, aka -RL with --no-dereference.
+ * src/chown.c (main): Likewise.
+ * src/chown-core.c (change_file_owner): Add to a comment.
+ * tests/chown/preserve-root: Add tests.
+
* NEWS: --preserve-root now works with chgrp, chmod, and chown.
* src/chmod.c (process_file): Do honor the --preserve-root option.
* src/chown-core.c (change_file_owner): Likewise, but here, also
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 026b34a19..60341abab 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,6 +1,8 @@
2006-12-14 Jim Meyering <jim@meyering.net>
* coreutils.texi: Remove two doubled words.
+ (Treating / specially): With --preserve-root, chgrp and chown
+ will not modify "/", even through a symlink.
2006-11-28 Jim Meyering <jim@meyering.net>
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 8e6126f36..c7952facc 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -1158,6 +1158,10 @@ to operate recursively on @file{/}, so they default to
option makes them safer for most purposes. For convenience you can
specify @option{--preserve-root} in an alias or in a shell function.
+Note that the @option{--preserve-root} option also ensures
+that @command{chgrp} and @command{chown} do not modify @file{/}
+even when dereferencing a symlink pointing to @file{/}.
+
@node Special built-in utilities
@section Special built-in utilities
diff --git a/src/chgrp.c b/src/chgrp.c
index 7e96b4c36..faf58d36b 100644
--- a/src/chgrp.c
+++ b/src/chgrp.c
@@ -260,20 +260,14 @@ main (int argc, char **argv)
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
- chopt.affect_symlink_referent = false;
- }
- else
- {
- if (dereference == 0)
- error (EXIT_FAILURE, 0, _("-R -h requires -P"));
- chopt.affect_symlink_referent = true;
+ dereference = 0;
}
}
else
{
bit_flags = FTS_PHYSICAL;
- chopt.affect_symlink_referent = (dereference != 0);
}
+ chopt.affect_symlink_referent = (dereference != 0);
if (argc - optind < (reference_file ? 1 : 2))
{
diff --git a/src/chown-core.c b/src/chown-core.c
index 606db39ea..b39061091 100644
--- a/src/chown-core.c
+++ b/src/chown-core.c
@@ -261,7 +261,8 @@ change_file_owner (FTS *fts, FTSENT *ent,
{
if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, ent->fts_statp))
{
- /* This happens e.g., with "chown -R --preserve-root /". */
+ /* This happens e.g., with "chown -R --preserve-root 0 /"
+ and with "chown -RH --preserve-root 0 symlink-to-root". */
ROOT_DEV_INO_WARN (file_full_name);
/* Tell fts not to traverse into this hierarchy. */
fts_set (fts, ent, FTS_SKIP);
diff --git a/src/chown.c b/src/chown.c
index c2850ee13..63a32f5bf 100644
--- a/src/chown.c
+++ b/src/chown.c
@@ -273,20 +273,14 @@ main (int argc, char **argv)
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
- chopt.affect_symlink_referent = false;
- }
- else
- {
- if (dereference == 0)
- error (EXIT_FAILURE, 0, _("-R -h requires -P"));
- chopt.affect_symlink_referent = true;
+ dereference = 0;
}
}
else
{
bit_flags = FTS_PHYSICAL;
- chopt.affect_symlink_referent = (dereference != 0);
}
+ chopt.affect_symlink_referent = (dereference != 0);
if (argc - optind < (reference_file ? 1 : 2))
{
diff --git a/tests/chown/preserve-root b/tests/chown/preserve-root
index 152f59c30..4f8fe4f7f 100755
--- a/tests/chown/preserve-root
+++ b/tests/chown/preserve-root
@@ -55,6 +55,18 @@ chgrp -R --preserve-root 0 / >> out 2>&1 && fail=1
# and then, only to make them readable by owner.
chmod -R --preserve-root u+r / >> out 2>&1 && fail=1
+# With -RHh, --preserve-root should trigger nothing,
+# since the symlink in question is not a command line argument.
+# Contrary to the above commands, these two should succeed.
+echo '==== test -RHh' >> out
+chown -RHh --preserve-root `id -u` d >> out 2>&1 || fail=1
+chgrp -RHh --preserve-root `id -g` d >> out 2>&1 || fail=1
+
+# These must fail.
+echo '==== test -RLh' >> out
+chown -RLh --preserve-root `id -u` d >> out 2>&1 && fail=1
+chgrp -RLh --preserve-root `id -g` d >> out 2>&1 && fail=1
+
cat <<\EOF > exp || fail=1
chown: it is dangerous to operate recursively on `/'
chown: use --no-preserve-root to override this failsafe
@@ -62,6 +74,12 @@ chgrp: it is dangerous to operate recursively on `/'
chgrp: use --no-preserve-root to override this failsafe
chmod: it is dangerous to operate recursively on `/'
chmod: use --no-preserve-root to override this failsafe
+==== test -RHh
+==== test -RLh
+chown: it is dangerous to operate recursively on `d/slink-to-root' (same as `/')
+chown: use --no-preserve-root to override this failsafe
+chgrp: it is dangerous to operate recursively on `d/slink-to-root' (same as `/')
+chgrp: use --no-preserve-root to override this failsafe
EOF
cmp out exp || fail=1