#include <linux/pagemap.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
+#include <linux/mempool.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include "cifspdu.h"
unsigned char *p24);
extern int cifs_inet_pton(int, const char *, void *dst);
+extern mempool_t *cifs_req_poolp;
+
struct smb_vol {
char *username;
char *password;
gid_t linux_gid;
mode_t file_mode;
mode_t dir_mode;
- int rw:1;
- int retry:1;
- int intr:1;
+ unsigned rw:1;
+ unsigned retry:1;
+ unsigned intr:1;
+ unsigned setuids:1;
+ unsigned noperm:1;
unsigned int rsize;
unsigned int wsize;
unsigned int sockopt;
if(server->tcpStatus != CifsExiting)
server->tcpStatus = CifsGood;
spin_unlock(&GlobalMid_Lock);
- atomic_set(&server->inFlight,0);
+ /* atomic_set(&server->inFlight,0);*/
wake_up(&server->response_q);
}
}
unsigned int pdu_length, total_read;
struct smb_hdr *smb_buffer = NULL;
struct msghdr smb_msg;
- mm_segment_t temp_fs;
- struct iovec iov;
+ struct kvec iov;
struct socket *csocket = server->ssocket;
struct list_head *tmp;
struct cifsSesInfo *ses;
current->flags |= PF_MEMALLOC;
server->tsk = current; /* save process info to wake at shutdown */
cFYI(1, ("Demultiplex PID: %d", current->pid));
-
- temp_fs = get_fs(); /* we must turn off socket api parm checking */
- set_fs(get_ds());
+ write_lock(&GlobalSMBSeslock);
+ atomic_inc(&tcpSesAllocCount);
+ length = tcpSesAllocCount.counter;
+ write_unlock(&GlobalSMBSeslock);
+ if(length > 1) {
+ mempool_resize(cifs_req_poolp,
+ length + CIFS_MIN_RCV_POOL,
+ GFP_KERNEL);
+ }
while (server->tcpStatus != CifsExiting) {
if (smb_buffer == NULL)
iov.iov_base = smb_buffer;
iov.iov_len = sizeof (struct smb_hdr) - 1;
/* 1 byte less above since wct is not always returned in error cases */
- smb_msg.msg_iov = &iov;
- smb_msg.msg_iovlen = 1;
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
length =
- sock_recvmsg(csocket, &smb_msg,
- sizeof (struct smb_hdr) -
- 1 /* RFC1001 header and SMB header */ ,
- MSG_PEEK /* flags see socket.h */ );
+ kernel_recvmsg(csocket, &smb_msg,
+ &iov, 1,
+ sizeof (struct smb_hdr) -
+ 1 /* RFC1001 header and SMB header */ ,
+ MSG_PEEK /* flags see socket.h */ );
if(server->tcpStatus == CifsExiting) {
break;
/* some servers kill tcp session rather than returning
smb negprot error in which case reconnecting here is
not going to help - return error to mount */
- spin_lock(&GlobalMid_Lock);
- server->tcpStatus = CifsExiting;
- spin_unlock(&GlobalMid_Lock);
- wake_up(&server->response_q);
break;
}
-
+ if(length == -EINTR) {
+ cFYI(1,("cifsd thread killed"));
+ break;
+ }
cFYI(1,("Reconnecting after unexpected peek error %d",length));
cifs_reconnect(server);
csocket = server->ssocket;
if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
iov.iov_base = smb_buffer;
iov.iov_len = 4;
- length = sock_recvmsg(csocket, &smb_msg, 4, 0);
+ length = kernel_recvmsg(csocket, &smb_msg,
+ &iov, 1, 4, 0);
cFYI(0,("Received 4 byte keep alive packet"));
} else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
- iov.iov_base = smb_buffer;
- iov.iov_len = 4;
- length = sock_recvmsg(csocket, &smb_msg, 4, 0);
+ iov.iov_base = smb_buffer;
+ iov.iov_len = 4;
+ length = kernel_recvmsg(csocket, &smb_msg,
+ &iov, 1, 4, 0);
cFYI(1,("Good RFC 1002 session rsp"));
} else if ((temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE)
&& (length == 5)) {
/* if nack on negprot (rather than
ret of smb negprot error) reconnecting
not going to help, ret error to mount */
- spin_lock(&GlobalMid_Lock);
- server->tcpStatus = CifsExiting;
- spin_unlock(&GlobalMid_Lock);
- /* wake up thread doing negprot */
- wake_up(&server->response_q);
break;
} else {
/* give server a second to
connected to port 139 (the NACK is
since we do not begin with RFC1001
session initialize frame) */
- server->addr.sockAddr.sin_port = CIFS_PORT;
+ server->addr.sockAddr.sin_port = htons(CIFS_PORT);
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
for (total_read = 0;
total_read < pdu_length;
total_read += length) {
- length = sock_recvmsg(csocket, &smb_msg,
+ length = kernel_recvmsg(csocket, &smb_msg,
+ &iov, 1,
pdu_length - total_read, 0);
if (length == 0) {
cERROR(1,
("Frame less than four bytes received %d bytes long.",
length));
if (length > 0) {
- length = sock_recvmsg(csocket, &smb_msg, length, 0); /* throw away junk frame */
+ length = kernel_recvmsg(csocket, &smb_msg,
+ &iov, 1,
+ length, 0); /* throw away junk frame */
cFYI(1,
(" with junk 0x%x in it ",
*(__u32 *) smb_buffer));
}
spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
- spin_unlock(&GlobalMid_Lock);
+ server->tsk = NULL;
atomic_set(&server->inFlight, 0);
+ spin_unlock(&GlobalMid_Lock);
/* Although there should not be any requests blocked on
this queue it can not hurt to be paranoid and try to wake up requests
that may haven been blocked when more than 50 at time were on the wire
to the same server - they now will see the session is in exit state
and get out of SendReceive. */
- wake_up_all(&server->request_q);
- server->tsk = NULL;
+ wake_up_all(&server->request_q);
+ /* give those requests time to exit */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ/8);
+
if(server->ssocket) {
sock_release(csocket);
server->ssocket = NULL;
}
- set_fs(temp_fs);
if (smb_buffer) /* buffer usually freed in free_mid - need to free it on error or exit */
cifs_buf_release(smb_buffer);
spin_unlock(&GlobalMid_Lock);
read_unlock(&GlobalSMBSeslock);
set_current_state(TASK_INTERRUPTIBLE);
- /* 1/8th of sec should be more than enough time for them to exit */
+ /* 1/8th of sec is more than enough time for them to exit */
schedule_timeout(HZ/8);
}
}
kfree(server);
- cFYI(1, ("About to exit from demultiplex thread"));
+ write_lock(&GlobalSMBSeslock);
+ atomic_dec(&tcpSesAllocCount);
+ length = tcpSesAllocCount.counter;
+ write_unlock(&GlobalSMBSeslock);
+ if(length > 0) {
+ mempool_resize(cifs_req_poolp,
+ length + CIFS_MIN_RCV_POOL,
+ GFP_KERNEL);
+ }
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ/4);
return 0;
}
if((i==15) && (value[i] != 0))
printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");
}
+ } else if (strnicmp(data, "credentials", 4) == 0) {
+ /* ignore */
} else if (strnicmp(data, "version", 3) == 0) {
/* ignore */
} else if (strnicmp(data, "rw", 2) == 0) {
vol->retry = 1;
} else if (strnicmp(data, "soft", 4) == 0) {
vol->retry = 0;
+ } else if (strnicmp(data, "perm", 4) == 0) {
+ vol->noperm = 0;
+ } else if (strnicmp(data, "noperm", 6) == 0) {
+ vol->noperm = 1;
+ } else if (strnicmp(data, "setuids", 7) == 0) {
+ vol->setuids = 1;
+ } else if (strnicmp(data, "nosetuids", 9) == 0) {
+ vol->setuids = 0;
} else if (strnicmp(data, "nohard", 6) == 0) {
vol->retry = 0;
} else if (strnicmp(data, "nosoft", 6) == 0) {
}
static struct cifsSesInfo *
-cifs_find_tcp_session(__u32 new_target_ip_addr,
+cifs_find_tcp_session(struct in_addr * target_ip_addr,
+ struct in6_addr *target_ip6_addr,
char *userName, struct TCP_Server_Info **psrvTcp)
{
struct list_head *tmp;
struct cifsSesInfo *ses;
-
*psrvTcp = NULL;
read_lock(&GlobalSMBSeslock);
+
list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
if (ses->server) {
- if (ses->server->addr.sockAddr.sin_addr.s_addr ==
- new_target_ip_addr) {
+ if((target_ip_addr &&
+ (ses->server->addr.sockAddr.sin_addr.s_addr
+ == target_ip_addr->s_addr)) || (target_ip6_addr
+ && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
+ target_ip6_addr,sizeof(*target_ip6_addr)))){
/* BB lock server and tcp session and increment use count here?? */
*psrvTcp = ses->server; /* found a match on the TCP session */
/* BB check if reconnection needed */
}
static struct cifsTconInfo *
-find_unc(__u32 new_target_ip_addr, char *uncName, char *userName)
+find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
{
struct list_head *tmp;
struct cifsTconInfo *tcon;
{
int rc = 0;
int connected = 0;
- unsigned short int orig_port = 0;
+ __be16 orig_port = 0;
if(*csocket == NULL) {
rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
/* send RFC1001 sessinit */
- if(psin_server->sin_port == htons(139)) {
+ if(psin_server->sin_port == htons(RFC1001_PORT)) {
/* some servers require RFC1001 sessinit before sending
negprot - BB check reconnection in case where second
sessinit is sent but no second negprot */
{
int rc = 0;
int connected = 0;
+ __be16 orig_port = 0;
if(*csocket == NULL) {
rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
}
if(!connected) {
+ /* save original port so we can retry user specified port
+ later if fall back ports fail this time */
+
+ orig_port = psin_server->sin6_port;
/* do not retry on the same port we just failed on */
if(psin_server->sin6_port != htons(CIFS_PORT)) {
psin_server->sin6_port = htons(CIFS_PORT);
/* give up here - unless we want to retry on different
protocol families some day */
if (!connected) {
+ if(orig_port)
+ psin_server->sin6_port = orig_port;
cFYI(1,("Error %d connecting to server via ipv6",rc));
sock_release(*csocket);
*csocket = NULL;
{
int rc = 0;
int xid;
+ int address_type = AF_INET;
struct socket *csocket = NULL;
struct sockaddr_in sin_server;
struct sockaddr_in6 sin_server6;
if (volume_info.UNCip && volume_info.UNC) {
rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);
- if(rc == 0) {
+ if(rc <= 0) {
/* not ipv4 address, try ipv6 */
rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u);
- }
+ if(rc > 0)
+ address_type = AF_INET6;
+ } else {
+ address_type = AF_INET;
+ }
- if(rc != 1) {
+ if(rc <= 0) {
/* we failed translating address */
if(volume_info.UNC)
kfree(volume_info.UNC);
}
}
- existingCifsSes =
- cifs_find_tcp_session(sin_server.sin_addr.s_addr,
- volume_info.username, &srvTcp);
+ if(address_type == AF_INET)
+ existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
+ NULL /* no ipv6 addr */,
+ volume_info.username, &srvTcp);
+ else if(address_type == AF_INET6)
+ existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
+ &sin_server6.sin6_addr,
+ volume_info.username, &srvTcp);
+ else {
+ if(volume_info.UNC)
+ kfree(volume_info.UNC);
+ if(volume_info.password)
+ kfree(volume_info.password);
+ FreeXid(xid);
+ return -EINVAL;
+ }
+
+
if (srvTcp) {
cFYI(1, ("Existing tcp session with server found "));
} else { /* create socket */
so no need to spinlock this init of tcpStatus */
srvTcp->tcpStatus = CifsNew;
init_MUTEX(&srvTcp->tcpSem);
- kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
+ rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
CLONE_FS | CLONE_FILES | CLONE_VM);
+ if(rc < 0) {
+ rc = -ENOMEM;
+ sock_release(csocket);
+ if(volume_info.UNC)
+ kfree(volume_info.UNC);
+ if(volume_info.password)
+ kfree(volume_info.password);
+ FreeXid(xid);
+ return rc;
+ } else
+ rc = 0;
memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
}
}
cifs_sb->mnt_file_mode = volume_info.file_mode;
cifs_sb->mnt_dir_mode = volume_info.dir_mode;
cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
+
+ if(volume_info.noperm)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
+ if(volume_info.setuids)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
+
tcon =
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
volume_info.username);
}
}
}
- if (pSesInfo->capabilities & CAP_LARGE_FILES) {
- cFYI(0, ("Large files supported "));
- sb->s_maxbytes = (u64) 1 << 63;
- } else
- sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
+ if(pSesInfo) {
+ if (pSesInfo->capabilities & CAP_LARGE_FILES) {
+ sb->s_maxbytes = (u64) 1 << 63;
+ } else
+ sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
+ }
/* on error free sesinfo and tcon struct if needed */
if (rc) {
+ /* if session setup failed, use count is zero but
+ we still need to free cifsd thread */
if(atomic_read(&srvTcp->socketUseCount) == 0) {
spin_lock(&GlobalMid_Lock);
srvTcp->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock);
+ if(srvTcp->tsk)
+ send_sig(SIGKILL,srvTcp->tsk,1);
}
/* If find_unc succeeded then rc == 0 so we can not end */
- if (tcon) /* up here accidently freeing someone elses tcon struct */
+ if (tcon) /* up accidently freeing someone elses tcon struct */
tconInfoFree(tcon);
if (existingCifsSes == 0) {
if (pSesInfo) {
- if (pSesInfo->server) {
- if (pSesInfo->Suid)
- CIFSSMBLogoff(xid, pSesInfo);
- if(pSesInfo->server->tsk)
+ if ((pSesInfo->server) &&
+ (pSesInfo->status == CifsGood)) {
+ int temp_rc;
+ temp_rc = CIFSSMBLogoff(xid, pSesInfo);
+ /* if the socketUseCount is now zero */
+ if((temp_rc == -ESHUTDOWN) &&
+ (pSesInfo->server->tsk))
send_sig(SIGKILL,pSesInfo->server->tsk,1);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 4); /* give captive thread time to exit */
} else
cFYI(1, ("No session or bad tcon"));
sesInfoFree(pSesInfo);
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
- char *user = ses->userName;
- char *domain = ses->domainName;
+ char *user;
+ char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
int len;
+ __u32 capabilities;
+ __u16 count;
cFYI(1, ("In sesssetup "));
-
+ if(ses == NULL)
+ return -EINVAL;
+ user = ses->userName;
+ domain = ses->domainName;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
return -ENOMEM;
/* send SMBsessionSetup here */
header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- 0 /* no tCon exists yet */ , 13 /* wct */ );
+ NULL /* no tCon exists yet */ , 13 /* wct */ );
pSMB->req_no_secext.AndXCommand = 0xFF;
pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- pSMB->req_no_secext.Capabilities =
- CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS;
+ capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS;
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- pSMB->req_no_secext.Capabilities |= CAP_UNICODE;
+ capabilities |= CAP_UNICODE;
}
if (ses->capabilities & CAP_STATUS32) {
smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- pSMB->req_no_secext.Capabilities |= CAP_STATUS32;
+ capabilities |= CAP_STATUS32;
}
if (ses->capabilities & CAP_DFS) {
smb_buffer->Flags2 |= SMBFLG2_DFS;
- pSMB->req_no_secext.Capabilities |= CAP_DFS;
+ capabilities |= CAP_DFS;
}
- pSMB->req_no_secext.Capabilities =
- cpu_to_le32(pSMB->req_no_secext.Capabilities);
+ pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
/* pSMB->req_no_secext.CaseInsensitivePasswordLength =
CIFS_SESSION_KEY_SIZE; */
pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
}
- BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += BCC(smb_buffer);
- BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
+ count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
+ smb_buffer->smb_buf_length += count;
+ pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
&bytes_returned, 1);
/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
} else if ((smb_buffer_response->WordCount == 3)
|| (smb_buffer_response->WordCount == 4)) {
- pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
- if (pSMBr->resp.Action & GUEST_LOGIN)
+ __u16 action = le16_to_cpu(pSMBr->resp.Action);
+ __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
+ if (action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */
- if (ses) {
- ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
- cFYI(1, ("UID = %d ", ses->Suid));
+ ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
+ cFYI(1, ("UID = %d ", ses->Suid));
/* response can have either 3 or 4 word count - Samba sends 3 */
- bcc_ptr = pByteArea(smb_buffer_response);
- if ((pSMBr->resp.hdr.WordCount == 3)
- || ((pSMBr->resp.hdr.WordCount == 4)
- && (pSMBr->resp.SecurityBlobLength <
- pSMBr->resp.ByteCount))) {
- if (pSMBr->resp.hdr.WordCount == 4)
- bcc_ptr +=
- pSMBr->resp.SecurityBlobLength;
-
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- if ((long) (bcc_ptr) % 2) {
- remaining_words =
- (BCC(smb_buffer_response)
- - 1) / 2;
- bcc_ptr++; /* Unicode strings must be word aligned */
- } else {
- remaining_words =
- BCC
- (smb_buffer_response) / 2;
- }
- len =
- UniStrnlen((wchar_t *) bcc_ptr,
- remaining_words - 1);
+ bcc_ptr = pByteArea(smb_buffer_response);
+ if ((pSMBr->resp.hdr.WordCount == 3)
+ || ((pSMBr->resp.hdr.WordCount == 4)
+ && (blob_len < pSMBr->resp.ByteCount))) {
+ if (pSMBr->resp.hdr.WordCount == 4)
+ bcc_ptr += blob_len;
+
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
+ if ((long) (bcc_ptr) % 2) {
+ remaining_words =
+ (BCC(smb_buffer_response) - 1) /2;
+ bcc_ptr++; /* Unicode strings must be word aligned */
+ } else {
+ remaining_words =
+ BCC(smb_buffer_response) / 2;
+ }
+ 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 */
- ses->serverOS = cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverOS,
- (wchar_t *)bcc_ptr, len,nls_codepage);
+ ses->serverOS = cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
+ cifs_strfromUCS_le(ses->serverOS,
+ (wchar_t *)bcc_ptr, len,nls_codepage);
+ bcc_ptr += 2 * (len + 1);
+ remaining_words -= len + 1;
+ ses->serverOS[2 * len] = 0;
+ ses->serverOS[1 + (2 * len)] = 0;
+ if (remaining_words > 0) {
+ len = UniStrnlen((wchar_t *)bcc_ptr,
+ remaining_words-1);
+ ses->serverNOS =cifs_kcalloc(2 * (len + 1),GFP_KERNEL);
+ cifs_strfromUCS_le(ses->serverNOS,
+ (wchar_t *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1);
+ ses->serverNOS[2 * len] = 0;
+ ses->serverNOS[1 + (2 * len)] = 0;
remaining_words -= len + 1;
- ses->serverOS[2 * len] = 0;
- ses->serverOS[1 + (2 * len)] = 0;
if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *)bcc_ptr,
- remaining_words
- - 1);
- ses->serverNOS =cifs_kcalloc(2 * (len + 1),GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverNOS,
- (wchar_t *)bcc_ptr,len,nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverNOS[2 * len] = 0;
- ses->serverNOS[1 + (2 * len)] = 0;
- remaining_words -= len + 1;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
+ len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
/* last string is not always null terminated (for e.g. for Windows XP & 2000) */
- ses->serverDomain =
- cifs_kcalloc(2*(len+1),GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverDomain,
- (wchar_t *)bcc_ptr,len,nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverDomain[2*len] = 0;
- ses->serverDomain[1+(2*len)] = 0;
- } /* else no more room so create dummy domain string */
- else
- ses->serverDomain =
- cifs_kcalloc(2,
- GFP_KERNEL);
- } else { /* no room so create dummy domain and NOS string */
ses->serverDomain =
- cifs_kcalloc(2, GFP_KERNEL);
- ses->serverNOS =
- cifs_kcalloc(2, GFP_KERNEL);
- }
- } else { /* ASCII */
- len = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + len) - (long)
- pByteArea(smb_buffer_response)
+ cifs_kcalloc(2*(len+1),GFP_KERNEL);
+ cifs_strfromUCS_le(ses->serverDomain,
+ (wchar_t *)bcc_ptr,len,nls_codepage);
+ bcc_ptr += 2 * (len + 1);
+ ses->serverDomain[2*len] = 0;
+ ses->serverDomain[1+(2*len)] = 0;
+ } /* else no more room so create dummy domain string */
+ else
+ ses->serverDomain =
+ cifs_kcalloc(2,
+ GFP_KERNEL);
+ } else { /* no room so create dummy domain and NOS string */
+ ses->serverDomain =
+ cifs_kcalloc(2, GFP_KERNEL);
+ ses->serverNOS =
+ cifs_kcalloc(2, GFP_KERNEL);
+ }
+ } else { /* ASCII */
+ len = strnlen(bcc_ptr, 1024);
+ if (((long) bcc_ptr + len) - (long)
+ pByteArea(smb_buffer_response)
<= BCC(smb_buffer_response)) {
- ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL);
- strncpy(ses->serverOS,bcc_ptr, len);
+ ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL);
+ strncpy(ses->serverOS,bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0; /* null terminate the string */
- bcc_ptr++;
+ bcc_ptr += len;
+ bcc_ptr[0] = 0; /* null terminate the string */
+ bcc_ptr++;
- len = strnlen(bcc_ptr, 1024);
- ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL);
- strncpy(ses->serverNOS, bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
+ len = strnlen(bcc_ptr, 1024);
+ ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL);
+ strncpy(ses->serverNOS, bcc_ptr, len);
+ bcc_ptr += len;
+ bcc_ptr[0] = 0;
+ bcc_ptr++;
- len = strnlen(bcc_ptr, 1024);
- ses->serverDomain = cifs_kcalloc(len + 1,GFP_KERNEL);
- strncpy(ses->serverDomain, bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
- } else
- cFYI(1,
- ("Variable field of length %d extends beyond end of smb ",
- len));
- }
- } else {
- cERROR(1,
- (" Security Blob Length extends beyond end of SMB"));
+ len = strnlen(bcc_ptr, 1024);
+ ses->serverDomain = cifs_kcalloc(len + 1,GFP_KERNEL);
+ strncpy(ses->serverDomain, bcc_ptr, len);
+ bcc_ptr += len;
+ bcc_ptr[0] = 0;
+ bcc_ptr++;
+ } else
+ cFYI(1,
+ ("Variable field of length %d extends beyond end of smb ",
+ len));
}
} else {
- cERROR(1, ("No session structure passed in."));
+ cERROR(1,
+ (" Security Blob Length extends beyond end of SMB"));
}
} else {
cERROR(1,
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
- char *user = ses->userName;
- char *domain = ses->domainName;
+ char *user;
+ char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
int len;
+ __u32 capabilities;
+ __u16 count;
cFYI(1, ("In spnego sesssetup "));
+ if(ses == NULL)
+ return -EINVAL;
+ user = ses->userName;
+ domain = ses->domainName;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
/* send SMBsessionSetup here */
header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- 0 /* no tCon exists yet */ , 12 /* wct */ );
+ NULL /* no tCon exists yet */ , 12 /* wct */ );
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
pSMB->req.AndXCommand = 0xFF;
pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- pSMB->req.Capabilities =
- CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
+ capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_EXTENDED_SECURITY;
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- pSMB->req.Capabilities |= CAP_UNICODE;
+ capabilities |= CAP_UNICODE;
}
if (ses->capabilities & CAP_STATUS32) {
smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- pSMB->req.Capabilities |= CAP_STATUS32;
+ capabilities |= CAP_STATUS32;
}
if (ses->capabilities & CAP_DFS) {
smb_buffer->Flags2 |= SMBFLG2_DFS;
- pSMB->req.Capabilities |= CAP_DFS;
+ capabilities |= CAP_DFS;
}
- pSMB->req.Capabilities = cpu_to_le32(pSMB->req.Capabilities);
+ pSMB->req.Capabilities = cpu_to_le32(capabilities);
pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
bcc_ptr = pByteArea(smb_buffer);
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
}
- BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += BCC(smb_buffer);
- BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
+ count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
+ smb_buffer->smb_buf_length += count;
+ pSMB->req.ByteCount = cpu_to_le16(count);
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
&bytes_returned, 1);
/* 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)) {
- pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
- pSMBr->resp.SecurityBlobLength =
+ __u16 action = le16_to_cpu(pSMBr->resp.Action);
+ __u16 blob_len =
le16_to_cpu(pSMBr->resp.SecurityBlobLength);
- if (pSMBr->resp.Action & GUEST_LOGIN)
+ if (action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
if (ses) {
ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
if ((pSMBr->resp.hdr.WordCount == 3)
|| ((pSMBr->resp.hdr.WordCount == 4)
- && (pSMBr->resp.SecurityBlobLength <
+ && (blob_len <
pSMBr->resp.ByteCount))) {
if (pSMBr->resp.hdr.WordCount == 4) {
bcc_ptr +=
- pSMBr->resp.SecurityBlobLength;
+ blob_len;
cFYI(1,
("Security Blob Length %d ",
- pSMBr->resp.SecurityBlobLength));
+ blob_len));
}
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
- char *domain = ses->domainName;
+ char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
PNEGOTIATE_MESSAGE SecurityBlob;
PCHALLENGE_MESSAGE SecurityBlob2;
+ __u32 negotiate_flags, capabilities;
+ __u16 count;
cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
+ if(ses == NULL)
+ return -EINVAL;
+ domain = ses->domainName;
*pNTLMv2_flag = FALSE;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
/* send SMBsessionSetup here */
header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- 0 /* no tCon exists yet */ , 12 /* wct */ );
+ NULL /* no tCon exists yet */ , 12 /* wct */ );
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- pSMB->req.Capabilities =
- CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
+ capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_EXTENDED_SECURITY;
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- pSMB->req.Capabilities |= CAP_UNICODE;
+ capabilities |= CAP_UNICODE;
}
if (ses->capabilities & CAP_STATUS32) {
smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- pSMB->req.Capabilities |= CAP_STATUS32;
+ capabilities |= CAP_STATUS32;
}
if (ses->capabilities & CAP_DFS) {
smb_buffer->Flags2 |= SMBFLG2_DFS;
- pSMB->req.Capabilities |= CAP_DFS;
+ capabilities |= CAP_DFS;
}
- pSMB->req.Capabilities = cpu_to_le32(pSMB->req.Capabilities);
+ pSMB->req.Capabilities = cpu_to_le32(capabilities);
bcc_ptr = (char *) &pSMB->req.SecurityBlob;
SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
SecurityBlob->MessageType = NtLmNegotiate;
- SecurityBlob->NegotiateFlags =
+ negotiate_flags =
NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
/* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
if(sign_CIFS_PDUs)
- SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
+ negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
if(ntlmv2_support)
- SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
+ negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
/* setup pointers to domain name and workstation name */
bcc_ptr += SecurityBlobLength;
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- SecurityBlob->NegotiateFlags |=
- NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
+ __u16 len;
+ negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
strncpy(bcc_ptr, domain, 63);
- SecurityBlob->DomainName.Length = strnlen(domain, 64);
+ len = strnlen(domain, 64);
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(SecurityBlob->DomainName.Length);
+ cpu_to_le16(len);
SecurityBlob->DomainName.Buffer =
cpu_to_le32((long) &SecurityBlob->
DomainString -
(long) &SecurityBlob->Signature);
- bcc_ptr += SecurityBlob->DomainName.Length;
- SecurityBlobLength += SecurityBlob->DomainName.Length;
+ bcc_ptr += len;
+ SecurityBlobLength += len;
SecurityBlob->DomainName.Length =
- cpu_to_le16(SecurityBlob->DomainName.Length);
+ cpu_to_le16(len);
}
if (ses->capabilities & CAP_UNICODE) {
if ((long) bcc_ptr % 2) {
bcc_ptr++; /* empty domain field */
*bcc_ptr = 0;
}
- SecurityBlob->NegotiateFlags =
- cpu_to_le32(SecurityBlob->NegotiateFlags);
+ SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
- BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += BCC(smb_buffer);
- BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
+ count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
+ smb_buffer->smb_buf_length += count;
+ pSMB->req.ByteCount = cpu_to_le16(count);
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
&bytes_returned, 1);
if (smb_buffer_response->Status.CifsError ==
- (NT_STATUS_MORE_PROCESSING_REQUIRED))
+ cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
rc = 0;
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)) {
- pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
- pSMBr->resp.SecurityBlobLength =
- le16_to_cpu(pSMBr->resp.SecurityBlobLength);
- if (pSMBr->resp.Action & GUEST_LOGIN)
+ __u16 action = le16_to_cpu(pSMBr->resp.Action);
+ __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
+
+ if (action & GUEST_LOGIN)
cFYI(1, (" Guest login"));
/* Do we want to set anything in SesInfo struct when guest login? */
cFYI(1, ("UID = %d ", ses->Suid));
if ((pSMBr->resp.hdr.WordCount == 3)
|| ((pSMBr->resp.hdr.WordCount == 4)
- && (pSMBr->resp.SecurityBlobLength <
+ && (blob_len <
pSMBr->resp.ByteCount))) {
+
if (pSMBr->resp.hdr.WordCount == 4) {
- bcc_ptr +=
- pSMBr->resp.SecurityBlobLength;
+ bcc_ptr += blob_len;
cFYI(1,
("Security Blob Length %d ",
- pSMBr->resp.SecurityBlobLength));
+ blob_len));
}
cFYI(1, ("NTLMSSP Challenge rcvd "));
memcpy(ses->server->cryptKey,
SecurityBlob2->Challenge,
CIFS_CRYPTO_KEY_SIZE);
- if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2)
+ if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
*pNTLMv2_flag = TRUE;
if((SecurityBlob2->NegotiateFlags &
- NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
+ cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
|| (sign_CIFS_PDUs > 1))
ses->server->secMode |=
SECMODE_SIGN_REQUIRED;
if ((SecurityBlob2->NegotiateFlags &
- NTLMSSP_NEGOTIATE_SIGN) && (sign_CIFS_PDUs))
+ cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
ses->server->secMode |=
SECMODE_SIGN_ENABLED;
return rc;
}
-
static int
CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *ntlm_session_key, int ntlmv2_flag,
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
- char *user = ses->userName;
- char *domain = ses->domainName;
+ char *user;
+ char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
int len;
int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
PAUTHENTICATE_MESSAGE SecurityBlob;
+ __u32 negotiate_flags, capabilities;
+ __u16 count;
cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
-
+ if(ses == NULL)
+ return -EINVAL;
+ user = ses->userName;
+ domain = ses->domainName;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
return -ENOMEM;
/* send SMBsessionSetup here */
header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- 0 /* no tCon exists yet */ , 12 /* wct */ );
+ NULL /* no tCon exists yet */ , 12 /* wct */ );
pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
pSMB->req.AndXCommand = 0xFF;
if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- pSMB->req.Capabilities =
- CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
+ capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_EXTENDED_SECURITY;
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- pSMB->req.Capabilities |= CAP_UNICODE;
+ capabilities |= CAP_UNICODE;
}
if (ses->capabilities & CAP_STATUS32) {
smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- pSMB->req.Capabilities |= CAP_STATUS32;
+ capabilities |= CAP_STATUS32;
}
if (ses->capabilities & CAP_DFS) {
smb_buffer->Flags2 |= SMBFLG2_DFS;
- pSMB->req.Capabilities |= CAP_DFS;
+ capabilities |= CAP_DFS;
}
- pSMB->req.Capabilities = cpu_to_le32(pSMB->req.Capabilities);
+ pSMB->req.Capabilities = cpu_to_le32(capabilities);
bcc_ptr = (char *) &pSMB->req.SecurityBlob;
SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
SecurityBlob->MessageType = NtLmAuthenticate;
bcc_ptr += SecurityBlobLength;
- SecurityBlob->NegotiateFlags =
+ negotiate_flags =
NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
0x80000000 | NTLMSSP_NEGOTIATE_128;
if(sign_CIFS_PDUs)
- SecurityBlob->NegotiateFlags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
+ negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
if(ntlmv2_flag)
- SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
+ negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
/* setup pointers to domain name and workstation name */
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- SecurityBlob->DomainName.Length =
+ __u16 len =
cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
nls_codepage);
- SecurityBlob->DomainName.Length *= 2;
+ len *= 2;
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(SecurityBlob->DomainName.Length);
+ cpu_to_le16(len);
SecurityBlob->DomainName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += SecurityBlob->DomainName.Length;
- SecurityBlobLength += SecurityBlob->DomainName.Length;
+ bcc_ptr += len;
+ SecurityBlobLength += len;
SecurityBlob->DomainName.Length =
- cpu_to_le16(SecurityBlob->DomainName.Length);
+ cpu_to_le16(len);
}
if (user == NULL) {
SecurityBlob->UserName.Buffer = 0;
SecurityBlob->UserName.Length = 0;
SecurityBlob->UserName.MaximumLength = 0;
} else {
- SecurityBlob->UserName.Length =
+ __u16 len =
cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64,
nls_codepage);
- SecurityBlob->UserName.Length *= 2;
+ len *= 2;
SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(SecurityBlob->UserName.Length);
+ cpu_to_le16(len);
SecurityBlob->UserName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += SecurityBlob->UserName.Length;
- SecurityBlobLength += SecurityBlob->UserName.Length;
+ bcc_ptr += len;
+ SecurityBlobLength += len;
SecurityBlob->UserName.Length =
- cpu_to_le16(SecurityBlob->UserName.Length);
+ cpu_to_le16(len);
}
/* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage);
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- SecurityBlob->NegotiateFlags |=
- NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
+ __u16 len;
+ negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
strncpy(bcc_ptr, domain, 63);
- SecurityBlob->DomainName.Length = strnlen(domain, 64);
+ len = strnlen(domain, 64);
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(SecurityBlob->DomainName.Length);
+ cpu_to_le16(len);
SecurityBlob->DomainName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += SecurityBlob->DomainName.Length;
- SecurityBlobLength += SecurityBlob->DomainName.Length;
- SecurityBlob->DomainName.Length =
- cpu_to_le16(SecurityBlob->DomainName.Length);
+ bcc_ptr += len;
+ SecurityBlobLength += len;
+ SecurityBlob->DomainName.Length = cpu_to_le16(len);
}
if (user == NULL) {
SecurityBlob->UserName.Buffer = 0;
SecurityBlob->UserName.Length = 0;
SecurityBlob->UserName.MaximumLength = 0;
} else {
+ __u16 len;
strncpy(bcc_ptr, user, 63);
- SecurityBlob->UserName.Length = strnlen(user, 64);
+ len = strnlen(user, 64);
SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(SecurityBlob->UserName.Length);
+ cpu_to_le16(len);
SecurityBlob->UserName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += SecurityBlob->UserName.Length;
- SecurityBlobLength += SecurityBlob->UserName.Length;
- SecurityBlob->UserName.Length =
- cpu_to_le16(SecurityBlob->UserName.Length);
+ bcc_ptr += len;
+ SecurityBlobLength += len;
+ SecurityBlob->UserName.Length = cpu_to_le16(len);
}
/* BB fill in our workstation name if known BB */
bcc_ptr++; /* null domain */
*bcc_ptr = 0;
}
- SecurityBlob->NegotiateFlags =
- cpu_to_le32(SecurityBlob->NegotiateFlags);
+ SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
- BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += BCC(smb_buffer);
- BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
+ count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
+ smb_buffer->smb_buf_length += count;
+ pSMB->req.ByteCount = cpu_to_le16(count);
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
&bytes_returned, 1);
/* 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)) {
- pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
- pSMBr->resp.SecurityBlobLength =
+ __u16 action = le16_to_cpu(pSMBr->resp.Action);
+ __u16 blob_len =
le16_to_cpu(pSMBr->resp.SecurityBlobLength);
- if (pSMBr->resp.Action & GUEST_LOGIN)
+ if (action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
/* if(SecurityBlob2->MessageType != NtLm??){
cFYI("Unexpected message type on auth response is %d "));
/* response can have either 3 or 4 word count - Samba sends 3 */
if ((pSMBr->resp.hdr.WordCount == 3)
|| ((pSMBr->resp.hdr.WordCount == 4)
- && (pSMBr->resp.SecurityBlobLength <
+ && (blob_len <
pSMBr->resp.ByteCount))) {
if (pSMBr->resp.hdr.WordCount == 4) {
bcc_ptr +=
- pSMBr->resp.SecurityBlobLength;
+ blob_len;
cFYI(1,
("Security Blob Length %d ",
- pSMBr->resp.SecurityBlobLength));
+ blob_len));
}
cFYI(1,
struct smb_hdr *smb_buffer_response;
TCONX_REQ *pSMB;
TCONX_RSP *pSMBr;
- char *bcc_ptr;
+ unsigned char *bcc_ptr;
int rc = 0;
int length;
+ __u16 count;
if (ses == NULL)
return -EIO;
smb_buffer_response = smb_buffer;
header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
- 0 /*no tid */ , 4 /*wct */ );
+ NULL /*no tid */ , 4 /*wct */ );
smb_buffer->Uid = ses->Suid;
pSMB = (TCONX_REQ *) smb_buffer;
pSMBr = (TCONX_RSP *) smb_buffer_response;
pSMB->AndXCommand = 0xFF;
pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
- bcc_ptr = &(pSMB->Password[0]);
+ bcc_ptr = &pSMB->Password[0];
bcc_ptr++; /* skip password */
if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
strcpy(bcc_ptr, "?????");
bcc_ptr += strlen("?????");
bcc_ptr += 1;
- BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += BCC(smb_buffer);
- BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
+ count = bcc_ptr - &pSMB->Password[0];
+ pSMB->hdr.smb_buf_length += count;
+ pSMB->ByteCount = cpu_to_le16(count);
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
/* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
/* above now done in SendReceive */
if ((rc == 0) && (tcon != NULL)) {
- tcon->tidStatus = CifsGood;
+ tcon->tidStatus = CifsGood;
tcon->tid = smb_buffer_response->Tid;
bcc_ptr = pByteArea(smb_buffer_response);
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
length = UniStrnlen((wchar_t *) bcc_ptr, 512);
- if (((long) bcc_ptr + (2 * length)) -
- (long) pByteArea(smb_buffer_response) <=
+ if ((bcc_ptr + (2 * length)) -
+ pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
if(tcon->nativeFileSystem)
kfree(tcon->nativeFileSystem);
/* else do not bother copying these informational fields */
} else {
length = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + length) -
- (long) pByteArea(smb_buffer_response) <=
+ if ((bcc_ptr + length) -
+ pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
if(tcon->nativeFileSystem)
kfree(tcon->nativeFileSystem);
int rc = 0;
int xid;
struct cifsSesInfo *ses = NULL;
+ struct task_struct *cifsd_task;
xid = GetXid();
}
tconInfoFree(cifs_sb->tcon);
if ((ses) && (ses->server)) {
+ /* save off task so we do not refer to ses later */
+ cifsd_task = ses->server->tsk;
cFYI(1, ("About to do SMBLogoff "));
rc = CIFSSMBLogoff(xid, ses);
if (rc == -EBUSY) {
FreeXid(xid);
return 0;
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 4); /* give captive thread time to exit */
- if((ses->server) && (ses->server->ssocket)) {
- cFYI(1,("Waking up socket by sending it signal "));
- send_sig(SIGKILL,ses->server->tsk,1);
- }
+ } else if (rc == -ESHUTDOWN) {
+ cFYI(1,("Waking up socket by sending it signal"));
+ send_sig(SIGKILL,cifsd_task,1);
+ rc = 0;
+ } /* else - we have an smb session
+ left on this socket do not kill cifsd */
} else
cFYI(1, ("No session or bad tcon"));
}