Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Jan 2011 19:50:12 -0500
From:      Ben Kibbey <bjk@luxsci.net>
To:        Eygene Ryabinkin <rea@freebsd.org>
Cc:        ports@freebsd.org
Subject:   Re: FreeBSD Port: sysutils/userinfo
Message-ID:  <201101100051.p0A0p2Fa000944@rs49.luxsci.com>
In-Reply-To: <m%2Bt893bNDW3fqmhN1J7EbghUmjQ@5UW8B3LwPEGInFShts5A7R/S2Yo>
References:  <201101091555.p09Ft22H023380@rs49.luxsci.com> <m%2Bt893bNDW3fqmhN1J7EbghUmjQ@5UW8B3LwPEGInFShts5A7R/S2Yo>

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

--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Jan 10, 2011 at 01:20:24AM +0300, Eygene Ryabinkin wrote:
> 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.

That makes sense. I've fixed the utmp[x] checking to only check for
headers and not mess with non-POSIX functions but still conditionally
support setutxdb() and getutxuser(). Could you test the new attached
patch?  I'm trying to us getutxuser() and from what I've read from the
manual page it seems like it should work. If not, then I'll use the one
you wrote.

> 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;

Could you tell me the command line you used?

>  - at least login.c uses unsafe constructions like
> {{{
> for (i = 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

Thanks for the input. I'll fix those soon!

 
-- 
Ben Kibbey
[XMPP: bjk AT thiessen DOT org] - [IRC: (bjk) FreeNode/OFTC]

--zYM0uCDKw75PZbzx
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="patch.diff"

diff --git a/configure.ac b/configure.ac
index 2a34b55..4a80044 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,36 +24,7 @@ AC_HEADER_DIRENT
 AC_HEADER_STDC
 AC_CHECK_HEADERS([fcntl.h limits.h paths.h stdlib.h string.h sys/param.h \
 		  unistd.h sys/syslimits.h libgen.h err.h shadow.h \
-		  lastlog.h err.h sys/mman.h getopt.h])
-
-dnl Some systems have utmpx.h but don't utilize it (they use the older utmp
-dnl format).
-AC_CHECK_HEADER([utmpx.h], [have_utmpx=1], [have_utmpx=0])
-
-if test $have_utmpx = 1; then
-    AC_MSG_CHECKING([how utmp is utilized])
-    AC_RUN_IFELSE([\
-		#include <stdio.h>
-		#include <utmpx.h>
-
-		int main()
-		{
-		    struct utmpx *u; 
-
-		    if ((u = getutxent()) == NULL)
-			exit(1);
-
-		    exit(0);
-		}
-		], [utmpx_works=1], [utmpx_works=0])
-    
-    if test $utmpx_works = 1; then
-	AC_MSG_RESULT([utmpx])
-	AC_DEFINE([UTMPX_FORMAT], 1, [Define if your system USES utmpx.])
-    else
-	AC_MSG_RESULT([utmp])
-    fi
-fi
+		  lastlog.h err.h sys/mman.h getopt.h utmp.h utmpx.h])
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
diff --git a/src/modules/login.c b/src/modules/login.c
index 0f354a7..9f5e73e 100644
--- a/src/modules/login.c
+++ b/src/modules/login.c
@@ -15,6 +15,10 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -24,11 +28,6 @@
 #include <time.h>
 #include <pwd.h>
 #include <ctype.h>
-#include <utmp.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
 
 #include "login.h"
 
@@ -73,7 +72,7 @@ void ui_module_exit()
     return;
 }
 
-#ifndef UTMPX_FORMAT
+#ifndef HAVE_UTMPX_H
 /* This is for *BSD (login process id). */
 #ifdef BSD_KVM
 char *ui_module_pid(uid_t uid, int multi)
@@ -339,14 +338,65 @@ static void last_strings(char *str)
 }
 
 /* Get the lastlog structure from the lastlog file. */
