Hey there, I posted a quick fix for a problem I found with all samba's up
to 2.2.7a on the general samba list, which describes the following
problem:

In Windows, if you create a file with NORMAL attributes and ALWAYS_CREATE,
close the file and then re-create it with, say, HIDDEN and ALWAYS_CREATE,
the file *should* be upgraded to HIDDEN. The other way around, ie.
starting with HIDDEN and re-creating with NORMAL should keep the file as
HIDDEN. Currently, samba always keep the original attributes. This causes
windows to incorrectly store hidden and system files from in a roaming
profile which gets you that stupid popping-up Desktop.ini in new profiles
after the second login (because the files are not hidden on the profile
directory). Why windows opens the files as non-hidden first is unknown to
me :) Anyways, here is a patch that fixes it. I have tried my best to make
it as clean as possible but as I know little of samba internals it may be
wrong ...

This works for me, and stops Desktop.ini appearing all over the place. I
haven't found any problems with it yet.

--- samba-2.2.7a/source/smbd/open.c     Tue Dec 10 15:58:17 2002
+++ samba-2.2.7a-truncfix/source/smbd/open.c    Tue Jan  7 11:49:13 2003
@@ -685,6 +685,43 @@
        return num_share_modes;
 }
 
+int open_upgrade_attributes(connection_struct *conn, char *path, mode_t 
+existing_mode, mode_t new_mode)
+{
+       uint32 old_dos_mode, new_dos_mode;
+       SMB_STRUCT_STAT sbuf;
+       files_struct *fsp;
+       int ret;
+
+       ZERO_STRUCT(sbuf);
+
+       sbuf.st_mode = existing_mode;
+       old_dos_mode = dos_mode(conn, path, &sbuf);
+
+       sbuf.st_mode = new_mode ;
+       new_dos_mode = old_dos_mode | (dos_mode(conn, path, &sbuf) & 
+(FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN));
+       
+       if(new_dos_mode != old_dos_mode) {
+               DEBUG(5,("upgrading attributes for file %s from %d to %d during 
+truncate\n",path,old_dos_mode, new_dos_mode));
+       
+               if (vfs_stat(conn,path,&sbuf))
+                       return -1;
+
+               fsp = open_file_fchmod(conn,path,&sbuf);
+               if (!fsp)
+                       return -1;
+               become_root();
+               ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unix_mode(conn, new_dos_mode, 
+path));
+               unbecome_root();
+               close_file_fchmod(fsp);
+       
+               return ret;
+       }
+       
+       return 0;
+}      
+
+       
+
 static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t 
existing_mode, mode_t new_mode)
 {
        uint32 old_dos_mode, new_dos_mode;
@@ -829,6 +866,10 @@
                        errno = EACCES;
                        return NULL;
                }
+               /* Upgrade attributes if the truncate specified more attributes
+                * than the old file
+                */
+               open_upgrade_attributes(conn,fname, psbuf->st_mode, mode);
        }
 
        if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)

Reply via email to