LCOV - code coverage report
Current view: top level - auth/ntlmssp - ntlmssp_client.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 379 500 75.8 %
Date: 2024-05-31 13:13:24 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       39391 : NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
      60             :                                 TALLOC_CTX *out_mem_ctx,
      61             :                                 DATA_BLOB in, DATA_BLOB *out)
      62             : {
      63         313 :         struct gensec_ntlmssp_context *gensec_ntlmssp =
      64       39391 :                 talloc_get_type_abort(gensec_security->private_data,
      65             :                                       struct gensec_ntlmssp_context);
      66       39391 :         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
      67         313 :         NTSTATUS status;
      68       39391 :         const DATA_BLOB version_blob = ntlmssp_version_blob();
      69             : 
      70             :         /* generate the ntlmssp negotiate packet */
      71       39704 :         status = msrpc_gen(out_mem_ctx,
      72             :                   out, "CddAAb",
      73             :                   "NTLMSSP",
      74             :                   NTLMSSP_NEGOTIATE,
      75             :                   ntlmssp_state->neg_flags,
      76             :                   "", /* domain */
      77             :                   "", /* workstation */
      78       39391 :                   version_blob.data, version_blob.length);
      79       39391 :         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       39391 :         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       39391 :         ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
     100             :                                                              *out);
     101       39391 :         if (ntlmssp_state->negotiate_blob.length != out->length) {
     102           0 :                 return NT_STATUS_NO_MEMORY;
     103             :         }
     104             : 
     105       39391 :         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
     106             : 
     107       39391 :         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       38479 : 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         165 :         struct gensec_ntlmssp_context *gensec_ntlmssp =
     230       38479 :                 talloc_get_type_abort(gensec_security->private_data,
     231             :                                       struct gensec_ntlmssp_context);
     232       38479 :         struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     233       38479 :         uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0;
     234         165 :         DATA_BLOB server_domain_blob;
     235         165 :         DATA_BLOB challenge_blob;
     236       38479 :         DATA_BLOB target_info = data_blob(NULL, 0);
     237         165 :         char *server_domain;
     238         165 :         const char *chal_parse_string;
     239       38479 :         const char *chal_parse_string_short = NULL;
     240         165 :         const char *auth_gen_string;
     241       38479 :         DATA_BLOB lm_response = data_blob(NULL, 0);
     242       38479 :         DATA_BLOB nt_response = data_blob(NULL, 0);
     243       38479 :         DATA_BLOB session_key = data_blob(NULL, 0);
     244       38479 :         DATA_BLOB lm_session_key = data_blob(NULL, 0);
     245       38479 :         DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
     246         165 :         NTSTATUS nt_status;
     247       38479 :         int flags = 0;
     248       38479 :         const char *user = NULL, *domain = NULL, *workstation = NULL;
     249       38479 :         bool is_anonymous = false;
     250       38479 :         const DATA_BLOB version_blob = ntlmssp_version_blob();
     251       38479 :         const NTTIME *server_timestamp = NULL;
     252       38479 :         uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
     253       38479 :         DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer));
     254       38479 :         gnutls_hmac_hd_t hmac_hnd = NULL;
     255         165 :         int rc;
     256             : 
     257       38479 :         TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
     258       38479 :         if (!mem_ctx) {
     259           0 :                 return NT_STATUS_NO_MEMORY;
     260             :         }
     261             : 
     262       38479 :         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       38479 :         data_blob_free(&server_domain_blob);
     276             : 
     277       38479 :         DEBUG(3, ("Got challenge flags:\n"));
     278       38479 :         debug_ntlmssp_flags(chal_flags);
     279             : 
     280       38479 :         nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
     281             :                                              chal_flags, "challenge");
     282       38479 :         if (!NT_STATUS_IS_OK(nt_status)) {
     283           0 :                 return nt_status;
     284             :         }
     285             : 
     286       38479 :         if (ntlmssp_state->unicode) {
     287       38479 :                 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
     288       38314 :                         chal_parse_string = "CdUdbddB";
     289             :                 } else {
     290           0 :                         chal_parse_string = "CdUdbdd";
     291           0 :                         chal_parse_string_short = "CdUdb";
     292             :                 }
     293       38314 :                 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       38479 :         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       38479 :         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       38479 :         if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
     366       11751 :                 ntlmssp_state->server.is_standalone = true;
     367             :         } else {
     368       26728 :                 ntlmssp_state->server.is_standalone = false;
     369             :         }
     370             :         /* TODO: parse struct_blob and fill in the rest */
     371       38479 :         ntlmssp_state->server.netbios_name = "";
     372       38479 :         ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain);
     373       38479 :         ntlmssp_state->server.dns_name = "";
     374       38479 :         ntlmssp_state->server.dns_domain = "";
     375             : 
     376       38479 :         if (challenge_blob.length != 8) {
     377           0 :                 talloc_free(mem_ctx);
     378           0 :                 return NT_STATUS_INVALID_PARAMETER;
     379             :         }
     380             : 
     381       38479 :         is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials);
     382       38479 :         cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx,
     383             :                                                  &user, &domain);
     384             : 
     385       38479 :         workstation = cli_credentials_get_workstation(gensec_security->credentials);
     386             : 
     387       38479 :         if (user == NULL) {
     388           0 :                 DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
     389           0 :                 return NT_STATUS_INVALID_PARAMETER;
     390             :         }
     391             : 
     392       38479 :         if (domain == NULL) {
     393          97 :                 DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
     394          97 :                 return NT_STATUS_INVALID_PARAMETER;
     395             :         }
     396             : 
     397       38382 :         if (workstation == NULL) {
     398           0 :                 DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
     399           0 :                 return NT_STATUS_INVALID_PARAMETER;
     400             :         }
     401             : 
     402       38382 :         if (is_anonymous) {
     403        1111 :                 ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS;
     404             :                 /*
     405             :                  * don't use the ccache for anonymous auth
     406             :                  */
     407        1111 :                 ntlmssp_state->use_ccache = false;
     408             :         }
     409       38382 :         if (ntlmssp_state->use_ccache) {
     410         103 :                 struct samr_Password *nt_hash = NULL;
     411             : 
     412             :                 /*
     413             :                  * If we have a password given we don't
     414             :                  * use the ccache
     415             :                  */
     416         103 :                 nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials,
     417             :                                                       mem_ctx);
     418         103 :                 if (nt_hash != NULL) {
     419          49 :                         ZERO_STRUCTP(nt_hash);
     420          49 :                         TALLOC_FREE(nt_hash);
     421          49 :                         ntlmssp_state->use_ccache = false;
     422             :                 }
     423             :         }
     424             : 
     425       38382 :         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       38328 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     494       37720 :                 flags |= CLI_CRED_NTLM2;
     495             :         }
     496       38328 :         if (ntlmssp_state->use_ntlmv2) {
     497       37443 :                 flags |= CLI_CRED_NTLMv2_AUTH;
     498             :         }
     499       38328 :         if (ntlmssp_state->use_nt_response) {
     500       38328 :                 flags |= CLI_CRED_NTLM_AUTH;
     501             :         }
     502       38328 :         if (ntlmssp_state->allow_lm_response) {
     503         885 :                 flags |= CLI_CRED_LANMAN_AUTH;
     504             :         }
     505             : 
     506       38328 :         if (target_info.length != 0 && !is_anonymous) {
     507       37217 :                 struct AV_PAIR *pairs = NULL;
     508       37217 :                 uint32_t count = 0;
     509         145 :                 enum ndr_err_code err;
     510       37217 :                 struct AV_PAIR *timestamp = NULL;
     511       37217 :                 struct AV_PAIR *eol = NULL;
     512       37217 :                 uint32_t i = 0;
     513       37217 :                 const char *service = NULL;
     514       37217 :                 const char *hostname = NULL;
     515             : 
     516       37362 :                 err = ndr_pull_struct_blob(&target_info,
     517             :                                         ntlmssp_state,
     518       37217 :                                         &ntlmssp_state->server.av_pair_list,
     519             :                                         (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST);
     520       37217 :                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
     521           0 :                         return ndr_map_error2ntstatus(err);
     522             :                 }
     523             : 
     524       37217 :                 count = ntlmssp_state->server.av_pair_list.count;
     525             :                 /*
     526             :                  * We need room for Flags, SingleHost,
     527             :                  * ChannelBindings and Target
     528             :                  */
     529       37217 :                 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR,
     530             :                                           count + 4);
     531       37217 :                 if (pairs == NULL) {
     532           0 :                         return NT_STATUS_NO_MEMORY;
     533             :                 }
     534             : 
     535      259053 :                 for (i = 0; i < count; i++) {
     536      221836 :                         pairs[i] = ntlmssp_state->server.av_pair_list.pair[i];
     537             :                 }
     538             : 
     539       37217 :                 ntlmssp_state->client.av_pair_list.count = count;
     540       37217 :                 ntlmssp_state->client.av_pair_list.pair = pairs;
     541             : 
     542       37217 :                 eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
     543             :                                           MsvAvEOL);
     544       37217 :                 if (eol == NULL) {
     545           0 :                         return NT_STATUS_INVALID_PARAMETER;
     546             :                 }
     547             : 
     548       37217 :                 timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
     549             :                                                 MsvAvTimestamp);
     550       37217 :                 if (timestamp != NULL) {
     551       35751 :                         uint32_t sign_features =
     552             :                                         GENSEC_FEATURE_SESSION_KEY |
     553             :                                         GENSEC_FEATURE_SIGN |
     554             :                                         GENSEC_FEATURE_SEAL;
     555             : 
     556       35751 :                         server_timestamp = &timestamp->Value.AvTimestamp;
     557             : 
     558       35751 :                         if (ntlmssp_state->force_old_spnego) {
     559           0 :                                 sign_features = 0;
     560             :                         }
     561             : 
     562       35751 :                         if (gensec_security->want_features & sign_features) {
     563       35420 :                                 struct AV_PAIR *av_flags = NULL;
     564             : 
     565       35420 :                                 av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
     566             :                                                                MsvAvFlags);
     567       35420 :                                 if (av_flags == NULL) {
     568       35420 :                                         av_flags = eol;
     569       35420 :                                         eol++;
     570       35420 :                                         count++;
     571       35420 :                                         *eol = *av_flags;
     572       35420 :                                         av_flags->AvId = MsvAvFlags;
     573       35420 :                                         av_flags->Value.AvFlags = 0;
     574             :                                 }
     575             : 
     576       35420 :                                 av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
     577       35420 :                                 ntlmssp_state->new_spnego = true;
     578             :                         }
     579             :                 }
     580             : 
     581             :                 {
     582       37217 :                         struct AV_PAIR *SingleHost = NULL;
     583             : 
     584       37217 :                         SingleHost = eol;
     585       37217 :                         eol++;
     586       37217 :                         count++;
     587       37217 :                         *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       37217 :                         SingleHost->AvId = MsvAvSingleHost;
     595       37217 :                         SingleHost->Value.AvSingleHost.token_info.Flags = 0;
     596       37217 :                         SingleHost->Value.AvSingleHost.token_info.TokenIL = 0;
     597       37217 :                         generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId,
     598             :                                         sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId));
     599       37217 :                         SingleHost->Value.AvSingleHost.remaining = data_blob_null;
     600             :                 }
     601             : 
     602       37217 :                 if (!(gensec_security->want_features & GENSEC_FEATURE_CB_OPTIONAL)
     603          40 :                     || gensec_security->channel_bindings != NULL)
     604             :                 {
     605       37202 :                         struct AV_PAIR *ChannelBindings = NULL;
     606             : 
     607       37202 :                         ChannelBindings = eol;
     608       37202 :                         eol++;
     609       37202 :                         count++;
     610       37202 :                         *eol = *ChannelBindings;
     611             : 
     612       37202 :                         ChannelBindings->AvId = MsvChannelBindings;
     613       37347 :                         nt_status = ntlmssp_hash_channel_bindings(gensec_security,
     614       37202 :                                         ChannelBindings->Value.ChannelBindings);
     615       37202 :                         if (!NT_STATUS_IS_OK(nt_status)) {
     616           0 :                                 return nt_status;
     617             :                         }
     618             :                 }
     619             : 
     620       37217 :                 service = gensec_get_target_service(gensec_security);
     621       37217 :                 hostname = gensec_get_target_hostname(gensec_security);
     622       37217 :                 if (service != NULL && hostname != NULL) {
     623       36786 :                         struct AV_PAIR *target = NULL;
     624             : 
     625       36786 :                         target = eol;
     626       36786 :                         eol++;
     627       36786 :                         count++;
     628       36786 :                         *eol = *target;
     629             : 
     630       36786 :                         target->AvId = MsvAvTargetName;
     631       36786 :                         target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s",
     632             :                                                                      service,
     633             :                                                                      hostname);
     634       36786 :                         if (target->Value.AvTargetName == NULL) {
     635           0 :                                 return NT_STATUS_NO_MEMORY;
     636             :                         }
     637             :                 }
     638             : 
     639       37217 :                 ntlmssp_state->client.av_pair_list.count = count;
     640       37217 :                 ntlmssp_state->client.av_pair_list.pair = pairs;
     641             : 
     642       37217 :                 err = ndr_push_struct_blob(&target_info,
     643             :                                         ntlmssp_state,
     644       37072 :                                         &ntlmssp_state->client.av_pair_list,
     645             :                                         (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
     646       37217 :                 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
     647           0 :                         return NT_STATUS_NO_MEMORY;
     648             :                 }
     649             :         }
     650             : 
     651       38328 :         nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx,
     652             :                                                       &flags, challenge_blob,
     653             :                                                       server_timestamp, target_info,
     654             :                                                       &lm_response, &nt_response,
     655             :                                                       &lm_session_key, &session_key);
     656       38328 :         if (!NT_STATUS_IS_OK(nt_status)) {
     657           0 :                 return nt_status;
     658             :         }
     659             : 
     660       38328 :         if (!(flags & CLI_CRED_LANMAN_AUTH)) {
     661             :                 /* LM Key is still possible, just silly, so we do not
     662             :                  * allow it. Fortunately all LM crypto is off by
     663             :                  * default and we require command line options to end
     664             :                  * up here */
     665       37612 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
     666             :         }
     667             : 
     668       38328 :         if (!(flags & CLI_CRED_NTLM2)) {
     669             :                 /* NTLM2 is incompatible... */
     670        1745 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
     671             :         }
     672             : 
     673       38328 :         if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
     674           0 :             && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) {
     675           0 :                 DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
     676           0 :                 if (lm_response.length == 24) {
     677           0 :                         nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
     678           0 :                                                               lm_response.data,
     679             :                                                               new_session_key.data);
     680           0 :                         if (!NT_STATUS_IS_OK(nt_status)) {
     681           0 :                                 return nt_status;
     682             :                         }
     683             :                 } else {
     684           0 :                         static const uint8_t zeros[24];
     685           0 :                         nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
     686             :                                                               zeros,
     687             :                                                               new_session_key.data);
     688           0 :                         if (!NT_STATUS_IS_OK(nt_status)) {
     689           0 :                                 return nt_status;
     690             :                         }
     691             :                 }
     692           0 :                 session_key = new_session_key;
     693           0 :                 dump_data_pw("LM session key\n", session_key.data, session_key.length);
     694             :         }
     695             : 
     696             : 
     697             :         /* Key exchange encryptes a new client-generated session key with
     698             :            the password-derived key */
     699       38328 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
     700             :                 /* Make up a new session key */
     701         165 :                 uint8_t client_session_key[16];
     702         165 :                 gnutls_cipher_hd_t cipher_hnd;
     703       38328 :                 gnutls_datum_t enc_session_key = {
     704       38328 :                         .data = session_key.data,
     705       38328 :                         .size = session_key.length,
     706             :                 };
     707             : 
     708       38328 :                 generate_random_buffer(client_session_key, sizeof(client_session_key));
     709             : 
     710             :                 /* Encrypt the new session key with the old one */
     711       38328 :                 encrypted_session_key = data_blob_talloc(ntlmssp_state,
     712             :                                                          client_session_key, sizeof(client_session_key));
     713       38328 :                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
     714             : 
     715       38328 :                 rc = gnutls_cipher_init(&cipher_hnd,
     716             :                                         GNUTLS_CIPHER_ARCFOUR_128,
     717             :                                         &enc_session_key,
     718             :                                         NULL);
     719       38328 :                 if (rc < 0) {
     720           0 :                         nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     721           0 :                         ZERO_ARRAY(client_session_key);
     722           0 :                         goto done;
     723             :                 }
     724       38328 :                 rc = gnutls_cipher_encrypt(cipher_hnd,
     725       38163 :                                            encrypted_session_key.data,
     726             :                                            encrypted_session_key.length);
     727       38328 :                 gnutls_cipher_deinit(cipher_hnd);
     728       38328 :                 if (rc < 0) {
     729           0 :                         nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     730           0 :                         ZERO_ARRAY(client_session_key);
     731           0 :                         goto done;
     732             :                 }
     733             : 
     734       38328 :                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
     735             : 
     736             :                 /* Mark the new session key as the 'real' session key */
     737       38328 :                 session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key));
     738       38328 :                 ZERO_ARRAY(client_session_key);
     739             :         }
     740             : 
     741             :         /* this generates the actual auth packet */
     742       38493 :         nt_status = msrpc_gen(mem_ctx,
     743             :                        out, auth_gen_string,
     744             :                        "NTLMSSP",
     745             :                        NTLMSSP_AUTH,
     746             :                        lm_response.data, lm_response.length,
     747             :                        nt_response.data, nt_response.length,
     748             :                        domain,
     749             :                        user,
     750             :                        workstation,
     751             :                        encrypted_session_key.data, encrypted_session_key.length,
     752             :                        ntlmssp_state->neg_flags,
     753       38328 :                        version_blob.data, version_blob.length,
     754             :                        mic_blob.data, mic_blob.length);
     755       38328 :         if (!NT_STATUS_IS_OK(nt_status)) {
     756           0 :                 talloc_free(mem_ctx);
     757           0 :                 return nt_status;
     758             :         }
     759             : 
     760       38328 :         if (DEBUGLEVEL >= 10) {
     761           0 :                 struct AUTHENTICATE_MESSAGE *authenticate =
     762           2 :                         talloc(ntlmssp_state, struct AUTHENTICATE_MESSAGE);
     763           2 :                 if (authenticate != NULL) {
     764           0 :                         NTSTATUS status;
     765           2 :                         authenticate->NegotiateFlags = ntlmssp_state->neg_flags;
     766           2 :                         status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
     767             :                                 out, authenticate, authenticate);
     768           2 :                         if (NT_STATUS_IS_OK(status)) {
     769           2 :                                 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
     770             :                                                 authenticate);
     771             :                         }
     772           2 :                         TALLOC_FREE(authenticate);
     773             :                 }
     774             :         }
     775             : 
     776             :         /*
     777             :          * We always include the MIC, even without:
     778             :          * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
     779             :          * ntlmssp_state->new_spnego = true;
     780             :          *
     781             :          * This matches a Windows client.
     782             :          */
     783       38493 :         rc = gnutls_hmac_init(&hmac_hnd,
     784             :                               GNUTLS_MAC_MD5,
     785       38328 :                          session_key.data,
     786       38328 :                          MIN(session_key.length, 64));
     787       38328 :         if (rc < 0) {
     788           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     789           0 :                 goto done;
     790             :         }
     791             : 
     792       38493 :         rc = gnutls_hmac(hmac_hnd,
     793       38328 :                          ntlmssp_state->negotiate_blob.data,
     794             :                          ntlmssp_state->negotiate_blob.length);
     795       38328 :         if (rc < 0) {
     796           0 :                 gnutls_hmac_deinit(hmac_hnd, NULL);
     797           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     798           0 :                 goto done;
     799             :         }
     800       38328 :         rc = gnutls_hmac(hmac_hnd, in.data, in.length);
     801       38328 :         if (rc < 0) {
     802           0 :                 gnutls_hmac_deinit(hmac_hnd, NULL);
     803           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     804           0 :                 goto done;
     805             :         }
     806       38328 :         rc = gnutls_hmac(hmac_hnd, out->data, out->length);
     807       38328 :         if (rc < 0) {
     808           0 :                 gnutls_hmac_deinit(hmac_hnd, NULL);
     809           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     810           0 :                 goto done;
     811             :         }
     812             : 
     813       38328 :         gnutls_hmac_deinit(hmac_hnd, mic_buffer);
     814             : 
     815       38328 :         memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE);
     816       38328 :         ZERO_ARRAY(mic_buffer);
     817             : 
     818       38328 :         nt_status = NT_STATUS_OK;
     819       38382 : done:
     820       38382 :         ZERO_ARRAY_LEN(ntlmssp_state->negotiate_blob.data,
     821             :                        ntlmssp_state->negotiate_blob.length);
     822       38382 :         data_blob_free(&ntlmssp_state->negotiate_blob);
     823             : 
     824       38382 :         ntlmssp_state->session_key = session_key;
     825       38382 :         talloc_steal(ntlmssp_state, session_key.data);
     826             : 
     827       38382 :         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
     828       38382 :         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
     829             : 
     830       38382 :         talloc_steal(out_mem_ctx, out->data);
     831             : 
     832       38382 :         ntlmssp_state->expected_state = NTLMSSP_DONE;
     833             : 
     834       38382 :         if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
     835       37972 :                 nt_status = ntlmssp_sign_init(ntlmssp_state);
     836       37972 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     837           0 :                         DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
     838             :                                   nt_errstr(nt_status)));
     839           0 :                         talloc_free(mem_ctx);
     840           0 :                         return nt_status;
     841             :                 }
     842             :         }
     843             : 
     844       38382 :         talloc_free(mem_ctx);
     845       38382 :         return nt_status;
     846             : }
     847             : 
     848       39548 : NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
     849             : {
     850         315 :         struct gensec_ntlmssp_context *gensec_ntlmssp;
     851         315 :         struct ntlmssp_state *ntlmssp_state;
     852         315 :         NTSTATUS nt_status;
     853             : 
     854       39548 :         nt_status = gensec_ntlmssp_start(gensec_security);
     855       39548 :         NT_STATUS_NOT_OK_RETURN(nt_status);
     856             : 
     857         315 :         gensec_ntlmssp =
     858       39548 :                 talloc_get_type_abort(gensec_security->private_data,
     859             :                                       struct gensec_ntlmssp_context);
     860             : 
     861       39548 :         ntlmssp_state = talloc_zero(gensec_ntlmssp,
     862             :                                     struct ntlmssp_state);
     863       39548 :         if (!ntlmssp_state) {
     864           0 :                 return NT_STATUS_NO_MEMORY;
     865             :         }
     866             : 
     867       39548 :         gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
     868             : 
     869       39548 :         ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     870             : 
     871       39548 :         ntlmssp_state->role = NTLMSSP_CLIENT;
     872             : 
     873       39548 :         ntlmssp_state->client.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     874       39548 :         ntlmssp_state->client.netbios_name = cli_credentials_get_workstation(gensec_security->credentials);
     875             : 
     876       39548 :         ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
     877             : 
     878       39863 :         ntlmssp_state->use_nt_response = \
     879       39548 :                 gensec_setting_bool(gensec_security->settings,
     880             :                                     "ntlmssp_client",
     881             :                                     "send_nt_response",
     882             :                                     true);
     883             : 
     884       39548 :         ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx);
     885             : 
     886       79096 :         ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response
     887       61132 :                                               && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
     888       21899 :                                                   || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
     889             : 
     890       39548 :         ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
     891             : 
     892       39548 :         ntlmssp_state->force_old_spnego = gensec_setting_bool(gensec_security->settings,
     893             :                                                 "ntlmssp_client", "force_old_spnego", false);
     894             : 
     895       39548 :         ntlmssp_state->expected_state = NTLMSSP_INITIAL;
     896             : 
     897       39548 :         ntlmssp_state->neg_flags =
     898             :                 NTLMSSP_NEGOTIATE_NTLM |
     899             :                 NTLMSSP_NEGOTIATE_VERSION |
     900             :                 NTLMSSP_REQUEST_TARGET;
     901             : 
     902       39548 :         if (ntlmssp_state->unicode) {
     903       39548 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
     904             :         } else {
     905           0 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
     906             :         }
     907             : 
     908       39548 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
     909       39068 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
     910             :         }
     911             : 
     912       39548 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
     913         288 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
     914             :         }
     915             : 
     916       39548 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
     917         608 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
     918             :         }
     919             : 
     920       39548 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
     921       39548 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
     922             :         }
     923             : 
     924       39548 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
     925       39548 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
     926             :         }
     927             : 
     928       39548 :         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
     929       38940 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     930             :         } else {
     931             :                 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
     932         608 :                 ntlmssp_state->use_ntlmv2 = false;
     933             :         }
     934             : 
     935       39548 :         if (ntlmssp_state->use_ntlmv2) {
     936       38663 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     937       38663 :                 ntlmssp_state->allow_lm_response = false;
     938       38663 :                 ntlmssp_state->allow_lm_key = false;
     939             :         }
     940             : 
     941       39548 :         if (ntlmssp_state->allow_lm_key) {
     942         304 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
     943             :         }
     944             : 
     945       39548 :         if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
     946             :                 /*
     947             :                  * We need to set this to allow a later SetPassword
     948             :                  * via the SAMR pipe to succeed. Strange.... We could
     949             :                  * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
     950             :                  *
     951             :                  * Without this, Windows will not create the master key
     952             :                  * that it thinks is only used for NTLMSSP signing and
     953             :                  * sealing.  (It is actually pulled out and used directly)
     954             :                  *
     955             :                  * We don't require this here as some servers (e.g. NetAPP)
     956             :                  * doesn't support this.
     957             :                  */
     958       27341 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     959             :         }
     960       39548 :         if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     961       12680 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
     962             : 
     963       12680 :                 if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
     964             :                         /*
     965             :                          * We need to handle NTLMSSP_NEGOTIATE_SIGN as
     966             :                          * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
     967             :                          * is requested.
     968             :                          */
     969        9019 :                         ntlmssp_state->force_wrap_seal = true;
     970             :                 }
     971             :         }
     972       39548 :         if (ntlmssp_state->force_wrap_seal) {
     973           0 :                 bool ret;
     974             : 
     975             :                 /*
     976             :                  * We want also work against old Samba servers
     977             :                  * which didn't had GENSEC_FEATURE_LDAP_STYLE
     978             :                  * we negotiate SEAL too. We may remove this
     979             :                  * in a few years. As all servers should have
     980             :                  * GENSEC_FEATURE_LDAP_STYLE by then.
     981             :                  */
     982        9019 :                 ret = gensec_setting_bool(gensec_security->settings,
     983             :                                           "ntlmssp_client",
     984             :                                           "ldap_style_send_seal",
     985             :                                           true);
     986        9019 :                 if (ret) {
     987        9014 :                         ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
     988             :                 }
     989             :         }
     990       39548 :         if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     991       10777 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
     992       10777 :                 ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
     993             :         }
     994       39548 :         if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) {
     995         103 :                 ntlmssp_state->use_ccache = true;
     996             :         }
     997             : 
     998       39548 :         ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
     999       39548 :         ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;
    1000             : 
    1001       39548 :         return NT_STATUS_OK;
    1002             : }
    1003             : 
    1004          50 : NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security)
    1005             : {
    1006          50 :         struct gensec_ntlmssp_context *gensec_ntlmssp = NULL;
    1007           0 :         NTSTATUS status;
    1008             : 
    1009          50 :         status = gensec_ntlmssp_client_start(gensec_security);
    1010          50 :         if (!NT_STATUS_IS_OK(status)) {
    1011           0 :                 return status;
    1012             :         }
    1013             : 
    1014          50 :         gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
    1015             :                                                struct gensec_ntlmssp_context);
    1016          50 :         gensec_ntlmssp->ntlmssp_state->use_ccache = false;
    1017          50 :         gensec_ntlmssp->ntlmssp_state->resume_ccache = true;
    1018          50 :         gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
    1019             : 
    1020          50 :         return NT_STATUS_OK;
    1021             : }

Generated by: LCOV version 1.14