diff options
| author | explorer <explorer@NetBSD.org> | 1996-08-10 22:10:17 +0000 |
|---|---|---|
| committer | explorer <explorer@NetBSD.org> | 1996-08-10 22:10:17 +0000 |
| commit | e670f342d90fa0584ec2f2663232808103eb2887 (patch) | |
| tree | 43c620202c41c0c8b9e19f462dfeac3401a395aa /libexec/fingerd | |
| parent | 22018a843b8524e85741f8b4184c9b14915dea66 (diff) | |
Replace our fingerd with one from OpenBSD, which fixes some security holes
and adds new features.
Diffstat (limited to 'libexec/fingerd')
| -rw-r--r-- | libexec/fingerd/fingerd.8 | 69 | ||||
| -rw-r--r-- | libexec/fingerd/fingerd.c | 189 |
2 files changed, 208 insertions, 50 deletions
diff --git a/libexec/fingerd/fingerd.8 b/libexec/fingerd/fingerd.8 index 47e175f4ef8..b97dff95591 100644 --- a/libexec/fingerd/fingerd.8 +++ b/libexec/fingerd/fingerd.8 @@ -1,5 +1,5 @@ -.\" Copyright (c) 1980, 1991 The Regents of the University of California. -.\" All rights reserved. +.\" Copyright (c) 1980, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" from: @(#)fingerd.8 6.4 (Berkeley) 3/16/91 -.\" $Id: fingerd.8,v 1.2 1993/08/01 07:40:24 mycroft Exp $ +.\" from: @(#)fingerd.8 8.1 (Berkeley) 6/4/93 +.\" $Id: fingerd.8,v 1.3 1996/08/10 22:10:17 explorer Exp $ .\" -.Dd March 16, 1991 +.Dd June 4, 1993 .Dt FINGERD 8 .Os BSD 4.3 .Sh NAME @@ -40,10 +40,17 @@ .Nd remote user information server .Sh SYNOPSIS .Nm fingerd +.Op Fl s +.Op Fl l +.Op Fl u +.Op Fl m +.Op Fl p +.Op Fl S +.Op Fl P Ar filename .Sh DESCRIPTION .Nm Fingerd is a simple protocol based on -.%T RFC742 +.%T RFC1196 that provides an interface to the Name and Finger programs at several network sites. The program is supposed to return a friendly, @@ -86,6 +93,56 @@ in the command line include both and .Dq user names . If a name is ambiguous, all possible derivations are returned. +.Pp +The following options may be passed to +.Nm fingerd +as server program arguments in +.Pa /etc/inetd.conf : +.Bl -tag -width Ds +.It Fl s +Enable secure mode. +Forwarding of queries to other remote hosts is denied. +.It Fl l +Enable logging. +The name of the host originating the query is reported via +.Xr syslog 3 +at LOG_NOTICE priority. +.It Fl u +Queries without a user name are rejected. +.It Fl m +Prevent matching of +.Ar user +names. +.Ar User +is usually a login name; however, matching will also be done on the +users' real names, unless the +.Fl m +option is supplied. +.It Fl p +Prevents +.Nm finger +from displaying the contents of the +.Dq Pa .plan +and +.Dq Pa .project +files. +.It Fl S +Prints user information in short mode, one line per user. +This overrides the +.Dq Pa Whois switch +that may be passed in from the remote client. +.It Fl P +Use an alternate program as the local information provider. +The default local program +executed by +.Nm fingerd +is +.Xr finger 1 . +By specifying a customized local server, +this option allows a system manager +to have more control over what information is +provided to remote sites. +.El .Sh SEE ALSO .Xr finger 1 .Sh BUGS diff --git a/libexec/fingerd/fingerd.c b/libexec/fingerd/fingerd.c index fe97fc52365..35f6da54126 100644 --- a/libexec/fingerd/fingerd.c +++ b/libexec/fingerd/fingerd.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1983 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,72 +32,156 @@ */ #ifndef lint -char copyright[] = -"@(#) Copyright (c) 1983 The Regents of the University of California.\n\ - All rights reserved.\n"; +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/*static char sccsid[] = "from: @(#)fingerd.c 5.6 (Berkeley) 6/1/90";*/ -static char rcsid[] = "$Id: fingerd.c,v 1.2 1993/08/01 18:30:56 mycroft Exp $"; +/*static char sccsid[] = "from: @(#)fingerd.c 8.1 (Berkeley) 6/4/93";*/ +static char rcsid[] = "$Id: fingerd.c,v 1.3 1996/08/10 22:10:18 explorer Exp $"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> + +#include <unistd.h> +#include <syslog.h> +#include <netdb.h> #include <stdio.h> +#include <stdlib.h> +#include <strings.h> #include "pathnames.h" -main() +void err __P((const char *, ...)); + +int +main(argc, argv) + int argc; + char *argv[]; { register FILE *fp; - register int ch; + register int ch, ac = 2; register char *lp; - int p[2]; + struct hostent *hp; + struct sockaddr_in sin; + int p[2], logging, secure, user_required, short_list, sval; #define ENTRIES 50 - char **ap, *av[ENTRIES + 1], line[1024], *strtok(); + char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog; -#ifdef LOGGING /* unused for now */ -#include <netinet/in.h> - struct sockaddr_in sin; - int sval; + prog = _PATH_FINGER; + logging = secure = user_required = short_list = 0; + openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON); + opterr = 0; + while ((ch = getopt(argc, argv, "sluSmpP:")) != EOF) + switch (ch) { + case 'l': + logging = 1; + break; + case 'P': + prog = optarg; + break; + case 's': + secure = 1; + break; + case 'u': + user_required = 1; + break; + case 'S': + short_list = 1; + av[ac++] = "-s"; + break; + case 'm': + av[ac++] = "-m"; + break; + case 'p': + av[ac++] = "-p"; + break; + case '?': + default: + err("illegal option -- %c", ch); + } - sval = sizeof(sin); - if (getpeername(0, &sin, &sval) < 0) - fatal("getpeername"); -#endif + if (logging) { + sval = sizeof(sin); + if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0) + err("getpeername: %s", strerror(errno)); + if ((hp = gethostbyaddr((char *)&sin.sin_addr.s_addr, + sizeof(sin.sin_addr.s_addr), AF_INET))) + lp = hp->h_name; + else + lp = inet_ntoa(sin.sin_addr); + syslog(LOG_NOTICE, "query from %s", lp); + } if (!fgets(line, sizeof(line), stdin)) exit(1); - - av[0] = "finger"; - for (lp = line, ap = &av[1];;) { - *ap = strtok(lp, " \t\r\n"); - if (!*ap) - break; - /* RFC742: "/[Ww]" == "-l" */ - if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) - *ap = "-l"; - if (++ap == av + ENTRIES) + + av[ac++] = "--"; + comp = &av[1]; + for (lp = line, ap = &av[ac]; ac < ENTRIES;) { + if ((*ap = strtok(lp, " \t\r\n")) == NULL) break; lp = NULL; + if (secure && strchr(*ap, '@')) { + (void) puts("fowarding service denied\r\n"); + exit(1); + } + + ch = strlen(*ap); + while ((*ap)[ch-1] == '@') + (*ap)[--ch] = '\0'; + if (**ap == '\0') + continue; + + /* RFC1196: "/[Ww]" == "-l" */ + if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) { + if (!short_list) { + av[1] = "-l"; + comp = &av[0]; + } + } else { + ap++; + ac++; + } + } + av[ENTRIES - 1] = NULL; + + if ((lp = strrchr(prog, '/'))) + *comp = ++lp; + else + *comp = prog; + + if (user_required) { + for (ap = comp + 1; strcmp("--", *(ap++)); ); + if (*ap == NULL) { + (void) puts("must provide username\r\n"); + exit(1); + } } if (pipe(p) < 0) - fatal("pipe"); + err("pipe: %s", strerror(errno)); - switch(fork()) { + switch(vfork()) { case 0: - (void)close(p[0]); + (void) close(p[0]); if (p[1] != 1) { - (void)dup2(p[1], 1); - (void)close(p[1]); + (void) dup2(p[1], 1); + (void) close(p[1]); } - execv(_PATH_FINGER, av); + execv(prog, comp); + err("execv: %s: %s", prog, strerror(errno)); _exit(1); case -1: - fatal("fork"); + err("fork: %s", strerror(errno)); } - (void)close(p[1]); + (void) close(p[1]); if (!(fp = fdopen(p[0], "r"))) - fatal("fdopen"); + err("fdopen: %s", strerror(errno)); while ((ch = getc(fp)) != EOF) { if (ch == '\n') putchar('\r'); @@ -106,12 +190,29 @@ main() exit(0); } -fatal(msg) - char *msg; -{ - extern int errno; - char *strerror(); +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif - fprintf(stderr, "fingerd: %s: %s\r\n", msg, strerror(errno)); +void +#if __STDC__ +err(const char *fmt, ...) +#else +err(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void) vsyslog(LOG_ERR, fmt, ap); + va_end(ap); exit(1); + /* NOTREACHED */ } |
