#include <sys/socket.h>
#include <sys/stat.h>
-#include <utmp.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
* another value on error.
*/
extern int get_session_host (char **out);
-extern /*@null@*/struct utmp *get_current_utmp (void);
-extern struct utmp *prepare_utmp (const char *name,
- const char *line,
- const char *host,
- /*@null@*/const struct utmp *ut);
-/*
- * failtmp - update the cumulative failure log
- *
- * failtmp updates the (struct utmp) formatted failure log which
- * maintains a record of all login failures.
- */
-extern void failtmp (const char *username, const struct utmp *);
+#ifndef ENABLE_LOGIND
/**
* @brief Update or create an utmp entry in utmp, wtmp, utmpw, or wtmpx
*
* @param[in] user username
* @param[in] tty tty
* @param[in] host hostname
- * @param[in] utent utmp entry
+ *
+ * @return 0 if utmp was updated properly,
+ * 1 on error.
+ */
+extern int update_utmp (const char *user,
+ const char *tty,
+ const char *host);
+/**
+ * @brief Update the cumulative failure log
+ *
+ * @param[in] failent_user username
+ * @param[in] tty tty
+ * @param[in] host hostname
+ *
*/
-extern void update_utmp (const char *user,
- const char *tty,
- const char *host,
- /*@null@*/const struct utmp *utent);
+extern void record_failure(const char *failent_user,
+ const char *tty,
+ const char *hostname);
+#endif /* ENABLE_LOGIND */
/* valid.c */
extern bool valid (const char *, const struct passwd *);
* failtmp updates the (struct utmp) formatted failure log which
* maintains a record of all login failures.
*/
-void failtmp (const char *username, const struct utmp *failent)
+static void failtmp (const char *username, const struct utmp *failent)
{
const char *ftmp;
int fd;
*
* Return NULL if no entries exist in utmp for the current process.
*/
+static
/*@null@*/ /*@only@*/struct utmp *get_current_utmp (void)
{
struct utmp *ut;
*
* The returned structure shall be freed by the caller.
*/
+static
/*@only@*/struct utmp *prepare_utmp (const char *name,
const char *line,
const char *host,
return err;
}
-void update_utmp (const char *user,
- const char *tty,
- const char *host,
- /*@null@*/const struct utmp *utent)
+int update_utmp (const char *user,
+ const char *tty,
+ const char *host)
{
- struct utmp *ut = prepare_utmp (user, tty, host, utent);
+ struct utmp *utent, *ut;
+
+ utent = get_current_utmp ();
+ if (utent == NULL) {
+ return -1;
+ }
+
+ ut = prepare_utmp (user, tty, host, utent);
(void) setutmp (ut); /* make entry in the utmp & wtmp files */
+ free (utent);
free (ut);
+
+ return 1;
+}
+
+void record_failure(const char *failent_user,
+ const char *tty,
+ const char *hostname)
+{
+ struct utmp *utent, *failent;
+
+ if (getdef_str ("FTMP_FILE") != NULL) {
+ utent = get_current_utmp ();
+ failent = prepare_utmp (failent_user, tty, hostname, utent);
+ failtmp (failent_user, failent);
+ free (utent);
+ free (failent);
+ }
}
struct passwd *pwd = NULL;
char **envp = environ;
const char *failent_user;
- /*@null@*/struct utmp *utent;
+ char *host = NULL;
#ifdef USE_PAM
int retcode;
exit (1); /* must be a terminal */
}
- utent = get_current_utmp ();
+ err = get_session_host(&host);
/*
* Be picky if run by normal users (possible if installed setuid
- * root), but not if run by root. This way it still allows logins
- * even if your getty is broken, or if something corrupts utmp,
- * but users must "exec login" which will use the existing utmp
- * entry (will not overwrite remote hostname). --marekm
+ * root), but not if run by root.
*/
- if (!amroot && (NULL == utent)) {
- (void) puts (_("No utmp entry. You must exec \"login\" from the lowest level \"sh\""));
+ if (!amroot && (err != 0)) {
+ SYSLOG ((LOG_ERR,
+ "No session entry, error %d. You must exec \"login\" from the lowest level \"sh\"",
+ err));
exit (1);
}
- /* NOTE: utent might be NULL afterwards */
tmptty = ttyname (0);
if (NULL == tmptty) {
if (rflg || hflg) {
cp = hostname;
-#if defined(HAVE_STRUCT_UTMP_UT_HOST)
- } else if ((NULL != utent) && ('\0' != utent->ut_host[0])) {
- cp = utent->ut_host;
-#endif /* HAVE_STRUCT_UTMP_UT_HOST */
+ } else if ((host != NULL) && (host[0] != '\0')) {
+ cp = host;
} else {
cp = "";
}
snprintf (fromhost, sizeof fromhost,
" on '%.100s'", tty);
}
+ free(host);
top:
/* only allow ALARM sec. for login */
if ((NULL != pwd) && getdef_bool ("FAILLOG_ENAB")) {
failure (pwd->pw_uid, tty, &faillog);
}
- if (getdef_str ("FTMP_FILE") != NULL) {
- struct utmp *failent =
- prepare_utmp (failent_user,
- tty,
- hostname,
- utent);
- failtmp (failent_user, failent);
- free (failent);
- }
+#ifndef ENABLE_LOGIND
+ record_failure(failent_user, tty, hostname);
+#endif /* ENABLE_LOGIND */
retries--;
if (retries <= 0) {
}
}
+#ifndef ENABLE_LOGIND
/*
* 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);
+ err = update_utmp (username, tty, hostname);
+ if (err != 0) {
+ SYSLOG ((LOG_WARN, "Unable to update utmp entry for %s", username));
+ }
+#endif /* ENABLE_LOGIND */
/* The pwd and spwd entries for the user have been copied.
*