xref: /csrg-svn/libexec/fingerd/fingerd.c (revision 55235)
122492Sdist /*
235556Sbostic  * Copyright (c) 1983 The Regents of the University of California.
335556Sbostic  * All rights reserved.
435556Sbostic  *
542664Sbostic  * %sccs.include.redist.c%
622492Sdist  */
722492Sdist 
816471Ssam #ifndef lint
922492Sdist char copyright[] =
1035556Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
1122492Sdist  All rights reserved.\n";
1235556Sbostic #endif /* not lint */
1316471Ssam 
1422492Sdist #ifndef lint
15*55235Sbostic static char sccsid[] = "@(#)fingerd.c	5.10 (Berkeley) 07/15/92";
1635556Sbostic #endif /* not lint */
1722492Sdist 
18*55235Sbostic #include <sys/types.h>
19*55235Sbostic #include <sys/socket.h>
20*55235Sbostic #include <netinet/in.h>
21*55235Sbostic #include <arpa/inet.h>
2252435Sbostic #include <errno.h>
23*55235Sbostic 
2452435Sbostic #include <unistd.h>
25*55235Sbostic #include <syslog.h>
26*55235Sbostic #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
35*55235Sbostic main(argc, argv)
36*55235Sbostic 	int argc;
37*55235Sbostic 	char *argv[];
3816471Ssam {
3936261Sbostic 	register FILE *fp;
4036261Sbostic 	register int ch;
4136261Sbostic 	register char *lp;
4255083Stef 	struct hostent *hp;
4316471Ssam 	struct sockaddr_in sin;
44*55235Sbostic 	int p[2], logging, secure, sval;
45*55235Sbostic #define	ENTRIES	50
46*55235Sbostic 	char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog;
4716471Ssam 
48*55235Sbostic 	prog = _PATH_FINGER;
49*55235Sbostic 	logging = secure = 0;
50*55235Sbostic 	openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON);
51*55235Sbostic 	opterr = 0;
52*55235Sbostic 	while ((ch = getopt(argc, argv, "slp:")) != EOF)
5355083Stef 		switch (ch) {
5455083Stef 		case 'l':
55*55235Sbostic 			logging = 1;
5655083Stef 			break;
5755083Stef 		case 'p':
5855083Stef 			prog = optarg;
5955083Stef 			break;
60*55235Sbostic 		case 's':
61*55235Sbostic 			secure = 1;
62*55235Sbostic 			break;
6355083Stef 		case '?':
6455083Stef 		default:
65*55235Sbostic 			err("illegal option -- %c", ch);
6655083Stef 		}
6736261Sbostic 
6855083Stef 	if (logging) {
69*55235Sbostic 		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,
73*55235Sbostic 		    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__
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