aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifspdu.h2
-rw-r--r--fs/cifs/cifsproto.h17
-rw-r--r--fs/cifs/cifssmb.c26
-rw-r--r--fs/cifs/dir.c58
-rw-r--r--fs/cifs/file.c19
-rw-r--r--fs/cifs/inode.c54
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,
191extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, 191extern 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);
194extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, 194
195 char *full_path, __u64 mode, __u64 uid, 195struct 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
205extern 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
5015int 5015int
5016CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, 5016CIFSSMBUnixSetInfo(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"));
5030setPermsRetry: 5030setPermsRetry:
@@ -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)