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

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


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

Modified:
   upstream/trunk/ChangeLog
   upstream/trunk/lib/prototypes.h
   upstream/trunk/src/su.c
   upstream/trunk/src/suauth.c
Log:
	* lib/prototypes.h, src/suauth.c, src/su.c (check_su_auth): Do not
	use the pwent global variable to communicate between APIs of
	different files. Added boolean parameter su_to_root to
	check_su_auth().
	* src/su.c (check_perms): Return the passwd entry of the finally
	authenticated user. Remove usage of the pwent variable.
	* src/su.c: The password of the caller is the one from the
	spwd structure only if the passwd's password is 'x'.

Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog	2011-06-13 18:26:16 UTC (rev 3345)
+++ upstream/trunk/ChangeLog	2011-06-13 18:26:26 UTC (rev 3346)
@@ -17,6 +17,14 @@
 	restricted_shell is called only once. This will allow moving the
 	environment definition after the switch to the new user.
 	* src/su.c: Extract the authentication from the main function.
+	* lib/prototypes.h, src/suauth.c, src/su.c (check_su_auth): Do not
+	use the pwent global variable to communicate between APIs of
+	different files. Added boolean parameter su_to_root to
+	check_su_auth().
+	* src/su.c (check_perms): Return the passwd entry of the finally
+	authenticated user. Remove usage of the pwent variable.
+	* src/su.c: The password of the caller is the one from the
+	spwd structure only if the passwd's password is 'x'.
 
 2011-06-10  Nicolas François  <nicolas.francois at centraliens.net>
 

Modified: upstream/trunk/lib/prototypes.h
===================================================================
--- upstream/trunk/lib/prototypes.h	2011-06-13 18:26:16 UTC (rev 3345)
+++ upstream/trunk/lib/prototypes.h	2011-06-13 18:26:26 UTC (rev 3346)
@@ -348,7 +348,9 @@
 extern long strtoday (const char *);
 
 /* suauth.c */