-static char *lastlogin(uid_t uid, char *tf)
+#if (defined(__FreeBSD_version) && __FreeBSD_version >= 900000)
+static char *lastlogin(const struct passwd *pw, char *tf)
+{
+    struct utmpx *last, *found;
+    static char buf[LINE_MAX];
+
+    if (setutxdb(UTXDB_LASTLOGIN, NULL) == -1) {
+	warn("lastlog");
+	return NULL;
+    }
+
+    found = getutxuser(pw->pw_name);
+
+    if (!found)
+	return NULL;
+
+    found->ut_type = DEAD_PROCESS;
+    last = getutxid(found);
+
+    if (!last)
+	return NULL;
+
+    if (!last->ut_line[0])
+	strncpy(buf, "!", sizeof(buf));
+    else
+	strncpy(buf, last->ut_line, sizeof(buf));
+
+    strncat(buf, ",", sizeof(buf));
+
+    if (last->ut_host[0] && isalnum(last->ut_host[0]))
+	strncat(buf, last->ut_host, sizeof(buf));
+    else {
+	/*
+	 * If a users tty is tty1-n, it must be a console login. 
+	 */
+	if (strlen(last->ut_line) > 3 && isdigit(last->ut_line[3]))
+	    strncat(buf, "-", sizeof(buf));
+	else
+	    strncat(buf, "!", sizeof(buf));
+    }
+
+    strncat(buf, ",", sizeof(buf));
+
+    if (last->ut_time[0])
+	strncat(buf, stamp(last->ut_time, tf), sizeof(buf));
+    else
+	strncat(buf, "!", sizeof(buf));
+
+    return buf;
+}
+#else
+static char *lastlogin(const struct passwd *pw, char *tf)
 {
     int count;
     long offset;
     static char buf[LINE_MAX];
 
 #ifdef __NetBSD__
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
     char tmp[64], htmp[UTX_HOSTSIZE + 1];
 #else
     char tmp[64], htmp[UT_HOSTSIZE + 1];
@@ -368,7 +418,7 @@ static char *lastlogin(uid_t uid, char *tf)
 	}
     }
 
