X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fstatd%2Fmonitor.c;h=fb321967759419c705c64a8cb6349f3cd6c8d1b6;hp=f818b2b4ae69d38f282845887853ddcb53695b74;hb=7f98c14d38badedd30d2d4a6b1d15e913967bf87;hpb=99979a6cf2f862d2365d27fa90fab4416c374903 diff --git a/utils/statd/monitor.c b/utils/statd/monitor.c index f818b2b..fb32196 100644 --- a/utils/statd/monitor.c +++ b/utils/statd/monitor.c @@ -21,8 +21,8 @@ #include #include +#include "sockaddr.h" #include "rpcmisc.h" -#include "misc.h" #include "nsm.h" #include "statd.h" #include "notlist.h" @@ -33,20 +33,26 @@ notify_list * rtnl = NULL; /* Run-time notify list. */ /* * Reject requests from non-loopback addresses in order * to prevent attack described in CERT CA-99.05. + * + * Although the kernel contacts the statd service via only IPv4 + * transports, the statd service can receive other requests, such + * as SM_NOTIFY, from remote peers via IPv6. */ -static int +static _Bool caller_is_localhost(struct svc_req *rqstp) { - struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt); - struct in_addr caller; - - caller = sin->sin_addr; - if (caller.s_addr != htonl(INADDR_LOOPBACK)) { - xlog_warn("Call to statd from non-local host %s", - inet_ntoa(caller)); - return 0; - } - return 1; + struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt); + char buf[INET6_ADDRSTRLEN]; + + if (!nfs_is_v4_loopback(sap)) + goto out_nonlocal; + return true; + +out_nonlocal: + if (!statd_present_address(sap, buf, sizeof(buf))) + buf[0] = '\0'; + xlog_warn("SM_MON/SM_UNMON call from non-local host %s", buf); + return false; } /* @@ -145,7 +151,7 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp) clnt = rtnl; while ((clnt = nlist_gethost(clnt, mon_name, 0))) { - if (matchhostname(NL_MY_NAME(clnt), my_name) && + if (statd_matchhostname(NL_MY_NAME(clnt), my_name) && NL_MY_PROC(clnt) == id->my_proc && NL_MY_PROG(clnt) == id->my_prog && NL_MY_VERS(clnt) == id->my_vers && @@ -298,7 +304,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp) * entry winds up in the list the way I'm currently handling them.) */ while ((clnt = nlist_gethost(clnt, mon_name, 0))) { - if (matchhostname(NL_MY_NAME(clnt), my_name) && + if (statd_matchhostname(NL_MY_NAME(clnt), my_name) && NL_MY_PROC(clnt) == id->my_proc && NL_MY_PROG(clnt) == id->my_prog && NL_MY_VERS(clnt) == id->my_vers) { @@ -309,7 +315,8 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp) /* PRC: do the HA callout: */ ha_callout("del-client", mon_name, my_name, -1); - nsm_delete_monitored_host(clnt->dns_name); + nsm_delete_monitored_host(clnt->dns_name, + mon_name, my_name); nlist_free(&rtnl, clnt); return (&result); @@ -363,7 +370,8 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) temp = NL_NEXT(clnt); /* PRC: do the HA callout: */ ha_callout("del-client", mon_name, my_name, -1); - nsm_delete_monitored_host(clnt->dns_name); + nsm_delete_monitored_host(clnt->dns_name, + mon_name, my_name); nlist_free(&rtnl, clnt); ++count; clnt = temp;