summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>1999-11-18 09:33:48 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>1999-11-18 09:33:48 +0000
commitbc6e78fde2d97a7b5e7bb45a6db230afa30c8fe7 (patch)
tree41591d7592240792af614e64f8e8cec459131cf1 /usr.sbin
parentf0650fa2d06dcfa7c3103e50537235200d39a534 (diff)
Notes
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/inetd/Makefile1
-rw-r--r--usr.sbin/inetd/inetd.841
-rw-r--r--usr.sbin/inetd/inetd.c522
3 files changed, 66 insertions, 498 deletions
diff --git a/usr.sbin/inetd/Makefile b/usr.sbin/inetd/Makefile
index 03c727b30846..0df97554b47c 100644
--- a/usr.sbin/inetd/Makefile
+++ b/usr.sbin/inetd/Makefile
@@ -2,6 +2,7 @@
# $FreeBSD$
PROG= inetd
+SRCS= inetd.c builtins.c
MAN8= inetd.8
MLINKS= inetd.8 inetd.conf.5
MAINTAINER=des@freebsd.org
diff --git a/usr.sbin/inetd/inetd.8 b/usr.sbin/inetd/inetd.8
index 906e68e55e68..f063f27c9a5c 100644
--- a/usr.sbin/inetd/inetd.8
+++ b/usr.sbin/inetd/inetd.8
@@ -351,14 +351,46 @@ The
should be just as arguments
normally are, starting with argv[0], which is the name of
the program. If the service is provided internally, the
-word
+.Em service-name
+of the service (and any arguments to it) or the word
.Dq internal
should take the place of this entry.
.Pp
+Currently, the only internal service to take arguments is
+.Dq auth .
+Without options, the service will always return
+.Dq ERROR\ : HIDDEN-USER .
+The available arguments to this service that alter its behaviour are:
+.Bl -tag -width indent
+.It Fl r
+Offer a real
+.Dq auth
+service, as per RFC 1413. All the following flags apply only in this case.
+.It Fl f
+If the file
+.Pa .fakeid
+exists in the home directory of the identified user, report the username
+found in that file instead of the real username.
+.It Fl n
+If the file
+.Pa .noident
+exists in the home directory of the identified user, return
+.Dq ERROR\ : HIDDEN-USER .
+instead.
+.It Fl o Ar osname
+Use
+.Ar osname
+instead of the name of the system implementation
+returned by
+.Xr uname 3 .
+.It Fl t Ar sec[.usec]
+Specify a timeout for the service. The default timeout is 10.0 seconds.
+.El
+.Pp
The
.Nm
program
-provides several
+also provides several other
.Dq trivial
services internally by use of
routines within itself. These services are
@@ -597,6 +629,11 @@ socket but was unable to.
.Xr rshd 8 ,
.Xr telnetd 8 ,
.Xr tftpd 8
+.Rs
+.%A Michael C. St. Johns
+.%T Identification Protocol
+.%O RFC1413
+.Re
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c
index 3081e123259b..dc99fa023c8f 100644
--- a/usr.sbin/inetd/inetd.c
+++ b/usr.sbin/inetd/inetd.c
@@ -104,9 +104,7 @@ static const char rcsid[] =
* Comment lines are indicated by a `#' in column 1.
*/
#include <sys/param.h>
-#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -133,6 +131,9 @@ static const char rcsid[] =
#include <libutil.h>
#include <sysexits.h>
+#include "inetd.h"
+#include "pathnames.h"
+
#ifndef LIBWRAP_ALLOW_FACILITY
# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
#endif
@@ -159,8 +160,6 @@ static const char rcsid[] =
#endif
-#include "pathnames.h"
-
#ifndef MAXCHILD
#define MAXCHILD -1 /* maximum number of this service
< 0 = no limit */
@@ -185,7 +184,6 @@ int wrap_ex = 0;
int wrap_bi = 0;
int debug = 0;
int log = 0;
-int nsock;
int maxsock; /* highest-numbered descriptor */
fd_set allsock;
int options;
@@ -197,122 +195,13 @@ struct servent *sp;
struct rpcent *rpc;
struct in_addr bind_address;
int signalpipe[2];
-
-struct servtab {
- char *se_service; /* name of service */
- int se_socktype; /* type of socket to use */
- char *se_proto; /* protocol used */
- int se_maxchild; /* max number of children */
- int se_maxcpm; /* max connects per IP per minute */
- int se_numchild; /* current number of children */
- pid_t *se_pids; /* array of child pids */
- char *se_user; /* user name to run as */
- char *se_group; /* group name to run as */
-#ifdef LOGIN_CAP
- char *se_class; /* login class name to run with */
+#ifdef SANITY_CHECK
+int nsock;
#endif
- struct biltin *se_bi; /* if built-in, description */
- char *se_server; /* server program */
- char *se_server_name; /* server program without path */
-#define MAXARGV 20
- char *se_argv[MAXARGV+1]; /* program arguments */
- int se_fd; /* open descriptor */
- struct sockaddr_in se_ctrladdr;/* bound address */
- u_char se_type; /* type: normal, mux, or mux+ */
- u_char se_checked; /* looked at during merge */
- u_char se_accept; /* i.e., wait/nowait mode */
- u_char se_rpc; /* ==1 if RPC service */
- int se_rpc_prog; /* RPC program number */
- u_int se_rpc_lowvers; /* RPC low version */
- u_int se_rpc_highvers; /* RPC high version */
- int se_count; /* number started since se_time */
- struct timeval se_time; /* start of se_count */
- struct servtab *se_next;
-} *servtab;
-
-#define NORM_TYPE 0
-#define MUX_TYPE 1
-#define MUXPLUS_TYPE 2
-#define TTCP_TYPE 3
-#define ISMUX(sep) (((sep)->se_type == MUX_TYPE) || \
- ((sep)->se_type == MUXPLUS_TYPE))
-#define ISMUXPLUS(sep) ((sep)->se_type == MUXPLUS_TYPE)
-#define ISTTCP(sep) ((sep)->se_type == TTCP_TYPE)
-
-
-void chargen_dg __P((int, struct servtab *));
-void chargen_stream __P((int, struct servtab *));
-void close_sep __P((struct servtab *));
-void flag_signal __P((char));
-void flag_config __P((int));
-void config __P((void));
-void daytime_dg __P((int, struct servtab *));
-void daytime_stream __P((int, struct servtab *));
-void discard_dg __P((int, struct servtab *));
-void discard_stream __P((int, struct servtab *));
-void echo_dg __P((int, struct servtab *));
-void echo_stream __P((int, struct servtab *));
-void endconfig __P((void));
-struct servtab *enter __P((struct servtab *));
-void freeconfig __P((struct servtab *));
-struct servtab *getconfigent __P((void));
-void ident_stream __P((int, struct servtab *));
-void machtime_dg __P((int, struct servtab *));
-void machtime_stream __P((int, struct servtab *));
-int matchservent __P((char *, char *, char *));
-char *newstr __P((char *));
-char *nextline __P((FILE *));
-void print_service __P((char *, struct servtab *));
-void addchild __P((struct servtab *, int));
-void flag_reapchild __P((int));
-void reapchild __P((void));
-void enable __P((struct servtab *));
-void disable __P((struct servtab *));
-void flag_retry __P((int));
-void retry __P((void));
-int setconfig __P((void));
-void setup __P((struct servtab *));
-char *sskip __P((char **));
-char *skip __P((char **));
-struct servtab *tcpmux __P((int));
-int cpmip __P((struct servtab *, int));
-void inetd_setproctitle __P((char *, int));
-
-void unregisterrpc __P((register struct servtab *sep));
-
-struct biltin {
- char *bi_service; /* internally provided service name */
- int bi_socktype; /* type of socket supported */
- short bi_fork; /* 1 if should fork before call */
- int bi_maxchild; /* max number of children (-1=default) */
- void (*bi_fn)(); /* function which performs it */
-} biltins[] = {
- /* Echo received data */
- { "echo", SOCK_STREAM, 1, -1, echo_stream },
- { "echo", SOCK_DGRAM, 0, 1, echo_dg },
- /* Internet /dev/null */
- { "discard", SOCK_STREAM, 1, -1, discard_stream },
- { "discard", SOCK_DGRAM, 0, 1, discard_dg },
+struct servtab *servtab;
- /* Return 32 bit time since 1970 */
- { "time", SOCK_STREAM, 0, -1, machtime_stream },
- { "time", SOCK_DGRAM, 0, 1, machtime_dg },
-
- /* Return human-readable time */
- { "daytime", SOCK_STREAM, 0, -1, daytime_stream },
- { "daytime", SOCK_DGRAM, 0, 1, daytime_dg },
-
- /* Familiar character generator */
- { "chargen", SOCK_STREAM, 1, -1, chargen_stream },
- { "chargen", SOCK_DGRAM, 0, 1, chargen_dg },
-
- { "tcpmux", SOCK_STREAM, 1, -1, (void (*)())tcpmux },
-
- { "auth", SOCK_STREAM, 1, -1, ident_stream },
-
- { NULL }
-};
+extern struct biltin biltins[];
#define NUMINT (sizeof(intab) / sizeof(struct inent))
char *CONFIG = _PATH_INETDCONF;
@@ -474,11 +363,13 @@ main(argc, argv, envp)
}
if (pipe(signalpipe) != 0) {
- syslog(LOG_ERR, "pipe: %%m");
+ syslog(LOG_ERR, "pipe: %m");
exit(EX_OSERR);
}
FD_SET(signalpipe[0], &allsock);
+#ifdef SANITY_CHECK
nsock++;
+#endif
if (signalpipe[0] > maxsock)
maxsock = signalpipe[0];
if (signalpipe[1] > maxsock)
@@ -488,10 +379,12 @@ main(argc, argv, envp)
int n, ctrl;
fd_set readable;
+#ifdef SANITY_CHECK
if (nsock == 0) {
syslog(LOG_ERR, "%s: nsock=0", __FUNCTION__);
exit(EX_SOFTWARE);
}
+#endif
readable = allsock;
if ((n = select(maxsock + 1, &readable, (fd_set *)0,
(fd_set *)0, (struct timeval *)0)) <= 0) {
@@ -535,6 +428,9 @@ main(argc, argv, envp)
if (debug)
warnx("someone wants %s", sep->se_service);
if (sep->se_accept && sep->se_socktype == SOCK_STREAM) {
+ i = 1;
+ if (ioctl(sep->se_fd, FIONBIO, &i) < 0)
+ syslog(LOG_ERR, "ioctl (FIONBIO, 1): %m");
ctrl = accept(sep->se_fd, (struct sockaddr *)0,
(int *)0);
if (debug)
@@ -549,6 +445,11 @@ main(argc, argv, envp)
close(ctrl);
continue;
}
+ i = 0;
+ if (ioctl(sep->se_fd, FIONBIO, &i) < 0)
+ syslog(LOG_ERR, "ioctl1(FIONBIO, 0): %m");
+ if (ioctl(ctrl, FIONBIO, &i) < 0)
+ syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m");
if (cpmip(sep, ctrl) < 0) {
close(ctrl);
continue;
@@ -954,7 +855,7 @@ void config()
} else {
rpc = getrpcbyname(sep->se_service);
if (rpc == 0) {
- syslog(LOG_ERR, "%s/%s unknown RPC service.",
+ syslog(LOG_ERR, "%s/%s unknown RPC service",
sep->se_service, sep->se_proto);
if (sep->se_fd != -1)
(void) close(sep->se_fd);
@@ -1164,7 +1065,7 @@ enter(cp)
sep = (struct servtab *)malloc(sizeof (*sep));
if (sep == (struct servtab *)0) {
- syslog(LOG_ERR, "Out of memory.");
+ syslog(LOG_ERR, "malloc: %m");
exit(EX_OSERR);
}
*sep = *cp;
@@ -1198,9 +1099,9 @@ enable(struct servtab *sep)
"%s: %s: not off", __FUNCTION__, sep->se_service);
exit(EX_SOFTWARE);
}
+ nsock++;
#endif
FD_SET(sep->se_fd, &allsock);
- nsock++;
if (sep->se_fd > maxsock)
maxsock = sep->se_fd;
}
@@ -1231,9 +1132,9 @@ disable(struct servtab *sep)
syslog(LOG_ERR, "%s: nsock=0", __FUNCTION__);
exit(EX_SOFTWARE);
}
+ nsock--;
#endif
FD_CLR(sep->se_fd, &allsock);
- nsock--;
if (sep->se_fd == maxsock)
maxsock--;
}
@@ -1343,7 +1244,7 @@ more:
break;
default:
syslog(LOG_ERR,
- "bad RPC version specifier; %s\n",
+ "bad RPC version specifier; %s",
sep->se_service);
freeconfig(sep);
goto more;
@@ -1455,7 +1356,7 @@ more:
if (sep->se_maxchild) {
sep->se_pids = malloc(sep->se_maxchild * sizeof(*sep->se_pids));
if (sep->se_pids == NULL) {
- syslog(LOG_ERR, "Out of memory.");
+ syslog(LOG_ERR, "malloc: %m");
exit(EX_OSERR);
}
}
@@ -1626,50 +1527,6 @@ inetd_setproctitle(a, s)
/*
* Internet services provided internally by inetd:
*/
-#define BUFSIZE 8192
-
-#define IDENT_RESPONSE ":ERROR:HIDDEN-USER\r\n"
-
-/* ARGSUSED */
-void
-ident_stream(s, sep) /* Ident service */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZE];
- int i, j;
-
- inetd_setproctitle(sep->se_service, s);
- j = 0;
- while ((i = read(s, buffer + j, sizeof(buffer) - j)) > 0) {
- j += i;
- buffer[j] = '\0';
- if (strchr(buffer, '\n'))
- break;
- if (strchr(buffer, '\r'))
- break;
- }
- while (j > 0 && (buffer[j-1] == '\n' || buffer[j-1] == '\r'))
- j--;
- write(s, buffer, j);
- write(s, IDENT_RESPONSE, strlen(IDENT_RESPONSE));
- exit(0);
-}
-/* ARGSUSED */
-void
-echo_stream(s, sep) /* Echo service -- echo data back */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZE];
- int i;
-
- inetd_setproctitle(sep->se_service, s);
- while ((i = read(s, buffer, sizeof(buffer))) > 0 &&
- write(s, buffer, i) > 0)
- ;
- exit(0);
-}
int check_loop(sin, sep)
struct sockaddr_in *sin;
@@ -1693,245 +1550,6 @@ int check_loop(sin, sep)
return 0;
}
-/* ARGSUSED */
-void
-echo_dg(s, sep) /* Echo service -- echo data back */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZE];
- int i, size;
- struct sockaddr_in sin;
-
- size = sizeof(sin);
- if ((i = recvfrom(s, buffer, sizeof(buffer), 0,
- (struct sockaddr *)&sin, &size)) < 0)
- return;
-
- if (check_loop(&sin, sep))
- return;
-
- (void) sendto(s, buffer, i, 0, (struct sockaddr *)&sin,
- sizeof(sin));
-}
-
-/* ARGSUSED */
-void
-discard_stream(s, sep) /* Discard service -- ignore data */
- int s;
- struct servtab *sep;
-{
- int ret;
- char buffer[BUFSIZE];
-
- inetd_setproctitle(sep->se_service, s);
- while (1) {
- while ((ret = read(s, buffer, sizeof(buffer))) > 0)
- ;
- if (ret == 0 || errno != EINTR)
- break;
- }
- exit(0);
-}
-
-/* ARGSUSED */
-void
-discard_dg(s, sep) /* Discard service -- ignore data */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZE];
-
- (void) read(s, buffer, sizeof(buffer));
-}
-
-#include <ctype.h>
-#define LINESIZ 72
-char ring[128];
-char *endring;
-
-void
-initring()
-{
- int i;
-
- endring = ring;
-
- for (i = 0; i <= 128; ++i)
- if (isprint(i))
- *endring++ = i;
-}
-
-/* ARGSUSED */
-void
-chargen_stream(s, sep) /* Character generator */
- int s;
- struct servtab *sep;
-{
- int len;
- char *rs, text[LINESIZ+2];
-
- inetd_setproctitle(sep->se_service, s);
-
- if (!endring) {
- initring();
- rs = ring;
- }
-
- text[LINESIZ] = '\r';
- text[LINESIZ + 1] = '\n';
- for (rs = ring;;) {
- if ((len = endring - rs) >= LINESIZ)
- memmove(text, rs, LINESIZ);
- else {
- memmove(text, rs, len);
- memmove(text + len, ring, LINESIZ - len);
- }
- if (++rs == endring)
- rs = ring;
- if (write(s, text, sizeof(text)) != sizeof(text))
- break;
- }
- exit(0);
-}
-
-/* ARGSUSED */
-void
-chargen_dg(s, sep) /* Character generator */
- int s;
- struct servtab *sep;
-{
- struct sockaddr_in sin;
- static char *rs;
- int len, size;
- char text[LINESIZ+2];
-
- if (endring == 0) {
- initring();
- rs = ring;
- }
-
- size = sizeof(sin);
- if (recvfrom(s, text, sizeof(text), 0,
- (struct sockaddr *)&sin, &size) < 0)
- return;
-
- if (check_loop(&sin, sep))
- return;
-
- if ((len = endring - rs) >= LINESIZ)
- memmove(text, rs, LINESIZ);
- else {
- memmove(text, rs, len);
- memmove(text + len, ring, LINESIZ - len);
- }
- if (++rs == endring)
- rs = ring;
- text[LINESIZ] = '\r';
- text[LINESIZ + 1] = '\n';
- (void) sendto(s, text, sizeof(text), 0,
- (struct sockaddr *)&sin, sizeof(sin));
-}
-
-/*
- * Return a machine readable date and time, in the form of the
- * number of seconds since midnight, Jan 1, 1900. Since gettimeofday
- * returns the number of seconds since midnight, Jan 1, 1970,
- * we must add 2208988800 seconds to this figure to make up for
- * some seventy years Bell Labs was asleep.
- */
-
-unsigned long
-machtime()
-{
- struct timeval tv;
-
- if (gettimeofday(&tv, (struct timezone *)NULL) < 0) {
- if (debug)
- warnx("unable to get time of day");
- return (0L);
- }
-#define OFFSET ((u_long)25567 * 24*60*60)
- return (htonl((long)(tv.tv_sec + OFFSET)));
-#undef OFFSET
-}
-
-/* ARGSUSED */
-void
-machtime_stream(s, sep)
- int s;
- struct servtab *sep;
-{
- unsigned long result;
-
- result = machtime();
- (void) write(s, (char *) &result, sizeof(result));
-}
-
-/* ARGSUSED */
-void
-machtime_dg(s, sep)
- int s;
- struct servtab *sep;
-{
- unsigned long result;
- struct sockaddr_in sin;
- int size;
-
- size = sizeof(sin);
- if (recvfrom(s, (char *)&result, sizeof(result), 0,
- (struct sockaddr *)&sin, &size) < 0)
- return;
-
- if (check_loop(&sin, sep))
- return;
-
- result = machtime();
- (void) sendto(s, (char *) &result, sizeof(result), 0,
- (struct sockaddr *)&sin, sizeof(sin));
-}
-
-/* ARGSUSED */
-void
-daytime_stream(s, sep) /* Return human-readable time of day */
- int s;
- struct servtab *sep;
-{
- char buffer[256];
- time_t clock;
-
- clock = time((time_t *) 0);
-
- (void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
- (void) write(s, buffer, strlen(buffer));
-}
-
-/* ARGSUSED */
-void
-daytime_dg(s, sep) /* Return human-readable time of day */
- int s;
- struct servtab *sep;
-{
- char buffer[256];
- time_t clock;
- struct sockaddr_in sin;
- int size;
-
- clock = time((time_t *) 0);
-
- size = sizeof(sin);
- if (recvfrom(s, buffer, sizeof(buffer), 0,
- (struct sockaddr *)&sin, &size) < 0)
- return;
-
- if (check_loop(&sin, sep))
- return;
-
- (void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
- (void) sendto(s, buffer, strlen(buffer), 0,
- (struct sockaddr *)&sin, sizeof(sin));
-}
-
/*
* print_service:
* Dump relevant information to stderr
@@ -1955,94 +1573,6 @@ print_service(action, sep)
(void *) sep->se_bi, sep->se_server);
}
-/*
- * Based on TCPMUX.C by Mark K. Lottor November 1988
- * sri-nic::ps:<mkl>tcpmux.c
- */
-
-
-static int /* # of characters upto \r,\n or \0 */
-getline(fd, buf, len)
- int fd;
- char *buf;
- int len;
-{
- int count = 0, n;
- struct sigaction sa;
-
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = SIG_DFL;
- sigaction(SIGALRM, &sa, (struct sigaction *)0);
- do {
- alarm(10);
- n = read(fd, buf, len-count);
- alarm(0);
- if (n == 0)
- return (count);
- if (n < 0)
- return (-1);
- while (--n >= 0) {
- if (*buf == '\r' || *buf == '\n' || *buf == '\0')
- return (count);
- count++;
- buf++;
- }
- } while (count < len);
- return (count);
-}
-
-#define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */
-
-#define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1)
-
-struct servtab *
-tcpmux(s)
- int s;
-{
- struct servtab *sep;
- char service[MAX_SERV_LEN+1];
- int len;
-
- /* Get requested service name */
- if ((len = getline(s, service, MAX_SERV_LEN)) < 0) {
- strwrite(s, "-Error reading service name\r\n");
- return (NULL);
- }
- service[len] = '\0';
-
- if (debug)
- warnx("tcpmux: someone wants %s", service);
-
- /*
- * Help is a required command, and lists available services,
- * one per line.
- */
- if (!strcasecmp(service, "help")) {
- for (sep = servtab; sep; sep = sep->se_next) {
- if (!ISMUX(sep))
- continue;
- (void)write(s,sep->se_service,strlen(sep->se_service));
- strwrite(s, "\r\n");
- }
- return (NULL);
- }
-
- /* Try matching a service in inetd.conf with the request */
- for (sep = servtab; sep; sep = sep->se_next) {
- if (!ISMUX(sep))
- continue;
- if (!strcasecmp(service, sep->se_service)) {
- if (ISMUXPLUS(sep)) {
- strwrite(s, "+Go\r\n");
- }
- return (sep);
- }
- }
- strwrite(s, "-Service not available\r\n");
- return (NULL);
-}
-
#define CPMHSIZE 256
#define CPMHMASK (CPMHSIZE-1)
#define CHTGRAN 10