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/include | |
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/include')
-rw-r--r-- | source3/include/proto.h | 8 | ||||
-rw-r--r-- | source3/include/smb.h | 28 |
2 files changed, 24 insertions, 12 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 372ed16fd5..4c7d4f3d42 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3089,9 +3089,13 @@ void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid, bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp); bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp); NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode); -void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok); -void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok); +const UNIX_USER_TOKEN *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash); +void set_delete_on_close_lck(files_struct *fsp, + struct share_mode_lock *lck, + bool delete_on_close, + const UNIX_USER_TOKEN *tok); bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok); +bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash); bool set_sticky_write_time(struct file_id fileid, struct timespec write_time); bool set_write_time(struct file_id fileid, struct timespec write_time); int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, diff --git a/source3/include/smb.h b/source3/include/smb.h index 5269c2348f..95c1d62357 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -733,6 +733,12 @@ Offset Data length. #define MSG_SMB_SHARE_MODE_ENTRY_SIZE 72 #endif +struct delete_token_list { + struct delete_token_list *next, *prev; + uint32_t name_hash; + UNIX_USER_TOKEN *delete_token; +}; + struct share_mode_lock { const char *servicepath; /* canonicalized. */ const char *base_name; @@ -740,8 +746,7 @@ struct share_mode_lock { struct file_id id; int num_share_modes; struct share_mode_entry *share_modes; - UNIX_USER_TOKEN *delete_token; - bool delete_on_close; + struct delete_token_list *delete_tokens; struct timespec old_write_time; struct timespec changed_write_time; bool fresh; @@ -758,20 +763,23 @@ struct locking_data { union { struct { int num_share_mode_entries; - bool delete_on_close; struct timespec old_write_time; struct timespec changed_write_time; - uint32 delete_token_size; /* Only valid if either of - the two previous fields - are True. */ + uint32 num_delete_token_entries; } s; struct share_mode_entry dummy; /* Needed for alignment. */ } u; /* The following four entries are implicit - struct share_mode_entry modes[num_share_mode_entries]; - char unix_token[delete_token_size] (divisible by 4). - char share_name[]; - char file_name[]; + + (1) struct share_mode_entry modes[num_share_mode_entries]; + + (2) A num_delete_token_entries of structs { + uint32_t len_delete_token; + char unix_token[len_delete_token] (divisible by 4). + }; + + (3) char share_name[]; + (4) char file_name[]; */ }; |