home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.utils.bug
- Path: sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!jarthur.claremont.edu!jason
- From: jason@jarthur.claremont.edu (Jason Merrill)
- Subject: Patch to allow restricting root su's
- Message-ID: <1992Oct12.071959.24208@muddcs.claremont.edu>
- Sender: gnulists@ai.mit.edu
- Organization: Harvey Mudd College, Claremont, CA 91711
- Distribution: gnu
- Date: Mon, 12 Oct 1992 07:19:59 GMT
- Approved: bug-gnu-utils@prep.ai.mit.edu
- Lines: 124
-
- Since I wanted to be able to restrict root access with the GNU su, I
- decided to patch it myself. Here is the result.
-
- An additional benefit is that if getlogin() does not return the name of the
- user doing the su'ing, su will use getpwuid(getuid())->pw_name instead.
-
- Since I wanted to be able to check the name of the user before asking for a
- password, I moved the code to determine old_name into main() and made
- old_name a global variable.
-
- The restriction code is #ifdef'd for your convenience.
-
- ----cut here----
- --- /gnu/tmp/shellutils-1.7/src/su.c Sat Aug 22 22:40:20 1992
- +++ shellutils-1.7/src/su.c Mon Oct 12 00:18:05 1992
- @@ -65,6 +65,7 @@
- -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog.
-
- -DSYSLOG_NON_ROOT Log all su's, not just those to root (UID 0).
- + -DRESTRICT_ROOT Only allow root su's from users in group 0.
- Never logs attempted su's to nonexistent accounts.
-
- Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
- @@ -75,6 +76,10 @@
- #include <pwd.h>
- #include "system.h"
-
- +#ifdef RESTRICT_ROOT
- +#include <grp.h>
- +#endif
- +
- #ifdef HAVE_SYSLOG_H
- #include <syslog.h>
- void log_su ();
- @@ -156,6 +161,12 @@
- /* If nonzero, change some environment vars to indicate the user su'd to. */
- int change_environment;
-
- +/* The name of the user doing the su'ing. */
- +#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE) \
- + || defined (RESTRICT_ROOT)
- +char *old_user;
- +#endif
- +
- struct option longopts[] =
- {
- {"command", 1, 0, 'c'},
- @@ -220,10 +231,54 @@
- if (optind < argc)
- additional_args = argv + optind;
-
- +#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE) \
- + || defined (RESTRICT_ROOT)
- +
- +#define STRDUP(s) strcpy (xmalloc (strlen (s) + 1), (s))
- +
- + /* The utmp entry (via getlogin) is probably the best way to identify
- + the user, especially if someone su's from a su-shell.
- + However, they may be on a pty, in which case getlogin() can't find
- + them, so use the current uid. */
- + old_user = getlogin ();
- + if (old_user == 0)
- + {
- + pw = getpwuid (getuid ());
- + if (pw == 0)
- + old_user = "";
- + else
- + old_user = STRDUP (pw->pw_name);
- + }
- +#endif
- +
- pw = getpwnam (new_user);
- if (pw == 0)
- error (1, 0, "user %s does not exist", new_user);
- endpwent ();
- +
- +#ifdef RESTRICT_ROOT
- + if (pw->pw_uid == 0)
- + {
- + struct group* gr;
- + char** p;
- +
- + gr = getgrgid (0);
- + if (gr != 0)
- + {
- + for (p = gr->gr_mem; *p != 0; p++)
- + if (strcmp (old_user, *p) == 0)
- + goto found;
- +
- +#ifdef SYSLOG_FAILURE
- + log_su (pw, 0);
- +#endif
- + error (1, 0, "You do not have permission to su to %s", new_user);
- +
- + found:
- + }
- + }
- +#endif
- +
- if (!correct_password (pw))
- {
- #ifdef SYSLOG_FAILURE
- @@ -404,7 +459,7 @@
- struct passwd *pw;
- int successful;
- {
- - char *new_user, *old_user, *tty;
- + char *new_user, *tty;
-
- #ifndef SYSLOG_NON_ROOT
- if (pw->pw_uid)
- @@ -411,11 +466,6 @@
- return;
- #endif
- new_user = pw->pw_name;
- - /* The utmp entry (via getlogin) is probably the best way to identify
- - the user, especially if someone su's from a su-shell. */
- - old_user = getlogin ();
- - if (old_user == 0)
- - old_user = "";
- tty = ttyname (2);
- if (tty == 0)
- tty = "";
-
-