]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
Support systems that only have utmpx 118/head
authorA. Wilcox <AWilcox@Wilcox-Tech.com>
Sun, 24 Jun 2018 05:13:12 +0000 (00:13 -0500)
committerA. Wilcox <AWilcox@Wilcox-Tech.com>
Sun, 24 Jun 2018 05:13:12 +0000 (00:13 -0500)
This allows shadow-utils to build on systems like Adélie, which have no
<utmp.h> header or `struct utmp`.  We use a <utmpx.h>-based daemon,
utmps[1], which uses `struct utmpx` only.

Tested both `login` and `logoutd` with utmps and both work correctly.

[1]: http://skarnet.org/software/utmps/

configure.ac
lib/prototypes.h
libmisc/utmp.c
src/login.c

index 41068a5d5b0555702d7e54f744a7630110d7e1a9..6bc88cfd63d1e8bb9968fe818dfc6001886779df 100644 (file)
@@ -74,12 +74,6 @@ AC_CHECK_MEMBERS([struct utmp.ut_type,
                   struct utmp.ut_time,
                   struct utmp.ut_xtime,
                   struct utmp.ut_tv],,,[[#include <utmp.h>]])
-dnl There are dependencies:
-dnl If UTMPX has to be used, the utmp structure shall have a ut_id field.
-if test "$ac_cv_header_utmpx_h" = "yes" &&
-   test "$ac_cv_member_struct_utmp_ut_id" != "yes"; then
-       AC_MSG_ERROR(Systems with UTMPX and no ut_id field in the utmp structure are not supported)
-fi
 
 AC_CHECK_MEMBERS([struct utmpx.ut_name,
                   struct utmpx.ut_host,
index b7d4888176671c929df5c2b1ba8bc3bdc66d5ce6..d9e7f6f4c4929ce4260eb34b961420d45f1e7c96 100644 (file)
@@ -416,17 +416,19 @@ extern int set_filesize_limit (int blocks);
 extern int user_busy (const char *name, uid_t uid);
 
 /* utmp.c */
+#ifndef USE_UTMPX
 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);
 extern int setutmp (struct utmp *ut);
-#ifdef USE_UTMPX
+#else
+extern /*@null@*/struct utmpx *get_current_utmp (void);
 extern struct utmpx *prepare_utmpx (const char *name,
                                     const char *line,
                                     const char *host,
-                                    /*@null@*/const struct utmp *ut);
+                                    /*@null@*/const struct utmpx *ut);
 extern int setutmpx (struct utmpx *utx);
 #endif                         /* USE_UTMPX */
 
index f5614a220c142d98ce4af50966e9bf38f1dd2104..ba69cf61fdb41163c0a09909811b9255adeedce9 100644 (file)
 #include "defines.h"
 #include "prototypes.h"
 
-#include <utmp.h>
-
 #ifdef USE_UTMPX
 #include <utmpx.h>
+#else
+#include <utmp.h>
 #endif
 
 #include <assert.h>
@@ -97,6 +97,7 @@ static bool is_my_tty (const char *tty)
  *
  *     Return NULL if no entries exist in utmp for the current process.
  */
+#ifndef USE_UTMPX
 /*@null@*/ /*@only@*/struct utmp *get_current_utmp (void)
 {
        struct utmp *ut;
@@ -130,6 +131,36 @@ static bool is_my_tty (const char *tty)
 
        return ret;
 }
+#else
+/*@null@*/ /*@only*/struct utmpx *get_current_utmp(void)
+{
+       struct utmpx *ut;
+       struct utmpx *ret = NULL;
+
+       setutxent ();
+
+       /* Find the utmpx entry for this PID. */
+       while ((ut = getutxent ()) != NULL) {
+               if (   (ut->ut_pid == getpid ())
+                   && ('\0' != ut->ut_id[0])
+                   && (   (LOGIN_PROCESS == ut->ut_type)
+                       || (USER_PROCESS == ut->ut_type))
+                   && is_my_tty (ut->ut_line)) {
+                       break;
+               }
+       }
+
+       if (NULL != ut) {
+               ret = (struct utmpx *) xmalloc (sizeof (*ret));
+               memcpy (ret, ut, sizeof (*ret));
+       }
+
+       endutxent ();
+
+       return ret;
+}
+#endif
+
 
 #ifndef USE_PAM
 /*
@@ -166,6 +197,7 @@ static void updwtmpx (const char *filename, const struct utmpx *utx)
 #endif                         /* ! USE_PAM */
 
 
+#ifndef USE_UTMPX
 /*
  * prepare_utmp - prepare an utmp entry so that it can be logged in a
  *                utmp/wtmp file.
@@ -325,14 +357,14 @@ int setutmp (struct utmp *ut)
        return err;
 }
 
-#ifdef USE_UTMPX
+#else
 /*
  * prepare_utmpx - the UTMPX version for prepare_utmp
  */
 /*@only@*/struct utmpx *prepare_utmpx (const char *name,
                                        const char *line,
                                        const char *host,
-                                       /*@null@*/const struct utmp *ut)
+                                       /*@null@*/const struct utmpx *ut)
 {
        struct timeval tv;
        char *hostname = NULL;
@@ -398,7 +430,7 @@ int setutmp (struct utmp *ut)
                                struct sockaddr_in *sa =
                                        (struct sockaddr_in *) info->ai_addr;
 #ifdef HAVE_STRUCT_UTMPX_UT_ADDR
-                               memcpy (utxent->ut_addr,
+                               memcpy (&utxent->ut_addr,
                                        &(sa->sin_addr),
                                        MIN (sizeof (utxent->ut_addr),
                                             sizeof (sa->sin_addr)));
index e287cb0b5a57f047c3405d3cedaaa353a3620b8c..7677adf1651a752831139a69881b430b1f9a1db3 100644 (file)
@@ -129,7 +129,12 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
 static void update_utmp (const char *user,
                          const char *tty,
                          const char *host,
-                         /*@null@*/const struct utmp *utent);
+#ifdef USE_UTMPX
+                         /*@null@*/const struct utmpx *utent
+#else
+                         /*@null@*/const struct utmp *utent
+#endif
+                       );
 
 #ifndef USE_PAM
 static struct faillog faillog;
@@ -481,17 +486,23 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
 static void update_utmp (const char *user,
                          const char *tty,
                          const char *host,
-                         /*@null@*/const struct utmp *utent)
+#ifdef USE_UTMPX
+                         /*@null@*/const struct utmpx *utent
+#else
+                         /*@null@*/const struct utmp *utent
+#endif
+                        )
 {
-       struct utmp  *ut  = prepare_utmp  (user, tty, host, utent);
 #ifdef USE_UTMPX
        struct utmpx *utx = prepare_utmpx (user, tty, host, utent);
+#else
+       struct utmp  *ut  = prepare_utmp  (user, tty, host, utent);
 #endif                         /* USE_UTMPX */
 
+#ifndef USE_UTMPX
        (void) setutmp  (ut);   /* make entry in the utmp & wtmp files */
        free (ut);
-
-#ifdef USE_UTMPX
+#else
        (void) setutmpx (utx);  /* make entry in the utmpx & wtmpx files */
        free (utx);
 #endif                         /* USE_UTMPX */
@@ -539,7 +550,11 @@ int main (int argc, char **argv)
        struct passwd *pwd = NULL;
        char **envp = environ;
        const char *failent_user;
+#ifdef USE_UTMPX
+       /*@null@*/struct utmpx *utent;
+#else
        /*@null@*/struct utmp *utent;
+#endif
 
 #ifdef USE_PAM
        int retcode;
@@ -681,7 +696,7 @@ int main (int argc, char **argv)
 
        if (rflg || hflg) {
                cp = hostname;
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
+#if defined(HAVE_STRUCT_UTMP_UT_HOST) || defined(USE_UTMPX)
        } else if ((NULL != utent) && ('\0' != utent->ut_host[0])) {
                cp = utent->ut_host;
 #endif                         /* HAVE_STRUCT_UTMP_UT_HOST */