aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-08-06 00:39:02 -0400
committerSteve French <sfrench@us.ibm.com>2008-08-06 00:39:02 -0400
commit95089910933e10768cfef1ab0bab0c55b962aacb (patch)
treec80dd73d46196aff3e6c12a12bfb6b6f20aac08c /fs/cifs
parent2dd2dfa060650118661422d4e666ac804c388751 (diff)
[CIFS] cifs_mkdir and cifs_create should respect the setgid bit on parent dir
If a server supports unix extensions but does not support POSIX create routines, then the client will create a new inode with a standard SMB mkdir or create/open call and then will set the mode. When it does this, it does not take the setgid bit on the parent directory into account. This patch has CIFS flip on the setgid bit when the parent directory has it. If the share is mounted with "setuids" then also change the group owner to the gid of the parent. This patch should apply cleanly on top of the setattr cleanup patches that I sent a few weeks ago. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/dir.c13
-rw-r--r--fs/cifs/inode.c18
2 files changed, 25 insertions, 6 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 634cf330fe04..e962e75e6f7b 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -236,12 +236,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
236 236
237 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 237 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
238 args.uid = (__u64) current->fsuid; 238 args.uid = (__u64) current->fsuid;
239 args.gid = (__u64) current->fsgid; 239 if (inode->i_mode & S_ISGID)
240 args.gid = (__u64) inode->i_gid;
241 else
242 args.gid = (__u64) current->fsgid;
240 } else { 243 } else {
241 args.uid = NO_CHANGE_64; 244 args.uid = NO_CHANGE_64;
242 args.gid = NO_CHANGE_64; 245 args.gid = NO_CHANGE_64;
243 } 246 }
244
245 CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, 247 CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
246 cifs_sb->local_nls, 248 cifs_sb->local_nls,
247 cifs_sb->mnt_cifs_flags & 249 cifs_sb->mnt_cifs_flags &
@@ -270,7 +272,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
270 (cifs_sb->mnt_cifs_flags & 272 (cifs_sb->mnt_cifs_flags &
271 CIFS_MOUNT_SET_UID)) { 273 CIFS_MOUNT_SET_UID)) {
272 newinode->i_uid = current->fsuid; 274 newinode->i_uid = current->fsuid;
273 newinode->i_gid = current->fsgid; 275 if (inode->i_mode & S_ISGID)
276 newinode->i_gid =
277 inode->i_gid;
278 else
279 newinode->i_gid =
280 current->fsgid;
274 } 281 }
275 } 282 }
276 } 283 }
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index d952914dfc4c..6d911896d74c 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -985,7 +985,12 @@ mkdir_get_info:
985 * failed to get it from the server or was set bogus */ 985 * failed to get it from the server or was set bogus */
986 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) 986 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
987 direntry->d_inode->i_nlink = 2; 987 direntry->d_inode->i_nlink = 2;
988
988 mode &= ~current->fs->umask; 989 mode &= ~current->fs->umask;
990 /* must turn on setgid bit if parent dir has it */
991 if (inode->i_mode & S_ISGID)
992 mode |= S_ISGID;
993
989 if (pTcon->unix_ext) { 994 if (pTcon->unix_ext) {
990 struct cifs_unix_set_info_args args = { 995 struct cifs_unix_set_info_args args = {
991 .mode = mode, 996 .mode = mode,
@@ -996,7 +1001,10 @@ mkdir_get_info:
996 }; 1001 };
997 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 1002 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
998 args.uid = (__u64)current->fsuid; 1003 args.uid = (__u64)current->fsuid;
999 args.gid = (__u64)current->fsgid; 1004 if (inode->i_mode & S_ISGID)
1005 args.gid = (__u64)inode->i_gid;
1006 else
1007 args.gid = (__u64)current->fsgid;
1000 } else { 1008 } else {
1001 args.uid = NO_CHANGE_64; 1009 args.uid = NO_CHANGE_64;
1002 args.gid = NO_CHANGE_64; 1010 args.gid = NO_CHANGE_64;
@@ -1026,8 +1034,12 @@ mkdir_get_info:
1026 CIFS_MOUNT_SET_UID) { 1034 CIFS_MOUNT_SET_UID) {
1027 direntry->d_inode->i_uid = 1035 direntry->d_inode->i_uid =
1028 current->fsuid; 1036 current->fsuid;
1029 direntry->d_inode->i_gid = 1037 if (inode->i_mode & S_ISGID)
1030 current->fsgid; 1038 direntry->d_inode->i_gid =
1039 inode->i_gid;
1040 else
1041 direntry->d_inode->i_gid =
1042 current->fsgid;
1031 } 1043 }
1032 } 1044 }
1033 } 1045 }