- Reworked tcp wrapper code to correctly use API (bz 480223)

- General clean up of tcp wrapper code.
This commit is contained in:
Steve Dickson 2009-01-31 11:42:01 +00:00
parent e237fe4711
commit ca5a1dab1d
5 changed files with 400 additions and 103 deletions

View File

@ -0,0 +1,194 @@
Author: Steve Dickson <steved@redhat.com>
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 <steved@redhat.com>
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 <config.h>
#endif
+#ifdef HAVE_LIBWRAP
#include <tcpwrapper.h>
#include <unistd.h>
#include <string.h>
@@ -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

View File

@ -0,0 +1,89 @@
Author: Steve Dickson <steved@redhat.com>
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 <steved@redhat.com>
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);
}

View File

@ -0,0 +1,106 @@
Author: Steve Dickson <steved@redhat.com>
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 <steved@redhat.com>
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 <sys/signal.h>
#include <sys/queue.h>
#include <sys/stat.h>
-#include <unistd.h>
+#include <tcpd.h>
#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),

View File

@ -1,100 +0,0 @@
commit 5f09a2bacb4bf0a906e2d19931568b91fb6c5088
Author: Steve Dickson <steved@redhat.com>
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 <steved@redhat.com>
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 <config.h>
#endif
+#include <stdio.h>
#include <tcpwrapper.h>
#include <unistd.h>
#include <string.h>
@@ -55,6 +56,8 @@
#include <rpc/rpcent.h>
#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);
}

View File

@ -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 <steved@redhat.com> 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 <steved@redhat.com> 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