summaryrefslogtreecommitdiff
path: root/source3/include
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2011-01-25 14:23:19 -0800
committerJeremy Allison <jra@samba.org>2011-01-25 14:23:19 -0800
commit44732734cca2328a8aceb2db9b577c923920f644 (patch)
tree05bc735662ba82137e96479322c4d3737bff9693 /source3/include
parenta65bce4e38d0b940286c7c93c226651e5fb45082 (diff)
downloadsamba-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.h8
-rw-r--r--source3/include/smb.h28
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[];
*/
};