Use the remote address for access control, not the local address. This fixes
the nfsd problems that some people have with the new code. Add support for the vfs.nfsrv.nfs_privport sysctl which denies access unless the client is using a port number less than 1024. Not really sure if this is particularly useful since it doesn't add any real security.
This commit is contained in:
parent
0eec5c87bf
commit
36b83ac1b0
@ -348,19 +348,61 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
nfs_realign(&mreq);
|
||||
|
||||
/*
|
||||
* Note: we want rq_addr, not svc_getrpccaller -
|
||||
* Note: we want rq_addr, not svc_getrpccaller for nd_nam2 -
|
||||
* NFS_SRVMAXDATA uses a NULL value for nd_nam2 to detect TCP
|
||||
* mounts.
|
||||
*/
|
||||
memset(&nd, 0, sizeof(nd));
|
||||
nd.nd_md = nd.nd_mrep = mreq;
|
||||
nd.nd_dpos = mtod(mreq, caddr_t);
|
||||
nd.nd_nam = (struct sockaddr *) &xprt->xp_ltaddr;
|
||||
nd.nd_nam = svc_getrpccaller(rqst);
|
||||
nd.nd_nam2 = rqst->rq_addr;
|
||||
nd.nd_procnum = procnum;
|
||||
nd.nd_cr = NULL;
|
||||
nd.nd_flag = flag;
|
||||
|
||||
if (nfs_privport) {
|
||||
/* Check if source port is privileged */
|
||||
u_short port;
|
||||
struct sockaddr *nam = nd.nd_nam;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)nam;
|
||||
/*
|
||||
* INET/INET6 - same code:
|
||||
* sin_port and sin6_port are at same offset
|
||||
*/
|
||||
port = ntohs(sin->sin_port);
|
||||
if (port >= IPPORT_RESERVED &&
|
||||
nd.nd_procnum != NFSPROC_NULL) {
|
||||
#ifdef INET6
|
||||
char b6[INET6_ADDRSTRLEN];
|
||||
#if defined(KLD_MODULE)
|
||||
/* Do not use ip6_sprintf: the nfs module should work without INET6. */
|
||||
#define ip6_sprintf(buf, a) \
|
||||
(sprintf((buf), "%x:%x:%x:%x:%x:%x:%x:%x", \
|
||||
(a)->s6_addr16[0], (a)->s6_addr16[1], \
|
||||
(a)->s6_addr16[2], (a)->s6_addr16[3], \
|
||||
(a)->s6_addr16[4], (a)->s6_addr16[5], \
|
||||
(a)->s6_addr16[6], (a)->s6_addr16[7]), \
|
||||
(buf))
|
||||
#endif
|
||||
#endif
|
||||
printf("NFS request from unprivileged port (%s:%d)\n",
|
||||
#ifdef INET6
|
||||
sin->sin_family == AF_INET6 ?
|
||||
ip6_sprintf(b6, &satosin6(sin)->sin6_addr) :
|
||||
#if defined(KLD_MODULE)
|
||||
#undef ip6_sprintf
|
||||
#endif
|
||||
#endif
|
||||
inet_ntoa(sin->sin_addr), port);
|
||||
svcerr_weakauth(rqst);
|
||||
svc_freereq(rqst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (proc != nfsrv_null) {
|
||||
if (!svc_getcred(rqst, &nd.nd_cr, &nd.nd_credflavor)) {
|
||||
svcerr_weakauth(rqst);
|
||||
|
@ -65,6 +65,7 @@ void
|
||||
xdrmbuf_create(XDR *xdrs, struct mbuf *m, enum xdr_op op)
|
||||
{
|
||||
|
||||
KASSERT(m != NULL, ("xdrmbuf_create with NULL mbuf chain"));
|
||||
xdrs->x_op = op;
|
||||
xdrs->x_ops = &xdrmbuf_ops;
|
||||
xdrs->x_base = (char *) m;
|
||||
|
Loading…
Reference in New Issue
Block a user