home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / gnu / utils / bug / 2041 < prev    next >
Encoding:
Text File  |  1992-11-11  |  12.8 KB  |  400 lines

  1. Newsgroups: gnu.utils.bug
  2. 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
  3. From: jason@jarthur.claremont.edu (Fool on a Pedestal)
  4. Subject: Fix for chown(2)-related probs on Sequents
  5. Message-ID: <9211110301.AA07925@life.ai.mit.edu>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: GNUs Not Usenet
  8. References: <1992Nov2.071132.18627@muddcs.claremont.edu> 
  9. Distribution: gnu
  10. Date: Wed, 11 Nov 1992 03:01:07 GMT
  11. Approved: bug-gnu-utils@prep.ai.mit.edu
  12. Lines: 386
  13.  
  14. My strategy went along the lines of the rename/mvdir pair already in the
  15. fileutils distribution; I wrote a wrapper for chown(2), called dochown,
  16. which is installed setuid root.  The programs then call xchown, which
  17. spawns a dochown process if necessary.  If chown(2) behaves reasonably,
  18. then xchown is #defined to chown.
  19.  
  20. Previously the code for dochown was sitting in the middle of chgrp, but I
  21. decided to break it out so that chown and install could behave reasonably,
  22. too.
  23.  
  24. The check for chown(2) brain damage requires using AC_TEST_PROG; is this an
  25. acceptable thing to do?
  26.  
  27. diff -ur tmp/fileutils-3.4/Makefile.in fileutils-3.4/Makefile.in
  28. --- tmp/fileutils-3.4/Makefile.in    Thu Sep 10 19:46:28 1992
  29. +++ fileutils-3.4/Makefile.in    Tue Nov 10 18:30:07 1992
  30. @@ -60,6 +60,10 @@
  31.  # -DAFS            If you use the Andrew File System and want
  32.  #            install to ignore AFS errors from trying to
  33.  #            change files' groups.
  34. +# -DDOCHOWN=\"$(libdir)/dochown\"
  35. +#            If your chown system call can only be used by the
  36. +#            superuser (Sequent Dynix), so must be called
  37. +#            suid root.
  38.  # Define zero or one of the following; you need one to compile df.
  39.  # The numbers after STATFS are the number of args it's passed.
  40.  # See lib/fsusage.c for more details.
  41. diff -ur tmp/fileutils-3.4/configure.in fileutils-3.4/configure.in
  42. --- tmp/fileutils-3.4/configure.in    Thu Oct 29 11:57:10 1992
  43. +++ fileutils-3.4/configure.in    Tue Nov 10 17:30:10 1992
  44. @@ -119,6 +119,11 @@
  45.  AC_ALLOCA
  46.  AC_ST_BLOCKS
  47.  AC_UTIME_NULL
  48. +echo checking for brain damaged chown
  49. +touch conftest.f
  50. +AC_TEST_PROGRAM([main() { return chown("conftest.f",getuid(),getgid()); }]
  51. +, ,LIBOBJS="$LIBOBJS xchown.o" LIBPROGS="$LIBPROGS dochown" 
  52. +AC_DEFINE(DOCHOWN, \\\\\"\$(libdir)/dochown\\\\\"))
  53.  AC_XENIX_DIR
  54.  AC_IRIX_SUN
  55.  AC_DYNIX_SEQ
  56. diff -ur tmp/fileutils-3.4/lib/Makefile.in fileutils-3.4/lib/Makefile.in
  57. --- tmp/fileutils-3.4/lib/Makefile.in    Thu Sep 10 19:24:05 1992
  58. +++ fileutils-3.4/lib/Makefile.in    Tue Nov 10 18:30:32 1992
  59. @@ -28,7 +28,7 @@
  60.  stripslash.c xgetcwd.c xmalloc.c xstrdup.c userspec.c yesno.c \
  61.  getdate.y posixtm.y \
  62.  fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c stpcpy.c \
  63. -strdup.c strstr.c alloca.c
  64. +strdup.c strstr.c alloca.c xchown.c
  65.  
  66.  OBJECTS = argmatch.o backupfile.o basename.o dirname.o eaccess.o \
  67.  error.o filemode.o getopt.o getopt1.o \
  68. diff -ur tmp/fileutils-3.4/lib/makepath.c fileutils-3.4/lib/makepath.c
  69. --- tmp/fileutils-3.4/lib/makepath.c    Sat Aug 22 12:28:18 1992
  70. +++ fileutils-3.4/lib/makepath.c    Tue Nov 10 17:38:24 1992
  71. @@ -61,6 +61,10 @@
  72.  typedef int gid_t;
  73.  #endif
  74.  
  75. +#ifndef DOCHOWN
  76. +#define xchown chown
  77. +#endif
  78. +
  79.  void error ();
  80.  
  81.  /* Ensure that the directory ARGPATH exists.
  82. @@ -144,7 +148,7 @@
  83.              error (0, 0, verbose_fmt_string, dirpath);
  84.  
  85.            if (owner != (uid_t) -1 && group != (gid_t) -1
  86. -              && chown (dirpath, owner, group)
  87. +              && xchown (dirpath, owner, group)
  88.  #ifdef AFS
  89.                && errno != EPERM
  90.  #endif
  91. @@ -192,7 +196,7 @@
  92.  
  93.        if (owner != (uid_t) -1 && group != (gid_t) -1)
  94.      {
  95. -      if (chown (dirpath, owner, group)
  96. +      if (xchown (dirpath, owner, group)
  97.  #ifdef AFS
  98.            && errno != EPERM
  99.  #endif
  100. @@ -240,7 +244,7 @@
  101.       be able to chmod them.  So don't give files away.  */
  102.  
  103.        if (owner != (uid_t) -1 && group != (gid_t) -1
  104. -      && chown (dirpath, owner, group)
  105. +      && xchown (dirpath, owner, group)
  106.  #ifdef AFS
  107.        && errno != EPERM
  108.  #endif
  109. diff -ur tmp/fileutils-3.4/lib/system.h fileutils-3.4/lib/system.h
  110. --- tmp/fileutils-3.4/lib/system.h    Sat Aug 22 12:03:48 1992
  111. +++ fileutils-3.4/lib/system.h    Tue Nov 10 17:30:24 1992
  112. @@ -226,3 +226,7 @@
  113.  #endif
  114.  #endif
  115.  #endif
  116. +
  117. +#ifndef DOCHOWN
  118. +#define xchown chown
  119. +#endif
  120. diff -ur tmp/fileutils-3.4/lib/xchown.c fileutils-3.4/lib/xchown.c
  121. --- tmp/fileutils-3.4/lib/xchown.c    Tue Nov 10 15:45:02 1992
  122. +++ fileutils-3.4/lib/xchown.c    Tue Nov 10 18:34:00 1992
  123. @@ -0,0 +1,63 @@
  124. +/* xchown.c -- reasonable chown() replacement for Sequent Dynix
  125. +   Copyright (C) 1992 Free Software Foundation, Inc.
  126. +
  127. +   This program is free software; you can redistribute it and/or modify
  128. +   it under the terms of the GNU General Public License as published by
  129. +   the Free Software Foundation; either version 2, or (at your option)
  130. +   any later version.
  131. +
  132. +   This program is distributed in the hope that it will be useful,
  133. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  134. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  135. +   GNU General Public License for more details.
  136. +
  137. +   You should have received a copy of the GNU General Public License
  138. +   along with this program; if not, write to the Free Software
  139. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  140. +   
  141. +#include <sys/wait.h>
  142. +#include <stdio.h>
  143. +#include <errno.h>
  144. +#ifndef STDC_HEADERS
  145. +extern int errno;
  146. +#endif
  147. +
  148. +int
  149. +xchown (path, owner, group)
  150. +     char *path;
  151. +     int owner, group;
  152. +{
  153. +  if (getuid () == 0)
  154. +    return chown (path, owner, group);
  155. +  else
  156. +    {
  157. +      int pid;
  158. +      union wait status;
  159. +      char ownstr[5],grpstr[5];
  160. +
  161. +      sprintf (ownstr, "%d", owner); /* Is there a better way? */
  162. +      sprintf (grpstr, "%d", group);
  163. +  
  164. +      pid = fork ();
  165. +      switch (pid)
  166. +    {
  167. +    case -1:        /* Error. */
  168. +      error (1, errno, "xchown: cannot fork");
  169. +
  170. +    case 0:            /* Child. */
  171. +      execl (DOCHOWN, "dochown", path, ownstr, grpstr, 0);
  172. +      error (255, errno, "xchown: cannot run `%s'", DOCHOWN);
  173. +
  174. +    default:        /* Parent. */
  175. +      while (wait (&status) != pid)
  176. +        /* Slack. */ ;
  177. +
  178. +      errno = status.w_retcode;
  179. +      if (errno == 2)    /* dochown wasn't happy */
  180. +        exit (2);
  181. +      if (errno != 0)
  182. +        return -1;
  183. +    }
  184. +      return 0;
  185. +    }
  186. +}
  187. diff -ur tmp/fileutils-3.4/src/Makefile.in fileutils-3.4/src/Makefile.in
  188. --- tmp/fileutils-3.4/src/Makefile.in    Thu Sep 10 19:28:13 1992
  189. +++ fileutils-3.4/src/Makefile.in    Tue Nov 10 18:31:07 1992
  190. @@ -23,7 +23,7 @@
  191.  
  192.  SOURCES = chmod.c chgrp.c chown.c cp-aux.c cp-hash.c cp.c \
  193.  dd.c df.c du.c install.c ln.c ls.c mkdir.c mkfifo.c mknod.c mv.c mvdir.c \
  194. -rm.c rmdir.c touch.c version.c
  195. +rm.c rmdir.c touch.c version.c dochown.c
  196.  
  197.  DISTFILES = Makefile.in cp.h $(SOURCES)
  198.  
  199. @@ -88,6 +88,9 @@
  200.  
  201.  dir: dir.o
  202.      $(CC) $(LDFLAGS) -o $@ dir.o ../lib/libfu.a version.o $(LIBS)
  203. +
  204. +dochown: dochown.o
  205. +    $(CC) $(LDFLAGS) -o $@ dochown.o ../lib/libfu.a version.o $(LIBS)
  206.  
  207.  du: du.o
  208.      $(CC) $(LDFLAGS) -o $@ du.o ../lib/libfu.a version.o $(LIBS)
  209. diff -ur tmp/fileutils-3.4/src/chgrp.c fileutils-3.4/src/chgrp.c
  210. --- tmp/fileutils-3.4/src/chgrp.c    Fri Jul 17 12:48:38 1992
  211. +++ fileutils-3.4/src/chgrp.c    Tue Nov 10 17:30:59 1992
  212. @@ -167,7 +167,7 @@
  213.      {
  214.        if (verbose)
  215.      describe_change (file, 1);
  216. -      if (chown (file, file_stats.st_uid, group))
  217. +      if (xchown (file, file_stats.st_uid, group))
  218.      {
  219.        if (force_silent == 0)
  220.          error (0, errno, "%s", file);
  221. diff -ur tmp/fileutils-3.4/src/chown.c fileutils-3.4/src/chown.c
  222. --- tmp/fileutils-3.4/src/chown.c    Fri Aug 21 18:32:40 1992
  223. +++ fileutils-3.4/src/chown.c    Tue Nov 10 17:32:05 1992
  224. @@ -171,7 +171,7 @@
  225.      {
  226.        if (verbose)
  227.      describe_change (file, 1);
  228. -      if (chown (file, newuser, newgroup))
  229. +      if (xchown (file, newuser, newgroup))
  230.      {
  231.        if (force_silent == 0)
  232.          error (0, errno, "%s", file);
  233. diff -ur tmp/fileutils-3.4/src/cp.c fileutils-3.4/src/cp.c
  234. --- tmp/fileutils-3.4/src/cp.c    Thu Oct 29 12:01:18 1992
  235. +++ fileutils-3.4/src/cp.c    Tue Nov 10 17:32:41 1992
  236. @@ -741,7 +741,7 @@
  237.  
  238.        /* If non-root uses -p, it's ok if we can't preserve ownership.
  239.       But root probably wants to know, e.g. if NFS disallows it.  */
  240. -      if (chown (dst_path, src_sb.st_uid, src_sb.st_gid)
  241. +      if (xchown (dst_path, src_sb.st_uid, src_sb.st_gid)
  242.        && (errno != EPERM || myeuid == 0))
  243.      {
  244.        error (0, errno, "%s", dst_path);
  245. @@ -967,7 +967,7 @@
  246.  
  247.        /* If non-root uses -p, it's ok if we can't preserve ownership.
  248.           But root probably wants to know, e.g. if NFS disallows it.  */
  249. -      if (chown (dst_path, src_sb.st_uid, src_sb.st_gid)
  250. +      if (xchown (dst_path, src_sb.st_uid, src_sb.st_gid)
  251.            && (errno != EPERM || myeuid == 0))
  252.          {
  253.            error (0, errno, "%s", dst_path);
  254. diff -ur tmp/fileutils-3.4/src/dochown.c fileutils-3.4/src/dochown.c
  255. --- tmp/fileutils-3.4/src/dochown.c    Tue Nov 10 18:26:38 1992
  256. +++ fileutils-3.4/src/dochown.c    Tue Nov 10 18:18:16 1992
  257. @@ -0,0 +1,117 @@
  258. +/* dochown -- Execute chown() system call on Sequent Symmetry
  259. +   Copyright (C) 1992 Free Software Foundation, Inc.
  260. +
  261. +   This program is free software; you can redistribute it and/or modify
  262. +   it under the terms of the GNU General Public License as published by
  263. +   the Free Software Foundation; either version 2, or (at your option)
  264. +   any later version.
  265. +
  266. +   This program is distributed in the hope that it will be useful,
  267. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  268. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  269. +   GNU General Public License for more details.
  270. +
  271. +   You should have received a copy of the GNU General Public License
  272. +   along with this program; if not, write to the Free Software
  273. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  274. +
  275. +/* Helper program for GNU chgrp and install on systems which restrict the
  276. +   chown() system call (i.e. Sequent Symmetry running Dynix)
  277. +
  278. +   Usage: dochown path owner group
  279. +
  280. +   PATH is the file or directory to modify (string).
  281. +   OWNER is the desired uid (uid_t).
  282. +   GROUP is the desired gid (gid_t).
  283. +   This program performs the necessary sanity checking on its arguments.
  284. +
  285. +   All error messages are #ifdefed so that chgrp can be made silent.
  286. +
  287. +   Must be installed setuid root.
  288. +
  289. +   Jason Merrill (jason@jarthur.claremont.edu) */
  290. +
  291. +#include <sys/types.h>
  292. +#include <stdio.h>
  293. +#include <pwd.h>
  294. +#include <grp.h>
  295. +#include "system.h"
  296. +
  297. +char *program_name;        /* Name of program */
  298. +
  299. +main (argc, argv)
  300. +     int argc;
  301. +     char **argv;
  302. +{
  303. +  char *path;
  304. +  int owner, group;
  305. +  uid_t uid;
  306. +  int retval;
  307. +  struct stat file_stats;
  308. +
  309. +  program_name = argv[0];
  310. +  if (argc != 4)
  311. +    {
  312. +      int i;
  313. +      fprintf (stderr, "Usage: %s path owner group\n", program_name);
  314. +      for (i = 0; i < argc; i++)
  315. +    fprintf (stderr, "Arg %d: %s\n", i, argv[i]);
  316. +      return 2;
  317. +    }
  318. +
  319. +  path = argv[1];
  320. +  owner = atoi (argv[2]);
  321. +  group = atoi (argv[3]);
  322. +  
  323. +  if (lstat (path, &file_stats))
  324. +    return errno;        /* Problem with file */
  325. +  
  326. +  retval = 0;
  327. +  uid = getuid ();
  328. +  if (uid != 0)            /* No need to check if you're root */
  329. +    {
  330. +      if (owner == -1) owner = file_stats.st_uid;
  331. +      if (group == -1) group = file_stats.st_gid;
  332. +      if (uid != file_stats.st_uid || uid != owner)
  333. +    {
  334. +#ifdef DEBUG      
  335. +      error (0, 0, "uid %d, now %d, want %d",
  336. +         uid, file_stats.st_uid, owner);
  337. +#endif      
  338. +      retval = EPERM;        /* Not owner */
  339. +    }
  340. +      else
  341. +    {
  342. +      struct passwd *pwd = getpwuid (uid);
  343. +      if (pwd == NULL)
  344. +        {
  345. +#ifdef DEBUG          
  346. +          error (0, 0, "No passwd entry");
  347. +#endif          
  348. +          retval = EPERM;    /* Fake user */
  349. +        }
  350. +      else if (pwd->pw_gid != group)
  351. +        {
  352. +          struct group *grp = getgrgid (group);
  353. +          char **p = grp->gr_mem;
  354. +          for (; *p != NULL; p++)
  355. +        if (strcmp (*p, pwd->pw_name) == 0) goto found;
  356. +#ifdef DEBUG
  357. +          error (0, 0, "Not in group %s", grp->gr_name);
  358. +#endif          
  359. +          retval = EPERM;    /* Not in group */
  360. +        found:
  361. +          endgrent ();
  362. +        }
  363. +      endpwent ();
  364. +    }
  365. +    }
  366. +  if (retval == 0 && chown (path, owner, group))
  367. +    {
  368. +#ifdef DEBUG
  369. +      error (0, errno, "%s", path);
  370. +#endif      
  371. +      retval = errno;
  372. +    }
  373. +  return retval;  
  374. +}
  375. diff -ur tmp/fileutils-3.4/src/install.c fileutils-3.4/src/install.c
  376. --- tmp/fileutils-3.4/src/install.c    Thu Oct 29 11:00:50 1992
  377. +++ fileutils-3.4/src/install.c    Tue Nov 10 17:31:24 1992
  378. @@ -379,7 +379,7 @@
  379.       want to know.  But AFS returns EPERM when you try to change a
  380.       file's group; thus the kludge.  */
  381.  
  382. -  if (chown (path, owner_id, group_id)
  383. +  if (xchown (path, owner_id, group_id)
  384.  #ifdef AFS
  385.        && errno != EPERM
  386.  #endif
  387. diff -ur tmp/fileutils-3.4/src/mv.c fileutils-3.4/src/mv.c
  388. --- tmp/fileutils-3.4/src/mv.c    Thu Oct 29 12:14:28 1992
  389. +++ fileutils-3.4/src/mv.c    Tue Nov 10 17:33:08 1992
  390. @@ -406,7 +406,7 @@
  391.  
  392.    /* Try to preserve ownership.  For non-root it might fail, but that's ok.
  393.       But root probably wants to know, e.g. if NFS disallows it.  */
  394. -  if (chown (dest, source_stats.st_uid, source_stats.st_gid)
  395. +  if (xchown (dest, source_stats.st_uid, source_stats.st_gid)
  396.        && (errno != EPERM || myeuid == 0))
  397.      {
  398.        error (0, errno, "%s", dest);
  399.  
  400.