chmod: add notations +40, 00440, etc.

* NEWS: Document this.
* doc/perm.texi (Operator Numeric Modes): New section.
(Numeric Modes, Directory Setuid and Setgid): Document new behavior.
* src/chmod.c (usage): Document new behavior.
(main): Support new options -0, -1, etc.
* tests/chmod/setgid: Test these new features.
This commit is contained in:
Paul Eggert 2012-03-08 19:00:27 -08:00
parent 9076b28464
commit 8931cdbfda
4 changed files with 86 additions and 16 deletions

15
NEWS
View File

@ -4,6 +4,21 @@ GNU coreutils NEWS -*- outline -*-
** New features
As a GNU extension, 'chmod', 'mkdir', and 'install' now accept operators
'-', '+', '=' followed by octal modes; for example, 'chmod +40 FOO' enables
and 'chmod -40 FOO' disables FOO's group-read permissions. Operator
numeric modes can be combined with symbolic modes by separating them with
commas; for example, =0,u+r clears all permissions except for enabling
user-read permissions. Unlike ordinary numeric modes, operator numeric
modes do not preserve directory setuid and setgid bits; for example,
'chmod =0 FOO' clears all of FOO's permissions, including setuid and setgid.
Also, ordinary numeric modes with five or more digits no longer preserve
setuid and setgid bits, so that 'chmod 00755 FOO' now clears FOO's setuid
and setgid bits. This allows scripts to be portable to other systems which
lack the GNU extension mentioned previously, and where ordinary numeric
modes do not preserve directory setuid and setgid bits.
dd now accepts the count_bytes, skip_bytes iflags and the seek_bytes
oflag, to more easily allow processing portions of a file.

View File

@ -17,6 +17,7 @@ symbolic form or as an octal number.
* Mode Structure:: Structure of file mode bits.
* Symbolic Modes:: Mnemonic representation of file mode bits.
* Numeric Modes:: File mode bits as octal numbers.
* Operator Numeric Modes:: ANDing, ORing, and setting modes octally.
* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories.
@end menu
@ -495,13 +496,16 @@ alternative to giving a symbolic mode, you can give an octal (base 8)
number that represents the mode.
This number is always interpreted in octal; you do not have to add a
leading @samp{0}, as you do in C. Mode @samp{0055} is the same as
mode @samp{55}.
mode @samp{55}. (However, modes of five digits or more, such as
@samp{00055}, are sometimes special. @xref{Directory Setuid and Setgid}.)
A numeric mode is usually shorter than the corresponding symbolic
mode, but it is limited in that normally it cannot take into account the
previous file mode bits; it can only set them absolutely.
(As discussed in the next section, the set-user-ID and set-group-ID
bits of directories are an exception to this general limitation.)
The set-user-ID and set-group-ID bits of directories are an exception
to this general limitation; @xref{Directory Setuid and Setgid}.
Also, operator numeric modes can take previous file mode bits into
account; @xref{Operator Numeric Modes}.
The permissions granted to the user,
to other users in the file's group,
@ -541,6 +545,26 @@ For example, numeric mode @samp{4755} corresponds to symbolic mode
@samp{ug=rw,o=r}. Numeric mode @samp{0} corresponds to symbolic mode
@samp{a=}.
@node Operator Numeric Modes
@section Operator Numeric Modes
An operator numeric mode is a numeric mode that is prefixed by a
@samp{-}, @samp{+}, or @samp{=} operator, which has the same
interpretation as in symbolic modes. For example, @samp{+440} enables
read permission for the file's owner and group, @samp{-1} disables
execute permission for other users, and @samp{=600} clears all
permissions except for enabling read-write permissions for the file's
owner. Operator numeric modes can be combined with symbolic modes by
separating them with a comma; for example, @samp{=0,u+r} clears all
permissions except for enabling read permission for the file's owner.
The commands @samp{chmod =755 @var{dir}} and @samp{chmod 755
@var{dir}} differ in that the former clears the directory @var{dir}'s
setuid and setgid bits, whereas the latter preserves them.
@xref{Directory Setuid and Setgid}.
Operator numeric modes are a @acronym{GNU} extension.
@node Directory Setuid and Setgid
@section Directories and the Set-User-ID and Set-Group-ID Bits
@ -559,8 +583,10 @@ bits of directories. If commands like @command{chmod} and
mechanisms would be less convenient and it would be harder to share
files. Therefore, a command like @command{chmod} does not affect the
set-user-ID or set-group-ID bits of a directory unless the user
specifically mentions them in a symbolic mode, or sets them in
a numeric mode. For example, on systems that support
specifically mentions them in a symbolic mode, or uses an operator
numeric mode such as @samp{=755}, or sets them in a numeric mode, or
clears them in a numeric mode that has five or more octal digits.
For example, on systems that support
set-group-ID inheritance:
@example
@ -582,22 +608,32 @@ explicitly in the symbolic or numeric modes, e.g.:
@example
# These commands try to set the set-user-ID
# and set-group-ID bits of the subdirectories.
mkdir G H
mkdir G
chmod 6755 G
chmod u=rwx,go=rx,a+s H
mkdir -m 6755 I
chmod +6000 G
chmod u=rwx,go=rx,a+s G
mkdir -m 6755 H
mkdir -m +6000 I
mkdir -m u=rwx,go=rx,a+s J
@end example
If you want to try to clear these bits, you must mention them
explicitly in a symbolic mode, e.g.:
explicitly in a symbolic mode, or use an operator numeric mode, or
specify a numeric mode with five or more octal digits, e.g.:
@example
# This command tries to clear the set-user-ID
# These commands try to clear the set-user-ID
# and set-group-ID bits of the directory D.
chmod a-s D
chmod -6000 D
chmod =755 D
chmod 00755 D
@end example
This behavior is a @acronym{GNU} extension. Portable scripts should
not rely on requests to set or clear these bits on directories, as
@acronym{POSIX} allows implementations to ignore these requests.
The @acronym{GNU} behavior with numeric modes of four or fewer digits
is intended for scripts portable to systems that preserve these bits;
the behavior with numeric modes of five or more digits is for scripts
portable to systems that do not preserve the bits.

