Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Jan 2011 01:20:24 +0300
From:      Eygene Ryabinkin <rea@freebsd.org>
To:        Ben Kibbey <bjk@luxsci.net>
Cc:        ports@FreeBSD.org
Subject:   Re: FreeBSD Port: sysutils/userinfo
Message-ID:  <m%2Bt893bNDW3fqmhN1J7EbghUmjQ@5UW8B3LwPEGInFShts5A7R/S2Yo>
In-Reply-To: <201101091555.p09Ft22H023380@rs49.luxsci.com>
References:  <201101091555.p09Ft22H023380@rs49.luxsci.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--/e2eDi0V/xtL+Mc8
Content-Type: multipart/mixed; boundary="neYutvxvOLaeuPCA"
Content-Disposition: inline


--neYutvxvOLaeuPCA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Ben, good day.

Sun, Jan 09, 2011 at 10:54:28AM -0500, Ben Kibbey wrote:
> I noticed a build failure for the userinfo utility not too long ago.
> There is no longer a ports maintainer for this one so I thought I'd try
> to get it fixed here. Could someone see if the following patch fixes it
> as I don't have a FreeBSD box.

I believe that the attached patch will fix the utility.  The need of
login.{h,c} hunks is obvious, the need for the configure one should
be explained, I think.  At my machine when I had compiled the code
the number of the active sessions was 0; so getutxent() will return NULL.
I think that the test should really be using UTXDB_LOG that has all
entries for utmpx.  And that check was implemented.

Two more nits:
 - I wasn't able to invoke 'ui -O login.so -la -- `users`', it were
   giving me the main help until I had killed the chaining test
   just after option parsing;

 - at least login.c uses unsafe constructions like
{{{
for (i =3D 0; i < cnt; i++) {
	...
	strncat(line, buf, sizeof(line));
	...
}
}}}
   It won't protect you from overrunning 'line', because the last
   argument of that strncat specifies how many bytes from _buf_
   we want to copy at most.  You will likely want to read the
   "Security considerations" section of
     http://www.freebsd.org/cgi/man.cgi?query=3Dstrncat&apropos=3D0&sektion=
=3D0&manpath=3DFreeBSD+8.1-RELEASE&format=3Dhtml
   or to use strlcpy/strlcat (but they aren't the standard ones
   on all platforms).
--=20
Eygene Ryabinkin                                        ,,,^..^,,,
[ Life's unfair - but root password helps!           | codelabs.ru ]
[ 82FE 06BC D497 C0DE 49EC  4FF0 16AF 9EAE 8152 ECFB | freebsd.org ]

--neYutvxvOLaeuPCA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch-utmpx
Content-Transfer-Encoding: quoted-printable

--- src/modules/login.c.orig	2011-01-09 22:06:08.813688876 +0300
+++ src/modules/login.c	2011-01-10 00:27:50.225685582 +0300
@@ -24,7 +24,6 @@
 #include <time.h>
 #include <pwd.h>
 #include <ctype.h>
-#include <utmp.h>
=20
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -32,6 +31,11 @@
=20
 #include "login.h"
=20
+#ifndef FREEBSD_UTMPX
+/* FreeBSD with utmpx support has utmp.h that will #error us. */
+#include <utmp.h>
+#endif
+
 #ifndef HAVE_STRSEP
 #include "../strsep.c"
 #endif
@@ -338,6 +342,40 @@
     return;
 }
=20
+#ifdef FREEBSD_UTMPX
+/*
+ * Get the last login data for the given user
+ * via utmpx(3) interface.
+ *.
+ * Has a side effect of setting the current database
+ * to the LASTLOGIN one.
+ */
+static char *lastloginx(const char *name, char *tf)
+{
+    static char buf[LINE_MAX];
+    struct utmpx *last =3D NULL;
+
+    if (setutxdb(UTXDB_LASTLOGIN, NULL)) {
+        warn("setutxdb(UTXDB_LASTLOGIN)");
+        return NULL;
+    }
+
+    while ((last =3D getutxent()) !=3D NULL) {
+        if (last->ut_type =3D=3D USER_PROCESS &&
+            strcmp(last->ut_user, name) =3D=3D 0)
+            break;
+    }
+    if (last =3D=3D NULL)
+        return NULL;
+
+    snprintf(buf, sizeof(buf), "%s,%s,%s",
+      (last->ut_line[0] =3D=3D '\0' ? "!" : last->ut_line),
+      (last->ut_host[0] =3D=3D '\0' ? "-" : last->ut_host),
+      stamp(last->ut_tv.tv_sec, tf));
+
+    return buf;
+}
+#else /* defined(FREEBSD_UTMPX) */
 /* Get the lastlog structure from the lastlog file. */
 static char *lastlogin(uid_t uid, char *tf)
 {
@@ -423,6 +461,7 @@
=20
     return buf;
 }
