Retire MINIX tcpd(8)

Change-Id: If419d441c5df0b9f2e29db1ef0d904d102739f9b
This commit is contained in:
David van Moolenbroek 2017-02-14 18:24:20 +00:00
parent fd8826c892
commit b8046fb69b
18 changed files with 13 additions and 925 deletions

View File

@ -526,8 +526,8 @@
./usr/bin/sz minix-base
./usr/bin/tail minix-base
./usr/bin/tar minix-base
./usr/bin/tcpd minix-base
./usr/bin/tcpdp minix-base
./usr/bin/tcpd minix-base obsolete
./usr/bin/tcpdp minix-base obsolete
./usr/bin/tcpstat minix-base obsolete
./usr/bin/tee minix-base
./usr/bin/term minix-base

View File

@ -418,8 +418,8 @@
./usr/libdata/debug/usr/bin/synctree.debug minix-debug debug
./usr/libdata/debug/usr/bin/sz.debug minix-debug debug
./usr/libdata/debug/usr/bin/tail.debug minix-debug debug
./usr/libdata/debug/usr/bin/tcpd.debug minix-debug debug
./usr/libdata/debug/usr/bin/tcpdp.debug minix-debug debug
./usr/libdata/debug/usr/bin/tcpd.debug minix-debug debug,obsolete
./usr/libdata/debug/usr/bin/tcpdp.debug minix-debug debug,obsolete
./usr/libdata/debug/usr/bin/tcpstat.debug minix-debug debug,obsolete
./usr/libdata/debug/usr/bin/tee.debug minix-debug debug
./usr/libdata/debug/usr/bin/term.debug minix-debug debug

View File

@ -3306,7 +3306,7 @@
./usr/man/man5/resolv.conf.5 minix-man obsolete
./usr/man/man5/resolver.5 minix-man obsolete
./usr/man/man5/rhosts.5 minix-man
./usr/man/man5/serv.access.5 minix-man
./usr/man/man5/serv.access.5 minix-man obsolete
./usr/man/man5/statvfs.5 minix-man
./usr/man/man5/syslog.conf.5 minix-man
./usr/man/man5/system.conf.5 minix-man
@ -3461,7 +3461,7 @@
./usr/man/man8/sync.8 minix-man
./usr/man/man8/sysctl.8 minix-man
./usr/man/man8/syslogd.8 minix-man
./usr/man/man8/tcpd.8 minix-man
./usr/man/man8/tcpd.8 minix-man obsolete
./usr/man/man8/traceroute.8 minix-man
./usr/man/man8/uds.8 minix-man obsolete
./usr/man/man8/unix.8 minix-man

View File

@ -17,4 +17,5 @@ test -e /dev/bmp085b3s77 || (cd /dev && MAKEDEV bmp085b3s77)
/sbin/minix-service up /service/bmp085 -dev /dev/bmp085b3s77 \
-label bmp085.3.77 -args 'bus=3 address=0x77' && echo -n " bmp085"
daemonize tcpd http /usr/share/beaglebone/weather/weatherstation.lua
# FIXME: replace this with proper commands for inetd(8)
#daemonize tcpd http /usr/share/beaglebone/weather/weatherstation.lua

View File

@ -56,7 +56,6 @@ daemonize()
# Function to start a daemon, if it exists.
local IFS=':'
local name="$1"
test "$1" = tcpd && name="$2"
for dir in $PATH
do

View File

@ -9,7 +9,7 @@ CPPFLAGS.fslib.c+= -I${NETBSDSRCDIR}/minix/fs
CPPFLAGS.fsversion.c+= -I${NETBSDSRCDIR}/minix/fs
SRCS+= fsversion.c gcov.c itoa.c \
oneC_sum.c read_tsc_64.c servxcheck.c fslib.c
oneC_sum.c read_tsc_64.c fslib.c
.endif # defined(__MINIX)
.PATH: ${ARCHDIR}/gen ${.CURDIR}/gen

View File

@ -23,7 +23,7 @@ SUBDIR= arp at backup \
rotate setup \
slip spell sprofalyze sprofdiff srccrc \
svrctl swifi synctree sysenv \
tcpd tcpdp telnet \
telnet \
telnetd term termcap tget \
truncate umount \
update version vol \

View File

