Article View: gnu.utils.bug
Article #1082Fix for chown(2)-related probs on Sequents
From: Fool on a Pedestal
Date: Wed, 11 Nov 1992 03:01
Date: Wed, 11 Nov 1992 03:01
385 lines
13537 bytes
13537 bytes
My strategy went along the lines of the rename/mvdir pair already in the
fileutils distribution; I wrote a wrapper for chown(2), called dochown,
which is installed setuid root. The programs then call xchown, which
spawns a dochown process if necessary. If chown(2) behaves reasonably,
then xchown is #defined to chown.
Previously the code for dochown was sitting in the middle of chgrp, but I
decided to break it out so that chown and install could behave reasonably,
too.
The check for chown(2) brain damage requires using AC_TEST_PROG; is this an
acceptable thing to do?
diff -ur tmp/fileutils-3.4/Makefile.in fileutils-3.4/Makefile.in
--- tmp/fileutils-3.4/Makefile.in Thu Sep 10 19:46:28 1992
+++ fileutils-3.4/Makefile.in Tue Nov 10 18:30:07 1992
@@ -60,6 +60,10 @@
# -DAFS If you use the Andrew File System and want
# install to ignore AFS errors from trying to
# change files' groups.
+# -DDOCHOWN=\"$(libdir)/dochown\"
+# If your chown system call can only be used by the
+# superuser (Sequent Dynix), so must be called
+# suid root.
# Define zero or one of the following; you need one to compile df.
# The numbers after STATFS are the number of args it's passed.
# See lib/fsusage.c for more details.
diff -ur tmp/fileutils-3.4/configure.in fileutils-3.4/configure.in
--- tmp/fileutils-3.4/configure.in Thu Oct 29 11:57:10 1992
+++ fileutils-3.4/configure.in Tue Nov 10 17:30:10 1992
@@ -119,6 +119,11 @@
AC_ALLOCA
AC_ST_BLOCKS
AC_UTIME_NULL
+echo checking for brain damaged chown
+touch conftest.f
+AC_TEST_PROGRAM([main() { return chown("conftest.f",getuid(),getgid()); }]
+, ,LIBOBJS="$LIBOBJS xchown.o" LIBPROGS="$LIBPROGS dochown"
+AC_DEFINE(DOCHOWN, \\\\\"\$(libdir)/dochown\\\\\"))
AC_XENIX_DIR
AC_IRIX_SUN
AC_DYNIX_SEQ
diff -ur tmp/fileutils-3.4/lib/Makefile.in fileutils-3.4/lib/Makefile.in
--- tmp/fileutils-3.4/lib/Makefile.in Thu Sep 10 19:24:05 1992
+++ fileutils-3.4/lib/Makefile.in Tue Nov 10 18:30:32 1992
@@ -28,7 +28,7 @@
stripslash.c xgetcwd.c xmalloc.c xstrdup.c userspec.c yesno.c \
getdate.y posixtm.y \
fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c stpcpy.c \
-strdup.c strstr.c alloca.c
+strdup.c strstr.c alloca.c xchown.c
OBJECTS = argmatch.o backupfile.o basename.o dirname.o eaccess.o \
error.o filemode.o getopt.o getopt1.o \
diff -ur tmp/fileutils-3.4/lib/makepath.c fileutils-3.4/lib/makepath.c
--- tmp/fileutils-3.4/lib/makepath.c Sat Aug 22 12:28:18 1992
+++ fileutils-3.4/lib/makepath.c Tue Nov 10 17:38:24 1992
@@ -61,6 +61,10 @@
typedef int gid_t;
#endif
+#ifndef DOCHOWN
+#define xchown chown
+#endif
+
void error ();
/* Ensure that the directory ARGPATH exists.
@@ -144,7 +148,7 @@
error (0, 0, verbose_fmt_string, dirpath);
if (owner != (uid_t) -1 && group != (gid_t) -1
- && chown (dirpath, owner, group)
+ && xchown (dirpath, owner, group)
#ifdef AFS
&& errno != EPERM
#endif
@@ -192,7 +196,7 @@
if (owner != (uid_t) -1 && group != (gid_t) -1)
{
- if (chown (dirpath, owner, group)
+ if (xchown (dirpath, owner, group)
#ifdef AFS
&& errno != EPERM
#endif
@@ -240,7 +244,7 @@
be able to chmod them. So don't give files away. */
if (owner != (uid_t) -1 && group != (gid_t) -1
- && chown (dirpath, owner, group)
+ && xchown (dirpath, owner, group)
#ifdef AFS
&& errno != EPERM
#endif
diff -ur tmp/fileutils-3.4/lib/system.h fileutils-3.4/lib/system.h
--- tmp/fileutils-3.4/lib/system.h Sat Aug 22 12:03:48 1992
+++ fileutils-3.4/lib/system.h Tue Nov 10 17:30:24 1992
@@ -226,3 +226,7 @@
#endif
#endif
#endif
+
+#ifndef DOCHOWN
+#define xchown chown
+#endif
diff -ur tmp/fileutils-3.4/lib/xchown.c fileutils-3.4/lib/xchown.c
--- tmp/fileutils-3.4/lib/xchown.c Tue Nov 10 15:45:02 1992
+++ fileutils-3.4/lib/xchown.c Tue Nov 10 18:34:00 1992
@@ -0,0 +1,63 @@
+/* xchown.c -- reasonable chown() replacement for Sequent Dynix
+ Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <sys/wait.h>
+#include <stdio.h>
+#include <errno.h>
+#ifndef STDC_HEADERS
+extern int errno;
+#endif
+
+int
+xchown (path, owner, group)
+ char *path;
+ int owner, group;
+{
+ if (getuid () == 0)
+ return chown (path, owner, group);
+ else
+ {
+ int pid;
+ union wait status;
+ char ownstr[5],grpstr[5];
+
+ sprintf (ownstr, "%d", owner); /* Is there a better way? */
+ sprintf (grpstr, "%d", group);
+
+ pid = fork ();
+ switch (pid)
+ {
+ case -1: /* Error. */
+ error (1, errno, "xchown: cannot fork");
+
+ case 0: /* Child. */
+ execl (DOCHOWN, "dochown", path, ownstr, grpstr, 0);
+ error (255, errno, "xchown: cannot run `%s'", DOCHOWN);
+
+ default: /* Parent. */
+ while (wait (&status) != pid)
+ /* Slack. */ ;
+
+ errno = status.w_retcode;
+ if (errno == 2) /* dochown wasn't happy */
+ exit (2);
+ if (errno != 0)
+ return -1;
+ }
+ return 0;
+ }
+}
diff -ur tmp/fileutils-3.4/src/Makefile.in fileutils-3.4/src/Makefile.in
--- tmp/fileutils-3.4/src/Makefile.in Thu Sep 10 19:28:13 1992
+++ fileutils-3.4/src/Makefile.in Tue Nov 10 18:31:07 1992
@@ -23,7 +23,7 @@
SOURCES = chmod.c chgrp.c chown.c cp-aux.c cp-hash.c cp.c \
dd.c df.c du.c install.c ln.c ls.c mkdir.c mkfifo.c mknod.c mv.c mvdir.c \
-rm.c rmdir.c touch.c version.c
+rm.c rmdir.c touch.c version.c dochown.c
DISTFILES = Makefile.in cp.h $(SOURCES)
@@ -88,6 +88,9 @@
dir: dir.o
$(CC) $(LDFLAGS) -o $@ dir.o ../lib/libfu.a version.o $(LIBS)
+
+dochown: dochown.o
+ $(CC) $(LDFLAGS) -o $@ dochown.o ../lib/libfu.a version.o $(LIBS)
du: du.o
$(CC) $(LDFLAGS) -o $@ du.o ../lib/libfu.a version.o $(LIBS)
diff -ur tmp/fileutils-3.4/src/chgrp.c fileutils-3.4/src/chgrp.c
--- tmp/fileutils-3.4/src/chgrp.c Fri Jul 17 12:48:38 1992
+++ fileutils-3.4/src/chgrp.c Tue Nov 10 17:30:59 1992
@@ -167,7 +167,7 @@
{
if (verbose)
describe_change (file, 1);
- if (chown (file, file_stats.st_uid, group))
+ if (xchown (file, file_stats.st_uid, group))
{
if (force_silent == 0)
error (0, errno, "%s", file);
diff -ur tmp/fileutils-3.4/src/chown.c fileutils-3.4/src/chown.c
--- tmp/fileutils-3.4/src/chown.c Fri Aug 21 18:32:40 1992
+++ fileutils-3.4/src/chown.c Tue Nov 10 17:32:05 1992
@@ -171,7 +171,7 @@
{
if (verbose)
describe_change (file, 1);
- if (chown (file, newuser, newgroup))
+ if (xchown (file, newuser, newgroup))
{
if (force_silent == 0)
error (0, errno, "%s", file);
diff -ur tmp/fileutils-3.4/src/cp.c fileutils-3.4/src/cp.c
--- tmp/fileutils-3.4/src/cp.c Thu Oct 29 12:01:18 1992
+++ fileutils-3.4/src/cp.c Tue Nov 10 17:32:41 1992
@@ -741,7 +741,7 @@
/* If non-root uses -p, it's ok if we can't preserve ownership.
But root probably wants to know, e.g. if NFS disallows it. */
- if (chown (dst_path, src_sb.st_uid, src_sb.st_gid)
+ if (xchown (dst_path, src_sb.st_uid, src_sb.st_gid)
&& (errno != EPERM || myeuid == 0))
{
error (0, errno, "%s", dst_path);
@@ -967,7 +967,7 @@
/* If non-root uses -p, it's ok if we can't preserve ownership.
But root probably wants to know, e.g. if NFS disallows it. */
- if (chown (dst_path, src_sb.st_uid, src_sb.st_gid)
+ if (xchown (dst_path, src_sb.st_uid, src_sb.st_gid)
&& (errno != EPERM || myeuid == 0))
{
error (0, errno, "%s", dst_path);
diff -ur tmp/fileutils-3.4/src/dochown.c fileutils-3.4/src/dochown.c
--- tmp/fileutils-3.4/src/dochown.c Tue Nov 10 18:26:38 1992
+++ fileutils-3.4/src/dochown.c Tue Nov 10 18:18:16 1992
@@ -0,0 +1,117 @@
+/* dochown -- Execute chown() system call on Sequent Symmetry
+ Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Helper program for GNU chgrp and install on systems which restrict the
+ chown() system call (i.e. Sequent Symmetry running Dynix)
+
+ Usage: dochown path owner group
+
+ PATH is the file or directory to modify (string).
+ OWNER is the desired uid (uid_t).
+ GROUP is the desired gid (gid_t).
+ This program performs the necessary sanity checking on its arguments.
+
+ All error messages are #ifdefed so that chgrp can be made silent.
+
+ Must be installed setuid root.
+
+ Jason Merrill (jason@jarthur.claremont.edu) */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#include "system.h"
+
+char *program_name; /* Name of program */
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *path;
+ int owner, group;
+ uid_t uid;
+ int retval;
+ struct stat file_stats;
+
+ program_name = argv[0];
+ if (argc != 4)
+ {
+ int i;
+ fprintf (stderr, "Usage: %s path owner group\n", program_name);
+ for (i = 0; i < argc; i++)
+ fprintf (stderr, "Arg %d: %s\n", i, argv[i]);
+ return 2;
+ }
+
+ path = argv[1];
+ owner = atoi (argv[2]);
+ group = atoi (argv[3]);
+
+ if (lstat (path, &file_stats))
+ return errno; /* Problem with file */
+
+ retval = 0;
+ uid = getuid ();
+ if (uid != 0) /* No need to check if you're root */
+ {
+ if (owner == -1) owner = file_stats.st_uid;
+ if (group == -1) group = file_stats.st_gid;
+ if (uid != file_stats.st_uid || uid != owner)
+ {
+#ifdef DEBUG
+ error (0, 0, "uid %d, now %d, want %d",
+ uid, file_stats.st_uid, owner);
+#endif
+ retval = EPERM; /* Not owner */
+ }
+ else
+ {
+ struct passwd *pwd = getpwuid (uid);
+ if (pwd == NULL)
+ {
+#ifdef DEBUG
+ error (0, 0, "No passwd entry");
+#endif
+ retval = EPERM; /* Fake user */
+ }
+ else if (pwd->pw_gid != group)
+ {
+ struct group *grp = getgrgid (group);
+ char **p = grp->gr_mem;
+ for (; *p != NULL; p++)
+ if (strcmp (*p, pwd->pw_name) == 0) goto found;
+#ifdef DEBUG
+ error (0, 0, "Not in group %s", grp->gr_name);
+#endif
+ retval = EPERM; /* Not in group */
+ found:
+ endgrent ();
+ }
+ endpwent ();
+ }
+ }
+ if (retval == 0 && chown (path, owner, group))
+ {
+#ifdef DEBUG
+ error (0, errno, "%s", path);
+#endif
+ retval = errno;
+ }
+ return retval;
+}
diff -ur tmp/fileutils-3.4/src/install.c fileutils-3.4/src/install.c
--- tmp/fileutils-3.4/src/install.c Thu Oct 29 11:00:50 1992
+++ fileutils-3.4/src/install.c Tue Nov 10 17:31:24 1992
@@ -379,7 +379,7 @@
want to know. But AFS returns EPERM when you try to change a
file's group; thus the kludge. */
- if (chown (path, owner_id, group_id)
+ if (xchown (path, owner_id, group_id)
#ifdef AFS
&& errno != EPERM
#endif
diff -ur tmp/fileutils-3.4/src/mv.c fileutils-3.4/src/mv.c
--- tmp/fileutils-3.4/src/mv.c Thu Oct 29 12:14:28 1992
+++ fileutils-3.4/src/mv.c Tue Nov 10 17:33:08 1992
@@ -406,7 +406,7 @@
/* Try to preserve ownership. For non-root it might fail, but that's ok.
But root probably wants to know, e.g. if NFS disallows it. */
- if (chown (dest, source_stats.st_uid, source_stats.st_gid)
+ if (xchown (dest, source_stats.st_uid, source_stats.st_gid)
&& (errno != EPERM || myeuid == 0))
{
error (0, errno, "%s", dest);
Technical Details
Message-ID:
<9211110301.AA07925@life.ai.mit.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!iggy.GW.Vitalink.COM!cs.widener.edu!eff!sol.ctr.columbia.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!jarthur.claremont.edu!jasonReferences:
<1992Nov2.071132.18627@muddcs.claremont.edu>Show Full Headers
Complete Article Headers
Newsgroups: gnu.utils.bug Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!iggy.GW.Vitalink.COM!cs.widener.edu!eff!sol.ctr.columbia.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!jarthur.claremont.edu!jason From: jason@jarthur.claremont.edu (Fool on a Pedestal) Subject: Fix for chown(2)-related probs on Sequents Message-ID: <9211110301.AA07925@life.ai.mit.edu> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet References: <1992Nov2.071132.18627@muddcs.claremont.edu> Distribution: gnu Date: Wed, 11 Nov 1992 03:01:07 GMT Approved: bug-gnu-utils@prep.ai.mit.edu Lines: 386