[linux-cifs-client] [PATCH] CIFS: reset ATTR_READONLY on Windows share when Linux client allows write permission

Urs Fleisch urs.fleisch at gmail.com
Sat Mar 17 09:10:18 GMT 2007


This bug is related to "[PATCH] CIFS: reset file mode when CIFS client  
notices that ATTR_READONLY is no longer set", which was sent to this  
mailing list a few days ago.

My system configuration is:
Ubuntu Linux Dapper (kernel package  
linux-image-2.6.15-23-386_2.6.15-23.39_i386.deb) client accessing Windows  
Server 2003 3790 Service Pack 1 (no UNIX extensions).

Problem description:
When all write permission bits are removed from a file on the Windows  
share (e.g. using chmod ugo-w filename), the read-only bit is set in the  
file (as seen in the Windows Explorer). Now it is not possible to get the  
write permissions back (e.g. using chmod ugo+w filename). The read-only  
bit has to be removed in the Windows Explorer. When this is done, the file  
is still displayed to be read-only (ls -l filename), but it can be made  
writeable (chmod ugo+w filename). When the patch from the message  
mentioned above is applied (discovered by Alan Tyson of HP, reported by  
Jeff Layton), the writeable bits are displayed correctly as soon as the  
read-only bit is removed in the Windows Explorer. The main problem,  
however, still exists as it is not possible to make the file writeable  
 from the Linux CIFS client.

Investigating the problem further, I found out that the problem occurs  
only if no other attribute is set on the file. If I set the archived or  
hidden bit in the Windows Explorer or unmark the "for fast searching,  
allow Indexing Service to index this file" checkbox (which sets the  
ATTR_NOT_CONTENT_INDEXED bit), the read-only bit can be cleared from the  
Linux client. Looking into the function cifs_setattr() in fs/cifs/inode.c  
and adding some debug output, it can be seen that time_buf.Attributes is  
zero in the problem case and the attribute will not be set. Sending the  
attributes with a zero value does not help as this seems to mean that no  
attributes have to be changed. So I added the ATTR_NORMAL bit in the case  
where ATTR_READONLY has to be cleared and no other attribute is set.

I made another small change: The ATTR_READONLY is only cleared if all  
writeable bits are set in the Linux permissions (the file is writeable for  
user, group and others). This is caused by the check ((mode & S_IWUGO) ==  
S_IWUGO). I think that this does not make sense, as soon as any write flag  
is set, the file is no longer read-only.

The following patch was applied after the patch from the message mentioned  
above and solves the problem.

Urs

--- linux-source-2.6.15-2.6.15.orig/fs/cifs/inode.c	2007-03-16  
08:41:42.000000000 +0100
+++ linux-source-2.6.15-2.6.15/fs/cifs/inode.c	2007-03-16  
14:26:15.000000000 +0100
@@ -1261,11 +1261,15 @@
  				time_buf.Attributes =
  					cpu_to_le32(cifsInode->cifsAttrs |
  						    ATTR_READONLY);
-		} else if ((mode & S_IWUGO) == S_IWUGO) {
-			if (cifsInode->cifsAttrs & ATTR_READONLY)
+		} else {
+			if (cifsInode->cifsAttrs & ATTR_READONLY) {
  				time_buf.Attributes =
  					cpu_to_le32(cifsInode->cifsAttrs &
  						    (~ATTR_READONLY));
+				if (!time_buf.Attributes)
+					time_buf.Attributes =
+						cpu_to_le32(ATTR_NORMAL);
+			}
  		}
  		/* BB to be implemented -
  		   via Windows security descriptors or streams */


More information about the linux-cifs-client mailing list