[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Feb 4 19:34:01 MST 2011


The branch, master has been updated
       via  df34e80 Fix try_chown code. Use new vfs_chown_fsp() which always trys fd first.
      from  ece9498 Move the "oplock file with byte range locks" check to the correct place, where we're making oplock decisions.

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


- Log -----------------------------------------------------------------
commit df34e804fc1a44e6ff096fbaf7a643778e857481
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.
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Sat Feb  5 03:33:59 CET 2011 on sn-devel-104

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

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