/*
* Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
/*
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;
KAUTH_VNODE_DELETE_CHILD;
} else {
testaction =
- KAUTH_VNODE_WRITE_DATA |
- KAUTH_VNODE_WRITE_ATTRIBUTES |
- KAUTH_VNODE_WRITE_EXTATTRIBUTES |
- KAUTH_VNODE_WRITE_SECURITY;
+ KAUTH_VNODE_WRITE_DATA;
}
if (nfsrv_authorize(vp, NULL, testaction, &context, nxo, 0))
nfsmode &= ~NFSV3ACCESS_MODIFY;
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) ||
int i;
caddr_t bpos;
int error = 0, count, len, left, siz, tlen, getret;
- int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen;
+ int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen, maxlen;
char *cp2;
mbuf_t mb, mb2, mreq;
mbuf_t m2;
nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
off = (off_t)fxdr_unsigned(u_long, *tl);
}
- nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd));
+ nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
+ reqlen = fxdr_unsigned(u_long, *tl);
+ maxlen = NFS_SRVMAXDATA(nfsd);
+ if (reqlen > maxlen)
+ reqlen = maxlen;
+
if ((error = nfsrv_fhtovp(&nfh, nam, TRUE, &vp, &nx, &nxo))) {
nfsm_reply(2 * NFSX_UNSIGNED);
nfsm_srvpostop_attr(1, NULL);
*tl++ = txdr_unsigned(stable);
else
*tl++ = txdr_unsigned(NFSV3WRITE_FILESYNC);
- /*
- * Actually, there is no need to txdr these fields,
- * but it may make the values more human readable,
- * for debugging purposes.
- */
+ /* write verifier */
*tl++ = txdr_unsigned(boottime_sec());
*tl = txdr_unsigned(0);
} else {
nfsm_build(tl, u_long *, 4 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(nfsd->nd_len);
*tl++ = txdr_unsigned(swp->nd_stable);
- /*
- * Actually, there is no need to txdr these fields,
- * but it may make the values more human readable,
- * for debugging purposes.
- */
+ /* write verifier */
*tl++ = txdr_unsigned(boottime_sec());
*tl = txdr_unsigned(0);
} else {
/*
* copy credentials making sure that the result can be compared with bcmp().
*
- * XXX ILLEGAL
+ * NOTE: This function is only intended to operate on a real input
+ * credential and a template output credential; the template
+ * ouptut credential is intended to then be used as an argument
+ * to kauth_cred_create() - AND NEVER REFERENCED OTHERWISE.
*/
void
nfsrv_setcred(kauth_cred_t incred, kauth_cred_t outcred)
int i;
bzero((caddr_t)outcred, sizeof (*outcred));
- outcred->cr_ref = 1;
outcred->cr_uid = kauth_cred_getuid(incred);
outcred->cr_ngroups = incred->cr_ngroups;
for (i = 0; i < incred->cr_ngroups; i++)
if (!error) {
if (nd.ni_cnd.cn_flags & ISSYMLINK)
error = EINVAL;
+ vp = nd.ni_vp;
}
if (error)
nfsm_reply(0);
context.vc_proc = procp;
context.vc_ucred = nfsd->nd_cr;
- hacked_context.vc_proc = procp;
- hacked_context.vc_ucred = proc_ucred(procp);
/*
* Save the original credential UID in case they are
vnode_put(vp);
vp = NULL;
}
+ hacked_context.vc_proc = procp;
+ hacked_context.vc_ucred = kauth_cred_proc_ref(procp);
+
nd.ni_cnd.cn_nameiop = LOOKUP;
nd.ni_cnd.cn_flags &= ~LOCKPARENT;
nd.ni_cnd.cn_context = &hacked_context;
if (nd.ni_cnd.cn_flags & ISSYMLINK)
error = EINVAL;
}
+ kauth_cred_unref(&hacked_context.vc_ucred);
}
out1:
if (xacl != NULL)
/* reset credential if it was remapped */
if (nfsd->nd_cr != saved_cred) {
- kauth_cred_rele(nfsd->nd_cr);
+ kauth_cred_unref(&nfsd->nd_cr);
+ /*
+ * consume reference taken above
+ */
nfsd->nd_cr = saved_cred;
- kauth_cred_ref(nfsd->nd_cr);
+ saved_cred = NULL;
}
tond.ni_cnd.cn_nameiop = RENAME;
if (topath)
FREE_ZONE(topath, MAXPATHLEN, M_NAMEI);
if (saved_cred)
- kauth_cred_rele(saved_cred);
+ kauth_cred_unref(&saved_cred);
return (0);
nfsmout:
if (topath)
FREE_ZONE(topath, MAXPATHLEN, M_NAMEI);
if (saved_cred)
- kauth_cred_rele(saved_cred);
+ kauth_cred_unref(&saved_cred);
return (error);
}
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;
vnode_t vp, nvp;
struct flrep fl;
struct nfs_filehandle dnfh, *nfhp = (struct nfs_filehandle *)&fl.fl_fhsize;
+ u_long fhsize;
struct nfs_export *nx;
struct nfs_export_options *nxo;
uio_t auio;
}
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)
*/
fp = (struct nfs_fattr *)&fl.fl_fattr;
nfsm_srvfillattr(vap, fp);
- fl.fl_fhsize = txdr_unsigned(nfhp->nfh_len);
+ fhsize = nfhp->nfh_len;
+ fl.fl_fhsize = txdr_unsigned(fhsize);
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;
/*
* Now copy the flrep structure out.
*/
- xfer = sizeof(struct flrep) - sizeof(fl.fl_nfh) + fl.fl_fhsize;
+ xfer = sizeof(struct flrep) - sizeof(fl.fl_nfh) + fhsize;
cp = (caddr_t)&fl;
while (xfer > 0) {
nfsm_clget;