-    offset = (long) uid *sizeof(struct lastlog);
+    offset = (long) pw->pw_uid *sizeof(struct lastlog);
 
     if (lseek(lastlogfd, offset, SEEK_SET) == -1) {
 	warn("%s", _PATH_LASTLOG);
@@ -392,7 +442,7 @@ static char *lastlogin(uid_t uid, char *tf)
     strncpy(htmp, last.ll_host, sizeof(htmp));
 
 #ifdef __NetBSD__
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
     htmp[UTX_HOSTSIZE] = '\0';
 #else
     htmp[UT_HOSTSIZE] = '\0';
@@ -405,8 +455,7 @@ static char *lastlogin(uid_t uid, char *tf)
 	strncat(buf, htmp, sizeof(buf));
     else {
 	/*
-	 * If a users tty is tty1-n, it must be a console
-	 * * login. 
+	 * If a users tty is tty1-n, it must be a console login. 
 	 */
 	if (last.ll_line[0] && isdigit((unsigned char) last.ll_line[3]))
 	    strncat(buf, "-", sizeof(buf));
@@ -423,6 +472,7 @@ static char *lastlogin(uid_t uid, char *tf)
 
     return buf;
 }
+#endif
 
 /* This will return an array of utmp structures if a user is logged in, NULL
  * otherwise. We'll try to keep the utmp file descriptor open if possible to
@@ -430,8 +480,7 @@ static char *lastlogin(uid_t uid, char *tf)
 static UTMP **get_utmp(const char *user)
 {
     UTMP **logins = NULL;
-
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
     UTMP *u;
 #else
     UTMP u;
@@ -451,11 +500,11 @@ static UTMP **get_utmp(const char *user)
 
     login_count = 0;
 
-#ifdef UTMPX_FORMAT
-    setutent();
+#ifdef HAVE_UTMPX_H
+    setutxent();
 
     while ((u = getutxent()) != NULL) {
-	if (strcmp(u->ut_name, user) == 0) {
+	if (!strcmp(u->ut_user, user)) {
 #else
     lseek(fd, 0, SEEK_SET);
 
@@ -474,14 +523,14 @@ static UTMP **get_utmp(const char *user)
 		return NULL;
 	    }
 
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 #ifdef __NetBSD__
 	    strncpy(logins[login_count]->ut_name, u->ut_name, UTX_NAMESIZE);
 	    strncpy(logins[login_count]->ut_line, u->ut_line, UTX_LINESIZE);
 	    strncpy(logins[login_count]->ut_host, u->ut_host, UTX_HOSTSIZE);
 	    logins[login_count]->ut_pid = u->ut_pid;
 #else
-	    strncpy(logins[login_count]->ut_name, u->ut_name, UT_NAMESIZE);
+	    strncpy(logins[login_count]->ut_user, u->ut_user, UT_NAMESIZE);
 	    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 = u->ut_tv.tv_sec;
@@ -555,7 +604,7 @@ static char *idle(UTMP ** u, int multi)
 	    continue;
 	}
 
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 	if (u[i]->ut_tv.tv_sec > st.st_atime) {
 #else
 	if (u[i]->ut_time > st.st_atime) {
@@ -567,7 +616,7 @@ static char *idle(UTMP ** u, int multi)
 
 	t = st.st_atime;
 
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 	if (t < u[i]->ut_tv.tv_sec)
 	    t = u[i]->ut_tv.tv_sec;
 #else
@@ -625,7 +674,7 @@ int ui_module_exec(char ***s, const struct passwd *pw, const int multi,
 	int i;
 	char m[2] = { multi, '\0' };
 #ifdef __NetBSD__
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 	char htmp[UTX_HOSTSIZE + 1];
 #else
 	char htmp[UT_HOSTSIZE + 1];
@@ -639,7 +688,7 @@ int ui_module_exec(char ***s, const struct passwd *pw, const int multi,
 		add_string(&strings, (u) ? idle(u, multi) : "!");
 		break;
 	    case 'l':
-		last_strings(lastlogin(pw->pw_uid, tf));
+		last_strings(lastlogin(pw, tf));
 		break;
 	    case 'h':
 		for (i = 0; i < login_count; i++) {
@@ -693,7 +742,7 @@ int ui_module_exec(char ***s, const struct passwd *pw, const int multi,
 		break;
 	    case 't':
 		for (i = 0; i < login_count; i++) {
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 		    strncat(line, stamp(u[i]->ut_tv.tv_sec, tf), sizeof(line));
 #else
 		    strncat(line, stamp(u[i]->ut_time, tf), sizeof(line));
@@ -710,7 +759,7 @@ int ui_module_exec(char ***s, const struct passwd *pw, const int multi,
 		break;
 	    case 'd':
 		for (i = 0; i < login_count; i++) {
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 		    if ((now - u[i]->ut_tv.tv_sec) > 60) {
 			snprintf(buf, sizeof(buf), "%lu",
 				 ((now - u[i]->ut_tv.tv_sec) / 60));
@@ -735,7 +784,7 @@ int ui_module_exec(char ***s, const struct passwd *pw, const int multi,
 		add_string(&strings, line);
 		break;
 	    case 'p':
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 		for (i = 0; i < login_count; i++) {
 		    if (u[i]->ut_pid) {
 			snprintf(buf, sizeof(buf), "%li", (long) u[i]->ut_pid);
diff --git a/src/modules/login.h b/src/modules/login.h
index 55bd5bb..7296a88 100644
--- a/src/modules/login.h
+++ b/src/modules/login.h
@@ -50,7 +50,7 @@
 #define _PATH_LASTLOG	"/var/adm/lastlog"
 #endif
 
-#ifdef UTMPX_FORMAT
+#ifdef HAVE_UTMPX_H
 #include <utmpx.h>
 #ifndef UT_HOSTSIZE
 #define UT_HOSTSIZE 256
@@ -59,11 +59,11 @@
 #endif
 typedef struct utmpx UTMP;
 #else
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
 typedef struct utmp UTMP;
 #endif
-
-#define setutent setutxent
-#define ut_xtime ut_tv.tv_sec
+#endif
 
 #define TIMEBUFSIZE	64
 
@@ -92,7 +92,6 @@ static int lastlogfd;
 static time_t now;
 static int login_count;
 
-char *parentpid(uid_t, int, char *);
 void add_string(char ***, const char *);
 char *stamp(time_t, const char *);
 

--zYM0uCDKw75PZbzx--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101100051.p0A0p2Fa000944>