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:
fvdl 1996-12-11 00:01:56 +00:00
parent 2f296724a8
commit 6913afc057
2 changed files with 30 additions and 23 deletions

View File

@ -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;
}

View File

@ -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 *));