X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fcifs%2Fcifssmb.c;h=925881e00ff210e08822cc456337be1734f801d8;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=075d8fb3d37608a96d0610c519794388351d1173;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 075d8fb3d..925881e00 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -44,11 +44,8 @@ static struct { int index; char *name; } protocols[] = { -#ifdef CONFIG_CIFS_WEAK_PW_HASH - {LANMAN_PROT, "\2LM1.2X002"}, -#endif /* weak password hashing for legacy clients */ {CIFS_PROT, "\2NT LM 0.12"}, - {POSIX_PROT, "\2POSIX 2"}, + {CIFS_PROT, "\2POSIX 2"}, {BAD_PROT, "\2"} }; #else @@ -56,29 +53,11 @@ static struct { int index; char *name; } protocols[] = { -#ifdef CONFIG_CIFS_WEAK_PW_HASH - {LANMAN_PROT, "\2LM1.2X002"}, -#endif /* weak password hashing for legacy clients */ {CIFS_PROT, "\2NT LM 0.12"}, {BAD_PROT, "\2"} }; #endif -/* 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 -#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 -#else -#define CIFS_NUM_PROT 1 -#endif /* CONFIG_CIFS_WEAK_PW_HASH */ -#endif /* CIFS_POSIX */ - /* Mark as invalid, all open files on tree connections since they were closed when session to server was lost */ @@ -209,6 +188,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, return rc; } +#ifdef CONFIG_CIFS_EXPERIMENTAL int small_smb_init_no_tc(const int smb_command, const int wct, struct cifsSesInfo *ses, void **request_buf) @@ -234,6 +214,7 @@ small_smb_init_no_tc(const int smb_command, const int wct, return rc; } +#endif /* CONFIG_CIFS_EXPERIMENTAL */ /* If the return code is zero, this function must fill in request_buf pointer */ static int @@ -341,8 +322,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, /* potential retries of smb operations it turns out we can determine */ /* from the mid flags when the request buffer can be resent without */ /* having to use a second distinct buffer for the response */ - if(response_buf) - *response_buf = *request_buf; + *response_buf = *request_buf; header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, wct /*wct */ ); @@ -393,10 +373,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) NEGOTIATE_RSP *pSMBr; int rc = 0; int bytes_returned; - int i; struct TCP_Server_Info * server; u16 count; - unsigned int secFlags; if(ses->server) server = ses->server; @@ -408,200 +386,101 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) (void **) &pSMB, (void **) &pSMBr); if (rc) return rc; - - /* if any of auth flags (ie not sign or seal) are overriden use them */ - if(ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) - secFlags = ses->overrideSecFlg; - else /* if override flags set only sign/seal OR them with global auth */ - secFlags = extended_security | ses->overrideSecFlg; - - cFYI(1,("secFlags 0x%x",secFlags)); - pSMB->hdr.Mid = GetNextMid(server); pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; - if((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) + if (extended_security) pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; - - count = 0; - for(i=0;iDialectsArray+count, protocols[i].name, 16); - count += strlen(protocols[i].name) + 1; - /* null at end of source and target buffers anyway */ - } + + count = strlen(protocols[0].name) + 1; + strncpy(pSMB->DialectsArray, protocols[0].name, 30); + /* null guaranteed to be at end of source and target buffers anyway */ + pSMB->hdr.smb_buf_length += count; pSMB->ByteCount = cpu_to_le16(count); rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc != 0) - goto neg_err_exit; - - cFYI(1,("Dialect: %d", pSMBr->DialectIndex)); - /* Check wct = 1 error case */ - if((pSMBr->hdr.WordCount < 13) || (pSMBr->DialectIndex == BAD_PROT)) { - /* core returns wct = 1, but we do not ask for core - otherwise - small wct just comes when dialect index is -1 indicating we - could not negotiate a common dialect */ - rc = -EOPNOTSUPP; - goto neg_err_exit; -#ifdef CONFIG_CIFS_WEAK_PW_HASH - } else if((pSMBr->hdr.WordCount == 13) - && (pSMBr->DialectIndex == LANMAN_PROT)) { - struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; - - if((secFlags & CIFSSEC_MAY_LANMAN) || - (secFlags & CIFSSEC_MAY_PLNTXT)) - server->secType = LANMAN; - else { - cERROR(1, ("mount failed weak security disabled" - " in /proc/fs/cifs/SecurityFlags")); - rc = -EOPNOTSUPP; - goto neg_err_exit; - } - server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); - server->maxReq = le16_to_cpu(rsp->MaxMpxCount); - server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), - (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); - GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); - /* even though we do not use raw we might as well set this - accurately, in case we ever find a need for it */ - if((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { - server->maxRw = 0xFF00; - server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; - } else { - server->maxRw = 0;/* we do not need to use raw anyway */ - server->capabilities = CAP_MPX_MODE; - } - server->timeZone = le16_to_cpu(rsp->ServerTimeZone); - - /* BB get server time for time conversions and add - code to use it and timezone since this is not UTC */ - - if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { - memcpy(server->cryptKey, rsp->EncryptionKey, - CIFS_CRYPTO_KEY_SIZE); - } else if (server->secMode & SECMODE_PW_ENCRYPT) { - rc = -EIO; /* need cryptkey unless plain text */ - goto neg_err_exit; - } - - cFYI(1,("LANMAN negotiated")); - /* we will not end up setting signing flags - as no signing - was in LANMAN and server did not return the flags on */ - goto signing_check; -#else /* weak security disabled */ - } else if(pSMBr->hdr.WordCount == 13) { - cERROR(1,("mount failed, cifs module not built " - "with CIFS_WEAK_PW_HASH support")); - rc = -EOPNOTSUPP; -#endif /* WEAK_PW_HASH */ - goto neg_err_exit; - } else if(pSMBr->hdr.WordCount != 17) { - /* unknown wct */ - rc = -EOPNOTSUPP; - goto neg_err_exit; - } - /* else wct == 17 NTLM */ - server->secMode = pSMBr->SecurityMode; - if((server->secMode & SECMODE_USER) == 0) - cFYI(1,("share mode security")); - - if((server->secMode & SECMODE_PW_ENCRYPT) == 0) -#ifdef CONFIG_CIFS_WEAK_PW_HASH - if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) -#endif /* CIFS_WEAK_PW_HASH */ - cERROR(1,("Server requests plain text password" - " but client support disabled")); - - if((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2) - server->secType = NTLMv2; - else if(secFlags & CIFSSEC_MAY_NTLM) - server->secType = NTLM; - else if(secFlags & CIFSSEC_MAY_NTLMV2) - server->secType = NTLMv2; - /* else krb5 ... any others ... */ - - /* one byte, so no need to convert this or EncryptionKeyLen from - little endian */ - server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); - /* probably no need to store and check maxvcs */ - server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), + if (rc == 0) { + server->secMode = pSMBr->SecurityMode; + if((server->secMode & SECMODE_USER) == 0) + cFYI(1,("share mode security")); + server->secType = NTLM; /* BB override default for + NTLMv2 or kerberos v5 */ + /* one byte - no need to convert this or EncryptionKeyLen + from little endian */ + server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); + /* probably no need to store and check maxvcs */ + server->maxBuf = + min(le32_to_cpu(pSMBr->MaxBufferSize), (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); - server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); - 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); - if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { - memcpy(server->cryptKey, pSMBr->u.EncryptionKey, - CIFS_CRYPTO_KEY_SIZE); - } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) - && (pSMBr->EncryptionKeyLength == 0)) { - /* decode security blob */ - } else if (server->secMode & SECMODE_PW_ENCRYPT) { - rc = -EIO; /* no crypt key only if plain text pwd */ - goto neg_err_exit; - } + server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); + 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); + /* BB with UTC do we ever need to be using srvr timezone? */ + if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { + memcpy(server->cryptKey, pSMBr->u.EncryptionKey, + CIFS_CRYPTO_KEY_SIZE); + } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) + && (pSMBr->EncryptionKeyLength == 0)) { + /* decode security blob */ + } else + rc = -EIO; - /* BB might be helpful to save off the domain of server here */ + /* BB might be helpful to save off the domain of server here */ - if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && - (server->capabilities & CAP_EXTENDED_SECURITY)) { - count = pSMBr->ByteCount; - if (count < 16) - rc = -EIO; - else if (count == 16) { - server->secType = RawNTLMSSP; - if (server->socketUseCount.counter > 1) { - if (memcmp(server->server_GUID, - pSMBr->u.extended_response. - GUID, 16) != 0) { - cFYI(1, ("server UID changed")); + if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && + (server->capabilities & CAP_EXTENDED_SECURITY)) { + count = pSMBr->ByteCount; + if (count < 16) + rc = -EIO; + else if (count == 16) { + server->secType = RawNTLMSSP; + if (server->socketUseCount.counter > 1) { + if (memcmp + (server->server_GUID, + pSMBr->u.extended_response. + GUID, 16) != 0) { + cFYI(1, ("server UID changed")); + memcpy(server-> + server_GUID, + pSMBr->u. + extended_response. + GUID, 16); + } + } else memcpy(server->server_GUID, - pSMBr->u.extended_response.GUID, - 16); - } - } else - memcpy(server->server_GUID, - pSMBr->u.extended_response.GUID, 16); - } else { - rc = decode_negTokenInit(pSMBr->u.extended_response. - SecurityBlob, - count - 16, - &server->secType); - if(rc == 1) { - /* BB Need to fill struct for sessetup here */ - rc = -EOPNOTSUPP; + pSMBr->u.extended_response. + GUID, 16); } else { - rc = -EINVAL; + rc = decode_negTokenInit(pSMBr->u. + extended_response. + SecurityBlob, + count - 16, + &server->secType); + if(rc == 1) { + /* BB Need to fill struct for sessetup here */ + rc = -EOPNOTSUPP; + } else { + rc = -EINVAL; + } } + } else + server->capabilities &= ~CAP_EXTENDED_SECURITY; + if(sign_CIFS_PDUs == FALSE) { + if(server->secMode & SECMODE_SIGN_REQUIRED) + cERROR(1, + ("Server requires /proc/fs/cifs/PacketSigningEnabled")); + server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); + } else if(sign_CIFS_PDUs == 1) { + if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) + server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); } - } else - server->capabilities &= ~CAP_EXTENDED_SECURITY; - -#ifdef CONFIG_CIFS_WEAK_PW_HASH -signing_check: -#endif - if(sign_CIFS_PDUs == FALSE) { - if(server->secMode & SECMODE_SIGN_REQUIRED) - cERROR(1,("Server requires " - "/proc/fs/cifs/PacketSigningEnabled to be on")); - server->secMode &= - ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); - } else if(sign_CIFS_PDUs == 1) { - if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) - server->secMode &= - ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); - } else if(sign_CIFS_PDUs == 2) { - if((server->secMode & - (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { - cERROR(1,("signing required but server lacks support")); - } + } -neg_err_exit: + cifs_buf_release(pSMB); - - cFYI(1,("negprot rc %d",rc)); return rc; } @@ -1460,13 +1339,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, pSMB->hdr.smb_buf_length += count; pSMB->ByteCount = cpu_to_le16(count); - if (waitFlag) { - rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned); - } else { - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, timeout); - } cifs_stats_inc(&tcon->num_locks); if (rc) { cFYI(1, ("Send error in Lock = %d", rc)); @@ -1489,7 +1363,6 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, char *data_offset; struct cifs_posix_lock *parm_data; int rc = 0; - int timeout = 0; int bytes_returned = 0; __u16 params, param_offset, offset, byte_count, count; @@ -1509,6 +1382,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; pSMB->Flags = 0; + pSMB->Timeout = 0; pSMB->Reserved2 = 0; param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; offset = param_offset + params; @@ -1534,13 +1408,8 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, (((char *) &pSMB->hdr.Protocol) + offset); parm_data->lock_type = cpu_to_le16(lock_type); - if(waitFlag) { - timeout = 3; /* blocking operation, no timeout */ + if(waitFlag) parm_data->lock_flags = cpu_to_le16(1); - pSMB->Timeout = cpu_to_le32(-1); - } else - pSMB->Timeout = 0; - parm_data->pid = cpu_to_le32(current->tgid); parm_data->start = cpu_to_le64(pLockData->fl_start); parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ @@ -1551,14 +1420,8 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; pSMB->ByteCount = cpu_to_le16(byte_count); - if (waitFlag) { - rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned); - } else { - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, timeout); - } - + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, ("Send error in Posix Lock = %d", rc)); } else if (get_flag) { @@ -2376,7 +2239,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, } symlinkinfo[buflen] = 0; /* just in case so the caller does not go off the end of the buffer */ - cFYI(1,("readlink result - %s",symlinkinfo)); + cFYI(1,("readlink result - %s ",symlinkinfo)); } } qreparse_out: