extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
{
__u32 capabilities = 0;
/* BB FIXME add check that strings total less
than 335 or will need to send them as arrays */
- /* align unicode strings, must be word aligned */
- if ((long) bcc_ptr % 2) {
+ /* unicode strings, must be word aligned before the call */
+/* if ((long) bcc_ptr % 2) {
*bcc_ptr = 0;
bcc_ptr++;
- }
+ } */
/* copy user */
if(ses->userName == NULL) {
/* BB what about null user mounts - check that we do this BB */
strncpy(bcc_ptr, ses->userName, 300);
}
/* BB improve check for overflow */
- bcc_ptr += strnlen(ses->userName, 200);
+ bcc_ptr += strnlen(ses->userName, 300);
*bcc_ptr = 0;
bcc_ptr++; /* account for null termination */
int wct;
struct smb_hdr *smb_buf;
char *bcc_ptr;
+ char *str_area;
SESSION_SETUP_ANDX *pSMB;
__u32 capabilities;
int count;
int resp_buf_type = 0;
- struct kvec iov[1];
+ struct kvec iov[2];
enum securityEnum type;
__u16 action;
int bytes_remaining;
- cFYI(1,("new sess setup"));
if(ses == NULL)
return -EINVAL;
type = ses->server->secType;
+
+ cFYI(1,("sess setup type %d",type));
if(type == LANMAN) {
#ifndef CONFIG_CIFS_WEAK_PW_HASH
/* LANMAN and plaintext are less secure and off by default.
pSMB = (SESSION_SETUP_ANDX *)smb_buf;
capabilities = cifs_ssetup_hdr(ses, pSMB);
- bcc_ptr = pByteArea(smb_buf);
+
+ /* we will send the SMB in two pieces,
+ a fixed length beginning part, and a
+ second part which will include the strings
+ and rest of bcc area, in order to avoid having
+ to do a large buffer 17K allocation */
+ iov[0].iov_base = (char *)pSMB;
+ iov[0].iov_len = smb_buf->smb_buf_length + 4;
+
+ /* 2000 big enough to fit max user, domain, NOS name etc. */
+ str_area = kmalloc(2000, GFP_KERNEL);
+ bcc_ptr = str_area;
if(type == LANMAN) {
#ifdef CONFIG_CIFS_WEAK_PW_HASH
calc_lanman_hash(ses, lnm_session_key);
-#ifdef CONFIG_CIFS_DEBUG2
+/* #ifdef CONFIG_CIFS_DEBUG2
cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
CIFS_SESS_KEY_SIZE);
-#endif
+#endif */
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
bcc_ptr += CIFS_SESS_KEY_SIZE;
changed to do higher than lanman dialect and
we reconnected would we ever calc signing_key? */
- cERROR(1,("Negotiating LANMAN setting up strings"));
+ cFYI(1,("Negotiating LANMAN setting up strings"));
/* Unicode not allowed for LANMAN dialects */
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
#endif
if(first_time) /* should this be moved into common code
with similar ntlmv2 path? */
- cifs_calculate_mac_key( ses->server->mac_signing_key,
+ cifs_calculate_mac_key(ses->server->mac_signing_key,
ntlm_session_key, ses->password);
/* copy session key */
bcc_ptr += CIFS_SESS_KEY_SIZE;
memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
bcc_ptr += CIFS_SESS_KEY_SIZE;
- if(ses->capabilities & CAP_UNICODE)
+ if(ses->capabilities & CAP_UNICODE) {
+ /* unicode strings must be word aligned */
+ if (iov[0].iov_len % 2) {
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ }
unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
- else
+ } else
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
} else if (type == NTLMv2) {
char * v2_sess_key =
memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp));
bcc_ptr += sizeof(struct ntlmv2_resp);
kfree(v2_sess_key);
- if(ses->capabilities & CAP_UNICODE)
+ if(ses->capabilities & CAP_UNICODE) {
+ if(iov[0].iov_len % 2) {
+ *bcc_ptr = 0;
+ } bcc_ptr++;
unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
- else
+ } else
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
} else /* NTLMSSP or SPNEGO */ {
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
/* BB set password lengths */
}
- count = (long) bcc_ptr - (long) pByteArea(smb_buf);
+ count = (long) bcc_ptr - (long) str_area;
smb_buf->smb_buf_length += count;
- /* if we switch to small buffers, count will need to be fewer
- than 383 (strings less than 335 bytes) */
-
BCC_LE(smb_buf) = cpu_to_le16(count);
-
- /* BB FIXME check for other non ntlm code paths */
-
- /* BB check is this too big for a small smb? */
-
- iov[0].iov_base = (char *)pSMB;
- iov[0].iov_len = smb_buf->smb_buf_length + 4;
-
- rc = SendReceive2(xid, ses, iov, 1 /* num_iovecs */, &resp_buf_type, 0);
+ iov[1].iov_base = str_area;
+ iov[1].iov_len = count;
+ rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
/* SMB request buf freed in SendReceive2 */
cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
}
action = le16_to_cpu(pSMB->resp.Action);
if (action & GUEST_LOGIN)
- cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
+ cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
ses->Suid = smb_buf->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 */
rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp);
ssetup_exit:
+ kfree(str_area);
if(resp_buf_type == CIFS_SMALL_BUFFER) {
cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base));
cifs_small_buf_release(iov[0].iov_base);
return rc;
}
-#endif /* CONFIG_CIFS_EXPERIMENTAL */