LCOV - code coverage report
Current view: top level - auth/ntlmssp - ntlmssp_client.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 375 495 75.8 %
Date: 2024-04-21 15:09:00 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/Netbios implementation.
       3             :    Version 3.0
       4             :    handle NLTMSSP, client server side parsing
       5             : 
       6             :    Copyright (C) Andrew Tridgell      2001
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005
       8             :    Copyright (C) Stefan Metzmacher 2005
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : struct auth_session_info;
      25             : 
      26             : #include "includes.h"
      27             : #include "auth/ntlmssp/ntlmssp.h"
      28             : #include "../libcli/auth/libcli_auth.h"
      29             : #include "auth/credentials/credentials.h"
      30             : #include "auth/gensec/gensec.h"
      31             : #include "auth/gensec/gensec_internal.h"
      32             : #include "param/param.h"
      33             : #include "auth/ntlmssp/ntlmssp_private.h"
      34             : #include "../librpc/gen_ndr/ndr_ntlmssp.h"
      35             : #include "../auth/ntlmssp/ntlmssp_ndr.h"
      36             : #include "../nsswitch/libwbclient/wbclient.h"
      37             : 
      38             : #include "lib/crypto/gnutls_helpers.h"
      39             : #include <gnutls/gnutls.h>
      40             : #include <gnutls/crypto.h>
      41             : 
      42             : #undef DBGC_CLASS
      43             : #define DBGC_CLASS DBGC_AUTH
      44             : 
      45             : /*********************************************************************
      46             :  Client side NTLMSSP
      47             : *********************************************************************/
      48             : 
      49             : /**
      50             :  * Next state function for the Initial packet
      51             :  *
      52             :  * @param ntlmssp_state NTLMSSP State
      53             :  * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
      54             :  * @param in A NULL data blob (input ignored)
      55             :  * @param out The initial negotiate request to the server, as an talloc()ed DATA_BLOB, on out_mem_ctx
      56             :  * @return Errors or NT_STATUS_OK.
      57             :  */
      58             : 
      59       38666 : NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
      60             :                                 TALLOC_CTX *out_mem_ctx,
      61             :                                 DATA_BLOB in, DATA_BLOB *out)
      62             : {
      63         296 :         struct gensec_ntlmssp_context *gensec_ntlmssp =
      64       38666 :                 talloc_get_type_abort(gensec_security->private_data,
      65             :                                       struct gensec_ntlmssp_context);
      66       38666 :         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
      67         296 :         NTSTATUS status;
      68       38666 :         const DATA_BLOB version_blob = ntlmssp_version_blob();
      69             : 
      70             :         /* generate the ntlmssp negotiate packet */
      71       38962 :         status = msrpc_gen(out_mem_ctx,
      72             :                   out, "CddAAb",
      73             :                   "NTLMSSP",
      74             :                   NTLMSSP_NEGOTIATE,
      75             :                   ntlmssp_state->neg_flags,
      76             :                   "", /* domain */
      77             :                   "", /* workstation */
      78       38666 :                   version_blob.data, version_blob.length);
      79       38666 :         if (!NT_STATUS_IS_OK(status)) {
      80           0 :                 DEBUG(0, ("ntlmssp_client_initial: failed to generate "
      81             :                           "ntlmssp negotiate packet\n"));
      82           0 :                 return status;
      83             :         }
      84             : 
      85       38666 :         if (DEBUGLEVEL >= 10) {
      86           2 :                 struct NEGOTIATE_MESSAGE *negotiate = talloc(
      87             :                         ntlmssp_state, struct NEGOTIATE_MESSAGE);
      88           2 :                 if (negotiate != NULL) {
      89           2 :                         status = ntlmssp_pull_NEGOTIATE_MESSAGE(
      90             :                                 out, negotiate, negotiate);
      91           2 :                         if (NT_STATUS_IS_OK(status)) {
      92           2 :                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
      93             :                                                 negotiate);
      94             :                         }
      95           2 :                         TALLOC_FREE(negotiate);
      96             :                 }
      97             :         }
      98             : 
      99       38666 :         ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
     100             :                                                              *out);
     101       38666 :         if (ntlmssp_state->negotiate_blob.length != out->length) {
     102           0 :                 return NT_STATUS_NO_MEMORY;
     103             :         }
     104             : 
     105       38666 :         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
     106             : 
     107       38666 :         return NT_STATUS_MORE_PROCESSING_REQUIRED;
     108             : }
     109             : 
     110          50 : NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security,
     111             :                                 TALLOC_CTX *out_mem_ctx,
     112             :                                 DATA_BLOB in, DATA_BLOB *out)
     113             : {
     114           0 :         struct gensec_ntlmssp_context *gensec_ntlmssp =
     115          50 :                 talloc_get_type_abort(gensec_security->private_data,
     116             :                                       struct gensec_ntlmssp_context);
     117          50 :         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     118          50 :         uint32_t neg_flags = 0;
     119           0 :         uint32_t ntlmssp_command;
     120           0 :         NTSTATUS status;
     121           0 :         bool ok;
     122             : 
     123          50 :         *out = data_blob_null;
     124             : 
     125          50 :         if (in.length == 0) {
     126             :                 /*
     127             :                  * This is compat code for older callers
     128             :                  * which were missing the "initial_blob"/"negotiate_blob".
     129             :                  *
     130             :                  * That means we can't calculate the NTLMSSP_MIC
     131             :                  * field correctly and need to force the
     132             :                  * old_spnego behaviour.
     133             :                  */
     134           0 :                 DEBUG(10, ("%s: in.length==%u force_old_spnego!\n",
     135             :                            __func__, (unsigned int)in.length));
     136           0 :                 ntlmssp_state->force_old_spnego = true;
     137           0 :                 ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
     138           0 :                 ntlmssp_state->required_flags = 0;
     139           0 :                 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
     140           0 :                 return NT_STATUS_MORE_PROCESSING_REQUIRED;
     141             :         }
     142             : 
     143             :         /* parse the NTLMSSP packet */
     144             : 
     145          50 :         if (in.length > UINT16_MAX) {
     146           0 :                 DEBUG(1, ("%s: reject large request of length %u\n",
     147             :                         __func__, (unsigned int)in.length));
     148           0 :                 return NT_STATUS_INVALID_PARAMETER;
     149             :         }
     150             : 
     151          50 :         ok = msrpc_parse(ntlmssp_state, &in, "Cdd",
     152             :                          "NTLMSSP",
     153             :                          &ntlmssp_command,
     154             :                          &neg_flags);
     155          50 :         if (!ok) {
     156           0 :                 DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n",
     157             :                         __func__, (unsigned int)in.length));
     158           0 :                 dump_data(2, in.data, in.length);
     159           0 :                 return NT_STATUS_INVALID_PARAMETER;
     160             :         }
     161             : 
     162          50 :         if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
     163           0 :                 DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n",
     164             :                         __func__, (unsigned int)in.length));
     165           0 :                 dump_data(2, in.data, in.length);
     166           0 :                 return NT_STATUS_INVALID_PARAMETER;
     167             :         }
     168             : 
     169          50 :         ntlmssp_state->neg_flags = neg_flags;
     170          50 :         DEBUG(3, ("Imported Negotiate flags:\n"));
     171          50 :         debug_ntlmssp_flags(neg_flags);
     172             : 
     173          50 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
     174          50 :                 ntlmssp_state->unicode = true;
     175             :         } else {
     176           0 :                 ntlmssp_state->unicode = false;
     177             :         }
     178             : 
     179          50 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
     180          44 :                 gensec_security->want_features |= GENSEC_FEATURE_SIGN;
     181             :         }
     182             : 
     183          50 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
     184          12 :                 gensec_security->want_features |= GENSEC_FEATURE_SEAL;
     185             :         }
     186             : 
     187          50 :         ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
     188          50 :         ntlmssp_state->required_flags = 0;
     189             : 
     190          50 :         if (DEBUGLEVEL >= 10) {
     191           0 :                 struct NEGOTIATE_MESSAGE *negotiate = talloc(
     192             :                         ntlmssp_state, struct NEGOTIATE_MESSAGE);
     193           0 :                 if (negotiate != NULL) {
     194           0 :                         status = ntlmssp_pull_NEGOTIATE_MESSAGE(
     195             :                                 &in, negotiate, negotiate);
     196           0 :                         if (NT_STATUS_IS_OK(status)) {
     197           0 :                                 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
     198             :                                                 negotiate);
     199             :                         }
     200           0 :                         TALLOC_FREE(negotiate);
     201             :                 }
     202             :         }
     203             : 
     204          50 :         ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
     205             :                                                              in);
     206          50 :         if (ntlmssp_state->negotiate_blob.length != in.length) {
     207           0 :                 return NT_STATUS_NO_MEMORY;
     208             :         }
     209             : 
     210          50 :         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
     211             : 
     212          50 :         return NT_STATUS_MORE_PROCESSING_REQUIRED;
     213             : }
     214             : 
     215             : /**
     216             :  * Next state function for the Challenge Packet.  Generate an auth packet.
     217             :  *
     218             :  * @param gensec_security GENSEC state
     219             :  * @param out_mem_ctx Memory context for *out
     220             :  * @param in The server challnege, as a DATA_BLOB.  reply.data must be NULL
     221             :  * @param out The next request (auth packet) to the server, as an allocated DATA_BLOB, on the out_mem_ctx context
     222             :  * @return Errors or NT_STATUS_OK.
     223             :  */
     224             : 
     225       37754 : NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
     226             :                                   TALLOC_CTX *out_mem_ctx,
     227             :                                   const DATA_BLOB in, DATA_BLOB *out)
     228             : {
     229         148 :         struct gensec_ntlmssp_context *gensec_ntlmssp =
     230       37754 :                 talloc_get_type_abort(gensec_security->private_data,
     231             :                                       struct gensec_ntlmssp_context);
     232       37754 :         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     233       37754 :         uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0;
     234         148 :         DATA_BLOB server_domain_blob;
     235         148 :         DATA_BLOB challenge_blob;
     236       37754 :         DATA_BLOB target_info = data_blob(NULL, 0);
     237         148 :         char *server_domain;
     238         148 :         const char *chal_parse_string;
     239       37754 :         const char *chal_parse_string_short = NULL;
     240         148 :         const char *auth_gen_string;
     241       37754 :         DATA_BLOB lm_response = data_blob(NULL, 0);
     242       37754 :         DATA_BLOB nt_response = data_blob(NULL, 0);
     243       37754 :         DATA_BLOB session_key = data_blob(NULL, 0);
     244       37754 :         DATA_BLOB lm_session_key = data_blob(NULL, 0);
     245       37754 :         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
     246         148 :         NTSTATUS nt_status;
     247       37754 :         int flags = 0;
     248       37754 :         const char *user = NULL, *domain = NULL, *workstation = NULL;
     249       37754 :         bool is_anonymous = false;
     250       37754 :         const DATA_BLOB version_blob = ntlmssp_version_blob();
     251       37754 :         const NTTIME *server_timestamp = NULL;
     252       37754 :         uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
     253       37754 :         DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer));
     254       37754 :         gnutls_hmac_hd_t hmac_hnd = NULL;
     255         148 :         int rc;
     256             : 
     257       37754 :         TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
     258       37754 :         if (!mem_ctx) {
     259           0 :                 return NT_STATUS_NO_MEMORY;
     260             :         }
     261             : 
     262       37754 :         if (!msrpc_parse(mem_ctx,
     263             :                          &in, "CdBd",
     264             :                          "NTLMSSP",
     265             :                          &ntlmssp_command,
     266             :                          &server_domain_blob,
     267             :                          &chal_flags)) {
     268           0 :                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
     269           0 :                 dump_data(2, in.data, in.length);
     270           0 :                 talloc_free(mem_ctx);
     271             : 
     272           0 :                 return NT_STATUS_INVALID_PARAMETER;
     273             :         }
     274             : 
     275       37754 :         data_blob_free(&server_domain_blob);
     276             : 
     277       37754 :         DEBUG(3, ("Got challenge flags:\n"));
     278       37754 :         debug_ntlmssp_flags(chal_flags);
     279             : 
     280       37754 :         nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
     281             :                                              chal_flags, "challenge");
     282       37754 :         if (!NT_STATUS_IS_OK(nt_status)) {
     283           0 :                 return nt_status;
     284             :         }
     285             : 
     286       37754 :         if (ntlmssp_state->unicode) {
     287       37754 :                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
     288       37606 :                         chal_parse_string = "CdUdbddB";
     289             :                 } else {
     290           0 :                         chal_parse_string = "CdUdbdd";
     291           0 :                         chal_parse_string_short = "CdUdb";
     292             :                 }
     293       37606 :                 auth_gen_string = "CdBBUUUBdbb";
     294             :         } else {
     295           0 :                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
     296           0 :                         chal_parse_string = "CdAdbddB";
     297             :                 } else {
     298           0 :                         chal_parse_string = "CdAdbdd";
     299           0 :                         chal_parse_string_short = "CdAdb";
     300             :                 }
     301             : 
     302           0 :                 auth_gen_string = "CdBBAAABdbb";
     303             :         }
     304             : 
     305       37754 :         if (!msrpc_parse(mem_ctx,
     306             :                          &in, chal_parse_string,
     307             :                          "NTLMSSP",
     308             :                          &ntlmssp_command,
     309             :                          &server_domain,
     310             :                          &chal_flags,
     311             :                          &challenge_blob, 8,
     312             :                          &unkn1, &unkn2,
     313             :                          &target_info)) {
     314             : 
     315           0 :                 bool ok = false;
     316             : 
     317           0 :                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
     318             : 
     319           0 :                 if (chal_parse_string_short != NULL) {
     320             :                         /*
     321             :                          * In the case where NTLMSSP_NEGOTIATE_TARGET_INFO
     322             :                          * is not used, some NTLMSSP servers don't return
     323             :                          * the unused unkn1 and unkn2 fields.
     324             :                          * See bug:
     325             :                          * https://bugzilla.samba.org/show_bug.cgi?id=10016
     326             :                          * for packet traces.
     327             :                          * Try and parse again without them.
     328             :                          */
     329           0 :                         ok = msrpc_parse(mem_ctx,
     330             :                                 &in, chal_parse_string_short,
     331             :                                 "NTLMSSP",
     332             :                                 &ntlmssp_command,
     333             :                                 &server_domain,
     334             :                                 &chal_flags,
     335             :                                 &challenge_blob, 8);
     336           0 :                         if (!ok) {
     337           0 :                                 DEBUG(1, ("Failed to short parse "
     338             :                                         "the NTLMSSP Challenge: (#2)\n"));
     339             :                         }
     340             :                 }
     341             : 
     342           0 :                 if (!ok) {
     343           0 :                         dump_data(2, in.data, in.length);
     344           0 :                         talloc_free(mem_ctx);
     345           0 :                         return NT_STATUS_INVALID_PARAMETER;
     346             :                 }
     347             :         }
     348             : 
     349       37754 :         if (DEBUGLEVEL >= 10) {
     350           0 :                 struct CHALLENGE_MESSAGE *challenge =
     351           2 :                         talloc(ntlmssp_state, struct CHALLENGE_MESSAGE);
     352           2 :                 if (challenge != NULL) {
     353           0 :                         NTSTATUS status;
     354           2 :                         challenge->NegotiateFlags = chal_flags;
     355           2 :                         status = ntlmssp_pull_CHALLENGE_MESSAGE(
     356             :                                         &in, challenge, challenge);
     357           2 :                         if (NT_STATUS_IS_OK(status)) {
     358           2 :                                 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
     359             :                                                 challenge);
     360             :                         }
     361           2 :                         TALLOC_FREE(challenge);
     362             :                 }
     363             :         }
     364             : 
     365       37754 :         if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
     366       11340 :                 ntlmssp_state->server.is_standalone = true;
     367             :         } else {
     368       26414 :                 ntlmssp_state->server.is_standalone = false;
     369             :         }
     370             :         /* TODO: parse struct_blob and fill in the rest */
     371       37754 :         ntlmssp_state->server.netbios_name = "";
     372       37754 :         ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain);
     373       37754 :         ntlmssp_state->server.dns_name = "";
     374       37754 :         ntlmssp_state->server.dns_domain = "";
     375             : 
     376       37754 :         if (challenge_blob.length != 8) {
     377           0 :                 talloc_free(mem_ctx);
     378           0 :                 return NT_STATUS_INVALID_PARAMETER;
     379             :         }
     380             : 
     381       37754 :         is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials);
     382       37754 :         cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx,
     383             :                                                  &user, &domain);
     384             : 
     385       37754 :         workstation = cli_credentials_get_workstation(gensec_security->credentials);
     386             : 
     387       37754 :         if (user == NULL) {
     388           0 :                 DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
     389           0 :                 return NT_STATUS_INVALID_PARAMETER;
     390             :         }
     391             : 
     392       37754 :         if (domain == NULL) {
     393          98 :                 DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
     394          98 :                 return NT_STATUS_INVALID_PARAMETER;
     395             :         }
     396             : 
     397       37656 :         if (workstation == NULL) {
     398           0 :                 DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
     399           0 :                 return NT_STATUS_INVALID_PARAMETER;
     400             :         }
     401             : 
     402       37656 :         if (is_anonymous) {
     403        1052 :                 ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS;
     404             :                 /*
     405             :                  * don't use the ccache for anonymous auth
     406             :                  */
     407        1052 :                 ntlmssp_state->use_ccache = false;
     408             :         }
     409       37656 :         if (ntlmssp_state->use_ccache) {
     410         104 :                 struct samr_Password *nt_hash = NULL;
     411             : 
     412             :                 /*
     413             :                  * If we have a password given we don't
     414             :                  * use the ccache
     415             :                  */
     416         104 :                 nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials,
     417             :                                                       mem_ctx);
     418         104 :                 if (nt_hash != NULL) {
     419          50 :                         ZERO_STRUCTP(nt_hash);
     420          50 :                         TALLOC_FREE(nt_hash);
     421          50 :                         ntlmssp_state->use_ccache = false;
     422             :                 }
     423             :         }
     424             : 
     425       37656 :         if (ntlmssp_state->use_ccache) {
     426           0 :                 struct wbcCredentialCacheParams params;
     427          54 :                 struct wbcCredentialCacheInfo *info = NULL;
     428          54 :                 struct wbcAuthErrorInfo *error = NULL;
     429           0 :                 struct wbcNamedBlob auth_blobs[2];
     430          54 :                 const struct wbcBlob *wbc_auth_blob = NULL;
     431          54 :                 const struct wbcBlob *wbc_session_key = NULL;
     432           0 :                 wbcErr wbc_status;
     433           0 :                 size_t i;
     434          54 :                 bool new_spnego = false;
     435             : 
     436          54 :                 params.account_name = user;
     437          54 :                 params.domain_name = domain;
     438          54 :                 params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP;
     439             : 
     440          54 :                 auth_blobs[0].name = "challenge_blob";
     441          54 :                 auth_blobs[0].flags = 0;
     442          54 :                 auth_blobs[0].blob.data = in.data;
     443          54 :                 auth_blobs[0].blob.length = in.length;
     444          54 :                 auth_blobs[1].name = "negotiate_blob";
     445          54 :                 auth_blobs[1].flags = 0;
     446          54 :                 auth_blobs[1].blob.data = ntlmssp_state->negotiate_blob.data;
     447          54 :                 auth_blobs[1].blob.length = ntlmssp_state->negotiate_blob.length;
     448          54 :                 params.num_blobs = ARRAY_SIZE(auth_blobs);
     449          54 :                 params.blobs = auth_blobs;
     450             : 
     451          54 :                 wbc_status = wbcCredentialCache(&params, &info, &error);
     452          54 :                 wbcFreeMemory(error);
     453          54 :                 if (!WBC_ERROR_IS_OK(wbc_status)) {
     454           0 :                         return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
     455             :                 }
     456             : 
     457         206 :                 for (i=0; i<info->num_blobs; i++) {
     458         152 :                         if (strequal(info->blobs[i].name, "auth_blob")) {
     459          54 :                                 wbc_auth_blob = &info->blobs[i].blob;
     460             :                         }
     461         152 :                         if (strequal(info->blobs[i].name, "session_key")) {
     462          54 :                                 wbc_session_key = &info->blobs[i].blob;
     463             :                         }
     464         152 :                         if (strequal(info->blobs[i].name, "new_spnego")) {
     465          44 :                                 new_spnego = true;
     466             :                         }
     467             :                 }
     468          54 :                 if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) {
     469           0 :                         wbcFreeMemory(info);
     470           0 :                         return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
     471             :                 }
     472             : 
     473          54 :                 session_key = data_blob_talloc(mem_ctx,
     474             :                                                wbc_session_key->data,
     475             :                                                wbc_session_key->length);
     476          54 :                 if (session_key.length != wbc_session_key->length) {
     477           0 :                         wbcFreeMemory(info);
     478           0 :                         return NT_STATUS_NO_MEMORY;
     479             :                 }
     480          54 :                 *out = data_blob_talloc(mem_ctx,
     481             :                                         wbc_auth_blob->data,
     482             :                                         wbc_auth_blob->length);
     483          54 :                 if (out->length != wbc_auth_blob->length) {
     484           0 :                         wbcFreeMemory(info);
     485           0 :                         return NT_STATUS_NO_MEMORY;
     486             :                 }
     487          54 :                 ntlmssp_state->new_spnego = new_spnego;
     488             : 
     489          54 :                 wbcFreeMemory(info);
     490          54 :                 goto done;
     491             :         }
     492             : 
     493       37602 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     494       36994 :                 flags |= CLI_CRED_NTLM2;
     495             :         }
     496       37602 :         if (ntlmssp_state->use_ntlmv2) {
     497       36717 :                 flags |= CLI_CRED_NTLMv2_AUTH;
     498             :         }
     499       37602 :         if (ntlmssp_state->use_nt_response) {
     500       37602 :                 flags |= CLI_CRED_NTLM_AUTH;
     501             :         }
     502       37602 :         if (ntlmssp_state->allow_lm_response) {
     503         885 :                 flags |= CLI_CRED_LANMAN_AUTH;
     504             :         }
     505             : 
     506       37602 :         if (target_info.length != 0 && !is_anonymous) {
     507       36550 :                 struct AV_PAIR *pairs = NULL;
     508       36550 :                 uint32_t count = 0;
     509         138 :                 enum ndr_err_code err;
     510       36550 :                 struct AV_PAIR *timestamp = NULL;
     511       36550 :                 struct AV_PAIR *eol = NULL;
     512       36550 :                 uint32_t i = 0;
     513       36550 :                 const char *service = NULL;
     514       36550 :                 const char *hostname = NULL;
     515             : 
     516       36688 :                 err = ndr_pull_struct_blob(&target_info,
     517             :                                         ntlmssp_state,
     518       36550 :                                         &ntlmssp_state->server.av_pair_list,
     519             :                                         (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST);
     520       36550 :                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
     521           0 :                         return ndr_map_error2ntstatus(err);
     522             :                 }
     523             : 
     524       36550 :                 count = ntlmssp_state->server.av_pair_list.count;
     525             :                 /*
     526             :                  * We need room for Flags, SingleHost,
     527             :                  * ChannelBindings and Target
     528             :                  */
     529       36550 :                 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR,
     530             :                                           count + 4);
     531       36550 :                 if (pairs == NULL) {
     532           0 :                         return NT_STATUS_NO_MEMORY;
     533             :                 }
     534             : 
     535      254382 :                 for (i = 0; i < count; i++) {
     536      217832 :                         pairs[i] = ntlmssp_state->server.av_pair_list.pair[i];
     537             :                 }
     538             : 
     539       36550 :                 ntlmssp_state->client.av_pair_list.count = count;
     540       36550 :                 ntlmssp_state->client.av_pair_list.pair = pairs;
     541             : 
     542       36550 :                 eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
     543             :                                           MsvAvEOL);
     544       36550 :                 if (eol == NULL) {
     545           0 :                         return NT_STATUS_INVALID_PARAMETER;
     546             :                 }
     547             : 
     548       36550 :                 timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
     549             :                                                 MsvAvTimestamp);
     550       36550 :                 if (timestamp != NULL) {
     551       35082 :                         uint32_t sign_features =
     552             :                                         GENSEC_FEATURE_SESSION_KEY |
     553             :                                         GENSEC_FEATURE_SIGN |
     554             :                                         GENSEC_FEATURE_SEAL;
     555             : 
     556       35082 :                         server_timestamp = &timestamp->Value.AvTimestamp;
     557             : 
     558       35082 :                         if (ntlmssp_state->force_old_spnego) {
     559           0 :                                 sign_features = 0;
     560             :                         }
     561             : 
     562       35082 :                         if (gensec_security->want_features & sign_features) {
     563       34815 :                                 struct AV_PAIR *av_flags = NULL;
     564             : 
     565       34815 :                                 av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
     566             :                                                                MsvAvFlags);
     567       34815 :                                 if (av_flags == NULL) {
     568       34815 :                                         av_flags = eol;
     569       34815 :                                         eol++;
     570       34815 :                                         count++;
     571       34815 :                                         *eol = *av_flags;
     572       34815 :                                         av_flags->AvId = MsvAvFlags;
     573       34815 :                                         av_flags->Value.AvFlags = 0;
     574             :                                 }
     575             : 
     576       34815 :                                 av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
     577       34815 :                                 ntlmssp_state->new_spnego = true;
     578             :                         }
     579             :                 }
     580             : 
     581             :                 {
     582       36550 :                         struct AV_PAIR *SingleHost = NULL;
     583             : 
     584       36550 :                         SingleHost = eol;
     585       36550 :                         eol++;
     586       36550 :                         count++;
     587       36550 :                         *eol = *SingleHost;
     588             : 
     589             :                         /*
     590             :                          * This is not really used, but we want to
     591             :                          * add some more random bytes and match
     592             :                          * Windows.
     593             :                          */
     594       36550 :                         SingleHost->AvId = MsvAvSingleHost;
     595       36550 :                         SingleHost->Value.AvSingleHost.token_info.Flags = 0;
     596       36550 :                         SingleHost->Value.AvSingleHost.token_info.TokenIL = 0;
     597       36550 :                         generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId,
     598             :                                         sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId));
     599       36550 :                         SingleHost->Value.AvSingleHost.remaining = data_blob_null;
     600             :                 }
     601             : 
     602             :                 {
     603       36550 :                         struct AV_PAIR *ChannelBindings = NULL;
     604             : 
     605       36550 :                         ChannelBindings = eol;
     606       36550 :                         eol++;
     607       36550 :                         count++;
     608       36550 :                         *eol = *ChannelBindings;
     609             : 
     610             :                         /*
     611             :                          * gensec doesn't support channel bindings yet,
     612             :                          * but we want to match Windows on the wire
     613             :                          */
     614       36550 :                         ChannelBindings->AvId = MsvChannelBindings;
     615       36550 :                         memset(ChannelBindings->Value.ChannelBindings, 0,
     616             :                                sizeof(ChannelBindings->Value.ChannelBindings));
     617             :                 }
     618             : 
     619       36550 :                 service = gensec_get_target_service(gensec_security);
     620       36550 :                 hostname = gensec_get_target_hostname(gensec_security);
     621       36550 :                 if (service != NULL && hostname != NULL) {
     622       36119 :                         struct AV_PAIR *target = NULL;
     623             : 
     624       36119 :                         target = eol;
     625       36119 :                         eol++;
     626       36119 :                         count++;
     627       36119 :                         *eol = *target;
     628             : 
     629       36119 :                         target->AvId = MsvAvTargetName;
     630       36119 :                         target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s",
     631             :                                                                      service,
     632             :                                                                      hostname);
     633       36119 :                         if (target->Value.AvTargetName == NULL) {
     634           0 :                                 return NT_STATUS_NO_MEMORY;
     635             :                         }
     636             :                 }
     637             : 
     638       36550 :                 ntlmssp_state->client.av_pair_list.count = count;
     639       36550 :                 ntlmssp_state->client.av_pair_list.pair = pairs;
     640             : 
     641       36550 :                 err = ndr_push_struct_blob(&target_info,
     642             :                                         ntlmssp_state,
     643       36412 :                                         &ntlmssp_state->client.av_pair_list,
     644             :                                         (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
     645       36550 :                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
     646           0 :                         return NT_STATUS_NO_MEMORY;
     647             :                 }
     648             :         }
     649             : 
     650       37602 :         nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx,
     651             :                                                       &flags, challenge_blob,
     652             :                                                       server_timestamp, target_info,
     653             :                                                       &lm_response, &nt_response,
     654             :                                                       &lm_session_key, &session_key);
     655       37602 :         if (!NT_STATUS_IS_OK(nt_status)) {
     656           0 :                 return nt_status;
     657             :         }
     658             : 
     659       37602 :         if (!(flags & CLI_CRED_LANMAN_AUTH)) {
     660             :                 /* LM Key is still possible, just silly, so we do not
     661             :                  * allow it. Fortunately all LM crypto is off by
     662             :                  * default and we require command line options to end
     663             :                  * up here */
     664       36886 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
     665             :         }
     666             : 
     667       37602 :         if (!(flags & CLI_CRED_NTLM2)) {
     668             :                 /* NTLM2 is incompatible... */
     669        1686 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
     670             :         }
     671             : 
     672       37602 :         if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
     673           0 :             && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) {
     674           0 :                 DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
     675           0 :                 if (lm_response.length == 24) {
     676           0 :                         nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
     677           0 :                                                               lm_response.data,
     678             :                                                               new_session_key.data);
     679           0 :                         if (!NT_STATUS_IS_OK(nt_status)) {
     680           0 :                                 return nt_status;
     681             :                         }
     682             :                 } else {
     683           0 :                         static const uint8_t zeros[24];
     684           0 :                         nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
     685             :                                                               zeros,
     686             :                                                               new_session_key.data);
     687           0 :                         if (!NT_STATUS_IS_OK(nt_status)) {
     688           0 :                                 return nt_status;
     689             :                         }
     690             :                 }
     691           0 :                 session_key = new_session_key;
     692           0 :                 dump_data_pw("LM session key\n", session_key.data, session_key.length);
     693             :         }
     694             : 
     695             : 
     696             :         /* Key exchange encryptes a new client-generated session key with
     697             :            the password-derived key */
     698       37602 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
     699             :                 /* Make up a new session key */
     700         148 :                 uint8_t client_session_key[16];
     701         148 :                 gnutls_cipher_hd_t cipher_hnd;
     702       37602 :                 gnutls_datum_t enc_session_key = {
     703       37602 :                         .data = session_key.data,
     704       37602 :                         .size = session_key.length,
     705             :                 };
     706             : 
     707       37602 :                 generate_random_buffer(client_session_key, sizeof(client_session_key));
     708             : 
     709             :                 /* Encrypt the new session key with the old one */
     710       37602 :                 encrypted_session_key = data_blob_talloc(ntlmssp_state,
     711             :                                                          client_session_key, sizeof(client_session_key));
     712       37602 :                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
     713             : 
     714       37602 :                 rc = gnutls_cipher_init(&cipher_hnd,
     715             :                                         GNUTLS_CIPHER_ARCFOUR_128,
     716             :                                         &enc_session_key,
     717             :                                         NULL);
     718       37602 :                 if (rc < 0) {
     719           0 :                         nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     720           0 :                         ZERO_ARRAY(client_session_key);
     721           0 :                         goto done;
     722             :                 }
     723       37602 :                 rc = gnutls_cipher_encrypt(cipher_hnd,
     724       37454 :                                            encrypted_session_key.data,
     725             :                                            encrypted_session_key.length);
     726       37602 :                 gnutls_cipher_deinit(cipher_hnd);
     727       37602 :                 if (rc < 0) {
     728           0 :                         nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     729           0 :                         ZERO_ARRAY(client_session_key);
     730           0 :                         goto done;
     731             :                 }
     732             : 
     733       37602 :                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
     734             : 
     735             :                 /* Mark the new session key as the 'real' session key */
     736       37602 :                 session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key));
     737       37602 :                 ZERO_ARRAY(client_session_key);
     738             :         }
     739             : 
     740             :         /* this generates the actual auth packet */
     741       37750 :         nt_status = msrpc_gen(mem_ctx,
     742             :                        out, auth_gen_string,
     743             :                        "NTLMSSP",
     744             :                        NTLMSSP_AUTH,
     745             :                        lm_response.data, lm_response.length,
     746             :                        nt_response.data, nt_response.length,
     747             :                        domain,
     748             :                        user,
     749             :                        workstation,
     750             :                        encrypted_session_key.data, encrypted_session_key.length,
     751             :                        ntlmssp_state->neg_flags,
     752       37602 :                        version_blob.data, version_blob.length,
     753             :                        mic_blob.data, mic_blob.length);
     754       37602 :         if (!NT_STATUS_IS_OK(nt_status)) {
     755           0 :                 talloc_free(mem_ctx);
     756           0 :                 return nt_status;
     757             :         }
     758             : 
     759       37602 :         if (DEBUGLEVEL >= 10) {
     760           0 :                 struct AUTHENTICATE_MESSAGE *authenticate =
     761           2 :                         talloc(ntlmssp_state, struct AUTHENTICATE_MESSAGE);
     762           2 :                 if (authenticate != NULL) {
     763           0 :                         NTSTATUS status;
     764           2 :                         authenticate->NegotiateFlags = ntlmssp_state->neg_flags;
     765           2 :                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
     766             :                                 out, authenticate, authenticate);
     767           2 :                         if (NT_STATUS_IS_OK(status)) {
     768           2 :                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
     769             :                                                 authenticate);
     770             :                         }
     771           2 :                         TALLOC_FREE(authenticate);
     772             :                 }
     773             :         }
     774             : 
     775             :         /*
     776             :          * We always include the MIC, even without:
     777             :          * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
     778             :          * ntlmssp_state->new_spnego = true;
     779             :          *
     780             :          * This matches a Windows client.
     781             :          */
     782       37750 :         rc = gnutls_hmac_init(&hmac_hnd,
     783             :                               GNUTLS_MAC_MD5,
     784       37602 :                          session_key.data,
     785       37602 :                          MIN(session_key.length, 64));
     786       37602 :         if (rc < 0) {
     787           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     788           0 :                 goto done;
     789             :         }
     790             : 
     791       37750 :         rc = gnutls_hmac(hmac_hnd,
     792       37602 :                          ntlmssp_state->negotiate_blob.data,
     793             :                          ntlmssp_state->negotiate_blob.length);
     794       37602 :         if (rc < 0) {
     795           0 :                 gnutls_hmac_deinit(hmac_hnd, NULL);
     796           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     797           0 :                 goto done;
     798             :         }
     799       37602 :         rc = gnutls_hmac(hmac_hnd, in.data, in.length);
     800       37602 :         if (rc < 0) {
     801           0 :                 gnutls_hmac_deinit(hmac_hnd, NULL);
     802           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     803           0 :                 goto done;
     804             :         }
     805       37602 :         rc = gnutls_hmac(hmac_hnd, out->data, out->length);
     806       37602 :         if (rc < 0) {
     807           0 :                 gnutls_hmac_deinit(hmac_hnd, NULL);
     808           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     809           0 :                 goto done;
     810             :         }
     811             : 
     812       37602 :         gnutls_hmac_deinit(hmac_hnd, mic_buffer);
     813             : 
     814       37602 :         memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE);
     815       37602 :         ZERO_ARRAY(mic_buffer);
     816             : 
     817       37602 :         nt_status = NT_STATUS_OK;
     818       37656 : done:
     819       37656 :         ZERO_ARRAY_LEN(ntlmssp_state->negotiate_blob.data,
     820             :                        ntlmssp_state->negotiate_blob.length);
     821       37656 :         data_blob_free(&ntlmssp_state->negotiate_blob);
     822             : 
     823       37656 :         ntlmssp_state->session_key = session_key;
     824       37656 :         talloc_steal(ntlmssp_state, session_key.data);
     825             : 
     826       37656 :         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
     827       37656 :         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
     828             : 
     829       37656 :         talloc_steal(out_mem_ctx, out->data);
     830             : 
     831       37656 :         ntlmssp_state->expected_state = NTLMSSP_DONE;
     832             : 
     833       37656 :         if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
     834       37310 :                 nt_status = ntlmssp_sign_init(ntlmssp_state);
     835       37310 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     836           0 :                         DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
     837             :                                   nt_errstr(nt_status)));
     838           0 :                         talloc_free(mem_ctx);
     839           0 :                         return nt_status;
     840             :                 }
     841             :         }
     842             : 
     843       37656 :         talloc_free(mem_ctx);
     844       37656 :         return nt_status;
     845             : }
     846             : 
     847       38823 : NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
     848             : {
     849         298 :         struct gensec_ntlmssp_context *gensec_ntlmssp;
     850         298 :         struct ntlmssp_state *ntlmssp_state;
     851         298 :         NTSTATUS nt_status;
     852             : 
     853       38823 :         nt_status = gensec_ntlmssp_start(gensec_security);
     854       38823 :         NT_STATUS_NOT_OK_RETURN(nt_status);
     855             : 
     856         298 :         gensec_ntlmssp =
     857       38823 :                 talloc_get_type_abort(gensec_security->private_data,
     858             :                                       struct gensec_ntlmssp_context);
     859             : 
     860       38823 :         ntlmssp_state = talloc_zero(gensec_ntlmssp,
     861             :                                     struct ntlmssp_state);
     862       38823 :         if (!ntlmssp_state) {
     863           0 :                 return NT_STATUS_NO_MEMORY;
     864             :         }
     865             : 
     866       38823 :         gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
     867             : 
     868       38823 :         ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     869             : 
     870       38823 :         ntlmssp_state->role = NTLMSSP_CLIENT;
     871             : 
     872       38823 :         ntlmssp_state->client.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     873       38823 :         ntlmssp_state->client.netbios_name = cli_credentials_get_workstation(gensec_security->credentials);
     874             : 
     875       38823 :         ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
     876             : 
     877       39121 :         ntlmssp_state->use_nt_response = \
     878       38823 :                 gensec_setting_bool(gensec_security->settings,
     879             :                                     "ntlmssp_client",
     880             :                                     "send_nt_response",
     881             :                                     true);
     882             : 
     883       38823 :         ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx);
     884             : 
     885       77646 :         ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response
     886       60123 :                                               && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
     887       21598 :                                                   || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
     888             : 
     889       38823 :         ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
     890             : 
     891       38823 :         ntlmssp_state->force_old_spnego = gensec_setting_bool(gensec_security->settings,
     892             :                                                 "ntlmssp_client", "force_old_spnego", false);
     893             : 
     894       38823 :         ntlmssp_state->expected_state = NTLMSSP_INITIAL;
     895             : 
     896       38823 :         ntlmssp_state->neg_flags =
     897             :                 NTLMSSP_NEGOTIATE_NTLM |
     898             :                 NTLMSSP_NEGOTIATE_VERSION |
     899             :                 NTLMSSP_REQUEST_TARGET;
     900             : 
     901       38823 :         if (ntlmssp_state->unicode) {
     902       38823 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
     903             :         } else {
     904           0 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
     905             :         }
     906             : 
     907       38823 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
     908       38343 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
     909             :         }
     910             : 
     911       38823 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
     912         288 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
     913             :         }
     914             : 
     915       38823 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
     916         608 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
     917             :         }
     918             : 
     919       38823 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
     920       38823 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
     921             :         }
     922             : 
     923       38823 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
     924       38823 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
     925             :         }
     926             : 
     927       38823 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
     928       38215 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     929             :         } else {
     930             :                 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
     931         608 :                 ntlmssp_state->use_ntlmv2 = false;
     932             :         }
     933             : 
     934       38823 :         if (ntlmssp_state->use_ntlmv2) {
     935       37938 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     936       37938 :                 ntlmssp_state->allow_lm_response = false;
     937       37938 :                 ntlmssp_state->allow_lm_key = false;
     938             :         }
     939             : 
     940       38823 :         if (ntlmssp_state->allow_lm_key) {
     941         304 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
     942             :         }
     943             : 
     944       38823 :         if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
     945             :                 /*
     946             :                  * We need to set this to allow a later SetPassword
     947             :                  * via the SAMR pipe to succeed. Strange.... We could
     948             :                  * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
     949             :                  *
     950             :                  * Without this, Windows will not create the master key
     951             :                  * that it thinks is only used for NTLMSSP signing and
     952             :                  * sealing.  (It is actually pulled out and used directly)
     953             :                  *
     954             :                  * We don't require this here as some servers (e.g. NetAPP)
     955             :                  * doesn't support this.
     956             :                  */
     957       26740 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     958             :         }
     959       38823 :         if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     960       12650 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
     961             : 
     962       12650 :                 if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
     963             :                         /*
     964             :                          * We need to handle NTLMSSP_NEGOTIATE_SIGN as
     965             :                          * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
     966             :                          * is requested.
     967             :                          */
     968        8997 :                         ntlmssp_state->force_wrap_seal = true;
     969             :                 }
     970             :         }
     971       38823 :         if (ntlmssp_state->force_wrap_seal) {
     972           0 :                 bool ret;
     973             : 
     974             :                 /*
     975             :                  * We want also work against old Samba servers
     976             :                  * which didn't had GENSEC_FEATURE_LDAP_STYLE
     977             :                  * we negotiate SEAL too. We may remove this
     978             :                  * in a few years. As all servers should have
     979             :                  * GENSEC_FEATURE_LDAP_STYLE by then.
     980             :                  */
     981        8997 :                 ret = gensec_setting_bool(gensec_security->settings,
     982             :                                           "ntlmssp_client",
     983             :                                           "ldap_style_send_seal",
     984             :                                           true);
     985        8997 :                 if (ret) {
     986        8992 :                         ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
     987             :                 }
     988             :         }
     989       38823 :         if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     990       10716 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
     991       10716 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
     992             :         }
     993       38823 :         if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) {
     994         104 :                 ntlmssp_state->use_ccache = true;
     995             :         }
     996             : 
     997       38823 :         ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
     998       38823 :         ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
     999             : 
    1000       38823 :         return NT_STATUS_OK;
    1001             : }
    1002             : 
    1003          50 : NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security)
    1004             : {
    1005          50 :         struct gensec_ntlmssp_context *gensec_ntlmssp = NULL;
    1006           0 :         NTSTATUS status;
    1007             : 
    1008          50 :         status = gensec_ntlmssp_client_start(gensec_security);
    1009          50 :         if (!NT_STATUS_IS_OK(status)) {
    1010           0 :                 return status;
    1011             :         }
    1012             : 
    1013          50 :         gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
    1014             :                                                struct gensec_ntlmssp_context);
    1015          50 :         gensec_ntlmssp->ntlmssp_state->use_ccache = false;
    1016          50 :         gensec_ntlmssp->ntlmssp_state->resume_ccache = true;
    1017          50 :         gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
    1018             : 
    1019          50 :         return NT_STATUS_OK;
    1020             : }

Generated by: LCOV version 1.14