Subject: Re: SMBFS problem : permission denied - when file already open on the server
To: None <netbsd-users@NetBSD.org>
From: Peter Postma <peter@pointless.nl>
List: netbsd-users
Date: 10/27/2004 02:30:32
--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Oct 27, 2004 at 10:13:12AM +0000, George Abdelmalik wrote:
> Hi all,
> 
> I've been running with 2.0_RC4 for a number for weeks.  This NetBSD box 
> is predominately used as a samba file server and central backup machine 
> as it has a DDS-4 tape drive.  I use mount_smbfs(8) to mount file 
> systems of Win 98, Win 2000 and WP boxes for backup purposes.
> 
> What I have observed is that having mounted one of these file systems 
> (which are shared as read-only from their windows host) that if a file 
> is already open on that host machine then access to that file from 
> within the smbfs mounted file system is not permitted.    "Error: 
> file.txt: Permission denied;"
> 
> This behaviour has been repeatable and I've also tried it out with 
> 2.99.9, which behaved the same.
> 
> My original thought was that it was probably a windows issue, but I've 
> recently set up the same test trying a linux implementation (Mandrake 
> 9.2, kenrel 2.6.x) of smbfs which didn't produce this error.
> 
> I've also discovered a posting on a FreeBSD mailing list 
> (http://www.freebsd.org/cgi/query-pr.cgi?pr=i386/64719) which describes 
> this exact same problem in their 4.9 release.  The problem has since 
> been fixed in release 4.10.
> 
> As the NetBSD smbfs is a port from FreeBSD's implementation it is very 
> likely that this problem has been inherited.
> 
> Is anybody able to confirm this issue?
> 

Yes, I can reproduce this problem.
The attached patch fixes it for me, can you also try it out and tell
me if it works?

-- 
Peter Postma

--envbJBWh7q8WU6mo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="smbfs.diff"

Index: smbfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_vnops.c,v
retrieving revision 1.44
diff -u -r1.44 smbfs_vnops.c
--- smbfs_vnops.c	13 Sep 2004 19:25:48 -0000	1.44
+++ smbfs_vnops.c	27 Oct 2004 00:27:53 -0000
@@ -270,17 +270,25 @@
 
 	smb_makescred(&scred, ap->a_p, ap->a_cred);
 	if (vp->v_type == VDIR)
-		error = smbfs_smb_ntcreatex(np, SMB_AM_OPENREAD, &scred);
+		error = smbfs_smb_ntcreatex(np,
+		    SMB_SM_DENYNONE|SMB_AM_OPENREAD, &scred);
 	else {
-		accmode = SMB_AM_OPENREAD;
+		/*
+		 * Use DENYNONE to give unixy semantics of permitting
+		 * everything not forbidden by permissions.  Ie denial
+		 * is up to server with clients/openers needing to use
+		 * advisory locks for further control.
+		 */
+		accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
 		if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
-			accmode = SMB_AM_OPENRW;
+			accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW;
 		error = smbfs_smb_open(np, accmode, &scred);
 		if (error) {
 			if (ap->a_mode & FWRITE)
 				return EACCES;
 		
-			error = smbfs_smb_open(np, SMB_AM_OPENREAD, &scred);
+			error = smbfs_smb_open(np,
+			    SMB_SM_DENYNONE|SMB_AM_OPENREAD, &scred);
 		}
 	}
 	if (!error)
@@ -420,7 +428,8 @@
  		np->n_size = vap->va_size;
 		uvm_vnp_setsize(vp, vap->va_size);
 		if ((np->n_flag & NOPEN) == 0) {
-			error = smbfs_smb_open(np, SMB_AM_OPENRW, &scred);
+			error = smbfs_smb_open(np,
+			    SMB_SM_DENYNONE|SMB_AM_OPENRW, &scred);
 			if (error == 0)
 				doclose = 1;
 		}

--envbJBWh7q8WU6mo--