static DECLARE_COMPLETION(cifsd_complete);
+extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
+ unsigned char *p24);
extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24);
gid_t linux_gid;
mode_t file_mode;
mode_t dir_mode;
- unsigned secFlg;
unsigned rw:1;
unsigned retry:1;
unsigned intr:1;
unsigned remap:1; /* set to remap seven reserved chars in filenames */
unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
unsigned sfu_emul:1;
+ unsigned krb5:1;
+ unsigned ntlm:1;
+ unsigned ntlmv2:1;
unsigned nullauth:1; /* attempt to authenticate with null user */
+ unsigned sign:1;
+ unsigned seal:1; /* encrypt */
unsigned nocase; /* request case insensitive filenames */
unsigned nobrl; /* disable sending byte range locks to srv */
unsigned int rsize;
while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
{
- try_to_freeze();
if(server->protocolType == IPV6) {
rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
} else {
continue;
if (bigbuf == NULL) {
bigbuf = cifs_buf_get();
- if (!bigbuf) {
- cERROR(1, ("No memory for large SMB response"));
+ if(bigbuf == NULL) {
+ cERROR(1,("No memory for large SMB response"));
msleep(3000);
/* retry will check if exiting */
continue;
}
- } else if (isLargeBuf) {
- /* we are reusing a dirty large buf, clear its start */
+ } else if(isLargeBuf) {
+ /* we are reusing a dirtry large buf, clear its start */
memset(bigbuf, 0, sizeof (struct smb_hdr));
}
if (smallbuf == NULL) {
smallbuf = cifs_small_buf_get();
- if (!smallbuf) {
- cERROR(1, ("No memory for SMB response"));
+ if(smallbuf == NULL) {
+ cERROR(1,("No memory for SMB response"));
msleep(1000);
/* retry will check if exiting */
continue;
kernel_recvmsg(csocket, &smb_msg,
&iov, 1, 4, 0 /* BB see socket.h flags */);
- if (server->tcpStatus == CifsExiting) {
+ if(server->tcpStatus == CifsExiting) {
break;
} else if (server->tcpStatus == CifsNeedReconnect) {
- cFYI(1, ("Reconnect after server stopped responding"));
+ cFYI(1,("Reconnect after server stopped responding"));
cifs_reconnect(server);
- cFYI(1, ("call to reconnect done"));
+ cFYI(1,("call to reconnect done"));
csocket = server->ssocket;
continue;
} else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
tcpStatus CifsNeedReconnect if server hung */
continue;
} else if (length <= 0) {
- if (server->tcpStatus == CifsNew) {
- cFYI(1, ("tcp session abend after SMBnegprot"));
+ if(server->tcpStatus == CifsNew) {
+ cFYI(1,("tcp session abend after SMBnegprot"));
/* some servers kill the TCP session rather than
returning an SMB negprot error, in which
case reconnecting here is not going to help,
and so simply return error to mount */
break;
}
- if (!try_to_freeze() && (length == -EINTR)) {
+ if(length == -EINTR) {
cFYI(1,("cifsd thread killed"));
break;
}
/* merge response - fix up 1st*/
if(coalesce_t2(smb_buffer,
mid_entry->resp_buf)) {
- mid_entry->multiRsp = 1;
break;
} else {
/* all parts received */
- mid_entry->multiEnd = 1;
goto multi_t2_fnd;
}
} else {
#ifdef CONFIG_CIFS_STATS2
mid_entry->when_received = jiffies;
#endif
- /* so we do not time out requests to server
- which is still responding (since server could
- be busy but not dead) */
- server->lstrp = jiffies;
break;
}
}
wake_up_process(task_to_wake);
} else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
&& (isMultiRsp == FALSE)) {
- cERROR(1, ("No task to wake, unknown frame rcvd! NumMids %d", midCount.counter));
+ cERROR(1, ("No task to wake, unknown frame rcvd!"));
cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
sizeof(struct smb_hdr));
-#ifdef CONFIG_CIFS_DEBUG2
- cifs_dump_detail(smb_buffer);
- cifs_dump_mids(server);
-#endif /* CIFS_DEBUG2 */
-
}
} /* end while !EXITING */
/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
vol->rw = TRUE;
+ vol->ntlm = TRUE;
/* default is always to request posix paths. */
vol->posix_paths = 1;
cERROR(1,("no security value specified"));
continue;
} else if (strnicmp(value, "krb5i", 5) == 0) {
- vol->secFlg |= CIFSSEC_MAY_KRB5 |
- CIFSSEC_MUST_SIGN;
+ vol->sign = 1;
+ vol->krb5 = 1;
} else if (strnicmp(value, "krb5p", 5) == 0) {
- /* vol->secFlg |= CIFSSEC_MUST_SEAL |
- CIFSSEC_MAY_KRB5; */
+ /* vol->seal = 1;
+ vol->krb5 = 1; */
cERROR(1,("Krb5 cifs privacy not supported"));
return 1;
} else if (strnicmp(value, "krb5", 4) == 0) {
- vol->secFlg |= CIFSSEC_MAY_KRB5;
+ vol->krb5 = 1;
} else if (strnicmp(value, "ntlmv2i", 7) == 0) {
- vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
- CIFSSEC_MUST_SIGN;
+ vol->ntlmv2 = 1;
+ vol->sign = 1;
} else if (strnicmp(value, "ntlmv2", 6) == 0) {
- vol->secFlg |= CIFSSEC_MAY_NTLMV2;
+ vol->ntlmv2 = 1;
} else if (strnicmp(value, "ntlmi", 5) == 0) {
- vol->secFlg |= CIFSSEC_MAY_NTLM |
- CIFSSEC_MUST_SIGN;
+ vol->ntlm = 1;
+ vol->sign = 1;
} else if (strnicmp(value, "ntlm", 4) == 0) {
/* ntlm is default so can be turned off too */
- vol->secFlg |= CIFSSEC_MAY_NTLM;
+ vol->ntlm = 1;
} else if (strnicmp(value, "nontlm", 6) == 0) {
- /* BB is there a better way to do this? */
- vol->secFlg |= CIFSSEC_MAY_NTLMV2;
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- } else if (strnicmp(value, "lanman", 6) == 0) {
- vol->secFlg |= CIFSSEC_MAY_LANMAN;
-#endif
+ vol->ntlm = 0;
} else if (strnicmp(value, "none", 4) == 0) {
- vol->nullauth = 1;
+ vol->nullauth = 1;
} else {
cERROR(1,("bad security option: %s", value));
return 1;
}
/* BB are there cases in which a comma can be valid in
a domain name and need special handling? */
- if (strnlen(value, 256) < 256) {
+ if (strnlen(value, 65) < 65) {
vol->domainname = value;
cFYI(1, ("Domain name set"));
} else {
vol->no_psx_acl = 0;
} else if (strnicmp(data, "noacl",5) == 0) {
vol->no_psx_acl = 1;
- } else if (strnicmp(data, "sign",4) == 0) {
- vol->secFlg |= CIFSSEC_MUST_SIGN;
-/* } else if (strnicmp(data, "seal",4) == 0) {
- vol->secFlg |= CIFSSEC_MUST_SEAL; */
} else if (strnicmp(data, "direct",6) == 0) {
vol->direct_io = 1;
} else if (strnicmp(data, "forcedirectio",13) == 0) {
read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalTreeConnectionList) {
- cFYI(1, ("Next tcon"));
+ cFYI(1, ("Next tcon - "));
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if (tcon->ses) {
if (tcon->ses->server) {
cFYI(1,
- ("old ip addr: %x == new ip %x ?",
+ (" old ip addr: %x == new ip %x ?",
tcon->ses->server->addr.sockAddr.sin_addr.
s_addr, new_target_ip_addr));
if (tcon->ses->server->addr.sockAddr.sin_addr.
s_addr == new_target_ip_addr) {
- /* BB lock tcon, server and tcp session and increment use count here? */
+ /* BB lock tcon and server and tcp session and increment use count here? */
/* found a match on the TCP session */
/* BB check if reconnection needed */
- cFYI(1,("IP match, old UNC: %s new: %s",
+ cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
tcon->treeName, uncName));
if (strncmp
(tcon->treeName, uncName,
MAX_TREE_SIZE) == 0) {
cFYI(1,
- ("and old usr: %s new: %s",
+ ("Matched UNC, old user: %s == new: %s ?",
tcon->treeName, uncName));
if (strncmp
(tcon->ses->userName,
userName,
MAX_USERNAME_SIZE) == 0) {
read_unlock(&GlobalSMBSeslock);
- /* matched smb session
- (user name */
- return tcon;
+ return tcon;/* also matched user (smb session)*/
}
}
}
if (volume_info.username)
strncpy(pSesInfo->userName,
volume_info.username,MAX_USERNAME_SIZE);
- if (volume_info.domainname) {
- int len = strlen(volume_info.domainname);
- pSesInfo->domainName =
- kmalloc(len + 1, GFP_KERNEL);
- if(pSesInfo->domainName)
- strcpy(pSesInfo->domainName,
- volume_info.domainname);
- }
+ if (volume_info.domainname)
+ strncpy(pSesInfo->domainName,
+ volume_info.domainname,MAX_USERNAME_SIZE);
pSesInfo->linux_uid = volume_info.linux_uid;
- pSesInfo->overrideSecFlg = volume_info.secFlg;
down(&pSesInfo->sesSem);
- /* BB FIXME need to pass vol->secFlgs BB */
rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
up(&pSesInfo->sesSem);
if(!rc)
}
cFYI(1,("Negotiate caps 0x%x",(int)cap));
-#ifdef CONFIG_CIFS_DEBUG2
- if(cap & CIFS_UNIX_FCNTL_CAP)
- cFYI(1,("FCNTL cap"));
- if(cap & CIFS_UNIX_EXTATTR_CAP)
- cFYI(1,("EXTATTR cap"));
- if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
- cFYI(1,("POSIX path cap"));
- if(cap & CIFS_UNIX_XATTR_CAP)
- cFYI(1,("XATTR cap"));
- if(cap & CIFS_UNIX_POSIX_ACL_CAP)
- cFYI(1,("POSIX ACL cap"));
-#endif /* CIFS_DEBUG2 */
+
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
cFYI(1,("setting capabilities failed"));
}
static int
CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
- char session_key[CIFS_SESS_KEY_SIZE],
+ char session_key[CIFS_SESSION_KEY_SIZE],
const struct nls_table *nls_codepage)
{
struct smb_hdr *smb_buffer;
pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
pSMB->req_no_secext.CaseInsensitivePasswordLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
+ cpu_to_le16(CIFS_SESSION_KEY_SIZE);
pSMB->req_no_secext.CaseSensitivePasswordLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
+ cpu_to_le16(CIFS_SESSION_KEY_SIZE);
bcc_ptr = pByteArea(smb_buffer);
- memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
- bcc_ptr += CIFS_SESS_KEY_SIZE;
- memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
- bcc_ptr += CIFS_SESS_KEY_SIZE;
+ memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
+ bcc_ptr += CIFS_SESSION_KEY_SIZE;
+ memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
+ bcc_ptr += CIFS_SESSION_KEY_SIZE;
if (ses->capabilities & CAP_UNICODE) {
if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
bcc_ptr++;
}
if(user == NULL)
- bytes_returned = 0; /* skip null user */
+ bytes_returned = 0; /* skill null user */
else
bytes_returned =
cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
if (remaining_words > 0) {
len = UniStrnlen((wchar_t *)bcc_ptr,
remaining_words-1);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
if(ses->serverNOS == NULL)
goto sesssetup_nomem;
/* if these kcallocs fail not much we
can do, but better to not fail the
sesssetup itself */
- kfree(ses->serverDomain);
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
ses->serverDomain =
kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS =
kzalloc(2, GFP_KERNEL);
}
if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response)
<= BCC(smb_buffer_response)) {
- kfree(ses->serverOS);
+ if(ses->serverOS)
+ kfree(ses->serverOS);
ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
if(ses->serverOS == NULL)
goto sesssetup_nomem;
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
if(ses->serverNOS == NULL)
goto sesssetup_nomem;
return rc;
}
+static int
+CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
+ char *SecurityBlob,int SecurityBlobLength,
+ const struct nls_table *nls_codepage)
+{
+ struct smb_hdr *smb_buffer;
+ struct smb_hdr *smb_buffer_response;
+ SESSION_SETUP_ANDX *pSMB;
+ SESSION_SETUP_ANDX *pSMBr;
+ char *bcc_ptr;
+ 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 == NULL) {
+ return -ENOMEM;
+ }
+ smb_buffer_response = smb_buffer;
+ pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
+
+ /* send SMBsessionSetup here */
+ header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
+ NULL /* no tCon exists yet */ , 12 /* wct */ );
+
+ smb_buffer->Mid = GetNextMid(ses->server);
+ pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ pSMB->req.AndXCommand = 0xFF;
+ if(ses->server->maxBuf > 64*1024)
+ ses->server->maxBuf = (64*1023);
+ pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
+ pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
+
+ if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+
+ capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
+ CAP_EXTENDED_SECURITY;
+ if (ses->capabilities & CAP_UNICODE) {
+ smb_buffer->Flags2 |= SMBFLG2_UNICODE;
+ capabilities |= CAP_UNICODE;
+ }
+ if (ses->capabilities & CAP_STATUS32) {
+ smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+ capabilities |= CAP_STATUS32;
+ }
+ if (ses->capabilities & CAP_DFS) {
+ smb_buffer->Flags2 |= SMBFLG2_DFS;
+ capabilities |= CAP_DFS;
+ }
+ pSMB->req.Capabilities = cpu_to_le32(capabilities);
+
+ pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
+ bcc_ptr = pByteArea(smb_buffer);
+ memcpy(bcc_ptr, SecurityBlob, SecurityBlobLength);
+ bcc_ptr += SecurityBlobLength;
+
+ if (ses->capabilities & CAP_UNICODE) {
+ if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode strings */
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ }
+ bytes_returned =
+ cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage);
+ bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */
+ bcc_ptr += 2; /* trailing null */
+ if (domain == NULL)
+ bytes_returned =
+ cifs_strtoUCS((__le16 *) bcc_ptr,
+ "CIFS_LINUX_DOM", 32, nls_codepage);
+ else
+ bytes_returned =
+ cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
+ nls_codepage);
+ bcc_ptr += 2 * bytes_returned;
+ bcc_ptr += 2;
+ bytes_returned =
+ cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
+ 32, nls_codepage);
+ bcc_ptr += 2 * bytes_returned;
+ bytes_returned =
+ cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+ nls_codepage);
+ bcc_ptr += 2 * bytes_returned;
+ bcc_ptr += 2;
+ bytes_returned =
+ cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
+ 64, nls_codepage);
+ bcc_ptr += 2 * bytes_returned;
+ bcc_ptr += 2;
+ } else {
+ strncpy(bcc_ptr, user, 200);
+ bcc_ptr += strnlen(user, 200);
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ if (domain == NULL) {
+ strcpy(bcc_ptr, "CIFS_LINUX_DOM");
+ bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
+ } else {
+ strncpy(bcc_ptr, domain, 64);
+ bcc_ptr += strnlen(domain, 64);
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ }
+ strcpy(bcc_ptr, "Linux version ");
+ bcc_ptr += strlen("Linux version ");
+ strcpy(bcc_ptr, system_utsname.release);
+ bcc_ptr += strlen(system_utsname.release) + 1;
+ strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
+ bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
+ }
+ 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 (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)) {
+ __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")); /* BB do we want to set anything in SesInfo struct ? */
+ if (ses) {
+ ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
+ cFYI(1, ("UID = %d ", ses->Suid));
+ bcc_ptr = pByteArea(smb_buffer_response); /* response can have either 3 or 4 word count - Samba sends 3 */
+
+ /* BB Fix below to make endian neutral !! */
+
+ 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;
+ cFYI(1,
+ ("Security Blob Length %d ",
+ 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 */
+ if(ses->serverOS)
+ kfree(ses->serverOS);
+ ses->serverOS =
+ kzalloc(2 * (len + 1), GFP_KERNEL);
+ cifs_strfromUCS_le(ses->serverOS,
+ (__le16 *)
+ 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);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
+ ses->serverNOS =
+ kzalloc(2 * (len + 1),
+ GFP_KERNEL);
+ cifs_strfromUCS_le(ses->serverNOS,
+ (__le16 *)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);
+ /* last string not null terminated (e.g.Windows XP/2000) */
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
+ ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
+ cifs_strfromUCS_le(ses->serverDomain,
+ (__le16 *)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 {
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
+ ses->serverDomain =
+ kzalloc(2,GFP_KERNEL);
+ }
+ } else {/* no room use dummy domain&NOS */
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
+ ses->serverDomain = kzalloc(2, GFP_KERNEL);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
+ ses->serverNOS = kzalloc(2, GFP_KERNEL);
+ }
+ } else { /* ASCII */
+
+ len = strnlen(bcc_ptr, 1024);
+ if (((long) bcc_ptr + len) - (long)
+ pByteArea(smb_buffer_response)
+ <= BCC(smb_buffer_response)) {
+ if(ses->serverOS)
+ kfree(ses->serverOS);
+ ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
+ strncpy(ses->serverOS, bcc_ptr, len);
+
+ bcc_ptr += len;
+ bcc_ptr[0] = 0; /* null terminate the string */
+ bcc_ptr++;
+
+ len = strnlen(bcc_ptr, 1024);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
+ ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
+ strncpy(ses->serverNOS, bcc_ptr, len);
+ bcc_ptr += len;
+ bcc_ptr[0] = 0;
+ bcc_ptr++;
+
+ len = strnlen(bcc_ptr, 1024);
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
+ ses->serverDomain = kzalloc(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"));
+ }
+ } else {
+ cERROR(1, ("No session structure passed in."));
+ }
+ } else {
+ cERROR(1,
+ (" Invalid Word count %d: ",
+ smb_buffer_response->WordCount));
+ rc = -EIO;
+ }
+
+ if (smb_buffer)
+ cifs_buf_release(smb_buffer);
+
+ return rc;
+}
+
static int
CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
struct cifsSesInfo *ses, int * pNTLMv2_flag,
/* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
if(sign_CIFS_PDUs)
negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
-/* if(ntlmv2_support)
- negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
+ if(ntlmv2_support)
+ negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
/* setup pointers to domain name and workstation name */
bcc_ptr += SecurityBlobLength;
bcc_ptr,
remaining_words
- 1);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS =
kzalloc(2 * (len + 1),
GFP_KERNEL);
if (remaining_words > 0) {
len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
/* last string is not always null terminated (for e.g. for Windows XP & 2000) */
- kfree(ses->serverDomain);
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
ses->serverDomain =
kzalloc(2 *
(len +
= 0;
} /* else no more room so create dummy domain string */
else {
- kfree(ses->serverDomain);
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
ses->serverDomain =
kzalloc(2,
GFP_KERNEL);
}
} else { /* no room so create dummy domain and NOS string */
- kfree(ses->serverDomain);
+ if(ses->serverDomain);
+ kfree(ses->serverDomain);
ses->serverDomain =
kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS =
kzalloc(2, GFP_KERNEL);
}
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS =
kzalloc(len + 1,
GFP_KERNEL);
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverDomain);
+ if(ses->serverDomain)
+ kfree(ses->serverDomain);
ses->serverDomain =
kzalloc(len + 1,
GFP_KERNEL);
SecurityBlob->LmChallengeResponse.Buffer = 0;
SecurityBlob->NtChallengeResponse.Length =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
+ cpu_to_le16(CIFS_SESSION_KEY_SIZE);
SecurityBlob->NtChallengeResponse.MaximumLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
- memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
+ cpu_to_le16(CIFS_SESSION_KEY_SIZE);
+ memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE);
SecurityBlob->NtChallengeResponse.Buffer =
cpu_to_le32(SecurityBlobLength);
- SecurityBlobLength += CIFS_SESS_KEY_SIZE;
- bcc_ptr += CIFS_SESS_KEY_SIZE;
+ SecurityBlobLength += CIFS_SESSION_KEY_SIZE;
+ bcc_ptr += CIFS_SESSION_KEY_SIZE;
if (ses->capabilities & CAP_UNICODE) {
if (domain == NULL) {
bcc_ptr,
remaining_words
- 1);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS =
kzalloc(2 * (len + 1),
GFP_KERNEL);
if(ses->serverDomain)
kfree(ses->serverDomain);
ses->serverDomain = kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS = kzalloc(2, GFP_KERNEL);
}
} else { /* ASCII */
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
+ if(ses->serverNOS)
+ kfree(ses->serverNOS);
ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
strncpy(ses->serverNOS, bcc_ptr, len);
bcc_ptr += len;
bcc_ptr = &pSMB->Password[0];
if((ses->server->secMode) & SECMODE_USER) {
pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
- *bcc_ptr = 0; /* password is null byte */
bcc_ptr++; /* skip password */
- /* already aligned so no need to do it below */
} else {
- pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
+ pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE);
/* BB FIXME add code to fail this if NTLMv2 or Kerberos
specified as required (when that support is added to
the vfs in the future) as only NTLM or the much
- weaker LANMAN (which we do not send by default) is accepted
+ weaker LANMAN (which we do not send) is accepted
by Samba (not sure whether other servers allow
NTLMv2 password here) */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- if((extended_security & CIFSSEC_MAY_LANMAN) &&
- (ses->server->secType == LANMAN))
- calc_lanman_hash(ses, bcc_ptr);
- else
-#endif /* CIFS_WEAK_PW_HASH */
SMBNTencrypt(ses->password,
ses->server->cryptKey,
bcc_ptr);
- bcc_ptr += CIFS_SESS_KEY_SIZE;
- if(ses->capabilities & CAP_UNICODE) {
- /* must align unicode strings */
- *bcc_ptr = 0; /* null byte password */
- bcc_ptr++;
- }
+ bcc_ptr += CIFS_SESSION_KEY_SIZE;
+ *bcc_ptr = 0;
+ bcc_ptr++; /* align */
}
if(ses->server->secMode &
}
/* else do not bother copying these informational fields */
}
- if(smb_buffer_response->WordCount == 3)
- tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
- else
- tcon->Flags = 0;
+ tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
} else if ((rc == 0) && tcon == NULL) {
/* all we need to save for IPC$ connection */
struct nls_table * nls_info)
{
int rc = 0;
- char ntlm_session_key[CIFS_SESS_KEY_SIZE];
+ char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
int ntlmv2_flag = FALSE;
int first_time = 0;
pSesInfo->server->secMode,
pSesInfo->server->capabilities,
pSesInfo->server->timeZone));
- if(experimEnabled < 2)
- rc = CIFS_SessSetup(xid, pSesInfo,
- first_time, nls_info);
- else if (extended_security
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ if(experimEnabled > 1)
+ rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */,
+ &ntlmv2_flag, nls_info);
+ else
+#endif
+ if (extended_security
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
&& (pSesInfo->server->secType == NTLMSSP)) {
- rc = -EOPNOTSUPP;
+ cFYI(1, ("New style sesssetup"));
+ rc = CIFSSpnegoSessSetup(xid, pSesInfo,
+ NULL /* security blob */,
+ 0 /* blob length */,
+ nls_info);
} else if (extended_security
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
&& (pSesInfo->server->secType == RawNTLMSSP)) {