diff options
-rw-r--r-- | fs/cifs/dir.c | 13 | ||||
-rw-r--r-- | fs/cifs/inode.c | 18 |
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 | } |