@ -1,5 +0,0 @@
PROG= tcpd
CPPFLAGS+= -DPARANOID=0
MAN= tcpd.8
.include <bsd.prog.mk>

View File

@ -1,127 +0,0 @@
.TH TCPD 8
.SH NAME
tcpd, tcpdp \- waits for a TCP connection request and starts a server
.SH SYNOPSIS
.B tcpd
.RB [ \-d ]
.RB [ \-m
.I maxclients
]
.I service
.I program
.RB [ arg ...
]
.SH DESCRIPTION
.de SP
.if t .sp 0.4
.if n .sp
..
.B Tcpd
is a daemon, that is, a user-space program that is normally started when the
operating system is started and that normally does not terminate until the
system is shut down.
Conceptually, you can think of
.B tcpd
as doing nothing but listening to a port for a connection attempt. Several
copies of
.B tcpd
will typically be started, one for each service that is to be provided.
When a connection is detected the tcpd for that port
.IR fork s
and then the child process
.IR exec s
an instance of the server for that port.
.P
The above description is simplified.
Normally two versions of the tcpd.c source code are compiled.
.B Tcpd
is the one that waits for a connection. When a connection occurs
.B tcpd
.IR fork s.
If
.B tcpd
was started with options or if the child detects that the access
control file
.IR /etc/serv.access
exists, the child will
.IR exec
its paranoid twin,
.B tcpdp,
which checks that the connection attempt is from an allowed node or network,
or that it is not from a disallowed node or network.
.B Tcpdp
also tries to look up the name corresponding to an IP address, and denies
the connection if a name cannot be found. Finally,
.B tcpdp
determines whether the connection is supposed to be logged.
If all is well, the child
.B tcpd
or
.B tcpdp
then
.IR exec s
the server for the service with any arguments specified on the command line
for that server.
.SH OPTIONS
.TP
.B \-d
turn on debugging.
.TP
.B \-m
allow no more than the specified
.IR maxclients
to start.
.SH EXAMPLES
.de EX
.TP 20
\\fB\\$1\\fR
# \\$2
..
.TP 20
.B tcpd telnet in.telnetd &
# wait for a telnet connection on the normal port
.TP 20
.B tcpd 8000 in.httpd /etc/httpd8000.conf &
# wait for web page request on port 8000 and use a custom config file for the in.httpd program.
.P
Note that command lines must be terminated with "&" to return control to the
calling process, leaving the daemon executing as a background process.
.P
The above examples show how tcpd might be invoked from /etc/rc or
another script that runs during system initialization. You will also
see this in the supplied startup scripts:
.TP 20
.B daemonize tcpd shell in.rshd
# daemonize is a shell function that tests whether a daemon is present and starts it if so, using the & to start it in the background.
.P
Another case that should be mentioned is that when a system administrator
wants to start (or restart) a daemon from a command line,
.BR intr (8)
should be used, like this:
.TP 20
.B intr -d tcpd telnet in.telnetd &
# remove the daemon from a process group and connect its input to /dev/null and its output to /dev/log.
.SH FILES
.TP 25n
.B /etc/serv.access
The access control file.
.SH "SEE ALSO"
.BR execve (2),
.BR fork (2),
.BR intr (8),
.BR serv.access (5).
.SH NOTES
That daemons cannot daemonize themselves is a way in which Minix differs from
most other Unix-like systems.
.P
Allowing access to your system from the net is dangerous. Be sure you
know what you are doing. Be sure the owner of your net knows what you are
doing. Don't enable services you don't need. Enable logging and look at your
logs.
.SH BUGS
None known, let us know...
.SH AUTHOR
Kees J. Bot <kjb@cs.vu.nl>
.P
Man page by Al Woodhull <asw@woodhull.com>
.\" rev 2006-06-02

View File

@ -1,315 +0,0 @@
/*
tcpd.c
*/
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <minix/config.h>
#include <minix/paths.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <net/hton.h>
#include <net/netlib.h>
#include <net/gen/in.h>
#include <net/gen/inet.h>
#include <netdb.h>
#include <net/gen/tcp.h>
#include <net/gen/tcp_io.h>
#include <arpa/inet.h>
#include <minix/minlib.h>
/* This program can be compiled to be paranoid, i.e. check incoming connection
* according to an access file, or to trust anyone. The much smaller "trust
* 'em" binary will call the paranoid version if the access file exists.
*/
static char *arg0, *service;
static unsigned nchildren;
static void report(const char *label)
{
int err= errno;
fprintf(stderr, "%s %s: %s: %s\n", arg0, service, label, strerror(err));
errno= err;
}
static void sigchld(int sig)
{
while (waitpid(-1, NULL, WNOHANG) > 0) {
if (nchildren > 0) nchildren--;
}
}
static void release(int *fd)
{
if (*fd != -1) {
close(*fd);
*fd= -1;
}
}
static void usage(void)
{
fprintf(stderr,
"Usage: %s [-d] [-m maxclients] service program [arg ...]\n",
arg0);
exit(1);
}
int main(int argc, char **argv)
{
tcpport_t port;
int last_failed = 0;
struct nwio_tcpcl tcplistenopt;
struct nwio_tcpconf tcpconf;
struct nwio_tcpopt tcpopt;
char *tcp_device;
struct servent *servent;
int tcp_fd, client_fd, r;
int pfd[2];
unsigned stall= 0;
struct sigaction sa;
sigset_t chldmask, chldunmask, oldmask;
char **progv;
#if !PARANOID
# define debug 0
# define max_children ((unsigned) -1)
arg0= argv[0];
/* Switch to the paranoid version of me if there are flags, or if
* there is an access file.
*/
if (argv[1][0] == '-' || access(_PATH_SERVACCES, F_OK) == 0) {
execv("/usr/bin/tcpdp", argv);
report("tcpdp");
exit(1);
}
if (argc < 3) usage();
service= argv[1];
progv= argv+2;
#else /* PARANOID */
int debug, i;
unsigned max_children;
arg0= argv[0];
debug= 0;
max_children= -1;
i= 1;
while (i < argc && argv[i][0] == '-') {
char *opt= argv[i++] + 1;
unsigned long m;
char *end;
if (*opt == '-' && opt[1] == 0) break; /* -- */
while (*opt != 0) switch (*opt++) {
case 'd':
debug= 1;
break;
case 'm':
if (*opt == 0) {
if (i == argc) usage();
opt= argv[i++];
}
m= strtoul(opt, &end, 10);
if (m <= 0 || m > UINT_MAX || *end != 0) usage();
max_children= m;
opt= "";
break;
default:
usage();
}
}
service= argv[i++];
progv= argv+i;
if (i >= argc) usage();
#endif
/* The interface to start the service on. */
if ((tcp_device= getenv("TCP_DEVICE")) == NULL) tcp_device= TCP_DEVICE;
/* Let SIGCHLD interrupt whatever I'm doing. */
sigemptyset(&chldmask);
sigaddset(&chldmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &chldmask, &oldmask);
chldunmask= oldmask;
sigdelset(&chldunmask, SIGCHLD);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sigchld;
sigaction(SIGCHLD, &sa, NULL);
/* Open a socket to the service I'm to serve. */
if ((servent= getservbyname(service, "tcp")) == NULL) {
unsigned long p;
char *end;
p= strtoul(service, &end, 0);
if (p <= 0 || p > 0xFFFF || *end != 0) {
fprintf(stderr, "%s: %s: Unknown service\n",
arg0, service);
exit(1);
}
port= htons((tcpport_t) p);
} else {
port= servent->s_port;
if (debug)
{
fprintf(stderr, "%s %s: listening to port %u\n",
arg0, service, ntohs(port));
}
}
/* No client yet. */
client_fd= -1;
while (1) {
if ((tcp_fd= open(tcp_device, O_RDWR)) < 0) {
report(tcp_device);
#if 0
if (errno == ENOENT || errno == ENODEV
|| errno == ENXIO) {
exit(1);
}
#endif
last_failed = 1;
goto bad;
}
if(last_failed)
fprintf(stderr, "%s %s: %s: Ok\n",
arg0, service, tcp_device);
last_failed = 0;
tcpconf.nwtc_flags= NWTC_LP_SET | NWTC_UNSET_RA | NWTC_UNSET_RP;
tcpconf.nwtc_locport= port;
if (ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf) < 0) {
report("Can't configure TCP channel");
exit(1);
}
tcpopt.nwto_flags= NWTO_DEL_RST;
if (ioctl(tcp_fd, NWIOSTCPOPT, &tcpopt) < 0) {
report("Can't set TCP options");
exit(1);
}
if (client_fd != -1) {
/* We have a client, so start a server for it. */
tcpopt.nwto_flags= 0;
(void) ioctl(client_fd, NWIOSTCPOPT, &tcpopt);
fflush(NULL);
/* Create a pipe to serve as an error indicator. */
if (pipe(pfd) < 0) {
report("pipe");
goto bad;
}
(void) fcntl(pfd[1], F_SETFD,
fcntl(pfd[1], F_GETFD) | FD_CLOEXEC);
/* Fork and exec. */
switch (fork()) {
case -1:
report("fork");
close(pfd[0]);
close(pfd[1]);
goto bad;
case 0:
close(tcp_fd);
close(pfd[0]);
#if PARANOID
/* Check if access to this service allowed. */
if (ioctl(client_fd, NWIOGTCPCONF, &tcpconf) == 0
&& tcpconf.nwtc_remaddr != tcpconf.nwtc_locaddr
&& !servxcheck(tcpconf.nwtc_remaddr, service, NULL)
) {
exit(1);
}
#endif
sigprocmask(SIG_SETMASK, &oldmask, NULL);
dup2(client_fd, 0);
dup2(client_fd, 1);
dup2(client_fd, 2);
close(client_fd);
execvp(progv[0], progv);
report(progv[0]);
write(pfd[1], &errno, sizeof(errno));
exit(1);
default:
nchildren++;
release(&client_fd);
close(pfd[1]);
r= read(pfd[0], &errno, sizeof(errno));
close(pfd[0]);
if (r != 0) goto bad;
break;
}
}
while (nchildren >= max_children) {
/* Too many clients, wait for one to die off. */
sigsuspend(&chldunmask);
}
/* Wait for a new connection. */
sigprocmask(SIG_UNBLOCK, &chldmask, NULL);
tcplistenopt.nwtcl_flags= 0;
while (ioctl(tcp_fd, NWIOTCPLISTEN, &tcplistenopt) < 0) {
if (errno != EINTR) {
if (errno != EAGAIN || debug) {
report("Unable to listen");
}
goto bad;
}
}
sigprocmask(SIG_BLOCK, &chldmask, NULL);
/* We got a connection. */
client_fd= tcp_fd;
tcp_fd= -1;
if (debug && ioctl(client_fd, NWIOGTCPCONF, &tcpconf) == 0) {
fprintf(stderr, "%s %s: Connection from %s:%u\n",
arg0, service,
inet_ntoa(*(struct in_addr *)&tcpconf.nwtc_remaddr),
ntohs(tcpconf.nwtc_remport));
}
/* All is well, no need to stall. */
stall= 0;
continue;
bad:
/* All is not well, release resources. */
release(&tcp_fd);
release(&client_fd);
/* Wait a bit if this happens more than once. */
if (stall != 0) {
if (debug) {
fprintf(stderr, "%s %s: stalling %u second%s\n",
arg0, service,
stall, stall == 1 ? "" : "s");
}
sleep(stall);
stall <<= 1;
} else {
stall= 1;
}
}
}

View File

@ -1,9 +0,0 @@
.include <bsd.own.mk>
PROG= tcpdp
.PATH: ${NETBSDSRCDIR}/minix/commands/tcpd
SRCS= tcpd.c
CPPFLAGS+= -DPARANOID=1
MAN=
.include <bsd.prog.mk>

View File

@ -12,8 +12,6 @@
#define _PATH_DRIVERS "/service"
#define _PATH_SERVACCES "/etc/serv.access"
#define _PATH_HOSTNAME_FILE "/etc/hostname.file"
#endif /* _MINIX_PATHS_H_ */

View File

@ -1,286 +0,0 @@
/* servxcheck() - Service access check. Author: Kees J. Bot
* 8 Jan 1997
*/
#define nil 0
#define ioctl _ioctl
#define open _open
#define write _write
#define close _close
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/ioctl.h>
#include <minix/paths.h>
#include <net/hton.h>
#include <net/gen/in.h>
#include <net/gen/tcp.h>
#include <net/gen/tcp_io.h>
#include <net/gen/inet.h>
#include <net/gen/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <minix/minlib.h>
/* Default service access file. */
static const char *path_servacces = _PATH_SERVACCES;
#define WLEN 256
static int getword(FILE *fp, char *word)
/* Read a word from the file open by 'fp', skip whitespace and comments.
* Colon and semicolon are returned as a one character "word". Returns
* word[0] or EOF.
*/
{
int c;
char *pw;
int wc;
wc= 0;
for (;;) {
if ((c= getc(fp)) == EOF) return EOF;
if (c == '#') { wc= 1; continue; }
if (c == '\n') { wc= 0; continue; }
if (wc) continue;
if (c <= ' ') continue;
break;
}
pw= word;
if (c == ':' || c == ';') {
*pw++ = c;
} else {
do {
if (pw < word + WLEN-1) *pw++ = c;
c= getc(fp);
} while (c != EOF && c > ' ' && c != ':' && c != ';');
if (c != EOF) ungetc(c, fp);
}
*pw= 0;
return word[0];
}
static int netspec(char *word, ipaddr_t *addr, ipaddr_t *mask)
/* Try to interpret 'word' as an network spec, e.g. 172.16.102.64/27. */
{
char *slash;
int r;
static char S32[]= "/32";
if (*word == 0) return 0;
if ((slash= strchr(word, '/')) == NULL) slash= S32;
*slash= 0;
r= inet_aton(word, (struct in_addr *)addr);
*slash++= '/';
if (!r) return 0;
r= 0;
while ((unsigned int)(*slash - '0') < 10u) {
r= 10*r + (*slash++ - '0');
if (r > 32) return 0;
}
if (*slash != 0 || slash[-1] == '/') return 0;
*mask= htonl(r == 0 ? 0L : (0xFFFFFFFFUL >> (32 - r)) << (32 - r));
return 1;
}
static int match(const char *word, const char *pattern)
/* Match word onto a pattern. Pattern may contain the * wildcard. */
{
unsigned cw, cp;
#define lc(c, d) ((((c)= (d)) - 'A') <= ('Z' - 'A') ? (c)+= ('a' - 'A') : 0)
for (;;) {
(void) lc(cw, *word);
(void) lc(cp, *pattern);
if (cp == '*') {
do pattern++; while (*pattern == '*');
(void) lc(cp, *pattern);
if (cp == 0) return 1;
while (cw != 0) {
if (cw == cp && match(word+1, pattern+1)) return 1;
word++;
(void) lc(cw, *word);
}
return 0;
} else
if (cw == 0 || cp == 0) {
return cw == cp;
} else
if (cw == cp) {
word++;
pattern++;
} else {
return 0;
}
}
#undef lc
}
static int get_name(ipaddr_t addr, char *name)
/* Do a reverse lookup on the remote IP address followed by a forward lookup
* to check if the host has that address. Return true if this is so, return
* either the true name or the ascii IP address in name[].
*/
{
struct hostent *he;
int i;
he= gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
if (he != NULL) {
strcpy(name, he->h_name);
he= gethostbyname(name);
if (he != NULL && he->h_addrtype == AF_INET) {
for (i= 0; he->h_addr_list[i] != NULL; i++) {
if (memcmp(he->h_addr_list[i], &addr, sizeof(addr)) == 0) {
strcpy(name, he->h_name);
return 1;
}
}
}
}
strcpy(name, inet_ntoa(*(struct in_addr *)&addr));
return 0;
}
/* "state" and "log" flags, made to be bitwise comparable. */
#define DEFFAIL 0x01
#define FAIL (0x02 | DEFFAIL)
#define PASS 0x04
int servxcheck(unsigned long peer, const char *service,
void (*logf)(int pass, const char *name))
{
FILE *fp;
char word[WLEN];
char name[WLEN];
int c;
int got_name, slist, seen, explicit, state, log;
ipaddr_t addr, mask;
/* Localhost? */
if ((peer & htonl(0xFF000000)) == htonl(0x7F000000)) return 1;
if ((fp= fopen(path_servacces, "r")) == nil) {
/* Succeed on error, fail if simply nonexistent. */
return (errno != ENOENT);
}
slist= 1; /* Services list (before the colon.) */
seen= 0; /* Given service not yet seen. */
explicit= 0; /* Service mentioned explicitly. */
got_name= -1; /* No reverse lookup done yet. */
log= FAIL; /* By default log failures only. */
state= DEFFAIL; /* Access denied until we know better. */
while ((c= getword(fp, word)) != EOF) {
if (c == ':') {
slist= 0; /* Switch to access list. */
} else
if (c == ';') {
slist= 1; /* Back to list of services. */
seen= 0;
} else
if (slist) {
/* Traverse services list. */
if (match(service, word)) {
/* Service has been spotted! */
if (match(word, service)) {
/* Service mentioned without wildcards. */
seen= explicit= 1;
} else {
/* Matched by a wildcard. */
if (!explicit) seen= 1;
}
}
} else {
/* Traverse access list. */
if (c == 'l' && strcmp(word, "log") == 0) {
if (seen) {
/* Log failures and successes. */
log= FAIL|PASS;
}
continue;
}
if (c != '-' && c != '+') {
if (logf == nil) {
syslog(LOG_ERR, "%s: strange check word '%s'\n",
path_servacces, word);
}
continue;
}
if (seen) {
if (state == DEFFAIL) {
/* First check determines the default. */
state= c == '+' ? FAIL : PASS;
}
if ((state == PASS) == (c == '+')) {
/* This check won't change state. */
} else
if (word[1] == 0) {
/* Lone + or - allows all or none. */
state= c == '-' ? FAIL : PASS;
} else
if (netspec(word+1, &addr, &mask)) {
/* Remote host is on the specified network? */
if (((peer ^ addr) & mask) == 0) {
state= c == '-' ? FAIL : PASS;
}
} else {
/* Name check. */
if (got_name == -1) {
got_name= get_name(peer, name);
}
/* Remote host name matches the word? */
if (!got_name) {
state= FAIL;
} else
if (match(name, word+1)) {
state= c == '-' ? FAIL : PASS;
}
}
}
}
}
fclose(fp);
if ((log & state) != 0) {
/* Log the result of the check. */
if (got_name == -1) (void) get_name(peer, name);
if (logf != nil) {
(*logf)(state == PASS, name);
} else {
syslog(LOG_NOTICE, "service '%s' %s to %s\n",
service, state == PASS ? "granted" : "denied", name);
}
}
return state == PASS;
}
const char *servxfile(const char *file)
/* Specify a file to use for the access checks other than the default. Return
* the old path.
*/
{
const char *oldpath= path_servacces;
path_servacces= file;
return oldpath;
}

