Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfsserver/nfs_nfsdsubs.c
Show All 38 Lines | |||||
/* | /* | ||||
* These functions support the macros and help fiddle mbuf chains for | * These functions support the macros and help fiddle mbuf chains for | ||||
* the nfs op functions. They do things like create the rpc header and | * the nfs op functions. They do things like create the rpc header and | ||||
* copy data between mbuf chains and uio lists. | * copy data between mbuf chains and uio lists. | ||||
*/ | */ | ||||
#include <fs/nfs/nfsport.h> | #include <fs/nfs/nfsport.h> | ||||
extern u_int32_t newnfs_true, newnfs_false; | extern u_int32_t newnfs_true, newnfs_false; | ||||
extern int nfs_rootfhset; | |||||
extern int nfs_pubfhset; | extern int nfs_pubfhset; | ||||
extern struct nfsclienthashhead *nfsclienthash; | |||||
extern int nfsrv_clienthashsize; | extern int nfsrv_clienthashsize; | ||||
extern struct nfslockhashhead *nfslockhash; | |||||
extern int nfsrv_lockhashsize; | extern int nfsrv_lockhashsize; | ||||
extern struct nfssessionhash *nfssessionhash; | |||||
extern int nfsrv_sessionhashsize; | extern int nfsrv_sessionhashsize; | ||||
extern int nfsrv_useacl; | extern int nfsrv_useacl; | ||||
extern uid_t nfsrv_defaultuid; | extern uid_t nfsrv_defaultuid; | ||||
extern gid_t nfsrv_defaultgid; | extern gid_t nfsrv_defaultgid; | ||||
NFSD_VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash); | |||||
NFSD_VNET_DECLARE(struct nfslockhashhead *, nfslockhash); | |||||
NFSD_VNET_DECLARE(struct nfssessionhash *, nfssessionhash); | |||||
NFSD_VNET_DECLARE(int, nfs_rootfhset); | |||||
NFSD_VNET_DECLARE(uid_t, nfsrv_defaultuid); | |||||
NFSD_VNET_DECLARE(gid_t, nfsrv_defaultgid); | |||||
NFSD_VNET_DEFINE(struct nfsdontlisthead, nfsrv_dontlisthead); | |||||
char nfs_v2pubfh[NFSX_V2FH]; | char nfs_v2pubfh[NFSX_V2FH]; | ||||
struct nfsdontlisthead nfsrv_dontlisthead; | struct nfsdontlisthead nfsrv_dontlisthead; | ||||
struct nfslayouthead nfsrv_recalllisthead; | struct nfslayouthead nfsrv_recalllisthead; | ||||
static nfstype newnfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, | static nfstype newnfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, | ||||
NFNON, NFCHR, NFNON }; | NFNON, NFCHR, NFNON }; | ||||
extern nfstype nfsv34_type[9]; | extern nfstype nfsv34_type[9]; | ||||
static u_int32_t nfsrv_isannfserr(u_int32_t); | static u_int32_t nfsrv_isannfserr(u_int32_t); | ||||
▲ Show 20 Lines • Show All 1,535 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int error = 0; | int error = 0; | ||||
/* | /* | ||||
* If not setting either uid nor gid, it's OK. | * If not setting either uid nor gid, it's OK. | ||||
*/ | */ | ||||
if (NFSVNO_NOTSETUID(nvap) && NFSVNO_NOTSETGID(nvap)) | if (NFSVNO_NOTSETUID(nvap) && NFSVNO_NOTSETGID(nvap)) | ||||
goto out; | goto out; | ||||
if ((NFSVNO_ISSETUID(nvap) && nvap->na_uid == nfsrv_defaultuid && | if ((NFSVNO_ISSETUID(nvap) && | ||||
enable_nobodycheck == 1) | nvap->na_uid == NFSD_VNET(nfsrv_defaultuid) && | ||||
|| (NFSVNO_ISSETGID(nvap) && nvap->na_gid == nfsrv_defaultgid && | enable_nobodycheck == 1) || | ||||
(NFSVNO_ISSETGID(nvap) && | |||||
nvap->na_gid == NFSD_VNET(nfsrv_defaultgid) && | |||||
enable_nogroupcheck == 1)) { | enable_nogroupcheck == 1)) { | ||||
error = NFSERR_BADOWNER; | error = NFSERR_BADOWNER; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (nd->nd_cred->cr_uid == 0) | if (nd->nd_cred->cr_uid == 0) | ||||
goto out; | goto out; | ||||
if ((NFSVNO_ISSETUID(nvap) && nvap->na_uid != nd->nd_cred->cr_uid) || | if ((NFSVNO_ISSETUID(nvap) && nvap->na_uid != nd->nd_cred->cr_uid) || | ||||
(NFSVNO_ISSETGID(nvap) && nvap->na_gid != nd->nd_cred->cr_gid && | (NFSVNO_ISSETGID(nvap) && nvap->na_gid != nd->nd_cred->cr_gid && | ||||
!groupmember(nvap->na_gid, nd->nd_cred))) | !groupmember(nvap->na_gid, nd->nd_cred))) | ||||
▲ Show 20 Lines • Show All 453 Lines • ▼ Show 20 Lines | nfsmout: | ||||
NFSEXITCODE2(error, nd); | NFSEXITCODE2(error, nd); | ||||
return (error); | return (error); | ||||
} | } | ||||
void | void | ||||
nfsd_init(void) | nfsd_init(void) | ||||
{ | { | ||||
int i; | int i; | ||||
static int inited = 0; | |||||
if (inited) | |||||
return; | |||||
inited = 1; | |||||
/* | /* | ||||
* Initialize client queues. Don't free/reinitialize | * Initialize client queues. Don't free/reinitialize | ||||
* them when nfsds are restarted. | * them when nfsds are restarted. | ||||
*/ | */ | ||||
nfsclienthash = malloc(sizeof(struct nfsclienthashhead) * | NFSD_VNET(nfsclienthash) = malloc(sizeof(struct nfsclienthashhead) * | ||||
nfsrv_clienthashsize, M_NFSDCLIENT, M_WAITOK | M_ZERO); | nfsrv_clienthashsize, M_NFSDCLIENT, M_WAITOK | M_ZERO); | ||||
for (i = 0; i < nfsrv_clienthashsize; i++) | for (i = 0; i < nfsrv_clienthashsize; i++) | ||||
LIST_INIT(&nfsclienthash[i]); | LIST_INIT(&NFSD_VNET(nfsclienthash)[i]); | ||||
nfslockhash = malloc(sizeof(struct nfslockhashhead) * | NFSD_VNET(nfslockhash) = malloc(sizeof(struct nfslockhashhead) * | ||||
nfsrv_lockhashsize, M_NFSDLOCKFILE, M_WAITOK | M_ZERO); | nfsrv_lockhashsize, M_NFSDLOCKFILE, M_WAITOK | M_ZERO); | ||||
for (i = 0; i < nfsrv_lockhashsize; i++) | for (i = 0; i < nfsrv_lockhashsize; i++) | ||||
LIST_INIT(&nfslockhash[i]); | LIST_INIT(&NFSD_VNET(nfslockhash)[i]); | ||||
nfssessionhash = malloc(sizeof(struct nfssessionhash) * | NFSD_VNET(nfssessionhash) = malloc(sizeof(struct nfssessionhash) * | ||||
nfsrv_sessionhashsize, M_NFSDSESSION, M_WAITOK | M_ZERO); | nfsrv_sessionhashsize, M_NFSDSESSION, M_WAITOK | M_ZERO); | ||||
for (i = 0; i < nfsrv_sessionhashsize; i++) { | for (i = 0; i < nfsrv_sessionhashsize; i++) { | ||||
mtx_init(&nfssessionhash[i].mtx, "nfssm", NULL, MTX_DEF); | mtx_init(&NFSD_VNET(nfssessionhash)[i].mtx, "nfssm", NULL, | ||||
LIST_INIT(&nfssessionhash[i].list); | MTX_DEF); | ||||
LIST_INIT(&NFSD_VNET(nfssessionhash)[i].list); | |||||
} | } | ||||
LIST_INIT(&nfsrv_dontlisthead); | LIST_INIT(&nfsrv_dontlisthead); | ||||
TAILQ_INIT(&nfsrv_recalllisthead); | TAILQ_INIT(&nfsrv_recalllisthead); | ||||
/* and the v2 pubfh should be all zeros */ | /* and the v2 pubfh should be all zeros */ | ||||
NFSBZERO(nfs_v2pubfh, NFSX_V2FH); | NFSBZERO(nfs_v2pubfh, NFSX_V2FH); | ||||
} | } | ||||
/* | /* | ||||
* Check the v4 root exports. | * Check the v4 root exports. | ||||
* Return 0 if ok, 1 otherwise. | * Return 0 if ok, 1 otherwise. | ||||
*/ | */ | ||||
int | int | ||||
nfsd_checkrootexp(struct nfsrv_descript *nd) | nfsd_checkrootexp(struct nfsrv_descript *nd) | ||||
{ | { | ||||
if (nfs_rootfhset == 0) | if (NFSD_VNET(nfs_rootfhset) == 0) | ||||
return (NFSERR_AUTHERR | AUTH_FAILED); | return (NFSERR_AUTHERR | AUTH_FAILED); | ||||
/* | /* | ||||
* For NFSv4.1/4.2, if the client specifies SP4_NONE, then these | * For NFSv4.1/4.2, if the client specifies SP4_NONE, then these | ||||
* operations are allowed regardless of the value of the "sec=XXX" | * operations are allowed regardless of the value of the "sec=XXX" | ||||
* field in the V4: exports line. | * field in the V4: exports line. | ||||
* For SP4_MACH_CRED, the check for Kerberos with Integrity or | |||||
* Privacy will be done later in the functions, once a ClientID | |||||
* is referenced. | |||||
* As such, these Kerberos checks only apply to NFSv4.0 mounts. | * As such, these Kerberos checks only apply to NFSv4.0 mounts. | ||||
*/ | */ | ||||
if ((nd->nd_flag & ND_NFSV41) != 0) | if ((nd->nd_flag & ND_NFSV41) != 0) | ||||
goto checktls; | goto checktls; | ||||
if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS) | if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS) | ||||
goto checktls; | 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)) | ||||
▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines |