From: Iker Pedrosa Date: Wed, 19 Jul 2023 07:42:35 +0000 (+0200) Subject: utmp: update `update_utmp()` X-Git-Tag: 4.14.0-rc1~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f368e1c1838de9d476a36897d7c53394569de08;p=thirdparty%2Fshadow.git utmp: update `update_utmp()` Remove `utmp` structure as an argument and include its logic inside the function. This will help remove any reference to utmp from login. Signed-off-by: Iker Pedrosa --- diff --git a/lib/prototypes.h b/lib/prototypes.h index d288a038b..bb3b9391c 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -485,30 +484,32 @@ extern int user_busy (const char *name, uid_t uid); * 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 *); diff --git a/libmisc/utmp.c b/libmisc/utmp.c index 4ffaedc53..0a86b18e3 100644 --- a/libmisc/utmp.c +++ b/libmisc/utmp.c @@ -61,7 +61,7 @@ static bool is_my_tty (const char tty[UT_LINESIZE]) * 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; @@ -120,6 +120,7 @@ void failtmp (const char *username, const struct utmp *failent) * * Return NULL if no entries exist in utmp for the current process. */ +static /*@null@*/ /*@only@*/struct utmp *get_current_utmp (void) { struct utmp *ut; @@ -220,6 +221,7 @@ static void updwtmp (const char *filename, const 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, @@ -359,13 +361,37 @@ static int setutmp (struct utmp *ut) 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); + } } diff --git a/src/login.c b/src/login.c index 749747b26..22deddd9a 100644 --- a/src/login.c +++ b/src/login.c @@ -498,7 +498,7 @@ int main (int argc, char **argv) struct passwd *pwd = NULL; char **envp = environ; const char *failent_user; - /*@null@*/struct utmp *utent; + char *host = NULL; #ifdef USE_PAM int retcode; @@ -535,19 +535,17 @@ int main (int argc, char **argv) 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) { @@ -642,10 +640,8 @@ int main (int argc, char **argv) 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 = ""; } @@ -657,6 +653,7 @@ int main (int argc, char **argv) snprintf (fromhost, sizeof fromhost, " on '%.100s'", tty); } + free(host); top: /* only allow ALARM sec. for login */ @@ -1004,15 +1001,9 @@ int main (int argc, char **argv) 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) { @@ -1183,11 +1174,16 @@ int main (int argc, char **argv) } } +#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. *