X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fmisc%2Ftcpwrapper.c;h=ceea5ce470607352bffe30d70618b04a2eb732a9;hp=498a8290ec3f20057dbaa7b1d599fd11c9df869b;hb=e47da19d63ea50a4e15f6ab491535d54097744de;hpb=764e46f5c5fe1a6e376f4cd350424f33afc9e838 diff --git a/support/misc/tcpwrapper.c b/support/misc/tcpwrapper.c index 498a829..ceea5ce 100644 --- a/support/misc/tcpwrapper.c +++ b/support/misc/tcpwrapper.c @@ -25,16 +25,16 @@ * authorized by the /etc/hosts.{allow,deny} files. The local system is * always treated as an authorized host. The access control tables are never * consulted for requests from the local system, and are always consulted - * for requests from other hosts. Access control is based on IP addresses - * only; attempts to map an address to a host name might cause the - * portmapper to hang. + * for requests from other hosts. * * Author: Wietse Venema (wietse@wzv.win.tue.nl), dept. of Mathematics and * Computing Science, Eindhoven University of Technology, The Netherlands. */ -#include "tcpwrapper.h" - +#ifdef HAVE_CONFIG_H +#include +#endif +#include #include #include #include @@ -49,16 +49,24 @@ #include #endif -static void logit(); -static void toggle_verboselog(); +static void logit(int severity, struct sockaddr_in *addr, + u_long procnum, u_long prognum, char *text); +static void toggle_verboselog(int sig); int verboselog = 0; int allow_severity = LOG_INFO; int deny_severity = LOG_WARNING; /* A handful of macros for "readability". */ +#ifdef HAVE_LIBWRAP /* coming from libwrap.a (tcp_wrappers) */ extern int hosts_ctl(char *daemon, char *name, char *addr, char *user); +#else +int hosts_ctl(char *daemon, char *name, char *addr, char *user) +{ + return 0; +} +#endif #define legal_port(a,p) \ (ntohs((a)->sin_port) < IPPORT_RESERVED || (p) >= IPPORT_RESERVED) @@ -78,6 +86,9 @@ extern int hosts_ctl(char *daemon, char *name, char *addr, char *user); #define log_client(addr, proc, prog) \ logit(allow_severity, addr, proc, prog, "") +#define ALLOW 1 +#define DENY 0 + int good_client(daemon, addr) char *daemon; @@ -87,52 +98,49 @@ struct sockaddr_in *addr; char **sp; char *tmpname; - /* Check the IP address first. */ - if (hosts_ctl(daemon, "", inet_ntoa(addr->sin_addr), "")) - return 1; - - /* Check the hostname. */ - hp = gethostbyaddr ((const char *) &(addr->sin_addr), - sizeof (addr->sin_addr), AF_INET); - - if (!hp) - return 0; - - /* must make sure the hostent is authorative. */ - tmpname = alloca (strlen (hp->h_name) + 1); - strcpy (tmpname, hp->h_name); - hp = gethostbyname(tmpname); - if (hp) { - /* now make sure the "addr->sin_addr" is on the list */ + /* First check the address. */ + if (hosts_ctl(daemon, "", inet_ntoa(addr->sin_addr), "") == DENY) + return DENY; + + /* Now do the hostname lookup */ + hp = gethostbyaddr ((const char *) &(addr->sin_addr), + sizeof (addr->sin_addr), AF_INET); + if (!hp) + return DENY; /* never heard of it. misconfigured DNS? */ + + /* Make sure the hostent is authorative. */ + tmpname = strdup(hp->h_name); + if (!tmpname) + return DENY; + hp = gethostbyname(tmpname); + free(tmpname); + if (!hp) + return DENY; /* never heard of it. misconfigured DNS? */ + + /* Now make sure the address is on the list */ for (sp = hp->h_addr_list ; *sp ; sp++) { - if (memcmp(*sp, &(addr->sin_addr), hp->h_length)==0) - break; + if (memcmp(*sp, &(addr->sin_addr), hp->h_length) == 0) + break; } if (!*sp) - /* it was a FAKE. */ - return 0; - } - else - /* never heard of it. misconfigured DNS? */ - return 0; - - /* Check the official name first. */ - if (hosts_ctl(daemon, "", hp->h_name, "")) - return 1; - - /* Check aliases. */ - for (sp = hp->h_aliases; *sp ; sp++) { - if (hosts_ctl(daemon, "", *sp, "")) - return 1; - } - - /* No match */ - return 0; + return DENY; /* it was a FAKE. */ + + /* Check the official name and address. */ + if (hosts_ctl(daemon, hp->h_name, inet_ntoa(addr->sin_addr), "") == DENY) + return DENY; + + /* Now check aliases. */ + for (sp = hp->h_aliases; *sp ; sp++) { + if (hosts_ctl(daemon, *sp, inet_ntoa(addr->sin_addr), "") == DENY) + return DENY; + } + + return ALLOW; } /* check_startup - additional startup code */ -void check_startup() +void check_startup(void) { /* @@ -176,22 +184,20 @@ struct sockaddr_in *addr; u_long proc; u_long prog; { - if (!(from_local(addr) || good_client(daemon, addr))) { - log_bad_host(addr, proc, prog); - return (FALSE); - } - if (verboselog) - log_client(addr, proc, prog); + if (!(from_local(addr) || good_client(daemon, addr))) { + log_bad_host(addr, proc, prog); + return (FALSE); + } + if (verboselog) + log_client(addr, proc, prog); + return (TRUE); } /* check_privileged_port - additional checks for privileged-port updates */ int -check_privileged_port(addr, proc, prog, port) -struct sockaddr_in *addr; -u_long proc; -u_long prog; -u_long port; +check_privileged_port(struct sockaddr_in *addr, + u_long proc, u_long prog, u_long port) { #ifdef CHECK_PORT if (!legal_port(addr, port)) { @@ -204,8 +210,7 @@ u_long port; /* toggle_verboselog - toggle verbose logging flag */ -static void toggle_verboselog(sig) -int sig; +static void toggle_verboselog(int sig) { (void) signal(sig, toggle_verboselog); verboselog = !verboselog; @@ -213,22 +218,20 @@ int sig; /* logit - report events of interest via the syslog daemon */ -static void logit(severity, addr, procnum, prognum, text) -int severity; -struct sockaddr_in *addr; -u_long procnum; -u_long prognum; -char *text; +static void logit(int severity, struct sockaddr_in *addr, + u_long procnum, u_long prognum, char *text) { char *procname; - char procbuf[4 * sizeof(u_long)]; + char procbuf[16 + 4 * sizeof(u_long)]; char *progname; - char progbuf[4 * sizeof(u_long)]; + char progbuf[16 + 4 * sizeof(u_long)]; struct rpcent *rpc; /* * Fork off a process or the portmap daemon might hang while * getrpcbynumber() or syslog() does its thing. + * + * Don't forget to wait for the children, too... */ if (fork() == 0) { @@ -240,16 +243,18 @@ char *text; } else if ((rpc = getrpcbynumber((int) prognum))) { progname = rpc->r_name; } else { - sprintf(progname = progbuf, "%lu", prognum); + snprintf(progname = progbuf, sizeof (progbuf), + "prog (%lu)", prognum); } /* Try to map procedure number to name. */ - sprintf(procname = procbuf, "%lu", (u_long) procnum); + snprintf(procname = procbuf, sizeof (procbuf), + "proc (%lu)", (u_long) procnum); /* Write syslog record. */ - syslog(severity, "connect from %s to %s(%s)%s", + syslog(severity, "connect from %s to %s in %s%s", inet_ntoa(addr->sin_addr), procname, progname, text); exit(0); }