summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-01-10 16:35:54 -0800
committerJeremy Allison <jra@samba.org>2008-01-10 16:35:54 -0800
commitf33f4ef4a24fcbf09eeba0d51e7db74e9b13b432 (patch)
treedfb7191eac84846a3edf20696f8f02516f04a8e8
parent13785d5c62093540139094f6dfcf808100790939 (diff)
downloadsamba-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.c39
-rw-r--r--source3/smbd/sec_ctx.c17
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, &current_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.
****************************************************************************/