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*55083Stef static char sccsid[] = "@(#)fingerd.c 5.9 (Berkeley) 07/12/92"; 1635556Sbostic #endif /* not lint */ 1722492Sdist 1852435Sbostic #include <errno.h> 1952435Sbostic #include <unistd.h> 2016471Ssam #include <stdio.h> 2152435Sbostic #include <stdlib.h> 2252435Sbostic #include <strings.h> 23*55083Stef #include <syslog.h> 24*55083Stef #include <netdb.h> 25*55083Stef #include <sys/types.h> 26*55083Stef #include <sys/socket.h> 27*55083Stef #include <netinet/in.h> 28*55083Stef #include <arpa/inet.h> 2937269Sbostic #include "pathnames.h" 3016471Ssam 3152435Sbostic void err __P((const char *, ...)); 3252435Sbostic 3352435Sbostic int 34*55083Stef main(int argc, char **argv) 3516471Ssam { 3636261Sbostic register FILE *fp; 3736261Sbostic register int ch; 3836261Sbostic register char *lp; 3936261Sbostic int p[2]; 4036261Sbostic #define ENTRIES 50 4152435Sbostic char **ap, *av[ENTRIES + 1], **comp, line[1024]; 42*55083Stef char *prog = _PATH_FINGER; 43*55083Stef struct hostent *hp; 4416471Ssam struct sockaddr_in sin; 45*55083Stef int sval = sizeof(sin); 46*55083Stef int secure=0, logging=0; 47*55083Stef extern char *optarg; 4816471Ssam 49*55083Stef openlog("fingerd", LOG_PID|LOG_CONS, LOG_DAEMON); 50*55083Stef while ((ch=getopt(argc, argv, "slp:")) != EOF) 51*55083Stef switch (ch) { 52*55083Stef case 's': 53*55083Stef secure++; 54*55083Stef break; 55*55083Stef case 'l': 56*55083Stef logging++; 57*55083Stef break; 58*55083Stef case 'p': 59*55083Stef prog = optarg; 60*55083Stef break; 61*55083Stef case '?': 62*55083Stef default: 63*55083Stef syslog(LOG_ERR, "unknown option: %c", ch); 64*55083Stef } 6536261Sbostic 66*55083Stef if (logging) { 67*55083Stef if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0) 68*55083Stef err("getpeername: %s", strerror(errno)); 69*55083Stef if (hp = gethostbyaddr((char *)&sin.sin_addr.s_addr, 70*55083Stef sizeof(sin.sin_addr.s_addr), AF_INET)) 71*55083Stef lp = hp->h_name; 72*55083Stef else 73*55083Stef lp = inet_ntoa(sin.sin_addr); 74*55083Stef syslog(LOG_NOTICE, "query from %s", lp); 75*55083Stef } 76*55083Stef 7736261Sbostic if (!fgets(line, sizeof(line), stdin)) 7836199Sbostic exit(1); 7952435Sbostic 8052435Sbostic comp = &av[1]; 8152435Sbostic for (lp = line, ap = &av[2];;) { 8236261Sbostic *ap = strtok(lp, " \t\r\n"); 83*55083Stef if (!*ap) { 84*55083Stef if (secure && ap == &av[2]) { 85*55083Stef puts("must provide username\r\n"); 86*55083Stef exit(1); 87*55083Stef } 8816471Ssam break; 89*55083Stef } 90*55083Stef if (secure && strchr(*ap, '@')) { 91*55083Stef puts("fowarding service denied\r\n"); 92*55083Stef exit(1); 93*55083Stef } 94*55083Stef 9536261Sbostic /* RFC742: "/[Ww]" == "-l" */ 9652446Sbostic if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) { 9752446Sbostic av[1] = "-l"; 9852446Sbostic comp = &av[0]; 9952446Sbostic } 10052435Sbostic else if (++ap == av + ENTRIES) 10136261Sbostic break; 10236261Sbostic lp = NULL; 10316471Ssam } 10436261Sbostic 105*55083Stef if (lp = strrchr(prog, '/')) 106*55083Stef *comp = ++lp; 107*55083Stef else 108*55083Stef *comp = prog; 10916770Sralph if (pipe(p) < 0) 11052435Sbostic err("pipe: %s", strerror(errno)); 11136261Sbostic 11252435Sbostic switch(vfork()) { 11336261Sbostic case 0: 11436261Sbostic (void)close(p[0]); 11516770Sralph if (p[1] != 1) { 11636261Sbostic (void)dup2(p[1], 1); 11736261Sbostic (void)close(p[1]); 11816770Sralph } 119*55083Stef execv(prog, comp); 120*55083Stef err("execv: %s: %s", prog, strerror(errno)); 12116770Sralph _exit(1); 12236261Sbostic case -1: 12352435Sbostic err("fork: %s", strerror(errno)); 12416770Sralph } 12536261Sbostic (void)close(p[1]); 12636261Sbostic if (!(fp = fdopen(p[0], "r"))) 12752435Sbostic err("fdopen: %s", strerror(errno)); 12836261Sbostic while ((ch = getc(fp)) != EOF) { 12936261Sbostic if (ch == '\n') 13016595Sralph putchar('\r'); 13136261Sbostic putchar(ch); 13216595Sralph } 13336261Sbostic exit(0); 13416471Ssam } 13516471Ssam 13652435Sbostic #if __STDC__ 13752435Sbostic #include <stdarg.h> 13852435Sbostic #else 13952435Sbostic #include <varargs.h> 14052435Sbostic #endif 14152435Sbostic 14252435Sbostic void 14352435Sbostic #if __STDC__ 14452435Sbostic err(const char *fmt, ...) 14552435Sbostic #else 14652435Sbostic err(fmt, va_alist) 14752435Sbostic char *fmt; 14852435Sbostic va_dcl 14952435Sbostic #endif 15016471Ssam { 15152435Sbostic va_list ap; 15252435Sbostic #if __STDC__ 15352435Sbostic va_start(ap, fmt); 15452435Sbostic #else 15552435Sbostic va_start(ap); 15652435Sbostic #endif 157*55083Stef (void)vsyslog(LOG_ERR, fmt, ap); 15852435Sbostic va_end(ap); 15916471Ssam exit(1); 16052435Sbostic /* NOTREACHED */ 16116471Ssam } 162