⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connect.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
					strncpy(ses->serverOS,bcc_ptr, len);					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->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"));		}	} else {		cERROR(1,		       (" Invalid Word count %d: ",			smb_buffer_response->WordCount));		rc = -EIO;	}		if (smb_buffer)		cifs_buf_release(smb_buffer);	return rc;}static intCIFSSpnegoSessSetup(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 == 0) {		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 */ );	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;	pSMB->req.AndXCommand = 0xFF;	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((wchar_t *) 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((wchar_t *) bcc_ptr,					  "CIFS_LINUX_DOM", 32, nls_codepage);		else			bytes_returned =			    cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,					  nls_codepage);		bcc_ptr += 2 * bytes_returned;		bcc_ptr += 2;		bytes_returned =		    cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",				  32, nls_codepage);		bcc_ptr += 2 * bytes_returned;		bytes_returned =		    cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,				  nls_codepage);		bcc_ptr += 2 * bytes_returned;		bcc_ptr += 2;		bytes_returned =		    cifs_strtoUCS((wchar_t *) 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, UTS_RELEASE);		bcc_ptr += strlen(UTS_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  */					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;						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) */							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)					    <= BCC(smb_buffer_response)) {						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++;						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"));			}		} 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 intCIFSNTLMSSPNegotiateSessSetup(unsigned int xid,			      struct cifsSesInfo *ses, int * pNTLMv2_flag,			      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 *domain;	int rc = 0;	int remaining_words = 0;	int bytes_returned = 0;	int len;	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) {		return -ENOMEM;	}	smb_buffer_response = smb_buffer;	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,			NULL /* no tCon exists yet */ , 12 /* wct */ );	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;	pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);	pSMB->req.AndXCommand = 0xFF;	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);	bcc_ptr = (char *) &pSMB->req.SecurityBlob;	SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;	strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);	SecurityBlob->MessageType = NtLmNegotiate;	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)		negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;	if(ntlmv2_support)		negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;	/* setup pointers to domain name and workstation name */	bcc_ptr += SecurityBlobLength;	SecurityBlob->WorkstationName.Buffer = 0;	SecurityBlob->WorkstationName.Length = 0;	SecurityBlob->WorkstationName.MaximumLength = 0;	if (domain == NULL) {		SecurityBlob->DomainName.Buffer = 0;		SecurityBlob->DomainName.Length = 0;		SecurityBlob->DomainName.MaximumLength = 0;	} else {		__u16 len;		negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;		strncpy(bcc_ptr, domain, 63);		len = strnlen(domain, 64);		SecurityBlob->DomainName.MaximumLength =		    cpu_to_le16(len);		SecurityBlob->DomainName.Buffer =		    cpu_to_le32((long) &SecurityBlob->				DomainString -				(long) &SecurityBlob->Signature);		bcc_ptr += len;		SecurityBlobLength += len;		SecurityBlob->DomainName.Length =		    cpu_to_le16(len);	}	if (ses->capabilities & CAP_UNICODE) {		if ((long) bcc_ptr % 2) {			*bcc_ptr = 0;			bcc_ptr++;		}		bytes_returned =		    cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",				  32, nls_codepage);		bcc_ptr += 2 * bytes_returned;		bytes_returned =		    cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,				  nls_codepage);		bcc_ptr += 2 * bytes_returned;		bcc_ptr += 2;	/* null terminate Linux version */		bytes_returned =		    cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -