[SCM] Samba Shared Repository - branch v3-6-test updated

Jeremy Allison jra at samba.org
Fri Feb 4 18:50:39 MST 2011


The branch, v3-6-test has been updated
       via  57b267e Fix try_chown code. Use new vfs_chown_fsp() which always trys fd first. (cherry picked from commit b8035a9b353ac63d421402748d7bd7ec71cbb076)
      from  f96b11d Move the "oplock file with byte range locks" check to the correct place, where we're making oplock decisions. (cherry picked from commit 8d8242cdfd4aec4be87c81022b7a53acfa8ffaaf)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit 57b267ee2bc9ff67555e3b926e5035362c9ba638
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Feb 4 17:48:10 2011 -0800

    Fix try_chown code. Use new vfs_chown_fsp() which always trys fd first.
    (cherry picked from commit b8035a9b353ac63d421402748d7bd7ec71cbb076)

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

Summary of changes:
 source3/include/proto.h     |    4 +-
 source3/modules/nfs4_acls.c |    8 ++--
 source3/smbd/posix_acls.c   |  117 +++++++++++++++---------------------------
 source3/smbd/vfs.c          |   30 +++++++++++
 4 files changed, 78 insertions(+), 81 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 4c7d4f3..94cd0a9 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5158,8 +5158,7 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
 			   struct security_descriptor **ppdesc);
 NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
 			  uint32_t security_info, struct security_descriptor **ppdesc);
-int try_chown(connection_struct *conn, struct smb_filename *smb_fname,
-	      uid_t uid, gid_t gid);
+NTSTATUS try_chown(files_struct *fsp, uid_t uid, gid_t gid);
 NTSTATUS append_parent_acl(files_struct *fsp,
 				const struct security_descriptor *pcsd,
 				struct security_descriptor **pp_new_sd);
@@ -5606,6 +5605,7 @@ int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
 			SMB_STRUCT_STAT *psbuf);
 NTSTATUS vfs_stat_fsp(files_struct *fsp);
+NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid);
 
 /* The following definitions come from utils/passwd_util.c  */
 
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index e2f9fe3..6e6b015 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -765,14 +765,14 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
 		if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
 		    ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
 
-			if(try_chown(fsp->conn, fsp->fsp_name, newUID,
-				     newGID)) {
+			status = try_chown(fsp, newUID, newGID);
+			if (!NT_STATUS_IS_OK(status)) {
 				DEBUG(3,("chown %s, %u, %u failed. Error = "
 					 "%s.\n", fsp_str_dbg(fsp),
 					 (unsigned int)newUID,
 					 (unsigned int)newGID,
-					 strerror(errno)));
-				return map_nt_error_from_unix(errno);
+					 nt_errstr(status)));
+				return status;
 			}
 
 			DEBUG(10,("chown %s, %u, %u succeeded.\n",
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 880d5b9..8707ff7 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3526,105 +3526,73 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
  Try to chown a file. We will be able to chown it under the following conditions.
 
   1) If we have root privileges, then it will just work.
-  2) If we have SeTakeOwnershipPrivilege we can change the user to the current user.
-  3) If we have SeRestorePrivilege we can change the user to any other user. 
+  2) If we have SeRestorePrivilege we can change the user + group to any other user. 
+  3) If we have SeTakeOwnershipPrivilege we can change the user to the current user.
   4) If we have write permission to the file and dos_filemodes is set
      then allow chown to the currently authenticated user.
 ****************************************************************************/
 
