From 2cd646a2d1d5e0e46aa4bb55b1847b0cb35bd855 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 28 Sep 2006 19:43:08 +0000 Subject: [CIFS] Remove static and unused symbols Most cases of the ones found by Shaggy by "make namespacecheck" could be removed or made static Ack: Dave Kleikamp Signed-off-by: Steve French --- fs/cifs/connect.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'fs/cifs/connect.c') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 0e9ba0b9d71..b3268e53ab9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -109,7 +109,7 @@ static int ipv6_connect(struct sockaddr_in6 *psin_server, * wake up waiters on reconnection? - (not needed currently) */ -int +static int cifs_reconnect(struct TCP_Server_Info *server) { int rc = 0; @@ -771,13 +771,17 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) separator[0] = ','; separator[1] = 0; - memset(vol->source_rfc1001_name,0x20,15); - for(i=0;i < strnlen(system_utsname.nodename,15);i++) { - /* does not have to be a perfect mapping since the field is - informational, only used for servers that do not support - port 445 and it can be overridden at mount time */ - vol->source_rfc1001_name[i] = - toupper(system_utsname.nodename[i]); + if(Local_System_Name[0] != 0) + memcpy(vol->source_rfc1001_name, Local_System_Name,15); + else { + memset(vol->source_rfc1001_name,0x20,15); + for(i=0;i < strnlen(system_utsname.nodename,15);i++) { + /* does not have to be perfect mapping since field is + informational, only used for servers that do not support + port 445 and it can be overridden at mount time */ + vol->source_rfc1001_name[i] = + toupper(system_utsname.nodename[i]); + } } vol->source_rfc1001_name[15] = 0; /* null target name indicates to use *SMBSERVR default called name -- cgit v1.2.3-70-g09d2 From 175ec9e11cf18f8373b32f7a33e75a4cf7ce25e3 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 30 Sep 2006 01:07:38 +0000 Subject: [CIFS] Rename server time zone field Server time zone is not really a time zone, rather a time adjustement in seconds. CC: Guenter Kukkukk Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsglob.h | 2 +- fs/cifs/cifspdu.h | 5 ++++- fs/cifs/cifssmb.c | 9 ++++----- fs/cifs/connect.c | 9 +++++---- 5 files changed, 15 insertions(+), 12 deletions(-) (limited to 'fs/cifs/connect.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 7ecfcbf31e5..e7641f9a13b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -465,7 +465,7 @@ static struct super_operations cifs_super_ops = { .umount_begin = cifs_umount_begin, .remount_fs = cifs_remount, #ifdef CONFIG_CIFS_STATS2 - cifs_show_stats, + .cifs_show_stats, #endif }; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 441f8d2514f..98eb5446e8c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -153,7 +153,7 @@ struct TCP_Server_Info { char sessid[4]; /* unique token id for this session */ /* (returned on Negotiate */ int capabilities; /* allow selective disabling of caps by smb sess */ - __u16 timeZone; + __u16 timeAdj; /* Adjust for difference in server time zone in sec */ __u16 CurrentMid; /* multiplex id - rotating counter */ char cryptKey[CIFS_CRYPTO_KEY_SIZE]; /* 16th byte of RFC1001 workstation name is always null */ diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 81df2bf8e75..e5dd8708d63 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -417,7 +417,10 @@ typedef struct lanman_neg_rsp { __le16 MaxNumberVcs; __le16 RawMode; __le32 SessionKey; - __le32 ServerTime; + struct { + __le16 Time; + __le16 Date; + } __attribute__((packed)) SrvTime; __le16 ServerTimeZone; __le16 EncryptionKeyLength; __le16 Reserved; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 99718591ea2..6e004587fa4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -473,7 +473,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->maxRw = 0;/* we do not need to use raw anyway */ server->capabilities = CAP_MPX_MODE; } - server->timeZone = le16_to_cpu(rsp->ServerTimeZone); tmp = le16_to_cpu(rsp->ServerTimeZone); if (tmp == (int)0xffff) { /* OS/2 often does not set timezone therefore @@ -492,11 +491,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) tmp = (int)(utc.tv_sec - ts.tv_sec); adjust = tmp < 0 ? -29 : 29; tmp = ((tmp + adjust) / 60) * 60; - server->timeZone = tmp; + server->timeAdj = tmp; } else { - server->timeZone = tmp * 60; /* also in seconds */ + server->timeAdj = tmp * 60; /* also in seconds */ } - cFYI(1,("server->timeZone: %d seconds", server->timeZone)); + cFYI(1,("server->timeAdj: %d seconds", server->timeAdj)); /* BB get server time for time conversions and add @@ -557,7 +556,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) cFYI(0, ("Max buf = %d", ses->server->maxBuf)); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); server->capabilities = le32_to_cpu(pSMBr->Capabilities); - server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); + server->timeAdj = le16_to_cpu(pSMBr->ServerTimeZone) * 60; if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { memcpy(server->cryptKey, pSMBr->u.EncryptionKey, CIFS_CRYPTO_KEY_SIZE); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index b3268e53ab9..083b2b2c157 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3320,15 +3320,16 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, if(linuxExtEnabled == 0) pSesInfo->capabilities &= (~CAP_UNIX); /* pSesInfo->sequence_number = 0;*/ - cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", + cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", pSesInfo->server->secMode, pSesInfo->server->capabilities, - pSesInfo->server->timeZone)); + pSesInfo->server->timeAdj)); if(experimEnabled < 2) rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info); else if (extended_security - && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) + && (pSesInfo->capabilities + & CAP_EXTENDED_SECURITY) && (pSesInfo->server->secType == NTLMSSP)) { rc = -EOPNOTSUPP; } else if (extended_security @@ -3342,7 +3343,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, if (!rc) { if(ntlmv2_flag) { char * v2_response; - cFYI(1,("Can use more secure NTLM version 2 password hash")); + cFYI(1,("more secure NTLM ver2 hash")); if(CalcNTLMv2_partial_mac_key(pSesInfo, nls_info)) { rc = -ENOMEM; -- cgit v1.2.3-70-g09d2 From 9ac00b7d96045fa3ce573e0ad5cdc0350ad8e1d2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 30 Sep 2006 04:13:17 +0000 Subject: [CIFS] Do not send newer QFSInfo to legacy servers which can not support it Fix dialect negotiation to save off when we have negotiated lanman. This allows us to avoid sending some somewhat newer requests that the server can not handle and go directly to the older version (infolevel) of the same call. Make sure we try to negotiate a level which allows us to get the server OS (which we check so we can detect Win9x vs. other legacy servers and eventually work around the Win9x DOS time bug (they reverse date/time fields). Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 8 +++++--- fs/cifs/cifsglob.h | 9 +++++++-- fs/cifs/cifspdu.h | 3 ++- fs/cifs/cifssmb.c | 8 +++++--- fs/cifs/connect.c | 1 + fs/cifs/sess.c | 23 ++++++++++++----------- 6 files changed, 32 insertions(+), 20 deletions(-) (limited to 'fs/cifs/connect.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ca53720fa5b..d6d226addde 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -199,10 +199,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) /* Only need to call the old QFSInfo if failed on newer one */ if(rc) - rc = CIFSSMBQFSInfo(xid, pTcon, buf); + if((pTcon->ses->flags & CIFS_SES_LANMAN) == 0) + rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ - /* Old Windows servers do not support level 103, retry with level - one if old server failed the previous call */ + /* Some old Windows servers also do not support level 103, retry with + older level one if old server failed the previous call or we + bypassed it because we detected that this was an older LANMAN sess */ if(rc) rc = SMBOldQFSInfo(xid, pTcon, buf); /* diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 98eb5446e8c..597afdf4c69 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -203,9 +203,14 @@ struct cifsSesInfo { char * domainName; char * password; }; -/* session flags */ +/* no more than one of the following three session flags may be set */ #define CIFS_SES_NT4 1 - +#define CIFS_SES_OS2 2 +#define CIFS_SES_W9X 4 +/* following flag is set for old servers such as OS2 (and Win95?) + which do not negotiate NTLM or POSIX dialects, but instead + negotiate one of the older LANMAN dialects */ +#define CIFS_SES_LANMAN 8 /* * there is one of these for each connection to a resource on a particular * session diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index e5dd8708d63..50505422dbb 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -26,7 +26,8 @@ #ifdef CONFIG_CIFS_WEAK_PW_HASH #define LANMAN_PROT 0 -#define CIFS_PROT 1 +#define LANMAN2_PROT 1 +#define CIFS_PROT 2 #else #define CIFS_PROT 0 #endif diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 6e004587fa4..f2fa05bbcb4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -46,6 +46,7 @@ static struct { } protocols[] = { #ifdef CONFIG_CIFS_WEAK_PW_HASH {LANMAN_PROT, "\2LM1.2X002"}, + {LANMAN2_PROT, "\2LANMAN2.1"}, #endif /* weak password hashing for legacy clients */ {CIFS_PROT, "\2NT LM 0.12"}, {POSIX_PROT, "\2POSIX 2"}, @@ -67,13 +68,13 @@ static struct { /* define the number of elements in the cifs dialect array */ #ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_WEAK_PW_HASH -#define CIFS_NUM_PROT 3 +#define CIFS_NUM_PROT 4 #else #define CIFS_NUM_PROT 2 #endif /* CIFS_WEAK_PW_HASH */ #else /* not posix */ #ifdef CONFIG_CIFS_WEAK_PW_HASH -#define CIFS_NUM_PROT 2 +#define CIFS_NUM_PROT 3 #else #define CIFS_NUM_PROT 1 #endif /* CONFIG_CIFS_WEAK_PW_HASH */ @@ -446,7 +447,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) goto neg_err_exit; #ifdef CONFIG_CIFS_WEAK_PW_HASH } else if((pSMBr->hdr.WordCount == 13) - && (pSMBr->DialectIndex == LANMAN_PROT)) { + && ((pSMBr->DialectIndex == LANMAN_PROT) + || (pSMBr->DialectIndex == LANMAN2_PROT))) { int tmp, adjust; struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 083b2b2c157..c96f3edf1b9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3316,6 +3316,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, first_time = 1; } if (!rc) { + pSesInfo->flags = 0; pSesInfo->capabilities = pSesInfo->server->capabilities; if(linuxExtEnabled == 0) pSesInfo->capabilities &= (~CAP_UNIX); diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index d1705ab8136..e4c4e466e32 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -268,6 +268,10 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo ses->serverOS = kzalloc(len + 1, GFP_KERNEL); if(ses->serverOS) strncpy(ses->serverOS, bcc_ptr, len); + if(strncmp(ses->serverOS, "OS/2",4) == 0) { + cFYI(1,("OS/2 server")); + ses->flags |= CIFS_SES_OS2; + } bcc_ptr += len + 1; bleft -= len + 1; @@ -290,16 +294,11 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo if(len > bleft) return rc; - if(ses->serverDomain) - kfree(ses->serverDomain); - - ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); - if(ses->serverOS) - strncpy(ses->serverOS, bcc_ptr, len); - - bcc_ptr += len + 1; - bleft -= len + 1; - + /* No domain field in LANMAN case. Domain is + returned by old servers in the SMB negprot response */ + /* BB For newer servers which do not support Unicode, + but thus do return domain here we could add parsing + for it later, but it is not very important */ cFYI(1,("ascii: bytes left %d",bleft)); return rc; @@ -366,6 +365,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, str_area = kmalloc(2000, GFP_KERNEL); bcc_ptr = str_area; + ses->flags &= ~CIFS_SES_LANMAN; + if(type == LANMAN) { #ifdef CONFIG_CIFS_WEAK_PW_HASH char lnm_session_key[CIFS_SESS_KEY_SIZE]; @@ -377,7 +378,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, /* and copy into bcc */ calc_lanman_hash(ses, lnm_session_key); - + ses->flags |= CIFS_SES_LANMAN; /* #ifdef CONFIG_CIFS_DEBUG2 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, CIFS_SESS_KEY_SIZE); -- cgit v1.2.3-70-g09d2 From 1a4e15a04ec69cb3552f4120079f5472377df5f7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 12 Oct 2006 21:33:51 +0000 Subject: [CIFS] Missing flags2 for DFS Partly suggested by Igor Mammedov Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 8 ++++++++ fs/cifs/connect.c | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'fs/cifs/connect.c') diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 6f50f2bc887..5dc5a966bd5 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3675,6 +3675,14 @@ getDFSRetry: strncpy(pSMB->RequestFileName, searchName, name_len); } + if(ses->server) { + if(ses->server->secMode & + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; + } + + pSMB->hdr.Uid = ses->Suid; + params = 2 /* level */ + name_len /*includes null */ ; pSMB->TotalDataCount = 0; pSMB->DataCount = 0; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c96f3edf1b9..1d17691086c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3219,7 +3219,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, } /* else do not bother copying these informational fields */ } - if(smb_buffer_response->WordCount == 3) + if((smb_buffer_response->WordCount == 3) || + (smb_buffer_response->WordCount == 7)) + /* field is in same location */ tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); else tcon->Flags = 0; -- cgit v1.2.3-70-g09d2