diff --git a/contrib/tcp_wrappers/hosts_access.5 b/contrib/tcp_wrappers/hosts_access.5 index 5fe1f2969b8c..49a6bf71d314 100644 --- a/contrib/tcp_wrappers/hosts_access.5 +++ b/contrib/tcp_wrappers/hosts_access.5 @@ -89,6 +89,13 @@ An expression of the form `n.n.n.n/m.m.m.m\' is interpreted as a bitwise AND of the address and the `mask\'. For example, the net/mask pattern `131.155.72.0/255.255.254.0\' matches every address in the range `131.155.72.0\' through `131.155.73.255\'. +.IP \(bu +A string that begins with a `/\' character is treated as a file +name. A host name or address is matched if it matches any host name +or address pattern listed in the named file. The file format is +zero or more lines with zero or more host name or address patterns +separated by whitespace. A file name pattern can be used anywhere +a host name or address pattern can be used. .SH WILDCARDS The access control language supports explicit wildcards: .IP ALL @@ -326,7 +333,7 @@ in.tftpd: ALL: (/some/where/safe_finger -l @%h | \\ /usr/ucb/mail -s %d-%h root) & .fi .PP -The safe_finger command comes with the tcpd wrapper and should be +The safe_finger command is intended for use in back-fingering and should be installed in a suitable place. It limits possible damage from data sent by the remote finger server. It gives better protection than the standard finger command. @@ -350,6 +357,12 @@ capacity of an internal buffer; when an access control rule is not terminated by a newline character; when the result of % expansion would overflow an internal buffer; when a system call fails that shouldn\'t. All problems are reported via the syslog daemon. +.SH IMPLEMENTATION NOTES +Some operating systems are distributed with TCP Wrappers as part of the +base system. It is common for such systems to build wrapping functionality +into networking utilities. Notably, some systems offer an \fIinetd\fR(8) +which does not require the use of the \fItcpd\fR(8). Check your system's +documentation for details. .SH FILES .na .nf @@ -376,3 +389,4 @@ Eindhoven University of Technology Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands \" @(#) hosts_access.5 1.20 95/01/30 19:51:46 +\" $FreeBSD$ diff --git a/contrib/tcp_wrappers/hosts_access.c b/contrib/tcp_wrappers/hosts_access.c index 9bdc7bcd66e9..27dd81db4565 100644 --- a/contrib/tcp_wrappers/hosts_access.c +++ b/contrib/tcp_wrappers/hosts_access.c @@ -15,6 +15,8 @@ * Compile with -DNETGROUP if your library provides support for netgroups. * * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + * + * $FreeBSD$ */ #ifndef lint @@ -240,6 +242,26 @@ struct request_info *request; } } +/* hostfile_match - look up host patterns from file */ + +static int hostfile_match(path, host) +char *path; +struct hosts_info *host; +{ + char tok[BUFSIZ]; + int match = NO; + FILE *fp; + + if ((fp = fopen(path, "r")) != 0) { + while (fscanf(fp, "%s", tok) == 1 && !(match = host_match(tok, host))) + /* void */ ; + fclose(fp); + } else if (errno != ENOENT) { + tcpd_warn("open %s: %m", path); + } + return (match); +} + /* host_match - match host name and/or address against pattern */ static int host_match(tok, host) @@ -267,6 +289,8 @@ struct host_info *host; tcpd_warn("netgroup support is disabled"); /* not tcpd_jump() */ return (NO); #endif + } else if (tok[0] == '/') { /* /file hack */ + return (hostfile_match(tok, host)); } else if (STR_EQ(tok, "KNOWN")) { /* check address and name */ char *name = eval_hostname(host); return (STR_NE(eval_hostaddr(host), unknown) && HOSTNAME_KNOWN(name)); diff --git a/contrib/tcp_wrappers/tcpdchk.c b/contrib/tcp_wrappers/tcpdchk.c index 49c5c82c1b44..6a317d9a84aa 100644 --- a/contrib/tcp_wrappers/tcpdchk.c +++ b/contrib/tcp_wrappers/tcpdchk.c @@ -12,6 +12,8 @@ * -v: show all rules. * * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + * + * $FreeBSD$ */ #ifndef lint @@ -350,6 +352,8 @@ char *pat; { if (pat[0] == '@') { tcpd_warn("%s: daemon name begins with \"@\"", pat); + } else if (pat[0] == '/') { + tcpd_warn("%s: daemon name begins with \"/\"", pat); } else if (pat[0] == '.') { tcpd_warn("%s: daemon name begins with dot", pat); } else if (pat[strlen(pat) - 1] == '.') { @@ -382,6 +386,8 @@ char *pat; { if (pat[0] == '@') { /* @netgroup */ tcpd_warn("%s: user name begins with \"@\"", pat); + } else if (pat[0] == '/') { + tcpd_warn("%s: user name begins with \"/\"", pat); } else if (pat[0] == '.') { tcpd_warn("%s: user name begins with dot", pat); } else if (pat[strlen(pat) - 1] == '.') { @@ -402,8 +408,13 @@ char *pat; static int check_host(pat) char *pat; { + char buf[BUFSIZ]; char *mask; int addr_count = 1; + FILE *fp; + struct tcpd_context saved_context; + char *cp; + char *wsp = " \t\r\n"; if (pat[0] == '@') { /* @netgroup */ #ifdef NO_NETGRENT @@ -422,6 +433,21 @@ char *pat; tcpd_warn("netgroup support disabled"); #endif #endif + } else if (pat[0] == '/') { /* /path/name */ + if ((fp = fopen(pat, "r")) != 0) { + saved_context = tcpd_context; + tcpd_context.file = pat; + tcpd_context.line = 0; + while (fgets(buf, sizeof(buf), fp)) { + tcpd_context.line++; + for (cp = strtok(buf, wsp); cp; cp = strtok((char *) 0, wsp)) + check_host(cp); + } + tcpd_context = saved_context; + fclose(fp); + } else if (errno != ENOENT) { + tcpd_warn("open %s: %m", pat); + } } else if (mask = split_at(pat, '/')) { /* network/netmask */ if (dot_quad_addr(pat) == INADDR_NONE || dot_quad_addr(mask) == INADDR_NONE)