]> granicus.if.org Git - shadow/blobdiff - src/login.c
* src/su.c: Extract export of environment from main().
[shadow] / src / login.c
index dd8103e6fd6919f53f93baeecccd79e113c6bad6..c24fc860d7cfb4f75b790acefed37c4eeab9d93b 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1989 - 1994, Julianne Frances Haugh
  * Copyright (c) 1996 - 2001, Marek Michałkiewicz
  * Copyright (c) 2001 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2009, Nicolas François
+ * Copyright (c) 2007 - 2010, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,9 @@
 #include "getdef.h"
 #include "prototypes.h"
 #include "pwauth.h"
+/*@-exitarg@*/
 #include "exitcodes.h"
+
 #ifdef USE_PAM
 #include "pam_defs.h"
 
@@ -80,7 +82,7 @@ static pam_handle_t *pamh = NULL;
 /*
  * Global variables
  */
-char *Prog;
+const char *Prog;
 
 static const char *hostname = "";
 static /*@null@*/ /*@only@*/char *username = NULL;
@@ -165,10 +167,10 @@ static void usage (void)
 static void setup_tty (void)
 {
        TERMIO termio;
-       int erasechar;
-       int killchar;
 
        if (GTTY (0, &termio) == 0) {   /* get terminal characteristics */
+               int erasechar;
+               int killchar;
 
                /*
                 * Add your favorite terminal modes here ...
@@ -240,7 +242,6 @@ static void check_nologin (bool login_to_root)
        fname = getdef_str ("NOLOGINS_FILE");
        if ((NULL != fname) && (access (fname, F_OK) == 0)) {
                FILE *nlfp;
-               int c;
 
                /*
                 * Cat the file if it can be opened, otherwise just
@@ -248,6 +249,7 @@ static void check_nologin (bool login_to_root)
                 */
                nlfp = fopen (fname, "r");
                if (NULL != nlfp) {
+                       int c;
                        while ((c = getc (nlfp)) != EOF) {
                                if (c == '\n') {
                                        (void) putchar ('\r');
@@ -525,14 +527,13 @@ int main (int argc, char **argv)
 #endif
        unsigned int delay;
        unsigned int retries;
-       bool failed;
        bool subroot = false;
 #ifndef USE_PAM
        bool is_console;
 #endif
        int err;
        const char *cp;
-       char *tmp;
+       const char *tmp;
        char fromhost[512];
        struct passwd *pwd = NULL;
        char **envp = environ;
@@ -736,7 +737,7 @@ int main (int argc, char **argv)
 #endif
        /* if fflg, then the user has already been authenticated */
        if (!fflg) {
-               int failcount = 0;
+               unsigned int failcount = 0;
                char hostn[256];
                char loginprompt[256];  /* That's one hell of a prompt :) */
 
@@ -746,8 +747,8 @@ int main (int argc, char **argv)
                                  sizeof (loginprompt),
                                  _("%s login: "), hostn);
                } else {
-                       snprintf (loginprompt,
-                                 sizeof (loginprompt), _("login: "));
+                       strncpy (loginprompt, _("login: "),
+                                sizeof (loginprompt));
                }
 
                retcode = pam_set_item (pamh, PAM_USER_PROMPT, loginprompt);
@@ -771,7 +772,7 @@ int main (int argc, char **argv)
                 */
                failcount = 0;
                while (true) {
-                       failed = false;
+                       bool failed = false;
 
                        failcount++;
 #ifdef HAS_PAM_FAIL_DELAY
@@ -788,10 +789,10 @@ int main (int argc, char **argv)
 
                        if (retcode == PAM_MAXTRIES) {
                                SYSLOG ((LOG_NOTICE,
-                                        "TOO MANY LOGIN TRIES (%d)%s FOR '%s'",
+                                        "TOO MANY LOGIN TRIES (%u)%s FOR '%s'",
                                         failcount, fromhost, failent_user));
                                fprintf(stderr,
-                                       _("Maximum number of tries exceeded (%d)\n"),
+                                       _("Maximum number of tries exceeded (%u)\n"),
                                        failcount);
                                PAM_END;
                                exit(0);
@@ -802,7 +803,7 @@ int main (int argc, char **argv)
                                PAM_END;
                                exit(99);
                        } else if (retcode != PAM_SUCCESS) {
-                               SYSLOG ((LOG_NOTICE,"FAILED LOGIN (%d)%s FOR '%s', %s",
+                               SYSLOG ((LOG_NOTICE,"FAILED LOGIN (%u)%s FOR '%s', %s",
                                         failcount, fromhost, failent_user,
                                         pam_strerror (pamh, retcode)));
                                failed = true;
@@ -827,14 +828,15 @@ int main (int argc, char **argv)
                        close (audit_fd);
 #endif                         /* WITH_AUDIT */
 
-                       fprintf (stderr, "\nLogin incorrect\n");
+                       (void) puts ("");
+                       (void) puts (_("Login incorrect"));
 
                        if (failcount >= retries) {
                                SYSLOG ((LOG_NOTICE,
-                                        "TOO MANY LOGIN TRIES (%d)%s FOR '%s'",
+                                        "TOO MANY LOGIN TRIES (%u)%s FOR '%s'",
                                         failcount, fromhost, failent_user));
                                fprintf(stderr,
-                                       _("Maximum number of tries exceeded (%d)\n"),
+                                       _("Maximum number of tries exceeded (%u)\n"),
                                        failcount);
                                PAM_END;
                                exit(0);
@@ -900,6 +902,7 @@ int main (int argc, char **argv)
 
 #else                          /* ! USE_PAM */
        while (true) {  /* repeatedly get login/password pairs */
+               bool failed;
                /* user_passwd is always a pointer to this constant string
                 * or a passwd or shadow password that will be memzero by
                 * pw_free / spw_free.
@@ -910,6 +913,7 @@ int main (int argc, char **argv)
                 * anymore. */
                if (NULL != pwd) {
                        pw_free (pwd);
+                       pwd = NULL;
                }
                if (NULL != spwd) {
                        spw_free (spwd);
@@ -1108,8 +1112,6 @@ int main (int argc, char **argv)
                addenv ("IFS= \t\n", NULL);     /* ... instead, set a safe IFS */
        }
 
-       update_utmp (username, tty, hostname, utent);
-
        if (pwd->pw_shell[0] == '*') {  /* subsystem root */
                pwd->pw_shell++;        /* skip the '*' */
                subsystem (pwd);        /* figure out what to execute */
@@ -1197,6 +1199,7 @@ int main (int argc, char **argv)
        }
        /* child */
 #endif
+
        /* If we were init, we need to start a new session */
        if (getppid() == 1) {
                setsid();
@@ -1205,6 +1208,11 @@ int main (int argc, char **argv)
                }
        }
 
+       /*
+        * The utmp entry needs to be updated to indicate the new status
+        * of the session, the new PID and SID.
+        */
+       update_utmp (username, tty, hostname, utent);
 
        /* The pwd and spwd entries for the user have been copied.
         *
@@ -1319,8 +1327,7 @@ int main (int argc, char **argv)
                /* exec the shell finally */
                err = shell (pwd->pw_shell, (char *) 0, newenvp);
        }
-       exit (err == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
-       /* NOT REACHED */
-       return 0;
+
+       return ((err == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
 }