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

📄 sess.c

📁 Linux内核自带的cifs模块
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   fs/cifs/sess.c * *   SMB/CIFS session setup handling routines * *   Copyright (c) International Business Machines  Corp., 2006, 2007 *   Author(s): Steve French (sfrench@us.ibm.com) * *   This library is free software; you can redistribute it and/or modify *   it under the terms of the GNU Lesser General Public License as published *   by the Free Software Foundation; either version 2.1 of the License, or *   (at your option) any later version. * *   This library is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See *   the GNU Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser General Public License *   along with this library; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <linux/fs.h>#include "cifspdu.h"#include "cifsglob.h"#include "cifsproto.h"#include "cifs_unicode.h"#include "cifs_debug.h"#include "ntlmssp.h"#include "nterr.h"#include <linux/utsname.h>extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,			 unsigned char *p24);static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB){	__u32 capabilities = 0;	/* init fields common to all four types of SessSetup */	/* note that header is initialized to zero in header_assemble */	pSMB->req.AndXCommand = 0xFF;	pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */	/* BB verify whether signing required on neg or just on auth frame	   (and NTLM case) */	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;	if (ses->server->secMode &	    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;	if (ses->capabilities & CAP_UNICODE) {		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;		capabilities |= CAP_UNICODE;	}	if (ses->capabilities & CAP_STATUS32) {		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;		capabilities |= CAP_STATUS32;	}	if (ses->capabilities & CAP_DFS) {		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;		capabilities |= CAP_DFS;	}	if (ses->capabilities & CAP_UNIX)		capabilities |= CAP_UNIX;	/* BB check whether to init vcnum BB */	return capabilities;}static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,				   const struct nls_table *nls_cp){	char *bcc_ptr = *pbcc_area;	int bytes_ret = 0;	/* BB FIXME add check that strings total less	than 335 or will need to send them as arrays */	/* 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) {		/* null user mount */		*bcc_ptr = 0;		*(bcc_ptr+1) = 0;	} else { /* 300 should be long enough for any conceivable user name */		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,					  300, nls_cp);	}	bcc_ptr += 2 * bytes_ret;	bcc_ptr += 2; /* account for null termination */	/* copy domain */	if (ses->domainName == NULL) {		/* Sending null domain better than using a bogus domain name (as		we did briefly in 2.6.18) since server will use its default */		*bcc_ptr = 0;		*(bcc_ptr+1) = 0;		bytes_ret = 0;	} else		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,					  256, nls_cp);	bcc_ptr += 2 * bytes_ret;	bcc_ptr += 2;  /* account for null terminator */	/* Copy OS version */	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,				  nls_cp);	bcc_ptr += 2 * bytes_ret;#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,				  32, nls_cp);#else	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,				  32, nls_cp);#endif	bcc_ptr += 2 * bytes_ret;	bcc_ptr += 2; /* trailing null */	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,				  32, nls_cp);	bcc_ptr += 2 * bytes_ret;	bcc_ptr += 2; /* trailing null */	*pbcc_area = bcc_ptr;}static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,				 const struct nls_table *nls_cp){	char *bcc_ptr = *pbcc_area;	/* copy user */	/* BB what about null user mounts - check that we do this BB */	/* copy user */	if (ses->userName == NULL) {		/* BB what about null user mounts - check that we do this BB */	} else { /* 300 should be long enough for any conceivable user name */		strncpy(bcc_ptr, ses->userName, 300);	}	/* BB improve check for overflow */	bcc_ptr += strnlen(ses->userName, 300);	*bcc_ptr = 0;	bcc_ptr++; /* account for null termination */	/* copy domain */	if (ses->domainName != NULL) {		strncpy(bcc_ptr, ses->domainName, 256);		bcc_ptr += strnlen(ses->domainName, 256);	} /* else we will send a null domain name	     so the server will default to its own domain */	*bcc_ptr = 0;	bcc_ptr++;	/* BB check for overflow here */	strcpy(bcc_ptr, "Linux version ");	bcc_ptr += strlen("Linux version ");#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)	strcpy(bcc_ptr, init_utsname()->release);	bcc_ptr += strlen(init_utsname()->release) + 1;#else	strcpy(bcc_ptr, system_utsname.release);	bcc_ptr += strlen(system_utsname.release) + 1;#endif	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;	*pbcc_area = bcc_ptr;}static int decode_unicode_ssetup(char **pbcc_area, int bleft,				 struct cifsSesInfo *ses,				 const struct nls_table *nls_cp){	int rc = 0;	int words_left, len;	char *data = *pbcc_area;	cFYI(1, ("bleft %d", bleft));	/* SMB header is unaligned, so cifs servers word align start of	   Unicode strings */	data++;	bleft--; /* Windows servers do not always double null terminate		    their final Unicode string - in which case we		    now will not attempt to decode the byte of junk		    which follows it */	words_left = bleft / 2;	/* save off server operating system */	len = UniStrnlen((wchar_t *) data, words_left);/* 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 (len >= words_left)		return rc;	kfree(ses->serverOS);	/* UTF-8 string will not grow more than four times as big as UCS-16 */	ses->serverOS = kzalloc(4 * len, GFP_KERNEL);	if (ses->serverOS != NULL)		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);	data += 2 * (len + 1);	words_left -= len + 1;	/* save off server network operating system */	len = UniStrnlen((wchar_t *) data, words_left);	if (len >= words_left)		return rc;	kfree(ses->serverNOS);	ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */	if (ses->serverNOS != NULL) {		cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,				   nls_cp);		if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {			cFYI(1, ("NT4 server"));			ses->flags |= CIFS_SES_NT4;		}	}	data += 2 * (len + 1);	words_left -= len + 1;	/* save off server domain */	len = UniStrnlen((wchar_t *) data, words_left);	if (len > words_left)		return rc;	kfree(ses->serverDomain);	ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */	if (ses->serverDomain != NULL) {		cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,				   nls_cp);		ses->serverDomain[2*len] = 0;		ses->serverDomain[(2*len) + 1] = 0;	}	data += 2 * (len + 1);	words_left -= len + 1;	cFYI(1, ("words left: %d", words_left));	return rc;}static int decode_ascii_ssetup(char **pbcc_area, int bleft,			       struct cifsSesInfo *ses,			       const struct nls_table *nls_cp){	int rc = 0;	int len;	char *bcc_ptr = *pbcc_area;	cFYI(1, ("decode sessetup ascii. bleft %d", bleft));	len = strnlen(bcc_ptr, bleft);	if (len >= bleft)		return rc;	kfree(ses->serverOS);

⌨️ 快捷键说明

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