[Pkg-shadow-commits] r3349 - in upstream/trunk: . src

Nicolas FRANÇOIS nekral-guest at alioth.debian.org
Mon Jun 13 18:26:47 UTC 2011


Author: nekral-guest
Date: 2011-06-13 18:26:47 +0000 (Mon, 13 Jun 2011)
New Revision: 3349

Modified:
   upstream/trunk/ChangeLog
   upstream/trunk/src/su.c
Log:
	* src/su.c (save_caller_context): Extract from main() the code
	used to save the caller's context.

Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog	2011-06-13 18:26:36 UTC (rev 3348)
+++ upstream/trunk/ChangeLog	2011-06-13 18:26:47 UTC (rev 3349)
@@ -1,3 +1,8 @@
+2011-06-12  Nicolas François  <nicolas.francois at centraliens.net>
+
+	* src/su.c (save_caller_context): Extract from main() the code
+	used to save the caller's context.
+
 2011-06-10  Nicolas François  <nicolas.francois at centraliens.net>
 
 	* src/su.c: Group some of the environment processing blocks. The

Modified: upstream/trunk/src/su.c
===================================================================
--- upstream/trunk/src/su.c	2011-06-13 18:26:36 UTC (rev 3348)
+++ upstream/trunk/src/su.c	2011-06-13 18:26:47 UTC (rev 3349)
@@ -75,10 +75,20 @@
  * Global variables
  */
 const char *Prog;
+const char *caller_tty = NULL;	/* Name of tty SU is run from */
+bool caller_is_root = false;
+uid_t caller_uid;
+#ifndef USE_PAM
+int caller_on_console = 0;
+#ifdef SU_ACCESS
+char *caller_pass;
+#endif
+#endif				/* !USE_PAM */
 
+
 /* not needed by sulog.c anymore */
 static char name[BUFSIZ];
-static char oldname[BUFSIZ];
+static char caller_name[BUFSIZ];
 
 /* If nonzero, change some environment vars to indicate the user su'd to. */
 static bool change_environment;
@@ -110,6 +120,7 @@
 static bool iswheel (const char *);
 #endif				/* !USE_PAM */
 static struct passwd * check_perms (void);
+static void save_caller_context (char **argv);
 
 #ifndef USE_PAM
 /*
@@ -178,12 +189,12 @@
 
 static void su_failure (const char *tty, bool su_to_root)
 {
-	sulog (tty, false, oldname, name);	/* log failed attempt */
+	sulog (tty, false, caller_name, name);	/* log failed attempt */
 #ifdef USE_SYSLOG
 	if (getdef_bool ("SYSLOG_SU_ENAB")) {
 		SYSLOG ((su_to_root ? LOG_NOTICE : LOG_INFO,
 		         "- %s %s:%s", tty,
-		         ('\0' != oldname[0]) ? oldname : "???",
+		         ('\0' != caller_name[0]) ? caller_name : "???",
 		         ('\0' != name[0]) ? name : "???"));
 	}
 	closelog ();
@@ -440,10 +451,10 @@
 	 * to Chris Evans <lady0110 at sable.ox.ac.uk>.
 	 */
 
