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