Don't switch user contexts unless you have to. Saves
authorJeremy Allison <jra@samba.org>
Fri, 11 Jan 2008 00:35:54 +0000 (16:35 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 11 Jan 2008 00:35:54 +0000 (16:35 -0800)
a bunch of syscalls on close. Noticed by Volker.
Jeremy.
(This used to be commit 3caeeaea162e2083a087c242b850c107a3be1bf9)

source3/smbd/close.c
source3/smbd/sec_ctx.c

index c74e13348e16c3212b4c95b12f121829f1518f61..f67a4ad6683a3535c644af82ea5028106e0b0a8d 100644 (file)
@@ -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;
 }
index 6edcc3676425e5e2711029fdebb58a849110eb9f..0f307f6a647b09eb9398692d68d18851b64f0f4d 100644 (file)
@@ -32,6 +32,23 @@ struct sec_ctx {
 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.
 ****************************************************************************/