diff options
author | Jeremy Allison <jra@samba.org> | 2011-01-25 14:23:19 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2011-01-25 14:23:19 -0800 |
commit | 44732734cca2328a8aceb2db9b577c923920f644 (patch) | |
tree | 05bc735662ba82137e96479322c4d3737bff9693 /source3/smbd/open.c | |
parent | a65bce4e38d0b940286c7c93c226651e5fb45082 (diff) | |
download | samba-44732734cca2328a8aceb2db9b577c923920f644.tar.gz samba-44732734cca2328a8aceb2db9b577c923920f644.tar.bz2 samba-44732734cca2328a8aceb2db9b577c923920f644.zip |
Fix bug #7863 - Unlink may unlink wrong file when hardlinks are involved.
Do this by keeping a linked list of delete on close tokens, one for
each filename that identifies a path to the dev/inode. Use the
jenkins hash of the pathname to identify the correct token.
Diffstat (limited to 'source3/smbd/open.c')
-rw-r--r-- | source3/smbd/open.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 722e461068..0de70451da 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -810,6 +810,7 @@ bool is_stat_open(uint32 access_mask) static NTSTATUS open_mode_check(connection_struct *conn, struct share_mode_lock *lck, + uint32_t name_hash, uint32 access_mask, uint32 share_access, uint32 create_options, @@ -825,7 +826,7 @@ static NTSTATUS open_mode_check(connection_struct *conn, /* A delete on close prohibits everything */ - if (lck->delete_on_close) { + if (is_delete_on_close_set(lck, name_hash)) { return NT_STATUS_DELETE_PENDING; } @@ -1823,7 +1824,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, /* Use the client requested access mask here, not the one we * open with. */ - status = open_mode_check(conn, lck, access_mask, share_access, + status = open_mode_check(conn, lck, fsp->name_hash, + access_mask, share_access, create_options, &file_existed); if (NT_STATUS_IS_OK(status)) { @@ -2045,7 +2047,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, return NT_STATUS_SHARING_VIOLATION; } - status = open_mode_check(conn, lck, access_mask, share_access, + status = open_mode_check(conn, lck, fsp->name_hash, + access_mask, share_access, create_options, &file_existed); if (NT_STATUS_IS_OK(status)) { @@ -2625,7 +2628,8 @@ static NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_SHARING_VIOLATION; } - status = open_mode_check(conn, lck, access_mask, share_access, + status = open_mode_check(conn, lck, fsp->name_hash, + access_mask, share_access, create_options, &dir_existed); if (!NT_STATUS_IS_OK(status)) { |