From 9b741727d9ff41a1a637a0b0b92497c446ac5a19 Mon Sep 17 00:00:00 2001 From: deraadt Date: Sat, 14 Dec 1996 15:36:50 +0000 Subject: [PATCH] better nfsrv_access() control, from netbsd --- sys/nfs/nfs_serv.c | 52 +++++++++++++++++++++++++--------------------- sys/nfs/nfs_var.h | 5 +++-- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index 82ccc51401d..ba8b2d891f2 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_serv.c,v 1.7 1996/11/08 23:20:14 niklas Exp $ */ +/* $OpenBSD: nfs_serv.c,v 1.8 1996/12/14 15:36:50 deraadt Exp $ */ /* $NetBSD: nfs_serv.c,v 1.25 1996/03/02 15:55:52 jtk Exp $ */ /* @@ -132,7 +132,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 | @@ -140,14 +140,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); @@ -315,7 +315,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); @@ -571,8 +571,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) @@ -785,7 +785,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); @@ -1050,7 +1050,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) @@ -1391,7 +1391,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; @@ -2446,7 +2446,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)); @@ -2713,7 +2713,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); @@ -3285,18 +3285,20 @@ 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; int rdonly; struct proc *p; + int override; { struct vattr vattr; int error; @@ -3325,11 +3327,13 @@ nfsrv_access(vp, flags, cred, rdonly, p) if ((vp->v_flag & VTEXT) && !vnode_pager_uncache(vp)) return (ETXTBSY); } - 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; } diff --git a/sys/nfs/nfs_var.h b/sys/nfs/nfs_var.h index 5e944220a3b..8b7ac70f417 100644 --- a/sys/nfs/nfs_var.h +++ b/sys/nfs/nfs_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_var.h,v 1.3 1996/09/21 11:06:20 deraadt Exp $ */ +/* $OpenBSD: nfs_var.h,v 1.4 1996/12/14 15:36:51 deraadt Exp $ */ /* $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */ /* @@ -227,7 +227,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 *)); -- 2.20.1