-	if (!amroot) {
+	if (!caller_is_root) {
 		if (   (0 == pw->pw_uid)
 		    && getdef_bool ("SU_WHEEL_ONLY")
-		    && !iswheel (oldname)) {
+		    && !iswheel (caller_name)) {
 			fprintf (stderr,
 			         _("You are not authorized to su %s\n"),
 			         name);
@@ -457,7 +468,7 @@
 			}
 		}
 
-		switch (check_su_auth (oldname, name, 0 == pw->pw_uid)) {
+		switch (check_su_auth (caller_name, name, 0 == pw->pw_uid)) {
 		case 0:	/* normal su, require target user's password */
 			break;
 		case 1:	/* require no password */
@@ -465,7 +476,7 @@
 			break;
 		case 2:	/* require own password */
 			puts (_("(Enter your own password)"));
-			pw->pw_passwd = oldpass;
+			pw->pw_passwd = caller_pass;
 			break;
 		default:	/* access denied (-1) or unexpected value */
 			fprintf (stderr,
@@ -486,12 +497,12 @@
 		         pam_strerror (pamh, ret)));
 		fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
 		(void) pam_end (pamh, ret);
-		su_failure (tty, 0 == pw->pw_uid);
+		su_failure (caller_tty, 0 == pw->pw_uid);
 	}
 
 	ret = pam_acct_mgmt (pamh, 0);
 	if (PAM_SUCCESS != ret) {
-		if (amroot) {
+		if (caller_is_root) {
 			fprintf (stderr,
 			         _("%s: %s\n(Ignored)\n"),
 			         Prog, pam_strerror (pamh, ret));
@@ -504,7 +515,7 @@
 				         _("%s: %s\n"),
 				         Prog, pam_strerror (pamh, ret));
 				(void) pam_end (pamh, ret);
-				su_failure (tty, 0 == pw->pw_uid);
+				su_failure (caller_tty, 0 == pw->pw_uid);
 			}
 		} else {
 			SYSLOG ((LOG_ERR, "pam_acct_mgmt: %s",
@@ -513,7 +524,7 @@
 			         _("%s: %s\n"),
 			         Prog, pam_strerror (pamh, ret));
 			(void) pam_end (pamh, ret);
-			su_failure (tty, 0 == pw->pw_uid);
+			su_failure (caller_tty, 0 == pw->pw_uid);
 		}
 	}
 #else				/* !USE_PAM */
@@ -528,12 +539,12 @@
 	 * The first character of an administrator defined method is an '@'
 	 * character.
 	 */
-	if (   !amroot
+	if (   !caller_is_root
 	    && (pw_auth (pw->pw_passwd, name, PW_SU, (char *) 0) != 0)) {
 		SYSLOG (((pw->pw_uid != 0)? LOG_NOTICE : LOG_WARN,
 		         "Authentication failed for %s", name));
 		fprintf(stderr, _("%s: Authentication failure\n"), Prog);
-		su_failure (tty, 0 == pw->pw_uid);
+		su_failure (caller_tty, 0 == pw->pw_uid);
 	}
 	(void) signal (SIGQUIT, oldsig);
 
@@ -542,7 +553,7 @@
 	 * expired accounts, but normal users can't become a user with an
 	 * expired password.
 	 */
-	if ((!amroot) && (NULL != spwd)) {
+	if ((!caller_is_root) && (NULL != spwd)) {
 		(void) expire (pw, spwd);
 	}
 
@@ -552,15 +563,15 @@
 	 * there is a "SU" entry in the /etc/porttime file denying access to
 	 * the account.
 	 */
-	if (!amroot) {
+	if (!caller_is_root) {
 		if (!isttytime (name, "SU", time ((time_t *) 0))) {
 			SYSLOG (((0 != pw->pw_uid) ? LOG_WARN : LOG_CRIT,
 			         "SU by %s to restricted account %s",
-			         oldname, name));
+			         caller_name, name));
 			fprintf (stderr,
 			         _("%s: You are not authorized to su at that time\n"),
 			         Prog);
-			su_failure (tty, 0 == pw->pw_uid);
+			su_failure (caller_tty, 0 == pw->pw_uid);
 		}
 	}
 #endif				/* !USE_PAM */
@@ -584,6 +595,80 @@
 }
 
 /*
+ * save_caller_context - save information from the call context
+ *
+ *	Save the program's name (Prog), caller's UID (caller_uid /
+ *	caller_is_root), name (caller_name), and password (caller_pass),
+ *	the TTY (ttyp), and whether su was called from a console
+ *	(is_console) for further processing and before they might change.
+ */
+static void save_caller_context (char **argv)
+{
+	struct passwd *pw = NULL;
+	/*
+	 * Get the program name. The program name is used as a prefix to
+	 * most error messages.
+	 */
+	Prog = Basename (argv[0]);
+
+	caller_uid = getuid ();
+	caller_is_root = (caller_uid == 0);
+
+	/*
+	 * Get the tty name. Entries will be logged indicating that the user
+	 * tried to change to the named new user from the current terminal.
+	 */
+	caller_tty = ttyname (0);
+	if ((isatty (0) != 0) && (NULL != caller_tty)) {
+#ifndef USE_PAM
+		caller_on_console = console (caller_tty);
+#endif
+	} else {
+		/*
+		 * Be more paranoid, like su from SimplePAMApps.  --marekm
+		 */
+		if (!caller_is_root) {
+			fprintf (stderr,
+			         _("%s: must be run from a terminal\n"),
+			         Prog);
+			exit (1);
+		}
+		caller_tty = "???";
+	}
+
+	/*
+	 * Get the user's real name. The current UID is used to determine
+	 * who has executed su. That user ID must exist.
+	 */
+	pw = get_my_pwent ();
+	if (NULL == pw) {
+		fprintf (stderr,
+		         _("%s: Cannot determine your user name.\n"),
+		         Prog);
+		SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
+		         (unsigned long) caller_uid));
+		su_failure (caller_tty, true); // FIXME: at this time I do not know the target UID
+	}
+	STRFCPY (caller_name, pw->pw_name);
+
+#ifndef USE_PAM
+#ifdef SU_ACCESS
+	/*
+	 * Sort out the password of user calling su, in case needed later
+	 * -- chris
+	 */
+	if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
+		struct spwd *spwd = getspnam (caller_name);
+		if (NULL != spwd) {
+			pw->pw_passwd = spwd->sp_pwdp;
+		}
+	}
+	caller_pass = xstrdup (pw->pw_passwd);
+#endif				/* SU_ACCESS */
+#endif				/* !USE_PAM */
+}
+
+/*
  * su - switch user id
  *
  *	su changes the user's ids to the values for the specified user.  if
@@ -596,11 +681,8 @@
 int main (int argc, char **argv)
 {
 	const char *cp;
-	const char *tty = NULL;	/* Name of tty SU is run from        */
 	bool doshell = false;
 	bool fakelogin = false;
