Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 0eec05715da3ca8ae3817a0833b18fa6 > files > 63

nfs-utils-1.0.9-50.el5.src.rpm

diff -up nfs-utils-1.0.9/support/misc/tcpwrapper.c.save nfs-utils-1.0.9/support/misc/tcpwrapper.c
--- nfs-utils-1.0.9/support/misc/tcpwrapper.c.save	2009-04-29 16:02:43.000000000 -0400
+++ nfs-utils-1.0.9/support/misc/tcpwrapper.c	2009-04-29 16:03:35.000000000 -0400
@@ -34,6 +34,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+#ifdef HAVE_LIBWRAP
 #include <tcpwrapper.h>
 #include <unistd.h>
 #include <string.h>
@@ -44,134 +45,145 @@
 #include <pwd.h>
 #include <sys/types.h>
 #include <sys/signal.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <tcpd.h>
+
+#include "xlog.h"
+
 #ifdef SYSV40
 #include <netinet/in.h>
 #include <rpc/rpcent.h>
 #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 int check_files(void);
+
+/*
+ * These need to exist since they are externed 
+ * public header files.
+ */
 int     verboselog = 0;
 int     allow_severity = LOG_INFO;
 int     deny_severity = LOG_WARNING;
 
-/* A handful of macros for "readability". */
+#define log_bad_host(addr, proc, prog) \
+  logit(deny_severity, addr, proc, prog, "request from unauthorized host")
 
-#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)
+#define ALLOW 1
+#define DENY 0
+
+typedef struct _haccess_t {
+	TAILQ_ENTRY(_haccess_t) list;
+	int access;
+    struct in_addr addr;
+} haccess_t;
+
+#define HASH_TABLE_SIZE 1021
+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);
+static void haccess_add(struct sockaddr_in *addr, u_long, int);
+
+inline unsigned int strtoint(char *str)
 {
-	return 0;
+	unsigned int n = 0;
+	int len = strlen(str);
+	int i;
+
+	for (i=0; i < len; i++)
+		n+=((int)str[i])*i;
+
+	return n;
 }
-#endif
+static inline int hashint(unsigned int num)
+{
+	return num % HASH_TABLE_SIZE;
+}
+#define HASH(_addr, _prog) \
+	hashint((strtoint((_addr))+(_prog)))
 
-#define	legal_port(a,p) \
-  (ntohs((a)->sin_port) < IPPORT_RESERVED || (p) >= IPPORT_RESERVED)
+void haccess_add(struct sockaddr_in *addr, u_long prog, int access)
+{
+	hash_head *head;
+ 	haccess_t *hptr;
+	int hash;
 
-#define log_bad_port(addr, proc, prog) \
-  logit(deny_severity, addr, proc, prog, ": request from unprivileged port")
+	hptr = (haccess_t *)malloc(sizeof(haccess_t));
+	if (hptr == NULL)
+		return;
 
-#define log_bad_host(addr, proc, prog) \
-  logit(deny_severity, addr, proc, prog, ": request from unauthorized host")
+	hash = HASH(inet_ntoa(addr->sin_addr), prog);
+	head = &(haccess_tbl[hash]);
 
-#define log_bad_owner(addr, proc, prog) \
-  logit(deny_severity, addr, proc, prog, ": request from non-local host")
+	hptr->access = access;
+	hptr->addr.s_addr = addr->sin_addr.s_addr;
 
-#define	log_no_forward(addr, proc, prog) \
-  logit(deny_severity, addr, proc, prog, ": request not forwarded")
+	if (TAILQ_EMPTY(&head->h_head))
+		TAILQ_INSERT_HEAD(&head->h_head, hptr, list);
+	else
+		TAILQ_INSERT_TAIL(&head->h_head, hptr, list);
+}
+haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long prog)
+{
+	hash_head *head;
+ 	haccess_t *hptr;
+	int hash;
 
-#define log_client(addr, proc, prog) \
-  logit(allow_severity, addr, proc, prog, "")
+	hash = HASH(inet_ntoa(addr->sin_addr), prog);
+	head = &(haccess_tbl[hash]);
+
+	TAILQ_FOREACH(hptr, &head->h_head, list) {
+		if (hptr->addr.s_addr == addr->sin_addr.s_addr)
+			return hptr;
+	}
+	return NULL;
+}
 
 int
 good_client(daemon, addr)
 char *daemon;
 struct sockaddr_in *addr;
 {
-    struct hostent *hp;
-    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 */
-	for (sp = hp->h_addr_list ; *sp ; sp++) {
-	    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;
-}
-
-/* check_startup - additional startup code */
-
-void    check_startup()
-{
-
-    /*
-     * 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);
-            }
-        }
-    }
+	struct request_info req;
 
-    (void) signal(SIGINT, toggle_verboselog);
+	request_init(&req, RQ_DAEMON, daemon, RQ_CLIENT_SIN, addr, 0);
+	sock_methods(&req);
+
+	if (hosts_access(&req)) 
+		return ALLOW;
+
+	return DENY;
+}
+
+/* check_files - check to see if either access files have changed */
+
+static int check_files()
+{
+	static time_t allow_mtime, deny_mtime;
+	struct stat astat, dstat;
+	int changed = 0;
+
+	if (stat("/etc/hosts.allow", &astat) < 0)
+		astat.st_mtime = 0;
+	if (stat("/etc/hosts.deny", &dstat) < 0)
+		dstat.st_mtime = 0;
+
+	if(!astat.st_mtime || !dstat.st_mtime)
+		return changed;
+
+	if (astat.st_mtime != allow_mtime)
+		changed = 1;
+	else if (dstat.st_mtime != deny_mtime)
+		changed = 1;
+
+	allow_mtime = astat.st_mtime;
+	deny_mtime = dstat.st_mtime;
+
+	return changed;
 }
 
 /* check_default - additional checks for NULL, DUMP, GETPORT and unknown */
@@ -183,85 +195,36 @@ 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);
-    return (TRUE);
-}
+	haccess_t *acc = NULL;
+	int changed = check_files();
 
-/* 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;
-{
-#ifdef CHECK_PORT
-    if (!legal_port(addr, port)) {
-	log_bad_port(addr, proc, prog);
-	return (FALSE);
-    }
-#endif
-    return (TRUE);
-}
+	acc = haccess_lookup(addr, prog);
+	if (acc && changed == 0)
+		return (acc->access);
+
+	if (!(from_local(addr) || good_client(daemon, addr))) {
+		log_bad_host(addr, proc, prog);
+		if (acc)
+			acc->access = FALSE;
+		else 
+			haccess_add(addr, prog, FALSE);
+		return (FALSE);
+	}
 
-/* toggle_verboselog - toggle verbose logging flag */
+	if (acc)
+		acc->access = TRUE;
+	else 
+		haccess_add(addr, prog, TRUE);
 
-static void toggle_verboselog(sig)
-int     sig;
-{
-    (void) signal(sig, toggle_verboselog);
-    verboselog = !verboselog;
+    return (TRUE);
 }
 
 /* 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;
-{
-    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);
-    }
+static void logit(int severity, struct sockaddr_in *addr,
+		  u_long procnum, u_long prognum, char *text)
+{
+	syslog(severity, "connect from %s denied: %s",
+	       inet_ntoa(addr->sin_addr), text);
 }
+#endif
diff -up nfs-utils-1.0.9/utils/mountd/mountd.man.save nfs-utils-1.0.9/utils/mountd/mountd.man
--- nfs-utils-1.0.9/utils/mountd/mountd.man.save	2009-04-29 16:02:39.000000000 -0400
+++ nfs-utils-1.0.9/utils/mountd/mountd.man	2009-04-29 16:03:29.000000000 -0400
@@ -166,13 +166,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),