[Pkg-shadow-commits] r2727 - in upstream/trunk: . src
Nicolas FRANÇOIS
nekral-guest at alioth.debian.org
Mon Apr 20 13:29:15 UTC 2009
Author: nekral-guest
Date: 2009-04-20 13:29:15 +0000 (Mon, 20 Apr 2009)
New Revision: 2727
Modified:
upstream/trunk/ChangeLog
upstream/trunk/src/login.c
Log:
* src/login.c: Get rid of pwent. pwd is sufficient as long as it
is always coming from xgetpwnam. There is no need to copy pwd to
pwent, this was not a good idea anyway as the strings from pwd
were not duplicated.
* src/login.c: Always free the pwd and spwd structure when we
retrieve a new one. This will clear the password of the previous
user from the memory.
* src/login.c: user_passwd is used to keep point to the password
of the user being authenticated.
* src/login.c: (non PAM) Fail if the user's entry cannot be found
after the user updated her password (if expire() requested an
update).
* src/login.c: If the user does not exist on the system, there is
no need to build a pwd structure (with shell).
Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog 2009-04-20 13:12:09 UTC (rev 2726)
+++ upstream/trunk/ChangeLog 2009-04-20 13:29:15 UTC (rev 2727)
@@ -1,5 +1,22 @@
2009-04-20 Nicolas François <nicolas.francois at centraliens.net>
+ * src/login.c: Get rid of pwent. pwd is sufficient as long as it
+ is always coming from xgetpwnam. There is no need to copy pwd to
+ pwent, this was not a good idea anyway as the strings from pwd
+ were not duplicated.
+ * src/login.c: Always free the pwd and spwd structure when we
+ retrieve a new one. This will clear the password of the previous
+ user from the memory.
+ * src/login.c: user_passwd is used to keep point to the password
+ of the user being authenticated.
+ * src/login.c: (non PAM) Fail if the user's entry cannot be found
+ after the user updated her password (if expire() requested an
+ update).
+ * src/login.c: If the user does not exist on the system, there is
+ no need to build a pwd structure (with shell).
+
+2009-04-20 Nicolas François <nicolas.francois at centraliens.net>
+
* src/login.c: ttytype already checks for TTYTYPE_FILE and TERM.
Just call ttytype.
Modified: upstream/trunk/src/login.c
===================================================================
--- upstream/trunk/src/login.c 2009-04-20 13:12:09 UTC (rev 2726)
+++ upstream/trunk/src/login.c 2009-04-20 13:29:15 UTC (rev 2727)
@@ -85,8 +85,6 @@
static char *username = NULL;
static int reason = PW_LOGIN;
-static struct passwd pwent;
-
#if HAVE_UTMPX_H
extern struct utmpx utxent;
struct utmpx failent;
@@ -490,10 +488,9 @@
const char *cp;
char *tmp;
char fromhost[512];
- struct passwd *pwd;
+ struct passwd *pwd = NULL;
char **envp = environ;
#ifndef USE_PAM
- static char temp_pw[2];
static char temp_shell[] = "/bin/sh";
#endif
const char *failent_user;
@@ -881,8 +878,6 @@
exit (1);
}
- pwent = *pwd;
-
retcode = pam_setcred (pamh, PAM_ESTABLISH_CRED);
PAM_FAIL_CHECK;
/* NOTE: If pam_setcred changes PAM_USER, this will not be taken
@@ -891,6 +886,22 @@
#else /* ! USE_PAM */
while (true) { /* repeatedly get login/password pairs */
+ /* user_passwd is always a pointer to this constant string
+ * or a passwd or shadow password that will be memzero by
+ * passwd_free / shadow_free.
+ * Do not free() user_passwd. */
+ const char *user_passwd = "!";
+
+ /* Do some cleanup to avoid keeping entries we do not need
+ * anymore. */
+ if (NULL != pwd) {
+ passwd_free (pwd);
+ }
+ if (NULL != spwd) {
+ shadow_free (spwd);
+ spwd = NULL;
+ }
+
failed = false; /* haven't failed authentication yet */
if (NULL == username) { /* need to get a login id */
if (subroot) {
@@ -913,25 +924,31 @@
pwd = xgetpwnam (username);
if (NULL == pwd) {
- pwent.pw_name = username;
- strcpy (temp_pw, "!");
- pwent.pw_passwd = temp_pw;
- pwent.pw_shell = temp_shell;
-
preauth_flag = false;
failed = true;
} else {
- pwent = *pwd;
+ user_passwd = pwd->pw_passwd;
+ /*
+ * If the encrypted password begins with a "!",
+ * the account is locked and the user cannot
+ * login, even if they have been
+ * "pre-authenticated."
+ */
+ if ( ('!' == user_passwd[0])
+ || ('*' == user_passwd[0])) {
+ failed = true;
+ }
}
- spwd = NULL;
- if ( (NULL != pwd)
- && (strcmp (pwd->pw_passwd, SHADOW_PASSWD_STRING) == 0)) {
- /* !USE_PAM, no need for xgetspnam */
- spwd = getspnam (username);
+ if (strcmp (user_passwd, SHADOW_PASSWD_STRING) == 0) {
+ spwd = xgetspnam (username);
if (NULL != spwd) {
- pwent.pw_passwd = spwd->sp_pwdp;
+ user_passwd = spwd->sp_pwdp;
} else {
+ /* The user exists in passwd, but not in
+ * shadow. SHADOW_PASSWD_STRING indicates
+ * that the password shall be in shadow.
+ */
SYSLOG ((LOG_WARN,
"no shadow password for '%s'%s",
username, fromhost));
@@ -939,16 +956,6 @@
}
/*
- * If the encrypted password begins with a "!", the account
- * is locked and the user cannot login, even if they have
- * been "pre-authenticated."
- */
- if ( ('!' == pwent.pw_passwd[0])
- || ('*' == pwent.pw_passwd[0])) {
- failed = true;
- }
-
- /*
* The -r and -f flags provide a name which has already
* been authenticated by some server.
*/
@@ -956,8 +963,7 @@
goto auth_ok;
}
- if (pw_auth (pwent.pw_passwd, username,
- reason, (char *) 0) == 0) {
+ if (pw_auth (user_passwd, username, reason, (char *) 0) == 0) {
goto auth_ok;
}
@@ -972,8 +978,8 @@
* authenticated and so on.
*/
if ( !failed
- && (NULL != pwent.pw_name)
- && (0 == pwent.pw_uid)
+ && (NULL != pwd)
+ && (0 == pwd->pw_uid)
&& !is_console) {
SYSLOG ((LOG_CRIT, "ILLEGAL ROOT LOGIN %s", fromhost));
failed = true;
@@ -986,7 +992,7 @@
}
if ( (NULL != pwd)
&& getdef_bool ("FAILLOG_ENAB")
- && !failcheck (pwent.pw_uid, &faillog, failed)) {
+ && !failcheck (pwd->pw_uid, &faillog, failed)) {
SYSLOG ((LOG_CRIT,
"exceeded failure limit for '%s' %s",
username, fromhost));
@@ -998,7 +1004,7 @@
/* don't log non-existent users */
if ((NULL != pwd) && getdef_bool ("FAILLOG_ENAB")) {
- failure (pwent.pw_uid, tty, &faillog);
+ failure (pwd->pw_uid, tty, &faillog);
}
if (getdef_str ("FTMP_FILE") != NULL) {
#if HAVE_UTMPX_H
@@ -1036,7 +1042,7 @@
* guys won't see that the passwordless account exists at
* all). --marekm
*/
- if (pwent.pw_passwd[0] == '\0') {
+ if (user_passwd[0] == '\0') {
pw_auth ("!", username, reason, (char *) 0);
}
@@ -1075,7 +1081,7 @@
* by Ivan Nejgebauer <ian at unsux.ns.ac.yu>. --marekm
*/
if ( getdef_bool ("PORTTIME_CHECKS_ENAB")
- && !isttytime (pwent.pw_name, tty, time ((time_t *) 0))) {
+ && !isttytime (username, tty, time ((time_t *) 0))) {
SYSLOG ((LOG_WARN, "invalid login time for '%s'%s",
username, fromhost));
closelog ();
@@ -1083,7 +1089,7 @@
exit (1);
}
- check_nologin (pwent.pw_uid == 0);
+ check_nologin (pwd->pw_uid == 0);
#endif
if (getenv ("IFS")) { /* don't export user IFS ... */
@@ -1091,9 +1097,9 @@
}
setutmp (username, tty, hostname); /* make entry in utmp & wtmp files */
- if (pwent.pw_shell[0] == '*') { /* subsystem root */
- pwent.pw_shell++; /* skip the '*' */
- subsystem (&pwent); /* figure out what to execute */
+ if (pwd->pw_shell[0] == '*') { /* subsystem root */
+ pwd->pw_shell++; /* skip the '*' */
+ subsystem (pwd); /* figure out what to execute */
subroot = true; /* say I was here again */
endpwent (); /* close all of the file which were */
endgrent (); /* open in the original rooted file */
@@ -1110,7 +1116,7 @@
AUDIT_USER_LOGIN,
NULL, /* Prog. name */
"login",
- pwd->pw_name,
+ username,
AUDIT_NO_ID,
hostname,
NULL, /* addr */
@@ -1121,31 +1127,38 @@
#ifndef USE_PAM /* pam_lastlog handles this */
if (getdef_bool ("LASTLOG_ENAB")) { /* give last login and log this one */
- dolastlog (&lastlog, &pwent, tty, hostname);
+ dolastlog (&lastlog, pwd, tty, hostname);
}
#endif
#ifndef USE_PAM /* PAM handles this as well */
/*
* Have to do this while we still have root privileges, otherwise we
- * don't have access to /etc/shadow. expire() closes password files,
- * and changes to the user in the child before executing the passwd
- * program. --marekm
+ * don't have access to /etc/shadow.
*/
- if (spwd) { /* check for age of password */
- if (expire (&pwent, spwd)) {
- /* !USE_PAM, no need for xgetpwnam */
- pwd = getpwnam (username);
- /* !USE_PAM, no need for xgetspnam */
- spwd = getspnam (username);
- if (pwd) {
- pwent = *pwd;
+ if (NULL != spwd) { /* check for age of password */
+ if (expire (pwd, spwd)) {
+ /* The user updated her password, get the new
+ * entries.
+ * Use the x variants because we need to keep the
+ * entry for a long time, and there might be other
+ * getxxyy in between.
+ */
+ passwd_free (pwd);
+ pwd = xgetpwnam (username);
+ if (NULL == pwd) {
+ SYSLOG ((LOG_ERR,
+ "cannot find user %s after update of expired password",
+ username));
+ exit (1);
}
+ shadow_free (spwd);
+ spwd = xgetspnam (username);
}
}
- setup_limits (&pwent); /* nice, ulimit etc. */
+ setup_limits (pwd); /* nice, ulimit etc. */
#endif /* ! USE_PAM */
- chown_tty (&pwent);
+ chown_tty (pwd);
#ifdef USE_PAM
/*
@@ -1180,7 +1193,8 @@
}
- /*
+ /* The pwd and spwd entries for the user have been copied.
+ *
* Close all the files so that unauthorized access won't occur.
*/
endpwent (); /* stop access to password file */
@@ -1192,18 +1206,18 @@
/* Drop root privileges */
#ifndef USE_PAM
- if (setup_uid_gid (&pwent, is_console))
+ if (setup_uid_gid (pwd, is_console))
#else
/* The group privileges were already dropped.
* See setup_groups() above.
*/
- if (change_uid (&pwent))
+ if (change_uid (pwd))
#endif
{
exit (1);
}
- setup_env (&pwent); /* set env vars, cd to the home dir */
+ setup_env (pwd); /* set env vars, cd to the home dir */
#ifdef USE_PAM
{
@@ -1280,7 +1294,7 @@
(void) signal (SIGHUP, SIG_DFL); /* added this. --marekm */
(void) signal (SIGINT, SIG_DFL); /* default interrupt signal */
- if (0 == pwent.pw_uid) {
+ if (0 == pwd->pw_uid) {
SYSLOG ((LOG_NOTICE, "ROOT LOGIN %s", fromhost));
} else if (getdef_bool ("LOG_OK_LOGINS")) {
SYSLOG ((LOG_INFO, "'%s' logged in %s", username, fromhost));
@@ -1288,10 +1302,10 @@
closelog ();
tmp = getdef_str ("FAKE_SHELL");
if (NULL != tmp) {
- err = shell (tmp, pwent.pw_shell, newenvp); /* fake shell */
+ err = shell (tmp, pwd->pw_shell, newenvp); /* fake shell */
} else {
/* exec the shell finally */
- err = shell (pwent.pw_shell, (char *) 0, newenvp);
+ err = shell (pwd->pw_shell, (char *) 0, newenvp);
}
exit (err == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
/* NOT REACHED */
More information about the Pkg-shadow-commits
mailing list