-int try_chown(connection_struct *conn, struct smb_filename *smb_fname,
-	      uid_t uid, gid_t gid)
+NTSTATUS try_chown(files_struct *fsp, uid_t uid, gid_t gid)
 {
-	int ret;
-	files_struct *fsp;
+	NTSTATUS status;
 
-	if(!CAN_WRITE(conn)) {
-		return -1;
+	if(!CAN_WRITE(fsp->conn)) {
+		return NT_STATUS_MEDIA_WRITE_PROTECTED;
 	}
 
 	/* Case (1). */
-	/* try the direct way first */
-	if (lp_posix_pathnames()) {
-		ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, uid, gid);
-	} else {
-		ret = SMB_VFS_CHOWN(conn, smb_fname->base_name, uid, gid);
+	status = vfs_chown_fsp(fsp, uid, gid);
+	if (NT_STATUS_IS_OK(status)) {
+		return status;
 	}
 
-	if (ret == 0)
-		return 0;
-
 	/* Case (2) / (3) */
 	if (lp_enable_privileges()) {
-
-		bool has_take_ownership_priv = security_token_has_privilege(get_current_nttok(conn), SEC_PRIV_TAKE_OWNERSHIP);
-		bool has_restore_priv = security_token_has_privilege(get_current_nttok(conn), SEC_PRIV_RESTORE);
-
-		/* Case (2) */
-		if ( ( has_take_ownership_priv && ( uid == get_current_uid(conn) ) ) ||
-		/* Case (3) */
-		     ( has_restore_priv ) ) {
-
-			become_root();
-			/* Keep the current file gid the same - take ownership doesn't imply group change. */
-			if (lp_posix_pathnames()) {
-				ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, uid,
-						    (gid_t)-1);
+		bool has_take_ownership_priv = security_token_has_privilege(
+						get_current_nttok(fsp->conn),
+						SEC_PRIV_TAKE_OWNERSHIP);
+		bool has_restore_priv = security_token_has_privilege(
+						get_current_nttok(fsp->conn),
+						SEC_PRIV_RESTORE);
+
+		if (has_restore_priv) {
+			; /* Case (2) */
+		} else if (has_take_ownership_priv) {
+			/* Case (3) */
+			if (uid == get_current_uid(fsp->conn)) {
+				gid = (gid_t)-1;
 			} else {
-				ret = SMB_VFS_CHOWN(conn, smb_fname->base_name, uid,
-						    (gid_t)-1);
+				has_take_ownership_priv = false;
 			}
+		}
+
+		if (has_take_ownership_priv || has_restore_priv) {
+			become_root();
+			status = vfs_chown_fsp(fsp, uid, gid);
 			unbecome_root();
-			return ret;
+			return status;
 		}
 	}
 
 	/* Case (4). */
-	if (!lp_dos_filemode(SNUM(conn))) {
-		errno = EPERM;
-		return -1;
+	if (!lp_dos_filemode(SNUM(fsp->conn))) {
+		return NT_STATUS_ACCESS_DENIED;
 	}
 
 	/* only allow chown to the current user. This is more secure,
 	   and also copes with the case where the SID in a take ownership ACL is
 	   a local SID on the users workstation
 	*/
-	if (uid != get_current_uid(conn)) {
-		errno = EPERM;
-		return -1;
-	}
-
-	if (lp_posix_pathnames()) {
-		ret = SMB_VFS_LSTAT(conn, smb_fname);
-	} else {
-		ret = SMB_VFS_STAT(conn, smb_fname);
-	}
-
-	if (ret == -1) {
-		return -1;
-	}
-
-	if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname, &fsp))) {
-		return -1;
+	if (uid != get_current_uid(fsp->conn)) {
+		return NT_STATUS_ACCESS_DENIED;
 	}
 
 	become_root();
 	/* Keep the current file gid the same. */
-	if (fsp->fh->fd == -1) {
-		if (lp_posix_pathnames()) {
-			ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, uid,
-					    (gid_t)-1);
-		} else {
-			ret = SMB_VFS_CHOWN(conn, smb_fname->base_name, uid,
-					    (gid_t)-1);
-		}
-	} else {
-		ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1);
-	}
+	status = vfs_chown_fsp(fsp, uid, (gid_t)-1);
 	unbecome_root();
 
-	close_file(NULL, fsp, NORMAL_CLOSE);
-
-	return ret;
+	return status;
 }
 
 #if 0
@@ -3912,15 +3880,14 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s
 			 fsp_str_dbg(fsp), (unsigned int)user,
 			 (unsigned int)grp));
 
-		if(try_chown(fsp->conn, fsp->fsp_name, user, grp) == -1) {
+		status = try_chown(fsp, user, grp);
+		if(!NT_STATUS_IS_OK(status)) {
 			DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error "
-				 "= %s.\n", fsp_str_dbg(fsp),
-				 (unsigned int)user, (unsigned int)grp,
-				 strerror(errno)));
-			if (errno == EPERM) {
-				return NT_STATUS_INVALID_OWNER;
-			}
-			return map_nt_error_from_unix(errno);
+				"= %s.\n", fsp_str_dbg(fsp),
+				(unsigned int)user,
+				(unsigned int)grp,
+				nt_errstr(status)));
+			return status;
 		}
 
 		/*
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 802639f..9e44d02 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1439,6 +1439,36 @@ int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
 	return handle->fns->lchown(handle, path, uid, gid);
 }
 
+NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
+{
+	int ret;
+
+	if (!fsp->is_directory && fsp->fh->fd != -1) {
+		/* Try fchown. */
+		ret = SMB_VFS_FCHOWN(fsp, uid, gid);
+		if (ret == 0) {
+			return NT_STATUS_OK;
+		}
+		if (ret == -1 && errno != ENOSYS) {
+			return map_nt_error_from_unix(errno);
+		}
+	}
+
+	if (fsp->posix_open) {
+		ret = SMB_VFS_LCHOWN(fsp->conn,
+			fsp->fsp_name->base_name,
+			uid, gid);
+	} else {
+		ret = SMB_VFS_CHOWN(fsp->conn,
+			fsp->fsp_name->base_name,
+			uid, gid);
+	}
+	if (ret == 0) {
+		return NT_STATUS_OK;
+	}
+	return map_nt_error_from_unix(errno);
+}
+
 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
 {
 	VFS_FIND(chdir);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list