diff options
author | Jeremy Allison <jra@samba.org> | 2002-08-30 18:57:23 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2002-08-30 18:57:23 +0000 |
commit | fcdecb7c29a4ae6d48e7cdf61dae43f06c2e930a (patch) | |
tree | 11bd8570262e1ef2344686b37c5a7549026678a2 /source3 | |
parent | 39e21d4ef21152724f2fff573f88ee25216aef0e (diff) | |
download | samba-fcdecb7c29a4ae6d48e7cdf61dae43f06c2e930a.tar.gz samba-fcdecb7c29a4ae6d48e7cdf61dae43f06c2e930a.tar.bz2 samba-fcdecb7c29a4ae6d48e7cdf61dae43f06c2e930a.zip |
Correctly fail opens with mismatching SYSTEM or HIDDEN attributes if we
are mapping system or hidden.
Jeremy.
(This used to be commit bd1e3df9ffa0717f26696a222e5ec6a0198b3352)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/open.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 8c6e8ed805..47e859d04b 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -679,6 +679,31 @@ static void kernel_flock(files_struct *fsp, int deny_mode) } +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; + SMB_STRUCT_STAT sbuf; + + ZERO_STRUCT(sbuf); + + sbuf.st_mode = existing_mode; + old_dos_mode = dos_mode(conn, path, &sbuf); + + sbuf.st_mode = new_mode; + new_dos_mode = dos_mode(conn, path, &sbuf); + + /* If we're mapping SYSTEM and HIDDEN ensure they match. */ + if (lp_map_system(SNUM(conn))) { + if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) != (new_dos_mode & FILE_ATTRIBUTE_SYSTEM)) + return False; + } + if (lp_map_hidden(SNUM(conn))) { + if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) != (new_dos_mode & FILE_ATTRIBUTE_HIDDEN)) + return False; + } + return True; +} + /**************************************************************************** Open a file with a share mode. On output from this open we are guarenteeing that @@ -773,6 +798,17 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) flags2 |= O_TRUNC; + /* We only care about matching attributes on file exists and truncate. */ + if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) { + if (!open_match_attributes(conn, fname, psbuf->st_mode, mode)) { + DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n", + fname, psbuf->st_mode, mode )); + file_free(fsp); + errno = EACCES; + return NULL; + } + } + if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) flags2 |= O_EXCL; |