Article View: gnu.utils.bug
Article #894Patch to allow restricting root su's
From: Jason Merrill
Date: Mon, 12 Oct 1992 07:19
Date: Mon, 12 Oct 1992 07:19
123 lines
3874 bytes
3874 bytes
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 = "";
Technical Details
Message-ID:
<1992Oct12.071959.24208@muddcs.claremont.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!think.com!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!jarthur.claremont.edu!jasonShow Full Headers
Complete Article Headers
Newsgroups: gnu.utils.bug Path: arc1-ca.pugleaf.net!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