diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-18 14:11:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-18 14:11:51 -0400 |
commit | ae9b728c8dc0a9939d89f84e8603258ca2a0df22 (patch) | |
tree | 2409a26fd6776e2d06098d5e8d00542fc384090d /fs/cifs | |
parent | d9b9c893048e9d308a833619f0866f1f52778cf5 (diff) | |
parent | e9630660bd9253b3ed3926e18278b740cf218365 (diff) |
Merge tag '4.3-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French:
"Fixes (three for stable) and improvements including much faster
encryption (SMB3.1.1 GCM)"
* tag '4.3-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: (27 commits)
smb3: smbdirect no longer experimental
cifs: fix crash in smb2_compound_op()/smb2_set_next_command()
cifs: fix crash in cifs_dfs_do_automount
cifs: fix parsing of symbolic link error response
cifs: refactor and clean up arguments in the reparse point parsing
SMB3: query inode number on open via create context
smb3: Send netname context during negotiate protocol
smb3: do not send compression info by default
smb3: add new mount option to retrieve mode from special ACE
smb3: Allow query of symlinks stored as reparse points
cifs: Fix a race condition with cifs_echo_request
cifs: always add credits back for unsolicited PDUs
fs: cifs: cifsssmb: Change return type of convert_ace_to_cifs_ace
add some missing definitions
cifs: fix typo in debug message with struct field ia_valid
smb3: minor cleanup of compound_send_recv
CIFS: Fix module dependency
cifs: simplify code by removing CONFIG_CIFS_ACL ifdef
cifs: Fix check for matching with existing mount
cifs: Properly handle auto disabling of serverino option
...
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/Kconfig | 18 | ||||
-rw-r--r-- | fs/cifs/Makefile | 3 | ||||
-rw-r--r-- | fs/cifs/cifs_debug.c | 2 | ||||
-rw-r--r-- | fs/cifs/cifs_fs_sb.h | 6 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 14 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 7 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 16 | ||||
-rw-r--r-- | fs/cifs/connect.c | 61 | ||||
-rw-r--r-- | fs/cifs/dfs_cache.c | 2 | ||||
-rw-r--r-- | fs/cifs/inode.c | 8 | ||||
-rw-r--r-- | fs/cifs/misc.c | 1 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 3 | ||||
-rw-r--r-- | fs/cifs/smb2inode.c | 12 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 143 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 96 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 36 | ||||
-rw-r--r-- | fs/cifs/smb2transport.c | 10 | ||||
-rw-r--r-- | fs/cifs/transport.c | 46 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 4 |
19 files changed, 335 insertions, 153 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 523e9ea78a28..b16219e5dac9 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -13,9 +13,11 @@ config CIFS | |||
13 | select CRYPTO_LIB_ARC4 | 13 | select CRYPTO_LIB_ARC4 |
14 | select CRYPTO_AEAD2 | 14 | select CRYPTO_AEAD2 |
15 | select CRYPTO_CCM | 15 | select CRYPTO_CCM |
16 | select CRYPTO_GCM | ||
16 | select CRYPTO_ECB | 17 | select CRYPTO_ECB |
17 | select CRYPTO_AES | 18 | select CRYPTO_AES |
18 | select CRYPTO_DES | 19 | select CRYPTO_DES |
20 | select KEYS | ||
19 | help | 21 | help |
20 | This is the client VFS module for the SMB3 family of NAS protocols, | 22 | This is the client VFS module for the SMB3 family of NAS protocols, |
21 | (including support for the most recent, most secure dialect SMB3.1.1) | 23 | (including support for the most recent, most secure dialect SMB3.1.1) |
@@ -109,7 +111,7 @@ config CIFS_WEAK_PW_HASH | |||
109 | 111 | ||
110 | config CIFS_UPCALL | 112 | config CIFS_UPCALL |
111 | bool "Kerberos/SPNEGO advanced session setup" | 113 | bool "Kerberos/SPNEGO advanced session setup" |
112 | depends on CIFS && KEYS | 114 | depends on CIFS |
113 | select DNS_RESOLVER | 115 | select DNS_RESOLVER |
114 | help | 116 | help |
115 | Enables an upcall mechanism for CIFS which accesses userspace helper | 117 | Enables an upcall mechanism for CIFS which accesses userspace helper |
@@ -144,14 +146,6 @@ config CIFS_POSIX | |||
144 | (such as Samba 3.10 and later) which can negotiate | 146 | (such as Samba 3.10 and later) which can negotiate |
145 | CIFS POSIX ACL support. If unsure, say N. | 147 | CIFS POSIX ACL support. If unsure, say N. |
146 | 148 | ||
147 | config CIFS_ACL | ||
148 | bool "Provide CIFS ACL support" | ||
149 | depends on CIFS_XATTR && KEYS | ||
150 | help | ||
151 | Allows fetching CIFS/NTFS ACL from the server. The DACL blob | ||
152 | is handed over to the application/caller. See the man | ||
153 | page for getcifsacl for more information. If unsure, say Y. | ||
154 | |||
155 | config CIFS_DEBUG | 149 | config CIFS_DEBUG |
156 | bool "Enable CIFS debugging routines" | 150 | bool "Enable CIFS debugging routines" |
157 | default y | 151 | default y |
@@ -184,7 +178,7 @@ config CIFS_DEBUG_DUMP_KEYS | |||
184 | 178 | ||
185 | config CIFS_DFS_UPCALL | 179 | config CIFS_DFS_UPCALL |
186 | bool "DFS feature support" | 180 | bool "DFS feature support" |
187 | depends on CIFS && KEYS | 181 | depends on CIFS |
188 | select DNS_RESOLVER | 182 | select DNS_RESOLVER |
189 | help | 183 | help |
190 | Distributed File System (DFS) support is used to access shares | 184 | Distributed File System (DFS) support is used to access shares |
@@ -203,10 +197,10 @@ config CIFS_NFSD_EXPORT | |||
203 | Allows NFS server to export a CIFS mounted share (nfsd over cifs) | 197 | Allows NFS server to export a CIFS mounted share (nfsd over cifs) |
204 | 198 | ||
205 | config CIFS_SMB_DIRECT | 199 | config CIFS_SMB_DIRECT |
206 | bool "SMB Direct support (Experimental)" | 200 | bool "SMB Direct support" |
207 | depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y | 201 | depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y |
208 | help | 202 | help |
209 | Enables SMB Direct experimental support for SMB 3.0, 3.02 and 3.1.1. | 203 | Enables SMB Direct support for SMB 3.0, 3.02 and 3.1.1. |
210 | SMB Direct allows transferring SMB packets over RDMA. If unsure, | 204 | SMB Direct allows transferring SMB packets over RDMA. If unsure, |
211 | say N. | 205 | say N. |
212 | 206 | ||
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index 51af69a1a328..41332f20055b 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
@@ -10,10 +10,9 @@ cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \ | |||
10 | cifs_unicode.o nterr.o cifsencrypt.o \ | 10 | cifs_unicode.o nterr.o cifsencrypt.o \ |
11 | readdir.o ioctl.o sess.o export.o smb1ops.o winucase.o \ | 11 | readdir.o ioctl.o sess.o export.o smb1ops.o winucase.o \ |
12 | smb2ops.o smb2maperror.o smb2transport.o \ | 12 | smb2ops.o smb2maperror.o smb2transport.o \ |
13 | smb2misc.o smb2pdu.o smb2inode.o smb2file.o | 13 | smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o |
14 | 14 | ||
15 | cifs-$(CONFIG_CIFS_XATTR) += xattr.o | 15 | cifs-$(CONFIG_CIFS_XATTR) += xattr.o |
16 | cifs-$(CONFIG_CIFS_ACL) += cifsacl.o | ||
17 | 16 | ||
18 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o | 17 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o |
19 | 18 | ||
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index ec933fb0b36e..a38d796f5ffe 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -240,9 +240,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) | |||
240 | #ifdef CONFIG_CIFS_XATTR | 240 | #ifdef CONFIG_CIFS_XATTR |
241 | seq_printf(m, ",XATTR"); | 241 | seq_printf(m, ",XATTR"); |
242 | #endif | 242 | #endif |
243 | #ifdef CONFIG_CIFS_ACL | ||
244 | seq_printf(m, ",ACL"); | 243 | seq_printf(m, ",ACL"); |
245 | #endif | ||
246 | seq_putc(m, '\n'); | 244 | seq_putc(m, '\n'); |
247 | seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize); | 245 | seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize); |
248 | seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); | 246 | seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index ed49222abecb..b326d2ca3765 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -52,6 +52,7 @@ | |||
52 | #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */ | 52 | #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */ |
53 | #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */ | 53 | #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */ |
54 | #define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */ | 54 | #define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */ |
55 | #define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */ | ||
55 | 56 | ||
56 | struct cifs_sb_info { | 57 | struct cifs_sb_info { |
57 | struct rb_root tlink_tree; | 58 | struct rb_root tlink_tree; |
@@ -83,5 +84,10 @@ struct cifs_sb_info { | |||
83 | * failover properly. | 84 | * failover properly. |
84 | */ | 85 | */ |
85 | char *origin_fullpath; /* \\HOST\SHARE\[OPTIONAL PATH] */ | 86 | char *origin_fullpath; /* \\HOST\SHARE\[OPTIONAL PATH] */ |
87 | /* | ||
88 | * Indicate whether serverino option was turned off later | ||
89 | * (cifs_autodisable_serverino) in order to match new mounts. | ||
90 | */ | ||
91 | bool mnt_cifs_serverino_autodisabled; | ||
86 | }; | 92 | }; |
87 | #endif /* _CIFS_FS_SB_H */ | 93 | #endif /* _CIFS_FS_SB_H */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 24635b65effa..270d3c58fb3b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -526,6 +526,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
526 | seq_puts(s, ",nobrl"); | 526 | seq_puts(s, ",nobrl"); |
527 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_HANDLE_CACHE) | 527 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_HANDLE_CACHE) |
528 | seq_puts(s, ",nohandlecache"); | 528 | seq_puts(s, ",nohandlecache"); |
529 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) | ||
530 | seq_puts(s, ",modefromsid"); | ||
529 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) | 531 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |
530 | seq_puts(s, ",cifsacl"); | 532 | seq_puts(s, ",cifsacl"); |
531 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 533 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
@@ -554,6 +556,11 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
554 | seq_printf(s, ",bsize=%u", cifs_sb->bsize); | 556 | seq_printf(s, ",bsize=%u", cifs_sb->bsize); |
555 | seq_printf(s, ",echo_interval=%lu", | 557 | seq_printf(s, ",echo_interval=%lu", |
556 | tcon->ses->server->echo_interval / HZ); | 558 | tcon->ses->server->echo_interval / HZ); |
559 | |||
560 | /* Only display max_credits if it was overridden on mount */ | ||
561 | if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE) | ||
562 | seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits); | ||
563 | |||
557 | if (tcon->snapshot_time) | 564 | if (tcon->snapshot_time) |
558 | seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); | 565 | seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); |
559 | if (tcon->handle_timeout) | 566 | if (tcon->handle_timeout) |
@@ -1517,11 +1524,9 @@ init_cifs(void) | |||
1517 | goto out_destroy_dfs_cache; | 1524 | goto out_destroy_dfs_cache; |
1518 | #endif /* CONFIG_CIFS_UPCALL */ | 1525 | #endif /* CONFIG_CIFS_UPCALL */ |
1519 | 1526 | ||
1520 | #ifdef CONFIG_CIFS_ACL | ||
1521 | rc = init_cifs_idmap(); | 1527 | rc = init_cifs_idmap(); |
1522 | if (rc) | 1528 | if (rc) |
1523 | goto out_register_key_type; | 1529 | goto out_register_key_type; |
1524 | #endif /* CONFIG_CIFS_ACL */ | ||
1525 | 1530 | ||
1526 | rc = register_filesystem(&cifs_fs_type); | 1531 | rc = register_filesystem(&cifs_fs_type); |
1527 | if (rc) | 1532 | if (rc) |
@@ -1536,10 +1541,8 @@ init_cifs(void) | |||
1536 | return 0; | 1541 | return 0; |
1537 | 1542 | ||
1538 | out_init_cifs_idmap: | 1543 | out_init_cifs_idmap: |
1539 | #ifdef CONFIG_CIFS_ACL | ||
1540 | exit_cifs_idmap(); | 1544 | exit_cifs_idmap(); |
1541 | out_register_key_type: | 1545 | out_register_key_type: |
1542 | #endif | ||
1543 | #ifdef CONFIG_CIFS_UPCALL | 1546 | #ifdef CONFIG_CIFS_UPCALL |
1544 | exit_cifs_spnego(); | 1547 | exit_cifs_spnego(); |
1545 | out_destroy_dfs_cache: | 1548 | out_destroy_dfs_cache: |
@@ -1571,9 +1574,7 @@ exit_cifs(void) | |||
1571 | unregister_filesystem(&cifs_fs_type); | 1574 | unregister_filesystem(&cifs_fs_type); |
1572 | unregister_filesystem(&smb3_fs_type); | 1575 | unregister_filesystem(&smb3_fs_type); |
1573 | cifs_dfs_release_automount_timer(); | 1576 | cifs_dfs_release_automount_timer(); |
1574 | #ifdef CONFIG_CIFS_ACL | ||
1575 | exit_cifs_idmap(); | 1577 | exit_cifs_idmap(); |
1576 | #endif | ||
1577 | #ifdef CONFIG_CIFS_UPCALL | 1578 | #ifdef CONFIG_CIFS_UPCALL |
1578 | exit_cifs_spnego(); | 1579 | exit_cifs_spnego(); |
1579 | #endif | 1580 | #endif |
@@ -1607,5 +1608,6 @@ MODULE_SOFTDEP("pre: sha256"); | |||
1607 | MODULE_SOFTDEP("pre: sha512"); | 1608 | MODULE_SOFTDEP("pre: sha512"); |
1608 | MODULE_SOFTDEP("pre: aead2"); | 1609 | MODULE_SOFTDEP("pre: aead2"); |
1609 | MODULE_SOFTDEP("pre: ccm"); | 1610 | MODULE_SOFTDEP("pre: ccm"); |
1611 | MODULE_SOFTDEP("pre: gcm"); | ||
1610 | module_init(init_cifs) | 1612 | module_init(init_cifs) |
1611 | module_exit(exit_cifs) | 1613 | module_exit(exit_cifs) |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 4777b3c4a92c..fe610e7e3670 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -550,6 +550,7 @@ struct smb_vol { | |||
550 | bool override_gid:1; | 550 | bool override_gid:1; |
551 | bool dynperm:1; | 551 | bool dynperm:1; |
552 | bool noperm:1; | 552 | bool noperm:1; |
553 | bool mode_ace:1; | ||
553 | bool no_psx_acl:1; /* set if posix acl support should be disabled */ | 554 | bool no_psx_acl:1; /* set if posix acl support should be disabled */ |
554 | bool cifs_acl:1; | 555 | bool cifs_acl:1; |
555 | bool backupuid_specified; /* mount option backupuid is specified */ | 556 | bool backupuid_specified; /* mount option backupuid is specified */ |
@@ -600,6 +601,7 @@ struct smb_vol { | |||
600 | __u64 snapshot_time; /* needed for timewarp tokens */ | 601 | __u64 snapshot_time; /* needed for timewarp tokens */ |
601 | __u32 handle_timeout; /* persistent and durable handle timeout in ms */ | 602 | __u32 handle_timeout; /* persistent and durable handle timeout in ms */ |
602 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ | 603 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ |
604 | __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ | ||
603 | }; | 605 | }; |
604 | 606 | ||
605 | /** | 607 | /** |
@@ -617,7 +619,8 @@ struct smb_vol { | |||
617 | CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \ | 619 | CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \ |
618 | CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \ | 620 | CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \ |
619 | CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ | 621 | CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ |
620 | CIFS_MOUNT_NO_DFS) | 622 | CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ |
623 | CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID) | ||
621 | 624 | ||
622 | /** | 625 | /** |
623 | * Generic VFS superblock mount flags (s_flags) to consider when | 626 | * Generic VFS superblock mount flags (s_flags) to consider when |
@@ -1870,7 +1873,6 @@ extern unsigned int cifs_min_small; /* min size of small buf pool */ | |||
1870 | extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ | 1873 | extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ |
1871 | extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ | 1874 | extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ |
1872 | 1875 | ||
1873 | #ifdef CONFIG_CIFS_ACL | ||
1874 | GLOBAL_EXTERN struct rb_root uidtree; | 1876 | GLOBAL_EXTERN struct rb_root uidtree; |
1875 | GLOBAL_EXTERN struct rb_root gidtree; | 1877 | GLOBAL_EXTERN struct rb_root gidtree; |
1876 | GLOBAL_EXTERN spinlock_t siduidlock; | 1878 | GLOBAL_EXTERN spinlock_t siduidlock; |
@@ -1879,7 +1881,6 @@ GLOBAL_EXTERN struct rb_root siduidtree; | |||
1879 | GLOBAL_EXTERN struct rb_root sidgidtree; | 1881 | GLOBAL_EXTERN struct rb_root sidgidtree; |
1880 | GLOBAL_EXTERN spinlock_t uidsidlock; | 1882 | GLOBAL_EXTERN spinlock_t uidsidlock; |
1881 | GLOBAL_EXTERN spinlock_t gidsidlock; | 1883 | GLOBAL_EXTERN spinlock_t gidsidlock; |
1882 | #endif /* CONFIG_CIFS_ACL */ | ||
1883 | 1884 | ||
1884 | void cifs_oplock_break(struct work_struct *work); | 1885 | void cifs_oplock_break(struct work_struct *work); |
1885 | void cifs_queue_oplock_break(struct cifsFileInfo *cfile); | 1886 | void cifs_queue_oplock_break(struct cifsFileInfo *cfile); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1fbd92843a73..e2f95965065d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -3600,11 +3600,9 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, | |||
3600 | return size; | 3600 | return size; |
3601 | } | 3601 | } |
3602 | 3602 | ||
3603 | static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace, | 3603 | static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace, |
3604 | const struct posix_acl_xattr_entry *local_ace) | 3604 | const struct posix_acl_xattr_entry *local_ace) |
3605 | { | 3605 | { |
3606 | __u16 rc = 0; /* 0 = ACL converted ok */ | ||
3607 | |||
3608 | cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm); | 3606 | cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm); |
3609 | cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag); | 3607 | cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag); |
3610 | /* BB is there a better way to handle the large uid? */ | 3608 | /* BB is there a better way to handle the large uid? */ |
@@ -3617,7 +3615,6 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace, | |||
3617 | cifs_dbg(FYI, "perm %d tag %d id %d\n", | 3615 | cifs_dbg(FYI, "perm %d tag %d id %d\n", |
3618 | ace->e_perm, ace->e_tag, ace->e_id); | 3616 | ace->e_perm, ace->e_tag, ace->e_id); |
3619 | */ | 3617 | */ |
3620 | return rc; | ||
3621 | } | 3618 | } |
3622 | 3619 | ||
3623 | /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */ | 3620 | /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */ |
@@ -3653,13 +3650,8 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL, | |||
3653 | cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); | 3650 | cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); |
3654 | return 0; | 3651 | return 0; |
3655 | } | 3652 | } |
3656 | for (i = 0; i < count; i++) { | 3653 | for (i = 0; i < count; i++) |
3657 | rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]); | 3654 | convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]); |
3658 | if (rc != 0) { | ||
3659 | /* ACE not converted */ | ||
3660 | break; | ||
3661 | } | ||
3662 | } | ||
3663 | if (rc == 0) { | 3655 | if (rc == 0) { |
3664 | rc = (__u16)(count * sizeof(struct cifs_posix_ace)); | 3656 | rc = (__u16)(count * sizeof(struct cifs_posix_ace)); |
3665 | rc += sizeof(struct cifs_posix_acl); | 3657 | rc += sizeof(struct cifs_posix_acl); |
@@ -3920,7 +3912,6 @@ GetExtAttrOut: | |||
3920 | 3912 | ||
3921 | #endif /* CONFIG_POSIX */ | 3913 | #endif /* CONFIG_POSIX */ |
3922 | 3914 | ||
3923 | #ifdef CONFIG_CIFS_ACL | ||
3924 | /* | 3915 | /* |
3925 | * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that | 3916 | * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that |
3926 | * all NT TRANSACTS that we init here have total parm and data under about 400 | 3917 | * all NT TRANSACTS that we init here have total parm and data under about 400 |
@@ -4164,7 +4155,6 @@ setCifsAclRetry: | |||
4164 | return (rc); | 4155 | return (rc); |
4165 | } | 4156 | } |
4166 | 4157 | ||
4167 | #endif /* CONFIG_CIFS_ACL */ | ||
4168 | 4158 | ||
4169 | /* Legacy Query Path Information call for lookup to old servers such | 4159 | /* Legacy Query Path Information call for lookup to old servers such |
4170 | as Win9x/WinME */ | 4160 | as Win9x/WinME */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 714a359c7c8d..a4830ced0f98 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -96,7 +96,8 @@ enum { | |||
96 | Opt_multiuser, Opt_sloppy, Opt_nosharesock, | 96 | Opt_multiuser, Opt_sloppy, Opt_nosharesock, |
97 | Opt_persistent, Opt_nopersistent, | 97 | Opt_persistent, Opt_nopersistent, |
98 | Opt_resilient, Opt_noresilient, | 98 | Opt_resilient, Opt_noresilient, |
99 | Opt_domainauto, Opt_rdma, | 99 | Opt_domainauto, Opt_rdma, Opt_modesid, |
100 | Opt_compress, | ||
100 | 101 | ||
101 | /* Mount options which take numeric value */ | 102 | /* Mount options which take numeric value */ |
102 | Opt_backupuid, Opt_backupgid, Opt_uid, | 103 | Opt_backupuid, Opt_backupgid, Opt_uid, |
@@ -175,6 +176,7 @@ static const match_table_t cifs_mount_option_tokens = { | |||
175 | { Opt_serverino, "serverino" }, | 176 | { Opt_serverino, "serverino" }, |
176 | { Opt_noserverino, "noserverino" }, | 177 | { Opt_noserverino, "noserverino" }, |
177 | { Opt_rwpidforward, "rwpidforward" }, | 178 | { Opt_rwpidforward, "rwpidforward" }, |
179 | { Opt_modesid, "modefromsid" }, | ||
178 | { Opt_cifsacl, "cifsacl" }, | 180 | { Opt_cifsacl, "cifsacl" }, |
179 | { Opt_nocifsacl, "nocifsacl" }, | 181 | { Opt_nocifsacl, "nocifsacl" }, |
180 | { Opt_acl, "acl" }, | 182 | { Opt_acl, "acl" }, |
@@ -212,6 +214,7 @@ static const match_table_t cifs_mount_option_tokens = { | |||
212 | { Opt_echo_interval, "echo_interval=%s" }, | 214 | { Opt_echo_interval, "echo_interval=%s" }, |
213 | { Opt_max_credits, "max_credits=%s" }, | 215 | { Opt_max_credits, "max_credits=%s" }, |
214 | { Opt_snapshot, "snapshot=%s" }, | 216 | { Opt_snapshot, "snapshot=%s" }, |
217 | { Opt_compress, "compress=%s" }, | ||
215 | 218 | ||
216 | { Opt_blank_user, "user=" }, | 219 | { Opt_blank_user, "user=" }, |
217 | { Opt_blank_user, "username=" }, | 220 | { Opt_blank_user, "username=" }, |
@@ -706,10 +709,10 @@ static bool | |||
706 | server_unresponsive(struct TCP_Server_Info *server) | 709 | server_unresponsive(struct TCP_Server_Info *server) |
707 | { | 710 | { |
708 | /* | 711 | /* |
709 | * We need to wait 2 echo intervals to make sure we handle such | 712 | * We need to wait 3 echo intervals to make sure we handle such |
710 | * situations right: | 713 | * situations right: |
711 | * 1s client sends a normal SMB request | 714 | * 1s client sends a normal SMB request |
712 | * 2s client gets a response | 715 | * 3s client gets a response |
713 | * 30s echo workqueue job pops, and decides we got a response recently | 716 | * 30s echo workqueue job pops, and decides we got a response recently |
714 | * and don't need to send another | 717 | * and don't need to send another |
715 | * ... | 718 | * ... |
@@ -718,9 +721,9 @@ server_unresponsive(struct TCP_Server_Info *server) | |||
718 | */ | 721 | */ |
719 | if ((server->tcpStatus == CifsGood || | 722 | if ((server->tcpStatus == CifsGood || |
720 | server->tcpStatus == CifsNeedNegotiate) && | 723 | server->tcpStatus == CifsNeedNegotiate) && |
721 | time_after(jiffies, server->lstrp + 2 * server->echo_interval)) { | 724 | time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { |
722 | cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", | 725 | cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", |
723 | server->hostname, (2 * server->echo_interval) / HZ); | 726 | server->hostname, (3 * server->echo_interval) / HZ); |
724 | cifs_reconnect(server); | 727 | cifs_reconnect(server); |
725 | wake_up(&server->response_q); | 728 | wake_up(&server->response_q); |
726 | return true; | 729 | return true; |
@@ -1223,11 +1226,11 @@ next_pdu: | |||
1223 | atomic_read(&midCount)); | 1226 | atomic_read(&midCount)); |
1224 | cifs_dump_mem("Received Data is: ", bufs[i], | 1227 | cifs_dump_mem("Received Data is: ", bufs[i], |
1225 | HEADER_SIZE(server)); | 1228 | HEADER_SIZE(server)); |
1229 | smb2_add_credits_from_hdr(bufs[i], server); | ||
1226 | #ifdef CONFIG_CIFS_DEBUG2 | 1230 | #ifdef CONFIG_CIFS_DEBUG2 |
1227 | if (server->ops->dump_detail) | 1231 | if (server->ops->dump_detail) |
1228 | server->ops->dump_detail(bufs[i], | 1232 | server->ops->dump_detail(bufs[i], |
1229 | server); | 1233 | server); |
1230 | smb2_add_credits_from_hdr(bufs[i], server); | ||
1231 | cifs_dump_mids(server); | 1234 | cifs_dump_mids(server); |
1232 | #endif /* CIFS_DEBUG2 */ | 1235 | #endif /* CIFS_DEBUG2 */ |
1233 | } | 1236 | } |
@@ -1830,6 +1833,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1830 | case Opt_rwpidforward: | 1833 | case Opt_rwpidforward: |
1831 | vol->rwpidforward = 1; | 1834 | vol->rwpidforward = 1; |
1832 | break; | 1835 | break; |
1836 | case Opt_modesid: | ||
1837 | vol->mode_ace = 1; | ||
1838 | break; | ||
1833 | case Opt_cifsacl: | 1839 | case Opt_cifsacl: |
1834 | vol->cifs_acl = 1; | 1840 | vol->cifs_acl = 1; |
1835 | break; | 1841 | break; |
@@ -1911,6 +1917,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1911 | case Opt_rdma: | 1917 | case Opt_rdma: |
1912 | vol->rdma = true; | 1918 | vol->rdma = true; |
1913 | break; | 1919 | break; |
1920 | case Opt_compress: | ||
1921 | vol->compression = UNKNOWN_TYPE; | ||
1922 | cifs_dbg(VFS, | ||
1923 | "SMB3 compression support is experimental\n"); | ||
1924 | break; | ||
1914 | 1925 | ||
1915 | /* Numeric Values */ | 1926 | /* Numeric Values */ |
1916 | case Opt_backupuid: | 1927 | case Opt_backupuid: |
@@ -2544,8 +2555,15 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol) | |||
2544 | if (vol->nosharesock) | 2555 | if (vol->nosharesock) |
2545 | return 0; | 2556 | return 0; |
2546 | 2557 | ||
2547 | /* BB update this for smb3any and default case */ | 2558 | /* If multidialect negotiation see if existing sessions match one */ |
2548 | if ((server->vals != vol->vals) || (server->ops != vol->ops)) | 2559 | if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { |
2560 | if (server->vals->protocol_id < SMB30_PROT_ID) | ||
2561 | return 0; | ||
2562 | } else if (strcmp(vol->vals->version_string, | ||
2563 | SMBDEFAULT_VERSION_STRING) == 0) { | ||
2564 | if (server->vals->protocol_id < SMB21_PROT_ID) | ||
2565 | return 0; | ||
2566 | } else if ((server->vals != vol->vals) || (server->ops != vol->ops)) | ||
2549 | return 0; | 2567 | return 0; |
2550 | 2568 | ||
2551 | if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) | 2569 | if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) |
@@ -2680,6 +2698,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
2680 | tcp_ses->sequence_number = 0; | 2698 | tcp_ses->sequence_number = 0; |
2681 | tcp_ses->reconnect_instance = 1; | 2699 | tcp_ses->reconnect_instance = 1; |
2682 | tcp_ses->lstrp = jiffies; | 2700 | tcp_ses->lstrp = jiffies; |
2701 | tcp_ses->compress_algorithm = cpu_to_le16(volume_info->compression); | ||
2683 | spin_lock_init(&tcp_ses->req_lock); | 2702 | spin_lock_init(&tcp_ses->req_lock); |
2684 | INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); | 2703 | INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); |
2685 | INIT_LIST_HEAD(&tcp_ses->smb_ses_list); | 2704 | INIT_LIST_HEAD(&tcp_ses->smb_ses_list); |
@@ -3460,12 +3479,16 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | |||
3460 | { | 3479 | { |
3461 | struct cifs_sb_info *old = CIFS_SB(sb); | 3480 | struct cifs_sb_info *old = CIFS_SB(sb); |
3462 | struct cifs_sb_info *new = mnt_data->cifs_sb; | 3481 | struct cifs_sb_info *new = mnt_data->cifs_sb; |
3482 | unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK; | ||
3483 | unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK; | ||
3463 | 3484 | ||
3464 | if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK)) | 3485 | if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK)) |
3465 | return 0; | 3486 | return 0; |
3466 | 3487 | ||
3467 | if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) != | 3488 | if (old->mnt_cifs_serverino_autodisabled) |
3468 | (new->mnt_cifs_flags & CIFS_MOUNT_MASK)) | 3489 | newflags &= ~CIFS_MOUNT_SERVER_INUM; |
3490 | |||
3491 | if (oldflags != newflags) | ||
3469 | return 0; | 3492 | return 0; |
3470 | 3493 | ||
3471 | /* | 3494 | /* |
@@ -3965,6 +3988,8 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
3965 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; | 3988 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; |
3966 | if (pvolume_info->rwpidforward) | 3989 | if (pvolume_info->rwpidforward) |
3967 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; | 3990 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; |
3991 | if (pvolume_info->mode_ace) | ||
3992 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID; | ||
3968 | if (pvolume_info->cifs_acl) | 3993 | if (pvolume_info->cifs_acl) |
3969 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; | 3994 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; |
3970 | if (pvolume_info->backupuid_specified) { | 3995 | if (pvolume_info->backupuid_specified) { |
@@ -4459,11 +4484,13 @@ cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, | |||
4459 | unsigned int xid, | 4484 | unsigned int xid, |
4460 | struct cifs_tcon *tcon, | 4485 | struct cifs_tcon *tcon, |
4461 | struct cifs_sb_info *cifs_sb, | 4486 | struct cifs_sb_info *cifs_sb, |
4462 | char *full_path) | 4487 | char *full_path, |
4488 | int added_treename) | ||
4463 | { | 4489 | { |
4464 | int rc; | 4490 | int rc; |
4465 | char *s; | 4491 | char *s; |
4466 | char sep, tmp; | 4492 | char sep, tmp; |
4493 | int skip = added_treename ? 1 : 0; | ||
4467 | 4494 | ||
4468 | sep = CIFS_DIR_SEP(cifs_sb); | 4495 | sep = CIFS_DIR_SEP(cifs_sb); |
4469 | s = full_path; | 4496 | s = full_path; |
@@ -4478,7 +4505,14 @@ cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, | |||
4478 | /* next separator */ | 4505 | /* next separator */ |
4479 | while (*s && *s != sep) | 4506 | while (*s && *s != sep) |
4480 | s++; | 4507 | s++; |
4481 | 4508 | /* | |
4509 | * if the treename is added, we then have to skip the first | ||
4510 | * part within the separators | ||
4511 | */ | ||
4512 | if (skip) { | ||
4513 | skip = 0; | ||
4514 | continue; | ||
4515 | } | ||
4482 | /* | 4516 | /* |
4483 | * temporarily null-terminate the path at the end of | 4517 | * temporarily null-terminate the path at the end of |
4484 | * the current component | 4518 | * the current component |
@@ -4526,8 +4560,7 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, | |||
4526 | 4560 | ||
4527 | if (rc != -EREMOTE) { | 4561 | if (rc != -EREMOTE) { |
4528 | rc = cifs_are_all_path_components_accessible(server, xid, tcon, | 4562 | rc = cifs_are_all_path_components_accessible(server, xid, tcon, |
4529 | cifs_sb, | 4563 | cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); |
4530 | full_path); | ||
4531 | if (rc != 0) { | 4564 | if (rc != 0) { |
4532 | cifs_dbg(VFS, "cannot query dirs between root and final path, " | 4565 | cifs_dbg(VFS, "cannot query dirs between root and final path, " |
4533 | "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); | 4566 | "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); |
diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index e3e1c13df439..1692c0c6c23a 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c | |||
@@ -492,7 +492,7 @@ static struct dfs_cache_entry *__find_cache_entry(unsigned int hash, | |||
492 | #ifdef CONFIG_CIFS_DEBUG2 | 492 | #ifdef CONFIG_CIFS_DEBUG2 |
493 | char *name = get_tgt_name(ce); | 493 | char *name = get_tgt_name(ce); |
494 | 494 | ||
495 | if (unlikely(IS_ERR(name))) { | 495 | if (IS_ERR(name)) { |
496 | rcu_read_unlock(); | 496 | rcu_read_unlock(); |
497 | return ERR_CAST(name); | 497 | return ERR_CAST(name); |
498 | } | 498 | } |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index d7cc62252634..1bffe029fb66 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -892,7 +892,6 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | |||
892 | cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc); | 892 | cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc); |
893 | } | 893 | } |
894 | 894 | ||
895 | #ifdef CONFIG_CIFS_ACL | ||
896 | /* fill in 0777 bits from ACL */ | 895 | /* fill in 0777 bits from ACL */ |
897 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 896 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
898 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid); | 897 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid); |
@@ -902,7 +901,6 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | |||
902 | goto cgii_exit; | 901 | goto cgii_exit; |
903 | } | 902 | } |
904 | } | 903 | } |
905 | #endif /* CONFIG_CIFS_ACL */ | ||
906 | 904 | ||
907 | /* fill in remaining high mode bits e.g. SUID, VTX */ | 905 | /* fill in remaining high mode bits e.g. SUID, VTX */ |
908 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) | 906 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) |
@@ -2415,7 +2413,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2415 | 2413 | ||
2416 | xid = get_xid(); | 2414 | xid = get_xid(); |
2417 | 2415 | ||
2418 | cifs_dbg(FYI, "setattr on file %pd attrs->iavalid 0x%x\n", | 2416 | cifs_dbg(FYI, "setattr on file %pd attrs->ia_valid 0x%x\n", |
2419 | direntry, attrs->ia_valid); | 2417 | direntry, attrs->ia_valid); |
2420 | 2418 | ||
2421 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) | 2419 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) |
@@ -2466,7 +2464,6 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2466 | if (attrs->ia_valid & ATTR_GID) | 2464 | if (attrs->ia_valid & ATTR_GID) |
2467 | gid = attrs->ia_gid; | 2465 | gid = attrs->ia_gid; |
2468 | 2466 | ||
2469 | #ifdef CONFIG_CIFS_ACL | ||
2470 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2467 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2471 | if (uid_valid(uid) || gid_valid(gid)) { | 2468 | if (uid_valid(uid) || gid_valid(gid)) { |
2472 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, | 2469 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, |
@@ -2478,7 +2475,6 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2478 | } | 2475 | } |
2479 | } | 2476 | } |
2480 | } else | 2477 | } else |
2481 | #endif /* CONFIG_CIFS_ACL */ | ||
2482 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) | 2478 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) |
2483 | attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); | 2479 | attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); |
2484 | 2480 | ||
@@ -2489,7 +2485,6 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2489 | if (attrs->ia_valid & ATTR_MODE) { | 2485 | if (attrs->ia_valid & ATTR_MODE) { |
2490 | mode = attrs->ia_mode; | 2486 | mode = attrs->ia_mode; |
2491 | rc = 0; | 2487 | rc = 0; |
2492 | #ifdef CONFIG_CIFS_ACL | ||
2493 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2488 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2494 | rc = id_mode_to_cifs_acl(inode, full_path, mode, | 2489 | rc = id_mode_to_cifs_acl(inode, full_path, mode, |
2495 | INVALID_UID, INVALID_GID); | 2490 | INVALID_UID, INVALID_GID); |
@@ -2499,7 +2494,6 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2499 | goto cifs_setattr_exit; | 2494 | goto cifs_setattr_exit; |
2500 | } | 2495 | } |
2501 | } else | 2496 | } else |
2502 | #endif /* CONFIG_CIFS_ACL */ | ||
2503 | if (((mode & S_IWUGO) == 0) && | 2497 | if (((mode & S_IWUGO) == 0) && |
2504 | (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { | 2498 | (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
2505 | 2499 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index b1a696a73f7c..f383877a6511 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -539,6 +539,7 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) | |||
539 | tcon = cifs_sb_master_tcon(cifs_sb); | 539 | tcon = cifs_sb_master_tcon(cifs_sb); |
540 | 540 | ||
541 | cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; | 541 | cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; |
542 | cifs_sb->mnt_cifs_serverino_autodisabled = true; | ||
542 | cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s.\n", | 543 | cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s.\n", |
543 | tcon ? tcon->treeName : "new server"); | 544 | tcon ? tcon->treeName : "new server"); |
544 | cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS).\n"); | 545 | cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS).\n"); |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 9e430ae9314f..b7421a096319 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -1223,16 +1223,15 @@ struct smb_version_operations smb1_operations = { | |||
1223 | .query_all_EAs = CIFSSMBQAllEAs, | 1223 | .query_all_EAs = CIFSSMBQAllEAs, |
1224 | .set_EA = CIFSSMBSetEA, | 1224 | .set_EA = CIFSSMBSetEA, |
1225 | #endif /* CIFS_XATTR */ | 1225 | #endif /* CIFS_XATTR */ |
1226 | #ifdef CONFIG_CIFS_ACL | ||
1227 | .get_acl = get_cifs_acl, | 1226 | .get_acl = get_cifs_acl, |
1228 | .get_acl_by_fid = get_cifs_acl_by_fid, | 1227 | .get_acl_by_fid = get_cifs_acl_by_fid, |
1229 | .set_acl = set_cifs_acl, | 1228 | .set_acl = set_cifs_acl, |
1230 | #endif /* CIFS_ACL */ | ||
1231 | .make_node = cifs_make_node, | 1229 | .make_node = cifs_make_node, |
1232 | }; | 1230 | }; |
1233 | 1231 | ||
1234 | struct smb_version_values smb1_values = { | 1232 | struct smb_version_values smb1_values = { |
1235 | .version_string = SMB1_VERSION_STRING, | 1233 | .version_string = SMB1_VERSION_STRING, |
1234 | .protocol_id = SMB10_PROT_ID, | ||
1236 | .large_lock_type = LOCKING_ANDX_LARGE_FILES, | 1235 | .large_lock_type = LOCKING_ANDX_LARGE_FILES, |
1237 | .exclusive_lock_type = 0, | 1236 | .exclusive_lock_type = 0, |
1238 | .shared_lock_type = LOCKING_ANDX_SHARED_LOCK, | 1237 | .shared_lock_type = LOCKING_ANDX_SHARED_LOCK, |
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 278405d26c47..d8d9cdfa30b6 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c | |||
@@ -120,6 +120,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, | |||
120 | SMB2_O_INFO_FILE, 0, | 120 | SMB2_O_INFO_FILE, 0, |
121 | sizeof(struct smb2_file_all_info) + | 121 | sizeof(struct smb2_file_all_info) + |
122 | PATH_MAX * 2, 0, NULL); | 122 | PATH_MAX * 2, 0, NULL); |
123 | if (rc) | ||
124 | goto finished; | ||
123 | smb2_set_next_command(tcon, &rqst[num_rqst]); | 125 | smb2_set_next_command(tcon, &rqst[num_rqst]); |
124 | smb2_set_related(&rqst[num_rqst++]); | 126 | smb2_set_related(&rqst[num_rqst++]); |
125 | trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, | 127 | trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, |
@@ -147,6 +149,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, | |||
147 | COMPOUND_FID, current->tgid, | 149 | COMPOUND_FID, current->tgid, |
148 | FILE_DISPOSITION_INFORMATION, | 150 | FILE_DISPOSITION_INFORMATION, |
149 | SMB2_O_INFO_FILE, 0, data, size); | 151 | SMB2_O_INFO_FILE, 0, data, size); |
152 | if (rc) | ||
153 | goto finished; | ||
150 | smb2_set_next_command(tcon, &rqst[num_rqst]); | 154 | smb2_set_next_command(tcon, &rqst[num_rqst]); |
151 | smb2_set_related(&rqst[num_rqst++]); | 155 | smb2_set_related(&rqst[num_rqst++]); |
152 | trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); | 156 | trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); |
@@ -163,6 +167,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, | |||
163 | COMPOUND_FID, current->tgid, | 167 | COMPOUND_FID, current->tgid, |
164 | FILE_END_OF_FILE_INFORMATION, | 168 | FILE_END_OF_FILE_INFORMATION, |
165 | SMB2_O_INFO_FILE, 0, data, size); | 169 | SMB2_O_INFO_FILE, 0, data, size); |
170 | if (rc) | ||
171 | goto finished; | ||
166 | smb2_set_next_command(tcon, &rqst[num_rqst]); | 172 | smb2_set_next_command(tcon, &rqst[num_rqst]); |
167 | smb2_set_related(&rqst[num_rqst++]); | 173 | smb2_set_related(&rqst[num_rqst++]); |
168 | trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); | 174 | trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); |
@@ -180,6 +186,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, | |||
180 | COMPOUND_FID, current->tgid, | 186 | COMPOUND_FID, current->tgid, |
181 | FILE_BASIC_INFORMATION, | 187 | FILE_BASIC_INFORMATION, |
182 | SMB2_O_INFO_FILE, 0, data, size); | 188 | SMB2_O_INFO_FILE, 0, data, size); |
189 | if (rc) | ||
190 | goto finished; | ||
183 | smb2_set_next_command(tcon, &rqst[num_rqst]); | 191 | smb2_set_next_command(tcon, &rqst[num_rqst]); |
184 | smb2_set_related(&rqst[num_rqst++]); | 192 | smb2_set_related(&rqst[num_rqst++]); |
185 | trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid, | 193 | trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid, |
@@ -206,6 +214,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, | |||
206 | COMPOUND_FID, current->tgid, | 214 | COMPOUND_FID, current->tgid, |
207 | FILE_RENAME_INFORMATION, | 215 | FILE_RENAME_INFORMATION, |
208 | SMB2_O_INFO_FILE, 0, data, size); | 216 | SMB2_O_INFO_FILE, 0, data, size); |
217 | if (rc) | ||
218 | goto finished; | ||
209 | smb2_set_next_command(tcon, &rqst[num_rqst]); | 219 | smb2_set_next_command(tcon, &rqst[num_rqst]); |
210 | smb2_set_related(&rqst[num_rqst++]); | 220 | smb2_set_related(&rqst[num_rqst++]); |
211 | trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); | 221 | trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); |
@@ -231,6 +241,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, | |||
231 | COMPOUND_FID, current->tgid, | 241 | COMPOUND_FID, current->tgid, |
232 | FILE_LINK_INFORMATION, | 242 | FILE_LINK_INFORMATION, |
233 | SMB2_O_INFO_FILE, 0, data, size); | 243 | SMB2_O_INFO_FILE, 0, data, size); |
244 | if (rc) | ||
245 | goto finished; | ||
234 | smb2_set_next_command(tcon, &rqst[num_rqst]); | 246 | smb2_set_next_command(tcon, &rqst[num_rqst]); |
235 | smb2_set_related(&rqst[num_rqst++]); | 247 | smb2_set_related(&rqst[num_rqst++]); |
236 | trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path); | 248 | trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path); |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 9fd56b0acd7e..0cdc4e47ca87 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -2027,6 +2027,10 @@ smb2_set_related(struct smb_rqst *rqst) | |||
2027 | struct smb2_sync_hdr *shdr; | 2027 | struct smb2_sync_hdr *shdr; |
2028 | 2028 | ||
2029 | shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); | 2029 | shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); |
2030 | if (shdr == NULL) { | ||
2031 | cifs_dbg(FYI, "shdr NULL in smb2_set_related\n"); | ||
2032 | return; | ||
2033 | } | ||
2030 | shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS; | 2034 | shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS; |
2031 | } | 2035 | } |
2032 | 2036 | ||
@@ -2041,6 +2045,12 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst) | |||
2041 | unsigned long len = smb_rqst_len(server, rqst); | 2045 | unsigned long len = smb_rqst_len(server, rqst); |
2042 | int i, num_padding; | 2046 | int i, num_padding; |
2043 | 2047 | ||
2048 | shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); | ||
2049 | if (shdr == NULL) { | ||
2050 | cifs_dbg(FYI, "shdr NULL in smb2_set_next_command\n"); | ||
2051 | return; | ||
2052 | } | ||
2053 | |||
2044 | /* SMB headers in a compound are 8 byte aligned. */ | 2054 | /* SMB headers in a compound are 8 byte aligned. */ |
2045 | 2055 | ||
2046 | /* No padding needed */ | 2056 | /* No padding needed */ |
@@ -2080,7 +2090,6 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst) | |||
2080 | } | 2090 | } |
2081 | 2091 | ||
2082 | finished: | 2092 | finished: |
2083 | shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); | ||
2084 | shdr->NextCommand = cpu_to_le32(len); | 2093 | shdr->NextCommand = cpu_to_le32(len); |
2085 | } | 2094 | } |
2086 | 2095 | ||
@@ -2374,6 +2383,34 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, | |||
2374 | } | 2383 | } |
2375 | 2384 | ||
2376 | static int | 2385 | static int |
2386 | parse_reparse_posix(struct reparse_posix_data *symlink_buf, | ||
2387 | u32 plen, char **target_path, | ||
2388 | struct cifs_sb_info *cifs_sb) | ||
2389 | { | ||
2390 | unsigned int len; | ||
2391 | |||
2392 | /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */ | ||
2393 | len = le16_to_cpu(symlink_buf->ReparseDataLength); | ||
2394 | |||
2395 | if (le64_to_cpu(symlink_buf->InodeType) != NFS_SPECFILE_LNK) { | ||
2396 | cifs_dbg(VFS, "%lld not a supported symlink type\n", | ||
2397 | le64_to_cpu(symlink_buf->InodeType)); | ||
2398 | return -EOPNOTSUPP; | ||
2399 | } | ||
2400 | |||
2401 | *target_path = cifs_strndup_from_utf16( | ||
2402 | symlink_buf->PathBuffer, | ||
2403 | len, true, cifs_sb->local_nls); | ||
2404 | if (!(*target_path)) | ||
2405 | return -ENOMEM; | ||
2406 | |||
2407 | convert_delimiter(*target_path, '/'); | ||
2408 | cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); | ||
2409 | |||
2410 | return 0; | ||
2411 | } | ||
2412 | |||
2413 | static int | ||
2377 | parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, | 2414 | parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, |
2378 | u32 plen, char **target_path, | 2415 | u32 plen, char **target_path, |
2379 | struct cifs_sb_info *cifs_sb) | 2416 | struct cifs_sb_info *cifs_sb) |
@@ -2381,11 +2418,7 @@ parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, | |||
2381 | unsigned int sub_len; | 2418 | unsigned int sub_len; |
2382 | unsigned int sub_offset; | 2419 | unsigned int sub_offset; |
2383 | 2420 | ||
2384 | /* We only handle Symbolic Link : MS-FSCC 2.1.2.4 */ | 2421 | /* We handle Symbolic Link reparse tag here. See: MS-FSCC 2.1.2.4 */ |
2385 | if (le32_to_cpu(symlink_buf->ReparseTag) != IO_REPARSE_TAG_SYMLINK) { | ||
2386 | cifs_dbg(VFS, "srv returned invalid symlink buffer\n"); | ||
2387 | return -EIO; | ||
2388 | } | ||
2389 | 2422 | ||
2390 | sub_offset = le16_to_cpu(symlink_buf->SubstituteNameOffset); | 2423 | sub_offset = le16_to_cpu(symlink_buf->SubstituteNameOffset); |
2391 | sub_len = le16_to_cpu(symlink_buf->SubstituteNameLength); | 2424 | sub_len = le16_to_cpu(symlink_buf->SubstituteNameLength); |
@@ -2407,6 +2440,41 @@ parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, | |||
2407 | return 0; | 2440 | return 0; |
2408 | } | 2441 | } |
2409 | 2442 | ||
2443 | static int | ||
2444 | parse_reparse_point(struct reparse_data_buffer *buf, | ||
2445 | u32 plen, char **target_path, | ||
2446 | struct cifs_sb_info *cifs_sb) | ||
2447 | { | ||
2448 | if (plen < sizeof(struct reparse_data_buffer)) { | ||
2449 | cifs_dbg(VFS, "reparse buffer is too small. Must be " | ||
2450 | "at least 8 bytes but was %d\n", plen); | ||
2451 | return -EIO; | ||
2452 | } | ||
2453 | |||
2454 | if (plen < le16_to_cpu(buf->ReparseDataLength) + | ||
2455 | sizeof(struct reparse_data_buffer)) { | ||
2456 | cifs_dbg(VFS, "srv returned invalid reparse buf " | ||
2457 | "length: %d\n", plen); | ||
2458 | return -EIO; | ||
2459 | } | ||
2460 | |||
2461 | /* See MS-FSCC 2.1.2 */ | ||
2462 | switch (le32_to_cpu(buf->ReparseTag)) { | ||
2463 | case IO_REPARSE_TAG_NFS: | ||
2464 | return parse_reparse_posix( | ||
2465 | (struct reparse_posix_data *)buf, | ||
2466 | plen, target_path, cifs_sb); | ||
2467 | case IO_REPARSE_TAG_SYMLINK: | ||
2468 | return parse_reparse_symlink( | ||
2469 | (struct reparse_symlink_data_buffer *)buf, | ||
2470 | plen, target_path, cifs_sb); | ||
2471 | default: | ||
2472 | cifs_dbg(VFS, "srv returned unknown symlink buffer " | ||
2473 | "tag:0x%08x\n", le32_to_cpu(buf->ReparseTag)); | ||
2474 | return -EOPNOTSUPP; | ||
2475 | } | ||
2476 | } | ||
2477 | |||
2410 | #define SMB2_SYMLINK_STRUCT_SIZE \ | 2478 | #define SMB2_SYMLINK_STRUCT_SIZE \ |
2411 | (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) | 2479 | (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) |
2412 | 2480 | ||
@@ -2533,23 +2601,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
2533 | goto querty_exit; | 2601 | goto querty_exit; |
2534 | } | 2602 | } |
2535 | 2603 | ||
2536 | if (plen < 8) { | 2604 | rc = parse_reparse_point(reparse_buf, plen, target_path, |
2537 | cifs_dbg(VFS, "reparse buffer is too small. Must be " | 2605 | cifs_sb); |
2538 | "at least 8 bytes but was %d\n", plen); | ||
2539 | rc = -EIO; | ||
2540 | goto querty_exit; | ||
2541 | } | ||
2542 | |||
2543 | if (plen < le16_to_cpu(reparse_buf->ReparseDataLength) + 8) { | ||
2544 | cifs_dbg(VFS, "srv returned invalid reparse buf " | ||
2545 | "length: %d\n", plen); | ||
2546 | rc = -EIO; | ||
2547 | goto querty_exit; | ||
2548 | } | ||
2549 | |||
2550 | rc = parse_reparse_symlink( | ||
2551 | (struct reparse_symlink_data_buffer *)reparse_buf, | ||
2552 | plen, target_path, cifs_sb); | ||
2553 | goto querty_exit; | 2606 | goto querty_exit; |
2554 | } | 2607 | } |
2555 | 2608 | ||
@@ -2561,26 +2614,32 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
2561 | err_buf = err_iov.iov_base; | 2614 | err_buf = err_iov.iov_base; |
2562 | if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || | 2615 | if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || |
2563 | err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) { | 2616 | err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) { |
2564 | rc = -ENOENT; | 2617 | rc = -EINVAL; |
2618 | goto querty_exit; | ||
2619 | } | ||
2620 | |||
2621 | symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; | ||
2622 | if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG || | ||
2623 | le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) { | ||
2624 | rc = -EINVAL; | ||
2565 | goto querty_exit; | 2625 | goto querty_exit; |
2566 | } | 2626 | } |
2567 | 2627 | ||
2568 | /* open must fail on symlink - reset rc */ | 2628 | /* open must fail on symlink - reset rc */ |
2569 | rc = 0; | 2629 | rc = 0; |
2570 | symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; | ||
2571 | sub_len = le16_to_cpu(symlink->SubstituteNameLength); | 2630 | sub_len = le16_to_cpu(symlink->SubstituteNameLength); |
2572 | sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); | 2631 | sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); |
2573 | print_len = le16_to_cpu(symlink->PrintNameLength); | 2632 | print_len = le16_to_cpu(symlink->PrintNameLength); |
2574 | print_offset = le16_to_cpu(symlink->PrintNameOffset); | 2633 | print_offset = le16_to_cpu(symlink->PrintNameOffset); |
2575 | 2634 | ||
2576 | if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { | 2635 | if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { |
2577 | rc = -ENOENT; | 2636 | rc = -EINVAL; |
2578 | goto querty_exit; | 2637 | goto querty_exit; |
2579 | } | 2638 | } |
2580 | 2639 | ||
2581 | if (err_iov.iov_len < | 2640 | if (err_iov.iov_len < |
2582 | SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { | 2641 | SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { |
2583 | rc = -ENOENT; | 2642 | rc = -EINVAL; |
2584 | goto querty_exit; | 2643 | goto querty_exit; |
2585 | } | 2644 | } |
2586 | 2645 | ||
@@ -2606,7 +2665,6 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
2606 | return rc; | 2665 | return rc; |
2607 | } | 2666 | } |
2608 | 2667 | ||
2609 | #ifdef CONFIG_CIFS_ACL | ||
2610 | static struct cifs_ntsd * | 2668 | static struct cifs_ntsd * |
2611 | get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, | 2669 | get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, |
2612 | const struct cifs_fid *cifsfid, u32 *pacllen) | 2670 | const struct cifs_fid *cifsfid, u32 *pacllen) |
@@ -2691,7 +2749,6 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, | |||
2691 | return pntsd; | 2749 | return pntsd; |
2692 | } | 2750 | } |
2693 | 2751 | ||
2694 | #ifdef CONFIG_CIFS_ACL | ||
2695 | static int | 2752 | static int |
2696 | set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | 2753 | set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, |
2697 | struct inode *inode, const char *path, int aclflag) | 2754 | struct inode *inode, const char *path, int aclflag) |
@@ -2749,7 +2806,6 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | |||
2749 | free_xid(xid); | 2806 | free_xid(xid); |
2750 | return rc; | 2807 | return rc; |
2751 | } | 2808 | } |
2752 | #endif /* CIFS_ACL */ | ||
2753 | 2809 | ||
2754 | /* Retrieve an ACL from the server */ | 2810 | /* Retrieve an ACL from the server */ |
2755 | static struct cifs_ntsd * | 2811 | static struct cifs_ntsd * |
@@ -2769,7 +2825,6 @@ get_smb2_acl(struct cifs_sb_info *cifs_sb, | |||
2769 | cifsFileInfo_put(open_file); | 2825 | cifsFileInfo_put(open_file); |
2770 | return pntsd; | 2826 | return pntsd; |
2771 | } | 2827 | } |
2772 | #endif | ||
2773 | 2828 | ||
2774 | static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, | 2829 | static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, |
2775 | loff_t offset, loff_t len, bool keep_size) | 2830 | loff_t offset, loff_t len, bool keep_size) |
@@ -3367,7 +3422,7 @@ smb2_dir_needs_close(struct cifsFileInfo *cfile) | |||
3367 | 3422 | ||
3368 | static void | 3423 | static void |
3369 | fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, | 3424 | fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, |
3370 | struct smb_rqst *old_rq) | 3425 | struct smb_rqst *old_rq, __le16 cipher_type) |
3371 | { | 3426 | { |
3372 | struct smb2_sync_hdr *shdr = | 3427 | struct smb2_sync_hdr *shdr = |
3373 | (struct smb2_sync_hdr *)old_rq->rq_iov[0].iov_base; | 3428 | (struct smb2_sync_hdr *)old_rq->rq_iov[0].iov_base; |
@@ -3376,7 +3431,10 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, | |||
3376 | tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM; | 3431 | tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM; |
3377 | tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len); | 3432 | tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len); |
3378 | tr_hdr->Flags = cpu_to_le16(0x01); | 3433 | tr_hdr->Flags = cpu_to_le16(0x01); |
3379 | get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CMM_NONCE); | 3434 | if (cipher_type == SMB2_ENCRYPTION_AES128_GCM) |
3435 | get_random_bytes(&tr_hdr->Nonce, SMB3_AES128GCM_NONCE); | ||
3436 | else | ||
3437 | get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CCM_NONCE); | ||
3380 | memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8); | 3438 | memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8); |
3381 | } | 3439 | } |
3382 | 3440 | ||
@@ -3534,8 +3592,13 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, | |||
3534 | rc = -ENOMEM; | 3592 | rc = -ENOMEM; |
3535 | goto free_sg; | 3593 | goto free_sg; |
3536 | } | 3594 | } |
3537 | iv[0] = 3; | 3595 | |
3538 | memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES128CMM_NONCE); | 3596 | if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) |
3597 | memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES128GCM_NONCE); | ||
3598 | else { | ||
3599 | iv[0] = 3; | ||
3600 | memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES128CCM_NONCE); | ||
3601 | } | ||
3539 | 3602 | ||
3540 | aead_request_set_crypt(req, sg, sg, crypt_len, iv); | 3603 | aead_request_set_crypt(req, sg, sg, crypt_len, iv); |
3541 | aead_request_set_ad(req, assoc_data_len); | 3604 | aead_request_set_ad(req, assoc_data_len); |
@@ -3635,7 +3698,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, | |||
3635 | } | 3698 | } |
3636 | 3699 | ||
3637 | /* fill the 1st iov with a transform header */ | 3700 | /* fill the 1st iov with a transform header */ |
3638 | fill_transform_hdr(tr_hdr, orig_len, old_rq); | 3701 | fill_transform_hdr(tr_hdr, orig_len, old_rq, server->cipher_type); |
3639 | 3702 | ||
3640 | rc = crypt_message(server, num_rqst, new_rq, 1); | 3703 | rc = crypt_message(server, num_rqst, new_rq, 1); |
3641 | cifs_dbg(FYI, "Encrypt message returned %d\n", rc); | 3704 | cifs_dbg(FYI, "Encrypt message returned %d\n", rc); |
@@ -4284,11 +4347,9 @@ struct smb_version_operations smb20_operations = { | |||
4284 | .query_all_EAs = smb2_query_eas, | 4347 | .query_all_EAs = smb2_query_eas, |
4285 | .set_EA = smb2_set_ea, | 4348 | .set_EA = smb2_set_ea, |
4286 | #endif /* CIFS_XATTR */ | 4349 | #endif /* CIFS_XATTR */ |
4287 | #ifdef CONFIG_CIFS_ACL | ||
4288 | .get_acl = get_smb2_acl, | 4350 | .get_acl = get_smb2_acl, |
4289 | .get_acl_by_fid = get_smb2_acl_by_fid, | 4351 | .get_acl_by_fid = get_smb2_acl_by_fid, |
4290 | .set_acl = set_smb2_acl, | 4352 | .set_acl = set_smb2_acl, |
4291 | #endif /* CIFS_ACL */ | ||
4292 | .next_header = smb2_next_header, | 4353 | .next_header = smb2_next_header, |
4293 | .ioctl_query_info = smb2_ioctl_query_info, | 4354 | .ioctl_query_info = smb2_ioctl_query_info, |
4294 | .make_node = smb2_make_node, | 4355 | .make_node = smb2_make_node, |
@@ -4385,11 +4446,9 @@ struct smb_version_operations smb21_operations = { | |||
4385 | .query_all_EAs = smb2_query_eas, | 4446 | .query_all_EAs = smb2_query_eas, |
4386 | .set_EA = smb2_set_ea, | 4447 | .set_EA = smb2_set_ea, |
4387 | #endif /* CIFS_XATTR */ | 4448 | #endif /* CIFS_XATTR */ |
4388 | #ifdef CONFIG_CIFS_ACL | ||
4389 | .get_acl = get_smb2_acl, | 4449 | .get_acl = get_smb2_acl, |
4390 | .get_acl_by_fid = get_smb2_acl_by_fid, | 4450 | .get_acl_by_fid = get_smb2_acl_by_fid, |
4391 | .set_acl = set_smb2_acl, | 4451 | .set_acl = set_smb2_acl, |
4392 | #endif /* CIFS_ACL */ | ||
4393 | .next_header = smb2_next_header, | 4452 | .next_header = smb2_next_header, |
4394 | .ioctl_query_info = smb2_ioctl_query_info, | 4453 | .ioctl_query_info = smb2_ioctl_query_info, |
4395 | .make_node = smb2_make_node, | 4454 | .make_node = smb2_make_node, |
@@ -4495,11 +4554,9 @@ struct smb_version_operations smb30_operations = { | |||
4495 | .query_all_EAs = smb2_query_eas, | 4554 | .query_all_EAs = smb2_query_eas, |
4496 | .set_EA = smb2_set_ea, | 4555 | .set_EA = smb2_set_ea, |
4497 | #endif /* CIFS_XATTR */ | 4556 | #endif /* CIFS_XATTR */ |
4498 | #ifdef CONFIG_CIFS_ACL | ||
4499 | .get_acl = get_smb2_acl, | 4557 | .get_acl = get_smb2_acl, |
4500 | .get_acl_by_fid = get_smb2_acl_by_fid, | 4558 | .get_acl_by_fid = get_smb2_acl_by_fid, |
4501 | .set_acl = set_smb2_acl, | 4559 | .set_acl = set_smb2_acl, |
4502 | #endif /* CIFS_ACL */ | ||
4503 | .next_header = smb2_next_header, | 4560 | .next_header = smb2_next_header, |
4504 | .ioctl_query_info = smb2_ioctl_query_info, | 4561 | .ioctl_query_info = smb2_ioctl_query_info, |
4505 | .make_node = smb2_make_node, | 4562 | .make_node = smb2_make_node, |
@@ -4606,11 +4663,9 @@ struct smb_version_operations smb311_operations = { | |||
4606 | .query_all_EAs = smb2_query_eas, | 4663 | .query_all_EAs = smb2_query_eas, |
4607 | .set_EA = smb2_set_ea, | 4664 | .set_EA = smb2_set_ea, |
4608 | #endif /* CIFS_XATTR */ | 4665 | #endif /* CIFS_XATTR */ |
4609 | #ifdef CONFIG_CIFS_ACL | ||
4610 | .get_acl = get_smb2_acl, | 4666 | .get_acl = get_smb2_acl, |
4611 | .get_acl_by_fid = get_smb2_acl_by_fid, | 4667 | .get_acl_by_fid = get_smb2_acl_by_fid, |
4612 | .set_acl = set_smb2_acl, | 4668 | .set_acl = set_smb2_acl, |
4613 | #endif /* CIFS_ACL */ | ||
4614 | .next_header = smb2_next_header, | 4669 | .next_header = smb2_next_header, |
4615 | .ioctl_query_info = smb2_ioctl_query_info, | 4670 | .ioctl_query_info = smb2_ioctl_query_info, |
4616 | .make_node = smb2_make_node, | 4671 | .make_node = smb2_make_node, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 75311a8a68bf..f58e4dc3987b 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -489,10 +489,25 @@ static void | |||
489 | build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt) | 489 | build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt) |
490 | { | 490 | { |
491 | pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES; | 491 | pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES; |
492 | pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + le16 cipher */ | 492 | pneg_ctxt->DataLength = cpu_to_le16(6); /* Cipher Count + two ciphers */ |
493 | pneg_ctxt->CipherCount = cpu_to_le16(1); | 493 | pneg_ctxt->CipherCount = cpu_to_le16(2); |
494 | /* pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;*/ /* not supported yet */ | 494 | pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM; |
495 | pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_CCM; | 495 | pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM; |
496 | } | ||
497 | |||
498 | static unsigned int | ||
499 | build_netname_ctxt(struct smb2_netname_neg_context *pneg_ctxt, char *hostname) | ||
500 | { | ||
501 | struct nls_table *cp = load_nls_default(); | ||
502 | |||
503 | pneg_ctxt->ContextType = SMB2_NETNAME_NEGOTIATE_CONTEXT_ID; | ||
504 | |||
505 | /* copy up to max of first 100 bytes of server name to NetName field */ | ||
506 | pneg_ctxt->DataLength = cpu_to_le16(2 + | ||
507 | (2 * cifs_strtoUTF16(pneg_ctxt->NetName, hostname, 100, cp))); | ||
508 | /* context size is DataLength + minimal smb2_neg_context */ | ||
509 | return DIV_ROUND_UP(le16_to_cpu(pneg_ctxt->DataLength) + | ||
510 | sizeof(struct smb2_neg_context), 8) * 8; | ||
496 | } | 511 | } |
497 | 512 | ||
498 | static void | 513 | static void |
@@ -521,7 +536,7 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt) | |||
521 | 536 | ||
522 | static void | 537 | static void |
523 | assemble_neg_contexts(struct smb2_negotiate_req *req, | 538 | assemble_neg_contexts(struct smb2_negotiate_req *req, |
524 | unsigned int *total_len) | 539 | struct TCP_Server_Info *server, unsigned int *total_len) |
525 | { | 540 | { |
526 | char *pneg_ctxt = (char *)req; | 541 | char *pneg_ctxt = (char *)req; |
527 | unsigned int ctxt_len; | 542 | unsigned int ctxt_len; |
@@ -551,17 +566,25 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, | |||
551 | *total_len += ctxt_len; | 566 | *total_len += ctxt_len; |
552 | pneg_ctxt += ctxt_len; | 567 | pneg_ctxt += ctxt_len; |
553 | 568 | ||
554 | build_compression_ctxt((struct smb2_compression_capabilities_context *) | 569 | if (server->compress_algorithm) { |
570 | build_compression_ctxt((struct smb2_compression_capabilities_context *) | ||
555 | pneg_ctxt); | 571 | pneg_ctxt); |
556 | ctxt_len = DIV_ROUND_UP( | 572 | ctxt_len = DIV_ROUND_UP( |
557 | sizeof(struct smb2_compression_capabilities_context), 8) * 8; | 573 | sizeof(struct smb2_compression_capabilities_context), |
574 | 8) * 8; | ||
575 | *total_len += ctxt_len; | ||
576 | pneg_ctxt += ctxt_len; | ||
577 | req->NegotiateContextCount = cpu_to_le16(5); | ||
578 | } else | ||
579 | req->NegotiateContextCount = cpu_to_le16(4); | ||
580 | |||
581 | ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt, | ||
582 | server->hostname); | ||
558 | *total_len += ctxt_len; | 583 | *total_len += ctxt_len; |
559 | pneg_ctxt += ctxt_len; | 584 | pneg_ctxt += ctxt_len; |
560 | 585 | ||
561 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); | 586 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); |
562 | *total_len += sizeof(struct smb2_posix_neg_context); | 587 | *total_len += sizeof(struct smb2_posix_neg_context); |
563 | |||
564 | req->NegotiateContextCount = cpu_to_le16(4); | ||
565 | } | 588 | } |
566 | 589 | ||
567 | static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) | 590 | static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) |
@@ -829,7 +852,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
829 | if ((ses->server->vals->protocol_id == SMB311_PROT_ID) || | 852 | if ((ses->server->vals->protocol_id == SMB311_PROT_ID) || |
830 | (strcmp(ses->server->vals->version_string, | 853 | (strcmp(ses->server->vals->version_string, |
831 | SMBDEFAULT_VERSION_STRING) == 0)) | 854 | SMBDEFAULT_VERSION_STRING) == 0)) |
832 | assemble_neg_contexts(req, &total_len); | 855 | assemble_neg_contexts(req, server, &total_len); |
833 | } | 856 | } |
834 | iov[0].iov_base = (char *)req; | 857 | iov[0].iov_base = (char *)req; |
835 | iov[0].iov_len = total_len; | 858 | iov[0].iov_len = total_len; |
@@ -2095,6 +2118,48 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp) | |||
2095 | return 0; | 2118 | return 0; |
2096 | } | 2119 | } |
2097 | 2120 | ||
2121 | static struct crt_query_id_ctxt * | ||
2122 | create_query_id_buf(void) | ||
2123 | { | ||
2124 | struct crt_query_id_ctxt *buf; | ||
2125 | |||
2126 | buf = kzalloc(sizeof(struct crt_query_id_ctxt), GFP_KERNEL); | ||
2127 | if (!buf) | ||
2128 | return NULL; | ||
2129 | |||
2130 | buf->ccontext.DataOffset = cpu_to_le16(0); | ||
2131 | buf->ccontext.DataLength = cpu_to_le32(0); | ||
2132 | buf->ccontext.NameOffset = cpu_to_le16(offsetof | ||
2133 | (struct crt_query_id_ctxt, Name)); | ||
2134 | buf->ccontext.NameLength = cpu_to_le16(4); | ||
2135 | /* SMB2_CREATE_QUERY_ON_DISK_ID is "QFid" */ | ||
2136 | buf->Name[0] = 'Q'; | ||
2137 | buf->Name[1] = 'F'; | ||
2138 | buf->Name[2] = 'i'; | ||
2139 | buf->Name[3] = 'd'; | ||
2140 | return buf; | ||
2141 | } | ||
2142 | |||
2143 | /* See MS-SMB2 2.2.13.2.9 */ | ||
2144 | static int | ||
2145 | add_query_id_context(struct kvec *iov, unsigned int *num_iovec) | ||
2146 | { | ||
2147 | struct smb2_create_req *req = iov[0].iov_base; | ||
2148 | unsigned int num = *num_iovec; | ||
2149 | |||
2150 | iov[num].iov_base = create_query_id_buf(); | ||
2151 | if (iov[num].iov_base == NULL) | ||
2152 | return -ENOMEM; | ||
2153 | iov[num].iov_len = sizeof(struct crt_query_id_ctxt); | ||
2154 | if (!req->CreateContextsOffset) | ||
2155 | req->CreateContextsOffset = cpu_to_le32( | ||
2156 | sizeof(struct smb2_create_req) + | ||
2157 | iov[num - 1].iov_len); | ||
2158 | le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_query_id_ctxt)); | ||
2159 | *num_iovec = num + 1; | ||
2160 | return 0; | ||
2161 | } | ||
2162 | |||
2098 | static int | 2163 | static int |
2099 | alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, | 2164 | alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, |
2100 | const char *treename, const __le16 *path) | 2165 | const char *treename, const __le16 *path) |
@@ -2423,6 +2488,12 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, | |||
2423 | return rc; | 2488 | return rc; |
2424 | } | 2489 | } |
2425 | 2490 | ||
2491 | if (n_iov > 2) { | ||
2492 | struct create_context *ccontext = | ||
2493 | (struct create_context *)iov[n_iov-1].iov_base; | ||
2494 | ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len); | ||
2495 | } | ||
2496 | add_query_id_context(iov, &n_iov); | ||
2426 | 2497 | ||
2427 | rqst->rq_nvec = n_iov; | 2498 | rqst->rq_nvec = n_iov; |
2428 | return 0; | 2499 | return 0; |
@@ -2550,12 +2621,11 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | |||
2550 | * indatalen is usually small at a couple of bytes max, so | 2621 | * indatalen is usually small at a couple of bytes max, so |
2551 | * just allocate through generic pool | 2622 | * just allocate through generic pool |
2552 | */ | 2623 | */ |
2553 | in_data_buf = kmalloc(indatalen, GFP_NOFS); | 2624 | in_data_buf = kmemdup(in_data, indatalen, GFP_NOFS); |
2554 | if (!in_data_buf) { | 2625 | if (!in_data_buf) { |
2555 | cifs_small_buf_release(req); | 2626 | cifs_small_buf_release(req); |
2556 | return -ENOMEM; | 2627 | return -ENOMEM; |
2557 | } | 2628 | } |
2558 | memcpy(in_data_buf, in_data, indatalen); | ||
2559 | } | 2629 | } |
2560 | 2630 | ||
2561 | req->CtlCode = cpu_to_le32(opcode); | 2631 | req->CtlCode = cpu_to_le32(opcode); |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 858353d20c39..7e2e782f8edd 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -123,7 +123,7 @@ struct smb2_sync_pdu { | |||
123 | __le16 StructureSize2; /* size of wct area (varies, request specific) */ | 123 | __le16 StructureSize2; /* size of wct area (varies, request specific) */ |
124 | } __packed; | 124 | } __packed; |
125 | 125 | ||
126 | #define SMB3_AES128CMM_NONCE 11 | 126 | #define SMB3_AES128CCM_NONCE 11 |
127 | #define SMB3_AES128GCM_NONCE 12 | 127 | #define SMB3_AES128GCM_NONCE 12 |
128 | 128 | ||
129 | struct smb2_transform_hdr { | 129 | struct smb2_transform_hdr { |
@@ -166,6 +166,8 @@ struct smb2_err_rsp { | |||
166 | __u8 ErrorData[1]; /* variable length */ | 166 | __u8 ErrorData[1]; /* variable length */ |
167 | } __packed; | 167 | } __packed; |
168 | 168 | ||
169 | #define SYMLINK_ERROR_TAG 0x4c4d5953 | ||
170 | |||
169 | struct smb2_symlink_err_rsp { | 171 | struct smb2_symlink_err_rsp { |
170 | __le32 SymLinkLength; | 172 | __le32 SymLinkLength; |
171 | __le32 SymLinkErrorTag; | 173 | __le32 SymLinkErrorTag; |
@@ -227,6 +229,7 @@ struct smb2_negotiate_req { | |||
227 | } __packed; | 229 | } __packed; |
228 | 230 | ||
229 | /* Dialects */ | 231 | /* Dialects */ |
232 | #define SMB10_PROT_ID 0x0000 /* local only, not sent on wire w/CIFS negprot */ | ||
230 | #define SMB20_PROT_ID 0x0202 | 233 | #define SMB20_PROT_ID 0x0202 |
231 | #define SMB21_PROT_ID 0x0210 | 234 | #define SMB21_PROT_ID 0x0210 |
232 | #define SMB30_PROT_ID 0x0300 | 235 | #define SMB30_PROT_ID 0x0300 |
@@ -293,7 +296,7 @@ struct smb2_encryption_neg_context { | |||
293 | __le16 DataLength; | 296 | __le16 DataLength; |
294 | __le32 Reserved; | 297 | __le32 Reserved; |
295 | __le16 CipherCount; /* AES-128-GCM and AES-128-CCM */ | 298 | __le16 CipherCount; /* AES-128-GCM and AES-128-CCM */ |
296 | __le16 Ciphers[1]; /* Ciphers[0] since only one used now */ | 299 | __le16 Ciphers[2]; |
297 | } __packed; | 300 | } __packed; |
298 | 301 | ||
299 | /* See MS-SMB2 2.2.3.1.3 */ | 302 | /* See MS-SMB2 2.2.3.1.3 */ |
@@ -316,6 +319,12 @@ struct smb2_compression_capabilities_context { | |||
316 | * For smb2_netname_negotiate_context_id See MS-SMB2 2.2.3.1.4. | 319 | * For smb2_netname_negotiate_context_id See MS-SMB2 2.2.3.1.4. |
317 | * Its struct simply contains NetName, an array of Unicode characters | 320 | * Its struct simply contains NetName, an array of Unicode characters |
318 | */ | 321 | */ |
322 | struct smb2_netname_neg_context { | ||
323 | __le16 ContextType; /* 0x100 */ | ||
324 | __le16 DataLength; | ||
325 | __le32 Reserved; | ||
326 | __le16 NetName[0]; /* hostname of target converted to UCS-2 */ | ||
327 | } __packed; | ||
319 | 328 | ||
320 | #define POSIX_CTXT_DATA_LEN 16 | 329 | #define POSIX_CTXT_DATA_LEN 16 |
321 | struct smb2_posix_neg_context { | 330 | struct smb2_posix_neg_context { |
@@ -640,6 +649,7 @@ struct smb2_tree_disconnect_rsp { | |||
640 | #define SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 "DH2Q" | 649 | #define SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 "DH2Q" |
641 | #define SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 "DH2C" | 650 | #define SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 "DH2C" |
642 | #define SMB2_CREATE_APP_INSTANCE_ID 0x45BCA66AEFA7F74A9008FA462E144D74 | 651 | #define SMB2_CREATE_APP_INSTANCE_ID 0x45BCA66AEFA7F74A9008FA462E144D74 |
652 | #define SMB2_CREATE_APP_INSTANCE_VERSION 0xB982D0B73B56074FA07B524A8116A010 | ||
643 | #define SVHDX_OPEN_DEVICE_CONTEX 0x9CCBCF9E04C1E643980E158DA1F6EC83 | 653 | #define SVHDX_OPEN_DEVICE_CONTEX 0x9CCBCF9E04C1E643980E158DA1F6EC83 |
644 | #define SMB2_CREATE_TAG_POSIX 0x93AD25509CB411E7B42383DE968BCD7C | 654 | #define SMB2_CREATE_TAG_POSIX 0x93AD25509CB411E7B42383DE968BCD7C |
645 | 655 | ||
@@ -654,9 +664,10 @@ struct smb2_tree_disconnect_rsp { | |||
654 | * [3] : durable context | 664 | * [3] : durable context |
655 | * [4] : posix context | 665 | * [4] : posix context |
656 | * [5] : time warp context | 666 | * [5] : time warp context |
657 | * [6] : compound padding | 667 | * [6] : query id context |
668 | * [7] : compound padding | ||
658 | */ | 669 | */ |
659 | #define SMB2_CREATE_IOV_SIZE 7 | 670 | #define SMB2_CREATE_IOV_SIZE 8 |
660 | 671 | ||
661 | struct smb2_create_req { | 672 | struct smb2_create_req { |
662 | struct smb2_sync_hdr sync_hdr; | 673 | struct smb2_sync_hdr sync_hdr; |
@@ -680,10 +691,10 @@ struct smb2_create_req { | |||
680 | 691 | ||
681 | /* | 692 | /* |
682 | * Maximum size of a SMB2_CREATE response is 64 (smb2 header) + | 693 | * Maximum size of a SMB2_CREATE response is 64 (smb2 header) + |
683 | * 88 (fixed part of create response) + 520 (path) + 150 (contexts) + | 694 | * 88 (fixed part of create response) + 520 (path) + 208 (contexts) + |
684 | * 2 bytes of padding. | 695 | * 2 bytes of padding. |
685 | */ | 696 | */ |
686 | #define MAX_SMB2_CREATE_RESPONSE_SIZE 824 | 697 | #define MAX_SMB2_CREATE_RESPONSE_SIZE 880 |
687 | 698 | ||
688 | struct smb2_create_rsp { | 699 | struct smb2_create_rsp { |
689 | struct smb2_sync_hdr sync_hdr; | 700 | struct smb2_sync_hdr sync_hdr; |
@@ -806,6 +817,13 @@ struct durable_reconnect_context_v2 { | |||
806 | __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */ | 817 | __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */ |
807 | } __packed; | 818 | } __packed; |
808 | 819 | ||
820 | /* See MS-SMB2 2.2.14.2.9 */ | ||
821 | struct on_disk_id { | ||
822 | __le64 DiskFileId; | ||
823 | __le64 VolumeId; | ||
824 | __u32 Reserved[4]; | ||
825 | } __packed; | ||
826 | |||
809 | /* See MS-SMB2 2.2.14.2.12 */ | 827 | /* See MS-SMB2 2.2.14.2.12 */ |
810 | struct durable_reconnect_context_v2_rsp { | 828 | struct durable_reconnect_context_v2_rsp { |
811 | __le32 Timeout; | 829 | __le32 Timeout; |
@@ -826,6 +844,12 @@ struct crt_twarp_ctxt { | |||
826 | 844 | ||
827 | } __packed; | 845 | } __packed; |
828 | 846 | ||
847 | /* See MS-SMB2 2.2.13.2.9 */ | ||
848 | struct crt_query_id_ctxt { | ||
849 | struct create_context ccontext; | ||
850 | __u8 Name[8]; | ||
851 | } __packed; | ||
852 | |||
829 | #define COPY_CHUNK_RES_KEY_SIZE 24 | 853 | #define COPY_CHUNK_RES_KEY_SIZE 24 |
830 | struct resume_key_req { | 854 | struct resume_key_req { |
831 | char ResumeKey[COPY_CHUNK_RES_KEY_SIZE]; | 855 | char ResumeKey[COPY_CHUNK_RES_KEY_SIZE]; |
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index d1181572758b..1ccbcf9c2c3b 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c | |||
@@ -734,7 +734,10 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) | |||
734 | struct crypto_aead *tfm; | 734 | struct crypto_aead *tfm; |
735 | 735 | ||
736 | if (!server->secmech.ccmaesencrypt) { | 736 | if (!server->secmech.ccmaesencrypt) { |
737 | tfm = crypto_alloc_aead("ccm(aes)", 0, 0); | 737 | if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) |
738 | tfm = crypto_alloc_aead("gcm(aes)", 0, 0); | ||
739 | else | ||
740 | tfm = crypto_alloc_aead("ccm(aes)", 0, 0); | ||
738 | if (IS_ERR(tfm)) { | 741 | if (IS_ERR(tfm)) { |
739 | cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n", | 742 | cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n", |
740 | __func__); | 743 | __func__); |
@@ -744,7 +747,10 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) | |||
744 | } | 747 | } |
745 | 748 | ||
746 | if (!server->secmech.ccmaesdecrypt) { | 749 | if (!server->secmech.ccmaesdecrypt) { |
747 | tfm = crypto_alloc_aead("ccm(aes)", 0, 0); | 750 | if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) |
751 | tfm = crypto_alloc_aead("gcm(aes)", 0, 0); | ||
752 | else | ||
753 | tfm = crypto_alloc_aead("ccm(aes)", 0, 0); | ||
748 | if (IS_ERR(tfm)) { | 754 | if (IS_ERR(tfm)) { |
749 | crypto_free_aead(server->secmech.ccmaesencrypt); | 755 | crypto_free_aead(server->secmech.ccmaesencrypt); |
750 | server->secmech.ccmaesencrypt = NULL; | 756 | server->secmech.ccmaesencrypt = NULL; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 60661b3f983a..5d6d44bfe10a 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -979,6 +979,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
979 | }; | 979 | }; |
980 | unsigned int instance; | 980 | unsigned int instance; |
981 | char *buf; | 981 | char *buf; |
982 | struct TCP_Server_Info *server; | ||
982 | 983 | ||
983 | optype = flags & CIFS_OP_MASK; | 984 | optype = flags & CIFS_OP_MASK; |
984 | 985 | ||
@@ -990,7 +991,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
990 | return -EIO; | 991 | return -EIO; |
991 | } | 992 | } |
992 | 993 | ||
993 | if (ses->server->tcpStatus == CifsExiting) | 994 | server = ses->server; |
995 | if (server->tcpStatus == CifsExiting) | ||
994 | return -ENOENT; | 996 | return -ENOENT; |
995 | 997 | ||
996 | /* | 998 | /* |
@@ -1001,7 +1003,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1001 | * other requests. | 1003 | * other requests. |
1002 | * This can be handled by the eventual session reconnect. | 1004 | * This can be handled by the eventual session reconnect. |
1003 | */ | 1005 | */ |
1004 | rc = wait_for_compound_request(ses->server, num_rqst, flags, | 1006 | rc = wait_for_compound_request(server, num_rqst, flags, |
1005 | &instance); | 1007 | &instance); |
1006 | if (rc) | 1008 | if (rc) |
1007 | return rc; | 1009 | return rc; |
@@ -1017,7 +1019,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1017 | * of smb data. | 1019 | * of smb data. |
1018 | */ | 1020 | */ |
1019 | 1021 | ||
1020 | mutex_lock(&ses->server->srv_mutex); | 1022 | mutex_lock(&server->srv_mutex); |
1021 | 1023 | ||
1022 | /* | 1024 | /* |
1023 | * All the parts of the compound chain belong obtained credits from the | 1025 | * All the parts of the compound chain belong obtained credits from the |
@@ -1026,24 +1028,24 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1026 | * we obtained credits and return -EAGAIN in such cases to let callers | 1028 | * we obtained credits and return -EAGAIN in such cases to let callers |
1027 | * handle it. | 1029 | * handle it. |
1028 | */ | 1030 | */ |
1029 | if (instance != ses->server->reconnect_instance) { | 1031 | if (instance != server->reconnect_instance) { |
1030 | mutex_unlock(&ses->server->srv_mutex); | 1032 | mutex_unlock(&server->srv_mutex); |
1031 | for (j = 0; j < num_rqst; j++) | 1033 | for (j = 0; j < num_rqst; j++) |
1032 | add_credits(ses->server, &credits[j], optype); | 1034 | add_credits(server, &credits[j], optype); |
1033 | return -EAGAIN; | 1035 | return -EAGAIN; |
1034 | } | 1036 | } |
1035 | 1037 | ||
1036 | for (i = 0; i < num_rqst; i++) { | 1038 | for (i = 0; i < num_rqst; i++) { |
1037 | midQ[i] = ses->server->ops->setup_request(ses, &rqst[i]); | 1039 | midQ[i] = server->ops->setup_request(ses, &rqst[i]); |
1038 | if (IS_ERR(midQ[i])) { | 1040 | if (IS_ERR(midQ[i])) { |
1039 | revert_current_mid(ses->server, i); | 1041 | revert_current_mid(server, i); |
1040 | for (j = 0; j < i; j++) | 1042 | for (j = 0; j < i; j++) |
1041 | cifs_delete_mid(midQ[j]); | 1043 | cifs_delete_mid(midQ[j]); |
1042 | mutex_unlock(&ses->server->srv_mutex); | 1044 | mutex_unlock(&server->srv_mutex); |
1043 | 1045 | ||
1044 | /* Update # of requests on wire to server */ | 1046 | /* Update # of requests on wire to server */ |
1045 | for (j = 0; j < num_rqst; j++) | 1047 | for (j = 0; j < num_rqst; j++) |
1046 | add_credits(ses->server, &credits[j], optype); | 1048 | add_credits(server, &credits[j], optype); |
1047 | return PTR_ERR(midQ[i]); | 1049 | return PTR_ERR(midQ[i]); |
1048 | } | 1050 | } |
1049 | 1051 | ||
@@ -1059,19 +1061,19 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1059 | else | 1061 | else |
1060 | midQ[i]->callback = cifs_compound_last_callback; | 1062 | midQ[i]->callback = cifs_compound_last_callback; |
1061 | } | 1063 | } |
1062 | cifs_in_send_inc(ses->server); | 1064 | cifs_in_send_inc(server); |
1063 | rc = smb_send_rqst(ses->server, num_rqst, rqst, flags); | 1065 | rc = smb_send_rqst(server, num_rqst, rqst, flags); |
1064 | cifs_in_send_dec(ses->server); | 1066 | cifs_in_send_dec(server); |
1065 | 1067 | ||
1066 | for (i = 0; i < num_rqst; i++) | 1068 | for (i = 0; i < num_rqst; i++) |
1067 | cifs_save_when_sent(midQ[i]); | 1069 | cifs_save_when_sent(midQ[i]); |
1068 | 1070 | ||
1069 | if (rc < 0) { | 1071 | if (rc < 0) { |
1070 | revert_current_mid(ses->server, num_rqst); | 1072 | revert_current_mid(server, num_rqst); |
1071 | ses->server->sequence_number -= 2; | 1073 | server->sequence_number -= 2; |
1072 | } | 1074 | } |
1073 | 1075 | ||
1074 | mutex_unlock(&ses->server->srv_mutex); | 1076 | mutex_unlock(&server->srv_mutex); |
1075 | 1077 | ||
1076 | /* | 1078 | /* |
1077 | * If sending failed for some reason or it is an oplock break that we | 1079 | * If sending failed for some reason or it is an oplock break that we |
@@ -1079,7 +1081,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1079 | */ | 1081 | */ |
1080 | if (rc < 0 || (flags & CIFS_NO_SRV_RSP)) { | 1082 | if (rc < 0 || (flags & CIFS_NO_SRV_RSP)) { |
1081 | for (i = 0; i < num_rqst; i++) | 1083 | for (i = 0; i < num_rqst; i++) |
1082 | add_credits(ses->server, &credits[i], optype); | 1084 | add_credits(server, &credits[i], optype); |
1083 | goto out; | 1085 | goto out; |
1084 | } | 1086 | } |
1085 | 1087 | ||
@@ -1099,7 +1101,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1099 | rqst[0].rq_nvec); | 1101 | rqst[0].rq_nvec); |
1100 | 1102 | ||
1101 | for (i = 0; i < num_rqst; i++) { | 1103 | for (i = 0; i < num_rqst; i++) { |
1102 | rc = wait_for_response(ses->server, midQ[i]); | 1104 | rc = wait_for_response(server, midQ[i]); |
1103 | if (rc != 0) | 1105 | if (rc != 0) |
1104 | break; | 1106 | break; |
1105 | } | 1107 | } |
@@ -1107,7 +1109,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1107 | for (; i < num_rqst; i++) { | 1109 | for (; i < num_rqst; i++) { |
1108 | cifs_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", | 1110 | cifs_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", |
1109 | midQ[i]->mid, le16_to_cpu(midQ[i]->command)); | 1111 | midQ[i]->mid, le16_to_cpu(midQ[i]->command)); |
1110 | send_cancel(ses->server, &rqst[i], midQ[i]); | 1112 | send_cancel(server, &rqst[i], midQ[i]); |
1111 | spin_lock(&GlobalMid_Lock); | 1113 | spin_lock(&GlobalMid_Lock); |
1112 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { | 1114 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { |
1113 | midQ[i]->mid_flags |= MID_WAIT_CANCELLED; | 1115 | midQ[i]->mid_flags |= MID_WAIT_CANCELLED; |
@@ -1123,7 +1125,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1123 | if (rc < 0) | 1125 | if (rc < 0) |
1124 | goto out; | 1126 | goto out; |
1125 | 1127 | ||
1126 | rc = cifs_sync_mid_result(midQ[i], ses->server); | 1128 | rc = cifs_sync_mid_result(midQ[i], server); |
1127 | if (rc != 0) { | 1129 | if (rc != 0) { |
1128 | /* mark this mid as cancelled to not free it below */ | 1130 | /* mark this mid as cancelled to not free it below */ |
1129 | cancelled_mid[i] = true; | 1131 | cancelled_mid[i] = true; |
@@ -1140,14 +1142,14 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
1140 | buf = (char *)midQ[i]->resp_buf; | 1142 | buf = (char *)midQ[i]->resp_buf; |
1141 | resp_iov[i].iov_base = buf; | 1143 | resp_iov[i].iov_base = buf; |
1142 | resp_iov[i].iov_len = midQ[i]->resp_buf_size + | 1144 | resp_iov[i].iov_len = midQ[i]->resp_buf_size + |
1143 | ses->server->vals->header_preamble_size; | 1145 | server->vals->header_preamble_size; |
1144 | 1146 | ||
1145 | if (midQ[i]->large_buf) | 1147 | if (midQ[i]->large_buf) |
1146 | resp_buf_type[i] = CIFS_LARGE_BUFFER; | 1148 | resp_buf_type[i] = CIFS_LARGE_BUFFER; |
1147 | else | 1149 | else |
1148 | resp_buf_type[i] = CIFS_SMALL_BUFFER; | 1150 | resp_buf_type[i] = CIFS_SMALL_BUFFER; |
1149 | 1151 | ||
1150 | rc = ses->server->ops->check_receive(midQ[i], ses->server, | 1152 | rc = server->ops->check_receive(midQ[i], server, |
1151 | flags & CIFS_LOG_ERROR); | 1153 | flags & CIFS_LOG_ERROR); |
1152 | 1154 | ||
1153 | /* mark it so buf will not be freed by cifs_delete_mid */ | 1155 | /* mark it so buf will not be freed by cifs_delete_mid */ |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 50ddb795aaeb..9076150758d8 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -96,7 +96,6 @@ static int cifs_xattr_set(const struct xattr_handler *handler, | |||
96 | break; | 96 | break; |
97 | 97 | ||
98 | case XATTR_CIFS_ACL: { | 98 | case XATTR_CIFS_ACL: { |
99 | #ifdef CONFIG_CIFS_ACL | ||
100 | struct cifs_ntsd *pacl; | 99 | struct cifs_ntsd *pacl; |
101 | 100 | ||
102 | if (!value) | 101 | if (!value) |
@@ -117,7 +116,6 @@ static int cifs_xattr_set(const struct xattr_handler *handler, | |||
117 | CIFS_I(inode)->time = 0; | 116 | CIFS_I(inode)->time = 0; |
118 | kfree(pacl); | 117 | kfree(pacl); |
119 | } | 118 | } |
120 | #endif /* CONFIG_CIFS_ACL */ | ||
121 | break; | 119 | break; |
122 | } | 120 | } |
123 | 121 | ||
@@ -247,7 +245,6 @@ static int cifs_xattr_get(const struct xattr_handler *handler, | |||
247 | break; | 245 | break; |
248 | 246 | ||
249 | case XATTR_CIFS_ACL: { | 247 | case XATTR_CIFS_ACL: { |
250 | #ifdef CONFIG_CIFS_ACL | ||
251 | u32 acllen; | 248 | u32 acllen; |
252 | struct cifs_ntsd *pacl; | 249 | struct cifs_ntsd *pacl; |
253 | 250 | ||
@@ -270,7 +267,6 @@ static int cifs_xattr_get(const struct xattr_handler *handler, | |||
270 | rc = acllen; | 267 | rc = acllen; |
271 | kfree(pacl); | 268 | kfree(pacl); |
272 | } | 269 | } |
273 | #endif /* CONFIG_CIFS_ACL */ | ||
274 | break; | 270 | break; |
275 | } | 271 | } |
276 | 272 | ||