Give permission to the owner of the file to preserve semantics only
in the relevant cases (read, write). Fixes PR 3017.
This commit is contained in:
parent
2f296724a8
commit
6913afc057
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_serv.c,v 1.26 1996/07/01 11:16:03 fvdl Exp $ */
|
||||
/* $NetBSD: nfs_serv.c,v 1.27 1996/12/11 00:01:56 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -131,7 +131,7 @@ nfsrv3_access(nfsd, slp, procp, mrq)
|
||||
}
|
||||
nfsmode = fxdr_unsigned(u_int32_t, *tl);
|
||||
if ((nfsmode & NFSV3ACCESS_READ) &&
|
||||
nfsrv_access(vp, VREAD, cred, rdonly, procp))
|
||||
nfsrv_access(vp, VREAD, cred, rdonly, procp, 0))
|
||||
nfsmode &= ~NFSV3ACCESS_READ;
|
||||
if (vp->v_type == VDIR)
|
||||
testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
|
||||
@ -139,14 +139,14 @@ nfsrv3_access(nfsd, slp, procp, mrq)
|
||||
else
|
||||
testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
|
||||
if ((nfsmode & testmode) &&
|
||||
nfsrv_access(vp, VWRITE, cred, rdonly, procp))
|
||||
nfsrv_access(vp, VWRITE, cred, rdonly, procp, 0))
|
||||
nfsmode &= ~testmode;
|
||||
if (vp->v_type == VDIR)
|
||||
testmode = NFSV3ACCESS_LOOKUP;
|
||||
else
|
||||
testmode = NFSV3ACCESS_EXECUTE;
|
||||
if ((nfsmode & testmode) &&
|
||||
nfsrv_access(vp, VEXEC, cred, rdonly, procp))
|
||||
nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0))
|
||||
nfsmode &= ~testmode;
|
||||
getret = VOP_GETATTR(vp, &va, cred, procp);
|
||||
vput(vp);
|
||||
@ -314,7 +314,7 @@ nfsrv_setattr(nfsd, slp, procp, mrq)
|
||||
error = EISDIR;
|
||||
goto out;
|
||||
} else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly,
|
||||
procp)) != 0)
|
||||
procp, 0)) != 0)
|
||||
goto out;
|
||||
}
|
||||
error = VOP_SETATTR(vp, &va, cred, procp);
|
||||
@ -570,8 +570,8 @@ nfsrv_read(nfsd, slp, procp, mrq)
|
||||
}
|
||||
if (!error) {
|
||||
nqsrv_getl(vp, ND_READ);
|
||||
if ((error = nfsrv_access(vp, VREAD, cred, rdonly, procp)) != 0)
|
||||
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp);
|
||||
if ((error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1)) != 0)
|
||||
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 1);
|
||||
}
|
||||
getret = VOP_GETATTR(vp, &va, cred, procp);
|
||||
if (!error)
|
||||
@ -784,7 +784,7 @@ nfsrv_write(nfsd, slp, procp, mrq)
|
||||
}
|
||||
if (!error) {
|
||||
nqsrv_getl(vp, ND_WRITE);
|
||||
error = nfsrv_access(vp, VWRITE, cred, rdonly, procp);
|
||||
error = nfsrv_access(vp, VWRITE, cred, rdonly, procp, 1);
|
||||
}
|
||||
if (error) {
|
||||
vput(vp);
|
||||
@ -1049,7 +1049,7 @@ loop1:
|
||||
vp = NULL;
|
||||
if (!error) {
|
||||
nqsrv_getl(vp, ND_WRITE);
|
||||
error = nfsrv_access(vp, VWRITE, cred, rdonly, procp);
|
||||
error = nfsrv_access(vp, VWRITE, cred, rdonly, procp, 1);
|
||||
}
|
||||
|
||||
if (nfsd->nd_stable == NFSV3WRITE_UNSTABLE)
|
||||
@ -1390,7 +1390,7 @@ nfsrv_create(nfsd, slp, procp, mrq)
|
||||
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
|
||||
if (va.va_size != -1) {
|
||||
error = nfsrv_access(vp, VWRITE, cred,
|
||||
(nd.ni_cnd.cn_flags & RDONLY), procp);
|
||||
(nd.ni_cnd.cn_flags & RDONLY), procp, 0);
|
||||
if (!error) {
|
||||
nqsrv_getl(vp, ND_WRITE);
|
||||
tempsize = va.va_size;
|
||||
@ -2447,7 +2447,7 @@ nfsrv_readdir(nfsd, slp, procp, mrq)
|
||||
#endif
|
||||
}
|
||||
if (!error)
|
||||
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp);
|
||||
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
nfsm_reply(NFSX_POSTOPATTR(v3));
|
||||
@ -2714,7 +2714,7 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq)
|
||||
#endif
|
||||
if (!error) {
|
||||
nqsrv_getl(vp, ND_READ);
|
||||
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp);
|
||||
error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0);
|
||||
}
|
||||
if (error) {
|
||||
vput(vp);
|
||||
@ -3286,13 +3286,14 @@ nfsrv_noop(nfsd, slp, procp, mrq)
|
||||
* refer to files already opened by a Unix client. You cannot just use
|
||||
* vn_writechk() and VOP_ACCESS() for two reasons.
|
||||
* 1 - You must check for exported rdonly as well as MNT_RDONLY for the write case
|
||||
* 2 - The owner is to be given access irrespective of mode bits so that
|
||||
* processes that chmod after opening a file don't break. I don't like
|
||||
* this because it opens a security hole, but since the nfs server opens
|
||||
* a security hole the size of a barn door anyhow, what the heck.
|
||||
* 2 - The owner is to be given access irrespective of mode bits for some
|
||||
* operations, so that processes that chmod after opening a file don't
|
||||
* break. I don't like this because it opens a security hole, but since
|
||||
* the nfs server opens a security hole the size of a barn door anyhow,
|
||||
* what the heck.
|
||||
*/
|
||||
int
|
||||
nfsrv_access(vp, flags, cred, rdonly, p)
|
||||
nfsrv_access(vp, flags, cred, rdonly, p, override)
|
||||
register struct vnode *vp;
|
||||
int flags;
|
||||
register struct ucred *cred;
|
||||
@ -3329,8 +3330,13 @@ nfsrv_access(vp, flags, cred, rdonly, p)
|
||||
error = VOP_GETATTR(vp, &vattr, cred, p);
|
||||
if (error)
|
||||
return (error);
|
||||
if ((error = VOP_ACCESS(vp, flags, cred, p)) != 0 &&
|
||||
cred->cr_uid != vattr.va_uid)
|
||||
return (error);
|
||||
return (0);
|
||||
error = VOP_ACCESS(vp, flags, cred, p);
|
||||
/*
|
||||
* Allow certain operations for the owner (reads and writes
|
||||
* on files that are already open).
|
||||
*/
|
||||
if (override && (error == EPERM || error == EACCES) &&
|
||||
cred->cr_uid == vattr.va_uid)
|
||||
error = 0;
|
||||
return error;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_var.h,v 1.5 1996/10/25 23:14:11 cgd Exp $ */
|
||||
/* $NetBSD: nfs_var.h,v 1.6 1996/12/11 00:01:58 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
|
||||
@ -182,7 +182,8 @@ int nfsrv_null __P((struct nfsrv_descript *, struct nfssvc_sock *,
|
||||
struct proc *, struct mbuf **));
|
||||
int nfsrv_noop __P((struct nfsrv_descript *, struct nfssvc_sock *,
|
||||
struct proc *, struct mbuf **));
|
||||
int nfsrv_access __P((struct vnode *, int, struct ucred *, int, struct proc *));
|
||||
int nfsrv_access __P((struct vnode *, int, struct ucred *, int, struct proc *,
|
||||
int));
|
||||
|
||||
/* nfs_socket.c */
|
||||
int nfs_connect __P((struct nfsmount *, struct nfsreq *));
|
||||
|
Loading…
Reference in New Issue
Block a user