Add flags to enable NFS over TLS to the NFS client and server.
An Internet Draft titled "Towards Remote Procedure Call Encryption By Default" (soon to be an RFC I think) describes how Sun RPC is to use TLS with NFS as a specific application case. Various commits prepared the NFS code to use KERN_TLS, mainly enabling use of ext_pgs mbufs for large RPC messages. r364475 added TLS support to the kernel RPC. This commit (which is the final one for kernel changes required to do NFS over TLS) adds support for three export flags: MNT_EXTLS - Requires a TLS connection. MNT_EXTLSCERT - Requires a TLS connection where the client presents a valid X.509 certificate during TLS handshake. MNT_EXTLSCERTUSER - Requires a TLS connection where the client presents a valid X.509 certificate with "user@domain" in the otherName field of the SubjectAltName during TLS handshake. Without these export options, clients are permitted, but not required, to use TLS. For the client, a new nmount(2) option called "tls" makes the client do a STARTTLS Null RPC and TLS handshake for all TCP connections used for the mount. The CLSET_TLS client control option is used to indicate to the kernel RPC that this should be done. Unless the above export flags or "tls" option is used, semantics should not change for the NFS client nor server. For NFS over TLS to work, the userspace daemons rpctlscd(8) { for client } or rpctlssd(8) daemon { for server } must be running.
This commit is contained in:
parent
66ac5b2c5a
commit
6e4b6ff88f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=364896
@ -281,6 +281,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
|||||||
CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one);
|
CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one);
|
||||||
if ((nmp->nm_flag & NFSMNT_RESVPORT))
|
if ((nmp->nm_flag & NFSMNT_RESVPORT))
|
||||||
CLNT_CONTROL(client, CLSET_PRIVPORT, &one);
|
CLNT_CONTROL(client, CLSET_PRIVPORT, &one);
|
||||||
|
if (NFSHASTLS(nmp))
|
||||||
|
CLNT_CONTROL(client, CLSET_TLS, &one);
|
||||||
if (NFSHASSOFT(nmp)) {
|
if (NFSHASSOFT(nmp)) {
|
||||||
if (nmp->nm_sotype == SOCK_DGRAM)
|
if (nmp->nm_sotype == SOCK_DGRAM)
|
||||||
/*
|
/*
|
||||||
|
@ -81,6 +81,9 @@ struct nfsexstuff {
|
|||||||
#define NFSVNO_EXPORTANON(e) ((e)->nes_exflag & MNT_EXPORTANON)
|
#define NFSVNO_EXPORTANON(e) ((e)->nes_exflag & MNT_EXPORTANON)
|
||||||
#define NFSVNO_EXSTRICTACCESS(e) ((e)->nes_exflag & MNT_EXSTRICTACCESS)
|
#define NFSVNO_EXSTRICTACCESS(e) ((e)->nes_exflag & MNT_EXSTRICTACCESS)
|
||||||
#define NFSVNO_EXV4ONLY(e) ((e)->nes_exflag & MNT_EXV4ONLY)
|
#define NFSVNO_EXV4ONLY(e) ((e)->nes_exflag & MNT_EXV4ONLY)
|
||||||
|
#define NFSVNO_EXTLS(e) ((e)->nes_exflag & MNT_EXTLS)
|
||||||
|
#define NFSVNO_EXTLSCERT(e) ((e)->nes_exflag & MNT_EXTLSCERT)
|
||||||
|
#define NFSVNO_EXTLSCERTUSER(e) ((e)->nes_exflag & MNT_EXTLSCERTUSER)
|
||||||
|
|
||||||
#define NFSVNO_SETEXRDONLY(e) ((e)->nes_exflag = (MNT_EXPORTED|MNT_EXRDONLY))
|
#define NFSVNO_SETEXRDONLY(e) ((e)->nes_exflag = (MNT_EXPORTED|MNT_EXRDONLY))
|
||||||
|
|
||||||
|
@ -1055,6 +1055,7 @@ bool ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep);
|
|||||||
#define NFSHASOPENMODE(n) ((n)->nm_state & NFSSTA_OPENMODE)
|
#define NFSHASOPENMODE(n) ((n)->nm_state & NFSSTA_OPENMODE)
|
||||||
#define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \
|
#define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \
|
||||||
(n)->nm_minorvers > 0)
|
(n)->nm_minorvers > 0)
|
||||||
|
#define NFSHASTLS(n) (((n)->nm_newflag & NFSMNT_TLS) != 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set boottime.
|
* Set boottime.
|
||||||
|
@ -37,12 +37,14 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include "opt_kgssapi.h"
|
#include "opt_kgssapi.h"
|
||||||
|
#include "opt_kern_tls.h"
|
||||||
|
|
||||||
#include <fs/nfs/nfsport.h>
|
#include <fs/nfs/nfsport.h>
|
||||||
|
|
||||||
#include <rpc/rpc.h>
|
#include <rpc/rpc.h>
|
||||||
#include <rpc/rpcsec_gss.h>
|
|
||||||
#include <rpc/replay.h>
|
#include <rpc/replay.h>
|
||||||
|
#include <rpc/rpcsec_gss.h>
|
||||||
|
#include <rpc/rpcsec_tls.h>
|
||||||
|
|
||||||
|
|
||||||
NFSDLOCKMUTEX;
|
NFSDLOCKMUTEX;
|
||||||
@ -67,6 +69,9 @@ nfscb_program(struct svc_req *rqst, SVCXPRT *xprt)
|
|||||||
{
|
{
|
||||||
struct nfsrv_descript nd;
|
struct nfsrv_descript nd;
|
||||||
int cacherep, credflavor;
|
int cacherep, credflavor;
|
||||||
|
#ifdef KERN_TLS
|
||||||
|
u_int maxlen;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&nd, 0, sizeof(nd));
|
memset(&nd, 0, sizeof(nd));
|
||||||
if (rqst->rq_proc != NFSPROC_NULL &&
|
if (rqst->rq_proc != NFSPROC_NULL &&
|
||||||
@ -107,6 +112,13 @@ nfscb_program(struct svc_req *rqst, SVCXPRT *xprt)
|
|||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
mac_cred_associate_nfsd(nd.nd_cred);
|
mac_cred_associate_nfsd(nd.nd_cred);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef KERN_TLS
|
||||||
|
if ((xprt->xp_tls & RPCTLS_FLAGS_HANDSHAKE) != 0 &&
|
||||||
|
rpctls_getinfo(&maxlen, false, false)) {
|
||||||
|
nd.nd_flag |= ND_EXTPG;
|
||||||
|
nd.nd_maxextsiz = maxlen;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
cacherep = nfs_cbproc(&nd, rqst->rq_xid);
|
cacherep = nfs_cbproc(&nd, rqst->rq_xid);
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "opt_bootp.h"
|
#include "opt_bootp.h"
|
||||||
#include "opt_nfsroot.h"
|
#include "opt_nfsroot.h"
|
||||||
|
#include "opt_kern_tls.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -77,6 +78,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <fs/nfsclient/nfs.h>
|
#include <fs/nfsclient/nfs.h>
|
||||||
#include <nfs/nfsdiskless.h>
|
#include <nfs/nfsdiskless.h>
|
||||||
|
|
||||||
|
#include <rpc/rpcsec_tls.h>
|
||||||
|
|
||||||
FEATURE(nfscl, "NFSv4 client");
|
FEATURE(nfscl, "NFSv4 client");
|
||||||
|
|
||||||
extern int nfscl_ticks;
|
extern int nfscl_ticks;
|
||||||
@ -117,7 +120,7 @@ static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
|
|||||||
static int mountnfs(struct nfs_args *, struct mount *,
|
static int mountnfs(struct nfs_args *, struct mount *,
|
||||||
struct sockaddr *, char *, u_char *, int, u_char *, int,
|
struct sockaddr *, char *, u_char *, int, u_char *, int,
|
||||||
u_char *, int, struct vnode **, struct ucred *,
|
u_char *, int, struct vnode **, struct ucred *,
|
||||||
struct thread *, int, int, int);
|
struct thread *, int, int, int, uint32_t);
|
||||||
static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
|
static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
|
||||||
struct sockaddr_storage *, int *, off_t *,
|
struct sockaddr_storage *, int *, off_t *,
|
||||||
struct timeval *);
|
struct timeval *);
|
||||||
@ -544,7 +547,7 @@ nfs_mountdiskless(char *path,
|
|||||||
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
|
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
|
||||||
if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
|
if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
|
||||||
NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
|
NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
|
||||||
NFS_DEFAULT_NEGNAMETIMEO, 0)) != 0) {
|
NFS_DEFAULT_NEGNAMETIMEO, 0, 0)) != 0) {
|
||||||
printf("nfs_mountroot: mount %s on /: %d\n", path, error);
|
printf("nfs_mountroot: mount %s on /: %d\n", path, error);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -746,7 +749,7 @@ static const char *nfs_opts[] = { "from", "nfs_args",
|
|||||||
"resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh",
|
"resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh",
|
||||||
"nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath",
|
"nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath",
|
||||||
"minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr",
|
"minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr",
|
||||||
"pnfs", "wcommitsize", "oneopenown",
|
"pnfs", "wcommitsize", "oneopenown", "tls",
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -897,9 +900,11 @@ nfs_mount(struct mount *mp)
|
|||||||
int dirlen, has_nfs_args_opt, has_nfs_from_opt,
|
int dirlen, has_nfs_args_opt, has_nfs_from_opt,
|
||||||
krbnamelen, srvkrbnamelen;
|
krbnamelen, srvkrbnamelen;
|
||||||
size_t hstlen;
|
size_t hstlen;
|
||||||
|
uint32_t newflag;
|
||||||
|
|
||||||
has_nfs_args_opt = 0;
|
has_nfs_args_opt = 0;
|
||||||
has_nfs_from_opt = 0;
|
has_nfs_from_opt = 0;
|
||||||
|
newflag = 0;
|
||||||
hst = malloc(MNAMELEN, M_TEMP, M_WAITOK);
|
hst = malloc(MNAMELEN, M_TEMP, M_WAITOK);
|
||||||
if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
|
if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
@ -983,6 +988,8 @@ nfs_mount(struct mount *mp)
|
|||||||
args.flags |= NFSMNT_PNFS;
|
args.flags |= NFSMNT_PNFS;
|
||||||
if (vfs_getopt(mp->mnt_optnew, "oneopenown", NULL, NULL) == 0)
|
if (vfs_getopt(mp->mnt_optnew, "oneopenown", NULL, NULL) == 0)
|
||||||
args.flags |= NFSMNT_ONEOPENOWN;
|
args.flags |= NFSMNT_ONEOPENOWN;
|
||||||
|
if (vfs_getopt(mp->mnt_optnew, "tls", NULL, NULL) == 0)
|
||||||
|
newflag |= NFSMNT_TLS;
|
||||||
if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
|
if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
|
||||||
if (opt == NULL) {
|
if (opt == NULL) {
|
||||||
vfs_mount_error(mp, "illegal readdirsize");
|
vfs_mount_error(mp, "illegal readdirsize");
|
||||||
@ -1337,7 +1344,7 @@ nfs_mount(struct mount *mp)
|
|||||||
args.fh = nfh;
|
args.fh = nfh;
|
||||||
error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
|
error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
|
||||||
dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
|
dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
|
||||||
nametimeo, negnametimeo, minvers);
|
nametimeo, negnametimeo, minvers, newflag);
|
||||||
out:
|
out:
|
||||||
if (!error) {
|
if (!error) {
|
||||||
MNT_ILOCK(mp);
|
MNT_ILOCK(mp);
|
||||||
@ -1386,7 +1393,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
|||||||
char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
|
char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
|
||||||
u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
|
u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
|
||||||
struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
|
struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
|
||||||
int minvers)
|
int minvers, uint32_t newflag)
|
||||||
{
|
{
|
||||||
struct nfsmount *nmp;
|
struct nfsmount *nmp;
|
||||||
struct nfsnode *np;
|
struct nfsnode *np;
|
||||||
@ -1396,6 +1403,9 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
|||||||
struct nfsclds *dsp, *tdsp;
|
struct nfsclds *dsp, *tdsp;
|
||||||
uint32_t lease;
|
uint32_t lease;
|
||||||
static u_int64_t clval = 0;
|
static u_int64_t clval = 0;
|
||||||
|
#ifdef KERN_TLS
|
||||||
|
u_int maxlen;
|
||||||
|
#endif
|
||||||
|
|
||||||
NFSCL_DEBUG(3, "in mnt\n");
|
NFSCL_DEBUG(3, "in mnt\n");
|
||||||
clp = NULL;
|
clp = NULL;
|
||||||
@ -1405,9 +1415,22 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
|||||||
free(nam, M_SONAME);
|
free(nam, M_SONAME);
|
||||||
return (0);
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
|
/* NFS-over-TLS requires that rpctls be functioning. */
|
||||||
|
if ((newflag & NFSMNT_TLS) != 0) {
|
||||||
|
error = EINVAL;
|
||||||
|
#ifdef KERN_TLS
|
||||||
|
if (rpctls_getinfo(&maxlen, true, false))
|
||||||
|
error = 0;
|
||||||
|
#endif
|
||||||
|
if (error != 0) {
|
||||||
|
free(nam, M_SONAME);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
nmp = malloc(sizeof (struct nfsmount) +
|
nmp = malloc(sizeof (struct nfsmount) +
|
||||||
krbnamelen + dirlen + srvkrbnamelen + 2,
|
krbnamelen + dirlen + srvkrbnamelen + 2,
|
||||||
M_NEWNFSMNT, M_WAITOK | M_ZERO);
|
M_NEWNFSMNT, M_WAITOK | M_ZERO);
|
||||||
|
nmp->nm_newflag = newflag;
|
||||||
TAILQ_INIT(&nmp->nm_bufq);
|
TAILQ_INIT(&nmp->nm_bufq);
|
||||||
TAILQ_INIT(&nmp->nm_sess);
|
TAILQ_INIT(&nmp->nm_sess);
|
||||||
if (clval == 0)
|
if (clval == 0)
|
||||||
@ -2011,6 +2034,8 @@ void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
|
|||||||
nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
|
nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
|
||||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
|
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
|
||||||
&buf, &blen);
|
&buf, &blen);
|
||||||
|
nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf,
|
||||||
|
&blen);
|
||||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
|
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
|
||||||
&buf, &blen);
|
&buf, &blen);
|
||||||
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
|
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
struct nfsmount {
|
struct nfsmount {
|
||||||
struct nfsmount_common nm_com; /* Common fields for nlm */
|
struct nfsmount_common nm_com; /* Common fields for nlm */
|
||||||
uint32_t nm_privflag; /* Private flags */
|
uint32_t nm_privflag; /* Private flags */
|
||||||
|
uint32_t nm_newflag; /* New mount flags */
|
||||||
int nm_numgrps; /* Max. size of groupslist */
|
int nm_numgrps; /* Max. size of groupslist */
|
||||||
u_char nm_fh[NFSX_FHMAX]; /* File handle of root dir */
|
u_char nm_fh[NFSX_FHMAX]; /* File handle of root dir */
|
||||||
int nm_fhsize; /* Size of root file handle */
|
int nm_fhsize; /* Size of root file handle */
|
||||||
@ -114,6 +115,9 @@ struct nfsmount {
|
|||||||
#define NFSMNTP_NOADVISE 0x00000100
|
#define NFSMNTP_NOADVISE 0x00000100
|
||||||
#define NFSMNTP_NOALLOCATE 0x00000200
|
#define NFSMNTP_NOALLOCATE 0x00000200
|
||||||
|
|
||||||
|
/* New mount flags only used by the kernel via nmount(2). */
|
||||||
|
#define NFSMNT_TLS 0x00000001
|
||||||
|
|
||||||
#define NFSMNT_DIRPATH(m) (&((m)->nm_name[(m)->nm_krbnamelen + 1]))
|
#define NFSMNT_DIRPATH(m) (&((m)->nm_name[(m)->nm_krbnamelen + 1]))
|
||||||
#define NFSMNT_SRVKRBNAME(m) \
|
#define NFSMNT_SRVKRBNAME(m) \
|
||||||
(&((m)->nm_name[(m)->nm_krbnamelen + (m)->nm_dirpathlen + 2]))
|
(&((m)->nm_name[(m)->nm_krbnamelen + (m)->nm_dirpathlen + 2]))
|
||||||
|
@ -38,11 +38,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "opt_inet6.h"
|
#include "opt_inet6.h"
|
||||||
#include "opt_kgssapi.h"
|
#include "opt_kgssapi.h"
|
||||||
|
#include "opt_kern_tls.h"
|
||||||
|
|
||||||
#include <fs/nfs/nfsport.h>
|
#include <fs/nfs/nfsport.h>
|
||||||
|
|
||||||
#include <rpc/rpc.h>
|
#include <rpc/rpc.h>
|
||||||
#include <rpc/rpcsec_gss.h>
|
#include <rpc/rpcsec_gss.h>
|
||||||
|
#include <rpc/rpcsec_tls.h>
|
||||||
|
|
||||||
#include <fs/nfsserver/nfs_fha_new.h>
|
#include <fs/nfsserver/nfs_fha_new.h>
|
||||||
|
|
||||||
@ -120,6 +122,9 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
|||||||
struct nfsrv_descript nd;
|
struct nfsrv_descript nd;
|
||||||
struct nfsrvcache *rp = NULL;
|
struct nfsrvcache *rp = NULL;
|
||||||
int cacherep, credflavor;
|
int cacherep, credflavor;
|
||||||
|
#ifdef KERN_TLS
|
||||||
|
u_int maxlen;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&nd, 0, sizeof(nd));
|
memset(&nd, 0, sizeof(nd));
|
||||||
if (rqst->rq_vers == NFS_VER2) {
|
if (rqst->rq_vers == NFS_VER2) {
|
||||||
@ -234,6 +239,14 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((xprt->xp_tls & RPCTLS_FLAGS_HANDSHAKE) != 0) {
|
||||||
|
nd.nd_flag |= ND_TLS;
|
||||||
|
if ((xprt->xp_tls & RPCTLS_FLAGS_VERIFIED) != 0)
|
||||||
|
nd.nd_flag |= ND_TLSCERT;
|
||||||
|
if ((xprt->xp_tls & RPCTLS_FLAGS_CERTUSER) != 0)
|
||||||
|
nd.nd_flag |= ND_TLSCERTUSER;
|
||||||
|
}
|
||||||
|
nd.nd_maxextsiz = 16384;
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
mac_cred_associate_nfsd(nd.nd_cred);
|
mac_cred_associate_nfsd(nd.nd_cred);
|
||||||
#endif
|
#endif
|
||||||
@ -268,6 +281,11 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KERN_TLS
|
||||||
|
if ((xprt->xp_tls & RPCTLS_FLAGS_HANDSHAKE) != 0 &&
|
||||||
|
rpctls_getinfo(&maxlen, false, false))
|
||||||
|
nd.nd_maxextsiz = maxlen;
|
||||||
|
#endif
|
||||||
cacherep = nfs_proc(&nd, rqst->rq_xid, xprt, &rp);
|
cacherep = nfs_proc(&nd, rqst->rq_xid, xprt, &rp);
|
||||||
NFSLOCKV4ROOTMUTEX();
|
NFSLOCKV4ROOTMUTEX();
|
||||||
nfsv4_relref(&nfsd_suspend_lock);
|
nfsv4_relref(&nfsd_suspend_lock);
|
||||||
|
@ -3283,6 +3283,19 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
|||||||
nd->nd_repstat = EACCES;
|
nd->nd_repstat = EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If TLS is required by the export, check the flags in nd_flag.
|
||||||
|
*/
|
||||||
|
if (nd->nd_repstat == 0 && ((NFSVNO_EXTLS(exp) &&
|
||||||
|
(nd->nd_flag & ND_TLS) == 0) ||
|
||||||
|
(NFSVNO_EXTLSCERT(exp) &&
|
||||||
|
(nd->nd_flag & ND_TLSCERT) == 0) ||
|
||||||
|
(NFSVNO_EXTLSCERTUSER(exp) &&
|
||||||
|
(nd->nd_flag & ND_TLSCERTUSER) == 0))) {
|
||||||
|
vput(*vpp);
|
||||||
|
nd->nd_repstat = NFSERR_ACCES;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Personally, I've never seen any point in requiring a
|
* Personally, I've never seen any point in requiring a
|
||||||
* reserved port#, since only in the rare case where the
|
* reserved port#, since only in the rare case where the
|
||||||
@ -3547,6 +3560,15 @@ nfsvno_v4rootexport(struct nfsrv_descript *nd)
|
|||||||
nd->nd_flag |= ND_EXGSSPRIVACY;
|
nd->nd_flag |= ND_EXGSSPRIVACY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* And set ND_EXxx flags for TLS. */
|
||||||
|
if ((exflags & MNT_EXTLS) != 0) {
|
||||||
|
nd->nd_flag |= ND_EXTLS;
|
||||||
|
if ((exflags & MNT_EXTLSCERT) != 0)
|
||||||
|
nd->nd_flag |= ND_EXTLSCERT;
|
||||||
|
if ((exflags & MNT_EXTLSCERTUSER) != 0)
|
||||||
|
nd->nd_flag |= ND_EXTLSCERTUSER;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
NFSEXITCODE(error);
|
NFSEXITCODE(error);
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -3816,6 +3816,11 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram,
|
|||||||
clp->lc_uid = nd->nd_cred->cr_uid;
|
clp->lc_uid = nd->nd_cred->cr_uid;
|
||||||
clp->lc_gid = nd->nd_cred->cr_gid;
|
clp->lc_gid = nd->nd_cred->cr_gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the client is using TLS, do so for the callback connection. */
|
||||||
|
if (nd->nd_flag & ND_TLS)
|
||||||
|
clp->lc_flags |= LCL_TLSCB;
|
||||||
|
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
clp->lc_program = fxdr_unsigned(u_int32_t, *tl);
|
clp->lc_program = fxdr_unsigned(u_int32_t, *tl);
|
||||||
error = nfsrv_getclientipaddr(nd, clp);
|
error = nfsrv_getclientipaddr(nd, clp);
|
||||||
|
@ -2114,15 +2114,28 @@ nfsd_checkrootexp(struct nfsrv_descript *nd)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS)
|
if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS)
|
||||||
return (0);
|
goto checktls;
|
||||||
if ((nd->nd_flag & (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) ==
|
if ((nd->nd_flag & (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) ==
|
||||||
(ND_GSSINTEGRITY | ND_EXGSSINTEGRITY))
|
(ND_GSSINTEGRITY | ND_EXGSSINTEGRITY))
|
||||||
return (0);
|
goto checktls;
|
||||||
if ((nd->nd_flag & (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) ==
|
if ((nd->nd_flag & (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) ==
|
||||||
(ND_GSSPRIVACY | ND_EXGSSPRIVACY))
|
(ND_GSSPRIVACY | ND_EXGSSPRIVACY))
|
||||||
return (0);
|
goto checktls;
|
||||||
if ((nd->nd_flag & (ND_GSS | ND_GSSINTEGRITY | ND_GSSPRIVACY |
|
if ((nd->nd_flag & (ND_GSS | ND_GSSINTEGRITY | ND_GSSPRIVACY |
|
||||||
ND_EXGSS)) == (ND_GSS | ND_EXGSS))
|
ND_EXGSS)) == (ND_GSS | ND_EXGSS))
|
||||||
|
goto checktls;
|
||||||
|
return (1);
|
||||||
|
checktls:
|
||||||
|
if ((nd->nd_flag & ND_EXTLS) == 0)
|
||||||
|
return (0);
|
||||||
|
if ((nd->nd_flag & (ND_TLSCERTUSER | ND_EXTLSCERTUSER)) ==
|
||||||
|
(ND_TLSCERTUSER | ND_EXTLSCERTUSER))
|
||||||
|
return (0);
|
||||||
|
if ((nd->nd_flag & (ND_TLSCERT | ND_EXTLSCERT | ND_EXTLSCERTUSER)) ==
|
||||||
|
(ND_TLSCERT | ND_EXTLSCERT))
|
||||||
|
return (0);
|
||||||
|
if ((nd->nd_flag & (ND_TLS | ND_EXTLSCERTUSER | ND_EXTLSCERT)) ==
|
||||||
|
ND_TLS)
|
||||||
return (0);
|
return (0);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user