From ca5a1dab1d51e6d2c47cf77f23274fcb51b8647d Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Sat, 31 Jan 2009 11:42:01 +0000 Subject: [PATCH] - Reworked tcp wrapper code to correctly use API (bz 480223) - General clean up of tcp wrapper code. --- nfs-utils-1.1.4-tcpwrap-cleanup.patch | 194 ++++++++++++++++++++++++ nfs-utils-1.1.4-tcpwrap-hash.patch | 89 +++++++++++ nfs-utils-1.1.4-tcpwrap-newrules.patch | 106 +++++++++++++ nfs-utils-1.1.4-tcpwrap-rulecheck.patch | 100 ------------ nfs-utils.spec | 14 +- 5 files changed, 400 insertions(+), 103 deletions(-) create mode 100644 nfs-utils-1.1.4-tcpwrap-cleanup.patch create mode 100644 nfs-utils-1.1.4-tcpwrap-hash.patch create mode 100644 nfs-utils-1.1.4-tcpwrap-newrules.patch delete mode 100644 nfs-utils-1.1.4-tcpwrap-rulecheck.patch diff --git a/nfs-utils-1.1.4-tcpwrap-cleanup.patch b/nfs-utils-1.1.4-tcpwrap-cleanup.patch new file mode 100644 index 0000000..187da42 --- /dev/null +++ b/nfs-utils-1.1.4-tcpwrap-cleanup.patch @@ -0,0 +1,194 @@ +Author: Steve Dickson +Date: Sat Jan 31 06:17:18 2009 -0500 + + General clean up. Removed unused routines. Reworked syslog + message to (hopefully) make it more sensible. Move + "#ifdef HAVE_LIBWRAP" around so nothing will be defined + when tcp wrapper is not configured. + + Signed-off-by: Steve Dickson + +diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c +--- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-31 06:27:54.000000000 -0500 ++++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-31 06:31:32.000000000 -0500 +@@ -34,6 +34,7 @@ + #ifdef HAVE_CONFIG_H + #include + #endif ++#ifdef HAVE_LIBWRAP + #include + #include + #include +@@ -57,40 +58,10 @@ + + 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) +- +-#define log_bad_port(addr, proc, prog) \ +- logit(deny_severity, addr, proc, prog, ": request from unprivileged port") ++static int check_files(void); + + #define log_bad_host(addr, proc, prog) \ +- logit(deny_severity, addr, proc, prog, ": request from unauthorized host") +- +-#define log_bad_owner(addr, proc, prog) \ +- logit(deny_severity, addr, proc, prog, ": request from non-local host") +- +-#define log_no_forward(addr, proc, prog) \ +- logit(deny_severity, addr, proc, prog, ": request not forwarded") +- +-#define log_client(addr, proc, prog) \ +- logit(allow_severity, addr, proc, prog, "") ++ logit(LOG_WARNING, addr, proc, prog, "request from unauthorized host") + + #define ALLOW 1 + #define DENY 0 +@@ -180,46 +151,9 @@ struct sockaddr_in *addr; + return DENY; + } + +-/* check_startup - additional startup code */ +- +-void check_startup(void) +-{ +- +- /* +- * Give up root privileges so that we can never allocate a privileged +- * port when forwarding an rpc request. +- * +- * Fix 8/3/00 Philipp Knirsch: First lookup our rpc user. If we find it, +- * switch to that uid, otherwise simply resue the old bin user and print +- * out a warning in syslog. +- */ +- +- struct passwd *pwent; +- +- pwent = getpwnam("rpc"); +- if (pwent == NULL) { +- syslog(LOG_WARNING, "user rpc not found, reverting to user bin"); +- if (setuid(1) == -1) { +- syslog(LOG_ERR, "setuid(1) failed: %m"); +- exit(1); +- } +- } +- else { +- if (setuid(pwent->pw_uid) == -1) { +- syslog(LOG_WARNING, "setuid() to rpc user failed: %m"); +- if (setuid(1) == -1) { +- syslog(LOG_ERR, "setuid(1) failed: %m"); +- exit(1); +- } +- } +- } +- +- (void) signal(SIGINT, toggle_verboselog); +-} +- + /* check_files - check to see if either access files have changed */ + +-int check_files() ++static int check_files() + { + static time_t allow_mtime, deny_mtime; + struct stat astat, dstat; +@@ -268,78 +202,21 @@ u_long prog; + haccess_add(addr, prog, FALSE); + return (FALSE); + } +- if (verboselog) +- log_client(addr, proc, prog); + + if (acc) + acc->access = TRUE; + else + haccess_add(addr, prog, TRUE); +- return (TRUE); +-} + +-/* check_privileged_port - additional checks for privileged-port updates */ +-int +-check_privileged_port(struct sockaddr_in *addr, +- u_long proc, u_long prog, u_long port) +-{ +-#ifdef CHECK_PORT +- if (!legal_port(addr, port)) { +- log_bad_port(addr, proc, prog); +- return (FALSE); +- } +-#endif + return (TRUE); + } + +-/* toggle_verboselog - toggle verbose logging flag */ +- +-static void toggle_verboselog(int sig) +-{ +- (void) signal(sig, toggle_verboselog); +- verboselog = !verboselog; +-} +- + /* logit - report events of interest via the syslog daemon */ + + static void logit(int severity, struct sockaddr_in *addr, + u_long procnum, u_long prognum, char *text) + { +- char *procname; +- char procbuf[16 + 4 * sizeof(u_long)]; +- char *progname; +- 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) { +- +- /* Try to map program number to name. */ +- +- if (prognum == 0) { +- progname = ""; +- } else if ((rpc = getrpcbynumber((int) prognum))) { +- progname = rpc->r_name; +- } else { +- snprintf(progname = progbuf, sizeof (progbuf), +- "prog (%lu)", prognum); +- } +- +- /* Try to map procedure number to name. */ +- +- snprintf(procname = procbuf, sizeof (procbuf), +- "proc (%lu)", (u_long) procnum); +- +- /* Write syslog record. */ +- +- syslog(severity, "connect from %s to %s in %s%s", +- inet_ntoa(addr->sin_addr), procname, progname, text); +- exit(0); +- } ++ syslog(severity, "connect from %s denied: %s", ++ inet_ntoa(addr->sin_addr), text); + } ++#endif diff --git a/nfs-utils-1.1.4-tcpwrap-hash.patch b/nfs-utils-1.1.4-tcpwrap-hash.patch new file mode 100644 index 0000000..fd6abb5 --- /dev/null +++ b/nfs-utils-1.1.4-tcpwrap-hash.patch @@ -0,0 +1,89 @@ +Author: Steve Dickson +Date: Sat Jan 31 05:30:13 2009 -0500 + + Only hash on IP address and Program number. Including the Procedure + number only creates needles extra hash entries. + + Signed-off-by: Steve Dickson + +diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c +--- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-31 06:22:35.000000000 -0500 ++++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-31 06:23:22.000000000 -0500 +@@ -106,8 +106,8 @@ typedef struct _hash_head { + TAILQ_HEAD(host_list, _haccess_t) h_head; + } hash_head; + hash_head haccess_tbl[HASH_TABLE_SIZE]; +-static haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long, u_long); +-static void haccess_add(struct sockaddr_in *addr, u_long, u_long, int); ++static haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long); ++static void haccess_add(struct sockaddr_in *addr, u_long, int); + + inline unsigned int strtoint(char *str) + { +@@ -124,11 +124,10 @@ inline int hashint(unsigned int num) + { + return num % HASH_TABLE_SIZE; + } +-#define HASH(_addr, _proc, _prog) \ +- hashint((strtoint((_addr))+(_proc)+(_prog))) ++#define HASH(_addr, _prog) \ ++ hashint((strtoint((_addr))+(_prog))) + +-void haccess_add(struct sockaddr_in *addr, u_long proc, +- u_long prog, int access) ++void haccess_add(struct sockaddr_in *addr, u_long prog, int access) + { + hash_head *head; + haccess_t *hptr; +@@ -138,7 +137,7 @@ void haccess_add(struct sockaddr_in *add + if (hptr == NULL) + return; + +- hash = HASH(inet_ntoa(addr->sin_addr), proc, prog); ++ hash = HASH(inet_ntoa(addr->sin_addr), prog); + head = &(haccess_tbl[hash]); + + hptr->access = access; +@@ -149,13 +148,13 @@ void haccess_add(struct sockaddr_in *add + else + TAILQ_INSERT_TAIL(&head->h_head, hptr, list); + } +-haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long proc, u_long prog) ++haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long prog) + { + hash_head *head; + haccess_t *hptr; + int hash; + +- hash = HASH(inet_ntoa(addr->sin_addr), proc, prog); ++ hash = HASH(inet_ntoa(addr->sin_addr), prog); + head = &(haccess_tbl[hash]); + + TAILQ_FOREACH(hptr, &head->h_head, list) { +@@ -300,7 +299,7 @@ u_long prog; + haccess_t *acc = NULL; + int changed = check_files(); + +- acc = haccess_lookup(addr, proc, prog); ++ acc = haccess_lookup(addr, prog); + if (acc && changed == 0) + return (acc->access); + +@@ -309,7 +308,7 @@ u_long prog; + if (acc) + acc->access = FALSE; + else +- haccess_add(addr, proc, prog, FALSE); ++ haccess_add(addr, prog, FALSE); + return (FALSE); + } + if (verboselog) +@@ -318,7 +317,7 @@ u_long prog; + if (acc) + acc->access = TRUE; + else +- haccess_add(addr, proc, prog, TRUE); ++ haccess_add(addr, prog, TRUE); + return (TRUE); + } + diff --git a/nfs-utils-1.1.4-tcpwrap-newrules.patch b/nfs-utils-1.1.4-tcpwrap-newrules.patch new file mode 100644 index 0000000..41de945 --- /dev/null +++ b/nfs-utils-1.1.4-tcpwrap-newrules.patch @@ -0,0 +1,106 @@ +Author: Steve Dickson +Date: Sat Jan 31 05:50:51 2009 -0500 + + Converted good_client() to correctly use the tcp wrapper + interface and added a note to the mountd man page saying + hostnames will be ignored when they can not be looked up. + + Signed-off-by: Steve Dickson + +diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c +--- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-31 06:25:16.000000000 -0500 ++++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-31 06:26:27.000000000 -0500 +@@ -46,7 +46,7 @@ + #include + #include + #include +-#include ++#include + + #include "xlog.h" + +@@ -169,58 +169,15 @@ good_client(daemon, addr) + char *daemon; + struct sockaddr_in *addr; + { +- struct hostent *hp; +- char **sp; +- char *tmpname; +- +- /* 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) { +- xlog(L_WARNING, +- "Warning: Client IP address '%s' not found in host lookup", +- inet_ntoa(addr->sin_addr)); +- return DENY; /* never heard of it. misconfigured DNS? */ +- } +- +- /* Make sure the hostent is authorative. */ +- tmpname = strdup(hp->h_name); +- if (!tmpname) { +- xlog(L_WARNING, "Warning: No memory for Host access check"); +- return DENY; +- } +- hp = gethostbyname(tmpname); +- if (!hp) { +- xlog(L_WARNING, +- "Warning: Client hostname '%s' not found in host lookup", tmpname); +- free(tmpname); +- return DENY; /* never heard of it. misconfigured DNS? */ +- } +- free(tmpname); ++ struct request_info req; + +- /* 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 (!*sp) +- return DENY; /* it was a FAKE. */ ++ request_init(&req, RQ_DAEMON, daemon, RQ_CLIENT_SIN, addr, 0); ++ sock_methods(&req); + +- /* 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; +- } ++ if (hosts_access(&req)) ++ return ALLOW; + +- return ALLOW; ++ return DENY; + } + + /* check_startup - additional startup code */ +diff -up nfs-utils-1.1.4/utils/mountd/mountd.man.orig nfs-utils-1.1.4/utils/mountd/mountd.man +--- nfs-utils-1.1.4/utils/mountd/mountd.man.orig 2008-10-17 10:20:09.000000000 -0400 ++++ nfs-utils-1.1.4/utils/mountd/mountd.man 2009-01-31 06:26:27.000000000 -0500 +@@ -181,13 +181,15 @@ mountd: .bar.com + You have to use the daemon name + .B mountd + for the daemon name (even if the binary has a different name). ++.B Note: ++hostnames used in either access file will be ignored when ++they can not be resolved into IP addresses. + + For further information please have a look at the + .BR tcpd (8) + and + .BR hosts_access (5) + manual pages. +- + .SH SEE ALSO + .BR rpc.nfsd (8), + .BR exportfs (8), diff --git a/nfs-utils-1.1.4-tcpwrap-rulecheck.patch b/nfs-utils-1.1.4-tcpwrap-rulecheck.patch deleted file mode 100644 index 1a19cbf..0000000 --- a/nfs-utils-1.1.4-tcpwrap-rulecheck.patch +++ /dev/null @@ -1,100 +0,0 @@ -commit 5f09a2bacb4bf0a906e2d19931568b91fb6c5088 -Author: Steve Dickson -Date: Tue Jan 20 06:16:56 2009 -0500 - - mountd: Don't do tcp wrapper check when there are no rules - - If there are no rules in either /etc/hosts.deny or - /etc/hosts.allow there is no need to do the host validation. - - Signed-off-by: Steve Dickson - -diff -up nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig nfs-utils-1.1.4/support/misc/tcpwrapper.c ---- nfs-utils-1.1.4/support/misc/tcpwrapper.c.orig 2009-01-07 12:56:07.000000000 -0500 -+++ nfs-utils-1.1.4/support/misc/tcpwrapper.c 2009-01-20 06:00:38.000000000 -0500 -@@ -34,6 +34,7 @@ - #ifdef HAVE_CONFIG_H - #include - #endif -+#include - #include - #include - #include -@@ -55,6 +56,8 @@ - #include - #endif - -+static int check_files(void); -+static int check_rules(void); - static void logit(int severity, struct sockaddr_in *addr, - u_long procnum, u_long prognum, char *text); - static void toggle_verboselog(int sig); -@@ -261,8 +264,40 @@ void check_startup(void) - (void) signal(SIGINT, toggle_verboselog); - } - --/* check_files - check to see if either access files have changed */ -+/* -+ * check_rules - check to see if any entries exist in -+ * either hosts file. -+ */ -+int check_rules() -+{ -+ FILE *fp; -+ char buf[BUFSIZ]; -+ -+ if ((fp = fopen("/etc/hosts.allow", "r")) == NULL) -+ return 0; -+ -+ while (fgets(buf, BUFSIZ, fp) != NULL) { -+ if (buf[0] == '#') -+ continue; -+ fclose(fp); -+ return 1; -+ } -+ fclose(fp); -+ -+ if ((fp = fopen("/etc/hosts.deny", "r")) == NULL) -+ return 0; -+ -+ while (fgets(buf, BUFSIZ, fp) != NULL) { -+ if (buf[0] == '#') -+ continue; -+ fclose(fp); -+ return 1; -+ } -+ fclose(fp); -+ return 0; -+} - -+/* check_files - check to see if either access files have changed */ - int check_files() - { - static time_t allow_mtime, deny_mtime; -@@ -304,6 +339,13 @@ u_long prog; - if (acc && changed == 0) - return (acc->access); - -+ /* -+ * See if there are any rules to be applied, -+ * if not, no need to check the address -+ */ -+ if (check_rules() == 0) -+ goto done; -+ - if (!(from_local(addr) || good_client(daemon, addr))) { - log_bad_host(addr, proc, prog); - if (acc) -@@ -315,10 +357,12 @@ u_long prog; - if (verboselog) - log_client(addr, proc, prog); - -+done: - if (acc) - acc->access = TRUE; - else - haccess_add(addr, proc, prog, TRUE); -+ - return (TRUE); - } - diff --git a/nfs-utils.spec b/nfs-utils.spec index 0c64105..c1e58b7 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser Name: nfs-utils URL: http://sourceforge.net/projects/nfs Version: 1.1.4 -Release: 14%{?dist} +Release: 15%{?dist} Epoch: 1 # group all 32bit related archs @@ -44,8 +44,10 @@ Patch114: nfs-utils-1.1.4-gssd-verbosity.patch Patch115: nfs-utils-1.1.4-mount-addrconfig.patch Patch116: nfs-utils-1.1.4-configure-uuid.patch Patch117: nfs-utils-1.1.4-configure-tirpc.patch -Patch118: nfs-utils-1.1.4-tcpwrap-rulecheck.patch -Patch119: nfs-utils-1.1.4-mount-textbased.patch +Patch118: nfs-utils-1.1.4-tcpwrap-hash.patch +Patch119: nfs-utils-1.1.4-tcpwrap-newrules.patch +Patch120: nfs-utils-1.1.4-tcpwrap-cleanup.patch +Patch121: nfs-utils-1.1.4-mount-textbased.patch %if %{enablefscache} Patch90: nfs-utils-1.1.0-mount-fsc.patch @@ -120,6 +122,8 @@ This package also contains the mount.nfs and umount.nfs program. %patch117 -p1 %patch118 -p1 %patch119 -p1 +%patch120 -p1 +%patch121 -p1 %if %{enablefscache} %patch90 -p1 @@ -283,6 +287,10 @@ fi %attr(4755,root,root) /sbin/umount.nfs4 %changelog +* Sat Jan 31 2009 Steve Dickson 1.1.4-15 +- Reworked tcp wrapper code to correctly use API (bz 480223) +- General clean up of tcp wrapper code. + * Tue Jan 27 2009 Steve Dickson 1.1.4-14 - text-based mount command: make po_rightmost() work for N options - text-based mount command: Function to stuff "struct pmap" from mount options