The branch, master has been updated
       via  3aa186f Simplify the logic in open_file() some more.
       via  3a705e5 Simplify the logic in open_file().
       via  1144b0d Use new common function.
       via  9d5e026 Make check_same_stat() and check_same_dev_ino() common 
functions.
       via  1f37ed7 Factor out check_same_dev_ino() from check_same_stat() so 
it can be called separately.
      from  7b1fb36 lib/ldb: Bump ldb release due to pyldb changes

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


- Log -----------------------------------------------------------------
commit 3aa186f1d4d9ca723fb9c876d0b3fc1f58d556fb
Author: Jeremy Allison <[email protected]>
Date:   Mon Jul 9 16:13:06 2012 -0700

    Simplify the logic in open_file() some more.
    
    Move the inheritance work into the if block
    where we created the file. We can never have
    created the file (and thus need no inheritance)
    for a stat-open.
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Tue Jul 10 03:30:22 CEST 2012 on sn-devel-104

commit 3a705e5f3d0843e3765852e26661aeee5ebdfd79
Author: Jeremy Allison <[email protected]>
Date:   Mon Jul 9 16:08:01 2012 -0700

    Simplify the logic in open_file().
    
    Move the fstat call into the block which opens a file descriptor.
    Remove the stat() call in the stat-open case. We already failed
    the open if !file_existed.

commit 1144b0dc043c42e4845316a4ccc3bdd49bfda822
Author: Jeremy Allison <[email protected]>
Date:   Mon Jul 9 12:28:48 2012 -0700

    Use new common function.

commit 9d5e026bde837ed853478a223e2823fd35c67d26
Author: Jeremy Allison <[email protected]>
Date:   Mon Jul 9 12:26:56 2012 -0700

    Make check_same_stat() and check_same_dev_ino() common functions.

commit 1f37ed7a5283ef3abd095d6a92efa231e7e2444d
Author: Jeremy Allison <[email protected]>
Date:   Mon Jul 9 11:35:20 2012 -0700

    Factor out check_same_dev_ino() from check_same_stat() so it can be called 
separately.

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

Summary of changes:
 source3/include/proto.h  |    4 ++
 source3/lib/util.c       |   29 ++++++++++
 source3/param/loadparm.c |    2 +-
 source3/smbd/open.c      |  133 +++++++++++++++++-----------------------------
 source3/smbd/proto.h     |    2 -
 5 files changed, 83 insertions(+), 87 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index b7f2852..7625983 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -400,6 +400,10 @@ bool file_exist_stat(const char *fname,SMB_STRUCT_STAT 
*sbuf,
                     bool fake_dir_create_times);
 bool socket_exist(const char *fname);
 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf);
+bool check_same_dev_ino(const SMB_STRUCT_STAT *sbuf1,
+                       const SMB_STRUCT_STAT *sbuf2);
+bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
+                       const SMB_STRUCT_STAT *sbuf2);
 void show_msg(const char *buf);
 int set_message_bcc(char *buf,int num_bytes);
 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 697f7b1..fa46448 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -126,6 +126,35 @@ uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
        return sbuf->st_ex_size;
 }
 
+/****************************************************************************
+ Check two stats have identical dev and ino fields.
+****************************************************************************/
+
+bool check_same_dev_ino(const SMB_STRUCT_STAT *sbuf1,
+                        const SMB_STRUCT_STAT *sbuf2)
+{
+       if (sbuf1->st_ex_dev != sbuf2->st_ex_dev ||
+                       sbuf1->st_ex_ino != sbuf2->st_ex_ino) {
+               return false;
+       }
+       return true;
+}
+
+/****************************************************************************
+ Check if a stat struct is identical for use.
+****************************************************************************/
+
+bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
+                       const SMB_STRUCT_STAT *sbuf2)
+{
+       if (sbuf1->st_ex_uid != sbuf2->st_ex_uid ||
+                       sbuf1->st_ex_gid != sbuf2->st_ex_gid ||
+                       !check_same_dev_ino(sbuf1, sbuf2)) {
+               return false;
+       }
+       return true;
+}
+
 /*******************************************************************
  Show a smb message structure.
 ********************************************************************/
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 12ba2f1..f8e7ace 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -8304,7 +8304,7 @@ static int process_usershare_file(const char *dir_name, 
const char *file_name, i
        }
 
        /* Is it the same dev/inode as was lstated ? */
-       if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != 
sbuf.st_ex_ino) {
+       if (!check_same_stat(&lsbuf, &sbuf)) {
                close(fd);
                DEBUG(0,("process_usershare_file: fstat of %s is a different 
file from lstat. "
                        "Symlink spoofing going on ?\n", fname ));
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index c88fe65..473fd97 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -551,7 +551,6 @@ static NTSTATUS open_file(files_struct *fsp,
        int accmode = (flags & O_ACCMODE);
        int local_flags = flags;
        bool file_existed = VALID_STAT(fsp->fsp_name->st);
-       bool file_created = false;
 
        fsp->fh->fd = -1;
        errno = EPERM;
@@ -606,6 +605,7 @@ static NTSTATUS open_file(files_struct *fsp,
            (!file_existed && (local_flags & O_CREAT)) ||
            ((local_flags & O_TRUNC) == O_TRUNC) ) {
                const char *wild;
+               int ret;
 
                /*
                 * We can't actually truncate here as the file may be locked.
@@ -678,70 +678,24 @@ static NTSTATUS open_file(files_struct *fsp,
                        return status;
                }
 
-               if ((local_flags & O_CREAT) && !file_existed) {
-                       file_created = true;
-               }
-
-       } else {
-               fsp->fh->fd = -1; /* What we used to call a stat open. */
-               if (!file_existed) {
-                       /* File must exist for a stat open. */
-                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               }
-
-               status = smbd_check_access_rights(conn,
-                               smb_fname,
-                               access_mask);
-
-               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)));
-                       status = NT_STATUS_OK;
-               }
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10,("open_file: "
-                               "smbd_check_access_rights on file "
-                               "%s returned %s\n",
-                               smb_fname_str_dbg(smb_fname),
-                               nt_errstr(status) ));
-                       return status;
-               }
-       }
-
-       if (!file_existed) {
-               int ret;
-
-               if (fsp->fh->fd == -1) {
-                       ret = SMB_VFS_STAT(conn, smb_fname);
-               } else {
-                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
-                       /* If we have an fd, this stat should succeed. */
-                       if (ret == -1) {
-                               DEBUG(0,("Error doing fstat on open file %s "
-                                        "(%s)\n",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno) ));
-                       }
-               }
-
-               /* For a non-io open, this stat failing means file not found. 
JRA */
+               ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
                if (ret == -1) {
+                       /* If we have an fd, this stat should succeed. */
+                       DEBUG(0,("Error doing fstat on open file %s "
+                               "(%s)\n",
+                               smb_fname_str_dbg(smb_fname),
+                               strerror(errno) ));
                        status = map_nt_error_from_unix(errno);
                        fd_close(fsp);
                        return status;
                }
 
-               if (file_created) {
+               if ((local_flags & O_CREAT) && !file_existed) {
+                       /* We created this file. */
+
                        bool need_re_stat = false;
                        /* Do all inheritance work after we've
-                          done a successful stat call and filled
+                          done a successful fstat call and filled
                           in the stat struct in fsp->fsp_name. */
 
                        /* Inherit the ACL if required */
@@ -760,17 +714,13 @@ static NTSTATUS open_file(files_struct *fsp,
                        }
 
                        if (need_re_stat) {
-                               if (fsp->fh->fd == -1) {
-                                       ret = SMB_VFS_STAT(conn, smb_fname);
-                               } else {
-                                       ret = SMB_VFS_FSTAT(fsp, 
&smb_fname->st);
-                                       /* If we have an fd, this stat should 
succeed. */
-                                       if (ret == -1) {
-                                               DEBUG(0,("Error doing fstat on 
open file %s "
-                                                        "(%s)\n",
-                                                        
smb_fname_str_dbg(smb_fname),
-                                                        strerror(errno) ));
-                                       }
+                               ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+                               /* If we have an fd, this stat should succeed. 
*/
+                               if (ret == -1) {
+                                       DEBUG(0,("Error doing fstat on open 
file %s "
+                                                "(%s)\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                strerror(errno) ));
                                }
                        }
 
@@ -778,6 +728,37 @@ static NTSTATUS open_file(files_struct *fsp,
                                     FILE_NOTIFY_CHANGE_FILE_NAME,
                                     smb_fname->base_name);
                }
+       } else {
+               fsp->fh->fd = -1; /* What we used to call a stat open. */
+               if (!file_existed) {
+                       /* File must exist for a stat open. */
+                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               }
+
+               status = smbd_check_access_rights(conn,
+                               smb_fname,
+                               access_mask);
+
+               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)));
+                       status = NT_STATUS_OK;
+               }
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(10,("open_file: "
+                               "smbd_check_access_rights on file "
+                               "%s returned %s\n",
+                               smb_fname_str_dbg(smb_fname),
+                               nt_errstr(status) ));
+                       return status;
+               }
        }
 
        /*
@@ -2737,22 +2718,6 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
 }
 
 /****************************************************************************
- Ensure we didn't get symlink raced on opening a directory.
-****************************************************************************/
-
-bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
-                       const SMB_STRUCT_STAT *sbuf2)
-{
-       if (sbuf1->st_ex_uid != sbuf2->st_ex_uid ||
-                       sbuf1->st_ex_gid != sbuf2->st_ex_gid ||
-                       sbuf1->st_ex_dev != sbuf2->st_ex_dev ||
-                       sbuf1->st_ex_ino != sbuf2->st_ex_ino) {
-               return false;
-       }
-       return true;
-}
-
-/****************************************************************************
  Open a directory from an NT SMB call.
 ****************************************************************************/
 
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 4279755..725f89c 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -620,8 +620,6 @@ bool is_deferred_open_async(const void *ptr);
 NTSTATUS open_file_fchmod(connection_struct *conn,
                          struct smb_filename *smb_fname,
                          files_struct **result);
-bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
-                       const SMB_STRUCT_STAT *sbuf2);
 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
                          struct smb_filename *smb_dname);
 void msg_file_was_renamed(struct messaging_context *msg,


-- 
Samba Shared Repository

Reply via email to