View File

@ -398,7 +398,7 @@ With --reference, change the mode of each FILE to that of RFILE.\n\
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
\n\
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.\n\
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'.\n\
"), stdout);
emit_ancillary_info ();
}
@ -430,7 +430,8 @@ main (int argc, char **argv)
recurse = force_silent = diagnose_surprises = false;
while ((c = getopt_long (argc, argv,
"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::",
("Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
"0::1::2::3::4::5::6::7::"),
long_options, NULL))
!= -1)
{
@ -449,6 +450,8 @@ main (int argc, char **argv)
case ',':
case '+':
case '=':
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/* Support nonportable uses like "chmod -w", but diagnose
surprises due to umask confusion. Even though "--", "--r",
etc., are valid modes, there is no "case '-'" here since

View File

@ -1,6 +1,7 @@
#!/bin/sh
# Make sure GNU chmod works the same way as those of Solaris, HPUX, AIX
# wrt directories with the setgid bit set.
# on directories with the setgid bit set. Also, check that the GNU octal
# notations work.
# Copyright (C) 2001-2012 Free Software Foundation, Inc.
@ -21,7 +22,7 @@
print_ver_ chmod
umask 0
mkdir d || framework_failure_
mkdir -m 755 d || framework_failure_
chmod g+s d 2> /dev/null && env -- test -g d ||
{
@ -40,9 +41,24 @@ chmod g+s d 2> /dev/null && env -- test -g d ||
env -- test -g d ||
skip_ 'cannot create setgid directories'
for mode in \
+ - g-s 00755 000755 =755 -2000 -7022 755 0755 \
+2000 -5022 =7777,-5022
do
chmod $mode d || fail=1
chmod 755 d
case $mode in
g-s | 00*755 | =755 | -2000 | -7022)
expected_mode=drwxr-xr-x ;;
*) expected_mode=drwxr-sr-x ;;
esac
ls_output=`ls -ld d`
case $ls_output in
$expected_mode*) ;;
*) fail=1 ;;
esac
case `ls -ld d` in drwxr-sr-x*);; *) fail=1;; esac
chmod =2755 d || fail=1
done
Exit $fail