From 6473a559c336d5c407f9df412ca2f55357767ff8 Mon Sep 17 00:00:00 2001
From: Steve French <sfrench@us.ibm.com>
Date: Tue, 29 Nov 2005 20:20:10 -0800
Subject: [CIFS] Fix missing permission check on setattr when noperm mount
 option is disabled.  Also set mode, uid, gid better on mkdir and create for
 the case when Unix Extensions is not enabled and setuids is enabled. This is
 necessary to fix the hole in which chown could be allowed for non-root users
 in some cases if root mounted, and also to display the mode and uid properly
 in some cases.

Signed-off-by: Steve French <sfrench@us.ibm.com>
---
 fs/cifs/inode.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

(limited to 'fs/cifs/inode.c')

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index d34325c887c..053c1cadf70 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -710,7 +710,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
 	char *full_path = NULL;
 	struct inode *newinode = NULL;
 
-	cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode));
+	cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
 
 	xid = GetXid();
 
@@ -768,7 +768,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
 			/* BB to be implemented via Windows secrty descriptors
 			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
 						 -1, -1, local_nls); */
-		}
+			if(direntry->d_inode) {
+				direntry->d_inode->i_mode = mode;
+				if(cifs_sb->mnt_cifs_flags & 
+				     CIFS_MOUNT_SET_UID) {
+					direntry->d_inode->i_uid = 
+						current->fsuid;
+					direntry->d_inode->i_gid = 
+						current->fsgid;
+				}
+			}
 	}
 	kfree(full_path);
 	FreeXid(xid);
@@ -1111,9 +1120,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 
 	cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
 		 direntry->d_name.name, attrs->ia_valid));
+
 	cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
 	pTcon = cifs_sb->tcon;
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM == 0) {
+		/* check if we have permission to change attrs */
+		rc = inode_change_ok(direntry->d_inode, attrs);
+		if(rc < 0) {
+			FreeXid(xid);
+			return rc;
+		} else
+			rc = 0;
+	}
+		
 	down(&direntry->d_sb->s_vfs_rename_sem);
 	full_path = build_path_from_dentry(direntry);
 	up(&direntry->d_sb->s_vfs_rename_sem);
@@ -1153,7 +1173,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 						  1 /* 45 seconds */);
 				cFYI(1,("Wrt seteof rc %d", rc));
 			}
-		}
+		} else 
+			rc = -EINVAL;
+
 		if (rc != 0) {
 			/* Set file size by pathname rather than by handle
 			   either because no valid, writeable file handle for
-- 
cgit