View File

@ -1,6 +1,6 @@
MAN= boot.cfg.5 configfile.5 crontab.5 ethers.5 \
fstab.5 keymap.5 \
passwd.5 rhosts.5 statvfs.5 serv.access.5 \
passwd.5 rhosts.5 statvfs.5 \
termcap.5 ttytab.5 TZ.5 utmp.5 \
pkg_install.conf.5 pkg_summary.5

View File

@ -1,166 +0,0 @@
.TH SERV.ACCESS 5
.SH NAME
serv.access \- Internet service access list
.SH SYNOPSIS
.B /etc/serv.access
.SH DESCRIPTION
.de SP
.if t .sp 0.4
.if n .sp
..
The
.B serv.access
file contains a list of rules that guide the access checks made by the
.BR servxcheck (3)
function. The file is a text file containing entries that look as follows:
.PP
.RS
.I service1 service2
.RB ... :
.I check1 check2
.RB ... ;
.RE
.PP
Each of the service names is a service name from the
.B /etc/services
file. The same names are used in the
.B /etc/inetd.conf
configuration file that guides
.BR inetd (8).
.PP
The checks may look as follows:
.PP
.BI +
.br
.BI -
.RS
Allow all, or allow none. Used to explicitly set the initial state.
.RE
.PP
.BI + name
.RS
Grant access to one of the services if the host name of the remote system
matches
.BR name .
.RE
.SP
.BI \- name
.RS
Deny access to one of the services if the host name of the remote system
matches
.BR name .
.RE
.PP
.BI + ipaddr
.br
.BI \- ipaddr
.br
.BI + netaddr / len
.br
.BI \- netaddr / len
.RS
Grants or denies access to a remote host with IP address
.IR ipaddr ,
or the remote host whose IP address is within the network
.IR netaddr .
.I Len
tells the number of bits used for the network address, i.e. the top
.I len
bits of the network address must equal the host address.
.RE
.PP
.BR log
.RS
This is not a check, but a flag that instruct
.B servxcheck()
to log the result of the access check whether it succeeds or not to
.BR /usr/adm/log .
By default only failure is logged.
.RE
.PP
The first "+" or "\-" access check sets the tone. Read it as "access denied
unless +...", or "access granted unless \-...". An access check will
therefore almost always start with a "+" check. To make the initial state
clear you can start with a lone "+" or "\-". Checks are done from left
to right. A check that doesn't match does not change the outcome. A check
that can't change the outcome is skipped.
.PP
Both the service and the host names may contain the
.B "\(**"
wildcard that matches any number of characters including none. Letters are
compared ignoring case. A service name may appear in more than one rule,
but a service mentioned explicitly is not matched by wildcard patterns in
later rules.
.PP
A check for a hostname causes
.B servxcheck()
to do a reverse lookup on the IP address of the remote host to find its
name. This name is then looked up to find the host's IP address(es).
If those lookups fail then all
.BI \- name
checks cause access to be denied, and no
.BI + name
check grants access.
The DNS lookup failures may be a
misconfiguration, but could indicate a break-in attempt from a badly
maintained host. You can use a simple "+*" in an otherwise empty list to
just deny misconfigured hosts.
.PP
An IP or network address check is simply done on the remote hosts IP
address. Such a check has no overhead, but a
.B log
flag will cause a reverse lookup anyway.
.PP
Comments start with "#" and continue until end of line.
.SH EXAMPLES
Example access file on a machine that offers most services only to hosts within
the cs.vu.nl domain, and news (nntp) only to two machines and a specific
network.
.PP
.RS
.nf
.ta +2.2i +.4i
# Service # Access list
login shell: +*.cs.vu.nl log;
telnet pop smtp finger: + log;
nntp: +flotsam.cs.vu.nl +jetsam.cs.vu.nl
+172.16.102.0/24 log;
*: +*.cs.vu.nl;
.fi
.RE
.PP
More paranoid example that limits all services by default, but allows ftp and
http to the world:
.PP
.RS
.nf
.ta +2.2i +.4i
# Service # Access list
ftp http: +;
smtp finger: + log;
nntp: +flotsam.cs.vu.nl +jetsam.cs.vu.nl
+172.16.102.0/24 log;
*: +*.cs.vu.nl log;
.fi
.RE
.PP
(Note that the last rule doesn't match any of the services mentioned
explicitly earlier.)
.SH FILES
.TP 25n
.B /etc/serv.access
The service access check file.
.SH "SEE ALSO"
.BR servxcheck (3),
.BR services (5),
.BR inetd.conf (5).
.SH NOTES
It may be wise not to put checks on telnet. It is reasonably secure, since
it always requires a password, and your only way in if things are seriously
hosed.
.SH BUGS
IP and DNS based access checks will stop most crackers, but not the really
determined ones. Luckily MINIX 3 is sufficiently strange to thwart the well
known cracking schemes. But don't ever allow yourself to feel secure.
.SH AUTHOR
Kees J. Bot <kjb@cs.vu.nl>

View File

@ -55,8 +55,6 @@ System configuration and data files; see also \fB/usr/etc/\fP.
\fBrc\fP system startup script, \fBboot\fP(8)
\fBservices\fP
TCP/IP names to services
\fBserv.access\fP
internet service access control, \fBserv.access\fP(5)
\fBshadow\fP shadow password database, \fBpasswd\fP(5)
\fBtermcap\fP terminal type descriptions, \fBtermcap\fP(1)
\fBttytab\fP terminals device table, \fBttytab\fP(5)

View File

@ -6,7 +6,7 @@ NOOBJ= # defined
FILES= LICENSE README.txt jquery.js style.css weatherstation.js \
index.html processing.js spin.js weatherstation.lua
# weatherstation.lua is an executable script run under tcpd and needs BINMODE
# weatherstation.lua is an executable script run under inetd and needs BINMODE
FILESMODE_weatherstation.lua=${BINMODE}
FILESDIR=/usr/share/beaglebone/weather

View File

@ -1,6 +1,6 @@
#!/usr/bin/lua
--
-- weatherstation.lua - a simple web server intended to be run from tcpd to
-- weatherstation.lua - a simple web server intended to be run from inetd to
-- expose sensors from the BeagleBone Weather cape and serve the web app.
--