diff options
Diffstat (limited to 'sys/fs/nfs/nfs_commonsubs.c')
-rw-r--r-- | sys/fs/nfs/nfs_commonsubs.c | 337 |
1 files changed, 247 insertions, 90 deletions
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 3c9af40253ad..a957315aaa12 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -135,7 +135,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = { { 1, 2, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Lookupp */ { 0, 1, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* NVerify */ { 1, 1, 0, 1, LK_EXCLUSIVE, 1, 0 }, /* Open */ - { 1, 1, 0, 0, LK_EXCLUSIVE, 1, 0 }, /* OpenAttr */ + { 1, 1, 1, 1, LK_EXCLUSIVE, 1, 1 }, /* OpenAttr */ { 0, 1, 0, 0, LK_EXCLUSIVE, 1, 0 }, /* OpenConfirm */ { 0, 1, 0, 0, LK_EXCLUSIVE, 1, 0 }, /* OpenDowngrade */ { 1, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* PutFH */ @@ -219,18 +219,19 @@ NFSD_VNET_DEFINE_STATIC(u_char *, nfsrv_dnsname) = NULL; static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 0, 0, 0 }; + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); static void nfsv4_wanted(struct nfsv4lock *lp); static uint32_t nfsv4_filesavail(struct statfs *, struct mount *); -static int nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len); static int nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name); static void nfsrv_removeuser(struct nfsusrgrp *usrp, int isuser); static int nfsrv_getrefstr(struct nfsrv_descript *, u_char **, u_char **, int *, int *); static void nfsrv_refstrbigenough(int, u_char **, u_char **, int *); +static uint32_t vtonfsv4_type(struct vattr *); +static __enum_uint8(vtype) nfsv4tov_type(uint32_t, uint16_t *); static struct { int op; @@ -250,10 +251,10 @@ static struct { { NFSV4OP_CREATE, 5, "Create", 6, }, { NFSV4OP_CREATE, 1, "Create", 6, }, { NFSV4OP_CREATE, 3, "Create", 6, }, + { NFSV4OP_REMOVE, 3, "Remove", 6, }, { NFSV4OP_REMOVE, 1, "Remove", 6, }, - { NFSV4OP_REMOVE, 1, "Remove", 6, }, - { NFSV4OP_SAVEFH, 5, "Rename", 6, }, - { NFSV4OP_SAVEFH, 4, "Link", 4, }, + { NFSV4OP_SAVEFH, 7, "Rename", 6, }, + { NFSV4OP_SAVEFH, 6, "Link", 4, }, { NFSV4OP_READDIR, 2, "Readdir", 7, }, { NFSV4OP_READDIR, 2, "Readdir", 7, }, { NFSV4OP_GETATTR, 1, "Getattr", 7, }, @@ -308,6 +309,7 @@ static struct { { NFSV4OP_DEALLOCATE, 2, "Deallocate", 10, }, { NFSV4OP_LAYOUTERROR, 1, "LayoutError", 11, }, { NFSV4OP_VERIFY, 3, "AppendWrite", 11, }, + { NFSV4OP_OPENATTR, 3, "OpenAttr", 8, }, }; /* @@ -317,7 +319,7 @@ static int nfs_bigrequest[NFSV42_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 1 + 0, 1, 0 }; /* @@ -610,32 +612,43 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap, break; case ND_NFSV4: NFSZERO_ATTRBIT(&attrbits); - if (vap->va_mode != (mode_t)VNOVAL) - NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_MODE); + np = NULL; + if (strcmp(vp->v_mount->mnt_vfc->vfc_name, "nfs") == 0) + np = VTONFS(vp); + if (vap->va_mode != (mode_t)VNOVAL) { + if ((flags & NFSSATTR_NEWFILE) != 0 && np != NULL && + NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, + NFSATTRBIT_MODEUMASK)) + NFSSETBIT_ATTRBIT(&attrbits, + NFSATTRBIT_MODEUMASK); + else + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_MODE); + } if ((flags & NFSSATTR_FULL) && vap->va_uid != (uid_t)VNOVAL) NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNER); if ((flags & NFSSATTR_FULL) && vap->va_gid != (gid_t)VNOVAL) NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNERGROUP); if ((flags & NFSSATTR_FULL) && vap->va_size != VNOVAL) NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE); + if ((flags & NFSSATTR_FULL) && vap->va_flags != VNOVAL) { + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN); + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM); + } if (vap->va_atime.tv_sec != VNOVAL) NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESSSET); if (vap->va_mtime.tv_sec != VNOVAL) NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFYSET); - if (vap->va_birthtime.tv_sec != VNOVAL && - strcmp(vp->v_mount->mnt_vfc->vfc_name, "nfs") == 0) { - /* - * We can only test for support of TimeCreate if - * the "vp" argument is for an NFS vnode. - */ - np = VTONFS(vp); - if (NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, - NFSATTRBIT_TIMECREATE)) - NFSSETBIT_ATTRBIT(&attrbits, - NFSATTRBIT_TIMECREATE); - } + /* + * We can only test for support of TimeCreate if + * the "vp" argument is for an NFS vnode. + */ + if (vap->va_birthtime.tv_sec != VNOVAL && np != NULL && + NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, + NFSATTRBIT_TIMECREATE)) + NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE); (void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0, - &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL); + &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL, + false, false, false); break; } } @@ -980,6 +993,17 @@ nfsm_fhtom(struct nfsmount *nmp, struct nfsrv_descript *nd, u_int8_t *fhp, (nmp->nm_privflag & NFSMNTP_FAKEROOTFH) != 0) { fhp = nmp->nm_fh; size = nmp->nm_fhsize; + } else if (size >= NFSX_FHMAX + NFSX_V4NAMEDDIRFH && + size <= NFSX_FHMAX + NFSX_V4NAMEDATTRFH) { + size -= (NFSX_FHMAX - NFSX_MYFH); + NFSM_BUILD(tl, uint32_t *, NFSX_MYFH + + 2 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(size); + NFSBCOPY(fhp, tl, NFSX_MYFH); + tl += (NFSX_MYFH / NFSX_UNSIGNED); + *tl = 0; + bytesize = NFSX_MYFH + 2 * NFSX_UNSIGNED; + break; } fullsiz = NFSM_RNDUP(size); if (set_true) { @@ -1277,7 +1301,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nap, struct nfsfh **nfhpp, fhandle_t *fhp, int fhsize, struct nfsv3_pathconf *pc, struct statfs *sbp, struct nfsstatfs *sfp, struct nfsfsinfo *fsp, NFSACL_T *aclp, int compare, int *retcmpp, - u_int32_t *leasep, u_int32_t *rderrp, NFSPROC_T *p, struct ucred *cred) + u_int32_t *leasep, u_int32_t *rderrp, bool *has_namedattrp, + NFSPROC_T *p, struct ucred *cred) { u_int32_t *tl; int i = 0, j, k, l = 0, m, bitpos, attrsum = 0; @@ -1293,6 +1318,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, gid_t gid; u_int32_t freenum = 0, tuint; u_int64_t uquad = 0, thyp, thyp2; + uint16_t tui16; + long has_pathconf; #ifdef QUOTA struct dqblk dqb; uid_t savuid; @@ -1316,6 +1343,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, * Just set default values to some of the important ones. */ if (nap != NULL) { + VATTR_NULL(&nap->na_vattr); nap->na_type = VREG; nap->na_mode = 0; nap->na_rdev = (NFSDEV_T)0; @@ -1365,6 +1393,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, sfp->sf_tbytes = UINT64_MAX; sfp->sf_abytes = UINT64_MAX; } + if (has_namedattrp != NULL) + *has_namedattrp = false; } /* @@ -1397,6 +1427,16 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, NFSCLRBIT_ATTRBIT(&checkattrbits, NFSATTRBIT_ACL); NFSCLRBIT_ATTRBIT(&checkattrbits, NFSATTRBIT_ACLSUPPORT); } + /* Some filesystems do not support uf_hidden */ + if (vp == NULL || VOP_PATHCONF(vp, + _PC_HAS_HIDDENSYSTEM, &has_pathconf) != 0) + has_pathconf = 0; + if (has_pathconf == 0) { + NFSCLRBIT_ATTRBIT(&checkattrbits, + NFSATTRBIT_HIDDEN); + NFSCLRBIT_ATTRBIT(&checkattrbits, + NFSATTRBIT_SYSTEM); + } if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits) || retnotsup) *retcmpp = NFSERR_NOTSAME; @@ -1407,11 +1447,16 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); if (compare) { if (!(*retcmpp)) { - if (nap->na_type != nfsv34tov_type(*tl)) + tui16 = 0; + if (nap->na_type != nfsv4tov_type(*tl, + &tui16) || + ((nap->na_bsdflags & SFBSD_NAMEDATTR) ^ + tui16) != 0) *retcmpp = NFSERR_NOTSAME; } } else if (nap != NULL) { - nap->na_type = nfsv34tov_type(*tl); + nap->na_type = nfsv4tov_type(*tl, + &nap->na_bsdflags); } attrsum += NFSX_UNSIGNED; break; @@ -1490,9 +1535,23 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, break; case NFSATTRBIT_NAMEDATTR: NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - if (compare && !(*retcmpp)) { - if (*tl != newnfs_false) - *retcmpp = NFSERR_NOTSAME; + if (compare) { + if (!(*retcmpp)) { + if (vp == NULL || VOP_PATHCONF(vp, + _PC_HAS_NAMEDATTR, &has_pathconf) + != 0) + has_pathconf = 0; + if ((has_pathconf != 0 && + *tl != newnfs_true) || + (has_pathconf == 0 && + *tl != newnfs_false)) + *retcmpp = NFSERR_NOTSAME; + } + } else if (has_namedattrp != NULL) { + if (*tl == newnfs_true) + *has_namedattrp = true; + else + *has_namedattrp = false; } attrsum += NFSX_UNSIGNED; break; @@ -1666,6 +1725,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, goto nfsmout; tfhsize = tnfhp->nfh_len; if (compare) { + if (tfhsize > NFSX_MYFH) + tfhsize = NFSX_MYFH; if (!(*retcmpp) && !NFSRV_CMPFH(tnfhp->nfh_fh, tfhsize, fhp, fhsize)) @@ -1745,9 +1806,17 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, free(cp2, M_NFSSTRING); break; case NFSATTRBIT_HIDDEN: - NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - if (compare && !(*retcmpp)) - *retcmpp = NFSERR_ATTRNOTSUPP; + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + if (compare) { + if (!(*retcmpp) && ((*tl == newnfs_true && + (nap->na_flags & UF_HIDDEN) == 0) || + (*tl == newnfs_false && + (nap->na_flags & UF_HIDDEN) != 0))) + *retcmpp = NFSERR_NOTSAME; + } else if (nap != NULL) { + if (*tl == newnfs_true) + nap->na_flags |= UF_HIDDEN; + } attrsum += NFSX_UNSIGNED; break; case NFSATTRBIT_HOMOGENEOUS: @@ -2119,9 +2188,17 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, attrsum += NFSX_HYPER; break; case NFSATTRBIT_SYSTEM: - NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - if (compare && !(*retcmpp)) - *retcmpp = NFSERR_ATTRNOTSUPP; + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + if (compare) { + if (!(*retcmpp) && ((*tl == newnfs_true && + (nap->na_flags & UF_SYSTEM) == 0) || + (*tl == newnfs_false && + (nap->na_flags & UF_SYSTEM) != 0))) + *retcmpp = NFSERR_NOTSAME; + } else if (nap != NULL) { + if (*tl == newnfs_true) + nap->na_flags |= UF_SYSTEM; + } attrsum += NFSX_UNSIGNED; break; case NFSATTRBIT_TIMEACCESS: @@ -2297,6 +2374,23 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, if (compare && !(*retcmpp) && i != nfs_srvmaxio) *retcmpp = NFSERR_NOTSAME; break; + case NFSATTRBIT_CHANGEATTRTYPE: + NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); + if (compare) { + if (!(*retcmpp)) { + tuint = NFSV4CHANGETYPE_UNDEFINED; + if ((vp->v_mount->mnt_vfc->vfc_flags & + VFCF_FILEREVINC) != 0) + tuint = NFSV4CHANGETYPE_VERS_COUNTER_NOPNFS; + else if ((vp->v_mount->mnt_vfc->vfc_flags & + VFCF_FILEREVCT) != 0) + tuint = NFSV4CHANGETYPE_TIME_METADATA; + if (fxdr_unsigned(uint32_t, *tl) != tuint) + *retcmpp = NFSERR_NOTSAME; + } + } + attrsum += NFSX_UNSIGNED; + break; default: printf("EEK! nfsv4_loadattr unknown attr=%d\n", bitpos); @@ -2553,7 +2647,8 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram, int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno, - struct statfs *pnfssf) + struct statfs *pnfssf, bool xattrsupp, bool has_hiddensystem, + bool has_namedattr) { int bitpos, retnum = 0; u_int32_t *tl; @@ -2567,8 +2662,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, struct nfsfsinfo fsinf; struct timespec temptime; NFSACL_T *aclp, *naclp = NULL; - size_t atsiz; - bool xattrsupp; + short irflag; #ifdef QUOTA struct dqblk dqb; uid_t savuid; @@ -2652,18 +2746,6 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, } } - /* Check to see if Extended Attributes are supported. */ - xattrsupp = false; - if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_XATTRSUPPORT)) { - if (NFSVOPLOCK(vp, LK_SHARED) == 0) { - error = VOP_GETEXTATTR(vp, EXTATTR_NAMESPACE_USER, - "xxx", NULL, &atsiz, cred, p); - NFSVOPUNLOCK(vp); - if (error != EOPNOTSUPP) - xattrsupp = true; - } - } - /* * Put out the attribute bitmap for the ones being filled in * and get the field for the number of attributes returned. @@ -2685,11 +2767,15 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT); NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACL); } + if (!has_hiddensystem) { + NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN); + NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM); + } retnum += nfsrv_putattrbit(nd, &attrbits); break; case NFSATTRBIT_TYPE: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = vtonfsv34_type(vap->va_type); + *tl = vtonfsv4_type(vap); retnum += NFSX_UNSIGNED; break; case NFSATTRBIT_FHEXPIRETYPE: @@ -2725,7 +2811,10 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, break; case NFSATTRBIT_NAMEDATTR: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = newnfs_false; + if (has_namedattr) + *tl = newnfs_true; + else + *tl = newnfs_false; retnum += NFSX_UNSIGNED; break; case NFSATTRBIT_FSID: @@ -2786,7 +2875,15 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, retnum += NFSX_UNSIGNED; break; case NFSATTRBIT_FILEHANDLE: - retnum += nfsm_fhtom(NULL, nd, (u_int8_t *)fhp, 0, 0); + siz = 0; + if (vp != NULL) { + irflag = vn_irflag_read(vp); + if ((irflag & VIRF_NAMEDDIR) != 0) + siz = NFSX_FHMAX + 2; + else if ((irflag & VIRF_NAMEDATTR) != 0) + siz = NFSX_FHMAX + 3; + } + retnum += nfsm_fhtom(NULL, nd, (u_int8_t *)fhp, siz, 0); break; case NFSATTRBIT_FILEID: NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER); @@ -2819,6 +2916,14 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, *tl = 0; retnum += 2 * NFSX_UNSIGNED; break; + case NFSATTRBIT_HIDDEN: + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + if ((vap->va_flags & UF_HIDDEN) != 0) + *tl = newnfs_true; + else + *tl = newnfs_false; + retnum += NFSX_UNSIGNED; + break; case NFSATTRBIT_HOMOGENEOUS: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); if (fsinf.fs_properties & NFSV3FSINFO_HOMOGENEOUS) @@ -3008,6 +3113,14 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, txdr_hyper(vap->va_bytes, tl); retnum += NFSX_HYPER; break; + case NFSATTRBIT_SYSTEM: + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + if ((vap->va_flags & UF_SYSTEM) != 0) + *tl = newnfs_true; + else + *tl = newnfs_false; + retnum += NFSX_UNSIGNED; + break; case NFSATTRBIT_TIMEACCESS: NFSM_BUILD(tl, u_int32_t *, NFSX_V4TIME); txdr_nfsv4time(&vap->va_atime, tl); @@ -3109,6 +3222,33 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, *tl = newnfs_false; retnum += NFSX_UNSIGNED; break; + case NFSATTRBIT_MODEUMASK: + NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); + /* + * Since FreeBSD applies the umask above the VFS/VOP, + * there is no umask to handle here. If FreeBSD + * moves handling of umask to below the VFS/VOP, + * this could change. + */ + *tl++ = vtonfsv34_mode(vap->va_mode); + *tl = 0; + retnum += 2 * NFSX_UNSIGNED; + break; + case NFSATTRBIT_CHANGEATTRTYPE: + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4CHANGETYPE_UNDEFINED); + if (mp != NULL) { + if ((mp->mnt_vfc->vfc_flags & + VFCF_FILEREVINC) != 0) + *tl = txdr_unsigned( + NFSV4CHANGETYPE_VERS_COUNTER_NOPNFS); + else if ((mp->mnt_vfc->vfc_flags & + VFCF_FILEREVCT) != 0) + *tl = txdr_unsigned( + NFSV4CHANGETYPE_TIME_METADATA); + } + retnum += NFSX_UNSIGNED; + break; default: printf("EEK! Bad V4 attribute bitpos=%d\n", bitpos); } @@ -3419,13 +3559,13 @@ tryagain: /* * If an '@' is found and the domain name matches, search for * the name with dns stripped off. - * Mixed case alpahbetics will match for the domain name, but - * all upper case will not. + * The match for alphabetics in now case insensitive, + * since RFC8881 defines this string as a DNS domain name. */ if (cnt == 0 && i < len && i > 0 && (len - 1 - i) == NFSD_VNET(nfsrv_dnsnamelen) && - !nfsrv_cmpmixedcase(cp, - NFSD_VNET(nfsrv_dnsname), NFSD_VNET(nfsrv_dnsnamelen))) { + strncasecmp(cp, NFSD_VNET(nfsrv_dnsname), + NFSD_VNET(nfsrv_dnsnamelen)) == 0) { len -= (NFSD_VNET(nfsrv_dnsnamelen) + 1); *(cp - 1) = '\0'; } @@ -3646,8 +3786,8 @@ tryagain: */ if (cnt == 0 && i < len && i > 0 && (len - 1 - i) == NFSD_VNET(nfsrv_dnsnamelen) && - !nfsrv_cmpmixedcase(cp, - NFSD_VNET(nfsrv_dnsname), NFSD_VNET(nfsrv_dnsnamelen))) { + strncasecmp(cp, NFSD_VNET(nfsrv_dnsname), + NFSD_VNET(nfsrv_dnsnamelen)) == 0) { len -= (NFSD_VNET(nfsrv_dnsnamelen) + 1); *(cp - 1) = '\0'; } @@ -3696,35 +3836,6 @@ out: } /* - * Cmp len chars, allowing mixed case in the first argument to match lower - * case in the second, but not if the first argument is all upper case. - * Return 0 for a match, 1 otherwise. - */ -static int -nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len) -{ - int i; - u_char tmp; - int fndlower = 0; - - for (i = 0; i < len; i++) { - if (*cp >= 'A' && *cp <= 'Z') { - tmp = *cp++ + ('a' - 'A'); - } else { - tmp = *cp++; - if (tmp >= 'a' && tmp <= 'z') - fndlower = 1; - } - if (tmp != *cp2++) - return (1); - } - if (fndlower) - return (0); - else - return (1); -} - -/* * Set the port for the nfsuserd. */ int @@ -4032,8 +4143,9 @@ nfssvc_idname(struct nfsd_idargs *nidp) */ cr = crget(); cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid; - crsetgroups(cr, nidp->nid_ngroup, grps); - cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0]; + crsetgroups_fallback(cr, nidp->nid_ngroup, grps, + GID_NOGROUP); + cr->cr_rgid = cr->cr_svgid = cr->cr_gid; cr->cr_prison = curthread->td_ucred->cr_prison; prison_hold(cr->cr_prison); #ifdef MAC @@ -4644,7 +4756,7 @@ newnfs_sndlock(int *flagp) ts.tv_sec = 0; ts.tv_nsec = 0; (void) nfsmsleep((caddr_t)flagp, NFSSOCKMUTEXPTR, - PZERO - 1, "nfsndlck", &ts); + PVFS, "nfsndlck", &ts); } *flagp |= NFSR_SNDLOCK; NFSUNLOCKSOCK(); @@ -5025,6 +5137,8 @@ nfsv4_freeslot(struct nfsclsession *sep, int slot, bool resetseq) mtx_lock(&sep->nfsess_mtx); if (resetseq) sep->nfsess_slotseq[slot]--; + else if (slot > sep->nfsess_foreslots) + sep->nfsess_slotseq[slot] = 0; if ((bitval & sep->nfsess_slots) == 0) printf("freeing free slot!!\n"); sep->nfsess_slots &= ~bitval; @@ -5154,3 +5268,46 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclsession *tsep, m_freem(nd->nd_mrep); return (error); } + +/* + * Translate a vnode type into an NFSv4 type, including the named + * attribute types. + */ +static uint32_t +vtonfsv4_type(struct vattr *vap) +{ + nfstype ntyp; + + if (vap->va_type >= 9) + ntyp = NFNON; + else + ntyp = nfsv34_type[vap->va_type]; + if ((vap->va_bsdflags & SFBSD_NAMEDATTR) != 0) { + if (ntyp == NFDIR) + ntyp = NFATTRDIR; + else if (ntyp == NFREG) + ntyp = NFNAMEDATTR; + } + return (txdr_unsigned((uint32_t)ntyp)); +} + +/* + * Translate an NFS type to a vnode type. + */ +static __enum_uint8(vtype) +nfsv4tov_type(uint32_t ntyp, uint16_t *bsdflags) +{ + __enum_uint8(vtype) vtyp; + + ntyp = fxdr_unsigned(uint32_t, ntyp) % (NFNAMEDATTR + 1); + if (ntyp == NFATTRDIR) { + vtyp = VDIR; + *bsdflags |= SFBSD_NAMEDATTR; + } else if (ntyp == NFNAMEDATTR) { + vtyp = VREG; + *bsdflags |= SFBSD_NAMEDATTR; + } else { + vtyp = nv34tov_type[ntyp]; + } + return (vtyp); +} |