Merge tag 'mmc-updates-for-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / fs / cifs / sess.c
index f230571a7ab30d1c7d809eafbfdf9cb5724c2dd3..79358e341fd2ea63cff42e6d608c58f65b5f9804 100644 (file)
@@ -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:
This page took 0.027058 seconds and 5 git commands to generate.