home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #23 / NN_1992_23.iso / spool / gnu / utils / bug / 1805 < prev    next >
Encoding:
Text File  |  1992-10-12  |  3.7 KB  |  137 lines

  1. Newsgroups: gnu.utils.bug
  2. Path: sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!jarthur.claremont.edu!jason
  3. From: jason@jarthur.claremont.edu (Jason Merrill)
  4. Subject: Patch to allow restricting root su's
  5. Message-ID: <1992Oct12.071959.24208@muddcs.claremont.edu>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: Harvey Mudd College, Claremont, CA 91711
  8. Distribution: gnu
  9. Date: Mon, 12 Oct 1992 07:19:59 GMT
  10. Approved: bug-gnu-utils@prep.ai.mit.edu
  11. Lines: 124
  12.  
  13. Since I wanted to be able to restrict root access with the GNU su, I
  14. decided to patch it myself.  Here is the result.
  15.  
  16. An additional benefit is that if getlogin() does not return the name of the
  17. user doing the su'ing, su will use getpwuid(getuid())->pw_name instead.
  18.  
  19. Since I wanted to be able to check the name of the user before asking for a
  20. password, I moved the code to determine old_name into main() and made
  21. old_name a global variable.
  22.  
  23. The restriction code is #ifdef'd for your convenience.
  24.  
  25. ----cut here----
  26. --- /gnu/tmp/shellutils-1.7/src/su.c    Sat Aug 22 22:40:20 1992
  27. +++ shellutils-1.7/src/su.c    Mon Oct 12 00:18:05 1992
  28. @@ -65,6 +65,7 @@
  29.     -DSYSLOG_FAILURE    Log failed su's (by default, to root) with syslog.
  30.  
  31.     -DSYSLOG_NON_ROOT    Log all su's, not just those to root (UID 0).
  32. +   -DRESTRICT_ROOT    Only allow root su's from users in group 0.
  33.     Never logs attempted su's to nonexistent accounts.
  34.  
  35.     Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
  36. @@ -75,6 +76,10 @@
  37.  #include <pwd.h>
  38.  #include "system.h"
  39.  
  40. +#ifdef RESTRICT_ROOT
  41. +#include <grp.h>
  42. +#endif
  43. +
  44.  #ifdef HAVE_SYSLOG_H
  45.  #include <syslog.h>
  46.  void log_su ();
  47. @@ -156,6 +161,12 @@
  48.  /* If nonzero, change some environment vars to indicate the user su'd to.  */
  49.  int change_environment;
  50.  
  51. +/* The name of the user doing the su'ing.  */
  52. +#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE) \
  53. +  || defined (RESTRICT_ROOT)
  54. +char *old_user;
  55. +#endif
  56. +
  57.  struct option longopts[] =
  58.  {
  59.    {"command", 1, 0, 'c'},
  60. @@ -220,10 +231,54 @@
  61.    if (optind < argc)
  62.      additional_args = argv + optind;
  63.  
  64. +#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE) \
  65. +  || defined (RESTRICT_ROOT)
  66. +
  67. +#define STRDUP(s) strcpy (xmalloc (strlen (s) + 1), (s))
  68. +
  69. +  /* The utmp entry (via getlogin) is probably the best way to identify
  70. +     the user, especially if someone su's from a su-shell.
  71. +     However, they may be on a pty, in which case getlogin() can't find
  72. +     them, so use the current uid. */
  73. +  old_user = getlogin ();
  74. +  if (old_user == 0)
  75. +    {
  76. +      pw = getpwuid (getuid ());
  77. +      if (pw == 0) 
  78. +    old_user = "";
  79. +      else
  80. +    old_user = STRDUP (pw->pw_name);
  81. +    }
  82. +#endif
  83. +
  84.    pw = getpwnam (new_user);
  85.    if (pw == 0)
  86.      error (1, 0, "user %s does not exist", new_user);
  87.    endpwent ();
  88. +
  89. +#ifdef RESTRICT_ROOT
  90. +  if (pw->pw_uid == 0)
  91. +    {
  92. +      struct group* gr;
  93. +      char** p;
  94. +
  95. +      gr = getgrgid (0);
  96. +      if (gr != 0)
  97. +    {
  98. +      for (p = gr->gr_mem; *p != 0; p++)
  99. +        if (strcmp (old_user, *p) == 0)
  100. +          goto found;
  101. +
  102. +#ifdef SYSLOG_FAILURE
  103. +      log_su (pw, 0);
  104. +#endif      
  105. +      error (1, 0, "You do not have permission to su to %s", new_user);
  106. +      
  107. +    found:
  108. +    }
  109. +    }    
  110. +#endif
  111. +  
  112.    if (!correct_password (pw))
  113.      {
  114.  #ifdef SYSLOG_FAILURE
  115. @@ -404,7 +459,7 @@
  116.       struct passwd *pw;
  117.       int successful;
  118.  {
  119. -  char *new_user, *old_user, *tty;
  120. +  char *new_user, *tty;
  121.  
  122.  #ifndef SYSLOG_NON_ROOT
  123.    if (pw->pw_uid)
  124. @@ -411,11 +466,6 @@
  125.      return;
  126.  #endif
  127.    new_user = pw->pw_name;
  128. -  /* The utmp entry (via getlogin) is probably the best way to identify
  129. -     the user, especially if someone su's from a su-shell.  */
  130. -  old_user = getlogin ();
  131. -  if (old_user == 0)
  132. -    old_user = "";
  133.    tty = ttyname (2);
  134.    if (tty == 0)
  135.      tty = "";
  136.  
  137.