* sanitize long output, fixing buffer overflows whilst doing so

* clean up for WARNS?=1
This commit is contained in:
lukem 1997-08-24 02:40:40 +00:00
parent f77381e893
commit fa55e11566
3 changed files with 90 additions and 92 deletions

View File

@ -1,8 +1,9 @@
# $NetBSD: Makefile,v 1.8 1997/01/09 20:21:17 tls Exp $ # $NetBSD: Makefile,v 1.9 1997/08/24 02:40:40 lukem Exp $
PROG = rusers PROG = rusers
DPADD= ${LIBRPCSVC} DPADD= ${LIBRPCSVC}
LDADD= -lrpcsvc LDADD= -lrpcsvc
WARNS?= 1
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
.\" $NetBSD: rusers.1,v 1.6 1997/01/09 20:21:18 tls Exp $ .\" $NetBSD: rusers.1,v 1.7 1997/08/24 02:40:42 lukem Exp $
.\" .\"
.\" Copyright (c) 1983, 1990 The Regents of the University of California. .\" Copyright (c) 1983, 1990 The Regents of the University of California.
.\" All rights reserved. .\" All rights reserved.
@ -32,7 +32,7 @@
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" from: @(#)rusers.1 6.7 (Berkeley) 4/23/91 .\" from: @(#)rusers.1 6.7 (Berkeley) 4/23/91
.\" $NetBSD: rusers.1,v 1.6 1997/01/09 20:21:18 tls Exp $ .\" $NetBSD: rusers.1,v 1.7 1997/08/24 02:40:42 lukem Exp $
.\" .\"
.Dd April 23, 1991 .Dd April 23, 1991
.Dt RUSERS 1 .Dt RUSERS 1
@ -62,7 +62,7 @@ Print all machines responding even if no one is currently logged in.
.It Fl l .It Fl l
Print a long format listing. This includes the user name, host name, Print a long format listing. This includes the user name, host name,
tty that the user is logged in to, the date and time the user tty that the user is logged in to, the date and time the user
logged in, the amount of time since the user typed on the keyboard, logged in, the idle time (in minutes),
and the remote host they logged in from (if applicable). and the remote host they logged in from (if applicable).
.El .El
.Sh DIAGNOSTICS .Sh DIAGNOSTICS

View File

