🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

2 total messages Started by Jason Merrill Mon, 02 Nov 1992 07:11
Problem with fileutils 3.4: chown(2) priviledged
#47
Author: Jason Merrill
Date: Mon, 02 Nov 1992 07:11
35 lines
1735 bytes
On the Sequent Symmetry, the system call chown(2) is considered
priviledged; if a non-superuser calls it, the call fails and errno is set
to EPERM.  This breaks chgrp and install rather badly.  The supplied
chgrp is setuid root, and the install doesn't set gid unless you're root.
Even the call chown(fname,-1,-1) fails.

Under Ultrix 4.2A (47), the situation is identical, as far as I can tell.

Under SunOS 4.1.2, the situation is the same except that chgrp isn't setuid
root, so no one can chgrp their files.

Is there a solution for this?  Why isn't there a separate library function
to set the group?

At any rate, install(1) shouldn't fail every time a non-root user runs it.

This patch will make install act like it does on these machines; there
should probably be a check for this behavior in configure.

--- /tmp/RCSA005056	Sun Nov  1 23:10:19 1992
+++ install.c	Sun Nov  1 23:06:53 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 (getuid() == 0 && chown (path, owner_id, group_id)
 #ifdef AFS
       && errno != EPERM
 #endif


--
Jason Merrill
jason@jarthur.claremont.edu
Fix for chown(2)-related probs on Sequents
#1082
Author: Fool on a Pedestal
Date: Wed, 11 Nov 1992 03:01
385 lines
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);
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads