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 "../lib/crypto/crypto.h"
33 #include "auth/gensec/gensec.h"
34 #include "auth/gensec/gensec_internal.h"
35 #include "auth/common_auth.h"
36 #include "param/param.h"
37 #include "param/loadparm.h"
38 #include "libcli/security/session.h"
41 #define DBGC_CLASS DBGC_AUTH
44 * Determine correct target name flags for reply, given server role
45 * and negotiated flags
47 * @param ntlmssp_state NTLMSSP State
48 * @param neg_flags The flags from the packet
49 * @param chal_flags The flags to be set in the reply packet
50 * @return The 'target name' string.
53 const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
54 uint32_t neg_flags, uint32_t *chal_flags)
56 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
57 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
58 *chal_flags |= NTLMSSP_REQUEST_TARGET;
59 if (ntlmssp_state->server.is_standalone) {
60 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
61 return ntlmssp_state->server.netbios_name;
63 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
64 return ntlmssp_state->server.netbios_domain;
72 * Next state function for the NTLMSSP Negotiate packet
74 * @param gensec_security GENSEC state
75 * @param out_mem_ctx Memory context for *out
76 * @param in The request, as a DATA_BLOB. reply.data must be NULL
77 * @param out The reply, as an allocated DATA_BLOB, caller to free.
78 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
81 NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
82 TALLOC_CTX *out_mem_ctx,
83 const DATA_BLOB request, DATA_BLOB *reply)
85 struct gensec_ntlmssp_context *gensec_ntlmssp =
86 talloc_get_type_abort(gensec_security->private_data,
87 struct gensec_ntlmssp_context);
88 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
89 struct auth4_context *auth_context = gensec_security->auth_context;
90 DATA_BLOB struct_blob;
91 uint32_t neg_flags = 0;
92 uint32_t ntlmssp_command, chal_flags;
94 const char *target_name;
96 struct timeval tv_now = timeval_current();
100 * Windows NT 4.0, windows_2000: use 30 minutes,
101 * Windows XP, Windows Server 2003, Windows Vista,
102 * Windows Server 2008, Windows 7, and Windows Server 2008 R2
105 * Newer systems doesn't check this, likely because the
106 * connectionless NTLMSSP is no longer supported.
108 * As we expect the AUTHENTICATION_MESSAGE to arrive
109 * directly after the NEGOTIATE_MESSAGE (typically less than
110 * as 1 second later). We use a hard timeout of 30 Minutes.
112 * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp
113 * instead we just remember our own time.
115 uint32_t max_lifetime = 30 * 60;
116 struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0);
118 /* parse the NTLMSSP packet */
120 file_save("ntlmssp_negotiate.dat", request.data, request.length);
123 if (request.length) {
124 if (request.length > UINT16_MAX) {
125 DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n",
126 (unsigned int)request.length));
127 return NT_STATUS_INVALID_PARAMETER;
130 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
134 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
135 (unsigned int)request.length));
136 dump_data(2, request.data, request.length);
137 return NT_STATUS_INVALID_PARAMETER;
139 debug_ntlmssp_flags(neg_flags);
141 if (DEBUGLEVEL >= 10) {
142 struct NEGOTIATE_MESSAGE *negotiate = talloc(
143 ntlmssp_state, struct NEGOTIATE_MESSAGE);
144 if (negotiate != NULL) {
145 status = ntlmssp_pull_NEGOTIATE_MESSAGE(
146 &request, negotiate, negotiate);
147 if (NT_STATUS_IS_OK(status)) {
148 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
151 TALLOC_FREE(negotiate);
156 status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
157 if (!NT_STATUS_IS_OK(status)){
161 /* Ask our caller what challenge they would like in the packet */
162 if (auth_context->get_ntlm_challenge) {
163 status = auth_context->get_ntlm_challenge(auth_context, cryptkey);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
170 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
171 return NT_STATUS_NOT_IMPLEMENTED;
174 /* The flags we send back are not just the negotiated flags,
175 * they are also 'what is in this packet'. Therfore, we
176 * operate on 'chal_flags' from here on
179 chal_flags = ntlmssp_state->neg_flags;
180 ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end);
182 /* get the right name to fill in as 'target' */
183 target_name = ntlmssp_target_name(ntlmssp_state,
184 neg_flags, &chal_flags);
185 if (target_name == NULL)
186 return NT_STATUS_INVALID_PARAMETER;
188 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
189 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
192 /* This creates the 'blob' of names that appears at the end of the packet */
193 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
194 enum ndr_err_code err;
195 struct AV_PAIR *pairs = NULL;
198 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
200 return NT_STATUS_NO_MEMORY;
203 pairs[0].AvId = MsvAvNbDomainName;
204 pairs[0].Value.AvNbDomainName = target_name;
206 pairs[1].AvId = MsvAvNbComputerName;
207 pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name;
209 pairs[2].AvId = MsvAvDnsDomainName;
210 pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain;
212 pairs[3].AvId = MsvAvDnsComputerName;
213 pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name;
215 if (!ntlmssp_state->force_old_spnego) {
216 pairs[4].AvId = MsvAvTimestamp;
217 pairs[4].Value.AvTimestamp =
218 timeval_to_nttime(&tv_now);
221 pairs[5].AvId = MsvAvEOL;
223 pairs[4].AvId = MsvAvEOL;
226 ntlmssp_state->server.av_pair_list.count = count;
227 ntlmssp_state->server.av_pair_list.pair = pairs;
229 err = ndr_push_struct_blob(&struct_blob,
231 &ntlmssp_state->server.av_pair_list,
232 (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST);
233 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
234 return NT_STATUS_NO_MEMORY;
237 struct_blob = data_blob_null;
241 /* Marshal the packet in the right format, be it unicode or ASCII */
242 const char *gen_string;
243 const DATA_BLOB version_blob = ntlmssp_version_blob();
245 if (ntlmssp_state->unicode) {
246 gen_string = "CdUdbddBb";
248 gen_string = "CdAdbddBb";
251 status = msrpc_gen(out_mem_ctx, reply, gen_string,
258 struct_blob.data, struct_blob.length,
259 version_blob.data, version_blob.length);
261 if (!NT_STATUS_IS_OK(status)) {
262 data_blob_free(&struct_blob);
266 if (DEBUGLEVEL >= 10) {
267 struct CHALLENGE_MESSAGE *challenge = talloc(
268 ntlmssp_state, struct CHALLENGE_MESSAGE);
269 if (challenge != NULL) {
270 challenge->NegotiateFlags = chal_flags;
271 status = ntlmssp_pull_CHALLENGE_MESSAGE(
272 reply, challenge, challenge);
273 if (NT_STATUS_IS_OK(status)) {
274 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
277 TALLOC_FREE(challenge);
282 data_blob_free(&struct_blob);
284 ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
286 if (ntlmssp_state->negotiate_blob.length != request.length) {
287 return NT_STATUS_NO_MEMORY;
290 ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state,
292 if (ntlmssp_state->challenge_blob.length != reply->length) {
293 return NT_STATUS_NO_MEMORY;
296 ntlmssp_state->expected_state = NTLMSSP_AUTH;
298 return NT_STATUS_MORE_PROCESSING_REQUIRED;
301 struct ntlmssp_server_auth_state {
302 struct gensec_security *gensec_security;
303 struct gensec_ntlmssp_context *gensec_ntlmssp;
305 struct auth_usersupplied_info *user_info;
306 DATA_BLOB user_session_key;
307 DATA_BLOB lm_session_key;
308 /* internal variables used by KEY_EXCH (client-supplied user session key */
309 DATA_BLOB encrypted_session_key;
311 /* internal variables used by NTLM2 */
312 uint8_t session_nonce[16];
315 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
316 struct gensec_ntlmssp_context *gensec_ntlmssp,
317 struct ntlmssp_server_auth_state *state,
318 const DATA_BLOB request);
319 static void ntlmssp_server_auth_done(struct tevent_req *subreq);
320 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
321 struct gensec_ntlmssp_context *gensec_ntlmssp,
322 struct ntlmssp_server_auth_state *state,
325 struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
326 struct tevent_context *ev,
327 struct gensec_security *gensec_security,
330 struct gensec_ntlmssp_context *gensec_ntlmssp =
331 talloc_get_type_abort(gensec_security->private_data,
332 struct gensec_ntlmssp_context);
333 struct auth4_context *auth_context = gensec_security->auth_context;
334 struct tevent_req *req = NULL;
335 struct ntlmssp_server_auth_state *state = NULL;
336 uint8_t authoritative = 0;
339 req = tevent_req_create(mem_ctx, &state,
340 struct ntlmssp_server_auth_state);
344 state->gensec_security = gensec_security;
345 state->gensec_ntlmssp = gensec_ntlmssp;
348 status = ntlmssp_server_preauth(gensec_security,
351 if (tevent_req_nterror(req, status)) {
352 return tevent_req_post(req, ev);
355 if (auth_context->check_ntlm_password_send != NULL) {
356 struct tevent_req *subreq = NULL;
358 subreq = auth_context->check_ntlm_password_send(state, ev,
361 if (tevent_req_nomem(subreq, req)) {
362 return tevent_req_post(req, ev);
364 tevent_req_set_callback(subreq,
365 ntlmssp_server_auth_done,
370 if (auth_context->check_ntlm_password == NULL) {
371 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
372 return tevent_req_post(req, ev);
375 status = auth_context->check_ntlm_password(auth_context,
379 &gensec_ntlmssp->server_returned_info,
380 &state->user_session_key,
381 &state->lm_session_key);
382 if (!NT_STATUS_IS_OK(status)) {
383 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
384 state->user_info->client.domain_name,
385 state->user_info->client.account_name,
388 if (tevent_req_nterror(req, status)) {
389 return tevent_req_post(req, ev);
391 talloc_steal(state, state->user_session_key.data);
392 talloc_steal(state, state->lm_session_key.data);
394 status = ntlmssp_server_postauth(gensec_security,
397 if (tevent_req_nterror(req, status)) {
398 return tevent_req_post(req, ev);
401 tevent_req_done(req);
402 return tevent_req_post(req, ev);
406 * Next state function for the Authenticate packet
408 * @param ntlmssp_state NTLMSSP State
409 * @param request The request, as a DATA_BLOB
410 * @return Errors or NT_STATUS_OK.
413 static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
414 struct gensec_ntlmssp_context *gensec_ntlmssp,
415 struct ntlmssp_server_auth_state *state,
416 const DATA_BLOB request)
418 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
419 struct auth4_context *auth_context = gensec_security->auth_context;
420 struct auth_usersupplied_info *user_info = NULL;
421 uint32_t ntlmssp_command, auth_flags;
423 const unsigned int version_len = 8;
424 DATA_BLOB version_blob = data_blob_null;
425 const unsigned int mic_len = NTLMSSP_MIC_SIZE;
426 DATA_BLOB mic_blob = data_blob_null;
427 uint8_t session_nonce_hash[16];
428 const char *parse_string;
430 struct timeval endtime;
431 bool expired = false;
434 file_save("ntlmssp_auth.dat", request.data, request.length);
437 if (ntlmssp_state->unicode) {
438 parse_string = "CdBBUUUBdbb";
440 parse_string = "CdBBAAABdbb";
444 data_blob_free(&ntlmssp_state->session_key);
445 data_blob_free(&ntlmssp_state->lm_resp);
446 data_blob_free(&ntlmssp_state->nt_resp);
448 ntlmssp_state->user = NULL;
449 ntlmssp_state->domain = NULL;
450 ntlmssp_state->client.netbios_name = NULL;
452 /* now the NTLMSSP encoded auth hashes */
453 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
456 &ntlmssp_state->lm_resp,
457 &ntlmssp_state->nt_resp,
458 &ntlmssp_state->domain,
459 &ntlmssp_state->user,
460 &ntlmssp_state->client.netbios_name,
461 &state->encrypted_session_key,
463 &version_blob, version_len,
466 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
467 dump_data(10, request.data, request.length);
469 data_blob_free(&version_blob);
470 data_blob_free(&mic_blob);
472 if (ntlmssp_state->unicode) {
473 parse_string = "CdBBUUUBd";
475 parse_string = "CdBBAAABd";
478 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
481 &ntlmssp_state->lm_resp,
482 &ntlmssp_state->nt_resp,
483 &ntlmssp_state->domain,
484 &ntlmssp_state->user,
485 &ntlmssp_state->client.netbios_name,
486 &state->encrypted_session_key,
491 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
492 dump_data(10, request.data, request.length);
495 data_blob_free(&state->encrypted_session_key);
498 /* Try again with a shorter string (Win9X truncates this packet) */
499 if (ntlmssp_state->unicode) {
500 parse_string = "CdBBUUU";
502 parse_string = "CdBBAAA";
505 /* now the NTLMSSP encoded auth hashes */
506 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
509 &ntlmssp_state->lm_resp,
510 &ntlmssp_state->nt_resp,
511 &ntlmssp_state->domain,
512 &ntlmssp_state->user,
513 &ntlmssp_state->client.netbios_name)) {
514 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
515 dump_data(2, request.data, request.length);
517 return NT_STATUS_INVALID_PARAMETER;
521 talloc_steal(state, state->encrypted_session_key.data);
523 if (auth_flags != 0) {
524 nt_status = ntlmssp_handle_neg_flags(ntlmssp_state,
527 if (!NT_STATUS_IS_OK(nt_status)){
532 if (DEBUGLEVEL >= 10) {
533 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
534 ntlmssp_state, struct AUTHENTICATE_MESSAGE);
535 if (authenticate != NULL) {
537 authenticate->NegotiateFlags = auth_flags;
538 status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
539 &request, authenticate, authenticate);
540 if (NT_STATUS_IS_OK(status)) {
541 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
544 TALLOC_FREE(authenticate);
548 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
549 ntlmssp_state->user, ntlmssp_state->domain,
550 ntlmssp_state->client.netbios_name,
551 (unsigned long)ntlmssp_state->lm_resp.length,
552 (unsigned long)ntlmssp_state->nt_resp.length));
555 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
556 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
559 if (ntlmssp_state->nt_resp.length > 24) {
560 struct NTLMv2_RESPONSE v2_resp;
561 enum ndr_err_code err;
564 const struct AV_PAIR *flags = NULL;
565 const struct AV_PAIR *eol = NULL;
566 uint32_t av_flags = 0;
568 err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp,
571 (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
572 if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
573 nt_status = ndr_map_error2ntstatus(err);
574 DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
575 "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
576 __func__, ntlmssp_state->nt_resp.length,
577 ntlmssp_state->user, ntlmssp_state->domain,
578 ntlmssp_state->client.netbios_name,
579 ndr_errstr(err), nt_errstr(nt_status)));
584 NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
587 eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
590 DEBUG(1,("%s: missing MsvAvEOL for "
591 "user=[%s] domain=[%s] workstation=[%s]\n",
592 __func__, ntlmssp_state->user, ntlmssp_state->domain,
593 ntlmssp_state->client.netbios_name));
594 return NT_STATUS_INVALID_PARAMETER;
597 flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
600 av_flags = flags->Value.AvFlags;
603 if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) {
604 if (mic_blob.length != NTLMSSP_MIC_SIZE) {
605 DEBUG(1,("%s: mic_blob.length[%u] for "
606 "user=[%s] domain=[%s] workstation=[%s]\n",
608 (unsigned)mic_blob.length,
610 ntlmssp_state->domain,
611 ntlmssp_state->client.netbios_name));
612 return NT_STATUS_INVALID_PARAMETER;
616 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE))
618 DEBUG(1,("%s: missing MIC "
619 "request.length[%u] for "
620 "user=[%s] domain=[%s] workstation=[%s]\n",
622 (unsigned)request.length,
624 ntlmssp_state->domain,
625 ntlmssp_state->client.netbios_name));
626 return NT_STATUS_INVALID_PARAMETER;
629 ntlmssp_state->new_spnego = true;
632 count = ntlmssp_state->server.av_pair_list.count;
633 if (v2_resp.Challenge.AvPairs.count < count) {
634 return NT_STATUS_INVALID_PARAMETER;
637 for (i = 0; i < count; i++) {
638 const struct AV_PAIR *sp =
639 &ntlmssp_state->server.av_pair_list.pair[i];
640 const struct AV_PAIR *cp = NULL;
642 if (sp->AvId == MsvAvEOL) {
646 cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
649 DEBUG(1,("%s: AvId 0x%x missing for"
650 "user=[%s] domain=[%s] "
651 "workstation=[%s]\n",
655 ntlmssp_state->domain,
656 ntlmssp_state->client.netbios_name));
657 return NT_STATUS_INVALID_PARAMETER;
661 #define CASE_STRING(v) case Msv ## v: do { \
663 if (sp->Value.v == NULL) { \
664 return NT_STATUS_INTERNAL_ERROR; \
666 if (cp->Value.v == NULL) { \
667 DEBUG(1,("%s: invalid %s " \
668 "got[%s] expect[%s] for " \
669 "user=[%s] domain=[%s] workstation=[%s]\n", \
673 ntlmssp_state->user, \
674 ntlmssp_state->domain, \
675 ntlmssp_state->client.netbios_name)); \
676 return NT_STATUS_INVALID_PARAMETER; \
678 cmp = strcmp(cp->Value.v, sp->Value.v); \
680 DEBUG(1,("%s: invalid %s " \
681 "got[%s] expect[%s] for " \
682 "user=[%s] domain=[%s] workstation=[%s]\n", \
686 ntlmssp_state->user, \
687 ntlmssp_state->domain, \
688 ntlmssp_state->client.netbios_name)); \
689 return NT_STATUS_INVALID_PARAMETER; \
692 CASE_STRING(AvNbComputerName);
693 CASE_STRING(AvNbDomainName);
694 CASE_STRING(AvDnsComputerName);
695 CASE_STRING(AvDnsDomainName);
696 CASE_STRING(AvDnsTreeName);
698 if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
701 struct timeval_buf tmp1;
702 struct timeval_buf tmp2;
704 nttime_to_timeval(&ct,
705 cp->Value.AvTimestamp);
706 nttime_to_timeval(&st,
707 sp->Value.AvTimestamp);
709 DEBUG(1,("%s: invalid AvTimestamp "
710 "got[%s] expect[%s] for "
711 "user=[%s] domain=[%s] "
712 "workstation=[%s]\n",
714 timeval_str_buf(&ct, false,
716 timeval_str_buf(&st, false,
719 ntlmssp_state->domain,
720 ntlmssp_state->client.netbios_name));
721 return NT_STATUS_INVALID_PARAMETER;
726 * This can't happen as we control
727 * ntlmssp_state->server.av_pair_list
729 return NT_STATUS_INTERNAL_ERROR;
734 nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
735 expired = timeval_expired(&endtime);
737 struct timeval_buf tmp;
738 DEBUG(1,("%s: challenge invalid (expired %s) for "
739 "user=[%s] domain=[%s] workstation=[%s]\n",
741 timeval_str_buf(&endtime, false, true, &tmp),
742 ntlmssp_state->user, ntlmssp_state->domain,
743 ntlmssp_state->client.netbios_name));
744 return NT_STATUS_INVALID_PARAMETER;
747 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
750 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
752 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
753 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
754 MD5_CTX md5_session_nonce_ctx;
755 state->doing_ntlm2 = true;
757 memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
758 memcpy(&state->session_nonce[8], ntlmssp_state->lm_resp.data, 8);
760 SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
762 MD5Init(&md5_session_nonce_ctx);
763 MD5Update(&md5_session_nonce_ctx, state->session_nonce, 16);
764 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
766 /* LM response is no longer useful */
767 data_blob_free(&ntlmssp_state->lm_resp);
769 /* We changed the effective challenge - set it */
770 if (auth_context->set_ntlm_challenge) {
771 nt_status = auth_context->set_ntlm_challenge(auth_context,
773 "NTLMSSP callback (NTLM2)");
774 if (!NT_STATUS_IS_OK(nt_status)) {
775 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
776 nt_errstr(nt_status)));
780 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
782 return NT_STATUS_NOT_IMPLEMENTED;
785 /* LM Key is incompatible. */
786 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
790 user_info = talloc_zero(state, struct auth_usersupplied_info);
792 return NT_STATUS_NO_MEMORY;
795 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
796 user_info->flags = 0;
797 user_info->mapped_state = false;
798 user_info->client.account_name = ntlmssp_state->user;
799 user_info->client.domain_name = ntlmssp_state->domain;
800 user_info->workstation_name = ntlmssp_state->client.netbios_name;
801 user_info->remote_host = gensec_get_remote_address(gensec_security);
802 user_info->local_host = gensec_get_local_address(gensec_security);
803 user_info->service_description
804 = gensec_get_target_service_description(gensec_security);
807 * This will just be the string "NTLMSSP" from
808 * gensec_ntlmssp_final_auth_type, but ensures it stays in sync
809 * with the same use in the authorization logging triggered by
810 * gensec_session_info() later
812 user_info->auth_description = gensec_final_auth_type(gensec_security);
814 user_info->password_state = AUTH_PASSWORD_RESPONSE;
815 user_info->password.response.lanman = ntlmssp_state->lm_resp;
816 user_info->password.response.nt = ntlmssp_state->nt_resp;
818 state->user_info = user_info;
822 static void ntlmssp_server_auth_done(struct tevent_req *subreq)
824 struct tevent_req *req =
825 tevent_req_callback_data(subreq,
827 struct ntlmssp_server_auth_state *state =
829 struct ntlmssp_server_auth_state);
830 struct gensec_security *gensec_security = state->gensec_security;
831 struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
832 struct auth4_context *auth_context = gensec_security->auth_context;
833 uint8_t authoritative = 0;
836 status = auth_context->check_ntlm_password_recv(subreq,
839 &gensec_ntlmssp->server_returned_info,
840 &state->user_session_key,
841 &state->lm_session_key);
843 if (!NT_STATUS_IS_OK(status)) {
844 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
845 state->user_info->client.domain_name,
846 state->user_info->client.account_name,
849 if (tevent_req_nterror(req, status)) {
852 talloc_steal(state, state->user_session_key.data);
853 talloc_steal(state, state->lm_session_key.data);
855 status = ntlmssp_server_postauth(state->gensec_security,
856 state->gensec_ntlmssp,
858 if (tevent_req_nterror(req, status)) {
862 tevent_req_done(req);
866 * Next state function for the Authenticate packet
867 * (after authentication - figures out the session keys etc)
869 * @param ntlmssp_state NTLMSSP State
870 * @return Errors or NT_STATUS_OK.
873 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
874 struct gensec_ntlmssp_context *gensec_ntlmssp,
875 struct ntlmssp_server_auth_state *state,
878 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
879 struct auth4_context *auth_context = gensec_security->auth_context;
880 DATA_BLOB user_session_key = state->user_session_key;
881 DATA_BLOB lm_session_key = state->lm_session_key;
882 NTSTATUS nt_status = NT_STATUS_OK;
883 DATA_BLOB session_key = data_blob(NULL, 0);
884 struct auth_session_info *session_info = NULL;
886 TALLOC_FREE(state->user_info);
888 if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST
889 && auth_context->generate_session_info != NULL)
894 * We need to check if the auth is anonymous or mapped to guest
896 tmp_status = auth_context->generate_session_info(auth_context, state,
897 gensec_ntlmssp->server_returned_info,
898 gensec_ntlmssp->ntlmssp_state->user,
899 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES,
901 if (!NT_STATUS_IS_OK(tmp_status)) {
903 * We don't care about failures,
904 * the worst result is that we try MIC checking
905 * for a map to guest authentication.
907 TALLOC_FREE(session_info);
911 if (session_info != NULL) {
912 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
914 * Anonymous and GUEST are not secure anyway.
915 * avoid new_spnego and MIC checking.
917 ntlmssp_state->new_spnego = false;
918 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
919 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
921 TALLOC_FREE(session_info);
924 dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
925 dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
927 /* Handle the different session key derivation for NTLM2 */
928 if (state->doing_ntlm2) {
929 if (user_session_key.data && user_session_key.length == 16) {
930 session_key = data_blob_talloc(ntlmssp_state,
932 hmac_md5(user_session_key.data, state->session_nonce,
933 sizeof(state->session_nonce), session_key.data);
934 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
935 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
938 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
939 session_key = data_blob_null;
941 } else if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
942 /* Ensure we can never get here on NTLMv2 */
943 && (ntlmssp_state->nt_resp.length == 0 || ntlmssp_state->nt_resp.length == 24)) {
945 if (lm_session_key.data && lm_session_key.length >= 8) {
946 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
947 session_key = data_blob_talloc(ntlmssp_state,
949 if (session_key.data == NULL) {
950 return NT_STATUS_NO_MEMORY;
952 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
954 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
956 static const uint8_t zeros[24] = {0, };
957 session_key = data_blob_talloc(
958 ntlmssp_state, NULL, 16);
959 if (session_key.data == NULL) {
960 return NT_STATUS_NO_MEMORY;
962 SMBsesskeygen_lm_sess_key(zeros, zeros,
964 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
966 dump_data_pw("LM session key:\n", session_key.data,
969 /* LM Key not selected */
970 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
972 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
973 session_key = data_blob_null;
976 } else if (user_session_key.data) {
977 session_key = user_session_key;
978 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
979 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
981 /* LM Key not selected */
982 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
984 } else if (lm_session_key.data) {
985 /* Very weird to have LM key, but no user session key, but anyway.. */
986 session_key = lm_session_key;
987 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
988 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
990 /* LM Key not selected */
991 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
994 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
995 session_key = data_blob_null;
997 /* LM Key not selected */
998 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
1001 /* With KEY_EXCH, the client supplies the proposed session key,
1002 but encrypts it with the long-term key */
1003 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1004 if (!state->encrypted_session_key.data
1005 || state->encrypted_session_key.length != 16) {
1006 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
1007 (unsigned)state->encrypted_session_key.length));
1008 return NT_STATUS_INVALID_PARAMETER;
1009 } else if (!session_key.data || session_key.length != 16) {
1010 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
1011 (unsigned int)session_key.length));
1012 ntlmssp_state->session_key = session_key;
1013 talloc_steal(ntlmssp_state, session_key.data);
1015 dump_data_pw("KEY_EXCH session key (enc):\n",
1016 state->encrypted_session_key.data,
1017 state->encrypted_session_key.length);
1018 arcfour_crypt(state->encrypted_session_key.data,
1020 state->encrypted_session_key.length);
1021 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
1022 state->encrypted_session_key.data,
1023 state->encrypted_session_key.length);
1024 dump_data_pw("KEY_EXCH session key:\n",
1025 state->encrypted_session_key.data,
1026 state->encrypted_session_key.length);
1029 ntlmssp_state->session_key = session_key;
1030 talloc_steal(ntlmssp_state, session_key.data);
1033 if (ntlmssp_state->new_spnego) {
1035 uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
1038 hmac_md5_init_limK_to_64(ntlmssp_state->session_key.data,
1039 ntlmssp_state->session_key.length,
1042 hmac_md5_update(ntlmssp_state->negotiate_blob.data,
1043 ntlmssp_state->negotiate_blob.length,
1045 hmac_md5_update(ntlmssp_state->challenge_blob.data,
1046 ntlmssp_state->challenge_blob.length,
1049 /* checked were we set ntlmssp_state->new_spnego */
1050 SMB_ASSERT(request.length >
1051 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
1053 hmac_md5_update(request.data, NTLMSSP_MIC_OFFSET, &ctx);
1054 hmac_md5_update(mic_buffer, NTLMSSP_MIC_SIZE, &ctx);
1055 hmac_md5_update(request.data +
1056 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
1058 (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
1060 hmac_md5_final(mic_buffer, &ctx);
1062 cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET,
1063 mic_buffer, NTLMSSP_MIC_SIZE);
1065 DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1066 "user=[%s] domain=[%s] workstation=[%s]\n",
1068 ntlmssp_state->user,
1069 ntlmssp_state->domain,
1070 ntlmssp_state->client.netbios_name));
1071 dump_data(1, request.data + NTLMSSP_MIC_OFFSET,
1073 dump_data(1, mic_buffer,
1075 return NT_STATUS_INVALID_PARAMETER;
1079 data_blob_free(&ntlmssp_state->negotiate_blob);
1080 data_blob_free(&ntlmssp_state->challenge_blob);
1082 if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
1083 if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
1085 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
1086 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
1089 ntlmssp_state->force_wrap_seal = true;
1091 nt_status = ntlmssp_sign_init(ntlmssp_state);
1094 data_blob_clear_free(&ntlmssp_state->internal_chal);
1095 data_blob_clear_free(&ntlmssp_state->chal);
1096 data_blob_clear_free(&ntlmssp_state->lm_resp);
1097 data_blob_clear_free(&ntlmssp_state->nt_resp);
1099 ntlmssp_state->expected_state = NTLMSSP_DONE;
1104 NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req,
1105 TALLOC_CTX *out_mem_ctx,
1110 *out = data_blob_null;
1112 if (tevent_req_is_nterror(req, &status)) {
1113 tevent_req_received(req);
1117 tevent_req_received(req);
1118 return NT_STATUS_OK;