@ -1,4 +1,4 @@
/* $NetBSD: rusers.c,v 1.12 1997/01/09 20:21:18 tls Exp $ */ /* $NetBSD: rusers.c,v 1.13 1997/08/24 02:40:44 lukem Exp $ */
/*- /*-
* Copyright (c) 1993 John Brezak * Copyright (c) 1993 John Brezak
@ -28,20 +28,22 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/cdefs.h>
#ifndef lint #ifndef lint
static char rcsid[] = "$NetBSD: rusers.c,v 1.12 1997/01/09 20:21:18 tls Exp $"; __RCSID("$NetBSD: rusers.c,v 1.13 1997/08/24 02:40:44 lukem Exp $");
#endif /* not lint */ #endif /* not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>
#include <rpc/rpc.h> #include <rpc/rpc.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <utmp.h> #include <err.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <strings.h>
#include <utmp.h>
/* /*
* For now we only try version 2 of the protocol. The current * For now we only try version 2 of the protocol. The current
@ -50,15 +52,22 @@ static char rcsid[] = "$NetBSD: rusers.c,v 1.12 1997/01/09 20:21:18 tls Exp $";
*/ */
#include <rpcsvc/rnusers.h> /* Old version */ #include <rpcsvc/rnusers.h> /* Old version */
#define MAX_INT 0x7fffffff #define MAX_INT 0x7fffffff
#define HOST_WIDTH 20 extern char *__progname; /* from crt0.o */
#define LINE_WIDTH 8
char *argv0;
struct timeval timeout = { 25, 0 }; struct timeval timeout = { 25, 0 };
int longopt; int longopt;
int allopt; int allopt;
void allhosts __P((void));
int main __P((int, char *[]));
void onehost __P((char *));
void remember_host __P((struct in_addr));
int rusers_reply __P((char *, struct sockaddr_in *));
int search_host __P((struct in_addr));
void usage __P((void));
struct host_list { struct host_list {
struct host_list *next; struct host_list *next;
struct in_addr addr; struct in_addr addr;
@ -84,10 +93,8 @@ remember_host(struct in_addr addr)
{ {
struct host_list *hp; struct host_list *hp;
if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) { if (!(hp = (struct host_list *)malloc(sizeof(struct host_list))))
fprintf(stderr, "%s: no memory.\n", argv0); errx(1, "no memory");
exit(1);
}
hp->addr.s_addr = addr.s_addr; hp->addr.s_addr = addr.s_addr;
hp->next = hosts; hp->next = hosts;
hosts = hp; hosts = hp;
@ -96,12 +103,10 @@ remember_host(struct in_addr addr)
int int
rusers_reply(char *replyp, struct sockaddr_in *raddrp) rusers_reply(char *replyp, struct sockaddr_in *raddrp)
{ {
int x, idle; int x;
char date[32], idle_time[64], remote[64], local[64];
struct hostent *hp; struct hostent *hp;
struct utmpidlearr *up = (struct utmpidlearr *)replyp; struct utmpidlearr *up = (struct utmpidlearr *)replyp;
char *host; char *host;
int days, hours, minutes, seconds;
if (search_host(raddrp->sin_addr)) if (search_host(raddrp->sin_addr))
return(0); return(0);
@ -116,61 +121,64 @@ rusers_reply(char *replyp, struct sockaddr_in *raddrp)
else else
host = inet_ntoa(raddrp->sin_addr); host = inet_ntoa(raddrp->sin_addr);
#define HOSTWID (int)sizeof(up->uia_arr[0]->ui_utmp.ut_host)
#define LINEWID (int)sizeof(up->uia_arr[0]->ui_utmp.ut_line)
#define NAMEWID (int)sizeof(up->uia_arr[0]->ui_utmp.ut_name)
if (!longopt) if (!longopt)
printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, host); printf("%-*.*s ", HOSTWID, HOSTWID, host);
for (x = 0; x < up->uia_cnt; x++) { for (x = 0; x < up->uia_cnt; x++) {
strncpy(date, unsigned int minutes;
&(ctime((time_t *)&(up->uia_arr[x]->ui_utmp.ut_time))[4]), char date[26], idle[8];
sizeof(date)-1); char remote[HOSTWID + 3]; /* "(" host ")" \0 */
char local[HOSTWID + LINEWID + 2]; /* host ":" line \0 */
idle = up->uia_arr[x]->ui_idle; if (!longopt) {
sprintf(idle_time, " :%02d", idle); printf("%.*s ", NAMEWID,
if (idle == MAX_INT) up->uia_arr[x]->ui_utmp.ut_name);
strcpy(idle_time, "??"); continue;
else if (idle == 0)
strcpy(idle_time, "");
else {
seconds = idle;
days = seconds/(60*60*24);
seconds %= (60*60*24);
hours = seconds/(60*60);
seconds %= (60*60);
minutes = seconds/60;
seconds %= 60;
if (idle > 60)
sprintf(idle_time, "%2d:%02d",
minutes, seconds);
if (idle >= (60*60))
sprintf(idle_time, "%2d:%02d:%02d",
hours, minutes, seconds);
if (idle >= (24*60*60))
sprintf(idle_time, "%d days, %d:%02d:%02d",
days, hours, minutes, seconds);
} }
strncpy(remote, up->uia_arr[x]->ui_utmp.ut_host, snprintf(local, sizeof(local), "%.*s:%s",
sizeof(remote)-1); HOSTWID, host,
if (strlen(remote) != 0) up->uia_arr[x]->ui_utmp.ut_line);
sprintf(remote, "(%.16s)",
up->uia_arr[x]->ui_utmp.ut_host);
if (longopt) { snprintf(date, sizeof(date), "%s",
strncpy(local, host, sizeof(local)); &(ctime((time_t *)&(up->uia_arr[x]->ui_utmp.ut_time)))[4]);
local[HOST_WIDTH + LINE_WIDTH + 1 -
strlen(up->uia_arr[x]->ui_utmp.ut_line) - 1] = 0;
strcat(local, ":");
strcat(local, up->uia_arr[x]->ui_utmp.ut_line);
printf("%-8.8s %-*.*s %-12.12s %8s %.18s\n", minutes = up->uia_arr[x]->ui_idle;
up->uia_arr[x]->ui_utmp.ut_name, if (minutes == MAX_INT)
HOST_WIDTH+LINE_WIDTH+1, HOST_WIDTH+LINE_WIDTH+1, local, strcpy(idle, "??");
date, else if (minutes == 0)
idle_time, strcpy(idle, "");
remote); else {
} else unsigned int days, hours;
printf("%0.8s ",
up->uia_arr[x]->ui_utmp.ut_name); days = minutes / (24 * 60);
minutes %= (24 * 60);
hours = minutes / 24;
minutes %= 24;
if (days > 0)
snprintf(idle, sizeof(idle), "%d d ", days);
else if (hours > 0)
snprintf(idle, sizeof(idle), "%2d:%02d",
hours, minutes);
else
snprintf(idle, sizeof(idle), ":%02d", minutes);
}
if (up->uia_arr[x]->ui_utmp.ut_host[0] != '\0')
snprintf(remote, sizeof(remote), "(%.*s)",
HOSTWID, up->uia_arr[x]->ui_utmp.ut_host);
else
remote[0] = '\0';
printf("%-*.*s %-*.*s %-12.12s %8.8s %s\n",
NAMEWID, NAMEWID, up->uia_arr[x]->ui_utmp.ut_name,
HOSTWID+LINEWID+1, HOSTWID+LINEWID+1, local,
date, idle, remote);
} }
if (!longopt) if (!longopt)
putchar('\n'); putchar('\n');
@ -184,28 +192,25 @@ onehost(char *host)
{ {
struct utmpidlearr up; struct utmpidlearr up;
CLIENT *rusers_clnt; CLIENT *rusers_clnt;
enum clnt_stat clnt_stat;
struct sockaddr_in addr; struct sockaddr_in addr;
struct hostent *hp; struct hostent *hp;
hp = gethostbyname(host); hp = gethostbyname(host);
if (hp == NULL) { if (hp == NULL)
fprintf(stderr, "%s: unknown host \"%s\"\n", errx(1, "unknown host \"%s\"", host);
argv0, host);
exit(1);
}
rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp"); rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp");
if (rusers_clnt == NULL) { if (rusers_clnt == NULL) {
clnt_pcreateerror(argv0); clnt_pcreateerror(__progname);
exit(1); exit(1);
} }
bzero((char *)&up, sizeof(up)); memset((char *)&up, 0, sizeof(up));
if (clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL, clnt_stat = clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL,
xdr_utmpidlearr, &up, timeout) != RPC_SUCCESS) { xdr_utmpidlearr, &up, timeout);
clnt_perror(rusers_clnt, argv0); if (clnt_stat != RPC_SUCCESS)
exit(1); errx(1, "%s", clnt_sperrno(clnt_stat));
}
addr.sin_addr.s_addr = *(int *)hp->h_addr; addr.sin_addr.s_addr = *(int *)hp->h_addr;
rusers_reply((char *)&up, &addr); rusers_reply((char *)&up, &addr);
} }
@ -216,20 +221,18 @@ allhosts(void)
struct utmpidlearr up; struct utmpidlearr up;
enum clnt_stat clnt_stat; enum clnt_stat clnt_stat;
bzero((char *)&up, sizeof(up)); memset((char *)&up, 0, sizeof(up));
clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE, clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE,
RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmpidlearr, RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmpidlearr,
&up, rusers_reply); (char *)&up, rusers_reply);
if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) { if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
fprintf(stderr, "%s: %s\n", argv0, clnt_sperrno(clnt_stat)); errx(1, "%s", clnt_sperrno(clnt_stat));
exit(1);
}
} }
void void
usage(void) usage(void)
{ {
fprintf(stderr, "Usage: %s [-la] [hosts ...]\n", argv0); fprintf(stderr, "Usage: %s [-la] [hosts ...]\n", __progname);
exit(1); exit(1);
} }
@ -239,12 +242,6 @@ main(int argc, char *argv[])
int ch; int ch;
extern int optind; extern int optind;
if (!(argv0 = rindex(argv[0], '/')))
argv0 = argv[0];
else
argv0++;
while ((ch = getopt(argc, argv, "al")) != -1) while ((ch = getopt(argc, argv, "al")) != -1)
switch (ch) { switch (ch) {
case 'a': case 'a':