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>