summaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 12:00:58 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 12:00:58 -0700
commit2843483d2eb02ad104edbe8b2429fb6a39d25063 (patch)
tree7a63d1fa408ab50277666b2d73d2553ea4cfc7a7 /fs/cifs/connect.c
parent26790656d7dc34206f78eeca0f4be5caede788ce (diff)
parenta761ac579b89bc1f00212a42401398108deba65c (diff)
downloadop-kernel-dev-2843483d2eb02ad104edbe8b2429fb6a39d25063.zip
op-kernel-dev-2843483d2eb02ad104edbe8b2429fb6a39d25063.tar.gz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (51 commits) [CIFS] log better errors on failed mounts [CIFS] Return better error when server requires signing but client forbids [CIFS] fix typo [CIFS] acl support part 4 [CIFS] Fix minor problems noticed by scan [CIFS] fix bad handling of EAGAIN error on kernel_recvmsg in cifs_demultiplex_thread [CIFS] build break [CIFS] endian fixes [CIFS] endian fixes in new acl code [CIFS] Fix some endianness problems in new acl code [CIFS] missing #endif from a previous patch [CIFS] formatting fixes [CIFS] Break up unicode_sessetup string functions [CIFS] parse server_GUID in SPNEGO negProt response [CIFS] [CIFS] Fix endian conversion problem in posix mkdir [CIFS] fix build break when lanman not enabled [CIFS] remove two sparse warnings [CIFS] remove compile warnings when debug disabled [CIFS] CIFS ACL support part 3 ...
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c262
1 files changed, 139 insertions, 123 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 370866c..19ee11f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -124,7 +124,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
struct mid_q_entry *mid_entry;
spin_lock(&GlobalMid_Lock);
- if ( kthread_should_stop() ) {
+ if (kthread_should_stop()) {
/* the demux thread will exit normally
next time through the loop */
spin_unlock(&GlobalMid_Lock);
@@ -151,9 +151,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
}
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
- if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
+ if ((tcon) && (tcon->ses) && (tcon->ses->server == server))
tcon->tidStatus = CifsNeedReconnect;
- }
}
read_unlock(&GlobalSMBSeslock);
/* do not want to be sending data on a socket we are freeing */
@@ -187,7 +186,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
spin_unlock(&GlobalMid_Lock);
up(&server->tcpSem);
- while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
+ while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
try_to_freeze();
if (server->protocolType == IPV6) {
rc = ipv6_connect(&server->addr.sockAddr6,
@@ -204,7 +203,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} else {
atomic_inc(&tcpSesReconnectCount);
spin_lock(&GlobalMid_Lock);
- if ( !kthread_should_stop() )
+ if (!kthread_should_stop())
server->tcpStatus = CifsGood;
server->sequence_number = 0;
spin_unlock(&GlobalMid_Lock);
@@ -358,11 +357,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
length = tcpSesAllocCount.counter;
write_unlock(&GlobalSMBSeslock);
complete(&cifsd_complete);
- if (length > 1) {
- mempool_resize(cifs_req_poolp,
- length + cifs_min_rcv,
- GFP_KERNEL);
- }
+ if (length > 1)
+ mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+ GFP_KERNEL);
set_freezable();
while (!kthread_should_stop()) {
@@ -378,7 +375,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
} else if (isLargeBuf) {
/* we are reusing a dirty large buf, clear its start */
- memset(bigbuf, 0, sizeof (struct smb_hdr));
+ memset(bigbuf, 0, sizeof(struct smb_hdr));
}
if (smallbuf == NULL) {
@@ -391,7 +388,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
/* beginning of smb buffer is cleared in our buf_get */
} else /* if existing small buf clear beginning */
- memset(smallbuf, 0, sizeof (struct smb_hdr));
+ memset(smallbuf, 0, sizeof(struct smb_hdr));
isLargeBuf = FALSE;
isMultiRsp = FALSE;
@@ -400,11 +397,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
iov.iov_len = 4;
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
+ pdu_length = 4; /* enough to get RFC1001 header */
+incomplete_rcv:
length =
kernel_recvmsg(csocket, &smb_msg,
- &iov, 1, 4, 0 /* BB see socket.h flags */);
+ &iov, 1, pdu_length, 0 /* BB other flags? */);
- if ( kthread_should_stop() ) {
+ if (kthread_should_stop()) {
break;
} else if (server->tcpStatus == CifsNeedReconnect) {
cFYI(1, ("Reconnect after server stopped responding"));
@@ -416,7 +415,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
msleep(1); /* minimum sleep to prevent looping
allowing socket to clear and app threads to set
tcpStatus CifsNeedReconnect if server hung */
- continue;
+ if (pdu_length < 4)
+ goto incomplete_rcv;
+ else
+ continue;
} else if (length <= 0) {
if (server->tcpStatus == CifsNew) {
cFYI(1, ("tcp session abend after SMBnegprot"));
@@ -437,13 +439,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
wake_up(&server->response_q);
continue;
} else if (length < 4) {
- cFYI(1,
- ("Frame under four bytes received (%d bytes long)",
+ cFYI(1, ("less than four bytes received (%d bytes)",
length));
- cifs_reconnect(server);
- csocket = server->ssocket;
- wake_up(&server->response_q);
- continue;
+ pdu_length -= length;
+ msleep(1);
+ goto incomplete_rcv;
}
/* The right amount was read from socket - 4 bytes */
@@ -504,7 +504,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* else we have an SMB response */
if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
- (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
+ (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
cERROR(1, ("Invalid size SMB length %d pdu_length %d",
length, pdu_length+4));
cifs_reconnect(server);
@@ -528,7 +528,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
total_read += length) {
length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
pdu_length - total_read, 0);
- if ( kthread_should_stop() ||
+ if (kthread_should_stop() ||
(length == -EINTR)) {
/* then will exit */
reconnect = 2;
@@ -546,6 +546,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
allowing socket to clear and app
threads to set tcpStatus
CifsNeedReconnect if server hung*/
+ length = 0;
continue;
} else if (length <= 0) {
cERROR(1, ("Received no data, expecting %d",
@@ -631,9 +632,9 @@ multi_t2_fnd:
/* Was previous buf put in mpx struct for multi-rsp? */
if (!isMultiRsp) {
/* smb buffer will be freed by user thread */
- if (isLargeBuf) {
+ if (isLargeBuf)
bigbuf = NULL;
- } else
+ else
smallbuf = NULL;
}
wake_up_process(task_to_wake);
@@ -676,9 +677,8 @@ multi_t2_fnd:
server->ssocket = NULL;
}
/* buffer usuallly freed in free_mid - need to free it here on exit */
- if (bigbuf != NULL)
- cifs_buf_release(bigbuf);
- if (smallbuf != NULL)
+ cifs_buf_release(bigbuf);
+ if (smallbuf) /* no sense logging a debug message if NULL */
cifs_small_buf_release(smallbuf);
read_lock(&GlobalSMBSeslock);
@@ -702,9 +702,8 @@ multi_t2_fnd:
list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo,
cifsSessionList);
- if (ses->server == server) {
+ if (ses->server == server)
ses->status = CifsExiting;
- }
}
spin_lock(&GlobalMid_Lock);
@@ -714,9 +713,8 @@ multi_t2_fnd:
cFYI(1, ("Clearing Mid 0x%x - waking up ",
mid_entry->mid));
task_to_wake = mid_entry->tsk;
- if (task_to_wake) {
+ if (task_to_wake)
wake_up_process(task_to_wake);
- }
}
}
spin_unlock(&GlobalMid_Lock);
@@ -749,18 +747,15 @@ multi_t2_fnd:
list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo,
cifsSessionList);
- if (ses->server == server) {
+ if (ses->server == server)
ses->server = NULL;
- }
}
write_unlock(&GlobalSMBSeslock);
kfree(server);
- if (length > 0) {
- mempool_resize(cifs_req_poolp,
- length + cifs_min_rcv,
- GFP_KERNEL);
- }
+ if (length > 0)
+ mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+ GFP_KERNEL);
return 0;
}
@@ -1477,7 +1472,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
if (psin_server->sin_port) { /* user overrode default port */
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in), 0);
+ sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = 1;
}
@@ -1493,7 +1488,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in), 0);
+ sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = 1;
}
@@ -1502,7 +1497,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
psin_server->sin_port = htons(RFC1001_PORT);
rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
psin_server,
- sizeof (struct sockaddr_in), 0);
+ sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = 1;
}
@@ -1610,7 +1605,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
if (psin_server->sin6_port) { /* user overrode default port */
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in6), 0);
+ sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = 1;
}
@@ -1626,7 +1621,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in6), 0);
+ sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = 1;
}
@@ -1634,7 +1629,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
if (!connected) {
psin_server->sin6_port = htons(RFC1001_PORT);
rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
- psin_server, sizeof (struct sockaddr_in6), 0);
+ psin_server, sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = 1;
}
@@ -1750,7 +1745,16 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
cFYI(1, ("very large write cap"));
#endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
- cFYI(1, ("setting capabilities failed"));
+ if (vol_info == NULL) {
+ cFYI(1, ("resetting capabilities failed"));
+ } else
+ cERROR(1, ("Negotiating Unix capabilities "
+ "with the server failed. Consider "
+ "mounting with the Unix Extensions\n"
+ "disabled, if problems are found, "
+ "by specifying the nounix mount "
+ "option."));
+
}
}
}
@@ -1909,8 +1913,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
return rc;
}
- srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
- if (srvTcp == NULL) {
+ srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
+ if (!srvTcp) {
rc = -ENOMEM;
sock_release(csocket);
kfree(volume_info.UNC);
@@ -1919,9 +1923,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
FreeXid(xid);
return rc;
} else {
- memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
memcpy(&srvTcp->addr.sockAddr, &sin_server,
- sizeof (struct sockaddr_in));
+ sizeof(struct sockaddr_in));
atomic_set(&srvTcp->inFlight, 0);
/* BB Add code for ipv6 case too */
srvTcp->ssocket = csocket;
@@ -2173,8 +2176,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (tsk)
kthread_stop(tsk);
}
- } else
+ } else {
cFYI(1, ("No session or bad tcon"));
+ if ((pSesInfo->server) &&
+ (pSesInfo->server->tsk)) {
+ struct task_struct *tsk;
+ force_sig(SIGKILL,
+ pSesInfo->server->tsk);
+ tsk = pSesInfo->server->tsk;
+ if (tsk)
+ kthread_stop(tsk);
+ }
+ }
sesInfoFree(pSesInfo);
/* pSesInfo = NULL; */
}
@@ -2185,8 +2198,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
tcon->ses = pSesInfo;
/* do not care if following two calls succeed - informational */
- CIFSSMBQFSDeviceInfo(xid, tcon);
- CIFSSMBQFSAttributeInfo(xid, tcon);
+ if (!tcon->ipc) {
+ CIFSSMBQFSDeviceInfo(xid, tcon);
+ CIFSSMBQFSAttributeInfo(xid, tcon);
+ }
/* tell server which Unix caps we support */
if (tcon->ses->capabilities & CAP_UNIX)
@@ -2526,8 +2541,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
sesssetup_nomem: /* do not return an error on nomem for the info strings,
since that could make reconnection harder, and
reconnection might be needed to free memory */
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
@@ -2547,7 +2561,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
int remaining_words = 0;
int bytes_returned = 0;
int len;
- int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
+ int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
PNEGOTIATE_MESSAGE SecurityBlob;
PCHALLENGE_MESSAGE SecurityBlob2;
__u32 negotiate_flags, capabilities;
@@ -2865,15 +2879,14 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
rc = -EIO;
}
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
static int
CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
- char *ntlm_session_key, int ntlmv2_flag,
- const struct nls_table *nls_codepage)
+ char *ntlm_session_key, int ntlmv2_flag,
+ const struct nls_table *nls_codepage)
{
struct smb_hdr *smb_buffer;
struct smb_hdr *smb_buffer_response;
@@ -2886,7 +2899,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
int remaining_words = 0;
int bytes_returned = 0;
int len;
- int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
+ int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
PAUTHENTICATE_MESSAGE SecurityBlob;
__u32 negotiate_flags, capabilities;
__u16 count;
@@ -2901,8 +2914,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
return -ENOMEM;
}
smb_buffer_response = smb_buffer;
- pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
- pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
+ pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
+ pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
/* send SMBsessionSetup here */
header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
@@ -2921,7 +2934,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_EXTENDED_SECURITY;
+ CAP_EXTENDED_SECURITY;
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
capabilities |= CAP_UNICODE;
@@ -2936,15 +2949,14 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
}
pSMB->req.Capabilities = cpu_to_le32(capabilities);
- bcc_ptr = (char *) &pSMB->req.SecurityBlob;
- SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
+ bcc_ptr = (char *)&pSMB->req.SecurityBlob;
+ SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
SecurityBlob->MessageType = NtLmAuthenticate;
bcc_ptr += SecurityBlobLength;
- negotiate_flags =
- NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
- 0x80000000 | NTLMSSP_NEGOTIATE_128;
+ negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
+ 0x80000000 | NTLMSSP_NEGOTIATE_128;
if (sign_CIFS_PDUs)
negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
if (ntlmv2_flag)
@@ -2979,36 +2991,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- __u16 len =
- cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
+ __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
nls_codepage);
- len *= 2;
+ ln *= 2;
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(len);
+ cpu_to_le16(ln);
SecurityBlob->DomainName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->DomainName.Length =
- cpu_to_le16(len);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->DomainName.Length = cpu_to_le16(ln);
}
if (user == NULL) {
SecurityBlob->UserName.Buffer = 0;
SecurityBlob->UserName.Length = 0;
SecurityBlob->UserName.MaximumLength = 0;
} else {
- __u16 len =
- cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
+ __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
nls_codepage);
- len *= 2;
+ ln *= 2;
SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(len);
+ cpu_to_le16(ln);
SecurityBlob->UserName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->UserName.Length =
- cpu_to_le16(len);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->UserName.Length = cpu_to_le16(ln);
}
/* SecurityBlob->WorkstationName.Length =
@@ -3052,33 +3060,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- __u16 len;
+ __u16 ln;
negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
strncpy(bcc_ptr, domain, 63);
- len = strnlen(domain, 64);
+ ln = strnlen(domain, 64);
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(len);
+ cpu_to_le16(ln);
SecurityBlob->DomainName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->DomainName.Length = cpu_to_le16(len);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->DomainName.Length = cpu_to_le16(ln);
}
if (user == NULL) {
SecurityBlob->UserName.Buffer = 0;
SecurityBlob->UserName.Length = 0;
SecurityBlob->UserName.MaximumLength = 0;
} else {
- __u16 len;
+ __u16 ln;
strncpy(bcc_ptr, user, 63);
- len = strnlen(user, 64);
- SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(len);
+ ln = strnlen(user, 64);
+ SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
SecurityBlob->UserName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->UserName.Length = cpu_to_le16(len);
+ cpu_to_le32(SecurityBlobLength);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->UserName.Length = cpu_to_le16(ln);
}
/* BB fill in our workstation name if known BB */
@@ -3100,12 +3107,11 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
&bytes_returned, 1);
if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
- } else if ((smb_buffer_response->WordCount == 3)
- || (smb_buffer_response->WordCount == 4)) {
+/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
+ } else if ((smb_buffer_response->WordCount == 3) ||
+ (smb_buffer_response->WordCount == 4)) {
__u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len =
- le16_to_cpu(pSMBr->resp.SecurityBlobLength);
+ __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
if (action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* BB Should we set anything
in SesInfo struct ? */
@@ -3145,8 +3151,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
} else {
remaining_words = BCC(smb_buffer_response) / 2;
}
- len =
- UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
+ len = UniStrnlen((wchar_t *) bcc_ptr,
+ remaining_words - 1);
/* We look for obvious messed up bcc or strings in response so we do not go off
the end since (at least) WIN2K and Windows XP have a major bug in not null
terminating last Unicode string in response */
@@ -3230,7 +3236,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
<= BCC(smb_buffer_response)) {
if (ses->serverOS)
kfree(ses->serverOS);
- ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
+ ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
strncpy(ses->serverOS,bcc_ptr, len);
bcc_ptr += len;
@@ -3259,28 +3265,24 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr[0] = 0;
bcc_ptr++;
} else
- cFYI(1,
- ("field of length %d "
+ cFYI(1, ("field of length %d "
"extends beyond end of smb ",
len));
}
} else {
- cERROR(1,
- (" Security Blob extends beyond end "
+ cERROR(1, ("Security Blob extends beyond end "
"of SMB"));
}
} else {
cERROR(1, ("No session structure passed in."));
}
} else {
- cERROR(1,
- (" Invalid Word count %d: ",
+ cERROR(1, ("Invalid Word count %d: ",
smb_buffer_response->WordCount));
rc = -EIO;
}
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
@@ -3389,6 +3391,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr = pByteArea(smb_buffer_response);
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
/* skip service field (NB: this field is always ASCII) */
+ if (length == 3) {
+ if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+ (bcc_ptr[2] == 'C')) {
+ cFYI(1, ("IPC connection"));
+ tcon->ipc = 1;
+ }
+ } else if (length == 2) {
+ if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+ /* the most common case */
+ cFYI(1, ("disk share connection"));
+ }
+ }
bcc_ptr += length + 1;
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
@@ -3399,9 +3413,11 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 2, GFP_KERNEL);
- cifs_strfromUCS_le(tcon->nativeFileSystem,
- (__le16 *) bcc_ptr,
- length, nls_codepage);
+ if (tcon->nativeFileSystem)
+ cifs_strfromUCS_le(
+ tcon->nativeFileSystem,
+ (__le16 *) bcc_ptr,
+ length, nls_codepage);
bcc_ptr += 2 * length;
bcc_ptr[0] = 0; /* null terminate the string */
bcc_ptr[1] = 0;
@@ -3416,8 +3432,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 1, GFP_KERNEL);
- strncpy(tcon->nativeFileSystem, bcc_ptr,
- length);
+ if (tcon->nativeFileSystem)
+ strncpy(tcon->nativeFileSystem, bcc_ptr,
+ length);
}
/* else do not bother copying these information fields*/
}
@@ -3433,8 +3450,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
ses->ipc_tid = smb_buffer_response->Tid;
}
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
OpenPOWER on IntegriCloud