The branch, master has been updated
       via  62ccae3 Factor out the code checking if a parent should override 
DELETE_ACCESS into a function.
       via  4ec2c2a Remove another level of indentation - deal with 
!NT_STATUS_OK individually.
       via  4b9bdee Add early return on stat open without O_CREAT if file 
doesn't exist. Reduces one level of indentation.
      from  1d53109 s3:libsmb: make use of map_nt_error_from_unix_common() in 
clitrans.c

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 62ccae32297683815da608cfb938573784614cf8
Author: Jeremy Allison <[email protected]>
Date:   Wed Oct 26 12:41:18 2011 -0700

    Factor out the code checking if a parent should override DELETE_ACCESS into 
a function.
    
    Autobuild-User: Jeremy Allison <[email protected]>
    Autobuild-Date: Wed Oct 26 23:15:05 CEST 2011 on sn-devel-104

commit 4ec2c2a5e8977852c9a553952596d819743e70af
Author: Jeremy Allison <[email protected]>
Date:   Wed Oct 26 11:00:11 2011 -0700

    Remove another level of indentation - deal with !NT_STATUS_OK individually.

commit 4b9bdee167987affbc2c4dbf381b0c61dfda3364
Author: Jeremy Allison <[email protected]>
Date:   Wed Oct 26 12:08:51 2011 -0700

    Add early return on stat open without O_CREAT if file doesn't exist.
    Reduces one level of indentation.

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/open.c |  181 +++++++++++++++++++++++++++++----------------------
 1 files changed, 102 insertions(+), 79 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 1e21799..6ad85b7 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -192,6 +192,25 @@ static NTSTATUS check_parent_access(struct 
connection_struct *conn,
 }
 
 /****************************************************************************
+ If the requester wanted DELETE_ACCESS and was only rejected because
+ the file ACL didn't include DELETE_ACCESS, see if the parent ACL
+ ovverrides this.
+****************************************************************************/
+
+static bool parent_override_delete(connection_struct *conn,
+                                       struct smb_filename *smb_fname,
+                                       uint32_t access_mask,
+                                       uint32_t rejected_mask)
+{
+       if ((access_mask & DELETE_ACCESS) &&
+                   (rejected_mask == DELETE_ACCESS) &&
+                   can_delete_file_in_directory(conn, smb_fname)) {
+               return true;
+       }
+       return false;
+}
+
+/****************************************************************************
  fd support routines - attempt to do a dos_open.
 ****************************************************************************/
 
