aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfs
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2023-03-16 22:55:36 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2023-03-16 22:55:36 +0000
commit896516e54a8c39c1c8be3ad918f38fbf196b57ed (patch)
tree116c337528af4ae55f6bc709b628bd94f1263aed /sys/fs/nfs
parent58436df347de665f6bc635a0e3018fc6f3d0a656 (diff)
downloadsrc-896516e54a8c39c1c8be3ad918f38fbf196b57ed.tar.gz
src-896516e54a8c39c1c8be3ad918f38fbf196b57ed.zip
Diffstat (limited to 'sys/fs/nfs')
-rw-r--r--sys/fs/nfs/nfs.h7
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c86
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c17
-rw-r--r--sys/fs/nfs/nfs_var.h5
-rw-r--r--sys/fs/nfs/nfsport.h1
5 files changed, 108 insertions, 8 deletions
diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h
index ffd612331c1f..eac318512a35 100644
--- a/sys/fs/nfs/nfs.h
+++ b/sys/fs/nfs/nfs.h
@@ -522,6 +522,13 @@ typedef struct {
(b)->bits[2] = NFSGETATTRBIT_STATFS2; \
} while (0)
+#define NFSROOTFS_GETATTRBIT(b) do { \
+ (b)->bits[0] = NFSGETATTRBIT_STATFS0 | NFSATTRBIT_GETATTR0 | \
+ NFSATTRBM_LEASETIME; \
+ (b)->bits[1] = NFSGETATTRBIT_STATFS1 | NFSATTRBIT_GETATTR1; \
+ (b)->bits[2] = NFSGETATTRBIT_STATFS2 | NFSATTRBIT_GETATTR2; \
+} while (0)
+
#define NFSISSETSTATFS_ATTRBIT(b) \
(((b)->bits[0] & NFSATTRBIT_STATFS0) || \
((b)->bits[1] & NFSATTRBIT_STATFS1) || \
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 9badd8be47d4..f98d9f8df99a 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -163,6 +163,87 @@ static int nfsv2_procid[NFS_V3NPROCS] = {
};
/*
+ * This static array indicates that a NFSv4 RPC should use
+ * RPCSEC_GSS, if the mount indicates that via sec=krb5[ip].
+ * System RPCs that do not use file handles will be false
+ * in this array so that they will use AUTH_SYS when the
+ * "syskrb5" mount option is specified, along with
+ * "sec=krb5[ip]".
+ */
+static bool nfscl_use_gss[NFSV42_NPROCS] = {
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false, /* SetClientID */
+ false, /* SetClientIDConfirm */
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false, /* Renew */
+ true,
+ false, /* ReleaseLockOwn */
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false, /* ExchangeID */
+ false, /* CreateSession */
+ false, /* DestroySession */
+ false, /* DestroyClientID */
+ false, /* FreeStateID */
+ true,
+ true,
+ true,
+ true,
+ false, /* ReclaimComplete */
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false, /* BindConnectionToSession */
+ true,
+ true,
+ true,
+ true,
+};
+
+/*
* Initialize sockets and congestion for a new NFS connection.
* We do not free the sockaddr if error.
* Which arguments are set to NULL indicate what kind of call it is.
@@ -679,7 +760,8 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
}
NFSUNLOCKSTATE();
} else if (nmp != NULL && NFSHASKERB(nmp) &&
- nd->nd_procnum != NFSPROC_NULL) {
+ nd->nd_procnum != NFSPROC_NULL && (!NFSHASSYSKRB5(nmp) ||
+ nfscl_use_gss[nd->nd_procnum])) {
if (NFSHASALLGSSNAME(nmp) && nmp->nm_krbnamelen > 0)
nd->nd_flag |= ND_USEGSSNAME;
if ((nd->nd_flag & ND_USEGSSNAME) != 0) {
@@ -720,7 +802,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
else
secflavour = RPCSEC_GSS_KRB5;
srv_principal = NFSMNT_SRVKRBNAME(nmp);
- } else if (nmp != NULL && !NFSHASKERB(nmp) &&
+ } else if (nmp != NULL && (!NFSHASKERB(nmp) || NFSHASSYSKRB5(nmp)) &&
nd->nd_procnum != NFSPROC_NULL &&
(nd->nd_flag & ND_USEGSSNAME) != 0) {
/*
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index e2e15063cf99..9e70eea522c4 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet6.h"
#include <fs/nfs/nfsport.h>
+#include <fs/nfsclient/nfsmount.h>
#include <sys/extattr.h>
@@ -436,7 +437,7 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV4OP_PUTFH);
- (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
+ nfsm_fhtom(nmp, nd, nfhp, fhlen, 0);
if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh
== 2 && procnum != NFSPROC_WRITEDS &&
procnum != NFSPROC_COMMITDS) {
@@ -467,7 +468,7 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
*tl = txdr_unsigned(nfsv4_opmap[procnum].op);
}
} else {
- (void) nfsm_fhtom(nd, nfhp, fhlen, 0);
+ nfsm_fhtom(NULL, nd, nfhp, fhlen, 0);
}
if (procnum < NFSV42_NPROCS)
NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]);
@@ -953,12 +954,15 @@ newnfs_init(void)
* Return the number of bytes output, including XDR overhead.
*/
int
-nfsm_fhtom(struct nfsrv_descript *nd, u_int8_t *fhp, int size, int set_true)
+nfsm_fhtom(struct nfsmount *nmp, struct nfsrv_descript *nd, u_int8_t *fhp,
+ int size, int set_true)
{
u_int32_t *tl;
u_int8_t *cp;
int fullsiz, bytesize = 0;
+ KASSERT(nmp == NULL || nmp->nm_fhsize > 0,
+ ("nfsm_fhtom: 0 length fh"));
if (size == 0)
size = NFSX_MYFH;
switch (nd->nd_flag & (ND_NFSV2 | ND_NFSV3 | ND_NFSV4)) {
@@ -973,6 +977,11 @@ nfsm_fhtom(struct nfsrv_descript *nd, u_int8_t *fhp, int size, int set_true)
break;
case ND_NFSV3:
case ND_NFSV4:
+ if (size == NFSX_FHMAX + 1 && nmp != NULL &&
+ (nmp->nm_privflag & NFSMNTP_FAKEROOTFH) != 0) {
+ fhp = nmp->nm_fh;
+ size = nmp->nm_fhsize;
+ }
fullsiz = NFSM_RNDUP(size);
if (set_true) {
bytesize = 2 * NFSX_UNSIGNED + fullsiz;
@@ -2737,7 +2746,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
retnum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_FILEHANDLE:
- retnum += nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0);
+ retnum += nfsm_fhtom(NULL, nd, (u_int8_t *)fhp, 0, 0);
break;
case NFSATTRBIT_FILEID:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 0a6d46964ffd..55396bfb0902 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -327,7 +327,8 @@ int nfsaddr_match(int, union nethostaddr *, NFSSOCKADDR_T);
int nfsaddr2_match(NFSSOCKADDR_T, NFSSOCKADDR_T);
int nfsm_strtom(struct nfsrv_descript *, const char *, int);
int nfsm_mbufuio(struct nfsrv_descript *, struct uio *, int);
-int nfsm_fhtom(struct nfsrv_descript *, u_int8_t *, int, int);
+int nfsm_fhtom(struct nfsmount *, struct nfsrv_descript *, u_int8_t *, int,
+ int);
int nfsm_advance(struct nfsrv_descript *, int, int);
void *nfsm_dissct(struct nfsrv_descript *, int, int);
void newnfs_copycred(struct nfscred *, struct ucred *);
@@ -510,7 +511,7 @@ int nfsrpc_lockt(struct nfsrv_descript *, vnode_t,
int nfsrpc_lock(struct nfsrv_descript *, struct nfsmount *, vnode_t,
u_int8_t *, int, struct nfscllockowner *, int, int, u_int64_t,
u_int64_t, short, struct ucred *, NFSPROC_T *, int);
-int nfsrpc_statfs(vnode_t, struct nfsstatfs *, struct nfsfsinfo *,
+int nfsrpc_statfs(vnode_t, struct nfsstatfs *, struct nfsfsinfo *, uint32_t *,
struct ucred *, NFSPROC_T *, struct nfsvattr *, int *);
int nfsrpc_fsinfo(vnode_t, struct nfsfsinfo *, struct ucred *,
NFSPROC_T *, struct nfsvattr *, int *);
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index 3a07d140950c..23e806ab8c47 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -1085,6 +1085,7 @@ void ncl_copy_vattr(struct vattr *dst, struct vattr *src);
#define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \
(n)->nm_minorvers > 0)
#define NFSHASTLS(n) (((n)->nm_newflag & NFSMNT_TLS) != 0)
+#define NFSHASSYSKRB5(n) (((n)->nm_newflag & NFSMNT_SYSKRB5) != 0)
/*
* Set boottime.