Commit e4aa25e7801163df058f62c617b859e9d3d4b148
1 parent
c052e2b423
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
[CIFS] Fix SMB2 negotiation support to select only one dialect (based on vers=)
Based on whether the user (on mount command) chooses: vers=3.0 (for smb3.0 support) vers=2.1 (for smb2.1 support) or (with subsequent patch, which will allow SMB2 support) vers=2.0 (for original smb2.02 dialect support) send only one dialect at a time during negotiate (we had been sending a list). Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Showing 5 changed files with 56 additions and 29 deletions Side-by-side Diff
fs/cifs/cifsglob.h
... | ... | @@ -179,6 +179,7 @@ |
179 | 179 | enum smb_version { |
180 | 180 | Smb_1 = 1, |
181 | 181 | Smb_21, |
182 | + Smb_30, | |
182 | 183 | }; |
183 | 184 | |
184 | 185 | struct mid_q_entry; |
... | ... | @@ -372,6 +373,8 @@ |
372 | 373 | |
373 | 374 | struct smb_version_values { |
374 | 375 | char *version_string; |
376 | + __u16 protocol_id; | |
377 | + __u32 req_capabilities; | |
375 | 378 | __u32 large_lock_type; |
376 | 379 | __u32 exclusive_lock_type; |
377 | 380 | __u32 shared_lock_type; |
378 | 381 | |
... | ... | @@ -1496,8 +1499,14 @@ |
1496 | 1499 | #define SMB1_VERSION_STRING "1.0" |
1497 | 1500 | extern struct smb_version_operations smb1_operations; |
1498 | 1501 | extern struct smb_version_values smb1_values; |
1502 | +#define SMB20_VERSION_STRING "2.0" | |
1503 | +/*extern struct smb_version_operations smb20_operations; */ /* not needed yet */ | |
1504 | +extern struct smb_version_values smb20_values; | |
1499 | 1505 | #define SMB21_VERSION_STRING "2.1" |
1500 | 1506 | extern struct smb_version_operations smb21_operations; |
1501 | 1507 | extern struct smb_version_values smb21_values; |
1508 | +#define SMB30_VERSION_STRING "3.0" | |
1509 | +/*extern struct smb_version_operations smb30_operations; */ /* not needed yet */ | |
1510 | +extern struct smb_version_values smb30_values; | |
1502 | 1511 | #endif /* _CIFS_GLOB_H */ |
fs/cifs/connect.c
... | ... | @@ -272,6 +272,7 @@ |
272 | 272 | static const match_table_t cifs_smb_version_tokens = { |
273 | 273 | { Smb_1, SMB1_VERSION_STRING }, |
274 | 274 | { Smb_21, SMB21_VERSION_STRING }, |
275 | + { Smb_30, SMB30_VERSION_STRING }, | |
275 | 276 | }; |
276 | 277 | |
277 | 278 | static int ip_connect(struct TCP_Server_Info *server); |
... | ... | @@ -1073,6 +1074,10 @@ |
1073 | 1074 | case Smb_21: |
1074 | 1075 | vol->ops = &smb21_operations; |
1075 | 1076 | vol->vals = &smb21_values; |
1077 | + break; | |
1078 | + case Smb_30: | |
1079 | + vol->ops = &smb21_operations; /* currently identical with 2.1 */ | |
1080 | + vol->vals = &smb30_values; | |
1076 | 1081 | break; |
1077 | 1082 | #endif |
1078 | 1083 | default: |
fs/cifs/smb2ops.c
... | ... | @@ -645,6 +645,25 @@ |
645 | 645 | |
646 | 646 | struct smb_version_values smb21_values = { |
647 | 647 | .version_string = SMB21_VERSION_STRING, |
648 | + .protocol_id = SMB21_PROT_ID, | |
649 | + .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */ | |
650 | + .large_lock_type = 0, | |
651 | + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, | |
652 | + .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | |
653 | + .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | |
654 | + .header_size = sizeof(struct smb2_hdr), | |
655 | + .max_header_size = MAX_SMB2_HDR_SIZE, | |
656 | + .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | |
657 | + .lock_cmd = SMB2_LOCK, | |
658 | + .cap_unix = 0, | |
659 | + .cap_nt_find = SMB2_NT_FIND, | |
660 | + .cap_large_files = SMB2_LARGE_FILES, | |
661 | +}; | |
662 | + | |
663 | +struct smb_version_values smb30_values = { | |
664 | + .version_string = SMB30_VERSION_STRING, | |
665 | + .protocol_id = SMB30_PROT_ID, | |
666 | + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU, | |
648 | 667 | .large_lock_type = 0, |
649 | 668 | .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, |
650 | 669 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
fs/cifs/smb2pdu.c
1 | 1 | /* |
2 | 2 | * fs/cifs/smb2pdu.c |
3 | 3 | * |
4 | - * Copyright (C) International Business Machines Corp., 2009, 2011 | |
4 | + * Copyright (C) International Business Machines Corp., 2009, 2012 | |
5 | 5 | * Etersoft, 2012 |
6 | 6 | * Author(s): Steve French (sfrench@us.ibm.com) |
7 | 7 | * Pavel Shilovsky (pshilovsky@samba.org) 2012 |
8 | 8 | |
... | ... | @@ -304,25 +304,7 @@ |
304 | 304 | cifs_buf_release(rsp); |
305 | 305 | } |
306 | 306 | |
307 | -#define SMB2_NUM_PROT 2 | |
308 | 307 | |
309 | -#define SMB2_PROT 0 | |
310 | -#define SMB21_PROT 1 | |
311 | -#define BAD_PROT 0xFFFF | |
312 | - | |
313 | -#define SMB2_PROT_ID 0x0202 | |
314 | -#define SMB21_PROT_ID 0x0210 | |
315 | -#define BAD_PROT_ID 0xFFFF | |
316 | - | |
317 | -static struct { | |
318 | - int index; | |
319 | - __le16 name; | |
320 | -} smb2protocols[] = { | |
321 | - {SMB2_PROT, cpu_to_le16(SMB2_PROT_ID)}, | |
322 | - {SMB21_PROT, cpu_to_le16(SMB21_PROT_ID)}, | |
323 | - {BAD_PROT, cpu_to_le16(BAD_PROT_ID)} | |
324 | -}; | |
325 | - | |
326 | 308 | /* |
327 | 309 | * |
328 | 310 | * SMB2 Worker functions follow: |
... | ... | @@ -348,7 +330,6 @@ |
348 | 330 | int resp_buftype; |
349 | 331 | struct TCP_Server_Info *server; |
350 | 332 | unsigned int sec_flags; |
351 | - u16 i; | |
352 | 333 | u16 temp = 0; |
353 | 334 | int blob_offset, blob_length; |
354 | 335 | char *security_blob; |
355 | 336 | |
... | ... | @@ -377,11 +358,10 @@ |
377 | 358 | |
378 | 359 | req->hdr.SessionId = 0; |
379 | 360 | |
380 | - for (i = 0; i < SMB2_NUM_PROT; i++) | |
381 | - req->Dialects[i] = smb2protocols[i].name; | |
361 | + req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); | |
382 | 362 | |
383 | - req->DialectCount = cpu_to_le16(i); | |
384 | - inc_rfc1001_len(req, i * 2); | |
363 | + req->DialectCount = cpu_to_le16(1); /* One vers= at a time for now */ | |
364 | + inc_rfc1001_len(req, 2); | |
385 | 365 | |
386 | 366 | /* only one of SMB2 signing flags may be set in SMB2 request */ |
387 | 367 | if ((sec_flags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) |
... | ... | @@ -391,7 +371,7 @@ |
391 | 371 | |
392 | 372 | req->SecurityMode = cpu_to_le16(temp); |
393 | 373 | |
394 | - req->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS); | |
374 | + req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities); | |
395 | 375 | |
396 | 376 | memcpy(req->ClientGUID, cifs_client_guid, SMB2_CLIENT_GUID_SIZE); |
397 | 377 | |
398 | 378 | |
... | ... | @@ -411,10 +391,14 @@ |
411 | 391 | |
412 | 392 | cFYI(1, "mode 0x%x", rsp->SecurityMode); |
413 | 393 | |
414 | - if (rsp->DialectRevision == smb2protocols[SMB21_PROT].name) | |
394 | + /* BB we may eventually want to match the negotiated vs. requested | |
395 | + dialect, even though we are only requesting one at a time */ | |
396 | + if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) | |
397 | + cFYI(1, "negotiated smb2.0 dialect"); | |
398 | + else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) | |
415 | 399 | cFYI(1, "negotiated smb2.1 dialect"); |
416 | - else if (rsp->DialectRevision == smb2protocols[SMB2_PROT].name) | |
417 | - cFYI(1, "negotiated smb2 dialect"); | |
400 | + else if (rsp->DialectRevision == cpu_to_le16(SMB30_PROT_ID)) | |
401 | + cFYI(1, "negotiated smb3.0 dialect"); | |
418 | 402 | else { |
419 | 403 | cERROR(1, "Illegal dialect returned by server %d", |
420 | 404 | le16_to_cpu(rsp->DialectRevision)); |
fs/cifs/smb2pdu.h
... | ... | @@ -163,9 +163,15 @@ |
163 | 163 | __le32 Capabilities; |
164 | 164 | __u8 ClientGUID[SMB2_CLIENT_GUID_SIZE]; |
165 | 165 | __le64 ClientStartTime; /* MBZ */ |
166 | - __le16 Dialects[2]; /* variable length */ | |
166 | + __le16 Dialects[1]; /* One dialect (vers=) at a time for now */ | |
167 | 167 | } __packed; |
168 | 168 | |
169 | +/* Dialects */ | |
170 | +#define SMB20_PROT_ID 0x0202 | |
171 | +#define SMB21_PROT_ID 0x0210 | |
172 | +#define SMB30_PROT_ID 0x0300 | |
173 | +#define BAD_PROT_ID 0xFFFF | |
174 | + | |
169 | 175 | /* SecurityMode flags */ |
170 | 176 | #define SMB2_NEGOTIATE_SIGNING_ENABLED 0x0001 |
171 | 177 | #define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x0002 |
... | ... | @@ -173,6 +179,10 @@ |
173 | 179 | #define SMB2_GLOBAL_CAP_DFS 0x00000001 |
174 | 180 | #define SMB2_GLOBAL_CAP_LEASING 0x00000002 /* Resp only New to SMB2.1 */ |
175 | 181 | #define SMB2_GLOBAL_CAP_LARGE_MTU 0X00000004 /* Resp only New to SMB2.1 */ |
182 | +#define SMB2_GLOBAL_CAP_MULTI_CHANNEL 0x00000008 /* New to SMB3 */ | |
183 | +#define SMB2_GLOBAL_CAP_PERSISTENT_HANDLES 0x00000010 /* New to SMB3 */ | |
184 | +#define SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020 /* New to SMB3 */ | |
185 | +#define SMB2_GLOBAL_CAP_ENCRYPTION 0x00000040 /* New to SMB3 */ | |
176 | 186 | /* Internal types */ |
177 | 187 | #define SMB2_NT_FIND 0x00100000 |
178 | 188 | #define SMB2_LARGE_FILES 0x00200000 |