View | Details | Raw Unified | Return to bug 205193 | Differences between
and this patch

Collapse All | Expand All

(-)usr.sbin/nfsuserd/nfsuserd.c (-9 / +70 lines)
Lines 40-45 __FBSDID("$FreeBSD: head/usr.sbin/nfsuse Link Here
40
#include <sys/vnode.h>
40
#include <sys/vnode.h>
41
#include <sys/wait.h>
41
#include <sys/wait.h>
42
42
43
#include <netinet/in.h>
44
45
#include <arpa/inet.h>
46
43
#include <nfs/nfssvc.h>
47
#include <nfs/nfssvc.h>
44
48
45
#include <rpc/rpc.h>
49
#include <rpc/rpc.h>
Lines 72-77 static void nfsuserdsrv(struct svc_req * Link Here
72
static bool_t	xdr_getid(XDR *, caddr_t);
76
static bool_t	xdr_getid(XDR *, caddr_t);
73
static bool_t	xdr_getname(XDR *, caddr_t);
77
static bool_t	xdr_getname(XDR *, caddr_t);
74
static bool_t	xdr_retval(XDR *, caddr_t);
78
static bool_t	xdr_retval(XDR *, caddr_t);
79
static int	nfsbind_localhost(void);
75
80
76
#define	MAXNAME		1024
81
#define	MAXNAME		1024
77
#define	MAXNFSUSERD	20
82
#define	MAXNFSUSERD	20
Lines 94-99 gid_t defaultgid = 65533; Link Here
94
int verbose = 0, im_a_slave = 0, nfsuserdcnt = -1, forcestart = 0;
99
int verbose = 0, im_a_slave = 0, nfsuserdcnt = -1, forcestart = 0;
95
int defusertimeout = DEFUSERTIMEOUT, manage_gids = 0;
100
int defusertimeout = DEFUSERTIMEOUT, manage_gids = 0;
96
pid_t slaves[MAXNFSUSERD];
101
pid_t slaves[MAXNFSUSERD];
102
static struct sockaddr_in fromip;
97
103
98
int
104
int
99
main(int argc, char *argv[])
105
main(int argc, char *argv[])
Lines 144-149 main(int argc, char *argv[]) Link Here
144
			}
150
			}
145
		}
151
		}
146
	}
152
	}
153
154
	fromip.sin_addr.s_addr = inet_addr("127.0.0.1");
155
147
	nid.nid_usermax = DEFUSERMAX;
156
	nid.nid_usermax = DEFUSERMAX;
148
	nid.nid_usertimeout = defusertimeout;
157
	nid.nid_usertimeout = defusertimeout;
149
158
Lines 460-483 nfsuserdsrv(struct svc_req *rqstp, SVCXP Link Here
460
	u_short sport;
469
	u_short sport;
461
	struct info info;
470
	struct info info;
462
	struct nfsd_idargs nid;
471
	struct nfsd_idargs nid;
463
	u_int32_t saddr;
464
	gid_t grps[NGROUPS];
472
	gid_t grps[NGROUPS];
465
	int ngroup;
473
	int ngroup;
474
	struct sockaddr_in *sin;
475
	int ret;
466
476
467
	/*
477
	/*
468
	 * Only handle requests from 127.0.0.1 on a reserved port number.
478
	 * Only handle requests from localhost on a reserved port number.
479
	 * If the upcall is from a different address, call nfsbind_localhost()
480
	 * to check for a remapping of localhost, due to jails.
469
	 * (Since a reserved port # at localhost implies a client with
481
	 * (Since a reserved port # at localhost implies a client with
470
	 *  local root, there won't be a security breach. This is about
482
	 *  local root, there won't be a security breach. This is about
471
	 *  the only case I can think of where a reserved port # means
483
	 *  the only case I can think of where a reserved port # means
472
	 *  something.)
484
	 *  something.)
473
	 */
485
	 */
474
	sport = ntohs(transp->xp_raddr.sin_port);
486
	if (rqstp->rq_proc != NULLPROC) {
475
	saddr = ntohl(transp->xp_raddr.sin_addr.s_addr);
487
		if (transp->xp_rtaddr.len < sizeof(*sin)) {
476
	if ((rqstp->rq_proc != NULLPROC && sport >= IPPORT_RESERVED) ||
488
			syslog(LOG_ERR, "xp_rtaddr too small");
477
	    saddr != 0x7f000001) {
489
			svcerr_weakauth(transp);
478
		syslog(LOG_ERR, "req from ip=0x%x port=%d\n", saddr, sport);
490
			return;
479
		svcerr_weakauth(transp);
491
		}
480
		return;
492
		sin = (struct sockaddr_in *)transp->xp_rtaddr.buf;
493
		sport = ntohs(sin->sin_port);
494
		if (sport >= IPPORT_RESERVED) {
495
			syslog(LOG_ERR, "not a reserved port#");
496
			svcerr_weakauth(transp);
497
			return;
498
		}
499
		ret = 1;
500
		if (sin->sin_addr.s_addr != fromip.sin_addr.s_addr)
501
			ret = nfsbind_localhost();
502
		if (ret == 0 || sin->sin_addr.s_addr !=
503
		    fromip.sin_addr.s_addr) {
504
			syslog(LOG_ERR, "bad from ip %s",
505
			    inet_ntoa(sin->sin_addr));
506
			svcerr_weakauth(transp);
507
			return;
508
		}
481
	}
509
	}
482
	switch (rqstp->rq_proc) {
510
	switch (rqstp->rq_proc) {
483
	case NULLPROC:
511
	case NULLPROC:
Lines 718-723 cleanup_term(int signo __unused) Link Here
718
	exit(0);
746
	exit(0);
719
}
747
}
720
748
749
/*
750
 * Get the IP address that the localhost address maps to.
751
 * This is needed when jails map localhost to another IP address.
752
 */
753
static int
754
nfsbind_localhost(void)
755
{
756
	struct sockaddr_in sad;
757
	socklen_t slen;
758
	int ret, s;
759
760
	s = socket(PF_INET, SOCK_DGRAM, 0);
761
	if (s < 0)
762
		return (0);
763
	memset(&sad, 0, sizeof(sad));
764
	sad.sin_len = sizeof(sad);
765
	sad.sin_family = AF_INET;
766
	sad.sin_addr.s_addr = inet_addr("127.0.0.1");
767
	sad.sin_port = 0;
768
	ret = bind(s, (struct sockaddr *)&sad, sizeof(sad));
769
	if (ret < 0) {
770
		close(s);
771
		return (0);
772
	}
773
	memset(&fromip, 0, sizeof(fromip));
774
	slen = sizeof(fromip);
775
	ret = getsockname(s, (struct sockaddr *)&fromip, &slen);
776
	close(s);
777
	if (ret < 0)
778
		return (0);
779
	return (1);
780
}
781
721
static void
782
static void
722
usage(void)
783
usage(void)
723
{
784
{

Return to bug 205193