X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fcifs%2Fsess.c;h=d1705ab8136e1fc53768240d6dbca66bfcb56132;hb=23e735bc7b0e1d614656881794257b4224efda3a;hp=c6fd01f55e90a638916bd62b2c0ef946f46c3d77;hpb=6d027cfdb19c26df3151a519ed55acfe2c4cb7c3;p=pandora-kernel.git diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index c6fd01f55e90..d1705ab8136e 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -33,8 +33,6 @@ 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; @@ -85,11 +83,11 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, /* 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 */ @@ -140,7 +138,7 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 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 */ @@ -315,20 +313,22 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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. @@ -353,7 +353,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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 @@ -361,16 +372,16 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, /* no capabilities flags in old lanman negotiation */ - pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; + pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); /* BB calculate hash with password */ /* and copy into bcc */ 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; @@ -379,7 +390,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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 @@ -398,7 +409,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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 */ @@ -406,9 +417,14 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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 = @@ -432,7 +448,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, cpu_to_le16(sizeof(struct ntlmv2_resp)); /* calculate session key */ - setup_ntlmv2_rsp(ses, v2_sess_key); + setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); if(first_time) /* should this be moved into common code with similar ntlmv2 path? */ /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, @@ -445,9 +461,12 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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; @@ -456,23 +475,14 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, /* 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)); @@ -489,7 +499,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, } 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 */ @@ -517,6 +527,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 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); @@ -525,4 +536,3 @@ ssetup_exit: return rc; } -#endif /* CONFIG_CIFS_EXPERIMENTAL */