fingerd.c revision 31308
11592Srgrimes/* 21592Srgrimes * Copyright (c) 1983, 1993 31592Srgrimes * The Regents of the University of California. All rights reserved. 41592Srgrimes * 51592Srgrimes * Redistribution and use in source and binary forms, with or without 61592Srgrimes * modification, are permitted provided that the following conditions 71592Srgrimes * are met: 81592Srgrimes * 1. Redistributions of source code must retain the above copyright 91592Srgrimes * notice, this list of conditions and the following disclaimer. 101592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111592Srgrimes * notice, this list of conditions and the following disclaimer in the 121592Srgrimes * documentation and/or other materials provided with the distribution. 131592Srgrimes * 3. All advertising materials mentioning features or use of this software 141592Srgrimes * must display the following acknowledgement: 151592Srgrimes * This product includes software developed by the University of 161592Srgrimes * California, Berkeley and its contributors. 171592Srgrimes * 4. Neither the name of the University nor the names of its contributors 181592Srgrimes * may be used to endorse or promote products derived from this software 191592Srgrimes * without specific prior written permission. 201592Srgrimes * 211592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241592Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311592Srgrimes * SUCH DAMAGE. 321592Srgrimes */ 331592Srgrimes 341592Srgrimes#ifndef lint 3531308Scharnierstatic const char copyright[] = 361592Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 371592Srgrimes The Regents of the University of California. All rights reserved.\n"; 381592Srgrimes#endif /* not lint */ 391592Srgrimes 401592Srgrimes#ifndef lint 4131308Scharnier#if 0 421592Srgrimesstatic char sccsid[] = "@(#)fingerd.c 8.1 (Berkeley) 6/4/93"; 4331308Scharnier#endif 4412908Swollmanstatic const char rcsid[] = 4531308Scharnier "$Id$"; 461592Srgrimes#endif /* not lint */ 471592Srgrimes 481592Srgrimes#include <sys/types.h> 491592Srgrimes#include <sys/socket.h> 501592Srgrimes#include <netinet/in.h> 5112908Swollman#include <netinet/tcp.h> 521592Srgrimes#include <arpa/inet.h> 531592Srgrimes#include <errno.h> 541592Srgrimes 551592Srgrimes#include <unistd.h> 561592Srgrimes#include <syslog.h> 571592Srgrimes#include <netdb.h> 581592Srgrimes#include <stdio.h> 591592Srgrimes#include <stdlib.h> 601592Srgrimes#include <strings.h> 611592Srgrimes#include "pathnames.h" 621592Srgrimes 6312908Swollmanvoid logerr __P((const char *, ...)); 641592Srgrimes 651592Srgrimesint 661592Srgrimesmain(argc, argv) 671592Srgrimes int argc; 681592Srgrimes char *argv[]; 691592Srgrimes{ 701592Srgrimes register FILE *fp; 711592Srgrimes register int ch; 721592Srgrimes register char *lp; 731592Srgrimes struct hostent *hp; 741592Srgrimes struct sockaddr_in sin; 751592Srgrimes int p[2], logging, secure, sval; 761592Srgrimes#define ENTRIES 50 771592Srgrimes char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog; 781592Srgrimes 791592Srgrimes prog = _PATH_FINGER; 801592Srgrimes logging = secure = 0; 811592Srgrimes openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON); 821592Srgrimes opterr = 0; 8324349Simp while ((ch = getopt(argc, argv, "slp:")) != -1) 841592Srgrimes switch (ch) { 851592Srgrimes case 'l': 861592Srgrimes logging = 1; 871592Srgrimes break; 881592Srgrimes case 'p': 891592Srgrimes prog = optarg; 901592Srgrimes break; 911592Srgrimes case 's': 921592Srgrimes secure = 1; 931592Srgrimes break; 941592Srgrimes case '?': 951592Srgrimes default: 9612908Swollman logerr("illegal option -- %c", ch); 971592Srgrimes } 981592Srgrimes 9912908Swollman /* 10012908Swollman * Enable server-side Transaction TCP. 10112908Swollman */ 10212908Swollman { 10312908Swollman int one = 1; 10412908Swollman if (setsockopt(STDOUT_FILENO, IPPROTO_TCP, TCP_NOPUSH, &one, 10512908Swollman sizeof one) < 0) { 10612908Swollman logerr("setsockopt(TCP_NOPUSH) failed: %m"); 10712908Swollman } 10812908Swollman } 10912908Swollman 1101592Srgrimes if (!fgets(line, sizeof(line), stdin)) 1111592Srgrimes exit(1); 1128870Srgrimes 11331168Ssef if (logging) { 11431168Ssef char *t; 11531168Ssef char *end; 11631168Ssef 11731168Ssef end = memchr(line, 0, sizeof(line)); 11831168Ssef if (end == NULL) { 11931168Ssef t = malloc(sizeof(line) + 1); 12031168Ssef memcpy(t, line, sizeof(line)); 12131168Ssef t[sizeof(line)] = 0; 12231168Ssef } else { 12331168Ssef t = strdup(line); 12431168Ssef } 12531168Ssef for (end = t; *end; end++) 12631168Ssef if (*end == '\n' || *end == '\r') 12731168Ssef *end = ' '; 12831168Ssef sval = sizeof(sin); 12931168Ssef if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0) 13031168Ssef logerr("getpeername: %s", strerror(errno)); 13131168Ssef if (hp = gethostbyaddr((char *)&sin.sin_addr.s_addr, 13231168Ssef sizeof(sin.sin_addr.s_addr), AF_INET)) 13331168Ssef lp = hp->h_name; 13431168Ssef else 13531168Ssef lp = inet_ntoa(sin.sin_addr); 13631168Ssef syslog(LOG_NOTICE, "query from %s: `%s'", lp, t); 13731168Ssef } 13831168Ssef 1391592Srgrimes comp = &av[1]; 14012728Speter av[2] = "--"; 14112728Speter for (lp = line, ap = &av[3];;) { 1421592Srgrimes *ap = strtok(lp, " \t\r\n"); 1431592Srgrimes if (!*ap) { 14412728Speter if (secure && ap == &av[3]) { 1451592Srgrimes puts("must provide username\r\n"); 1461592Srgrimes exit(1); 1471592Srgrimes } 1481592Srgrimes break; 1491592Srgrimes } 1501592Srgrimes if (secure && strchr(*ap, '@')) { 1516180Sphk puts("forwarding service denied\r\n"); 1521592Srgrimes exit(1); 1531592Srgrimes } 1541592Srgrimes 1551592Srgrimes /* RFC742: "/[Ww]" == "-l" */ 1561592Srgrimes if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) { 1571592Srgrimes av[1] = "-l"; 1581592Srgrimes comp = &av[0]; 1591592Srgrimes } 1601592Srgrimes else if (++ap == av + ENTRIES) 1611592Srgrimes break; 1621592Srgrimes lp = NULL; 1631592Srgrimes } 1641592Srgrimes 1651592Srgrimes if (lp = strrchr(prog, '/')) 1661592Srgrimes *comp = ++lp; 1671592Srgrimes else 1681592Srgrimes *comp = prog; 1691592Srgrimes if (pipe(p) < 0) 17012908Swollman logerr("pipe: %s", strerror(errno)); 1711592Srgrimes 1721592Srgrimes switch(vfork()) { 1731592Srgrimes case 0: 1741592Srgrimes (void)close(p[0]); 1751592Srgrimes if (p[1] != 1) { 1761592Srgrimes (void)dup2(p[1], 1); 1771592Srgrimes (void)close(p[1]); 1781592Srgrimes } 1791592Srgrimes execv(prog, comp); 18012908Swollman logerr("execv: %s: %s", prog, strerror(errno)); 1811592Srgrimes _exit(1); 1821592Srgrimes case -1: 18312908Swollman logerr("fork: %s", strerror(errno)); 1841592Srgrimes } 1851592Srgrimes (void)close(p[1]); 1861592Srgrimes if (!(fp = fdopen(p[0], "r"))) 18712908Swollman logerr("fdopen: %s", strerror(errno)); 1881592Srgrimes while ((ch = getc(fp)) != EOF) { 1891592Srgrimes if (ch == '\n') 1901592Srgrimes putchar('\r'); 1911592Srgrimes putchar(ch); 1921592Srgrimes } 1931592Srgrimes exit(0); 1941592Srgrimes} 1951592Srgrimes 1961592Srgrimes#if __STDC__ 1971592Srgrimes#include <stdarg.h> 1981592Srgrimes#else 1991592Srgrimes#include <varargs.h> 2001592Srgrimes#endif 2011592Srgrimes 2021592Srgrimesvoid 2031592Srgrimes#if __STDC__ 20412908Swollmanlogerr(const char *fmt, ...) 2051592Srgrimes#else 20612908Swollmanlogerr(fmt, va_alist) 2071592Srgrimes char *fmt; 2081592Srgrimes va_dcl 2091592Srgrimes#endif 2101592Srgrimes{ 2111592Srgrimes va_list ap; 2121592Srgrimes#if __STDC__ 2131592Srgrimes va_start(ap, fmt); 2141592Srgrimes#else 2151592Srgrimes va_start(ap); 2161592Srgrimes#endif 2171592Srgrimes (void)vsyslog(LOG_ERR, fmt, ap); 2181592Srgrimes va_end(ap); 2191592Srgrimes exit(1); 2201592Srgrimes /* NOTREACHED */ 2211592Srgrimes} 222