Index: linux/fs/nfsd/auth.c
diff -u linux/fs/nfsd/auth.c:1.2 linux/fs/nfsd/auth.c:1.2.2.1
--- linux/fs/nfsd/auth.c:1.2	Sat Nov  7 16:43:38 1998
+++ linux/fs/nfsd/auth.c	Tue Nov 10 10:31:46 1998
@@ -50,11 +50,10 @@
 	current->ngroups = i;
 
 	if ((cred->cr_uid)) {
-		cap_lower(current->cap_effective, CAP_DAC_OVERRIDE);
-		cap_lower(current->cap_effective, CAP_DAC_READ_SEARCH);
+		cap_t(current->cap_effective) &= ~CAP_FS_MASK;
 	} else {
-		cap_raise(current->cap_effective, CAP_DAC_OVERRIDE);
-		cap_raise(current->cap_effective, CAP_DAC_READ_SEARCH);
+		cap_t(current->cap_effective) |= (CAP_FS_MASK &
+		                                  current->cap_permitted);
 	}
 
 	rqstp->rq_userset = 1;
Index: linux/fs/nfsd/nfsfh.c
diff -u linux/fs/nfsd/nfsfh.c:1.3 linux/fs/nfsd/nfsfh.c:1.3.2.4
--- linux/fs/nfsd/nfsfh.c:1.3	Sat Nov  7 16:43:38 1998
+++ linux/fs/nfsd/nfsfh.c	Tue Nov 10 10:31:46 1998
@@ -1093,47 +1093,48 @@
 	/*
 	 * Security: Check that the export is valid for dentry <gam3@acm.org>
 	 */
+	error = 0;
 	if (fh->fh_dev != fh->fh_xdev) {
 		printk("fh_verify: Security: export on other device"
 		       " (%d, %d).\n", fh->fh_dev, fh->fh_xdev);
-		goto out;
+		error = nfserr_stale;
 	} else if (exp->ex_dentry != dentry) {
 		struct dentry *tdentry = dentry;
-		int err2 = 0;
 
-		error = nfserr_stale;
 		do {
 			tdentry = tdentry->d_parent;
-			if (exp->ex_dentry == tdentry) {
-				error = 0;
+			if (exp->ex_dentry == tdentry)
 				break;
-			}
-			if ((err2 = nfsd_permission(exp, tdentry, MAY_READ))) {
-				error = err2;
-#ifdef NFSD_PARANOIA
-				goto out1;
-#else
-				goto out;
-#endif
+			/* executable only by root and we can't be root */
+			if (current->fsuid &&
+			    !(tdentry->d_inode->i_uid  &&
+			        (tdentry->d_inode->i_mode & S_IXUSR)) &&
+			    !(tdentry->d_inode->i_gid &&
+			        (tdentry->d_inode->i_mode & S_IXGRP)) &&
+			    !(tdentry->d_inode->i_mode & S_IXOTH) && 
+			    (exp->ex_flags & NFSEXP_ROOTSQUASH)) {
+				error = nfserr_stale;
+dprintk("fh_verify: no root_squashed access.\n");
 			}
 		} while ((tdentry != tdentry->d_parent));
-		if (error) {
-			printk("fh_verify: Security: %s/%s bad export.\n",
+		if (exp->ex_dentry != tdentry) {
+			error = nfserr_stale;
+			printk("nfsd Security: %s/%s bad export.\n",
 			       dentry->d_parent->d_name.name,
 			       dentry->d_name.name);
 			goto out;
 		}
 	}
 
 	/* Finally, check access permissions. */
-	error = nfsd_permission(exp, dentry, access);
+	if (!error) {
+		error = nfsd_permission(exp, dentry, access);
+	}
 #ifdef NFSD_PARANOIA
-out1:
 if (error)
 printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n",
 dentry->d_parent->d_name.name, dentry->d_name.name, access, error);
 #endif
-
 out:
 	return error;
 }
Index: linux/fs/nfsd/vfs.c
diff -u linux/fs/nfsd/vfs.c:1.5 linux/fs/nfsd/vfs.c:1.5.2.1
--- linux/fs/nfsd/vfs.c:1.5	Sat Nov  7 16:43:38 1998
+++ linux/fs/nfsd/vfs.c	Tue Nov 10 10:31:46 1998
@@ -148,16 +148,18 @@
 	dprintk("nfsd: nfsd_lookup(fh %p, %s)\n", SVCFH_DENTRY(fhp), name);
 
 	/* Obtain dentry and export. */
-	err = fh_verify(rqstp, fhp, S_IFDIR, MAY_NOP);
+	err = fh_verify(rqstp, fhp, S_IFDIR, MAY_EXEC);
 	if (err)
 		goto out;
 
 	dparent = fhp->fh_dentry;
 	exp  = fhp->fh_export;
 
+#if 0
 	err = nfsd_permission(exp, dparent, MAY_EXEC);
 	if (err)
 		goto out;
+#endif
 	err = nfserr_noent;
 	if (fs_off_limits(dparent->d_sb))
 		goto out;
@@ -232,13 +234,17 @@
 	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 
+	err = inode_change_ok(inode, iap);
+	if (err)
+		goto out_nfserr;
+
 	/* The size case is special... */
 	if (iap->ia_valid & ATTR_SIZE) {
 if (!S_ISREG(inode->i_mode))
 printk("nfsd_setattr: size change??\n");
 		if (iap->ia_size < inode->i_size) {
 			err = nfsd_permission(fhp->fh_export, dentry, MAY_TRUNC);
-			if (err != 0)
+			if (err)
 				goto out;
 		}
 		err = get_write_access(inode);
@@ -1228,8 +1234,7 @@
 
 	if (acc == MAY_NOP)
 		return 0;
-
-	/*
+#if 0
 	dprintk("nfsd: permission 0x%x%s%s%s%s%s mode 0%o%s%s%s\n",
 		acc,
 		(acc & MAY_READ)?	" read"  : "",
@@ -1243,8 +1248,7 @@
 		IS_RDONLY(inode)?	" ro" : "");
 	dprintk("      owner %d/%d user %d/%d\n",
 		inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
-	 */
-
+#endif
 #ifndef CONFIG_NFSD_SUN
         if (dentry->d_mounts != dentry) {
 		return nfserr_perm;
