xref: /csrg-svn/libexec/fingerd/fingerd.c (revision 61423)
122492Sdist /*
2*61423Sbostic  * Copyright (c) 1983, 1993
3*61423Sbostic  *	The Regents of the University of California.  All rights reserved.
435556Sbostic  *
542664Sbostic  * %sccs.include.redist.c%
622492Sdist  */
722492Sdist 
816471Ssam #ifndef lint
9*61423Sbostic static char copyright[] =
10*61423Sbostic "@(#) Copyright (c) 1983, 1993\n\
11*61423Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1235556Sbostic #endif /* not lint */
1316471Ssam 
1422492Sdist #ifndef lint
15*61423Sbostic static char sccsid[] = "@(#)fingerd.c	8.1 (Berkeley) 06/04/93";
1635556Sbostic #endif /* not lint */
1722492Sdist 
1855235Sbostic #include <sys/types.h>
1955235Sbostic #include <sys/socket.h>
2055235Sbostic #include <netinet/in.h>
2155235Sbostic #include <arpa/inet.h>
2252435Sbostic #include <errno.h>
2355235Sbostic 
2452435Sbostic #include <unistd.h>
2555235Sbostic #include <syslog.h>
2655235Sbostic #include <netdb.h>
2716471Ssam #include <stdio.h>
2852435Sbostic #include <stdlib.h>
2952435Sbostic #include <strings.h>
3037269Sbostic #include "pathnames.h"
3116471Ssam 
3252435Sbostic void err __P((const char *, ...));
3352435Sbostic 
3452435Sbostic int
main(argc,argv)3555235Sbostic main(argc, argv)
3655235Sbostic 	int argc;
3755235Sbostic 	char *argv[];
3816471Ssam {
3936261Sbostic 	register FILE *fp;
4036261Sbostic 	register int ch;
4136261Sbostic 	register char *lp;
4255083Stef 	struct hostent *hp;
4316471Ssam 	struct sockaddr_in sin;
4455235Sbostic 	int p[2], logging, secure, sval;
4555235Sbostic #define	ENTRIES	50
4655235Sbostic 	char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog;
4716471Ssam 
4855235Sbostic 	prog = _PATH_FINGER;
4955235Sbostic 	logging = secure = 0;
5055235Sbostic 	openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON);
5155235Sbostic 	opterr = 0;
5255235Sbostic 	while ((ch = getopt(argc, argv, "slp:")) != EOF)
5355083Stef 		switch (ch) {
5455083Stef 		case 'l':
5555235Sbostic 			logging = 1;
5655083Stef 			break;
5755083Stef 		case 'p':
5855083Stef 			prog = optarg;
5955083Stef 			break;
6055235Sbostic 		case 's':
6155235Sbostic 			secure = 1;
6255235Sbostic 			break;
6355083Stef 		case '?':
6455083Stef 		default:
6555235Sbostic 			err("illegal option -- %c", ch);
6655083Stef 		}
6736261Sbostic 
6855083Stef 	if (logging) {
6955235Sbostic 		sval = sizeof(sin);
7055083Stef 		if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0)
7155083Stef 			err("getpeername: %s", strerror(errno));
7255083Stef 		if (hp = gethostbyaddr((char *)&sin.sin_addr.s_addr,
7355235Sbostic 		    sizeof(sin.sin_addr.s_addr), AF_INET))
7455083Stef 			lp = hp->h_name;
7555083Stef 		else
7655083Stef 			lp = inet_ntoa(sin.sin_addr);
7755083Stef 		syslog(LOG_NOTICE, "query from %s", lp);
7855083Stef 	}
7955083Stef 
8036261Sbostic 	if (!fgets(line, sizeof(line), stdin))
8136199Sbostic 		exit(1);
8252435Sbostic 
8352435Sbostic 	comp = &av[1];
8452435Sbostic 	for (lp = line, ap = &av[2];;) {
8536261Sbostic 		*ap = strtok(lp, " \t\r\n");
8655083Stef 		if (!*ap) {
8755083Stef 			if (secure && ap == &av[2]) {
8855083Stef 				puts("must provide username\r\n");
8955083Stef 				exit(1);
9055083Stef 			}
9116471Ssam 			break;
9255083Stef 		}
9355083Stef 		if (secure && strchr(*ap, '@')) {
9455083Stef 			puts("fowarding service denied\r\n");
9555083Stef 			exit(1);
9655083Stef 		}
9755083Stef 
9836261Sbostic 		/* RFC742: "/[Ww]" == "-l" */
9952446Sbostic 		if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) {
10052446Sbostic 			av[1] = "-l";
10152446Sbostic 			comp = &av[0];
10252446Sbostic 		}
10352435Sbostic 		else if (++ap == av + ENTRIES)
10436261Sbostic 			break;
10536261Sbostic 		lp = NULL;
10616471Ssam 	}
10736261Sbostic 
10855083Stef 	if (lp = strrchr(prog, '/'))
10955083Stef 		*comp = ++lp;
11055083Stef 	else
11155083Stef 		*comp = prog;
11216770Sralph 	if (pipe(p) < 0)
11352435Sbostic 		err("pipe: %s", strerror(errno));
11436261Sbostic 
11552435Sbostic 	switch(vfork()) {
11636261Sbostic 	case 0:
11736261Sbostic 		(void)close(p[0]);
11816770Sralph 		if (p[1] != 1) {
11936261Sbostic 			(void)dup2(p[1], 1);
12036261Sbostic 			(void)close(p[1]);
12116770Sralph 		}
12255083Stef 		execv(prog, comp);
12355083Stef 		err("execv: %s: %s", prog, strerror(errno));
12416770Sralph 		_exit(1);
12536261Sbostic 	case -1:
12652435Sbostic 		err("fork: %s", strerror(errno));
12716770Sralph 	}
12836261Sbostic 	(void)close(p[1]);
12936261Sbostic 	if (!(fp = fdopen(p[0], "r")))
13052435Sbostic 		err("fdopen: %s", strerror(errno));
13136261Sbostic 	while ((ch = getc(fp)) != EOF) {
13236261Sbostic 		if (ch == '\n')
13316595Sralph 			putchar('\r');
13436261Sbostic 		putchar(ch);
13516595Sralph 	}
13636261Sbostic 	exit(0);
13716471Ssam }
13816471Ssam 
13952435Sbostic #if __STDC__
14052435Sbostic #include <stdarg.h>
14152435Sbostic #else
14252435Sbostic #include <varargs.h>
14352435Sbostic #endif
14452435Sbostic 
14552435Sbostic void
14652435Sbostic #if __STDC__
err(const char * fmt,...)14752435Sbostic err(const char *fmt, ...)
14852435Sbostic #else
14952435Sbostic err(fmt, va_alist)
15052435Sbostic 	char *fmt;
15152435Sbostic         va_dcl
15252435Sbostic #endif
15316471Ssam {
15452435Sbostic 	va_list ap;
15552435Sbostic #if __STDC__
15652435Sbostic 	va_start(ap, fmt);
15752435Sbostic #else
15852435Sbostic 	va_start(ap);
15952435Sbostic #endif
16055083Stef 	(void)vsyslog(LOG_ERR, fmt, ap);
16152435Sbostic 	va_end(ap);
16216471Ssam 	exit(1);
16352435Sbostic 	/* NOTREACHED */
16416471Ssam }
165