diff options
author | Steve French <sfrench@us.ibm.com> | 2006-09-29 20:54:23 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-09-29 20:54:23 -0400 |
commit | 25ee4a98c662317a7973f3053567d4ec51857511 (patch) | |
tree | 1795f787fb677c6941853b0e5a86b14dce5e7936 /fs/cifs/cifssmb.c | |
parent | bf97d28711e2dc4dc947faa6477cd1b36b91a2da (diff) |
[CIFS] Handle legacy servers which return undefined time zone
Signed-off-by: Guenter Kukkukk <linux@kukkukk.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index dcd7087a1ae8..99718591ea29 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -447,6 +447,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
447 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 447 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
448 | } else if((pSMBr->hdr.WordCount == 13) | 448 | } else if((pSMBr->hdr.WordCount == 13) |
449 | && (pSMBr->DialectIndex == LANMAN_PROT)) { | 449 | && (pSMBr->DialectIndex == LANMAN_PROT)) { |
450 | int tmp, adjust; | ||
450 | struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; | 451 | struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; |
451 | 452 | ||
452 | if((secFlags & CIFSSEC_MAY_LANMAN) || | 453 | if((secFlags & CIFSSEC_MAY_LANMAN) || |
@@ -473,11 +474,36 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
473 | server->capabilities = CAP_MPX_MODE; | 474 | server->capabilities = CAP_MPX_MODE; |
474 | } | 475 | } |
475 | server->timeZone = le16_to_cpu(rsp->ServerTimeZone); | 476 | server->timeZone = le16_to_cpu(rsp->ServerTimeZone); |
477 | tmp = le16_to_cpu(rsp->ServerTimeZone); | ||
478 | if (tmp == (int)0xffff) { | ||
479 | /* OS/2 often does not set timezone therefore | ||
480 | * we must use server time to calc time zone. | ||
481 | * Could deviate slightly from the right zone. Not easy | ||
482 | * to adjust, since timezones are not always a multiple | ||
483 | * of 60 (sometimes 30 minutes - are there smaller?) | ||
484 | */ | ||
485 | struct timespec ts, utc; | ||
486 | utc = CURRENT_TIME; | ||
487 | ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), | ||
488 | le16_to_cpu(rsp->SrvTime.Time)); | ||
489 | cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d", | ||
490 | (int)ts.tv_sec, (int)utc.tv_sec, | ||
491 | (int)(utc.tv_sec - ts.tv_sec))); | ||
492 | tmp = (int)(utc.tv_sec - ts.tv_sec); | ||
493 | adjust = tmp < 0 ? -29 : 29; | ||
494 | tmp = ((tmp + adjust) / 60) * 60; | ||
495 | server->timeZone = tmp; | ||
496 | } else { | ||
497 | server->timeZone = tmp * 60; /* also in seconds */ | ||
498 | } | ||
499 | cFYI(1,("server->timeZone: %d seconds", server->timeZone)); | ||
500 | |||
476 | 501 | ||
477 | /* BB get server time for time conversions and add | 502 | /* BB get server time for time conversions and add |
478 | code to use it and timezone since this is not UTC */ | 503 | code to use it and timezone since this is not UTC */ |
479 | 504 | ||
480 | if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { | 505 | if (rsp->EncryptionKeyLength == |
506 | cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { | ||
481 | memcpy(server->cryptKey, rsp->EncryptionKey, | 507 | memcpy(server->cryptKey, rsp->EncryptionKey, |
482 | CIFS_CRYPTO_KEY_SIZE); | 508 | CIFS_CRYPTO_KEY_SIZE); |
483 | } else if (server->secMode & SECMODE_PW_ENCRYPT) { | 509 | } else if (server->secMode & SECMODE_PW_ENCRYPT) { |