diff options
author | Jeremy Allison <jra@samba.org> | 2008-01-10 16:35:54 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-01-10 16:35:54 -0800 |
commit | f33f4ef4a24fcbf09eeba0d51e7db74e9b13b432 (patch) | |
tree | dfb7191eac84846a3edf20696f8f02516f04a8e8 | |
parent | 13785d5c62093540139094f6dfcf808100790939 (diff) | |
download | samba-f33f4ef4a24fcbf09eeba0d51e7db74e9b13b432.tar.gz samba-f33f4ef4a24fcbf09eeba0d51e7db74e9b13b432.tar.bz2 samba-f33f4ef4a24fcbf09eeba0d51e7db74e9b13b432.zip |
Don't switch user contexts unless you have to. Saves
a bunch of syscalls on close. Noticed by Volker.
Jeremy.
(This used to be commit 3caeeaea162e2083a087c242b850c107a3be1bf9)
-rw-r--r-- | source3/smbd/close.c | 39 | ||||
-rw-r--r-- | source3/smbd/sec_ctx.c | 17 |
2 files changed, 42 insertions, 14 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index c74e13348e..f67a4ad668 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -163,7 +163,8 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, enum file_close_type close_type) { connection_struct *conn = fsp->conn; - bool delete_file = False; + bool delete_file = false; + bool changed_user = false; struct share_mode_lock *lck; SMB_STRUCT_STAT sbuf; NTSTATUS status = NT_STATUS_OK; @@ -246,18 +247,26 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " "- deleting file.\n", fsp->fsp_name)); - /* Become the user who requested the delete. */ + if (!unix_token_equal(lck->delete_token, ¤t_user.ut)) { + /* Become the user who requested the delete. */ - if (!push_sec_ctx()) { - smb_panic("close_remove_share_mode: file %s. failed to push " - "sec_ctx.\n"); - } + DEBUG(5,("close_remove_share_mode: file %s. " + "Change user to uid %u\n", + (unsigned int)lck->delete_token->uid)); - set_sec_ctx(lck->delete_token->uid, - lck->delete_token->gid, - lck->delete_token->ngroups, - lck->delete_token->groups, - NULL); + if (!push_sec_ctx()) { + smb_panic("close_remove_share_mode: file %s. failed to push " + "sec_ctx.\n"); + } + + set_sec_ctx(lck->delete_token->uid, + lck->delete_token->gid, + lck->delete_token->ngroups, + lck->delete_token->groups, + NULL); + + changed_user = true; + } /* We can only delete the file if the name we have is still valid and hasn't been renamed. */ @@ -326,9 +335,11 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, done: - /* unbecome user. */ - pop_sec_ctx(); - + if (changed_user) { + /* unbecome user. */ + pop_sec_ctx(); + } + TALLOC_FREE(lck); return status; } diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index 6edcc36764..0f307f6a64 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -33,6 +33,23 @@ static struct sec_ctx sec_ctx_stack[MAX_SEC_CTX_DEPTH + 1]; static int sec_ctx_stack_ndx; /**************************************************************************** + Are two UNIX tokens equal ? +****************************************************************************/ + +bool unix_token_equal(const UNIX_USER_TOKEN *t1, const UNIX_USER_TOKEN *t2) +{ + if (t1->uid != t2->uid || t1->gid != t2->gid || + t1->ngroups != t2->ngroups) { + return false; + } + if (memcmp(t1->groups, t2->groups, + t1->ngroups*sizeof(gid_t)) != 0) { + return false; + } + return true; +} + +/**************************************************************************** Become the specified uid. ****************************************************************************/ |