+#endif /* defined(FREEBSD_UTMPX) */
=20
 /* This will return an array of utmp structures if a user is logged in, NU=
LL
  * otherwise. We'll try to keep the utmp file descriptor open if possible =
to
@@ -452,10 +491,18 @@
     login_count =3D 0;
=20
 #ifdef UTMPX_FORMAT
+#ifdef FREEBSD_UTMPX
+    setutxent();
+#else
     setutent();
+#endif
=20
     while ((u =3D getutxent()) !=3D NULL) {
+#ifdef FREEBSD_UTMPX
+	if (strcmp(u->ut_user, user) =3D=3D 0) {
+#else
 	if (strcmp(u->ut_name, user) =3D=3D 0) {
+#endif
 #else
     lseek(fd, 0, SEEK_SET);
=20
@@ -481,7 +528,11 @@
 	    strncpy(logins[login_count]->ut_host, u->ut_host, UTX_HOSTSIZE);
 	    logins[login_count]->ut_pid =3D u->ut_pid;
 #else
+#ifdef FREEBSD_UTMPX
+	    strncpy(logins[login_count]->ut_user, u->ut_user, UT_NAMESIZE);
+#else
 	    strncpy(logins[login_count]->ut_name, u->ut_name, UT_NAMESIZE);
+#endif
 	    strncpy(logins[login_count]->ut_line, u->ut_line, UT_LINESIZE);
 	    strncpy(logins[login_count]->ut_host, u->ut_host, UT_HOSTSIZE);
 	    logins[login_count]->ut_tv.tv_sec =3D u->ut_tv.tv_sec;
@@ -639,7 +690,13 @@
 		add_string(&strings, (u) ? idle(u, multi) : "!");
 		break;
 	    case 'l':
-		last_strings(lastlogin(pw->pw_uid, tf));
+		last_strings(
+#ifdef FREEBSD_UTMPX
+		  lastloginx(pw->pw_name,tf)
+#else
+		  lastlogin(pw->pw_uid, tf)
+#endif
+		);
 		break;
 	    case 'h':
 		for (i =3D 0; i < login_count; i++) {
--- src/modules/login.h.orig	2011-01-09 23:40:11.136688587 +0300
+++ src/modules/login.h	2011-01-09 23:41:18.568686438 +0300
@@ -51,6 +51,9 @@
 #endif
=20
 #ifdef UTMPX_FORMAT
+#ifdef __FreeBSD__
+#define FREEBSD_UTMPX
+#endif
 #include <utmpx.h>
 #ifndef UT_HOSTSIZE
 #define UT_HOSTSIZE 256
--- configure.orig	2011-01-10 00:34:34.768686578 +0300
+++ configure	2011-01-10 00:35:46.413686990 +0300
@@ -20786,12 +20786,15 @@
   cat >conftest.$ac_ext <<_ACEOF
 \
 		#include <stdio.h>
+		#include <stdlib.h>
 		#include <utmpx.h>
=20
 		int main()
 		{
 		    struct utmpx *u;
=20
+		    if (setutxdb(UTXDB_LASTLOGIN, NULL))
+		        exit(1);
 		    if ((u =3D getutxent()) =3D=3D NULL)
 			exit(1);
=20

--neYutvxvOLaeuPCA--

--/e2eDi0V/xtL+Mc8
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.16 (FreeBSD)

iF4EAREIAAYFAk0qNKgACgkQFq+eroFS7Ps04QD+KSLbM+t2IISH8FrDL2Mf+z5F
fX7fAi/wwzXvF+KXuaYA/2WtwqzmKAO26eO1CIn8sNfz9OkyIdMJvHd4JIs3KTrv
=XQs3
-----END PGP SIGNATURE-----

--/e2eDi0V/xtL+Mc8--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?m%2Bt893bNDW3fqmhN1J7EbghUmjQ>