aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c95
1 files changed, 85 insertions, 10 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f00369277c06..da3154fa9c8a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -44,8 +44,11 @@ static struct {
44 int index; 44 int index;
45 char *name; 45 char *name;
46} protocols[] = { 46} protocols[] = {
47#ifdef CONFIG_CIFS_WEAK_PW_HASH
48 {LANMAN_PROT, "\2LM1.2X002"},
49#endif /* weak password hashing for legacy clients */
47 {CIFS_PROT, "\2NT LM 0.12"}, 50 {CIFS_PROT, "\2NT LM 0.12"},
48 {CIFS_PROT, "\2POSIX 2"}, 51 {POSIX_PROT, "\2POSIX 2"},
49 {BAD_PROT, "\2"} 52 {BAD_PROT, "\2"}
50}; 53};
51#else 54#else
@@ -53,11 +56,29 @@ static struct {
53 int index; 56 int index;
54 char *name; 57 char *name;
55} protocols[] = { 58} protocols[] = {
59#ifdef CONFIG_CIFS_WEAK_PW_HASH
60 {LANMAN_PROT, "\2LM1.2X002"},
61#endif /* weak password hashing for legacy clients */
56 {CIFS_PROT, "\2NT LM 0.12"}, 62 {CIFS_PROT, "\2NT LM 0.12"},
57 {BAD_PROT, "\2"} 63 {BAD_PROT, "\2"}
58}; 64};
59#endif 65#endif
60 66
67/* define the number of elements in the cifs dialect array */
68#ifdef CONFIG_CIFS_POSIX
69#ifdef CONFIG_CIFS_WEAK_PW_HASH
70#define CIFS_NUM_PROT 3
71#else
72#define CIFS_NUM_PROT 2
73#endif /* CIFS_WEAK_PW_HASH */
74#else /* not posix */
75#ifdef CONFIG_CIFS_WEAK_PW_HASH
76#define CIFS_NUM_PROT 2
77#else
78#define CIFS_NUM_PROT 1
79#endif /* CONFIG_CIFS_WEAK_PW_HASH */
80#endif /* CIFS_POSIX */
81
61 82
62/* Mark as invalid, all open files on tree connections since they 83/* Mark as invalid, all open files on tree connections since they
63 were closed when session to server was lost */ 84 were closed when session to server was lost */
@@ -322,7 +343,8 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
322 /* potential retries of smb operations it turns out we can determine */ 343 /* potential retries of smb operations it turns out we can determine */
323 /* from the mid flags when the request buffer can be resent without */ 344 /* from the mid flags when the request buffer can be resent without */
324 /* having to use a second distinct buffer for the response */ 345 /* having to use a second distinct buffer for the response */
325 *response_buf = *request_buf; 346 if(response_buf)
347 *response_buf = *request_buf;
326 348
327 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 349 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
328 wct /*wct */ ); 350 wct /*wct */ );
@@ -373,6 +395,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
373 NEGOTIATE_RSP *pSMBr; 395 NEGOTIATE_RSP *pSMBr;
374 int rc = 0; 396 int rc = 0;
375 int bytes_returned; 397 int bytes_returned;
398 int i;
376 struct TCP_Server_Info * server; 399 struct TCP_Server_Info * server;
377 u16 count; 400 u16 count;
378 401
@@ -388,19 +411,71 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
388 return rc; 411 return rc;
389 pSMB->hdr.Mid = GetNextMid(server); 412 pSMB->hdr.Mid = GetNextMid(server);
390 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 413 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
391 if (extended_security) 414/* if (extended_security)
392 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 415 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;*/
393 416
394 count = strlen(protocols[0].name) + 1; 417 count = 0;
395 strncpy(pSMB->DialectsArray, protocols[0].name, 30); 418 for(i=0;i<CIFS_NUM_PROT;i++) {
396 /* null guaranteed to be at end of source and target buffers anyway */ 419 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
397 420 count += strlen(protocols[i].name) + 1;
421 /* null at end of source and target buffers anyway */
422 }
398 pSMB->hdr.smb_buf_length += count; 423 pSMB->hdr.smb_buf_length += count;
399 pSMB->ByteCount = cpu_to_le16(count); 424 pSMB->ByteCount = cpu_to_le16(count);
400 425
401 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 426 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
402 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 427 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
403 if (rc == 0) { 428 if (rc == 0) {
429 cFYI(1,("Dialect: %d", pSMBr->DialectIndex));
430 /* Check wct = 1 error case */
431 if((pSMBr->hdr.WordCount < 13)
432 || (pSMBr->DialectIndex == BAD_PROT)) {
433 /* core returns wct = 1, but we do not ask for
434 core - otherwise it just comes when dialect
435 index is -1 indicating we could not negotiate
436 a common dialect */
437 rc = -EOPNOTSUPP;
438 goto neg_err_exit;
439 } else if((pSMBr->hdr.WordCount == 13) &&
440 (pSMBr->DialectIndex == LANMAN_PROT)) {
441 struct lanman_neg_rsp * rsp =
442 (struct lanman_neg_rsp *)pSMBr;
443
444
445 /* BB Mark ses struct as negotiated lanman level BB */
446 server->secType = LANMAN;
447 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
448 server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
449 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
450 (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
451
452 /* BB what do we do with raw mode? BB */
453 server->timeZone = le16_to_cpu(rsp->ServerTimeZone);
454 /* Do we have to set signing flags? no signing
455 was available LANMAN - default should be ok */
456
457 /* BB FIXME set default dummy capabilities since
458 they are not returned by the server in this dialect */
459
460 /* get server time for time conversions and add
461 code to use it and timezone since this is not UTC */
462
463 if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
464 memcpy(server->cryptKey, rsp->EncryptionKey,
465 CIFS_CRYPTO_KEY_SIZE);
466 } else {
467 rc = -EIO;
468 goto neg_err_exit;
469 }
470
471 cFYI(1,("LANMAN negotiated")); /* BB removeme BB */
472 goto neg_err_exit;
473 } else if(pSMBr->hdr.WordCount != 17) {
474 /* unknown wct */
475 rc = -EOPNOTSUPP;
476 goto neg_err_exit;
477 }
478
404 server->secMode = pSMBr->SecurityMode; 479 server->secMode = pSMBr->SecurityMode;
405 if((server->secMode & SECMODE_USER) == 0) 480 if((server->secMode & SECMODE_USER) == 0)
406 cFYI(1,("share mode security")); 481 cFYI(1,("share mode security"));
@@ -479,7 +554,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
479 } 554 }
480 555
481 } 556 }
482 557neg_err_exit:
483 cifs_buf_release(pSMB); 558 cifs_buf_release(pSMB);
484 return rc; 559 return rc;
485} 560}