[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: some other problems with chmod-safer.c, chown.c, etc.
From: |
Paul Eggert |
Subject: |
Re: some other problems with chmod-safer.c, chown.c, etc. |
Date: |
Sun, 01 Jan 2006 23:56:31 -0800 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
I installed the following to make coreutils act like FreeBSD with
respect to when chmod() is invoked, along the lines I suggested
earlier today. I noticed several other places where chmod can safely
be replaced by lchmod, and did those too, as that makes the programs
slightly safer in the presence of directories that are writeable by
attackers. When in doubt I left chmods alone, though.
If there's something amiss with this please let me know; it's easy
enough to back out the change.
We could get fancier and use fchmod for readable directories and for
readable or writeable regular files, falling back on lchmod for
everything else; but this still suffers from the same race conditions
that lchmod suffers from, and I'm not sure it's worth the hassle.
2006-01-01 Paul Eggert <address@hidden>
* NEWS: Document that mkfifo and mknod -m no longer set special bits.
* doc/coreutils.texi, perm.texi: Clarify file mode bits versus
file permission bits.
* doc/coreutils.texi (mkfifo invocation, mknod invocation): -m
affects only file permission bits.
* lib/chmod-safer.c, chmod-safer.h: Remove.
* lib/lchmod.h: New file.
* lib/mkdir-p.c: Include lchmod.h, lchown.h.
(make_dir_parents): Use lchown rather than chown, and
lchmod rather than chmod.
* m4/chmod-safer.m4: Remove.
* m4/lchmod.m4: New file.
* m4/jm-macros.m4 (gl_MACROS): Require gl_FUNC_LCHMOD.
Don't require gl_CHDIR_SAFER.
* src/copy.c: Include lchmod.h.
(copy_internal): Use lchmod rather than chmod.
* src/cp.c: Include lchmod.h.
(re_protect, make_dir_parents_private): Use lchmod rather than chmod.
* src/mkdir.c: Include lchmod.h.
(usage): Clarify -m's operation.
(main): Use lchmod rather than chmod. Don't use lchmod unless the
new mode contains bits outside the 777 range.
* src/mkfifo.c (usage): Clarify -m's operation.
(main): If -m is given, don't invoke chmod; use umask 0 instead.
Report an error if -m asks for bits outside the 777 range.
* src/mknod.c (usage, main): Likewise.
* src/mkdir.c, src/mkfifo.c, src/mknod.c: Undo 2005-12-19 changes.
Index: NEWS
===================================================================
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.354
diff -p -u -r1.354 NEWS
--- NEWS 15 Dec 2005 12:24:54 -0000 1.354
+++ NEWS 2 Jan 2006 07:27:03 -0000
@@ -23,6 +23,9 @@ GNU coreutils NEWS
if your locale settings appear to be messed up. This change
attempts to have the default be the best of both worlds.
+ mkfifo and mknod no longer set special mode bits (setuid, setgid,
+ and sticky) with the -m option.
+
sort now reports incompatible options (e.g., -i and -n) rather than
silently ignoring one of them.
Index: doc/coreutils.texi
===================================================================
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.303
diff -p -u -r1.303 coreutils.texi
--- doc/coreutils.texi 29 Dec 2005 21:45:32 -0000 1.303
+++ doc/coreutils.texi 2 Jan 2006 07:27:06 -0000
@@ -5683,7 +5683,7 @@ uniquely identifies each file within a p
@opindex --format
@opindex long ls @r{format}
@opindex verbose ls @r{format}
-In addition to the name of each file, print the file type, permissions,
+In addition to the name of each file, print the file type, file mode bits,
number of hard links, owner name, group name, size, and
timestamp (@pxref{Formatting file timestamps}), normally
the modification time.
@@ -5702,7 +5702,7 @@ The @var{blocks} computed counts each ha
this is arguably a deficiency.
@cindex permissions, output by @command{ls}
-The permissions listed are similar to symbolic mode specifications
+The file mode bits listed are similar to symbolic mode specifications
(@pxref{Symbolic Modes}). But @command{ls} combines multiple bits into the
third character of each set of permissions as follows:
@table @samp
@@ -5727,14 +5727,14 @@ If the executable bit is set and none of
Otherwise.
@end table
-Following the permission bits is a single character that specifies
+Following the file mode bits is a single character that specifies
whether an alternate access method such as an access control list
-applies to the file. When the character following the permissions is a
-space, there is no alternate access method. When it is a printing
+applies to the file. When the character following the file mode bits is a
+space, there is no alternate access method. When it is a printing
character, then there is such a method.
For a file with an extended access control list, a @samp{+} character is
-listed. Basic access control lists are equivalent to the permissions
+listed. Basic access control lists are equivalent to the permissions
listed, and are not considered an alternate access method.
@item -n
@@ -6572,7 +6572,7 @@ of one or more of the following strings:
@table @samp
@itemx mode
-Preserve the permission attributes, including access control lists.
+Preserve the file mode bits and access control lists.
@itemx ownership
Preserve the owner and group. On most modern systems,
only the super-user may change the owner of a file, and regular users
@@ -6594,7 +6594,7 @@ Using @option{--preserve} with no @var{a
to @option{--preserve=mode,ownership,timestamps}.
In the absence of this option, each destination file is created with the
-permissions of the corresponding source file, minus the bits set in the
+mode bits of the corresponding source file, minus the bits set in the
umask and minus the set-user-ID and set-group-ID bits.
@xref{File permissions}.
@@ -7057,7 +7057,7 @@ environment variable is set.
@pindex install
@cindex copying files and setting attributes
address@hidden copies files while setting their permission modes and, if
address@hidden copies files while setting their file mode bits and, if
possible, their owner and group. Synopses:
@example
@@ -7128,7 +7128,7 @@ may be either a group name or a numeric
@opindex -m
@opindex --mode
@cindex permissions of installed files, setting
-Set the permissions for the installed file or directory to @var{mode},
+Set the file mode bits for the installed file or directory to @var{mode},
which can be either an octal number, or a symbolic mode as in
@command{chmod}, with @samp{a=} (no access allowed to anyone) as the
point of departure (@pxref{File permissions}).
@@ -7898,8 +7898,8 @@ everyone) for the point of the departure
@opindex -p
@opindex --parents
@cindex parent directories, creating
-Make any missing parent directories for each argument. The mode for parent
-directories is set to the umask modified by @samp{u+wx}.
+Make any missing parent directories for each argument. The file permission
+bits of parent directories are set to the umask modified by @samp{u+wx}.
Ignore arguments corresponding to existing directories.
@item -v
@@ -7944,7 +7944,8 @@ The program accepts the following option
@cindex modes of created FIFOs, setting
Set the mode of created FIFOs to @var{mode}, which is symbolic as in
@command{chmod} and uses @samp{a=rw} (read and write allowed for everyone)
-for the point of departure. @xref{File permissions}.
+for the point of departure. @var{mode} should specify only file
+permission bits. @xref{File permissions}.
@end table
@@ -8015,6 +8016,7 @@ The program accepts the following option
@opindex --mode
Set the mode of created files to @var{mode}, which is symbolic as in
@command{chmod} and uses @samp{a=rw} as the point of departure.
address@hidden should specify only file permission bits.
@xref{File permissions}.
@end table
@@ -8567,7 +8569,7 @@ line, @command{chmod} changes the permis
In contrast, @command{chmod} ignores symbolic links encountered during
recursive directory traversals.
-If used, @var{mode} specifies the new permissions.
+If used, @var{mode} specifies the new file mode bits.
For details, see the section on @ref{File permissions}.
If you really want @var{mode} to have a leading @samp{-}, you should
use @option{--} first, e.g., @samp{chmod -- -w file}. Typically,
Index: doc/perm.texi
===================================================================
RCS file: /fetish/cu/doc/perm.texi,v
retrieving revision 1.13
retrieving revision 1.15
diff -p -u -r1.13 -r1.15
--- doc/perm.texi 13 Nov 2005 18:57:17 -0000 1.13
+++ doc/perm.texi 2 Jan 2006 07:42:35 -0000 1.15
@@ -1,6 +1,5 @@
-Each file has a set of @dfn{permissions} that control the kinds of
-access that users have to that file. The permissions for a file are
-also called its @dfn{access mode}. They can be represented either in
+Each file has a set of @dfn{file mode bits} that control the kinds of
+access that users have to that file. They can be represented either in
symbolic form or as an octal number.
@menu
@@ -12,6 +11,10 @@ symbolic form or as an octal number.
@node Mode Structure
@section Structure of File Permissions
+The file mode bits have two parts: the @dfn{file permission bits},
+which control ordinary access to the file, and @dfn{special mode
+bits}, which affect only some files.
+
There are three kinds of permissions that a user can have for a file:
@enumerate
@@ -50,8 +53,8 @@ file system the file is created on, and
can change the owner and group of a file by using the @command{chown} and
@command{chgrp} commands.
-In addition to the three sets of three permissions listed above, a
-file's permissions have three special components, which affect only
+In addition to the three sets of three permissions listed above, the
+file mode bits have three special components, which affect only
executable files (programs) and, on some systems, directories:
@enumerate
@@ -78,9 +81,9 @@ swap device so it will load more quickly
@dfn{sticky bit}.
@end enumerate
-In addition to the permissions listed above, there may be file attributes
-specific to the file system, e.g: access control lists (ACLs), whether a
-file is compressed, whether a file can be modified (immutability), whether
+In addition to the file mode bits listed above, there may be file attributes
+specific to the file system, e.g., access control lists (ACLs), whether a
+file is compressed, whether a file can be modified (immutability), and whether
a file can be dumped. These are usually set using programs
specific to the file system. For example:
@c should probably say a lot more about ACLs... someday
@@ -96,7 +99,7 @@ On FreeBSD the file permissions (``flags
file system are set using @command{chrflags}.
@end table
-Although a file's permission ``bits'' allow an operation on that file,
+Even if a file's permission bits allow an operation on that file,
that operation may still fail, because:
@itemize
@@ -115,9 +118,9 @@ may have just run @code{chmod a+w FILE}.
@section Symbolic Modes
@cindex symbolic modes
address@hidden modes} represent changes to files' permissions as
address@hidden modes} represent changes to files' mode bits as
operations on single-character symbols. They allow you to modify either
-all or selected parts of files' permissions, optionally based on
+all or selected parts of files' mode bits, optionally based on
their previous values, and perhaps on the current @code{umask} as well
(@pxref{Umask and Protection}).
@@ -137,7 +140,7 @@ symbolic modes.
@menu
* Setting Permissions:: Basic operations on permissions.
* Copying Permissions:: Copying existing permissions.
-* Changing Special Permissions:: Special permissions.
+* Changing Special Mode Bits:: Special mode bits.
* Conditional Executability:: Conditionally affecting executability.
* Multiple Changes:: Making multiple changes.
* Umask and Protection:: The effect of the umask.
@@ -275,34 +278,34 @@ it to mode 666 (@samp{rw-rw-rw-}). If t
(@samp{rwxr--r-x}). The @samp{-} and @samp{=} operations work
analogously.
address@hidden Changing Special Permissions
address@hidden Changing Special Permissions
address@hidden Changing Special Mode Bits
address@hidden Changing Special Mode Bits
address@hidden changing special permissions
address@hidden changing special mode bits
In addition to changing a file's read, write, and execute permissions,
-you can change its special permissions. @xref{Mode Structure}, for a
-summary of these permissions.
+you can change its special mode bits. @xref{Mode Structure}, for a
+summary of these special mode bits.
-To change a file's permission to set the user ID on execution, use
+To change the file mode bits to set the user ID on execution, use
@samp{u} in the @var{users} part of the symbolic mode and
address@hidden in the @var{permissions} part.
address@hidden instead of the @var{permissions} part.
-To change a file's permission to set the group ID on execution, use
+To change the file mode bits to set the group ID on execution, use
@samp{g} in the @var{users} part of the symbolic mode and
address@hidden in the @var{permissions} part.
address@hidden instead of the @var{permissions} part.
-To change a file's permission to set the restricted deletion flag or sticky
bit,
-omit the @var{users} part of the symbolic mode (or use @samp{a}) and put
address@hidden in the @var{permissions} part.
+To change the file mode bits to set the restricted deletion flag or sticky bit,
+omit the @var{users} part of the symbolic mode (or use @samp{a}) and use
address@hidden instead of the @var{permissions} part.
-For example, to add set-user-ID permission to a program,
+For example, to set the set-user-ID mode bit of a program,
you can use the mode:
@example
u+s
@end example
-To remove both set-user-ID and set-group-ID permission from
+To remove both set-user-ID and set-group-ID mode bits from
it, you can use the mode:
@example
@@ -320,7 +323,7 @@ The combination @samp{o+s} has no effect
the combinations @samp{u+t} and @samp{g+t} have no effect, and
@samp{o+t} acts like plain @samp{+t}.
-The @samp{=} operator is not very useful with special permissions; for
+The @samp{=} operator is not very useful with special mode bits; for
example, the mode:
@example
@@ -356,7 +359,7 @@ anyone could execute them before.
@cindex multiple changes to permissions
The format of symbolic modes is actually more complex than described
above (@pxref{Setting Permissions}). It provides two ways to make
-multiple changes to files' permissions.
+multiple changes to files' mode bits.
The first way is to specify multiple @var{operation} and
@var{permissions} parts after a @var{users} part in the symbolic mode.
@@ -396,7 +399,7 @@ u=rwx,g=rx,o=
@end example
@noindent
-sets all of the non-special permissions for the file explicitly. (It
+sets all of the permission bits for the file explicitly. (It
gives users who are not in the file's group no permission at all for
it.)
@@ -457,7 +460,7 @@ the file to all users.
@section Numeric Modes
@cindex numeric modes
address@hidden file permissions, numeric
address@hidden file mode bits, numeric
@cindex octal numbers for file modes
As an
alternative to giving a symbolic mode, you can give an octal (base 8)
@@ -466,20 +469,20 @@ This number is always interpreted in oct
leading 0, as you do in C. Mode 0055 is the same as mode 55.
A numeric mode is usually shorter than the corresponding symbolic
-mode, but it is limited in that it cannot take into account a file's
-previous permissions; it can only set them absolutely.
+mode, but it is limited in that it cannot take into account the
+previous file mode bits; it can only set them absolutely.
The permissions granted to the user,
to other users in the file's group,
and to other users not in the file's group each require three
bits, which are represented as one octal digit. The three special
-permissions also require one bit each, and they are as a group
+mode bits also require one bit each, and they are as a group
represented as another octal digit. Here is how the bits are arranged,
starting with the lowest valued bit:
@example
Value in Corresponding
-Mode Permission
+Mode Mode Bit
Other users not in the file's group:
1 Execute
@@ -496,7 +499,7 @@ Mode Permission
200 Write
400 Read
- Special permissions:
+ Special mode bits:
1000 Restricted deletion flag or sticky bit
2000 Set group ID on execution
4000 Set user ID on execution
Index: lib/mkdir-p.c
===================================================================
RCS file: /fetish/cu/lib/mkdir-p.c,v
retrieving revision 1.18
diff -p -u -r1.18 mkdir-p.c
--- lib/mkdir-p.c 23 Dec 2005 18:15:33 -0000 1.18
+++ lib/mkdir-p.c 2 Jan 2006 06:12:20 -0000
@@ -42,6 +42,8 @@
#include "chdir-safer.h"
#include "dirname.h"
#include "error.h"
+#include "lchmod.h"
+#include "lchown.h"
#include "quote.h"
#include "save-cwd.h"
#include "stat-macros.h"
@@ -195,7 +197,7 @@ make_dir_parents (char const *arg,
error (0, 0, verbose_fmt_string, quote (dir));
if ((owner != (uid_t) -1 || group != (gid_t) -1)
- && chown (basename_dir, owner, group)
+ && lchown (basename_dir, owner, group)
#if defined AFS && defined EPERM
&& errno != EPERM
#endif
@@ -302,7 +304,7 @@ make_dir_parents (char const *arg,
if (owner != (uid_t) -1 || group != (gid_t) -1)
{
- if (chown (fixup_permissions_dir, owner, group) != 0
+ if (lchown (fixup_permissions_dir, owner, group) != 0
#ifdef AFS
&& errno != EPERM
#endif
@@ -319,7 +321,7 @@ make_dir_parents (char const *arg,
required to honor only the file permission bits. In particular,
it need not honor the `special' bits, so if MODE includes any
special bits, set them here. */
- if ((mode & ~S_IRWXUGO) && chmod (fixup_permissions_dir, mode) != 0)
+ if ((mode & ~S_IRWXUGO) && lchmod (fixup_permissions_dir, mode) != 0)
{
error (0, errno, _("cannot change permissions of %s"),
quote (full_dir));
@@ -343,7 +345,7 @@ make_dir_parents (char const *arg,
{
leading_dirs->dirname_end[0] = '\0';
if ((cwd_problem && *full_dir != '/')
- || chmod (full_dir, parent_mode) != 0)
+ || lchmod (full_dir, parent_mode) != 0)
{
error (0, (cwd_problem ? 0 : errno),
_("cannot change permissions of %s"), quote (full_dir));
Index: m4/jm-macros.m4
===================================================================
RCS file: /fetish/cu/m4/jm-macros.m4,v
retrieving revision 1.236
diff -p -u -r1.236 jm-macros.m4
--- m4/jm-macros.m4 21 Dec 2005 10:21:04 -0000 1.236
+++ m4/jm-macros.m4 2 Jan 2006 06:12:20 -0000
@@ -50,6 +50,7 @@ AC_DEFUN([gl_MACROS],
AC_REQUIRE([gl_FUNC_DIRFD])
AC_REQUIRE([AC_FUNC_ACL])
+ AC_REQUIRE([gl_FUNC_LCHMOD])
AC_REQUIRE([gl_FUNC_LCHOWN])
AC_REQUIRE([gl_FUNC_RMDIR_NOTEMPTY])
AC_REQUIRE([gl_FUNC_CHOWN])
@@ -180,7 +181,6 @@ AC_DEFUN([gl_MACROS],
AC_REQUIRE([gl_DIACRIT])
AC_REQUIRE([gl_TYPE_SOCKLEN_T])
AC_REQUIRE([gl_FPRINTFTIME])
- AC_REQUIRE([gl_CHMOD_SAFER])
AC_REQUIRE([gl_CHDIR_SAFER])
])
Index: src/copy.c
===================================================================
RCS file: /fetish/cu/src/copy.c,v
retrieving revision 1.193
diff -p -u -r1.193 copy.c
--- src/copy.c 17 Dec 2005 10:33:33 -0000 1.193
+++ src/copy.c 2 Jan 2006 06:12:20 -0000
@@ -44,6 +44,7 @@
#include "getpagesize.h"
#include "hash.h"
#include "hash-pjw.h"
+#include "lchmod.h"
#include "quote.h"
#include "same.h"
#include "savedir.h"
@@ -1499,7 +1500,7 @@ copy_internal (char const *src_name, cha
dst_mode = dst_sb.st_mode;
restore_dst_mode = true;
- if (chmod (dst_name, dst_mode | S_IRWXU))
+ if (lchmod (dst_name, dst_mode | S_IRWXU) != 0)
{
error (0, errno, _("setting permissions for %s"),
quote (dst_name));
@@ -1740,7 +1741,7 @@ copy_internal (char const *src_name, cha
}
else if (restore_dst_mode)
{
- if (chmod (dst_name, dst_mode))
+ if (lchmod (dst_name, dst_mode) != 0)
{
error (0, errno, _("preserving permissions for %s"),
quote (dst_name));
Index: src/cp.c
===================================================================
RCS file: /fetish/cu/src/cp.c,v
retrieving revision 1.217
diff -p -u -r1.217 cp.c
--- src/cp.c 28 Dec 2005 10:22:41 -0000 1.217
+++ src/cp.c 2 Jan 2006 06:12:21 -0000
@@ -30,6 +30,7 @@
#include "error.h"
#include "dirname.h"
#include "filenamecat.h"
+#include "lchmod.h"
#include "quote.h"
#include "quotearg.h"
#include "stat-time.h"
@@ -335,7 +336,7 @@ re_protect (char const *const_dst_name,
}
else if (p->restore_mode)
{
- if (chmod (dst_name, p->mode))
+ if (lchmod (dst_name, p->mode) != 0)
{
error (0, errno, _("failed to preserve permissions for %s"),
quote (dst_name));
@@ -466,7 +467,7 @@ make_dir_parents_private (char const *co
new->mode = stats.st_mode;
new->restore_mode = true;
- if (chmod (dir, stats.st_mode | S_IRWXU))
+ if (lchmod (dir, stats.st_mode | S_IRWXU) != 0)
{
error (0, errno, _("setting permissions for %s"),
quote (dir));
Index: src/mkdir.c
===================================================================
RCS file: /fetish/cu/src/mkdir.c,v
retrieving revision 1.102
diff -p -u -r1.102 mkdir.c
--- src/mkdir.c 19 Dec 2005 18:17:16 -0000 1.102
+++ src/mkdir.c 2 Jan 2006 06:12:21 -0000
@@ -23,9 +23,9 @@
#include <sys/types.h>
#include "system.h"
-#include "chmod-safer.h"
#include "dirname.h"
#include "error.h"
+#include "lchmod.h"
#include "mkdir-p.h"
#include "modechange.h"
#include "quote.h"
@@ -65,7 +65,7 @@ Create the DIRECTORY(ies), if they do no
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
- -m, --mode=MODE set permission mode (as in chmod), not rwxrwxrwx - umask\n\
+ -m, --mode=MODE set file mode (as in chmod), not a=rwx - umask\n\
-p, --parents no error if existing, make parent directories as needed\n\
-v, --verbose print a message for each created directory\n\
"), stdout);
@@ -80,7 +80,6 @@ int
main (int argc, char **argv)
{
mode_t newmode;
- mode_t tmp_mode;
mode_t parent_mode IF_LINT (= 0);
const char *specified_mode = NULL;
const char *verbose_fmt_string = NULL;
@@ -144,11 +143,6 @@ main (int argc, char **argv)
umask (umask_value);
}
- /* This is the mode we'll use in the mknod or mkfifo call.
- If it doesn't include S_IRUSR, use S_IRUSR so the final
- open-for-fchmod will succeed. */
- tmp_mode = (newmode & S_IRUSR) ? newmode : S_IRUSR;
-
for (; optind < argc; ++optind)
{
char *dir = argv[optind];
@@ -168,7 +162,7 @@ main (int argc, char **argv)
}
else
{
- ok = (mkdir (dir, tmp_mode) == 0);
+ ok = (mkdir (dir, newmode) == 0);
if (! ok)
error (0, errno, _("cannot create directory %s"), quote (dir));
@@ -177,15 +171,13 @@ main (int argc, char **argv)
/* mkdir(2) is required to honor only the file permission bits.
In particular, it needn't do anything about `special' bits,
- so if any were set in newmode, apply them with chmod.
- This extra step is necessary in some cases when the containing
- directory has a default ACL. */
+ so if any were set in newmode, apply them with lchmod. */
/* Set the permissions only if this directory has just
been created. */
- if (ok && specified_mode
- && chmod_safer (dir, newmode, 0, S_IFDIR) != 0)
+ if (ok && specified_mode && (newmode & ~S_IRWXUGO)
+ && lchmod (dir, newmode) != 0)
{
error (0, errno, _("cannot set permissions of directory %s"),
quote (dir));
Index: src/mkfifo.c
===================================================================
RCS file: /fetish/cu/src/mkfifo.c,v
retrieving revision 1.79
diff -p -u -r1.79 mkfifo.c
--- src/mkfifo.c 19 Dec 2005 18:16:07 -0000 1.79
+++ src/mkfifo.c 2 Jan 2006 06:12:21 -0000
@@ -23,7 +23,6 @@
#include <sys/types.h>
#include "system.h"
-#include "chmod-safer.h"
#include "error.h"
#include "modechange.h"
#include "quote.h"
@@ -62,7 +61,7 @@ Create named pipes (FIFOs) with the give
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
- -m, --mode=MODE set permission mode (as in chmod), not a=rw - umask\n\
+ -m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -76,8 +75,7 @@ int
main (int argc, char **argv)
{
mode_t newmode;
- mode_t tmp_mode;
- const char *specified_mode;
+ char const *specified_mode = NULL;
int exit_status = EXIT_SUCCESS;
int optc;
@@ -89,8 +87,6 @@ main (int argc, char **argv)
atexit (close_stdout);
- specified_mode = NULL;
-
#ifndef S_ISFIFO
error (EXIT_FAILURE, 0, _("fifo files not supported"));
#else
@@ -122,33 +118,17 @@ main (int argc, char **argv)
error (EXIT_FAILURE, 0, _("invalid mode"));
newmode = mode_adjust (newmode, change, umask (0));
free (change);
+ if (newmode & ~S_IRWXUGO)
+ error (EXIT_FAILURE, 0,
+ _("mode must specify only file permission bits"));
}
- /* This is the mode we'll use in the mknod or mkfifo call.
- If it doesn't include S_IRUSR, use S_IRUSR so the final
- open-for-fchmod will succeed. */
- tmp_mode = (newmode & S_IRUSR) ? newmode : S_IRUSR;
-
for (; optind < argc; ++optind)
- {
- int fail = mkfifo (argv[optind], tmp_mode);
- if (fail)
+ if (mkfifo (argv[optind], newmode) != 0)
+ {
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
-
- /* If the containing directory happens to have a default ACL, chmod
- ensures the file mode permission bits are still set as desired. */
-
- if (fail == 0 && specified_mode)
- {
- fail = chmod_safer (argv[optind], newmode, 0, S_IFIFO);
- if (fail)
- error (0, errno, _("cannot set permissions of fifo %s"),
- quote (argv[optind]));
- }
-
- if (fail)
exit_status = EXIT_FAILURE;
- }
+ }
exit (exit_status);
#endif
Index: src/mknod.c
===================================================================
RCS file: /fetish/cu/src/mknod.c,v
retrieving revision 1.91
diff -p -u -r1.91 mknod.c
--- src/mknod.c 28 Dec 2005 10:22:41 -0000 1.91
+++ src/mknod.c 2 Jan 2006 06:12:21 -0000
@@ -23,7 +23,6 @@
#include <sys/types.h>
#include "system.h"
-#include "chmod-safer.h"
#include "error.h"
#include "modechange.h"
#include "quote.h"
@@ -63,7 +62,7 @@ Create the special file NAME of the give
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
- -m, --mode=MODE set permission mode (as in chmod), not a=rw - umask\n\
+ -m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -89,12 +88,10 @@ int
main (int argc, char **argv)
{
mode_t newmode;
- mode_t tmp_mode;
- const char *specified_mode;
+ char const *specified_mode = NULL;
int optc;
int expected_operands;
- mode_t node_type IF_LINT (= 0);
- dev_t device = 0;
+ mode_t node_type;
initialize_main (&argc, &argv);
program_name = argv[0];
@@ -104,8 +101,6 @@ main (int argc, char **argv)
atexit (close_stdout);
- specified_mode = NULL;
-
while ((optc = getopt_long (argc, argv, "m:", longopts, NULL)) != -1)
{
switch (optc)
@@ -128,13 +123,11 @@ main (int argc, char **argv)
error (EXIT_FAILURE, 0, _("invalid mode"));
newmode = mode_adjust (newmode, change, umask (0));
free (change);
+ if (newmode & ~S_IRWXUGO)
+ error (EXIT_FAILURE, 0,
+ _("mode must specify only file permission bits"));
}
- /* This is the mode we'll use in the mknod or mkfifo call.
- If it doesn't include S_IRUSR, use S_IRUSR so the final
- open-for-fchmod will succeed. */
- tmp_mode = (newmode & S_IRUSR) ? newmode : S_IRUSR;
-
/* If the number of arguments is 0 or 1,
or (if it's 2 or more and the second one starts with `p'), then there
must be exactly two operands. Otherwise, there must be four. */
@@ -191,6 +184,7 @@ main (int argc, char **argv)
char const *s_major = argv[optind + 2];
char const *s_minor = argv[optind + 3];
uintmax_t i_major, i_minor;
+ dev_t device;
if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
|| i_major != (major_t) i_major)
@@ -208,7 +202,7 @@ main (int argc, char **argv)
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
#endif
- if (mknod (argv[optind], tmp_mode | node_type, device) != 0)
+ if (mknod (argv[optind], newmode | node_type, device) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
}
break;
@@ -217,8 +211,7 @@ main (int argc, char **argv)
#ifndef S_ISFIFO
error (EXIT_FAILURE, 0, _("fifo files not supported"));
#else
- node_type = S_IFIFO;
- if (mkfifo (argv[optind], tmp_mode))
+ if (mkfifo (argv[optind], newmode) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
#endif
break;
@@ -228,16 +221,5 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- /* Perform an explicit chmod to ensure the file mode permission bits
- are set as specified. This extra step is necessary in some cases
- when the containing directory has a default ACL. */
-
- if (specified_mode)
- {
- if (chmod_safer (argv[optind], newmode, device, node_type) != 0)
- error (EXIT_FAILURE, errno, _("cannot set permissions of %s"),
- quote (argv[optind]));
- }
-
exit (EXIT_SUCCESS);
}
--- /dev/null 2005-09-24 22:00:15.000000000 -0700
+++ lib/lchmod.h 2006-01-01 22:06:30.000000000 -0800
@@ -0,0 +1,35 @@
+/* Provide a replacement for lchmod on hosts that lack it.
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef HAVE_LCHMOD
+
+/* The lchmod replacement follows symbolic links. Callers should take
+ this into account; lchmod should be applied only to arguments that
+ are known to not be symbolic links. On hosts that lack lchmod,
+ this can lead to race conditions between the check and the
+ invocation of lchmod, but we know of no workarounds that are
+ reliable in general. You might try requesting support for lchmod
+ from your operating system supplier. */
+
+# define lchmod chmod
+#endif
--- /dev/null 2005-09-24 22:00:15.000000000 -0700
+++ m4/lchmod.m4 2006-01-01 21:24:27.000000000 -0800
@@ -0,0 +1,15 @@
+#serial 1
+
+dnl Copyright (C) 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+dnl Provide a replacement for lchmod on hosts that lack it.
+
+AC_DEFUN([gl_FUNC_LCHMOD],
+[
+ AC_LIBSOURCES([lchmod.h])
+ AC_CHECK_FUNCS_ONCE([lchmod])
+])