1: /* 2: * Copyright (c) 1983, 1993 3: * The Regents of the University of California. All rights reserved. 4: * 5: * Redistribution and use in source and binary forms, with or without 6: * modification, are permitted provided that the following conditions 7: * are met: 8: * 1. Redistributions of source code must retain the above copyright 9: * notice, this list of conditions and the following disclaimer. 10: * 2. Redistributions in binary form must reproduce the above copyright 11: * notice, this list of conditions and the following disclaimer in the 12: * documentation and/or other materials provided with the distribution. 13: * 3. All advertising materials mentioning features or use of this software 14: * must display the following acknowledgement: 15: * This product includes software developed by the University of 16: * California, Berkeley and its contributors. 17: * 4. Neither the name of the University nor the names of its contributors 18: * may be used to endorse or promote products derived from this software 19: * without specific prior written permission. 20: * 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31: * SUCH DAMAGE. 32: */ 33: 34: #if defined(DOSCCS) & !defined(lint) 35: static char copyright[] = 36: "@(#) Copyright (c) 1983, 1993\n\ 37: The Regents of the University of California. All rights reserved.\n"; 38: #endif /* not lint */ 39: 40: #if defined(DOSCCS) & !defined(lint) 41: static char sccsid[] = "@(#)fingerd.c 8.1.1 (2.11BSD) 1995/04/01"; 42: #endif /* not lint */ 43: 44: #include <sys/types.h> 45: #include <sys/socket.h> 46: #include <netinet/in.h> 47: #include <arpa/inet.h> 48: #include <sys/errno.h> 49: 50: #include <syslog.h> 51: #include <netdb.h> 52: #include <stdio.h> 53: #include <strings.h> 54: #include "pathnames.h" 55: 56: extern char *optarg; 57: extern int optind, opterr, errno; 58: 59: int 60: main(argc, argv) 61: int argc; 62: char *argv[]; 63: { 64: register FILE *fp; 65: register int ch; 66: register char *lp; 67: struct hostent *hp; 68: struct sockaddr_in sin; 69: int p[2], logging, secure, sval; 70: #define ENTRIES 50 71: char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog; 72: 73: prog = _PATH_FINGER; 74: logging = secure = 0; 75: openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON); 76: opterr = 0; 77: while ((ch = getopt(argc, argv, "slp:")) != EOF) 78: switch (ch) { 79: case 'l': 80: logging = 1; 81: break; 82: case 'p': 83: prog = optarg; 84: break; 85: case 's': 86: secure = 1; 87: break; 88: case '?': 89: default: 90: err("illegal option -- %c", ch); 91: } 92: 93: if (logging) { 94: sval = sizeof(sin); 95: if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0) 96: err("getpeername: %s", strerror(errno)); 97: if (hp = gethostbyaddr((char *)&sin.sin_addr.s_addr, 98: sizeof(sin.sin_addr.s_addr), AF_INET)) 99: lp = hp->h_name; 100: else 101: lp = inet_ntoa(sin.sin_addr); 102: syslog(LOG_NOTICE, "query from %s", lp); 103: } 104: 105: if (!fgets(line, sizeof(line), stdin)) 106: exit(1); 107: 108: comp = &av[1]; 109: for (lp = line, ap = &av[2];;) { 110: *ap = strtok(lp, " \t\r\n"); 111: if (!*ap) { 112: if (secure && ap == &av[2]) { 113: puts("must provide username\r\n"); 114: exit(1); 115: } 116: break; 117: } 118: if (secure && strchr(*ap, '@')) { 119: puts("fowarding service denied\r\n"); 120: exit(1); 121: } 122: 123: /* RFC742: "/[Ww]" == "-l" */ 124: if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) { 125: av[1] = "-l"; 126: comp = &av[0]; 127: } 128: else if (++ap == av + ENTRIES) 129: break; 130: lp = NULL; 131: } 132: 133: if (lp = strrchr(prog, '/')) 134: *comp = ++lp; 135: else 136: *comp = prog; 137: if (pipe(p) < 0) 138: err("pipe: %s", strerror(errno)); 139: 140: switch(vfork()) { 141: case 0: 142: (void)close(p[0]); 143: if (p[1] != 1) { 144: (void)dup2(p[1], 1); 145: (void)close(p[1]); 146: } 147: execv(prog, comp); 148: err("execv: %s: %s", prog, strerror(errno)); 149: _exit(1); 150: case -1: 151: err("fork: %s", strerror(errno)); 152: } 153: (void)close(p[1]); 154: if (!(fp = fdopen(p[0], "r"))) 155: err("fdopen: %s", strerror(errno)); 156: while ((ch = getc(fp)) != EOF) { 157: if (ch == '\n') 158: putchar('\r'); 159: putchar(ch); 160: } 161: exit(0); 162: } 163: 164: #if __STDC__ 165: #include <stdarg.h> 166: #else 167: #include <varargs.h> 168: #endif 169: 170: void 171: #if __STDC__ 172: err(const char *fmt, ...) 173: #else 174: err(fmt, va_alist) 175: char *fmt; 176: va_dcl 177: #endif 178: { 179: va_list ap; 180: #if __STDC__ 181: va_start(ap, fmt); 182: #else 183: va_start(ap); 184: #endif 185: (void)vsyslog(LOG_ERR, fmt, ap); 186: va_end(ap); 187: exit(1); 188: /* NOTREACHED */ 189: }