summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-09-26 12:39:13 -0400
committerSteve Dickson <steved@redhat.com>2008-09-26 12:39:13 -0400
commit4ac04d76dc0fffe48313d6a16b4ca9b44c135818 (patch)
tree8b8d5e3e7f96b8c132eddbab597d5b5da0c194e8
parent92e4d5c342f15940362fc2b2df19df0893f0dd13 (diff)
downloadnfs-utils-4ac04d76dc0fffe48313d6a16b4ca9b44c135818.tar.gz
nfs-utils-4ac04d76dc0fffe48313d6a16b4ca9b44c135818.tar.xz
nfs-utils-4ac04d76dc0fffe48313d6a16b4ca9b44c135818.zip
rpc.tatd: refactor check to see if call is from loopback address
Refactor common logic to check if SM_FOO request is from loopback address. We'll have to do something about this for IPv6. On IPv6-capable systems, there will be only one AF_INET6 listener. The loopback caller will get either an IPv6 loopback address, or a mapped IPv4 loopback -- either way this will be an AF_INET6 address. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Acked-by: Neil Brown <neilb@suse.de> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--utils/statd/monitor.c82
1 files changed, 36 insertions, 46 deletions
diff --git a/utils/statd/monitor.c b/utils/statd/monitor.c
index eadc434..5d4aa49 100644
--- a/utils/statd/monitor.c
+++ b/utils/statd/monitor.c
@@ -29,6 +29,36 @@ notify_list * rtnl = NULL; /* Run-time notify list. */
#define LINELEN (4*(8+1)+SM_PRIV_SIZE*2+1)
+#ifdef RESTRICTED_STATD
+/*
+ * Reject requests from non-loopback addresses in order
+ * to prevent attack described in CERT CA-99.05.
+ */
+static int
+caller_is_localhost(struct svc_req *rqstp)
+{
+ struct in_addr caller;
+
+ caller = svc_getcaller(rqstp->rq_xprt)->sin_addr;
+ if (caller.s_addr != htonl(INADDR_LOOPBACK)) {
+ note(N_WARNING,
+ "Call to statd from non-local host %s",
+ inet_ntoa(caller));
+ return 0;
+ }
+ return 1;
+}
+#else /* RESTRICTED_STATD */
+/*
+ * No restrictions for remote callers.
+ */
+static int
+caller_is_localhost(struct svc_req *rqstp)
+{
+ return 1;
+}
+#endif /* RESTRICTED_STATD */
+
/*
* Services SM_MON requests.
*/
@@ -45,31 +75,19 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
notify_list *clnt;
struct in_addr my_addr;
char *dnsname;
-#ifdef RESTRICTED_STATD
- struct in_addr caller;
-#endif
struct hostent *hostinfo = NULL;
/* Assume that we'll fail. */
result.res_stat = STAT_FAIL;
result.state = -1; /* State is undefined for STAT_FAIL. */
- /* Restrict access to statd.
- * In the light of CERT CA-99.05, we tighten access to
- * statd. --okir
- */
#ifdef RESTRICTED_STATD
- /* 1. Reject anyone not calling from 127.0.0.1.
+ /* 1. Reject any remote callers.
* Ignore the my_name specified by the caller, and
* use "127.0.0.1" instead.
*/
- caller = svc_getcaller(rqstp->rq_xprt)->sin_addr;
- if (caller.s_addr != htonl(INADDR_LOOPBACK)) {
- note(N_WARNING,
- "Call to statd from non-local host %s",
- inet_ntoa(caller));
+ if (!caller_is_localhost(rqstp))
goto failure;
- }
my_addr.s_addr = htonl(INADDR_LOOPBACK);
/* 2. Reject any registrations for non-lockd services.
@@ -329,25 +347,12 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp)
*my_name = argp->my_id.my_name;
struct my_id *id = &argp->my_id;
char *cp;
-#ifdef RESTRICTED_STATD
- struct in_addr caller;
-#endif
result.state = MY_STATE;
-#ifdef RESTRICTED_STATD
- /* 1. Reject anyone not calling from 127.0.0.1.
- * Ignore the my_name specified by the caller, and
- * use "127.0.0.1" instead.
- */
- caller = svc_getcaller(rqstp->rq_xprt)->sin_addr;
- if (caller.s_addr != htonl(INADDR_LOOPBACK)) {
- note(N_WARNING,
- "Call to statd from non-local host %s",
- inet_ntoa(caller));
+ if (!caller_is_localhost(rqstp))
goto failure;
- }
-#endif
+
/* my_name must not have white space */
for (cp=my_name ; *cp ; cp++)
if (*cp == ' ' || *cp == '\t' || *cp == '\r' || *cp == '\n')
@@ -388,9 +393,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp)
clnt = NL_NEXT(clnt);
}
-#ifdef RESTRICTED_STATD
failure:
-#endif
note(N_WARNING, "Received erroneous SM_UNMON request from %s for %s",
my_name, mon_name);
return (&result);
@@ -404,21 +407,9 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp)
static sm_stat result;
notify_list *clnt;
char *my_name = argp->my_name;
-#ifdef RESTRICTED_STATD
- struct in_addr caller;
- /* 1. Reject anyone not calling from 127.0.0.1.
- * Ignore the my_name specified by the caller, and
- * use "127.0.0.1" instead.
- */
- caller = svc_getcaller(rqstp->rq_xprt)->sin_addr;
- if (caller.s_addr != htonl(INADDR_LOOPBACK)) {
- note(N_WARNING,
- "Call to statd from non-local host %s",
- inet_ntoa(caller));
+ if (!caller_is_localhost(rqstp))
goto failure;
- }
-#endif
result.state = MY_STATE;
@@ -457,8 +448,7 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp)
dprintf(N_DEBUG, "SM_UNMON_ALL request from %s with no "
"SM_MON requests from it.", my_name);
}
-#ifdef RESTRICTED_STATD
+
failure:
-#endif
return (&result);
}