X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/91447636331957f3d9b5ca5b508f07c526b0074d..3a60a9f5b85abb8c2cf24e1926c5c7b3f608a5e2:/bsd/nfs/nfs_serv.c?ds=sidebyside diff --git a/bsd/nfs/nfs_serv.c b/bsd/nfs/nfs_serv.c index 7f513b015..f6fc25fd4 100644 --- a/bsd/nfs/nfs_serv.c +++ b/bsd/nfs/nfs_serv.c @@ -147,7 +147,7 @@ nfsrv3_access(nfsd, slp, procp, mrq) mbuf_t mrep = nfsd->nd_mrep, md = nfsd->nd_md; mbuf_t nam = nfsd->nd_nam; caddr_t dpos = nfsd->nd_dpos; - vnode_t vp, dvp; + vnode_t vp; struct nfs_filehandle nfh; u_long *tl; long t1; @@ -234,18 +234,17 @@ nfsrv3_access(nfsd, slp, procp, mrq) if (nfsrv_authorize(vp, NULL, testaction, &context, nxo, 0)) nfsmode &= ~NFSV3ACCESS_EXTEND; } - dvp = NULLVP; + /* - * For hard links, this answer may be wrong if the vnode + * Note concerning NFSV3ACCESS_DELETE: + * For hard links, the answer may be wrong if the vnode * has multiple parents with different permissions. + * Also, some clients (e.g. MacOSX 10.3) may incorrectly + * interpret the missing/cleared DELETE bit. + * So we'll just leave the DELETE bit alone. At worst, + * we're telling the client it might be able to do + * something it really can't. */ - if ((nfsmode & NFSV3ACCESS_DELETE) && - (((dvp = vnode_getparent(vp)) == NULL) || - nfsrv_authorize(vp, dvp, KAUTH_VNODE_DELETE, &context, nxo, 0))) { - nfsmode &= ~NFSV3ACCESS_DELETE; - } - if (dvp != NULLVP) - vnode_put(dvp); if ((nfsmode & NFSV3ACCESS_EXECUTE) && (vnode_isdir(vp) || @@ -2996,6 +2995,8 @@ nfsrv_symlink(nfsd, slp, procp, mrq) VATTR_SET(vap, va_gid, kauth_cred_getgid(nfsd->nd_cr)); } VATTR_SET(vap, va_type, VLNK); + VATTR_CLEAR_ACTIVE(vap, va_data_size); + VATTR_CLEAR_ACTIVE(vap, va_access_time); /* authorize before creating */ error = nfsrv_authorize(dvp, NULL, KAUTH_VNODE_ADD_FILE, &context, nxo, 0); @@ -3485,6 +3486,8 @@ nfsrv_readdir(nfsd, slp, procp, mrq) } context.vc_proc = procp; context.vc_ucred = nfsd->nd_cr; + if (!v3 || (nxo->nxo_flags & NX_32BITCLIENTS)) + vnopflag |= VNODE_READDIR_SEEKOFF32; if (v3) { nfsm_srv_vattr_init(&at, v3); error = getret = vnode_getattr(vp, &at, &context); @@ -3654,6 +3657,8 @@ again: /* Finish off the record with the cookie */ nfsm_clget; if (v3) { + if (vnopflag & VNODE_READDIR_SEEKOFF32) + dp->d_seekoff &= 0x00000000ffffffffULL; txdr_hyper(&dp->d_seekoff, &tquad); *tl = tquad.nfsuquad[0]; bp += NFSX_UNSIGNED; @@ -3761,6 +3766,8 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq) } context.vc_proc = procp; context.vc_ucred = nfsd->nd_cr; + if (nxo->nxo_flags & NX_32BITCLIENTS) + vnopflag |= VNODE_READDIR_SEEKOFF32; nfsm_srv_vattr_init(&at, 1); error = getret = vnode_getattr(vp, &at, &context); if (!error && toff && verf && verf != at.va_filerev) @@ -3931,6 +3938,8 @@ again: fl.fl_fhsize = txdr_unsigned(nfhp->nfh_len); fl.fl_fhok = nfs_true; fl.fl_postopok = nfs_true; + if (vnopflag & VNODE_READDIR_SEEKOFF32) + dp->d_seekoff &= 0x00000000ffffffffULL; txdr_hyper(&dp->d_seekoff, &fl.fl_off); nfsm_clget;