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
> UINT16_MAX
) {
128 DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n",
129 (unsigned int)request
.length
));
130 return NT_STATUS_INVALID_PARAMETER
;
133 if ((request
.length
< 16) || !msrpc_parse(ntlmssp_state
, &request
, "Cdd",
137 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
138 (unsigned int)request
.length
));
139 dump_data(2, request
.data
, request
.length
);
140 return NT_STATUS_INVALID_PARAMETER
;
142 debug_ntlmssp_flags(neg_flags
);
144 if (DEBUGLEVEL
>= 10) {
145 struct NEGOTIATE_MESSAGE
*negotiate
= talloc(
146 ntlmssp_state
, struct NEGOTIATE_MESSAGE
);
147 if (negotiate
!= NULL
) {
148 status
= ntlmssp_pull_NEGOTIATE_MESSAGE(
149 &request
, negotiate
, negotiate
);
150 if (NT_STATUS_IS_OK(status
)) {
151 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE
,
154 TALLOC_FREE(negotiate
);
159 status
= ntlmssp_handle_neg_flags(ntlmssp_state
, neg_flags
, "negotiate");
160 if (!NT_STATUS_IS_OK(status
)){
164 /* Ask our caller what challenge they would like in the packet */
165 if (auth_context
->get_ntlm_challenge
) {
166 status
= auth_context
->get_ntlm_challenge(auth_context
, cryptkey
);
167 if (!NT_STATUS_IS_OK(status
)) {
168 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
173 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
174 return NT_STATUS_NOT_IMPLEMENTED
;
177 /* The flags we send back are not just the negotiated flags,
178 * they are also 'what is in this packet'. Therefore, we
179 * operate on 'chal_flags' from here on
182 chal_flags
= ntlmssp_state
->neg_flags
;
183 ntlmssp_state
->server
.challenge_endtime
= timeval_to_nttime(&tv_end
);
185 /* get the right name to fill in as 'target' */
186 target_name
= ntlmssp_target_name(ntlmssp_state
,
187 neg_flags
, &chal_flags
);
188 if (target_name
== NULL
)
189 return NT_STATUS_INVALID_PARAMETER
;
191 ntlmssp_state
->chal
= data_blob_talloc(ntlmssp_state
, cryptkey
, 8);
192 ntlmssp_state
->internal_chal
= data_blob_talloc(ntlmssp_state
,
195 /* This creates the 'blob' of names that appears at the end of the packet */
196 if (chal_flags
& NTLMSSP_NEGOTIATE_TARGET_INFO
) {
197 enum ndr_err_code err
;
198 struct AV_PAIR
*pairs
= NULL
;
201 pairs
= talloc_zero_array(ntlmssp_state
, struct AV_PAIR
, count
+ 1);
203 return NT_STATUS_NO_MEMORY
;
206 pairs
[0].AvId
= MsvAvNbDomainName
;
207 pairs
[0].Value
.AvNbDomainName
= target_name
;
209 pairs
[1].AvId
= MsvAvNbComputerName
;
210 pairs
[1].Value
.AvNbComputerName
= ntlmssp_state
->server
.netbios_name
;
212 pairs
[2].AvId
= MsvAvDnsDomainName
;
213 pairs
[2].Value
.AvDnsDomainName
= ntlmssp_state
->server
.dns_domain
;
215 pairs
[3].AvId
= MsvAvDnsComputerName
;
216 pairs
[3].Value
.AvDnsComputerName
= ntlmssp_state
->server
.dns_name
;
218 if (!ntlmssp_state
->force_old_spnego
) {
219 pairs
[4].AvId
= MsvAvTimestamp
;
220 pairs
[4].Value
.AvTimestamp
=
221 timeval_to_nttime(&tv_now
);
224 pairs
[5].AvId
= MsvAvEOL
;
226 pairs
[4].AvId
= MsvAvEOL
;
229 ntlmssp_state
->server
.av_pair_list
.count
= count
;
230 ntlmssp_state
->server
.av_pair_list
.pair
= pairs
;
232 err
= ndr_push_struct_blob(&struct_blob
,
234 &ntlmssp_state
->server
.av_pair_list
,
235 (ndr_push_flags_fn_t
)ndr_push_AV_PAIR_LIST
);
236 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
237 return NT_STATUS_NO_MEMORY
;
240 struct_blob
= data_blob_null
;
244 /* Marshal the packet in the right format, be it unicode or ASCII */
245 const char *gen_string
;
246 const DATA_BLOB version_blob
= ntlmssp_version_blob();
248 if (ntlmssp_state
->unicode
) {
249 gen_string
= "CdUdbddBb";
251 gen_string
= "CdAdbddBb";
254 status
= msrpc_gen(out_mem_ctx
, reply
, gen_string
,
261 struct_blob
.data
, struct_blob
.length
,
262 version_blob
.data
, version_blob
.length
);
264 if (!NT_STATUS_IS_OK(status
)) {
265 data_blob_free(&struct_blob
);
269 if (DEBUGLEVEL
>= 10) {
270 struct CHALLENGE_MESSAGE
*challenge
= talloc(
271 ntlmssp_state
, struct CHALLENGE_MESSAGE
);
272 if (challenge
!= NULL
) {
273 challenge
->NegotiateFlags
= chal_flags
;
274 status
= ntlmssp_pull_CHALLENGE_MESSAGE(
275 reply
, challenge
, challenge
);
276 if (NT_STATUS_IS_OK(status
)) {
277 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE
,
280 TALLOC_FREE(challenge
);
285 data_blob_free(&struct_blob
);
287 ntlmssp_state
->negotiate_blob
= data_blob_dup_talloc(ntlmssp_state
,
289 if (ntlmssp_state
->negotiate_blob
.length
!= request
.length
) {
290 return NT_STATUS_NO_MEMORY
;
293 ntlmssp_state
->challenge_blob
= data_blob_dup_talloc(ntlmssp_state
,
295 if (ntlmssp_state
->challenge_blob
.length
!= reply
->length
) {
296 return NT_STATUS_NO_MEMORY
;
299 ntlmssp_state
->expected_state
= NTLMSSP_AUTH
;
301 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
304 struct ntlmssp_server_auth_state
{
305 struct gensec_security
*gensec_security
;
306 struct gensec_ntlmssp_context
*gensec_ntlmssp
;
308 struct auth_usersupplied_info
*user_info
;
309 DATA_BLOB user_session_key
;
310 DATA_BLOB lm_session_key
;
311 /* internal variables used by KEY_EXCH (client-supplied user session key */
312 DATA_BLOB encrypted_session_key
;
314 /* internal variables used by NTLM2 */
315 uint8_t session_nonce
[16];
318 static NTSTATUS
ntlmssp_server_preauth(struct gensec_security
*gensec_security
,
319 struct gensec_ntlmssp_context
*gensec_ntlmssp
,
320 struct ntlmssp_server_auth_state
*state
,
321 const DATA_BLOB request
);
322 static void ntlmssp_server_auth_done(struct tevent_req
*subreq
);
323 static NTSTATUS
ntlmssp_server_postauth(struct gensec_security
*gensec_security
,
324 struct gensec_ntlmssp_context
*gensec_ntlmssp
,
325 struct ntlmssp_server_auth_state
*state
,
328 struct tevent_req
*ntlmssp_server_auth_send(TALLOC_CTX
*mem_ctx
,
329 struct tevent_context
*ev
,
330 struct gensec_security
*gensec_security
,
333 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
334 talloc_get_type_abort(gensec_security
->private_data
,
335 struct gensec_ntlmssp_context
);
336 struct auth4_context
*auth_context
= gensec_security
->auth_context
;
337 struct tevent_req
*req
= NULL
;
338 struct tevent_req
*subreq
= NULL
;
339 struct ntlmssp_server_auth_state
*state
= NULL
;
342 req
= tevent_req_create(mem_ctx
, &state
,
343 struct ntlmssp_server_auth_state
);
347 state
->gensec_security
= gensec_security
;
348 state
->gensec_ntlmssp
= gensec_ntlmssp
;
351 status
= ntlmssp_server_preauth(gensec_security
,
354 if (tevent_req_nterror(req
, status
)) {
355 return tevent_req_post(req
, ev
);
358 subreq
= auth_context
->check_ntlm_password_send(
359 state
, ev
, auth_context
, state
->user_info
);
360 if (tevent_req_nomem(subreq
, req
)) {
361 return tevent_req_post(req
, ev
);
363 tevent_req_set_callback(subreq
, ntlmssp_server_auth_done
, req
);
368 * Next state function for the Authenticate packet
370 * @param ntlmssp_state NTLMSSP State
371 * @param request The request, as a DATA_BLOB
372 * @return Errors or NT_STATUS_OK.
375 static NTSTATUS
ntlmssp_server_preauth(struct gensec_security
*gensec_security
,
376 struct gensec_ntlmssp_context
*gensec_ntlmssp
,
377 struct ntlmssp_server_auth_state
*state
,
378 const DATA_BLOB request
)
380 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
381 struct auth4_context
*auth_context
= gensec_security
->auth_context
;
382 struct auth_usersupplied_info
*user_info
= NULL
;
383 uint32_t ntlmssp_command
, auth_flags
;
385 const unsigned int version_len
= 8;
386 DATA_BLOB version_blob
= data_blob_null
;
387 const unsigned int mic_len
= NTLMSSP_MIC_SIZE
;
388 DATA_BLOB mic_blob
= data_blob_null
;
389 const uint8_t zero_channel_bindings
[16] = { 0, };
390 const uint8_t *client_channel_bindings
= zero_channel_bindings
;
391 uint8_t server_channel_bindings
[16] = { 0, };
392 const char *parse_string
;
394 struct timeval endtime
;
395 bool expired
= false;
398 file_save("ntlmssp_auth.dat", request
.data
, request
.length
);
401 if (ntlmssp_state
->unicode
) {
402 parse_string
= "CdBBUUUBdbb";
404 parse_string
= "CdBBAAABdbb";
408 data_blob_free(&ntlmssp_state
->session_key
);
409 data_blob_free(&ntlmssp_state
->lm_resp
);
410 data_blob_free(&ntlmssp_state
->nt_resp
);
412 ntlmssp_state
->user
= NULL
;
413 ntlmssp_state
->domain
= NULL
;
414 ntlmssp_state
->client
.netbios_name
= NULL
;
416 /* now the NTLMSSP encoded auth hashes */
417 ok
= msrpc_parse(ntlmssp_state
, &request
, parse_string
,
420 &ntlmssp_state
->lm_resp
,
421 &ntlmssp_state
->nt_resp
,
422 &ntlmssp_state
->domain
,
423 &ntlmssp_state
->user
,
424 &ntlmssp_state
->client
.netbios_name
,
425 &state
->encrypted_session_key
,
427 &version_blob
, version_len
,
430 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
431 dump_data(10, request
.data
, request
.length
);
433 data_blob_free(&version_blob
);
434 data_blob_free(&mic_blob
);
436 if (ntlmssp_state
->unicode
) {
437 parse_string
= "CdBBUUUBd";
439 parse_string
= "CdBBAAABd";
442 ok
= msrpc_parse(ntlmssp_state
, &request
, parse_string
,
445 &ntlmssp_state
->lm_resp
,
446 &ntlmssp_state
->nt_resp
,
447 &ntlmssp_state
->domain
,
448 &ntlmssp_state
->user
,
449 &ntlmssp_state
->client
.netbios_name
,
450 &state
->encrypted_session_key
,
455 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
456 dump_data(10, request
.data
, request
.length
);
459 data_blob_free(&state
->encrypted_session_key
);
462 /* Try again with a shorter string (Win9X truncates this packet) */
463 if (ntlmssp_state
->unicode
) {
464 parse_string
= "CdBBUUU";
466 parse_string
= "CdBBAAA";
469 /* now the NTLMSSP encoded auth hashes */
470 if (!msrpc_parse(ntlmssp_state
, &request
, parse_string
,
473 &ntlmssp_state
->lm_resp
,
474 &ntlmssp_state
->nt_resp
,
475 &ntlmssp_state
->domain
,
476 &ntlmssp_state
->user
,
477 &ntlmssp_state
->client
.netbios_name
)) {
478 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
479 dump_data(2, request
.data
, request
.length
);
481 return NT_STATUS_INVALID_PARAMETER
;
485 talloc_steal(state
, state
->encrypted_session_key
.data
);
487 if (auth_flags
!= 0) {
488 nt_status
= ntlmssp_handle_neg_flags(ntlmssp_state
,
491 if (!NT_STATUS_IS_OK(nt_status
)){
496 if (DEBUGLEVEL
>= 10) {
497 struct AUTHENTICATE_MESSAGE
*authenticate
= talloc(
498 ntlmssp_state
, struct AUTHENTICATE_MESSAGE
);
499 if (authenticate
!= NULL
) {
501 authenticate
->NegotiateFlags
= auth_flags
;
502 status
= ntlmssp_pull_AUTHENTICATE_MESSAGE(
503 &request
, authenticate
, authenticate
);
504 if (NT_STATUS_IS_OK(status
)) {
505 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE
,
508 TALLOC_FREE(authenticate
);
512 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
513 ntlmssp_state
->user
, ntlmssp_state
->domain
,
514 ntlmssp_state
->client
.netbios_name
,
515 (unsigned long)ntlmssp_state
->lm_resp
.length
,
516 (unsigned long)ntlmssp_state
->nt_resp
.length
));
519 file_save("nthash1.dat", &ntlmssp_state
->nt_resp
.data
, &ntlmssp_state
->nt_resp
.length
);
520 file_save("lmhash1.dat", &ntlmssp_state
->lm_resp
.data
, &ntlmssp_state
->lm_resp
.length
);
523 if (ntlmssp_state
->nt_resp
.length
> 24) {
524 struct NTLMv2_RESPONSE v2_resp
;
525 enum ndr_err_code err
;
528 const struct AV_PAIR
*flags
= NULL
;
529 const struct AV_PAIR
*cb
= NULL
;
530 const struct AV_PAIR
*eol
= NULL
;
531 uint32_t av_flags
= 0;
533 err
= ndr_pull_struct_blob(&ntlmssp_state
->nt_resp
,
536 (ndr_pull_flags_fn_t
)ndr_pull_NTLMv2_RESPONSE
);
537 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
538 nt_status
= ndr_map_error2ntstatus(err
);
539 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_BUFFER_TOO_SMALL
)) {
541 * Note that invalid blobs should result in
542 * INVALID_PARAMETER, as demonstrated by
543 * smb2.session.ntlmssp_bug14932
545 nt_status
= NT_STATUS_INVALID_PARAMETER
;
547 DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for "
548 "user=[%s] domain=[%s] workstation=[%s] - %s %s\n",
549 __func__
, ntlmssp_state
->nt_resp
.length
,
550 ntlmssp_state
->user
, ntlmssp_state
->domain
,
551 ntlmssp_state
->client
.netbios_name
,
552 ndr_errstr(err
), nt_errstr(nt_status
)));
557 NDR_PRINT_DEBUG(NTLMv2_RESPONSE
, &v2_resp
);
560 eol
= ndr_ntlmssp_find_av(&v2_resp
.Challenge
.AvPairs
,
563 DEBUG(1,("%s: missing MsvAvEOL for "
564 "user=[%s] domain=[%s] workstation=[%s]\n",
565 __func__
, ntlmssp_state
->user
, ntlmssp_state
->domain
,
566 ntlmssp_state
->client
.netbios_name
));
567 return NT_STATUS_INVALID_PARAMETER
;
570 flags
= ndr_ntlmssp_find_av(&v2_resp
.Challenge
.AvPairs
,
573 av_flags
= flags
->Value
.AvFlags
;
576 if (av_flags
& NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE
) {
577 if (mic_blob
.length
!= NTLMSSP_MIC_SIZE
) {
578 DEBUG(1,("%s: mic_blob.length[%u] for "
579 "user=[%s] domain=[%s] workstation=[%s]\n",
581 (unsigned)mic_blob
.length
,
583 ntlmssp_state
->domain
,
584 ntlmssp_state
->client
.netbios_name
));
585 return NT_STATUS_INVALID_PARAMETER
;
589 (NTLMSSP_MIC_OFFSET
+ NTLMSSP_MIC_SIZE
))
591 DEBUG(1,("%s: missing MIC "
592 "request.length[%u] for "
593 "user=[%s] domain=[%s] workstation=[%s]\n",
595 (unsigned)request
.length
,
597 ntlmssp_state
->domain
,
598 ntlmssp_state
->client
.netbios_name
));
599 return NT_STATUS_INVALID_PARAMETER
;
602 ntlmssp_state
->new_spnego
= true;
605 cb
= ndr_ntlmssp_find_av(&v2_resp
.Challenge
.AvPairs
,
608 client_channel_bindings
= cb
->Value
.ChannelBindings
;
611 count
= ntlmssp_state
->server
.av_pair_list
.count
;
612 if (v2_resp
.Challenge
.AvPairs
.count
< count
) {
613 return NT_STATUS_INVALID_PARAMETER
;
616 for (i
= 0; i
< count
; i
++) {
617 const struct AV_PAIR
*sp
=
618 &ntlmssp_state
->server
.av_pair_list
.pair
[i
];
619 const struct AV_PAIR
*cp
= NULL
;
621 if (sp
->AvId
== MsvAvEOL
) {
625 cp
= ndr_ntlmssp_find_av(&v2_resp
.Challenge
.AvPairs
,
628 DEBUG(1,("%s: AvId 0x%x missing for"
629 "user=[%s] domain=[%s] "
630 "workstation=[%s]\n",
634 ntlmssp_state
->domain
,
635 ntlmssp_state
->client
.netbios_name
));
636 return NT_STATUS_INVALID_PARAMETER
;
640 #define CASE_STRING(v) case Msv ## v: do { \
642 if (sp->Value.v == NULL) { \
643 return NT_STATUS_INTERNAL_ERROR; \
645 if (cp->Value.v == NULL) { \
646 DEBUG(1,("%s: invalid %s " \
647 "got[%s] expect[%s] for " \
648 "user=[%s] domain=[%s] workstation=[%s]\n", \
652 ntlmssp_state->user, \
653 ntlmssp_state->domain, \
654 ntlmssp_state->client.netbios_name)); \
655 return NT_STATUS_INVALID_PARAMETER; \
657 cmp = strcmp(cp->Value.v, sp->Value.v); \
659 DEBUG(1,("%s: invalid %s " \
660 "got[%s] expect[%s] for " \
661 "user=[%s] domain=[%s] workstation=[%s]\n", \
665 ntlmssp_state->user, \
666 ntlmssp_state->domain, \
667 ntlmssp_state->client.netbios_name)); \
668 return NT_STATUS_INVALID_PARAMETER; \
671 CASE_STRING(AvNbComputerName
);
672 CASE_STRING(AvNbDomainName
);
673 CASE_STRING(AvDnsComputerName
);
674 CASE_STRING(AvDnsDomainName
);
675 CASE_STRING(AvDnsTreeName
);
677 if (cp
->Value
.AvTimestamp
!= sp
->Value
.AvTimestamp
) {
680 struct timeval_buf tmp1
;
681 struct timeval_buf tmp2
;
683 nttime_to_timeval(&ct
,
684 cp
->Value
.AvTimestamp
);
685 nttime_to_timeval(&st
,
686 sp
->Value
.AvTimestamp
);
688 DEBUG(1,("%s: invalid AvTimestamp "
689 "got[%s] expect[%s] for "
690 "user=[%s] domain=[%s] "
691 "workstation=[%s]\n",
693 timeval_str_buf(&ct
, false,
695 timeval_str_buf(&st
, false,
698 ntlmssp_state
->domain
,
699 ntlmssp_state
->client
.netbios_name
));
700 return NT_STATUS_INVALID_PARAMETER
;
705 * This can't happen as we control
706 * ntlmssp_state->server.av_pair_list
708 return NT_STATUS_INTERNAL_ERROR
;
713 if (gensec_security
->channel_bindings
!= NULL
) {
714 nt_status
= ntlmssp_hash_channel_bindings(gensec_security
,
715 server_channel_bindings
);
716 if (!NT_STATUS_IS_OK(nt_status
)) {
720 ok
= mem_equal_const_time(client_channel_bindings
,
721 server_channel_bindings
,
723 if (!ok
&& gensec_security
->want_features
& GENSEC_FEATURE_CB_OPTIONAL
) {
725 * Unlike kerberos, explicit 16 zeros in
726 * MsvChannelBindings are not enough to
727 * pass the optional check.
729 * So we only let it through without explicit
730 * MsvChannelBindings.
732 ok
= (client_channel_bindings
== zero_channel_bindings
);
735 DBG_WARNING("Invalid channel bindings for "
736 "user=[%s] domain=[%s] workstation=[%s]\n",
738 ntlmssp_state
->domain
,
739 ntlmssp_state
->client
.netbios_name
);
740 dump_data(DBGLVL_WARNING
,
741 client_channel_bindings
,
743 dump_data(DBGLVL_WARNING
,
744 server_channel_bindings
,
746 return NT_STATUS_BAD_BINDINGS
;
750 nttime_to_timeval(&endtime
, ntlmssp_state
->server
.challenge_endtime
);
751 expired
= timeval_expired(&endtime
);
753 struct timeval_buf tmp
;
754 DEBUG(1,("%s: challenge invalid (expired %s) for "
755 "user=[%s] domain=[%s] workstation=[%s]\n",
757 timeval_str_buf(&endtime
, false, true, &tmp
),
758 ntlmssp_state
->user
, ntlmssp_state
->domain
,
759 ntlmssp_state
->client
.netbios_name
));
760 return NT_STATUS_INVALID_PARAMETER
;
763 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
766 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
768 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_NTLM2
) {
769 if (ntlmssp_state
->nt_resp
.length
== 24 && ntlmssp_state
->lm_resp
.length
== 24) {
770 state
->doing_ntlm2
= true;
772 memcpy(state
->session_nonce
, ntlmssp_state
->internal_chal
.data
, 8);
773 memcpy(&state
->session_nonce
[8], ntlmssp_state
->lm_resp
.data
, 8);
775 SMB_ASSERT(ntlmssp_state
->internal_chal
.data
&& ntlmssp_state
->internal_chal
.length
== 8);
777 /* LM response is no longer useful */
778 data_blob_free(&ntlmssp_state
->lm_resp
);
780 /* We changed the effective challenge - set it */
781 if (auth_context
->set_ntlm_challenge
) {
782 uint8_t session_nonce_hash
[16];
785 rc
= gnutls_hash_fast(GNUTLS_DIG_MD5
,
786 state
->session_nonce
,
790 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
794 nt_status
= auth_context
->set_ntlm_challenge(auth_context
,
796 "NTLMSSP callback (NTLM2)");
797 ZERO_ARRAY(session_nonce_hash
);
798 if (!NT_STATUS_IS_OK(nt_status
)) {
799 DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
800 nt_errstr(nt_status
)));
804 DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't have facility for challenge to be set\n"));
806 return NT_STATUS_NOT_IMPLEMENTED
;
809 /* LM Key is incompatible. */
810 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
814 user_info
= talloc_zero(state
, struct auth_usersupplied_info
);
816 return NT_STATUS_NO_MEMORY
;
819 user_info
->logon_parameters
= MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
| MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
820 user_info
->flags
= 0;
821 user_info
->client
.account_name
= ntlmssp_state
->user
;
822 user_info
->client
.domain_name
= ntlmssp_state
->domain
;
823 user_info
->workstation_name
= ntlmssp_state
->client
.netbios_name
;
824 user_info
->remote_host
= gensec_get_remote_address(gensec_security
);
825 user_info
->local_host
= gensec_get_local_address(gensec_security
);
826 user_info
->service_description
827 = gensec_get_target_service_description(gensec_security
);
830 * This will just be the string "NTLMSSP" from
831 * gensec_ntlmssp_final_auth_type, but ensures it stays in sync
832 * with the same use in the authorization logging triggered by
833 * gensec_session_info() later
835 user_info
->auth_description
= gensec_final_auth_type(gensec_security
);
837 user_info
->password_state
= AUTH_PASSWORD_RESPONSE
;
838 user_info
->password
.response
.lanman
= ntlmssp_state
->lm_resp
;
839 user_info
->password
.response
.nt
= ntlmssp_state
->nt_resp
;
841 state
->user_info
= user_info
;
845 static void ntlmssp_server_auth_done(struct tevent_req
*subreq
)
847 struct tevent_req
*req
=
848 tevent_req_callback_data(subreq
,
850 struct ntlmssp_server_auth_state
*state
=
852 struct ntlmssp_server_auth_state
);
853 struct gensec_security
*gensec_security
= state
->gensec_security
;
854 struct gensec_ntlmssp_context
*gensec_ntlmssp
= state
->gensec_ntlmssp
;
855 struct auth4_context
*auth_context
= gensec_security
->auth_context
;
856 uint8_t authoritative
= 1;
859 status
= auth_context
->check_ntlm_password_recv(subreq
,
862 &gensec_ntlmssp
->server_returned_info
,
863 &state
->user_session_key
,
864 &state
->lm_session_key
);
866 if (!NT_STATUS_IS_OK(status
)) {
867 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
868 state
->user_info
->client
.domain_name
,
869 state
->user_info
->client
.account_name
,
872 if (tevent_req_nterror(req
, status
)) {
875 talloc_steal(state
, state
->user_session_key
.data
);
876 talloc_steal(state
, state
->lm_session_key
.data
);
878 status
= ntlmssp_server_postauth(state
->gensec_security
,
879 state
->gensec_ntlmssp
,
881 if (tevent_req_nterror(req
, status
)) {
885 tevent_req_done(req
);
889 * Next state function for the Authenticate packet
890 * (after authentication - figures out the session keys etc)
892 * @param ntlmssp_state NTLMSSP State
893 * @return Errors or NT_STATUS_OK.
896 static NTSTATUS
ntlmssp_server_postauth(struct gensec_security
*gensec_security
,
897 struct gensec_ntlmssp_context
*gensec_ntlmssp
,
898 struct ntlmssp_server_auth_state
*state
,
901 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
902 struct auth4_context
*auth_context
= gensec_security
->auth_context
;
903 DATA_BLOB user_session_key
= state
->user_session_key
;
904 DATA_BLOB lm_session_key
= state
->lm_session_key
;
905 NTSTATUS nt_status
= NT_STATUS_OK
;
906 DATA_BLOB session_key
= data_blob(NULL
, 0);
907 struct auth_session_info
*session_info
= NULL
;
909 TALLOC_FREE(state
->user_info
);
911 if (lpcfg_map_to_guest(gensec_security
->settings
->lp_ctx
) != NEVER_MAP_TO_GUEST
912 && auth_context
->generate_session_info
!= NULL
)
917 * We need to check if the auth is anonymous or mapped to guest
919 tmp_status
= auth_context
->generate_session_info(auth_context
, state
,
920 gensec_ntlmssp
->server_returned_info
,
921 gensec_ntlmssp
->ntlmssp_state
->user
,
922 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
,
924 if (!NT_STATUS_IS_OK(tmp_status
)) {
926 * We don't care about failures,
927 * the worst result is that we try MIC checking
928 * for a map to guest authentication.
930 TALLOC_FREE(session_info
);
934 if (session_info
!= NULL
) {
935 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
937 * Anonymous and GUEST are not secure anyway.
938 * avoid new_spnego and MIC checking.
940 ntlmssp_state
->new_spnego
= false;
941 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_SIGN
;
942 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_SEAL
;
944 TALLOC_FREE(session_info
);
947 dump_data_pw("NT session key:\n", user_session_key
.data
, user_session_key
.length
);
948 dump_data_pw("LM first-8:\n", lm_session_key
.data
, lm_session_key
.length
);
950 /* Handle the different session key derivation for NTLM2 */
951 if (state
->doing_ntlm2
) {
952 if (user_session_key
.data
&& user_session_key
.length
== 16) {
955 session_key
= data_blob_talloc(ntlmssp_state
,
958 rc
= gnutls_hmac_fast(GNUTLS_MAC_MD5
,
959 user_session_key
.data
,
960 user_session_key
.length
,
961 state
->session_nonce
,
962 sizeof(state
->session_nonce
),
965 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
968 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
969 dump_data_pw("NTLM2 session key:\n", session_key
.data
, session_key
.length
);
972 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
973 session_key
= data_blob_null
;
975 } else if ((ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_LM_KEY
)
976 /* Ensure we can never get here on NTLMv2 */
977 && (ntlmssp_state
->nt_resp
.length
== 0 || ntlmssp_state
->nt_resp
.length
== 24)) {
979 if (lm_session_key
.data
&& lm_session_key
.length
>= 8) {
980 if (ntlmssp_state
->lm_resp
.data
&& ntlmssp_state
->lm_resp
.length
== 24) {
981 session_key
= data_blob_talloc(ntlmssp_state
,
983 if (session_key
.data
== NULL
) {
984 return NT_STATUS_NO_MEMORY
;
986 nt_status
= SMBsesskeygen_lm_sess_key(lm_session_key
.data
,
987 ntlmssp_state
->lm_resp
.data
,
989 if (!NT_STATUS_IS_OK(nt_status
)) {
992 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
994 static const uint8_t zeros
[24] = {0, };
995 session_key
= data_blob_talloc(
996 ntlmssp_state
, NULL
, 16);
997 if (session_key
.data
== NULL
) {
998 return NT_STATUS_NO_MEMORY
;
1000 nt_status
= SMBsesskeygen_lm_sess_key(zeros
, zeros
,
1002 if (!NT_STATUS_IS_OK(nt_status
)) {
1005 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
1007 dump_data_pw("LM session key:\n", session_key
.data
,
1008 session_key
.length
);
1010 /* LM Key not selected */
1011 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
1013 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
1014 session_key
= data_blob_null
;
1017 } else if (user_session_key
.data
) {
1018 session_key
= user_session_key
;
1019 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
1020 dump_data_pw("unmodified session key:\n", session_key
.data
, session_key
.length
);
1022 /* LM Key not selected */
1023 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
1025 } else if (lm_session_key
.data
) {
1026 /* Very weird to have LM key, but no user session key, but anyway.. */
1027 session_key
= lm_session_key
;
1028 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
1029 dump_data_pw("unmodified session key:\n", session_key
.data
, session_key
.length
);
1031 /* LM Key not selected */
1032 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
1035 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
1036 session_key
= data_blob_null
;
1038 /* LM Key not selected */
1039 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
1042 /* With KEY_EXCH, the client supplies the proposed session key,
1043 but encrypts it with the long-term key */
1044 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_KEY_EXCH
) {
1045 if (!state
->encrypted_session_key
.data
1046 || state
->encrypted_session_key
.length
!= 16) {
1047 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
1048 (unsigned)state
->encrypted_session_key
.length
));
1049 return NT_STATUS_INVALID_PARAMETER
;
1050 } else if (!session_key
.data
|| session_key
.length
!= 16) {
1051 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
1052 (unsigned int)session_key
.length
));
1053 ntlmssp_state
->session_key
= session_key
;
1054 talloc_steal(ntlmssp_state
, session_key
.data
);
1056 gnutls_cipher_hd_t cipher_hnd
;
1057 gnutls_datum_t enc_session_key
= {
1058 .data
= session_key
.data
,
1059 .size
= session_key
.length
,
1063 dump_data_pw("KEY_EXCH session key (enc):\n",
1064 state
->encrypted_session_key
.data
,
1065 state
->encrypted_session_key
.length
);
1067 rc
= gnutls_cipher_init(&cipher_hnd
,
1068 GNUTLS_CIPHER_ARCFOUR_128
,
1072 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1074 rc
= gnutls_cipher_encrypt(cipher_hnd
,
1075 state
->encrypted_session_key
.data
,
1076 state
->encrypted_session_key
.length
);
1077 gnutls_cipher_deinit(cipher_hnd
);
1079 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1082 ntlmssp_state
->session_key
= data_blob_talloc(ntlmssp_state
,
1083 state
->encrypted_session_key
.data
,
1084 state
->encrypted_session_key
.length
);
1085 dump_data_pw("KEY_EXCH session key:\n",
1086 state
->encrypted_session_key
.data
,
1087 state
->encrypted_session_key
.length
);
1090 ntlmssp_state
->session_key
= session_key
;
1091 talloc_steal(ntlmssp_state
, session_key
.data
);
1094 if (ntlmssp_state
->new_spnego
) {
1095 gnutls_hmac_hd_t hmac_hnd
= NULL
;
1096 uint8_t mic_buffer
[NTLMSSP_MIC_SIZE
] = { 0, };
1100 rc
= gnutls_hmac_init(&hmac_hnd
,
1102 ntlmssp_state
->session_key
.data
,
1103 MIN(ntlmssp_state
->session_key
.length
, 64));
1105 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1107 rc
= gnutls_hmac(hmac_hnd
,
1108 ntlmssp_state
->negotiate_blob
.data
,
1109 ntlmssp_state
->negotiate_blob
.length
);
1111 gnutls_hmac_deinit(hmac_hnd
, NULL
);
1112 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1114 rc
= gnutls_hmac(hmac_hnd
,
1115 ntlmssp_state
->challenge_blob
.data
,
1116 ntlmssp_state
->challenge_blob
.length
);
1118 gnutls_hmac_deinit(hmac_hnd
, NULL
);
1119 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1122 /* checked were we set ntlmssp_state->new_spnego */
1123 SMB_ASSERT(request
.length
>
1124 (NTLMSSP_MIC_OFFSET
+ NTLMSSP_MIC_SIZE
));
1126 rc
= gnutls_hmac(hmac_hnd
, request
.data
, NTLMSSP_MIC_OFFSET
);
1128 gnutls_hmac_deinit(hmac_hnd
, NULL
);
1129 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1131 rc
= gnutls_hmac(hmac_hnd
, mic_buffer
, NTLMSSP_MIC_SIZE
);
1133 gnutls_hmac_deinit(hmac_hnd
, NULL
);
1134 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1136 rc
= gnutls_hmac(hmac_hnd
,
1137 request
.data
+ (NTLMSSP_MIC_OFFSET
+ NTLMSSP_MIC_SIZE
),
1138 request
.length
- (NTLMSSP_MIC_OFFSET
+ NTLMSSP_MIC_SIZE
));
1140 gnutls_hmac_deinit(hmac_hnd
, NULL
);
1141 return gnutls_error_to_ntstatus(rc
, NT_STATUS_NTLM_BLOCKED
);
1143 gnutls_hmac_deinit(hmac_hnd
, mic_buffer
);
1145 cmp
= mem_equal_const_time(request
.data
+ NTLMSSP_MIC_OFFSET
,
1146 mic_buffer
, NTLMSSP_MIC_SIZE
);
1148 DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1149 "user=[%s] domain=[%s] workstation=[%s]\n",
1151 ntlmssp_state
->user
,
1152 ntlmssp_state
->domain
,
1153 ntlmssp_state
->client
.netbios_name
));
1154 dump_data(11, request
.data
+ NTLMSSP_MIC_OFFSET
,
1156 dump_data(11, mic_buffer
,
1160 ZERO_ARRAY(mic_buffer
);
1163 return NT_STATUS_INVALID_PARAMETER
;
1167 data_blob_free(&ntlmssp_state
->negotiate_blob
);
1168 data_blob_free(&ntlmssp_state
->challenge_blob
);
1170 if (gensec_ntlmssp_have_feature(gensec_security
, GENSEC_FEATURE_SIGN
)) {
1171 if (gensec_security
->want_features
& GENSEC_FEATURE_LDAP_STYLE
) {
1173 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
1174 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
1177 ntlmssp_state
->force_wrap_seal
= true;
1179 nt_status
= ntlmssp_sign_init(ntlmssp_state
);
1182 data_blob_clear_free(&ntlmssp_state
->internal_chal
);
1183 data_blob_clear_free(&ntlmssp_state
->chal
);
1184 data_blob_clear_free(&ntlmssp_state
->lm_resp
);
1185 data_blob_clear_free(&ntlmssp_state
->nt_resp
);
1187 ntlmssp_state
->expected_state
= NTLMSSP_DONE
;
1192 NTSTATUS
ntlmssp_server_auth_recv(struct tevent_req
*req
,
1193 TALLOC_CTX
*out_mem_ctx
,
1198 *out
= data_blob_null
;
1200 if (tevent_req_is_nterror(req
, &status
)) {
1201 tevent_req_received(req
);
1205 tevent_req_received(req
);
1206 return NT_STATUS_OK
;