summaryrefslogtreecommitdiffstats
path: root/fs/cifs/sess.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 14:06:30 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 14:06:30 -0700
commitd4141531f63a29bb2a980092b6f2828c385e6edd (patch)
tree4475e277bf75e2a9a5de07ce1e98b84c834387ec /fs/cifs/sess.c
parentf39d420f672f99ad9a0fe7deb951a0030d4f0d9e (diff)
parent7ac0febb81259fb9e0c447e0b90d0f05f409a02b (diff)
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French: "Various CIFS/SMB2/SMB3 updates for 3.11. Includes bug fixes - SMB3 support should be much more stable with key DFS fix and also signing possible now (although is more work to do to get SMB3 signing working well with multiuser). Mounts using the new SMB 3.02 dialect can now be done (specify "vers=3.02" on mount) against the most current Microsoft systems. Also includes a big cleanup of the cifs/smb2/smb3 authentication code from Jeff which fixes some long standing problems with the way allowed authentication flavors and signing are configured. Some followon patches later in the cycle will clean up allocation of structures for the various security mechanisms depending on what dialect is chosen (reduces memory usage a little) and to add support for the secure negotiate fsctl (for smb3) which prevents downgrade attacks." * 'for-next' of git://git.samba.org/sfrench/cifs-2.6: (39 commits) cifs: fill TRANS2_QUERY_FILE_INFO ByteCount fields cifs: fix SMB2 signing enablement in cifs_enable_signing [CIFS] Fix build warning [CIFS] SMB3 Signing enablement [CIFS] Do not set DFS flag on SMB2 open [CIFS] fix static checker warning cifs: try to handle the MUST SecurityFlags sanely When server doesn't provide SecurityBuffer on SMB2Negotiate pick default Handle big endianness in NTLM (ntlmv2) authentication revalidate directories instiantiated via FIND_* in order to handle DFS referrals SMB2 FSCTL and IOCTL worker function Charge at least one credit, if server says that it supports multicredit Remove typo Some missing share flags cifs: using strlcpy instead of strncpy Update headers to update various SMB3 ioctl definitions Update cifs version number Add ability to dipslay SMB3 share flags and capabilities for debugging Add some missing SMB3 and SMB3.02 flags Add SMB3.02 dialect support ...
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r--fs/cifs/sess.c95
1 files changed, 70 insertions, 25 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index f230571a7ab..79358e341fd 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -138,8 +138,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ if (ses->server->sign)
pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
if (ses->capabilities & CAP_UNICODE) {
@@ -310,11 +309,10 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
return;
}
-static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
- struct cifs_ses *ses,
- const struct nls_table *nls_cp)
+static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
+ struct cifs_ses *ses,
+ const struct nls_table *nls_cp)
{
- int rc = 0;
int len;
char *bcc_ptr = *pbcc_area;
@@ -322,24 +320,22 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
len = strnlen(bcc_ptr, bleft);
if (len >= bleft)
- return rc;
+ return;
kfree(ses->serverOS);
ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
if (ses->serverOS)
strncpy(ses->serverOS, bcc_ptr, len);
- if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
+ if (strncmp(ses->serverOS, "OS/2", 4) == 0)
cifs_dbg(FYI, "OS/2 server\n");
- ses->flags |= CIFS_SES_OS2;
- }
bcc_ptr += len + 1;
bleft -= len + 1;
len = strnlen(bcc_ptr, bleft);
if (len >= bleft)
- return rc;
+ return;
kfree(ses->serverNOS);
@@ -352,7 +348,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
len = strnlen(bcc_ptr, bleft);
if (len > bleft)
- return rc;
+ return;
/* No domain field in LANMAN case. Domain is
returned by old servers in the SMB negprot response */
@@ -360,8 +356,6 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
but thus do return domain here we could add parsing
for it later, but it is not very important */
cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
-
- return rc;
}
int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
@@ -432,8 +426,7 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
+ if (ses->server->sign) {
flags |= NTLMSSP_NEGOTIATE_SIGN;
if (!ses->server->session_estab)
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
@@ -471,8 +464,7 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
+ if (ses->server->sign) {
flags |= NTLMSSP_NEGOTIATE_SIGN;
if (!ses->server->session_estab)
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
@@ -558,6 +550,56 @@ setup_ntlmv2_ret:
return rc;
}
+enum securityEnum
+select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
+{
+ switch (server->negflavor) {
+ case CIFS_NEGFLAVOR_EXTENDED:
+ switch (requested) {
+ case Kerberos:
+ case RawNTLMSSP:
+ return requested;
+ case Unspecified:
+ if (server->sec_ntlmssp &&
+ (global_secflags & CIFSSEC_MAY_NTLMSSP))
+ return RawNTLMSSP;
+ if ((server->sec_kerberos || server->sec_mskerberos) &&
+ (global_secflags & CIFSSEC_MAY_KRB5))
+ return Kerberos;
+ /* Fallthrough */
+ default:
+ return Unspecified;
+ }
+ case CIFS_NEGFLAVOR_UNENCAP:
+ switch (requested) {
+ case NTLM:
+ case NTLMv2:
+ return requested;
+ case Unspecified:
+ if (global_secflags & CIFSSEC_MAY_NTLMV2)
+ return NTLMv2;
+ if (global_secflags & CIFSSEC_MAY_NTLM)
+ return NTLM;
+ /* Fallthrough */
+ default:
+ return Unspecified;
+ }
+ case CIFS_NEGFLAVOR_LANMAN:
+ switch (requested) {
+ case LANMAN:
+ return requested;
+ case Unspecified:
+ if (global_secflags & CIFSSEC_MAY_LANMAN)
+ return LANMAN;
+ /* Fallthrough */
+ default:
+ return Unspecified;
+ }
+ default:
+ return Unspecified;
+ }
+}
+
int
CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp)
@@ -579,11 +621,18 @@ CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
u16 blob_len;
char *ntlmsspblob = NULL;
- if (ses == NULL)
+ if (ses == NULL) {
+ WARN(1, "%s: ses == NULL!", __func__);
return -EINVAL;
+ }
- type = ses->server->secType;
+ type = select_sectype(ses->server, ses->sectype);
cifs_dbg(FYI, "sess setup type %d\n", type);
+ if (type == Unspecified) {
+ cifs_dbg(VFS, "Unable to select appropriate authentication method!");
+ return -EINVAL;
+ }
+
if (type == RawNTLMSSP) {
/* if memory allocation is successful, caller of this function
* frees it.
@@ -643,8 +692,6 @@ ssetup_ntlmssp_authenticate:
}
bcc_ptr = str_area;
- ses->flags &= ~CIFS_SES_LANMAN;
-
iov[1].iov_base = NULL;
iov[1].iov_len = 0;
@@ -668,7 +715,6 @@ ssetup_ntlmssp_authenticate:
ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
true : false, lnm_session_key);
- ses->flags |= CIFS_SES_LANMAN;
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
bcc_ptr += CIFS_AUTH_RESP_SIZE;
@@ -938,8 +984,7 @@ ssetup_ntlmssp_authenticate:
}
decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
} else {
- rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
- ses, nls_cp);
+ decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
}
ssetup_exit: