summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ypserv
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1997-04-10 14:12:51 +0000
committerwpaul <wpaul@FreeBSD.org>1997-04-10 14:12:51 +0000
commit2d779f05ef5a96063b9545faad4b44e44cb258cb (patch)
tree8862cf332c52fe5a52efc09a42716bc0c572348c /usr.sbin/ypserv
parent0425f851ec91e5c3426986b102dda2cccdf3abfd (diff)
downloadFreeBSD-src-2d779f05ef5a96063b9545faad4b44e44cb258cb.zip
FreeBSD-src-2d779f05ef5a96063b9545faad4b44e44cb258cb.tar.gz
Add a sanity test to ypproc_xfr_2_svc(): check that the map and domain
in the transfer request actually exist. Technically ypxfr can do this too, but why waste the cycles getting ypxfr off the ground for a transfer we already know is going to fail. Also apply stricter access control rules; ypproc_xfr_2_svc() is in a different class than the normal map access procedures procedures.
Diffstat (limited to 'usr.sbin/ypserv')
-rw-r--r--usr.sbin/ypserv/yp_server.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/usr.sbin/ypserv/yp_server.c b/usr.sbin/ypserv/yp_server.c
index e60251f..ce86a15 100644
--- a/usr.sbin/ypserv/yp_server.c
+++ b/usr.sbin/ypserv/yp_server.c
@@ -45,7 +45,7 @@
#include <rpc/rpc.h>
#ifndef lint
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$Id: yp_server.c,v 1.5 1997/03/15 06:06:06 wpaul Exp wpaul $";
#endif /* not lint */
int forked = 0;
@@ -305,25 +305,65 @@ ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
{
static ypresp_xfr result;
struct sockaddr_in *rqhost;
+ ypresp_master *mres;
+ ypreq_nokey mreq;
result.transid = argp->transid;
rqhost = svc_getcaller(rqstp->rq_xprt);
+ /*
+ * The FreeBSD ypxfr(8) program will not talk to a ypserv(8)
+ * or rpc.ypxfrd(8) unless it's using a reserved port, but we
+ * may as well check that the process calling this procedure
+ * is also using one.
+ *
+ * yp_access() may also do a reserved port test, but only
+ * if the YP_SECURE flag is set in the map. For this procedure,
+ * the check should be unconditional.
+ */
+ if (ntohs(rqhost->sin_port) >= IPPORT_RESERVED) {
+ yp_error("ypxfr request from non-reserved port (%s:%d) -- \
+rejecting", inet_ntoa(rqhost->sin_addr), ntohs(rqhost->sin_port));
+ YPXFR_RETURN(YPXFR_REFUSED)
+ }
+
#ifdef DB_CACHE
if (yp_access(argp->map_parms.map,
argp->map_parms.domain, (struct svc_req *)rqstp)) {
#else
if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) {
#endif
- YPXFR_RETURN(YPXFR_REFUSED);
+ YPXFR_RETURN(YPXFR_REFUSED)
}
+
if (argp->map_parms.domain == NULL) {
- YPXFR_RETURN(YPXFR_BADARGS);
+ YPXFR_RETURN(YPXFR_BADARGS)
}
if (yp_validdomain(argp->map_parms.domain)) {
- YPXFR_RETURN(YPXFR_NODOM);
+ YPXFR_RETURN(YPXFR_NODOM)
+ }
+
+ /*
+ * Determine the master host ourselves. The caller may
+ * be up to no good. This has the side effect of verifying
+ * that the requested map and domain actually exist.
+ */
+
+ mreq.domain = argp->map_parms.domain;
+ mreq.map = argp->map_parms.map;
+
+ mres = ypproc_master_2_svc(&mreq, rqstp);
+
+ if (mres->stat != YP_TRUE) {
+ yp_error("couldn't find master for map %s@%s",
+ argp->map_parms.map,
+ argp->map_parms.domain);
+ yp_error("host at %s (%s) may be pulling my leg",
+ argp->map_parms.peer,
+ inet_ntoa(rqhost->sin_addr));
+ YPXFR_RETURN(YPXFR_REFUSED)
}
switch(fork()) {
@@ -342,7 +382,7 @@ ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
if (strcmp(yp_dir, _PATH_YP)) {
execl(ypxfr_command, "ypxfr",
"-d", argp->map_parms.domain,
- "-h", argp->map_parms.peer,
+ "-h", mres->peer,
"-p", yp_dir, "-C", t,
g, inet_ntoa(rqhost->sin_addr),
p, argp->map_parms.map,
@@ -350,7 +390,7 @@ ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
} else {
execl(ypxfr_command, "ypxfr",
"-d", argp->map_parms.domain,
- "-h", argp->map_parms.peer,
+ "-h", mres->peer,
"-C", t,
g, inet_ntoa(rqhost->sin_addr),
p, argp->map_parms.map,
@@ -358,12 +398,12 @@ ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
}
forked++;
yp_error("ypxfr execl(%s): %s", ypxfr_command, strerror(errno));
- YPXFR_RETURN(YPXFR_XFRERR);
+ YPXFR_RETURN(YPXFR_XFRERR)
break;
}
case -1:
yp_error("ypxfr fork(): %s", strerror(errno));
- YPXFR_RETURN(YPXFR_XFRERR);
+ YPXFR_RETURN(YPXFR_XFRERR)
break;
default:
result.xfrstat = YPXFR_SUCC;
OpenPOWER on IntegriCloud