@@ -560,87 +579,90 @@ static NTSTATUS open_file(files_struct *fsp,
                }
 
        } else {
+               uint32_t access_granted = 0;
+
                fsp->fh->fd = -1; /* What we used to call a stat open. */
-               if (file_existed) {
-                       uint32_t access_granted = 0;
+               if (!file_existed) {
+                       /* File must exist for a stat open. */
+                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               }
 
-                       status = smbd_check_open_rights(conn,
-                                       smb_fname,
-                                       access_mask,
-                                       &access_granted);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               if (NT_STATUS_EQUAL(status, 
NT_STATUS_ACCESS_DENIED)) {
-                                       /*
-                                        * On NT_STATUS_ACCESS_DENIED, 
access_granted
-                                        * contains the denied bits.
-                                        */
-
-                                       if ((access_mask & 
FILE_WRITE_ATTRIBUTES) &&
-                                                       (access_granted & 
FILE_WRITE_ATTRIBUTES) &&
-                                                       
(lp_map_readonly(SNUM(conn)) ||
-                                                        
lp_map_archive(SNUM(conn)) ||
-                                                        
lp_map_hidden(SNUM(conn)) ||
-                                                        
lp_map_system(SNUM(conn)))) {
-                                               access_granted &= 
~FILE_WRITE_ATTRIBUTES;
-
-                                               DEBUG(10,("open_file: "
-                                                         "overrode "
-                                                         "FILE_WRITE_"
-                                                         "ATTRIBUTES "
-                                                         "on file %s\n",
-                                                         smb_fname_str_dbg(
-                                                                 smb_fname)));
-                                       }
+               status = smbd_check_open_rights(conn,
+                               smb_fname,
+                               access_mask,
+                               &access_granted);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                       /*
+                        * On NT_STATUS_ACCESS_DENIED, access_granted
+                        * contains the denied bits.
+                        */
 
-                                       if ((access_mask & DELETE_ACCESS) &&
-                                           (access_granted & DELETE_ACCESS) &&
-                                           can_delete_file_in_directory(conn,
-                                               smb_fname)) {
-                                               /* Were we trying to do a stat 
open
-                                                * for delete and didn't get 
DELETE
-                                                * access (only) ? Check if the
-                                                * directory allows 
DELETE_CHILD.
-                                                * See here:
-                                                * 
http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
-                                                * for details. */
-
-                                               access_granted &= 
~DELETE_ACCESS;
-
-                                               DEBUG(10,("open_file: "
-                                                         "overrode "
-                                                         "DELETE_ACCESS on "
-                                                         "file %s\n",
-                                                         smb_fname_str_dbg(
-                                                                 smb_fname)));
-                                       }
+                       if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
+                                       (access_granted & 
FILE_WRITE_ATTRIBUTES) &&
+                                       (lp_map_readonly(SNUM(conn)) ||
+                                        lp_map_archive(SNUM(conn)) ||
+                                        lp_map_hidden(SNUM(conn)) ||
+                                        lp_map_system(SNUM(conn)))) {
+                               access_granted &= ~FILE_WRITE_ATTRIBUTES;
+
+                               DEBUG(10,("open_file: "
+                                         "overrode "
+                                         "FILE_WRITE_"
+                                         "ATTRIBUTES "
+                                         "on file %s\n",
+                                         smb_fname_str_dbg(
+                                                 smb_fname)));
+                       }
 
-                                       if (access_granted != 0) {
-                                               DEBUG(10,("open_file: Access "
-                                                         "denied on file "
-                                                         "%s\n",
-                                                         smb_fname_str_dbg(
-                                                                 smb_fname)));
-                                               return status;
-                                       }
-                               } else if (NT_STATUS_EQUAL(status, 
NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
+                       if (parent_override_delete(conn,
+                                               smb_fname,
+                                               access_mask,
+                                               access_granted)) {
+                               /* Were we trying to do a stat open
+                                * for delete and didn't get DELETE
+                                * access (only) ? Check if the
+                                * directory allows DELETE_CHILD.
+                                * See here:
+                                * 
http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
+                                * for details. */
+
+                               access_granted &= ~DELETE_ACCESS;
+
+                               DEBUG(10,("open_file: "
+                                         "overrode "
+                                         "DELETE_ACCESS on "
+                                         "file %s\n",
+                                         smb_fname_str_dbg(
+                                                 smb_fname)));
+                       }
+
+                       if (access_granted != 0) {
+                               DEBUG(10,("open_file: Access "
+                                         "denied (0x%x) on file "
+                                         "%s\n",
+                                         access_granted,
+                                         smb_fname_str_dbg(
+                                                 smb_fname)));
+                               return status;
+                       }
+
+               } else if (NT_STATUS_EQUAL(status, 
NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
                                    fsp->posix_open &&
                                    S_ISLNK(smb_fname->st.st_ex_mode)) {
-                                       /* This is a POSIX stat open for delete
-                                        * or rename on a symlink that points
-                                        * nowhere. Allow. */
-                                       DEBUG(10,("open_file: allowing POSIX "
-                                                 "open on bad symlink %s\n",
-                                                 smb_fname_str_dbg(
-                                                         smb_fname)));
-                               } else {
-                                       DEBUG(10,("open_file: "
-                                                 "smbd_check_open_rights on 
file "
-                                                 "%s returned %s\n",
-                                                 smb_fname_str_dbg(smb_fname),
-                                                 nt_errstr(status) ));
-                                       return status;
-                               }
-                       }
+                       /* This is a POSIX stat open for delete
+                        * or rename on a symlink that points
+                        * nowhere. Allow. */
+                       DEBUG(10,("open_file: allowing POSIX "
+                                 "open on bad symlink %s\n",
+                                 smb_fname_str_dbg(
+                                         smb_fname)));
+               } else if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(10,("open_file: "
+                                 "smbd_check_open_rights on file "
+                                 "%s returned %s\n",
+                                 smb_fname_str_dbg(smb_fname),
+                                 nt_errstr(status) ));
+                       return status;
                }
        }
 
@@ -2787,10 +2809,11 @@ static NTSTATUS open_directory(connection_struct *conn,
                 * 
http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
                 * for details. */
 
-               if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
-                       (access_mask & DELETE_ACCESS) &&
-                       (access_granted == DELETE_ACCESS) &&
-                       can_delete_file_in_directory(conn, smb_dname))) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
+                               parent_override_delete(conn,
+                                               smb_dname,
+                                               access_mask,
+                                               access_granted)) {
                        DEBUG(10,("open_directory: overrode ACCESS_DENIED "
                                "on directory %s\n",
                                smb_fname_str_dbg(smb_dname)));


-- 
Samba Shared Repository

Reply via email to