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