From c3154b2947abbb8d03a412d5874fcceb1fc29393 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 14 Dec 2006 15:41:05 +0100 Subject: [PATCH] chgrp, chown: Don't prohibit -RLh, aka -RL with --no-dereference. * 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. * doc/coreutils.texi (Treating / specially): With --preserve-root, chgrp and chown will not modify "/", even through a symlink. --- ChangeLog | 5 +++++ doc/ChangeLog | 2 ++ doc/coreutils.texi | 4 ++++ src/chgrp.c | 10 ++-------- src/chown-core.c | 3 ++- src/chown.c | 10 ++-------- tests/chown/preserve-root | 18 ++++++++++++++++++ 7 files changed, 35 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2b8c46..385de58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2006-12-14 Jim Meyering + * 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 026b34a..60341ab 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,6 +1,8 @@ 2006-12-14 Jim Meyering * 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 diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 8e6126f..c7952fa 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 7e96b4c..faf58d3 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 606db39..b390610 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 c2850ee..63a32f5 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 152f59c..4f8fe4f 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 -- 2.7.4