-	bool amroot = false;
-	uid_t my_uid;
 	struct passwd *pw = NULL;
 	char *shellstr = NULL;
 	char *command = NULL;
@@ -611,11 +693,7 @@
 	int err = 0;
 
 	RETSIGTYPE (*oldsig) (int);
-	int is_console = 0;
 
-#ifdef SU_ACCESS
-	char *oldpass;
-#endif
 #endif				/* !USE_PAM */
 
 	(void) setlocale (LC_ALL, "");
@@ -624,11 +702,7 @@
 
 	change_environment = true;
 
-	/*
-	 * Get the program name. The program name is used as a prefix to
-	 * most error messages.
-	 */
-	Prog = Basename (argv[0]);
+	save_caller_context (argv);
 
 	OPENLOG ("su");
 
@@ -692,32 +766,7 @@
 
 	initenv ();
 
-	my_uid = getuid ();
-	amroot = (my_uid == 0);
-
 	/*
-	 * Get the tty name. Entries will be logged indicating that the user
-	 * tried to change to the named new user from the current terminal.
-	 */
-	tty = ttyname (0);
-	if ((isatty (0) != 0) && (NULL != tty)) {
-#ifndef USE_PAM
-		is_console = console (tty);
-#endif
-	} else {
-		/*
-		 * Be more paranoid, like su from SimplePAMApps.  --marekm
-		 */
-		if (!amroot) {
-			fprintf (stderr,
-			         _("%s: must be run from a terminal\n"),
-			         Prog);
-			exit (1);
-		}
-		tty = "???";
-	}
-
-	/*
 	 * The next argument must be either a user ID, or some flag to a
 	 * subshell. Pretty sticky since you can't have an argument which
 	 * doesn't start with a "-" unless you specify the new user name.
@@ -737,7 +786,7 @@
 			root_pw = getpwuid (0);
 			if (NULL == root_pw) {
 				SYSLOG ((LOG_CRIT, "There is no UID 0 user."));
-				su_failure (tty, true);
+				su_failure (caller_tty, true);
 			}
 			(void) strcpy (name, root_pw->pw_name);
 		}
@@ -748,37 +797,7 @@
 		doshell = false;
 	}
 
-	/*
-	 * Get the user's real name. The current UID is used to determine
-	 * who has executed su. That user ID must exist.
-	 */
-	pw = get_my_pwent ();
-	if (NULL == pw) {
-		fprintf (stderr,
-		         _("%s: Cannot determine your user name.\n"),
-		         Prog);
-		SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
-		         (unsigned long) my_uid));
-		su_failure (tty, true); // FIXME: at this time I do not know the target UID
-	}
-	STRFCPY (oldname, pw->pw_name);
-
-#ifndef USE_PAM
-#ifdef SU_ACCESS
-	/*
-	 * Sort out the password of user calling su, in case needed later
-	 * -- chris
-	 */
-	if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
-		struct spwd *spwd = getspnam (oldname);
-		if (NULL != spwd) {
-			pw->pw_passwd = spwd->sp_pwdp;
-		}
-	}
-	oldpass = xstrdup (pw->pw_passwd);
-#endif				/* SU_ACCESS */
-
-#else				/* USE_PAM */
+#ifdef USE_PAM
 	ret = pam_start ("su", name, &conv, &pamh);
 	if (PAM_SUCCESS != ret) {
 		SYSLOG ((LOG_ERR, "pam_start: error %d", ret);
@@ -788,9 +807,9 @@
 		exit (1);
 	}
 
-	ret = pam_set_item (pamh, PAM_TTY, (const void *) tty);
+	ret = pam_set_item (pamh, PAM_TTY, (const void *) caller_tty);
 	if (PAM_SUCCESS == ret) {
-		ret = pam_set_item (pamh, PAM_RUSER, (const void *) oldname);
+		ret = pam_set_item (pamh, PAM_RUSER, (const void *) caller_name);
 	}
 	if (PAM_SUCCESS != ret) {
 		SYSLOG ((LOG_ERR, "pam_set_item: %s",
@@ -815,7 +834,7 @@
 	 * restricted shell, the environment must be changed and the shell
 	 * must be the one specified in /etc/passwd.
 	 */
-	if (   !amroot
+	if (   !caller_is_root
 	    && restricted_shell (pw->pw_shell)) {
 		shellstr = NULL;
 		change_environment = true;
@@ -910,13 +929,13 @@
 		addenv ("IFS= \t\n", NULL);	/* ... instead, set a safe IFS */
 	}
 
-	sulog (tty, true, oldname, name);	/* save SU information */
+	sulog (caller_tty, true, caller_name, name);	/* save SU information */
 	endpwent ();
 	endspent ();
 #ifdef USE_SYSLOG
 	if (getdef_bool ("SYSLOG_SU_ENAB")) {
-		SYSLOG ((LOG_INFO, "+ %s %s:%s", tty,
-		         ('\0' != oldname[0]) ? oldname : "???",
+		SYSLOG ((LOG_INFO, "+ %s %s:%s", caller_tty,
+		         ('\0' != caller_name[0]) ? caller_name : "???",
 		         ('\0' != name[0]) ? name : "???"));
 	}
 #endif
@@ -978,11 +997,11 @@
 	environ = newenvp;	/* make new environment active */
 
 	/* no limits if su from root (unless su must fake login's behavior) */
-	if (!amroot || fakelogin) {
+	if (!caller_is_root || fakelogin) {
 		setup_limits (pw);
 	}
 
-	if (setup_uid_gid (pw, is_console) != 0) {
+	if (setup_uid_gid (pw, caller_on_console) != 0) {
 		exit (1);
 	}
 #endif				/* !USE_PAM */




More information about the Pkg-shadow-commits mailing list