-extern int check_su_auth (const char *actual_id, const char *wanted_id);
+extern int check_su_auth (const char *actual_id,
+                          const char *wanted_id,
+                          bool su_to_root);
 
 /* sulog.c */
 extern void sulog (const char *tty,

Modified: upstream/trunk/src/su.c
===================================================================
--- upstream/trunk/src/su.c	2011-06-13 18:26:16 UTC (rev 3345)
+++ upstream/trunk/src/su.c	2011-06-13 18:26:26 UTC (rev 3346)
@@ -93,8 +93,6 @@
 static pid_t pid_child = 0;
 #endif
 
-extern struct passwd pwent;
-
 /*
  * External identifiers
  */
@@ -114,7 +112,7 @@
 static RETSIGTYPE die (int);
 static bool iswheel (const char *);
 #endif				/* !USE_PAM */
-static void check_perms (void);
+static struct passwd * check_perms (void);
 
 #ifndef USE_PAM
 /*
@@ -181,12 +179,12 @@
 	return true;
 }
 
-static void su_failure (const char *tty)
+static void su_failure (const char *tty, bool su_to_root)
 {
 	sulog (tty, false, oldname, name);	/* log failed attempt */
 #ifdef USE_SYSLOG
 	if (getdef_bool ("SYSLOG_SU_ENAB")) {
-		SYSLOG (((0 != pwent.pw_uid) ? LOG_INFO : LOG_NOTICE,
+		SYSLOG ((su_to_root ? LOG_NOTICE : LOG_INFO,
 		         "- %s %s:%s", tty,
 		         ('\0' != oldname[0]) ? oldname : "???",
 		         ('\0' != name[0]) ? name : "???"));
@@ -413,28 +411,18 @@
  *	In case of subsystem login, the user is first authenticated in the
  *	caller's root subsystem, and then in the user's target subsystem.
  */
-static void check_perms (void)
+static struct passwd * check_perms (void)
 {
 	/*
 	 * The password file entries for the user is gotten and the account
 	 * validated.
 	 */
-	pw = xgetpwnam (name);
+	struct passwd *pw = xgetpwnam (name);
 	if (NULL == pw) {
 		(void) fprintf (stderr, _("Unknown id: %s\n"), name);
 		closelog ();
 		exit (1);
 	}
-#ifndef USE_PAM
-	spwd = NULL;
-	if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
-		spwd = getspnam (name); /* !USE_PAM, no need for xgetspnam */
-		if (NULL != spwd) {
-			pw->pw_passwd = spwd->sp_pwdp;
-		}
-	}
-#endif				/* !USE_PAM */
-	pwent = *pw;
 
 #ifndef USE_PAM
 	/*
@@ -456,7 +444,7 @@
 	 */
 
 	if (!amroot) {
-		if (   (0 == pwent.pw_uid)
+		if (   (0 == pw->pw_uid)
 		    && getdef_bool ("SU_WHEEL_ONLY")
 		    && !iswheel (oldname)) {
 			fprintf (stderr,
@@ -465,15 +453,22 @@
 			exit (1);
 		}
 #ifdef SU_ACCESS
-		switch (check_su_auth (oldname, name)) {
+		spwd = getspnam (name); /* !USE_PAM, no need for xgetspnam */
+		if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
+			if (NULL != spwd) {
+				pw->pw_passwd = spwd->sp_pwdp;
+			}
+		}
+
+		switch (check_su_auth (oldname, name, 0 == pw->pw_uid)) {
 		case 0:	/* normal su, require target user's password */
 			break;
 		case 1:	/* require no password */
-			pwent.pw_passwd = "";	/* XXX warning: const */
+			pw->pw_passwd = "";	/* XXX warning: const */
 			break;
 		case 2:	/* require own password */
 			puts (_("(Enter your own password)"));
-			pwent.pw_passwd = oldpass;
+			pw->pw_passwd = oldpass;
 			break;
 		default:	/* access denied (-1) or unexpected value */
 			fprintf (stderr,
@@ -494,7 +489,7 @@
 		         pam_strerror (pamh, ret)));
 		fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
 		(void) pam_end (pamh, ret);
-		su_failure (tty);
+		su_failure (tty, 0 == pw->pw_uid);
 	}
 
 	ret = pam_acct_mgmt (pamh, 0);
@@ -512,7 +507,7 @@
 				         _("%s: %s\n"),
 				         Prog, pam_strerror (pamh, ret));
 				(void) pam_end (pamh, ret);
-				su_failure (tty);
+				su_failure (tty, 0 == pw->pw_uid);
 			}
 		} else {
 			SYSLOG ((LOG_ERR, "pam_acct_mgmt: %s",
@@ -521,7 +516,7 @@
 			         _("%s: %s\n"),
 			         Prog, pam_strerror (pamh, ret));
 			(void) pam_end (pamh, ret);
-			su_failure (tty);
+			su_failure (tty, 0 == pw->pw_uid);
 		}
 	}
 #else				/* !USE_PAM */
@@ -537,11 +532,11 @@
 	 * character.
 	 */
 	if (   !amroot
-	    && (pw_auth (pwent.pw_passwd, name, PW_SU, (char *) 0) != 0)) {
-		SYSLOG (((pwent.pw_uid != 0)? LOG_NOTICE : LOG_WARN,
+	    && (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);
+		su_failure (tty, 0 == pw->pw_uid);
 	}
 	(void) signal (SIGQUIT, oldsig);
 
@@ -551,7 +546,7 @@
 	 * expired password.
 	 */
 	if ((!amroot) && (NULL != spwd)) {
-		(void) expire (&pwent, spwd);
+		(void) expire (pw, spwd);
 	}
 
 	/*
@@ -561,14 +556,14 @@
 	 * the account.
 	 */
 	if (!amroot) {
-		if (!isttytime (pwent.pw_name, "SU", time ((time_t *) 0))) {
-			SYSLOG (((0 != pwent.pw_uid) ? LOG_WARN : LOG_CRIT,
+		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));
 			fprintf (stderr,
 			         _("%s: You are not authorized to su at that time\n"),
 			         Prog);
-			su_failure (tty);
+			su_failure (tty, 0 == pw->pw_uid);
 		}
 	}
 #endif				/* !USE_PAM */
@@ -581,13 +576,14 @@
 	 * the shell specified in /etc/passwd (not the one specified with
 	 * --shell, which will be the one executed in the chroot later).
 	 */
-	if ('*' == pwent.pw_shell[0]) {	/* subsystem root required */
-		subsystem (&pwent);	/* change to the subsystem root */
+	if ('*' == pw->pw_shell[0]) {	/* subsystem root required */
+		subsystem (pw);	/* change to the subsystem root */
 		endpwent ();		/* close the old password databases */
 		endspent ();
 		return check_perms ();	/* authenticate in the subsystem */
 	}
 
+	return pw;
 }
 
 /*
@@ -622,8 +618,6 @@
 	RETSIGTYPE (*oldsig) (int);
 	int is_console = 0;
 
-	struct spwd *spwd = 0;
-
 #ifdef SU_ACCESS
 	char *oldpass;
 #endif
@@ -748,7 +742,7 @@
 			root_pw = getpwuid (0);
 			if (NULL == root_pw) {
 				SYSLOG ((LOG_CRIT, "There is no UID 0 user."));
-				su_failure (tty);
+				su_failure (tty, true);
 			}
 			(void) strcpy (name, root_pw->pw_name);
 		}
@@ -770,7 +764,7 @@
 		         Prog);
 		SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
 		         (unsigned long) my_uid));
-		su_failure (tty);
+		su_failure (tty, true); // FIXME: at this time I do not know the target UID
 	}
 	STRFCPY (oldname, pw->pw_name);
 
@@ -780,9 +774,11 @@
 	 * Sort out the password of user calling su, in case needed later
 	 * -- chris
 	 */
-	spwd = getspnam (oldname); /* !USE_PAM, no need for xgetspnam */
-	if (NULL != spwd) {
-		pw->pw_passwd = spwd->sp_pwdp;
+	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 */
@@ -810,7 +806,7 @@
 	}
 #endif				/* USE_PAM */
 
-	check_perms ();
+	pw = check_perms ();
 
 	/* If the user do not want to change the environment,
 	 * use the current SHELL.
@@ -825,7 +821,7 @@
 	 * must be the one specified in /etc/passwd.
 	 */
 	if (   !amroot
-	    && restricted_shell (pwent.pw_shell)) {
+	    && restricted_shell (pw->pw_shell)) {
 		shellstr = NULL;
 		change_environment = true;
 	}
@@ -834,7 +830,7 @@
 	 * in /etc/passwd.
 	 */
 	if (NULL == shellstr) {
-		shellstr = (char *) strdup (pwent.pw_shell);
+		shellstr = (char *) strdup (pw->pw_shell);
 	}
 
 	/*
@@ -905,9 +901,9 @@
 		}
 	}
 
-	cp = getdef_str ((pwent.pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
+	cp = getdef_str ((pw->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
 	if (NULL == cp) {
-		addenv ((pwent.pw_uid == 0) ? "PATH=/sbin:/bin:/usr/sbin:/usr/bin" : "PATH=/bin:/usr/bin", NULL);
+		addenv ((pw->pw_uid == 0) ? "PATH=/sbin:/bin:/usr/sbin:/usr/bin" : "PATH=/bin:/usr/bin", NULL);
 	} else if (strchr (cp, '=') != NULL) {
 		addenv (cp, NULL);
 	} else {
@@ -931,7 +927,7 @@
 
 #ifdef USE_PAM
 	/* set primary group id and supplementary groups */
-	if (setup_groups (&pwent) != 0) {
+	if (setup_groups (pw) != 0) {
 		pam_end (pamh, PAM_ABORT);
 		exit (1);
 	}
@@ -976,7 +972,7 @@
 	}
 
 	/* become the new user */
-	if (change_uid (&pwent) != 0) {
+	if (change_uid (pw) != 0) {
 		pam_close_session (pamh, 0);
 		pam_setcred (pamh, PAM_DELETE_CRED);
 		(void) pam_end (pamh, PAM_ABORT);
@@ -987,22 +983,22 @@
 
 	/* no limits if su from root (unless su must fake login's behavior) */
 	if (!amroot || fakelogin) {
-		setup_limits (&pwent);
+		setup_limits (pw);
 	}
 
-	if (setup_uid_gid (&pwent, is_console) != 0) {
+	if (setup_uid_gid (pw, is_console) != 0) {
 		exit (1);
 	}
 #endif				/* !USE_PAM */
 
 	if (change_environment) {
 		if (fakelogin) {
-			pwent.pw_shell = shellstr;
-			setup_env (&pwent);
+			pw->pw_shell = shellstr;
+			setup_env (pw);
 		} else {
-			addenv ("HOME", pwent.pw_dir);
-			addenv ("USER", pwent.pw_name);
-			addenv ("LOGNAME", pwent.pw_name);
+			addenv ("HOME", pw->pw_dir);
+			addenv ("USER", pw->pw_name);
+			addenv ("LOGNAME", pw->pw_name);
 			addenv ("SHELL", shellstr);
 		}
 	}

Modified: upstream/trunk/src/suauth.c
===================================================================
--- upstream/trunk/src/suauth.c	2011-06-13 18:26:16 UTC (rev 3345)
+++ upstream/trunk/src/suauth.c	2011-06-13 18:26:26 UTC (rev 3346)
@@ -48,11 +48,6 @@
 #define	DENY		-1
 #define	OWNPWORD	2
 
-/*
- * Global variables
- */
-struct passwd pwent;
-
 #ifdef SU_ACCESS
 
 /* Really, I could do with a few const char's here defining all the 
@@ -65,7 +60,9 @@
 static int lines = 0;
 
 
-int check_su_auth (const char *actual_id, const char *wanted_id)
+int check_su_auth (const char *actual_id,
+                   const char *wanted_id,
+                   bool su_to_root)
 {
 	int posn, endline;
 	const char field[] = ":";
@@ -131,7 +128,7 @@
 		if (!applies (actual_id, from_users))
 			continue;
 		if (!strcmp (action, "DENY")) {
-			SYSLOG ((pwent.pw_uid ? LOG_NOTICE : LOG_WARN,
+			SYSLOG ((su_to_root ? LOG_WARN : LOG_NOTICE,
 				 "DENIED su from '%s' to '%s' (%s)\n",
 				 actual_id, wanted_id, SUAUTHFILE));
 			fputs (_("Access to su to that account DENIED.\n"),
@@ -139,14 +136,14 @@
 			fclose (authfile_fd);
 			return DENY;
 		} else if (!strcmp (action, "NOPASS")) {
-			SYSLOG ((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
+			SYSLOG ((su_to_root ? LOG_NOTICE : LOG_INFO,
 				 "NO password asked for su from '%s' to '%s' (%s)\n",
 				 actual_id, wanted_id, SUAUTHFILE));
 			fputs (_("Password authentication bypassed.\n"),stderr);
 			fclose (authfile_fd);
 			return NOPWORD;
 		} else if (!strcmp (action, "OWNPASS")) {
-			SYSLOG ((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
+			SYSLOG ((su_to_root ? LOG_NOTICE : LOG_INFO,
 				 "su from '%s' to '%s': asking for user's own password (%s)\n",
 				 actual_id, wanted_id, SUAUTHFILE));
 			fputs (_("Please enter your OWN password as authentication.\n"),




More information about the Pkg-shadow-commits mailing list