* 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
#include "getdef.h"
#include "prototypes.h"
#include "pwauth.h"
+/*@-exitarg@*/
#include "exitcodes.h"
+
#ifdef USE_PAM
#include "pam_defs.h"
/*
* Global variables
*/
-char *Prog;
+const char *Prog;
static const char *hostname = "";
static /*@null@*/ /*@only@*/char *username = NULL;
static void setup_tty (void);
static void process_flags (int argc, char *const *argv);
static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *user);
-static void update_utmp (const char *username,
+static void update_utmp (const char *user,
const char *tty,
- const char *hostname,
+ const char *host,
/*@null@*/const struct utmp *utent);
#ifndef USE_PAM
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 ...
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
*/
nlfp = fopen (fname, "r");
if (NULL != nlfp) {
+ int c;
while ((c = getc (nlfp)) != EOF) {
if (c == '\n') {
(void) putchar ('\r');
* utent should be the utmp entry returned by get_current_utmp (or
* NULL).
*/
-static void update_utmp (const char *username,
+static void update_utmp (const char *user,
const char *tty,
- const char *hostname,
+ const char *host,
/*@null@*/const struct utmp *utent)
{
- struct utmp *ut = prepare_utmp (username, tty, hostname, utent);
-#ifdef HAVE_UTMPX_H
- struct utmpx *utx = prepare_utmpx (username, tty, hostname, utent);
-#endif /* HAVE_UTMPX_H */
+ struct utmp *ut = prepare_utmp (user, tty, host, utent);
+#ifdef USE_UTMPX
+ struct utmpx *utx = prepare_utmpx (user, tty, host, utent);
+#endif /* USE_UTMPX */
(void) setutmp (ut); /* make entry in the utmp & wtmp files */
free (ut);
-#ifdef HAVE_UTMPX_H
+#ifdef USE_UTMPX
(void) setutmpx (utx); /* make entry in the utmpx & wtmpx files */
free (utx);
-#endif /* HAVE_UTMPX_H */
+#endif /* USE_UTMPX */
}
/*
#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;
#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 :) */
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);
*/
failcount = 0;
while (true) {
- failed = false;
+ bool failed = false;
failcount++;
#ifdef HAS_PAM_FAIL_DELAY
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);
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;
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);
#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.
* anymore. */
if (NULL != pwd) {
pw_free (pwd);
+ pwd = NULL;
}
if (NULL != spwd) {
spw_free (spwd);
failure (pwd->pw_uid, tty, &faillog);
}
if (getdef_str ("FTMP_FILE") != NULL) {
-#ifdef HAVE_UTMPX_H
+#ifdef USE_UTMPX
struct utmpx *failent =
prepare_utmpx (failent_user,
tty,
/* FIXME: or fromhost? */hostname,
utent);
-#else
+#else /* !USE_UTMPX */
struct utmp *failent =
prepare_utmp (failent_user,
tty,
hostname,
utent);
-#endif
+#endif /* !USE_UTMPX */
failtmp (failent_user, failent);
free (failent);
}
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 */
}
/* child */
#endif
+
/* If we were init, we need to start a new session */
if (getppid() == 1) {
setsid();
}
}
+ /*
+ * 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.
*
/* 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);
}