summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES6
-rw-r--r--fs/cifs/Makefile2
-rw-r--r--fs/cifs/cifsencrypt.c6
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h11
-rw-r--r--fs/cifs/cifsproto.h10
-rw-r--r--fs/cifs/cifssmb.c32
-rw-r--r--fs/cifs/connect.c50
-rw-r--r--fs/cifs/ntlmssp.c130
-rw-r--r--fs/cifs/ntlmssp.h2
10 files changed, 210 insertions, 41 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index d335015..a9cf779 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,9 @@
+Version 1.41
+------------
+Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
+configure stronger authentication. Fix sfu symlinks so they can
+be followed (not just recognized).
+
Version 1.40
------------
Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 7384947..58c7725 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -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
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index a2c2485..c2cbe0e 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifsencrypt.c
*
- * Copyright (C) International Business Machines Corp., 2005
+ * Copyright (C) International Business Machines Corp., 2005,2006
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -36,7 +36,8 @@
extern void mdfour(unsigned char *out, unsigned char *in, int n);
extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
+static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu,
+ const char * key, char * signature)
{
struct MD5Context context;
@@ -259,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 */
}
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 821a8eb..4cf10f2 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
extern int cifs_ioctl (struct inode * inode, struct file * filep,
unsigned int command, unsigned long arg);
-#define CIFS_VERSION "1.40"
+#define CIFS_VERSION "1.41"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7bed276..006eb33 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -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
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 3c03aad..79e7f5a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -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,6 +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 */);
+#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 *);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 217323b..38ab9f6 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifssmb.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)
*
* Contains the routines for constructing the SMB PDUs themselves
@@ -186,7 +186,35 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
cifs_stats_inc(&tcon->num_smbs_sent);
return rc;
-}
+}
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+int
+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, NULL, request_buf);
+ if(rc)
+ return rc;
+
+ buffer = (struct smb_hdr *)*request_buf;
+ buffer->Mid = GetNextMid(ses->server);
+ if (ses->capabilities & CAP_UNICODE)
+ buffer->Flags2 |= SMBFLG2_UNICODE;
+ if (ses->capabilities & CAP_STATUS32)
+ buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+
+ /* uid, tid can stay at zero as set in header assemble */
+
+ /* BB add support for turning on the signing when
+ this function is used after 1st of session setup requests */
+
+ return rc;
+}
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
/* If the return code is zero, this function must fill in request_buf pointer */
static int
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index e488603..0e1560a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -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
@@ -2525,7 +2525,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
__u32 negotiate_flags, capabilities;
__u16 count;
- cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
+ cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
if(ses == NULL)
return -EINVAL;
domain = ses->domainName;
@@ -2575,7 +2575,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
SecurityBlob->MessageType = NtLmNegotiate;
negotiate_flags =
NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
- NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
+ NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
+ NTLMSSP_NEGOTIATE_56 |
/* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
if(sign_CIFS_PDUs)
negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -2588,26 +2589,11 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
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);
- }
+ /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
+ along with username on auth request (ie the response to challenge) */
+ SecurityBlob->DomainName.Buffer = 0;
+ SecurityBlob->DomainName.Length = 0;
+ SecurityBlob->DomainName.MaximumLength = 0;
if (ses->capabilities & CAP_UNICODE) {
if ((long) bcc_ptr % 2) {
*bcc_ptr = 0;
@@ -2677,7 +2663,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
SecurityBlob2->MessageType));
} else if (ses) {
ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
- cFYI(1, ("UID = %d ", ses->Suid));
+ cFYI(1, ("UID = %d", ses->Suid));
if ((pSMBr->resp.hdr.WordCount == 3)
|| ((pSMBr->resp.hdr.WordCount == 4)
&& (blob_len <
@@ -2685,17 +2671,17 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
if (pSMBr->resp.hdr.WordCount == 4) {
bcc_ptr += blob_len;
- cFYI(1,
- ("Security Blob Length %d ",
+ cFYI(1, ("Security Blob Length %d",
blob_len));
}
- cFYI(1, ("NTLMSSP Challenge rcvd "));
+ cFYI(1, ("NTLMSSP Challenge rcvd"));
memcpy(ses->server->cryptKey,
SecurityBlob2->Challenge,
CIFS_CRYPTO_KEY_SIZE);
- if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
+ if(SecurityBlob2->NegotiateFlags &
+ cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
*pNTLMv2_flag = TRUE;
if((SecurityBlob2->NegotiateFlags &
@@ -2818,7 +2804,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
bcc_ptr++;
} else
cFYI(1,
- ("Variable field of length %d extends beyond end of smb ",
+ ("Variable field of length %d extends beyond end of smb",
len));
}
} else {
@@ -2830,7 +2816,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
}
} else {
cERROR(1,
- (" Invalid Word count %d: ",
+ (" Invalid Word count %d:",
smb_buffer_response->WordCount));
rc = -EIO;
}
@@ -3447,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 */,
@@ -3455,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,
diff --git a/fs/cifs/ntlmssp.c b/fs/cifs/ntlmssp.c
new file mode 100644
index 0000000..4aabe2d
--- /dev/null
+++ b/fs/cifs/ntlmssp.c
@@ -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 */
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 803389b..d39b712 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/ntlmssp.h
*
- * Copyright (c) International Business Machines Corp., 2002
+ * 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
OpenPOWER on IntegriCloud