diff options
-rw-r--r-- | fs/cifs/cifspdu.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 17 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 26 | ||||
-rw-r--r-- | fs/cifs/dir.c | 58 | ||||
-rw-r--r-- | fs/cifs/file.c | 19 | ||||
-rw-r--r-- | fs/cifs/inode.c | 54 |
6 files changed, 102 insertions, 74 deletions
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 409abce12732..d2a073edd1b8 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -262,7 +262,7 @@ | |||
262 | */ | 262 | */ |
263 | #define CIFS_NO_HANDLE 0xFFFF | 263 | #define CIFS_NO_HANDLE 0xFFFF |
264 | 264 | ||
265 | #define NO_CHANGE_64 cpu_to_le64(0xFFFFFFFFFFFFFFFFULL) | 265 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL |
266 | #define NO_CHANGE_32 0xFFFFFFFFUL | 266 | #define NO_CHANGE_32 0xFFFFFFFFUL |
267 | 267 | ||
268 | /* IPC$ in ASCII */ | 268 | /* IPC$ in ASCII */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index b9f5e935f821..e65ff9849092 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -191,9 +191,20 @@ extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, | |||
191 | extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, | 191 | extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, |
192 | __u64 size, __u16 fileHandle, __u32 opener_pid, | 192 | __u64 size, __u16 fileHandle, __u32 opener_pid, |
193 | bool AllocSizeFlag); | 193 | bool AllocSizeFlag); |
194 | extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, | 194 | |
195 | char *full_path, __u64 mode, __u64 uid, | 195 | struct cifs_unix_set_info_args { |
196 | __u64 gid, dev_t dev, | 196 | __u64 ctime; |
197 | __u64 atime; | ||
198 | __u64 mtime; | ||
199 | __u64 mode; | ||
200 | __u64 uid; | ||
201 | __u64 gid; | ||
202 | dev_t device; | ||
203 | }; | ||
204 | |||
205 | extern int CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *pTcon, | ||
206 | char *fileName, | ||
207 | const struct cifs_unix_set_info_args *args, | ||
197 | const struct nls_table *nls_codepage, | 208 | const struct nls_table *nls_codepage, |
198 | int remap_special_chars); | 209 | int remap_special_chars); |
199 | 210 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c621ffa2ca90..ced8eaa9d37d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -5013,10 +5013,9 @@ SetAttrLgcyRetry: | |||
5013 | #endif /* temporarily unneeded SetAttr legacy function */ | 5013 | #endif /* temporarily unneeded SetAttr legacy function */ |
5014 | 5014 | ||
5015 | int | 5015 | int |
5016 | CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, | 5016 | CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, |
5017 | char *fileName, __u64 mode, __u64 uid, __u64 gid, | 5017 | const struct cifs_unix_set_info_args *args, |
5018 | dev_t device, const struct nls_table *nls_codepage, | 5018 | const struct nls_table *nls_codepage, int remap) |
5019 | int remap) | ||
5020 | { | 5019 | { |
5021 | TRANSACTION2_SPI_REQ *pSMB = NULL; | 5020 | TRANSACTION2_SPI_REQ *pSMB = NULL; |
5022 | TRANSACTION2_SPI_RSP *pSMBr = NULL; | 5021 | TRANSACTION2_SPI_RSP *pSMBr = NULL; |
@@ -5025,6 +5024,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, | |||
5025 | int bytes_returned = 0; | 5024 | int bytes_returned = 0; |
5026 | FILE_UNIX_BASIC_INFO *data_offset; | 5025 | FILE_UNIX_BASIC_INFO *data_offset; |
5027 | __u16 params, param_offset, offset, count, byte_count; | 5026 | __u16 params, param_offset, offset, count, byte_count; |
5027 | __u64 mode = args->mode; | ||
5028 | 5028 | ||
5029 | cFYI(1, ("In SetUID/GID/Mode")); | 5029 | cFYI(1, ("In SetUID/GID/Mode")); |
5030 | setPermsRetry: | 5030 | setPermsRetry: |
@@ -5080,16 +5080,16 @@ setPermsRetry: | |||
5080 | set file size and do not want to truncate file size to zero | 5080 | set file size and do not want to truncate file size to zero |
5081 | accidently as happened on one Samba server beta by putting | 5081 | accidently as happened on one Samba server beta by putting |
5082 | zero instead of -1 here */ | 5082 | zero instead of -1 here */ |
5083 | data_offset->EndOfFile = NO_CHANGE_64; | 5083 | data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); |
5084 | data_offset->NumOfBytes = NO_CHANGE_64; | 5084 | data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); |
5085 | data_offset->LastStatusChange = NO_CHANGE_64; | 5085 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); |
5086 | data_offset->LastAccessTime = NO_CHANGE_64; | 5086 | data_offset->LastAccessTime = cpu_to_le64(args->atime); |
5087 | data_offset->LastModificationTime = NO_CHANGE_64; | 5087 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); |
5088 | data_offset->Uid = cpu_to_le64(uid); | 5088 | data_offset->Uid = cpu_to_le64(args->uid); |
5089 | data_offset->Gid = cpu_to_le64(gid); | 5089 | data_offset->Gid = cpu_to_le64(args->gid); |
5090 | /* better to leave device as zero when it is */ | 5090 | /* better to leave device as zero when it is */ |
5091 | data_offset->DevMajor = cpu_to_le64(MAJOR(device)); | 5091 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); |
5092 | data_offset->DevMinor = cpu_to_le64(MINOR(device)); | 5092 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); |
5093 | data_offset->Permissions = cpu_to_le64(mode); | 5093 | data_offset->Permissions = cpu_to_le64(mode); |
5094 | 5094 | ||
5095 | if (S_ISREG(mode)) | 5095 | if (S_ISREG(mode)) |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index fb69c1fa85c9..634cf330fe04 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -226,23 +226,26 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
226 | /* If Open reported that we actually created a file | 226 | /* If Open reported that we actually created a file |
227 | then we now have to set the mode if possible */ | 227 | then we now have to set the mode if possible */ |
228 | if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { | 228 | if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { |
229 | struct cifs_unix_set_info_args args = { | ||
230 | .mode = mode, | ||
231 | .ctime = NO_CHANGE_64, | ||
232 | .atime = NO_CHANGE_64, | ||
233 | .mtime = NO_CHANGE_64, | ||
234 | .device = 0, | ||
235 | }; | ||
236 | |||
229 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 237 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
230 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 238 | args.uid = (__u64) current->fsuid; |
231 | (__u64)current->fsuid, | 239 | args.gid = (__u64) current->fsgid; |
232 | (__u64)current->fsgid, | ||
233 | 0 /* dev */, | ||
234 | cifs_sb->local_nls, | ||
235 | cifs_sb->mnt_cifs_flags & | ||
236 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
237 | } else { | 240 | } else { |
238 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 241 | args.uid = NO_CHANGE_64; |
239 | (__u64)-1, | 242 | args.gid = NO_CHANGE_64; |
240 | (__u64)-1, | ||
241 | 0 /* dev */, | ||
242 | cifs_sb->local_nls, | ||
243 | cifs_sb->mnt_cifs_flags & | ||
244 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
245 | } | 243 | } |
244 | |||
245 | CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, | ||
246 | cifs_sb->local_nls, | ||
247 | cifs_sb->mnt_cifs_flags & | ||
248 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
246 | } else { | 249 | } else { |
247 | /* BB implement mode setting via Windows security | 250 | /* BB implement mode setting via Windows security |
248 | descriptors e.g. */ | 251 | descriptors e.g. */ |
@@ -357,21 +360,24 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
357 | if (full_path == NULL) | 360 | if (full_path == NULL) |
358 | rc = -ENOMEM; | 361 | rc = -ENOMEM; |
359 | else if (pTcon->unix_ext) { | 362 | else if (pTcon->unix_ext) { |
360 | mode &= ~current->fs->umask; | 363 | struct cifs_unix_set_info_args args = { |
364 | .mode = mode & ~current->fs->umask, | ||
365 | .ctime = NO_CHANGE_64, | ||
366 | .atime = NO_CHANGE_64, | ||
367 | .mtime = NO_CHANGE_64, | ||
368 | .device = device_number, | ||
369 | }; | ||
361 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 370 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
362 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 371 | args.uid = (__u64) current->fsuid; |
363 | mode, (__u64)current->fsuid, | 372 | args.gid = (__u64) current->fsgid; |
364 | (__u64)current->fsgid, | ||
365 | device_number, cifs_sb->local_nls, | ||
366 | cifs_sb->mnt_cifs_flags & | ||
367 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
368 | } else { | 373 | } else { |
369 | rc = CIFSSMBUnixSetPerms(xid, pTcon, | 374 | args.uid = NO_CHANGE_64; |
370 | full_path, mode, (__u64)-1, (__u64)-1, | 375 | args.gid = NO_CHANGE_64; |
371 | device_number, cifs_sb->local_nls, | ||
372 | cifs_sb->mnt_cifs_flags & | ||
373 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
374 | } | 376 | } |
377 | rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, | ||
378 | &args, cifs_sb->local_nls, | ||
379 | cifs_sb->mnt_cifs_flags & | ||
380 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
375 | 381 | ||
376 | if (!rc) { | 382 | if (!rc) { |
377 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 383 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0aac824371a5..d40738d2ab58 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -310,18 +310,19 @@ int cifs_open(struct inode *inode, struct file *file) | |||
310 | /* time to set mode which we can not set earlier due to | 310 | /* time to set mode which we can not set earlier due to |
311 | problems creating new read-only files */ | 311 | problems creating new read-only files */ |
312 | if (pTcon->unix_ext) { | 312 | if (pTcon->unix_ext) { |
313 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 313 | struct cifs_unix_set_info_args args = { |
314 | inode->i_mode, | 314 | .mode = inode->i_mode, |
315 | (__u64)-1, (__u64)-1, 0 /* dev */, | 315 | .uid = NO_CHANGE_64, |
316 | .gid = NO_CHANGE_64, | ||
317 | .ctime = NO_CHANGE_64, | ||
318 | .atime = NO_CHANGE_64, | ||
319 | .mtime = NO_CHANGE_64, | ||
320 | .device = 0, | ||
321 | }; | ||
322 | CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, | ||
316 | cifs_sb->local_nls, | 323 | cifs_sb->local_nls, |
317 | cifs_sb->mnt_cifs_flags & | 324 | cifs_sb->mnt_cifs_flags & |
318 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 325 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
319 | } else { | ||
320 | /* BB implement via Windows security descriptors eg | ||
321 | CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, | ||
322 | -1, -1, local_nls); | ||
323 | in the meantime could set r/o dos attribute when | ||
324 | perms are eg: mode & 0222 == 0 */ | ||
325 | } | 326 | } |
326 | } | 327 | } |
327 | 328 | ||
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0e5dccc2f79a..024846719f1f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -986,23 +986,24 @@ mkdir_get_info: | |||
986 | direntry->d_inode->i_nlink = 2; | 986 | direntry->d_inode->i_nlink = 2; |
987 | mode &= ~current->fs->umask; | 987 | mode &= ~current->fs->umask; |
988 | if (pTcon->unix_ext) { | 988 | if (pTcon->unix_ext) { |
989 | struct cifs_unix_set_info_args args = { | ||
990 | .mode = mode, | ||
991 | .ctime = NO_CHANGE_64, | ||
992 | .atime = NO_CHANGE_64, | ||
993 | .mtime = NO_CHANGE_64, | ||
994 | .device = 0, | ||
995 | }; | ||
989 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 996 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
990 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 997 | args.uid = (__u64)current->fsuid; |
991 | mode, | 998 | args.gid = (__u64)current->fsgid; |
992 | (__u64)current->fsuid, | ||
993 | (__u64)current->fsgid, | ||
994 | 0 /* dev_t */, | ||
995 | cifs_sb->local_nls, | ||
996 | cifs_sb->mnt_cifs_flags & | ||
997 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
998 | } else { | 999 | } else { |
999 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 1000 | args.uid = NO_CHANGE_64; |
1000 | mode, (__u64)-1, | 1001 | args.gid = NO_CHANGE_64; |
1001 | (__u64)-1, 0 /* dev_t */, | ||
1002 | cifs_sb->local_nls, | ||
1003 | cifs_sb->mnt_cifs_flags & | ||
1004 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1005 | } | 1002 | } |
1003 | CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, | ||
1004 | cifs_sb->local_nls, | ||
1005 | cifs_sb->mnt_cifs_flags & | ||
1006 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1006 | } else { | 1007 | } else { |
1007 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && | 1008 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
1008 | (mode & S_IWUGO) == 0) { | 1009 | (mode & S_IWUGO) == 0) { |
@@ -1500,9 +1501,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1500 | FILE_BASIC_INFO time_buf; | 1501 | FILE_BASIC_INFO time_buf; |
1501 | bool set_time = false; | 1502 | bool set_time = false; |
1502 | bool set_dosattr = false; | 1503 | bool set_dosattr = false; |
1503 | __u64 mode = 0xFFFFFFFFFFFFFFFFULL; | 1504 | __u64 mode = NO_CHANGE_64; |
1504 | __u64 uid = 0xFFFFFFFFFFFFFFFFULL; | 1505 | __u64 uid = NO_CHANGE_64; |
1505 | __u64 gid = 0xFFFFFFFFFFFFFFFFULL; | 1506 | __u64 gid = NO_CHANGE_64; |
1506 | struct cifsInodeInfo *cifsInode; | 1507 | struct cifsInodeInfo *cifsInode; |
1507 | struct inode *inode = direntry->d_inode; | 1508 | struct inode *inode = direntry->d_inode; |
1508 | 1509 | ||
@@ -1586,12 +1587,21 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1586 | } | 1587 | } |
1587 | 1588 | ||
1588 | if ((pTcon->unix_ext) | 1589 | if ((pTcon->unix_ext) |
1589 | && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) | 1590 | && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) { |
1590 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, | 1591 | struct cifs_unix_set_info_args args = { |
1591 | 0 /* dev_t */, cifs_sb->local_nls, | 1592 | .mode = mode, |
1592 | cifs_sb->mnt_cifs_flags & | 1593 | .uid = uid, |
1594 | .gid = gid, | ||
1595 | .ctime = NO_CHANGE_64, | ||
1596 | .atime = NO_CHANGE_64, | ||
1597 | .mtime = NO_CHANGE_64, | ||
1598 | .device = 0, | ||
1599 | }; | ||
1600 | rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, | ||
1601 | cifs_sb->local_nls, | ||
1602 | cifs_sb->mnt_cifs_flags & | ||
1593 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1603 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1594 | else if (attrs->ia_valid & ATTR_MODE) { | 1604 | } else if (attrs->ia_valid & ATTR_MODE) { |
1595 | rc = 0; | 1605 | rc = 0; |
1596 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 1606 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
1597 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) | 1607 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |