auth/ntlmssp: implement channel binding support
[samba.git] / auth / ntlmssp / ntlmssp_server.c
blob1e49379a8ed6668e2e57a386dd51e49d643d326d
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
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/>.
23 #include "includes.h"
24 #include <tevent.h>
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>
43 #undef DBGC_CLASS
44 #define DBGC_CLASS DBGC_AUTH
46 /**
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;
65 } else {
66 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
67 return ntlmssp_state->server.netbios_domain;
69 } else {
70 return "";
74 /**
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;
96 uint8_t cryptkey[8];
97 const char *target_name;
98 NTSTATUS status;
99 struct timeval tv_now = timeval_current();
101 * See [MS-NLMP]
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
106 * use 36 hours.
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 */
122 #if 0
123 file_save("ntlmssp_negotiate.dat", request.data, request.length);
124 #endif
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",
134 "NTLMSSP",
135 &ntlmssp_command,
136 &neg_flags)) {
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,
152 negotiate);
154 TALLOC_FREE(negotiate);
159 status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate");
160 if (!NT_STATUS_IS_OK(status)){
161 return 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",
169 nt_errstr(status)));
170 return status;
172 } else {
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,
193 cryptkey, 8);
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;
199 uint32_t count = 5;
201 pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1);
202 if (pairs == NULL) {
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);
222 count += 1;
224 pairs[5].AvId = MsvAvEOL;
225 } else {
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,
233 ntlmssp_state,
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;
239 } else {
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";
250 } else {
251 gen_string = "CdAdbddBb";
254 status = msrpc_gen(out_mem_ctx, reply, gen_string,
255 "NTLMSSP",
256 NTLMSSP_CHALLENGE,
257 target_name,
258 chal_flags,
259 cryptkey, 8,
260 0, 0,
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);
266 return status;
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,
278 challenge);
280 TALLOC_FREE(challenge);
285 data_blob_free(&struct_blob);
287 ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state,
288 request);
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,
294 *reply);
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;
307 DATA_BLOB in;
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;
313 bool doing_ntlm2;
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,
326 DATA_BLOB request);
328 struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
329 struct tevent_context *ev,
330 struct gensec_security *gensec_security,
331 const DATA_BLOB in)
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;
340 NTSTATUS status;
342 req = tevent_req_create(mem_ctx, &state,
343 struct ntlmssp_server_auth_state);
344 if (req == NULL) {
345 return NULL;
347 state->gensec_security = gensec_security;
348 state->gensec_ntlmssp = gensec_ntlmssp;
349 state->in = in;
351 status = ntlmssp_server_preauth(gensec_security,
352 gensec_ntlmssp,
353 state, in);
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);
364 return 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;
384 NTSTATUS nt_status;
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;
393 bool ok;
394 struct timeval endtime;
395 bool expired = false;
397 #if 0
398 file_save("ntlmssp_auth.dat", request.data, request.length);
399 #endif
401 if (ntlmssp_state->unicode) {
402 parse_string = "CdBBUUUBdbb";
403 } else {
404 parse_string = "CdBBAAABdbb";
407 /* zero these out */
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,
418 "NTLMSSP",
419 &ntlmssp_command,
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,
426 &auth_flags,
427 &version_blob, version_len,
428 &mic_blob, mic_len);
429 if (!ok) {
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";
438 } else {
439 parse_string = "CdBBAAABd";
442 ok = msrpc_parse(ntlmssp_state, &request, parse_string,
443 "NTLMSSP",
444 &ntlmssp_command,
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,
451 &auth_flags);
454 if (!ok) {
455 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
456 dump_data(10, request.data, request.length);
458 /* zero this out */
459 data_blob_free(&state->encrypted_session_key);
460 auth_flags = 0;
462 /* Try again with a shorter string (Win9X truncates this packet) */
463 if (ntlmssp_state->unicode) {
464 parse_string = "CdBBUUU";
465 } else {
466 parse_string = "CdBBAAA";
469 /* now the NTLMSSP encoded auth hashes */
470 if (!msrpc_parse(ntlmssp_state, &request, parse_string,
471 "NTLMSSP",
472 &ntlmssp_command,
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,
489 auth_flags,
490 "authenticate");
491 if (!NT_STATUS_IS_OK(nt_status)){
492 return nt_status;
496 if (DEBUGLEVEL >= 10) {
497 struct AUTHENTICATE_MESSAGE *authenticate = talloc(
498 ntlmssp_state, struct AUTHENTICATE_MESSAGE);
499 if (authenticate != NULL) {
500 NTSTATUS status;
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,
506 authenticate);
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));
518 #if 0
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);
521 #endif
523 if (ntlmssp_state->nt_resp.length > 24) {
524 struct NTLMv2_RESPONSE v2_resp;
525 enum ndr_err_code err;
526 uint32_t i = 0;
527 uint32_t count = 0;
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,
534 ntlmssp_state,
535 &v2_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)));
553 return nt_status;
556 if (DEBUGLVL(10)) {
557 NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
560 eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
561 MsvAvEOL);
562 if (eol == NULL) {
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,
571 MsvAvFlags);
572 if (flags != NULL) {
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",
580 __func__,
581 (unsigned)mic_blob.length,
582 ntlmssp_state->user,
583 ntlmssp_state->domain,
584 ntlmssp_state->client.netbios_name));
585 return NT_STATUS_INVALID_PARAMETER;
588 if (request.length <
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",
594 __func__,
595 (unsigned)request.length,
596 ntlmssp_state->user,
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,
606 MsvChannelBindings);
607 if (cb != NULL) {
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) {
622 continue;
625 cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
626 sp->AvId);
627 if (cp == NULL) {
628 DEBUG(1,("%s: AvId 0x%x missing for"
629 "user=[%s] domain=[%s] "
630 "workstation=[%s]\n",
631 __func__,
632 (unsigned)sp->AvId,
633 ntlmssp_state->user,
634 ntlmssp_state->domain,
635 ntlmssp_state->client.netbios_name));
636 return NT_STATUS_INVALID_PARAMETER;
639 switch (cp->AvId) {
640 #define CASE_STRING(v) case Msv ## v: do { \
641 int cmp; \
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", \
649 __func__, #v, \
650 cp->Value.v, \
651 sp->Value.v, \
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); \
658 if (cmp != 0) { \
659 DEBUG(1,("%s: invalid %s " \
660 "got[%s] expect[%s] for " \
661 "user=[%s] domain=[%s] workstation=[%s]\n", \
662 __func__, #v, \
663 cp->Value.v, \
664 sp->Value.v, \
665 ntlmssp_state->user, \
666 ntlmssp_state->domain, \
667 ntlmssp_state->client.netbios_name)); \
668 return NT_STATUS_INVALID_PARAMETER; \
670 } while(0); break
671 CASE_STRING(AvNbComputerName);
672 CASE_STRING(AvNbDomainName);
673 CASE_STRING(AvDnsComputerName);
674 CASE_STRING(AvDnsDomainName);
675 CASE_STRING(AvDnsTreeName);
676 case MsvAvTimestamp:
677 if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) {
678 struct timeval ct;
679 struct timeval st;
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",
692 __func__,
693 timeval_str_buf(&ct, false,
694 true, &tmp1),
695 timeval_str_buf(&st, false,
696 true, &tmp2),
697 ntlmssp_state->user,
698 ntlmssp_state->domain,
699 ntlmssp_state->client.netbios_name));
700 return NT_STATUS_INVALID_PARAMETER;
702 break;
703 default:
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)) {
717 return nt_status;
720 ok = mem_equal_const_time(client_channel_bindings,
721 server_channel_bindings,
722 16);
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);
734 if (!ok) {
735 DBG_WARNING("Invalid channel bindings for "
736 "user=[%s] domain=[%s] workstation=[%s]\n",
737 ntlmssp_state->user,
738 ntlmssp_state->domain,
739 ntlmssp_state->client.netbios_name);
740 dump_data(DBGLVL_WARNING,
741 client_channel_bindings,
742 16);
743 dump_data(DBGLVL_WARNING,
744 server_channel_bindings,
745 16);
746 return NT_STATUS_BAD_BINDINGS;
750 nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
751 expired = timeval_expired(&endtime);
752 if (expired) {
753 struct timeval_buf tmp;
754 DEBUG(1,("%s: challenge invalid (expired %s) for "
755 "user=[%s] domain=[%s] workstation=[%s]\n",
756 __func__,
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
764 client challenge
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];
783 int rc;
785 rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
786 state->session_nonce,
788 session_nonce_hash);
789 if (rc < 0) {
790 return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
794 nt_status = auth_context->set_ntlm_challenge(auth_context,
795 session_nonce_hash,
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)));
801 return nt_status;
803 } else {
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);
815 if (!user_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;
842 return NT_STATUS_OK;
845 static void ntlmssp_server_auth_done(struct tevent_req *subreq)
847 struct tevent_req *req =
848 tevent_req_callback_data(subreq,
849 struct tevent_req);
850 struct ntlmssp_server_auth_state *state =
851 tevent_req_data(req,
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;
857 NTSTATUS status;
859 status = auth_context->check_ntlm_password_recv(subreq,
860 gensec_ntlmssp,
861 &authoritative,
862 &gensec_ntlmssp->server_returned_info,
863 &state->user_session_key,
864 &state->lm_session_key);
865 TALLOC_FREE(subreq);
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,
870 nt_errstr(status));
872 if (tevent_req_nterror(req, status)) {
873 return;
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,
880 state, state->in);
881 if (tevent_req_nterror(req, status)) {
882 return;
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,
899 DATA_BLOB request)
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)
914 NTSTATUS tmp_status;
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,
923 &session_info);
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) {
953 int rc;
955 session_key = data_blob_talloc(ntlmssp_state,
956 NULL, 16);
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),
963 session_key.data);
964 if (rc < 0) {
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);
971 } else {
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,
982 NULL, 16);
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,
988 session_key.data);
989 if (!NT_STATUS_IS_OK(nt_status)) {
990 return nt_status;
992 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
993 } else {
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,
1001 session_key.data);
1002 if (!NT_STATUS_IS_OK(nt_status)) {
1003 return 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);
1009 } else {
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;
1034 } else {
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);
1055 } else {
1056 gnutls_cipher_hd_t cipher_hnd;
1057 gnutls_datum_t enc_session_key = {
1058 .data = session_key.data,
1059 .size = session_key.length,
1061 int rc;
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,
1069 &enc_session_key,
1070 NULL);
1071 if (rc < 0) {
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);
1078 if (rc < 0) {
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);
1089 } else {
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, };
1097 bool cmp;
1098 int rc;
1100 rc = gnutls_hmac_init(&hmac_hnd,
1101 GNUTLS_MAC_MD5,
1102 ntlmssp_state->session_key.data,
1103 MIN(ntlmssp_state->session_key.length, 64));
1104 if (rc < 0) {
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);
1110 if (rc < 0) {
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);
1117 if (rc < 0) {
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);
1127 if (rc < 0) {
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);
1132 if (rc < 0) {
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));
1139 if (rc < 0) {
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);
1147 if (!cmp) {
1148 DEBUG(1,("%s: invalid NTLMSSP_MIC for "
1149 "user=[%s] domain=[%s] workstation=[%s]\n",
1150 __func__,
1151 ntlmssp_state->user,
1152 ntlmssp_state->domain,
1153 ntlmssp_state->client.netbios_name));
1154 dump_data(11, request.data + NTLMSSP_MIC_OFFSET,
1155 NTLMSSP_MIC_SIZE);
1156 dump_data(11, mic_buffer,
1157 NTLMSSP_MIC_SIZE);
1160 ZERO_ARRAY(mic_buffer);
1162 if (!cmp) {
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
1175 * is requested.
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;
1189 return nt_status;
1192 NTSTATUS ntlmssp_server_auth_recv(struct tevent_req *req,
1193 TALLOC_CTX *out_mem_ctx,
1194 DATA_BLOB *out)
1196 NTSTATUS status;
1198 *out = data_blob_null;
1200 if (tevent_req_is_nterror(req, &status)) {
1201 tevent_req_received(req);
1202 return status;
1205 tevent_req_received(req);
1206 return NT_STATUS_OK;