fingerd.c revision 12908
197049Speter/* 2174993Srafan * Copyright (c) 1983, 1993 397049Speter * The Regents of the University of California. All rights reserved. 497049Speter * 597049Speter * Redistribution and use in source and binary forms, with or without 697049Speter * modification, are permitted provided that the following conditions 797049Speter * are met: 897049Speter * 1. Redistributions of source code must retain the above copyright 997049Speter * notice, this list of conditions and the following disclaimer. 1097049Speter * 2. Redistributions in binary form must reproduce the above copyright 1197049Speter * notice, this list of conditions and the following disclaimer in the 1297049Speter * documentation and/or other materials provided with the distribution. 1397049Speter * 3. All advertising materials mentioning features or use of this software 1497049Speter * must display the following acknowledgement: 1597049Speter * This product includes software developed by the University of 1697049Speter * California, Berkeley and its contributors. 1797049Speter * 4. Neither the name of the University nor the names of its contributors 1897049Speter * may be used to endorse or promote products derived from this software 1997049Speter * without specific prior written permission. 2097049Speter * 2197049Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2297049Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2397049Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2497049Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2597049Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2697049Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2797049Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2897049Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2997049Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3097049Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3197049Speter * SUCH DAMAGE. 3297049Speter */ 3397049Speter 3497049Speter#ifndef lint 3597049Speterstatic char copyright[] = 3697049Speter"@(#) Copyright (c) 1983, 1993\n\ 3797049Speter The Regents of the University of California. All rights reserved.\n"; 38174993Srafan#endif /* not lint */ 3997049Speter 4097049Speter#ifndef lint 4197049Speter/* 42166124Srafanstatic char sccsid[] = "@(#)fingerd.c 8.1 (Berkeley) 6/4/93"; 43166124Srafan*/ 44166124Srafanstatic const char rcsid[] = 4597049Speter "$Id$"; 4697049Speter#endif /* not lint */ 47166124Srafan 48166124Srafan#include <sys/types.h> 49166124Srafan#include <sys/socket.h> 50166124Srafan#include <netinet/in.h> 51166124Srafan#include <netinet/tcp.h> 5297049Speter#include <arpa/inet.h> 5397049Speter#include <errno.h> 5497049Speter 5597049Speter#include <unistd.h> 5697049Speter#include <syslog.h> 57174993Srafan#include <netdb.h> 58174993Srafan#include <stdio.h> 59174993Srafan#include <stdlib.h> 6097049Speter#include <strings.h> 61166124Srafan#include "pathnames.h" 62166124Srafan 63166124Srafanvoid logerr __P((const char *, ...)); 6497049Speter 6597049Speterint 66166124Srafanmain(argc, argv) 67166124Srafan int argc; 6897049Speter char *argv[]; 69166124Srafan{ 70166124Srafan register FILE *fp; 71166124Srafan register int ch; 72166124Srafan register char *lp; 7397049Speter struct hostent *hp; 7497049Speter struct sockaddr_in sin; 75166124Srafan int p[2], logging, secure, sval; 7697049Speter#define ENTRIES 50 7797049Speter char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog; 7897049Speter 7997049Speter prog = _PATH_FINGER; 80166124Srafan logging = secure = 0; 8197049Speter openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON); 82166124Srafan opterr = 0; 83166124Srafan while ((ch = getopt(argc, argv, "slp:")) != EOF) 84166124Srafan switch (ch) { 85166124Srafan case 'l': 86166124Srafan logging = 1; 87166124Srafan break; 8897049Speter case 'p': 8997049Speter prog = optarg; 9097049Speter break; 9197049Speter case 's': 9297049Speter secure = 1; 9397049Speter break; 9497049Speter case '?': 9597049Speter default: 96166124Srafan logerr("illegal option -- %c", ch); 97166124Srafan } 98166124Srafan 99166124Srafan if (logging) { 100166124Srafan sval = sizeof(sin); 10197049Speter if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0) 10297049Speter logerr("getpeername: %s", strerror(errno)); 10397049Speter if (hp = gethostbyaddr((char *)&sin.sin_addr.s_addr, 10497049Speter sizeof(sin.sin_addr.s_addr), AF_INET)) 10597049Speter lp = hp->h_name; 10697049Speter else 10797049Speter lp = inet_ntoa(sin.sin_addr); 10897049Speter syslog(LOG_NOTICE, "query from %s", lp); 10997049Speter } 11097049Speter 11197049Speter /* 11297049Speter * Enable server-side Transaction TCP. 11397049Speter */ 11497049Speter { 11597049Speter int one = 1; 116166124Srafan if (setsockopt(STDOUT_FILENO, IPPROTO_TCP, TCP_NOPUSH, &one, 117166124Srafan sizeof one) < 0) { 11897049Speter logerr("setsockopt(TCP_NOPUSH) failed: %m"); 11997049Speter } 120166124Srafan } 12197049Speter 12297049Speter if (!fgets(line, sizeof(line), stdin)) 12397049Speter exit(1); 12497049Speter 12597049Speter comp = &av[1]; 12697049Speter av[2] = "--"; 12797049Speter for (lp = line, ap = &av[3];;) { 12897049Speter *ap = strtok(lp, " \t\r\n"); 12997049Speter if (!*ap) { 130 if (secure && ap == &av[3]) { 131 puts("must provide username\r\n"); 132 exit(1); 133 } 134 break; 135 } 136 if (secure && strchr(*ap, '@')) { 137 puts("forwarding service denied\r\n"); 138 exit(1); 139 } 140 141 /* RFC742: "/[Ww]" == "-l" */ 142 if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) { 143 av[1] = "-l"; 144 comp = &av[0]; 145 } 146 else if (++ap == av + ENTRIES) 147 break; 148 lp = NULL; 149 } 150 151 if (lp = strrchr(prog, '/')) 152 *comp = ++lp; 153 else 154 *comp = prog; 155 if (pipe(p) < 0) 156 logerr("pipe: %s", strerror(errno)); 157 158 switch(vfork()) { 159 case 0: 160 (void)close(p[0]); 161 if (p[1] != 1) { 162 (void)dup2(p[1], 1); 163 (void)close(p[1]); 164 } 165 execv(prog, comp); 166 logerr("execv: %s: %s", prog, strerror(errno)); 167 _exit(1); 168 case -1: 169 logerr("fork: %s", strerror(errno)); 170 } 171 (void)close(p[1]); 172 if (!(fp = fdopen(p[0], "r"))) 173 logerr("fdopen: %s", strerror(errno)); 174 while ((ch = getc(fp)) != EOF) { 175 if (ch == '\n') 176 putchar('\r'); 177 putchar(ch); 178 } 179 exit(0); 180} 181 182#if __STDC__ 183#include <stdarg.h> 184#else 185#include <varargs.h> 186#endif 187 188void 189#if __STDC__ 190logerr(const char *fmt, ...) 191#else 192logerr(fmt, va_alist) 193 char *fmt; 194 va_dcl 195#endif 196{ 197 va_list ap; 198#if __STDC__ 199 va_start(ap, fmt); 200#else 201 va_start(ap); 202#endif 203 (void)vsyslog(LOG_ERR, fmt, ap); 204 va_end(ap); 205 exit(1); 206 /* NOTREACHED */ 207} 208