2 Unix SMB/Netbios implementation.
4 handle NTLMSSP, server side
6 Copyright (C) Andrew Tridgell 2001
7 Copyright (C) Andrew Bartlett 2001-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "lib/util/tevent_ntstatus.h"
26 #include "lib/util/time_basic.h"
27 #include "auth/ntlmssp/ntlmssp.h"
28 #include "auth/ntlmssp/ntlmssp_private.h"
29 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
30 #include "auth/ntlmssp/ntlmssp_ndr.h"
31 #include "../libcli/auth/libcli_auth.h"
32 #include "auth/gensec/gensec.h"
33 #include "auth/gensec/gensec_internal.h"
34 #include "auth/common_auth.h"
35 #include "param/param.h"
36 #include "param/loadparm.h"
37 #include "libcli/security/session.h"
39 #include "lib/crypto/gnutls_helpers.h"
40 #include <gnutls/gnutls.h>
41 #include <gnutls/crypto.h>
44 #define DBGC_CLASS DBGC_AUTH
47 * Determine correct target name flags for reply, given server role
48 * and negotiated flags
50 * @param ntlmssp_state NTLMSSP State
51 * @param neg_flags The flags from the packet
52 * @param chal_flags The flags to be set in the reply packet
53 * @return The 'target name' string.
56 const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
57 uint32_t neg_flags, uint32_t *chal_flags)
59 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
60 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
61 *chal_flags |= NTLMSSP_REQUEST_TARGET;
62 if (ntlmssp_state->server.is_standalone) {
63 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
64 return ntlmssp_state->server.netbios_name;
66 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
67 return ntlmssp_state->server.netbios_domain;
75 * Next state function for the NTLMSSP Negotiate packet
77 * @param gensec_security GENSEC state
78 * @param out_mem_ctx Memory context for *out
79 * @param in The request, as a DATA_BLOB. reply.data must be NULL
80 * @param out The reply, as an allocated DATA_BLOB, caller to free.
81 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
84 NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
85 TALLOC_CTX *out_mem_ctx,
86 const DATA_BLOB request, DATA_BLOB *reply)
88 struct gensec_ntlmssp_context *gensec_ntlmssp =
89 talloc_get_type_abort(gensec_security->private_data,
90 struct gensec_ntlmssp_context);
91 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
92 struct auth4_context *auth_context = gensec_security->auth_context;
93 DATA_BLOB struct_blob;
94 uint32_t neg_flags = 0;
95 uint32_t ntlmssp_command, chal_flags;
97 const char *target_name;
99 struct timeval tv_now = timeval_current();
103 * Windows NT 4.0, windows_2000: use 30 minutes,
104 * Windows XP, Windows Server 2003, Windows Vista,
105 * Windows Server 2008, Windows 7, and Windows Server 2008 R2
108 * Newer systems doesn't check this, likely because the
109 * connectionless NTLMSSP is no longer supported.
111 * As we expect the AUTHENTICATION_MESSAGE to arrive
112 * directly after the NEGOTIATE_MESSAGE (typically less than
113 * as 1 second later). We use a hard timeout of 30 Minutes.
115 * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp
116 * instead we just remember our own time.
118 uint32_t max_lifetime = 30 * 60;
119 struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0);
121 /* parse the NTLMSSP packet */
123 file_save("ntlmssp_negotiate.dat", request.data, request.length);
126 if (request.length) {
127 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
131 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
132 (unsigned int)request.length));
133 dump_data(2, request.data, request.length);
134 return NT_STATUS_INVALID_PARAMETER;
136 debug_ntlmssp_flags(neg_flags);
138 if (DEBUGLEVEL >= 10) {
139 struct NEGOTIATE_MESSAGE *negotiate = talloc(
140 ntlmssp_state, struct NEGOTIATE_MESSAGE);
141 if (negotiate != NULL) {
142 status = ntlmssp_pull_NEGOTIATE_MESSAGE(
143 &request, negotiate, negotiate);
144 if (NT_STATUS_IS_OK(status)) {
145 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
148 TALLOC_FREE(negotiate);
153 status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
154 if (!NT_STATUS_IS_OK(status)){
158 /* Ask our caller what challenge they would like in the packet */
159 if (auth_context->get_ntlm_challenge) {
160 status = auth_context->get_ntlm_challenge(auth_context, cryptkey);
161 if (!NT_STATUS_IS_OK(status)) {
162 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
167 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
168 return NT_STATUS_NOT_IMPLEMENTED;
171 /* The flags we send back are not just the negotiated flags,
172 * they are also 'what is in this packet'. Therefore, we
173 * operate on 'chal_flags' from here on
176 chal_flags = ntlmssp_state->neg_flags;
177 ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end);
179 /* get the right name to fill in as 'target' */
180 target_name = ntlmssp_target_name(ntlmssp_state,
181 neg_flags, &chal_flags);
182 if (target_name == NULL)
183 return NT_STATUS_INVALID_PARAMETER;
185 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
186 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
189 /* This creates the 'blob' of names that appears at the end of the packet */
190 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
191 enum ndr_err_code err;
192 struct AV_PAIR *pairs = NULL;
195 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
197 return NT_STATUS_NO_MEMORY;
200 pairs[0].AvId = MsvAvNbDomainName;
201 pairs[0].Value.AvNbDomainName = target_name;
203 pairs[1].AvId = MsvAvNbComputerName;
204 pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name;
206 pairs[2].AvId = MsvAvDnsDomainName;
207 pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain;
209 pairs[3].AvId = MsvAvDnsComputerName;
210 pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name;
212 if (!ntlmssp_state->force_old_spnego) {
213 pairs[4].AvId = MsvAvTimestamp;
214 pairs[4].Value.AvTimestamp =
215 timeval_to_nttime(&tv_now);
218 pairs[5].AvId = MsvAvEOL;
220 pairs[4].AvId = MsvAvEOL;
223 ntlmssp_state->server.av_pair_list.count = count;
224 ntlmssp_state->server.av_pair_list.pair = pairs;
226 err = ndr_push_struct_blob(&struct_blob,
228 &ntlmssp_state->server.av_pair_list,
229 (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
230 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
231 return NT_STATUS_NO_MEMORY;
234 struct_blob = data_blob_null;
238 /* Marshal the packet in the right format, be it unicode or ASCII */
239 const char *gen_string;
240 const DATA_BLOB version_blob = ntlmssp_version_blob();
242 if (ntlmssp_state->unicode) {
243 gen_string = "CdUdbddBb";
245 gen_string = "CdAdbddBb";
248 status = msrpc_gen(out_mem_ctx, reply, gen_string,
255 struct_blob.data, struct_blob.length,
256 version_blob.data, version_blob.length);
258 if (!NT_STATUS_IS_OK(status)) {
259 data_blob_free(&struct_blob);
263 if (DEBUGLEVEL >= 10) {
264 struct CHALLENGE_MESSAGE *challenge = talloc(
265 ntlmssp_state, struct CHALLENGE_MESSAGE);
266 if (challenge != NULL) {
267 challenge->NegotiateFlags = chal_flags;
268 status = ntlmssp_pull_CHALLENGE_MESSAGE(
269 reply, challenge, challenge);
270 if (NT_STATUS_IS_OK(status)) {
271 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
274 TALLOC_FREE(challenge);
279 data_blob_free(&struct_blob);
281 ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
283 if (ntlmssp_state->negotiate_blob.length != request.length) {
284 return NT_STATUS_NO_MEMORY;
287 ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state,
289 if (ntlmssp_state->challenge_blob.length != reply->length) {
290 return NT_STATUS_NO_MEMORY;
293 ntlmssp_state->expected_state = NTLMSSP_AUTH;
295 return NT_STATUS_MORE_PROCESSING_REQUIRED;
298 struct ntlmssp_server_auth_state {
299 struct gensec_security *gensec_security;
300 struct gensec_ntlmssp_context *gensec_ntlmssp;
302 struct auth_usersupplied_info *user_info;
303 DATA_BLOB user_session_key;
304 DATA_BLOB lm_session_key;
305 /* internal variables used by KEY_EXCH (client-supplied user session key */
306 DATA_BLOB encrypted_session_key;
308 /* internal variables used by NTLM2 */
309 uint8_t session_nonce[16];
312 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
313 struct gensec_ntlmssp_context *gensec_ntlmssp,
314 struct ntlmssp_server_auth_state *state,
315 const DATA_BLOB request);
316 static void ntlmssp_server_auth_done(struct tevent_req *subreq);
317 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
318 struct gensec_ntlmssp_context *gensec_ntlmssp,
319 struct ntlmssp_server_auth_state *state,
322 struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
323 struct tevent_context *ev,
324 struct gensec_security *gensec_security,
327 struct gensec_ntlmssp_context *gensec_ntlmssp =
328 talloc_get_type_abort(gensec_security->private_data,
329 struct gensec_ntlmssp_context);
330 struct auth4_context *auth_context = gensec_security->auth_context;
331 struct tevent_req *req = NULL;
332 struct tevent_req *subreq = NULL;
333 struct ntlmssp_server_auth_state *state = NULL;
336 req = tevent_req_create(mem_ctx, &state,
337 struct ntlmssp_server_auth_state);
341 state->gensec_security = gensec_security;
342 state->gensec_ntlmssp = gensec_ntlmssp;
345 status = ntlmssp_server_preauth(gensec_security,
348 if (tevent_req_nterror(req, status)) {
349 return tevent_req_post(req, ev);
352 subreq = auth_context->check_ntlm_password_send(
353 state, ev, auth_context, state->user_info);
354 if (tevent_req_nomem(subreq, req)) {
355 return tevent_req_post(req, ev);
357 tevent_req_set_callback(subreq, ntlmssp_server_auth_done, req);
362 * Next state function for the Authenticate packet
364 * @param ntlmssp_state NTLMSSP State
365 * @param request The request, as a DATA_BLOB
366 * @return Errors or NT_STATUS_OK.
369 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
370 struct gensec_ntlmssp_context *gensec_ntlmssp,
371 struct ntlmssp_server_auth_state *state,
372 const DATA_BLOB request)
374 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
375 struct auth4_context *auth_context = gensec_security->auth_context;
376 struct auth_usersupplied_info *user_info = NULL;
377 uint32_t ntlmssp_command, auth_flags;
379 const unsigned int version_len = 8;
380 DATA_BLOB version_blob = data_blob_null;
381 const unsigned int mic_len = NTLMSSP_MIC_SIZE;
382 DATA_BLOB mic_blob = data_blob_null;
383 const uint8_t zero_channel_bindings[16] = { 0, };
384 const uint8_t *client_channel_bindings = zero_channel_bindings;
385 uint8_t server_channel_bindings[16] = { 0, };
386 const char *parse_string;
388 struct timeval endtime;
389 bool expired = false;
392 file_save("ntlmssp_auth.dat", request.data, request.length);
395 if (ntlmssp_state->unicode) {
396 parse_string = "CdBBUUUBdbb";
398 parse_string = "CdBBAAABdbb";
402 data_blob_free(&ntlmssp_state->session_key);
403 data_blob_free(&ntlmssp_state->lm_resp);
404 data_blob_free(&ntlmssp_state->nt_resp);
406 ntlmssp_state->user = NULL;
407 ntlmssp_state->domain = NULL;
408 ntlmssp_state->client.netbios_name = NULL;
410 /* now the NTLMSSP encoded auth hashes */
411 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
414 &ntlmssp_state->lm_resp,
415 &ntlmssp_state->nt_resp,
416 &ntlmssp_state->domain,
417 &ntlmssp_state->user,
418 &ntlmssp_state->client.netbios_name,
419 &state->encrypted_session_key,
421 &version_blob, version_len,
424 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
425 dump_data(10, request.data, request.length);
427 data_blob_free(&version_blob);
428 data_blob_free(&mic_blob);
430 if (ntlmssp_state->unicode) {
431 parse_string = "CdBBUUUBd";
433 parse_string = "CdBBAAABd";
436 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
439 &ntlmssp_state->lm_resp,
440 &ntlmssp_state->nt_resp,
441 &ntlmssp_state->domain,
442 &ntlmssp_state->user,
443 &ntlmssp_state->client.netbios_name,
444 &state->encrypted_session_key,
449 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
450 dump_data(10, request.data, request.length);
453 data_blob_free(&state->encrypted_session_key);
456 /* Try again with a shorter string (Win9X truncates this packet) */
457 if (ntlmssp_state->unicode) {
458 parse_string = "CdBBUUU";
460 parse_string = "CdBBAAA";
463 /* now the NTLMSSP encoded auth hashes */
464 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
467 &ntlmssp_state->lm_resp,
468 &ntlmssp_state->nt_resp,
469 &ntlmssp_state->domain,
470 &ntlmssp_state->user,
471 &ntlmssp_state->client.netbios_name)) {
472 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
473 dump_data(2, request.data, request.length);
475 return NT_STATUS_INVALID_PARAMETER;
479 talloc_steal(state, state->encrypted_session_key.data);
481 if (auth_flags != 0) {
482 nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
485 if (!NT_STATUS_IS_OK(nt_status)){
490 if (DEBUGLEVEL >= 10) {
491 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
492 ntlmssp_state, struct AUTHENTICATE_MESSAGE);
493 if (authenticate != NULL) {
495 authenticate->NegotiateFlags = auth_flags;
496 status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
497 &request, authenticate, authenticate);
498 if (NT_STATUS_IS_OK(status)) {
499 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
502 TALLOC_FREE(authenticate);
506 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
507 ntlmssp_state->user, ntlmssp_state->domain,
508 ntlmssp_state->client.netbios_name,
509 (unsigned long)ntlmssp_state->lm_resp.length,
510 (unsigned long)ntlmssp_state->nt_resp.length));
513 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
514 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
517 if (ntlmssp_state->nt_resp.length > 24) {
518 struct NTLMv2_RESPONSE v2_resp;
519 enum ndr_err_code err;
522 const struct AV_PAIR *flags = NULL;
523 const struct AV_PAIR *cb = NULL;
524 const struct AV_PAIR *eol = NULL;
525 uint32_t av_flags = 0;
527 err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp,
530 (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
531 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
532 nt_status = ndr_map_error2ntstatus(err);
533 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_BUFFER_TOO_SMALL)) {
535 * Note that invalid blobs should result in
536 * INVALID_PARAMETER, as demonstrated by
537 * smb2.session.ntlmssp_bug14932
539 nt_status = NT_STATUS_INVALID_PARAMETER;
541 DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
542 "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
543 __func__, ntlmssp_state->nt_resp.length,
544 ntlmssp_state->user, ntlmssp_state->domain,
545 ntlmssp_state->client.netbios_name,
546 ndr_errstr(err), nt_errstr(nt_status)));
551 NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
554 eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
557 DEBUG(1,("%s: missing MsvAvEOL for "
558 "user=[%s] domain=[%s] workstation=[%s]\n",
559 __func__, ntlmssp_state->user, ntlmssp_state->domain,
560 ntlmssp_state->client.netbios_name));
561 return NT_STATUS_INVALID_PARAMETER;
564 flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
567 av_flags = flags->Value.AvFlags;
570 if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) {
571 if (mic_blob.length != NTLMSSP_MIC_SIZE) {
572 DEBUG(1,("%s: mic_blob.length[%u] for "
573 "user=[%s] domain=[%s] workstation=[%s]\n",
575 (unsigned)mic_blob.length,
577 ntlmssp_state->domain,
578 ntlmssp_state->client.netbios_name));
579 return NT_STATUS_INVALID_PARAMETER;
583 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE))
585 DEBUG(1,("%s: missing MIC "
586 "request.length[%u] for "
587 "user=[%s] domain=[%s] workstation=[%s]\n",
589 (unsigned)request.length,
591 ntlmssp_state->domain,
592 ntlmssp_state->client.netbios_name));
593 return NT_STATUS_INVALID_PARAMETER;
596 ntlmssp_state->new_spnego = true;
599 cb = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
602 client_channel_bindings = cb->Value.ChannelBindings;
605 count = ntlmssp_state->server.av_pair_list.count;
606 if (v2_resp.Challenge.AvPairs.count < count) {
607 return NT_STATUS_INVALID_PARAMETER;
610 for (i = 0; i < count; i++) {
611 const struct AV_PAIR *sp =
612 &ntlmssp_state->server.av_pair_list.pair[i];
613 const struct AV_PAIR *cp = NULL;
615 if (sp->AvId == MsvAvEOL) {
619 cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
622 DEBUG(1,("%s: AvId 0x%x missing for"
623 "user=[%s] domain=[%s] "
624 "workstation=[%s]\n",
628 ntlmssp_state->domain,
629 ntlmssp_state->client.netbios_name));
630 return NT_STATUS_INVALID_PARAMETER;
634 #define CASE_STRING(v) case Msv ## v: do { \
636 if (sp->Value.v == NULL) { \
637 return NT_STATUS_INTERNAL_ERROR; \
639 if (cp->Value.v == NULL) { \
640 DEBUG(1,("%s: invalid %s " \
641 "got[%s] expect[%s] for " \
642 "user=[%s] domain=[%s] workstation=[%s]\n", \
646 ntlmssp_state->user, \
647 ntlmssp_state->domain, \
648 ntlmssp_state->client.netbios_name)); \
649 return NT_STATUS_INVALID_PARAMETER; \
651 cmp = strcmp(cp->Value.v, sp->Value.v); \
653 DEBUG(1,("%s: invalid %s " \
654 "got[%s] expect[%s] for " \
655 "user=[%s] domain=[%s] workstation=[%s]\n", \
659 ntlmssp_state->user, \
660 ntlmssp_state->domain, \
661 ntlmssp_state->client.netbios_name)); \
662 return NT_STATUS_INVALID_PARAMETER; \
665 CASE_STRING(AvNbComputerName);
666 CASE_STRING(AvNbDomainName);
667 CASE_STRING(AvDnsComputerName);
668 CASE_STRING(AvDnsDomainName);
669 CASE_STRING(AvDnsTreeName);
671 if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
674 struct timeval_buf tmp1;
675 struct timeval_buf tmp2;
677 nttime_to_timeval(&ct,
678 cp->Value.AvTimestamp);
679 nttime_to_timeval(&st,
680 sp->Value.AvTimestamp);
682 DEBUG(1,("%s: invalid AvTimestamp "
683 "got[%s] expect[%s] for "
684 "user=[%s] domain=[%s] "
685 "workstation=[%s]\n",
687 timeval_str_buf(&ct, false,
689 timeval_str_buf(&st, false,
692 ntlmssp_state->domain,
693 ntlmssp_state->client.netbios_name));
694 return NT_STATUS_INVALID_PARAMETER;
699 * This can't happen as we control
700 * ntlmssp_state->server.av_pair_list
702 return NT_STATUS_INTERNAL_ERROR;
707 if (gensec_security->channel_bindings != NULL) {
708 nt_status = ntlmssp_hash_channel_bindings(gensec_security,
709 server_channel_bindings);
710 if (!NT_STATUS_IS_OK(nt_status)) {
714 ok = mem_equal_const_time(client_channel_bindings,
715 server_channel_bindings,
717 if (!ok && gensec_security->want_features & GENSEC_FEATURE_CB_OPTIONAL) {
719 * Unlike kerberos, explicit 16 zeros in
720 * MsvChannelBindings are not enough to
721 * pass the optional check.
723 * So we only let it through without explicit
724 * MsvChannelBindings.
726 ok = (client_channel_bindings == zero_channel_bindings);
729 DBG_WARNING("Invalid channel bindings for "
730 "user=[%s] domain=[%s] workstation=[%s]\n",
732 ntlmssp_state->domain,
733 ntlmssp_state->client.netbios_name);
734 dump_data(DBGLVL_WARNING,
735 client_channel_bindings,
737 dump_data(DBGLVL_WARNING,
738 server_channel_bindings,
740 return NT_STATUS_BAD_BINDINGS;
744 nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
745 expired = timeval_expired(&endtime);
747 struct timeval_buf tmp;
748 DEBUG(1,("%s: challenge invalid (expired %s) for "
749 "user=[%s] domain=[%s] workstation=[%s]\n",
751 timeval_str_buf(&endtime, false, true, &tmp),
752 ntlmssp_state->user, ntlmssp_state->domain,
753 ntlmssp_state->client.netbios_name));
754 return NT_STATUS_INVALID_PARAMETER;
757 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
760 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
762 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
763 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
764 state->doing_ntlm2 = true;
766 memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
767 memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
769 SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
771 /* LM response is no longer useful */
772 data_blob_free(&ntlmssp_state->lm_resp);
774 /* We changed the effective challenge - set it */
775 if (auth_context->set_ntlm_challenge) {
776 uint8_t session_nonce_hash[16];
779 rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
780 state->session_nonce,
784 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
788 nt_status = auth_context->set_ntlm_challenge(auth_context,
790 "NTLMSSP callback (NTLM2)");
791 ZERO_ARRAY(session_nonce_hash);
792 if (!NT_STATUS_IS_OK(nt_status)) {
793 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
794 nt_errstr(nt_status)));
798 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
800 return NT_STATUS_NOT_IMPLEMENTED;
803 /* LM Key is incompatible. */
804 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
808 user_info = talloc_zero(state, struct auth_usersupplied_info);
810 return NT_STATUS_NO_MEMORY;
813 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
814 user_info->flags = 0;
815 user_info->client.account_name = ntlmssp_state->user;
816 user_info->client.domain_name = ntlmssp_state->domain;
817 user_info->workstation_name = ntlmssp_state->client.netbios_name;
818 user_info->remote_host = gensec_get_remote_address(gensec_security);
819 user_info->local_host = gensec_get_local_address(gensec_security);
820 user_info->service_description
821 = gensec_get_target_service_description(gensec_security);
824 * This will just be the string "NTLMSSP" from
825 * gensec_ntlmssp_final_auth_type, but ensures it stays in sync
826 * with the same use in the authorization logging triggered by
827 * gensec_session_info() later
829 user_info->auth_description = gensec_final_auth_type(gensec_security);
831 user_info->password_state = AUTH_PASSWORD_RESPONSE;
832 user_info->password.response.lanman = ntlmssp_state->lm_resp;
833 user_info->password.response.nt = ntlmssp_state->nt_resp;
835 state->user_info = user_info;
839 static void ntlmssp_server_auth_done(struct tevent_req *subreq)
841 struct tevent_req *req =
842 tevent_req_callback_data(subreq,
844 struct ntlmssp_server_auth_state *state =
846 struct ntlmssp_server_auth_state);
847 struct gensec_security *gensec_security = state->gensec_security;
848 struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
849 struct auth4_context *auth_context = gensec_security->auth_context;
850 uint8_t authoritative = 1;
853 status = auth_context->check_ntlm_password_recv(subreq,
856 &gensec_ntlmssp->server_returned_info,
857 &state->user_session_key,
858 &state->lm_session_key);
860 if (!NT_STATUS_IS_OK(status)) {
861 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
862 state->user_info->client.domain_name,
863 state->user_info->client.account_name,
866 if (tevent_req_nterror(req, status)) {
869 talloc_steal(state, state->user_session_key.data);
870 talloc_steal(state, state->lm_session_key.data);
872 status = ntlmssp_server_postauth(state->gensec_security,
873 state->gensec_ntlmssp,
875 if (tevent_req_nterror(req, status)) {
879 tevent_req_done(req);
883 * Next state function for the Authenticate packet
884 * (after authentication - figures out the session keys etc)
886 * @param ntlmssp_state NTLMSSP State
887 * @return Errors or NT_STATUS_OK.
890 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
891 struct gensec_ntlmssp_context *gensec_ntlmssp,
892 struct ntlmssp_server_auth_state *state,
895 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
896 struct auth4_context *auth_context = gensec_security->auth_context;
897 DATA_BLOB user_session_key = state->user_session_key;
898 DATA_BLOB lm_session_key = state->lm_session_key;
899 NTSTATUS nt_status = NT_STATUS_OK;
900 DATA_BLOB session_key = {};
901 struct auth_session_info *session_info = NULL;
903 TALLOC_FREE(state->user_info);
905 if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST
906 && auth_context->generate_session_info != NULL)
911 * We need to check if the auth is anonymous or mapped to guest
913 tmp_status = auth_context->generate_session_info(auth_context, state,
914 gensec_ntlmssp->server_returned_info,
915 gensec_ntlmssp->ntlmssp_state->user,
916 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
918 if (!NT_STATUS_IS_OK(tmp_status)) {
920 * We don't care about failures,
921 * the worst result is that we try MIC checking
922 * for a map to guest authentication.
924 TALLOC_FREE(session_info);
928 if (session_info != NULL) {
929 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
931 * Anonymous and GUEST are not secure anyway.
932 * avoid new_spnego and MIC checking.
934 ntlmssp_state->new_spnego = false;
935 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
936 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
938 TALLOC_FREE(session_info);
941 dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
942 dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
944 /* Handle the different session key derivation for NTLM2 */
945 if (state->doing_ntlm2) {
946 if (user_session_key.data && user_session_key.length == 16) {
949 session_key = data_blob_talloc(ntlmssp_state,
952 rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
953 user_session_key.data,
954 user_session_key.length,
955 state->session_nonce,
956 sizeof(state->session_nonce),
959 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
962 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
963 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
966 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
967 session_key = data_blob_null;
969 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
970 /* Ensure we can never get here on NTLMv2 */
971 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
973 if (lm_session_key.data && lm_session_key.length >= 8) {
974 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
975 session_key = data_blob_talloc(ntlmssp_state,
977 if (session_key.data == NULL) {
978 return NT_STATUS_NO_MEMORY;
980 nt_status = SMBsesskeygen_lm_sess_key(lm_session_key.data,
981 ntlmssp_state->lm_resp.data,
983 if (!NT_STATUS_IS_OK(nt_status)) {
986 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
988 static const uint8_t zeros[24] = {0, };
989 session_key = data_blob_talloc(
990 ntlmssp_state, NULL, 16);
991 if (session_key.data == NULL) {
992 return NT_STATUS_NO_MEMORY;
994 nt_status = SMBsesskeygen_lm_sess_key(zeros, zeros,
996 if (!NT_STATUS_IS_OK(nt_status)) {
999 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
1001 dump_data_pw("LM session key:\n", session_key.data,
1002 session_key.length);
1004 /* LM Key not selected */
1005 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1007 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
1008 session_key = data_blob_null;
1011 } else if (user_session_key.data) {
1012 session_key = user_session_key;
1013 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
1014 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
1016 /* LM Key not selected */
1017 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1019 } else if (lm_session_key.data) {
1020 /* Very weird to have LM key, but no user session key, but anyway.. */
1021 session_key = lm_session_key;
1022 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
1023 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
1025 /* LM Key not selected */
1026 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1029 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
1030 session_key = data_blob_null;
1032 /* LM Key not selected */
1033 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1036 /* With KEY_EXCH, the client supplies the proposed session key,
1037 but encrypts it with the long-term key */
1038 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1039 if (!state->encrypted_session_key.data
1040 || state->encrypted_session_key.length != 16) {
1041 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
1042 (unsigned)state->encrypted_session_key.length));
1043 return NT_STATUS_INVALID_PARAMETER;
1044 } else if (!session_key.data || session_key.length != 16) {
1045 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
1046 (unsigned int)session_key.length));
1047 ntlmssp_state->session_key = session_key;
1048 talloc_steal(ntlmssp_state, session_key.data);
1050 gnutls_cipher_hd_t cipher_hnd;
1051 gnutls_datum_t enc_session_key = {
1052 .data = session_key.data,
1053 .size = session_key.length,
1057 dump_data_pw("KEY_EXCH session key (enc):\n",
1058 state->encrypted_session_key.data,
1059 state->encrypted_session_key.length);
1061 rc = gnutls_cipher_init(&cipher_hnd,
1062 GNUTLS_CIPHER_ARCFOUR_128,
1066 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1068 rc = gnutls_cipher_encrypt(cipher_hnd,
1069 state->encrypted_session_key.data,
1070 state->encrypted_session_key.length);
1071 gnutls_cipher_deinit(cipher_hnd);
1073 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1076 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
1077 state->encrypted_session_key.data,
1078 state->encrypted_session_key.length);
1079 dump_data_pw("KEY_EXCH session key:\n",
1080 state->encrypted_session_key.data,
1081 state->encrypted_session_key.length);
1084 ntlmssp_state->session_key = session_key;
1085 talloc_steal(ntlmssp_state, session_key.data);
1088 if (ntlmssp_state->new_spnego) {
1089 gnutls_hmac_hd_t hmac_hnd = NULL;
1090 uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
1094 rc = gnutls_hmac_init(&hmac_hnd,
1096 ntlmssp_state->session_key.data,
1097 MIN(ntlmssp_state->session_key.length, 64));
1099 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1101 rc = gnutls_hmac(hmac_hnd,
1102 ntlmssp_state->negotiate_blob.data,
1103 ntlmssp_state->negotiate_blob.length);
1105 gnutls_hmac_deinit(hmac_hnd, NULL);
1106 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1108 rc = gnutls_hmac(hmac_hnd,
1109 ntlmssp_state->challenge_blob.data,
1110 ntlmssp_state->challenge_blob.length);
1112 gnutls_hmac_deinit(hmac_hnd, NULL);
1113 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1116 /* checked were we set ntlmssp_state->new_spnego */
1117 SMB_ASSERT(request.length >
1118 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1120 rc = gnutls_hmac(hmac_hnd, request.data, NTLMSSP_MIC_OFFSET);
1122 gnutls_hmac_deinit(hmac_hnd, NULL);
1123 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1125 rc = gnutls_hmac(hmac_hnd, mic_buffer, NTLMSSP_MIC_SIZE);
1127 gnutls_hmac_deinit(hmac_hnd, NULL);
1128 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1130 rc = gnutls_hmac(hmac_hnd,
1131 request.data + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
1132 request.length - (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1134 gnutls_hmac_deinit(hmac_hnd, NULL);
1135 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
1137 gnutls_hmac_deinit(hmac_hnd, mic_buffer);
1139 cmp = mem_equal_const_time(request.data + NTLMSSP_MIC_OFFSET,
1140 mic_buffer, NTLMSSP_MIC_SIZE);
1142 DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1143 "user=[%s] domain=[%s] workstation=[%s]\n",
1145 ntlmssp_state->user,
1146 ntlmssp_state->domain,
1147 ntlmssp_state->client.netbios_name));
1148 dump_data(11, request.data + NTLMSSP_MIC_OFFSET,
1150 dump_data(11, mic_buffer,
1154 ZERO_ARRAY(mic_buffer);
1157 return NT_STATUS_INVALID_PARAMETER;
1161 data_blob_free(&ntlmssp_state->negotiate_blob);
1162 data_blob_free(&ntlmssp_state->challenge_blob);
1164 if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
1165 if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
1167 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
1168 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
1171 ntlmssp_state->force_wrap_seal = true;
1173 nt_status = ntlmssp_sign_init(ntlmssp_state);
1176 data_blob_clear_free(&ntlmssp_state->internal_chal);
1177 data_blob_clear_free(&ntlmssp_state->chal);
1178 data_blob_clear_free(&ntlmssp_state->lm_resp);
1179 data_blob_clear_free(&ntlmssp_state->nt_resp);
1181 ntlmssp_state->expected_state = NTLMSSP_DONE;
1186 NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req,
1187 TALLOC_CTX *out_mem_ctx,
1192 *out = data_blob_null;
1194 if (tevent_req_is_nterror(req, &status)) {
1195 tevent_req_received(req);
1199 tevent_req_received(req);
1200 return NT_STATUS_OK;