summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2007-12-27 21:31:08 +0100
committerVolker Lendecke <vl@samba.org>2007-12-28 08:52:29 +0100
commit33f01360e0a40f6d1fa03035979d816ff9198d85 (patch)
tree4547dd3c84b81e66062a4c4e36dfd6f4b02d0415 /source3/smbd
parent675f41dc144fc0c150b44d931a9242f1ac1ebe5f (diff)
downloadsamba-33f01360e0a40f6d1fa03035979d816ff9198d85.tar.gz
samba-33f01360e0a40f6d1fa03035979d816ff9198d85.tar.bz2
samba-33f01360e0a40f6d1fa03035979d816ff9198d85.zip
Fix setting the initial permission bits
This fixes a make test failure on Solaris. When creating a new file, file_set_dosmode() called from open_file_ntcreate calculates a new permission mask, very likely different from what had been calculated in open_file_ntcreate. Further down we overwrote the newly calculated value with SMB_FCHMOD_ACL, ignoring what file_set_dosmode had calculated. Why did Linux not see this? fchmod_acl on a newly created file without acls would not retrieve an acl at all, whereas under Solaris acl(2) returns something even for files with just posix permissions returns something. Jeremy, given that we have very similar code in 3.0.28 this might also explain some of the bug reports that people have concerning ACLs on new files. Volker P.S: This one took a while to find... (This used to be commit 2135dfe91bf1ae114a18c15286b535662200677d)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/dosmode.c18
-rw-r--r--source3/smbd/open.c13
2 files changed, 25 insertions, 6 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 8e3c9b4c91..a96f80ee0e 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -438,12 +438,19 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
dosmode &= SAMBA_ATTRIBUTES_MASK;
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
- if (!st || (st && !VALID_STAT(*st))) {
+
+ if (st == NULL) {
+ SET_STAT_INVALID(st1);
st = &st1;
+ }
+
+ if (!VALID_STAT(*st)) {
if (SMB_VFS_STAT(conn,fname,st))
return(-1);
}
+ unixmode = st->st_mode;
+
get_acl_group_bits(conn, fname, &st->st_mode);
if (S_ISDIR(st->st_mode))
@@ -451,8 +458,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
else
dosmode &= ~aDIR;
- if (dos_mode(conn,fname,st) == dosmode)
+ if (dos_mode(conn,fname,st) == dosmode) {
+ st->st_mode = unixmode;
return(0);
+ }
/* Store the DOS attributes in an EA by preference. */
if (set_ea_dos_attribute(conn, fname, st, dosmode)) {
@@ -460,6 +469,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
+ st->st_mode = unixmode;
return 0;
}
@@ -500,6 +510,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
+ st->st_mode = unixmode;
return 0;
}
@@ -534,6 +545,9 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
+ if (ret == 0) {
+ st->st_mode = unixmode;
+ }
}
return( ret );
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index f30808b30a..d3ba9e076c 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1864,10 +1864,15 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
if (lp_map_archive(SNUM(conn)) ||
lp_store_dos_attributes(SNUM(conn))) {
if (!posix_open) {
- file_set_dosmode(conn, fname,
- new_dos_attributes | aARCH, NULL,
- parent_dir,
- true);
+ SMB_STRUCT_STAT tmp_sbuf;
+ SET_STAT_INVALID(tmp_sbuf);
+ if (file_set_dosmode(
+ conn, fname,
+ new_dos_attributes | aARCH,
+ &tmp_sbuf, parent_dir,
+ true) == 0) {
+ unx_mode = tmp_sbuf.st_mode;
+ }
}
}
}