r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[vlendec/samba-autobuild/.git] / source3 / libsmb / ntlmssp.c
index 70fcd24e764ea274bb692e6b543405b22c0ef670..0c0744867dc37a2e0b3e32ffbb84ab972fe0a726 100644 (file)
@@ -9,7 +9,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -18,8 +18,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -299,13 +298,13 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       *out = data_blob(NULL, 0);
+       *out = data_blob_null;
 
        if (!in.length && ntlmssp_state->stored_response.length) {
                input = ntlmssp_state->stored_response;
                
                /* we only want to read the stored response once - overwrite it */
-               ntlmssp_state->stored_response = data_blob(NULL, 0);
+               ntlmssp_state->stored_response = data_blob_null;
        } else {
                input = in;
        }
@@ -325,7 +324,7 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
                                 "NTLMSSP",
                                 &ntlmssp_command)) {
                        DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
-                       dump_data(2, (const char *)input.data, input.length);
+                       dump_data(2, input.data, input.length);
                        return NT_STATUS_INVALID_PARAMETER;
                }
        }
@@ -420,8 +419,8 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
        }
 
-       if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {
-               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+       if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
        }
 
        if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
@@ -531,7 +530,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
                                                        &neg_flags)) {
                        DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
                                (unsigned int)request.length));
-                       dump_data(2, (const char *)request.data, request.length);
+                       dump_data(2, request.data, request.length);
                        return NT_STATUS_INVALID_PARAMETER;
                }
                debug_ntlmssp_flags(neg_flags);
@@ -582,7 +581,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
                          NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
                          0, "");
        } else {
-               struct_blob = data_blob(NULL, 0);
+               struct_blob = data_blob_null;
        }
 
        {
@@ -623,10 +622,10 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
                                    const DATA_BLOB request, DATA_BLOB *reply) 
 {
-       DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
-       DATA_BLOB user_session_key = data_blob(NULL, 0);
-       DATA_BLOB lm_session_key = data_blob(NULL, 0);
-       DATA_BLOB session_key = data_blob(NULL, 0);
+       DATA_BLOB encrypted_session_key = data_blob_null;
+       DATA_BLOB user_session_key = data_blob_null;
+       DATA_BLOB lm_session_key = data_blob_null;
+       DATA_BLOB session_key = data_blob_null;
        uint32 ntlmssp_command, auth_flags;
        NTSTATUS nt_status = NT_STATUS_OK;
 
@@ -642,7 +641,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
        char *workstation = NULL;
 
        /* parse the NTLMSSP packet */
-       *reply = data_blob(NULL, 0);
+       *reply = data_blob_null;
 
 #if 0
        file_save("ntlmssp_auth.dat", request.data, request.length);
@@ -695,7 +694,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
                                 &user, 
                                 &workstation)) {
                        DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
-                       dump_data(2, (const char *)request.data, request.length);
+                       dump_data(2, request.data, request.length);
                        SAFE_FREE(domain);
                        SAFE_FREE(user);
                        SAFE_FREE(workstation);
@@ -807,25 +806,34 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
                        
                } else {
                        DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
-                       session_key = data_blob(NULL, 0);
+                       session_key = data_blob_null;
                }
        } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
                if (lm_session_key.data && lm_session_key.length >= 8) {
                        if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
                                session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+                               if (session_key.data == NULL) {
+                                       return NT_STATUS_NO_MEMORY;
+                               }
                                SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, 
                                                          session_key.data);
                                DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
-                               dump_data_pw("LM session key:\n", session_key.data, session_key.length);
                        } else {
-                               /* use the key unmodified - it's
-                                * probably a NULL key from the guest
-                                * login */
-                               session_key = lm_session_key;
+                               static const uint8 zeros[24] = { 0, };
+                               session_key = data_blob_talloc(
+                                       ntlmssp_state->mem_ctx, NULL, 16);
+                               if (session_key.data == NULL) {
+                                       return NT_STATUS_NO_MEMORY;
+                               }
+                               SMBsesskeygen_lm_sess_key(
+                                       lm_session_key.data, zeros,
+                                       session_key.data);
                        }
+                       dump_data_pw("LM session key:\n", session_key.data,
+                                    session_key.length);
                } else {
                        DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
-                       session_key = data_blob(NULL, 0);
+                       session_key = data_blob_null;
                }
        } else if (user_session_key.data) {
                session_key = user_session_key;
@@ -837,7 +845,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
                dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
        } else {
                DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
-               session_key = data_blob(NULL, 0);
+               session_key = data_blob_null;
        }
 
        /* With KEY_EXCH, the client supplies the proposed session key, 
@@ -868,7 +876,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
        }
 
        if (!NT_STATUS_IS_OK(nt_status)) {
-               ntlmssp_state->session_key = data_blob(NULL, 0);
+               ntlmssp_state->session_key = data_blob_null;
        } else if (ntlmssp_state->session_key.length) {
                nt_status = ntlmssp_sign_init(ntlmssp_state);
        }
@@ -919,6 +927,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
                NTLMSSP_NEGOTIATE_128 |
                NTLMSSP_NEGOTIATE_56 |
                NTLMSSP_UNKNOWN_02000000 |
+               NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
                NTLMSSP_NEGOTIATE_NTLM |
                NTLMSSP_NEGOTIATE_NTLM2 |
                NTLMSSP_NEGOTIATE_KEY_EXCH |
@@ -982,14 +991,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
        uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
        DATA_BLOB server_domain_blob;
        DATA_BLOB challenge_blob;
-       DATA_BLOB struct_blob = data_blob(NULL, 0);
+       DATA_BLOB struct_blob = data_blob_null;
        char *server_domain;
        const char *chal_parse_string;
        const char *auth_gen_string;
-       DATA_BLOB lm_response = data_blob(NULL, 0);
-       DATA_BLOB nt_response = data_blob(NULL, 0);
-       DATA_BLOB session_key = data_blob(NULL, 0);
-       DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
+       DATA_BLOB lm_response = data_blob_null;
+       DATA_BLOB nt_response = data_blob_null;
+       DATA_BLOB session_key = data_blob_null;
+       DATA_BLOB encrypted_session_key = data_blob_null;
        NTSTATUS nt_status = NT_STATUS_OK;
 
        if (!msrpc_parse(&reply, "CdBd",
@@ -998,7 +1007,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                         &server_domain_blob,
                         &chal_flags)) {
                DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
-               dump_data(2, (const char *)reply.data, reply.length);
+               dump_data(2, reply.data, reply.length);
 
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -1039,7 +1048,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                         &unkn1, &unkn2,
                         &struct_blob)) {
                DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
-               dump_data(2, (const char *)reply.data, reply.length);
+               dump_data(2, reply.data, reply.length);
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -1053,7 +1062,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
        }
 
        if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
-               static const uchar zeros[16];
+               static const uchar zeros[16] = { 0, };
                /* do nothing - blobs are zero length */
 
                /* session key is all zeros */
@@ -1101,7 +1110,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
 
                DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
                DEBUG(5, ("challenge is: \n"));
-               dump_data(5, (const char *)session_nonce_hash, 8);
+               dump_data(5, session_nonce_hash, 8);
                
                nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
                SMBNTencrypt_hash(ntlmssp_state->nt_hash,
@@ -1220,6 +1229,7 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
 
        (*ntlmssp_state)->neg_flags = 
                NTLMSSP_NEGOTIATE_128 |
+               NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
                NTLMSSP_NEGOTIATE_NTLM |
                NTLMSSP_NEGOTIATE_NTLM2 |
                NTLMSSP_NEGOTIATE_KEY_EXCH |