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;
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) ||
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);
}
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);
/* 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;
}
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)
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;