]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
utmp: update `update_utmp()`
authorIker Pedrosa <ipedrosa@redhat.com>
Wed, 19 Jul 2023 07:42:35 +0000 (09:42 +0200)
committerSerge Hallyn <serge@hallyn.com>
Wed, 2 Aug 2023 15:13:28 +0000 (10:13 -0500)
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 <ipedrosa@redhat.com>
lib/prototypes.h
libmisc/utmp.c
src/login.c

index d288a038b79ec7600421c0795b2907e5822b2437..bb3b9391cf342b33613de3a4b8617e2dacf5a9ee 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <sys/socket.h>
 #include <sys/stat.h>
-#include <utmp.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
@@ -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 *);
index 4ffaedc5332ffb3d11463fb58ae61697da89798e..0a86b18e3db1ea233ca18c5eae59b6ceaa40c278 100644 (file)
@@ -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);
+       }
 }
index 749747b267e3f57fb4826a073bf697d44efafd65..22deddd9aa2a8e549e152159eb77f9b1e104fe9f 100644 (file)
@@ -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.
         *