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 ...
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user