mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r13274: Fix for bug #3467. Not a show stopper.
jason qian <jason@infrant.com> was a *fantastic*
help in tracking this down.
Jeremy.
(This used to be commit 9f4a9c70fa
)
This commit is contained in:
parent
0e551cd5a2
commit
86c9bac4c3
@ -657,6 +657,7 @@ struct share_mode_lock {
|
||||
int num_share_modes;
|
||||
struct share_mode_entry *share_modes;
|
||||
BOOL delete_on_close;
|
||||
BOOL initial_delete_on_close;
|
||||
BOOL fresh;
|
||||
BOOL modified;
|
||||
};
|
||||
|
@ -123,6 +123,7 @@ struct locking_data {
|
||||
struct {
|
||||
int num_share_mode_entries;
|
||||
BOOL delete_on_close;
|
||||
BOOL initial_delete_on_close;
|
||||
} s;
|
||||
struct share_mode_entry dummy; /* Needed for alignment. */
|
||||
} u;
|
||||
@ -282,6 +283,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
|
||||
ld = (struct locking_data *)db_data.dptr;
|
||||
ld->u.s.num_share_mode_entries = 1;
|
||||
ld->u.s.delete_on_close = 0;
|
||||
ld->u.s.initial_delete_on_close = 0;
|
||||
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
|
||||
create_share_mode_entry(shares, new_entry);
|
||||
|
||||
|
@ -49,6 +49,7 @@ struct locking_data {
|
||||
struct {
|
||||
int num_share_mode_entries;
|
||||
BOOL delete_on_close;
|
||||
BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */
|
||||
} s;
|
||||
struct share_mode_entry dummy; /* Needed for alignment. */
|
||||
} u;
|
||||
@ -435,11 +436,15 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
|
||||
data = (struct locking_data *)dbuf.dptr;
|
||||
|
||||
lck->delete_on_close = data->u.s.delete_on_close;
|
||||
lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
|
||||
lck->num_share_modes = data->u.s.num_share_mode_entries;
|
||||
|
||||
DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
|
||||
"num_share_modes: %d\n", lck->delete_on_close,
|
||||
lck->num_share_modes));
|
||||
"initial_delete_on_close: %d, "
|
||||
"num_share_modes: %d\n",
|
||||
lck->delete_on_close,
|
||||
lck->initial_delete_on_close,
|
||||
lck->num_share_modes));
|
||||
|
||||
if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
|
||||
DEBUG(0, ("invalid number of share modes: %d\n",
|
||||
@ -535,8 +540,10 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
|
||||
ZERO_STRUCTP(data);
|
||||
data->u.s.num_share_mode_entries = lck->num_share_modes;
|
||||
data->u.s.delete_on_close = lck->delete_on_close;
|
||||
DEBUG(10, ("unparse_share_modes: del: %d, num: %d\n",
|
||||
data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
|
||||
DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, num: %d\n",
|
||||
data->u.s.delete_on_close,
|
||||
data->u.s.initial_delete_on_close,
|
||||
data->u.s.num_share_mode_entries));
|
||||
memcpy(result.dptr + sizeof(*data), lck->share_modes,
|
||||
sizeof(struct share_mode_entry)*lck->num_share_modes);
|
||||
@ -613,6 +620,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
|
||||
lck->num_share_modes = 0;
|
||||
lck->share_modes = NULL;
|
||||
lck->delete_on_close = False;
|
||||
lck->initial_delete_on_close = False;
|
||||
lck->fresh = False;
|
||||
lck->modified = False;
|
||||
|
||||
@ -1046,6 +1054,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
|
||||
changed the delete on close flag. This will be noticed
|
||||
in the close code, the last closer will delete the file
|
||||
if flag is set.
|
||||
Note that setting this to any value clears the initial_delete_on_close flag.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
|
||||
@ -1070,6 +1079,11 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
|
||||
lck->modified = True;
|
||||
}
|
||||
|
||||
if (lck->initial_delete_on_close) {
|
||||
lck->initial_delete_on_close = False;
|
||||
lck->modified = True;
|
||||
}
|
||||
|
||||
talloc_free(lck);
|
||||
return True;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
||||
DEBUG(0, ("close_file: Could not delete share entry for file %s\n", fsp->fsp_name));
|
||||
}
|
||||
|
||||
delete_file = lck->delete_on_close;
|
||||
delete_file = (lck->delete_on_close | lck->initial_delete_on_close);
|
||||
|
||||
if (delete_file) {
|
||||
int i;
|
||||
@ -345,7 +345,7 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
|
||||
DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
|
||||
}
|
||||
|
||||
delete_dir = lck->delete_on_close;
|
||||
delete_dir = (lck->delete_on_close | lck->initial_delete_on_close);
|
||||
|
||||
talloc_free(lck);
|
||||
|
||||
|
@ -1660,32 +1660,28 @@ files_struct *open_file_ntcreate(connection_struct *conn,
|
||||
}
|
||||
set_share_mode(lck, fsp, 0, fsp->oplock_type);
|
||||
|
||||
if (create_options & FILE_DELETE_ON_CLOSE) {
|
||||
uint32 dosattr= existing_dos_attributes;
|
||||
NTSTATUS result;
|
||||
|
||||
if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
|
||||
info == FILE_WAS_SUPERSEDED) {
|
||||
dosattr = new_dos_attributes;
|
||||
}
|
||||
|
||||
result = can_set_delete_on_close(fsp, True, dosattr);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
/* Remember to delete the mode we just added. */
|
||||
del_share_mode(lck, fsp);
|
||||
talloc_free(lck);
|
||||
fd_close(conn,fsp);
|
||||
file_free(fsp);
|
||||
set_saved_ntstatus(result);
|
||||
return NULL;
|
||||
}
|
||||
lck->delete_on_close = True;
|
||||
lck->modified = True;
|
||||
}
|
||||
|
||||
if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
|
||||
info == FILE_WAS_SUPERSEDED) {
|
||||
|
||||
/* Handle strange delete on close create semantics. */
|
||||
if (create_options & FILE_DELETE_ON_CLOSE) {
|
||||
NTSTATUS result = can_set_delete_on_close(fsp, True, new_dos_attributes);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
/* Remember to delete the mode we just added. */
|
||||
del_share_mode(lck, fsp);
|
||||
talloc_free(lck);
|
||||
fd_close(conn,fsp);
|
||||
file_free(fsp);
|
||||
set_saved_ntstatus(result);
|
||||
return NULL;
|
||||
}
|
||||
/* Note that here we set the *inital* delete on close flag,
|
||||
not the regular one. */
|
||||
lck->initial_delete_on_close = True;
|
||||
lck->modified = True;
|
||||
}
|
||||
|
||||
/* Files should be initially set as archive */
|
||||
if (lp_map_archive(SNUM(conn)) ||
|
||||
lp_store_dos_attributes(SNUM(conn))) {
|
||||
@ -1976,7 +1972,9 @@ files_struct *open_directory(connection_struct *conn,
|
||||
|
||||
set_share_mode(lck, fsp, 0, NO_OPLOCK);
|
||||
|
||||
if (create_options & FILE_DELETE_ON_CLOSE) {
|
||||
if ((create_options & FILE_DELETE_ON_CLOSE) &&
|
||||
(info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
|
||||
info == FILE_WAS_SUPERSEDED)) {
|
||||
status = can_set_delete_on_close(fsp, True, 0);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
set_saved_ntstatus(status);
|
||||
@ -1985,7 +1983,7 @@ files_struct *open_directory(connection_struct *conn,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lck->delete_on_close = True;
|
||||
lck->initial_delete_on_close = True;
|
||||
lck->modified = True;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user