home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.utils.bug
- Path: 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
-
- 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);
-
-