[CIFS] SessionSetup cleanup part 2
The cifs session setup code has three cases, and a fourth for backlevel LANMAN2 style session setup needed to be added. This new session setup implmentation will eventually replace the other three and should be easier to read while fixing a few minor problems (not setting the LARGE READ/WRITEX flags when NTLMSSP was negotiated for example) and adding support for NTLMv2 (which will be added with the next patch. In the meantime, this code is marked in an CONFIG_CIFS_EXPERIMENTAL block and will not be turned on by default until it is tested against more server types. Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
b580513e84
commit
5815449d1b
7 changed files with 161 additions and 13 deletions
|
@ -3,4 +3,4 @@
|
|||
#
|
||||
obj-$(CONFIG_CIFS) += cifs.o
|
||||
|
||||
cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o
|
||||
cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o ntlmssp.o
|
||||
|
|
|
@ -260,4 +260,5 @@ void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_respon
|
|||
/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
|
||||
|
||||
hmac_md5_final(v2_session_response,&context);
|
||||
cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); /* BB removeme BB */
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* fs/cifs/cifsglob.h
|
||||
*
|
||||
* Copyright (C) International Business Machines Corp., 2002,2005
|
||||
* Copyright (C) International Business Machines Corp., 2002,2006
|
||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
|
@ -430,6 +430,15 @@ struct dir_notify_req {
|
|||
#define CIFS_LARGE_BUFFER 2
|
||||
#define CIFS_IOVEC 4 /* array of response buffers */
|
||||
|
||||
/* Type of session setup needed */
|
||||
#define CIFS_PLAINTEXT 0
|
||||
#define CIFS_LANMAN 1
|
||||
#define CIFS_NTLM 2
|
||||
#define CIFS_NTLMSSP_NEG 3
|
||||
#define CIFS_NTLMSSP_AUTH 4
|
||||
#define CIFS_SPNEGO_INIT 5
|
||||
#define CIFS_SPNEGO_TARG 6
|
||||
|
||||
/*
|
||||
*****************************************************************
|
||||
* All constants go here
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* fs/cifs/cifsproto.h
|
||||
*
|
||||
* Copyright (c) International Business Machines Corp., 2002,2005
|
||||
* Copyright (c) International Business Machines Corp., 2002,2006
|
||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
|
@ -64,8 +64,14 @@ extern int map_smb_to_linux_error(struct smb_hdr *smb);
|
|||
extern void header_assemble(struct smb_hdr *, char /* command */ ,
|
||||
const struct cifsTconInfo *, int /* length of
|
||||
fixed section (word count) in two byte units */);
|
||||
extern int small_smb_init_no_tc(int smb_cmd, int wct, struct cifsSesInfo *ses,
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
|
||||
struct cifsSesInfo *ses,
|
||||
void ** request_buf);
|
||||
extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
|
||||
const int stage, int * pNTLMv2_flg,
|
||||
const struct nls_table *nls_cp);
|
||||
#endif
|
||||
extern __u16 GetNextMid(struct TCP_Server_Info *server);
|
||||
extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
|
||||
struct cifsTconInfo *);
|
||||
|
|
|
@ -187,14 +187,16 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
int
|
||||
small_smb_init_no_tcon(int smb_command, int wct, struct cifsSesInfo *ses,
|
||||
void **request_buf)
|
||||
small_smb_init_no_tc(const int smb_command, const int wct,
|
||||
struct cifsSesInfo *ses, void **request_buf)
|
||||
{
|
||||
int rc;
|
||||
struct smb_hdr * buffer;
|
||||
|
||||
rc = small_smb_init(smb_command, wct, 0, request_buf);
|
||||
rc = small_smb_init(smb_command, wct, NULL, request_buf);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
|
@ -212,7 +214,7 @@ small_smb_init_no_tcon(int smb_command, int wct, struct cifsSesInfo *ses,
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
||||
|
||||
/* If the return code is zero, this function must fill in request_buf pointer */
|
||||
static int
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* fs/cifs/connect.c
|
||||
*
|
||||
* Copyright (C) International Business Machines Corp., 2002,2005
|
||||
* Copyright (C) International Business Machines Corp., 2002,2006
|
||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
|
@ -2816,7 +2816,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
|
|||
}
|
||||
} else {
|
||||
cERROR(1,
|
||||
(" Invalid Word count %d: ",
|
||||
(" Invalid Word count %d:",
|
||||
smb_buffer_response->WordCount));
|
||||
rc = -EIO;
|
||||
}
|
||||
|
@ -3433,7 +3433,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
|||
if (extended_security
|
||||
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
||||
&& (pSesInfo->server->secType == NTLMSSP)) {
|
||||
cFYI(1, ("New style sesssetup "));
|
||||
cFYI(1, ("New style sesssetup"));
|
||||
rc = CIFSSpnegoSessSetup(xid, pSesInfo,
|
||||
NULL /* security blob */,
|
||||
0 /* blob length */,
|
||||
|
@ -3441,7 +3441,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
|
|||
} else if (extended_security
|
||||
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
|
||||
&& (pSesInfo->server->secType == RawNTLMSSP)) {
|
||||
cFYI(1, ("NTLMSSP sesssetup "));
|
||||
cFYI(1, ("NTLMSSP sesssetup"));
|
||||
rc = CIFSNTLMSSPNegotiateSessSetup(xid,
|
||||
pSesInfo,
|
||||
&ntlmv2_flag,
|
||||
|
|
130
fs/cifs/ntlmssp.c
Normal file
130
fs/cifs/ntlmssp.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* fs/cifs/ntlmssp.h
|
||||
*
|
||||
* Copyright (c) International Business Machines Corp., 2006
|
||||
* 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 "cifspdu.h"
|
||||
#include "cifsglob.h"
|
||||
#include "cifsproto.h"
|
||||
#include "cifs_unicode.h"
|
||||
#include "cifs_debug.h"
|
||||
#include "ntlmssp.h"
|
||||
#include "nterr.h"
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
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;
|
||||
}
|
||||
|
||||
/* BB check whether to init vcnum BB */
|
||||
return capabilities;
|
||||
}
|
||||
int
|
||||
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
|
||||
int * pNTLMv2_flg, const struct nls_table *nls_cp)
|
||||
{
|
||||
int rc = 0;
|
||||
int wct;
|
||||
struct smb_hdr *smb_buffer;
|
||||
char *bcc_ptr;
|
||||
SESSION_SETUP_ANDX *pSMB;
|
||||
__u32 capabilities;
|
||||
|
||||
if(ses == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
cFYI(1,("SStp type: %d",type));
|
||||
if(type < CIFS_NTLM) {
|
||||
#ifndef CONFIG_CIFS_WEAK_PW_HASH
|
||||
/* LANMAN and plaintext are less secure and off by default.
|
||||
So we make this explicitly be turned on in kconfig (in the
|
||||
build) and turned on at runtime (changed from the default)
|
||||
in proc/fs/cifs or via mount parm. Unfortunately this is
|
||||
needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
wct = 10; /* lanman 2 style sessionsetup */
|
||||
} else if(type < CIFS_NTLMSSP_NEG)
|
||||
wct = 13; /* old style NTLM sessionsetup */
|
||||
else /* same size for negotiate or auth, NTLMSSP or extended security */
|
||||
wct = 12;
|
||||
|
||||
rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
|
||||
(void **)&smb_buffer);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
|
||||
|
||||
capabilities = cifs_ssetup_hdr(ses, pSMB);
|
||||
bcc_ptr = pByteArea(smb_buffer);
|
||||
if(type > CIFS_NTLM) {
|
||||
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
|
||||
capabilities |= CAP_EXTENDED_SECURITY;
|
||||
pSMB->req.Capabilities = cpu_to_le32(capabilities);
|
||||
/* BB set password lengths */
|
||||
} else if(type < CIFS_NTLM) /* lanman */ {
|
||||
/* no capabilities flags in old lanman negotiation */
|
||||
/* pSMB->old_req.PasswordLength = */ /* BB fixme BB */
|
||||
} else /* type CIFS_NTLM */ {
|
||||
pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
|
||||
pSMB->req_no_secext.CaseInsensitivePasswordLength =
|
||||
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
|
||||
pSMB->req_no_secext.CaseSensitivePasswordLength =
|
||||
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
|
||||
|
||||
cifs_small_buf_release(smb_buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
Loading…
Reference in a new issue