[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Jul 9 19:31:02 MDT 2012


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 <jra at samba.org>
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 <jra at samba.org>
    Autobuild-Date(master): Tue Jul 10 03:30:22 CEST 2012 on sn-devel-104

commit 3a705e5f3d0843e3765852e26661aeee5ebdfd79
Author: Jeremy Allison <jra at samba.org>
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 <jra at samba.org>
Date:   Mon Jul 9 12:28:48 2012 -0700

    Use new common function.

commit 9d5e026bde837ed853478a223e2823fd35c67d26
Author: Jeremy Allison <jra at samba.org>
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 <jra at samba.org>
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


More information about the samba-cvs mailing list