(ndr_pull_flags_fn_t)ndr_pull_security_unix_token);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("parse_delete_tokens_list: "
- "ndr_pull_share_mode_data failed\n"));
+ "ndr_pull_security_unix_token failed\n"));
return -1;
}
p += token_len;
delete_tokens_size += token_len;
+ if (p >= end_ptr) {
+ DEBUG(0,("parse_delete_tokens_list: corrupt data"));
+ return -1;
+ }
+
+ pdtl->delete_nt_token = TALLOC_ZERO_P(pdtl, struct security_token);
+ if (pdtl->delete_nt_token == NULL) {
+ DEBUG(0,("parse_delete_tokens_list: talloc failed"));
+ return -1;
+ }
+
+ blob.data = p;
+ blob.length = end_ptr - p;
+
+ ndr_err = ndr_pull_struct_blob(&blob,
+ pdtl,
+ pdtl->delete_nt_token,
+ (ndr_pull_flags_fn_t)ndr_pull_security_token);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(1, ("parse_delete_tokens_list: "
+ "ndr_pull_security_token failed\n"));
+ return -1;
+ }
+
+ token_len = ndr_size_security_token(pdtl->delete_nt_token, 0);
+
+ p += token_len;
+ delete_tokens_size += token_len;
+
/* Add to the list. */
DLIST_ADD(lck->delete_tokens, pdtl);
}
for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
num_delete_token_entries++;
delete_tokens_size += sizeof(uint32_t) +
- ndr_size_security_unix_token(pdtl->delete_token, 0);
+ ndr_size_security_unix_token(pdtl->delete_token, 0) +
+ ndr_size_security_token(pdtl->delete_nt_token, 0);
}
result.dsize = sizeof(*data) +
/* Store any delete on close tokens. */
for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
struct security_unix_token *pdt = pdtl->delete_token;
+ struct security_token *pdt_nt = pdtl->delete_nt_token;
uint8_t *p = result.dptr + offset;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
/* We know we have space here as we counted above. */
memcpy(p, blob.data, blob.length);
+ p += blob.length;
+ offset += blob.length;
+ TALLOC_FREE(blob.data);
+
+ ndr_err = ndr_push_struct_blob(&blob,
+ talloc_tos(),
+ pdt_nt,
+ (ndr_push_flags_fn_t)ndr_push_security_token);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ smb_panic("ndr_push_security_token failed");
+ }
+
+ /* We know we have space here as we counted above. */
+ memcpy(p, blob.data, blob.length);
+ p += blob.length;
offset += blob.length;
TALLOC_FREE(blob.data);
}
static bool add_delete_on_close_token(struct share_mode_lock *lck,
uint32_t name_hash,
+ const struct security_token *nt_tok,
const struct security_unix_token *tok)
{
struct delete_token_list *dtl;
TALLOC_FREE(dtl);
return false;
}
+ dtl->delete_nt_token = dup_nt_token(dtl, nt_tok);
+ if (dtl->delete_nt_token == NULL) {
+ TALLOC_FREE(dtl);
+ return false;
+ }
DLIST_ADD(lck->delete_tokens, dtl);
lck->modified = true;
return true;
void set_delete_on_close_lck(files_struct *fsp,
struct share_mode_lock *lck,
bool delete_on_close,
+ const struct security_token *nt_tok,
const struct security_unix_token *tok)
{
struct delete_token_list *dtl;
bool ret;
if (delete_on_close) {
+ SMB_ASSERT(nt_tok != NULL);
SMB_ASSERT(tok != NULL);
} else {
+ SMB_ASSERT(nt_tok == NULL);
SMB_ASSERT(tok == NULL);
}
TALLOC_FREE(dtl->delete_token);
dtl->delete_token = copy_unix_token(dtl, tok);
SMB_ASSERT(dtl->delete_token != NULL);
+ TALLOC_FREE(dtl->delete_nt_token);
+ dtl->delete_nt_token = dup_nt_token(dtl, nt_tok);
+ SMB_ASSERT(dtl->delete_nt_token != NULL);
}
return;
}
return;
}
- ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
+ ret = add_delete_on_close_token(lck, fsp->name_hash, nt_tok, tok);
SMB_ASSERT(ret);
}
-bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
+bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
+ const struct security_token *nt_tok,
+ const struct security_unix_token *tok)
{
struct share_mode_lock *lck;
return False;
}
- set_delete_on_close_lck(fsp, lck, delete_on_close,
- delete_on_close ? tok : NULL);
+ if (delete_on_close) {
+ set_delete_on_close_lck(fsp, lck, true,
+ nt_tok,
+ tok);
+ } else {
+ set_delete_on_close_lck(fsp, lck, false,
+ NULL,
+ NULL);
+ }
if (fsp->is_directory) {
SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
return True;
}
-const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
+/****************************************************************************
+ Return the NT token and UNIX token if there's a match. Return true if
+ found, false if not.
+****************************************************************************/
+
+bool get_delete_on_close_token(struct share_mode_lock *lck,
+ uint32_t name_hash,
+ const struct security_token **pp_nt_tok,
+ const struct security_unix_token **pp_tok)
{
struct delete_token_list *dtl;
DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
(unsigned int)dtl->name_hash ));
if (dtl->name_hash == name_hash) {
- return dtl->delete_token;
+ if (pp_nt_tok) {
+ *pp_nt_tok = dtl->delete_nt_token;
+ }
+ if (pp_tok) {
+ *pp_tok = dtl->delete_token;
+ }
+ return true;
}
}
- return NULL;
+ return false;
}
bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
{
- return (get_delete_on_close_token(lck, name_hash) != NULL);
+ return get_delete_on_close_token(lck, name_hash, NULL, NULL);
}
bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
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);
-const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash);
+bool get_delete_on_close_token(struct share_mode_lock *lck,
+ uint32_t name_hash,
+ const struct security_token **pp_nt_tok,
+ const struct security_unix_token **pp_tok);
void set_delete_on_close_lck(files_struct *fsp,
struct share_mode_lock *lck,
bool delete_on_close,
+ const struct security_token *nt_tok,
+ const struct security_unix_token *tok);
+bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
+ const struct security_token *nt_tok,
const struct security_unix_token *tok);
-bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_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);
NTSTATUS tmp_status;
struct file_id id;
const struct security_unix_token *del_token = NULL;
+ const struct security_token *del_nt_token = NULL;
+ bool got_tokens = false;
/* Ensure any pending write time updates are done. */
if (fsp->update_write_time_event) {
became_user = True;
}
fsp->delete_on_close = true;
- set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
+ set_delete_on_close_lck(fsp, lck, True,
+ get_current_nttok(conn),
+ get_current_utok(conn));
if (became_user) {
unbecome_user();
}
*/
fsp->update_write_time_on_close = false;
- del_token = get_delete_on_close_token(lck, fsp->name_hash);
- SMB_ASSERT(del_token != NULL);
+ got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
+ &del_nt_token, &del_token);
+ SMB_ASSERT(got_tokens);
if (!unix_token_equal(del_token, get_current_utok(conn))) {
/* Become the user who requested the delete. */
del_token->gid,
del_token->ngroups,
del_token->groups,
- NULL);
+ del_nt_token);
changed_user = true;
}
*/
fsp->delete_on_close = false;
- set_delete_on_close_lck(fsp, lck, false, NULL);
+ set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
done:
bool delete_dir = False;
NTSTATUS status = NT_STATUS_OK;
NTSTATUS status1 = NT_STATUS_OK;
+ const struct security_token *del_nt_token = NULL;
const struct security_unix_token *del_token = NULL;
/*
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
fsp->fsp_name->base_name);
set_delete_on_close_lck(fsp, lck, true,
+ get_current_nttok(fsp->conn),
get_current_utok(fsp->conn));
fsp->delete_on_close = true;
if (became_user) {
}
}
- del_token = get_delete_on_close_token(lck, fsp->name_hash);
- delete_dir = (del_token != NULL);
+ delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
+ &del_nt_token, &del_token);
if (delete_dir) {
int i;
del_token->gid,
del_token->ngroups,
del_token->groups,
- NULL);
+ del_nt_token);
TALLOC_FREE(lck);