permission upgrade during O_TRUNC
steve at griffin.sio2.nl
steve at griffin.sio2.nl
Tue Jan 7 09:59:00 GMT 2003
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)
More information about the samba-technical
mailing list