source: vendor/current/auth/ntlmssp/ntlmssp_client.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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