summaryrefslogtreecommitdiff
path: root/libexec/fingerd
diff options
context:
space:
mode:
authorexplorer <explorer@NetBSD.org>1996-08-10 22:10:17 +0000
committerexplorer <explorer@NetBSD.org>1996-08-10 22:10:17 +0000
commite670f342d90fa0584ec2f2663232808103eb2887 (patch)
tree43c620202c41c0c8b9e19f462dfeac3401a395aa /libexec/fingerd
parent22018a843b8524e85741f8b4184c9b14915dea66 (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.869
-rw-r--r--libexec/fingerd/fingerd.c189
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 */
}