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