2 Unix SMB/Netbios implementation.
4 handle NLTMSSP, client server side parsing
6 Copyright (C) Andrew Tridgell 2001
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005
8 Copyright (C) Stefan Metzmacher 2005
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 struct auth_session_info
;
27 #include "auth/ntlmssp/ntlmssp.h"
28 #include "../lib/crypto/crypto.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #include "auth/credentials/credentials.h"
31 #include "auth/gensec/gensec.h"
32 #include "auth/gensec/gensec_internal.h"
33 #include "param/param.h"
34 #include "auth/ntlmssp/ntlmssp_private.h"
35 #include "../librpc/gen_ndr/ndr_ntlmssp.h"
36 #include "../auth/ntlmssp/ntlmssp_ndr.h"
37 #include "../nsswitch/libwbclient/wbclient.h"
39 /*********************************************************************
41 *********************************************************************/
44 * Next state function for the Initial packet
46 * @param ntlmssp_state NTLMSSP State
47 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
48 * @param in A NULL data blob (input ignored)
49 * @param out The initial negotiate request to the server, as an talloc()ed DATA_BLOB, on out_mem_ctx
50 * @return Errors or NT_STATUS_OK.
53 NTSTATUS
ntlmssp_client_initial(struct gensec_security
*gensec_security
,
54 TALLOC_CTX
*out_mem_ctx
,
55 DATA_BLOB in
, DATA_BLOB
*out
)
57 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
58 talloc_get_type_abort(gensec_security
->private_data
,
59 struct gensec_ntlmssp_context
);
60 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
62 const DATA_BLOB version_blob
= ntlmssp_version_blob();
64 /* generate the ntlmssp negotiate packet */
65 status
= msrpc_gen(out_mem_ctx
,
69 ntlmssp_state
->neg_flags
,
72 version_blob
.data
, version_blob
.length
);
73 if (!NT_STATUS_IS_OK(status
)) {
74 DEBUG(0, ("ntlmssp_client_initial: failed to generate "
75 "ntlmssp negotiate packet\n"));
79 if (DEBUGLEVEL
>= 10) {
80 struct NEGOTIATE_MESSAGE
*negotiate
= talloc(
81 ntlmssp_state
, struct NEGOTIATE_MESSAGE
);
82 if (negotiate
!= NULL
) {
83 status
= ntlmssp_pull_NEGOTIATE_MESSAGE(
84 out
, negotiate
, negotiate
);
85 if (NT_STATUS_IS_OK(status
)) {
86 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE
,
89 TALLOC_FREE(negotiate
);
93 ntlmssp_state
->negotiate_blob
= data_blob_dup_talloc(ntlmssp_state
,
95 if (ntlmssp_state
->negotiate_blob
.length
!= out
->length
) {
96 return NT_STATUS_NO_MEMORY
;
99 ntlmssp_state
->expected_state
= NTLMSSP_CHALLENGE
;
101 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
104 NTSTATUS
gensec_ntlmssp_resume_ccache(struct gensec_security
*gensec_security
,
105 TALLOC_CTX
*out_mem_ctx
,
106 DATA_BLOB in
, DATA_BLOB
*out
)
108 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
109 talloc_get_type_abort(gensec_security
->private_data
,
110 struct gensec_ntlmssp_context
);
111 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
112 uint32_t neg_flags
= 0;
113 uint32_t ntlmssp_command
;
117 *out
= data_blob_null
;
119 if (in
.length
== 0) {
121 * This is compat code for older callers
122 * which were missing the "initial_blob"/"negotiate_blob".
124 * That means we can't calculate the NTLMSSP_MIC
125 * field correctly and need to force the
126 * old_spnego behaviour.
128 DEBUG(10, ("%s: in.length==%u force_old_spnego!\n",
129 __func__
, (unsigned int)in
.length
));
130 ntlmssp_state
->force_old_spnego
= true;
131 ntlmssp_state
->neg_flags
|= ntlmssp_state
->required_flags
;
132 ntlmssp_state
->required_flags
= 0;
133 ntlmssp_state
->expected_state
= NTLMSSP_CHALLENGE
;
134 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
137 /* parse the NTLMSSP packet */
139 if (in
.length
> UINT16_MAX
) {
140 DEBUG(1, ("%s: reject large request of length %u\n",
141 __func__
, (unsigned int)in
.length
));
142 return NT_STATUS_INVALID_PARAMETER
;
145 ok
= msrpc_parse(ntlmssp_state
, &in
, "Cdd",
150 DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n",
151 __func__
, (unsigned int)in
.length
));
152 dump_data(2, in
.data
, in
.length
);
153 return NT_STATUS_INVALID_PARAMETER
;
156 if (ntlmssp_command
!= NTLMSSP_NEGOTIATE
) {
157 DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n",
158 __func__
, (unsigned int)in
.length
));
159 dump_data(2, in
.data
, in
.length
);
160 return NT_STATUS_INVALID_PARAMETER
;
163 ntlmssp_state
->neg_flags
= neg_flags
;
164 DEBUG(3, ("Imported Negotiate flags:\n"));
165 debug_ntlmssp_flags(neg_flags
);
167 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_UNICODE
) {
168 ntlmssp_state
->unicode
= true;
170 ntlmssp_state
->unicode
= false;
173 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SIGN
) {
174 gensec_security
->want_features
|= GENSEC_FEATURE_SIGN
;
177 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SEAL
) {
178 gensec_security
->want_features
|= GENSEC_FEATURE_SEAL
;
181 ntlmssp_state
->conf_flags
= ntlmssp_state
->neg_flags
;
182 ntlmssp_state
->required_flags
= 0;
184 if (DEBUGLEVEL
>= 10) {
185 struct NEGOTIATE_MESSAGE
*negotiate
= talloc(
186 ntlmssp_state
, struct NEGOTIATE_MESSAGE
);
187 if (negotiate
!= NULL
) {
188 status
= ntlmssp_pull_NEGOTIATE_MESSAGE(
189 &in
, negotiate
, negotiate
);
190 if (NT_STATUS_IS_OK(status
)) {
191 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE
,
194 TALLOC_FREE(negotiate
);
198 ntlmssp_state
->negotiate_blob
= data_blob_dup_talloc(ntlmssp_state
,
200 if (ntlmssp_state
->negotiate_blob
.length
!= in
.length
) {
201 return NT_STATUS_NO_MEMORY
;
204 ntlmssp_state
->expected_state
= NTLMSSP_CHALLENGE
;
206 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
210 * Next state function for the Challenge Packet. Generate an auth packet.
212 * @param gensec_security GENSEC state
213 * @param out_mem_ctx Memory context for *out
214 * @param in The server challnege, as a DATA_BLOB. reply.data must be NULL
215 * @param out The next request (auth packet) to the server, as an allocated DATA_BLOB, on the out_mem_ctx context
216 * @return Errors or NT_STATUS_OK.
219 NTSTATUS
ntlmssp_client_challenge(struct gensec_security
*gensec_security
,
220 TALLOC_CTX
*out_mem_ctx
,
221 const DATA_BLOB in
, DATA_BLOB
*out
)
223 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
224 talloc_get_type_abort(gensec_security
->private_data
,
225 struct gensec_ntlmssp_context
);
226 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
227 uint32_t chal_flags
, ntlmssp_command
, unkn1
= 0, unkn2
= 0;
228 DATA_BLOB server_domain_blob
;
229 DATA_BLOB challenge_blob
;
230 DATA_BLOB target_info
= data_blob(NULL
, 0);
232 const char *chal_parse_string
;
233 const char *chal_parse_string_short
= NULL
;
234 const char *auth_gen_string
;
235 DATA_BLOB lm_response
= data_blob(NULL
, 0);
236 DATA_BLOB nt_response
= data_blob(NULL
, 0);
237 DATA_BLOB session_key
= data_blob(NULL
, 0);
238 DATA_BLOB lm_session_key
= data_blob(NULL
, 0);
239 DATA_BLOB encrypted_session_key
= data_blob(NULL
, 0);
242 const char *user
= NULL
, *domain
= NULL
, *workstation
= NULL
;
243 bool is_anonymous
= false;
244 const DATA_BLOB version_blob
= ntlmssp_version_blob();
245 const NTTIME
*server_timestamp
= NULL
;
246 uint8_t mic_buffer
[NTLMSSP_MIC_SIZE
] = { 0, };
247 DATA_BLOB mic_blob
= data_blob_const(mic_buffer
, sizeof(mic_buffer
));
250 TALLOC_CTX
*mem_ctx
= talloc_new(out_mem_ctx
);
252 return NT_STATUS_NO_MEMORY
;
255 if (!msrpc_parse(mem_ctx
,
261 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
262 dump_data(2, in
.data
, in
.length
);
263 talloc_free(mem_ctx
);
265 return NT_STATUS_INVALID_PARAMETER
;
268 data_blob_free(&server_domain_blob
);
270 DEBUG(3, ("Got challenge flags:\n"));
271 debug_ntlmssp_flags(chal_flags
);
273 nt_status
= ntlmssp_handle_neg_flags(ntlmssp_state
,
274 chal_flags
, "challenge");
275 if (!NT_STATUS_IS_OK(nt_status
)) {
279 if (ntlmssp_state
->unicode
) {
280 if (chal_flags
& NTLMSSP_NEGOTIATE_TARGET_INFO
) {
281 chal_parse_string
= "CdUdbddB";
283 chal_parse_string
= "CdUdbdd";
284 chal_parse_string_short
= "CdUdb";
286 auth_gen_string
= "CdBBUUUBdbb";
288 if (chal_flags
& NTLMSSP_NEGOTIATE_TARGET_INFO
) {
289 chal_parse_string
= "CdAdbddB";
291 chal_parse_string
= "CdAdbdd";
292 chal_parse_string_short
= "CdAdb";
295 auth_gen_string
= "CdBBAAABdbb";
298 if (!msrpc_parse(mem_ctx
,
299 &in
, chal_parse_string
,
310 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
312 if (chal_parse_string_short
!= NULL
) {
314 * In the case where NTLMSSP_NEGOTIATE_TARGET_INFO
315 * is not used, some NTLMSSP servers don't return
316 * the unused unkn1 and unkn2 fields.
318 * https://bugzilla.samba.org/show_bug.cgi?id=10016
320 * Try and parse again without them.
322 ok
= msrpc_parse(mem_ctx
,
323 &in
, chal_parse_string_short
,
330 DEBUG(1, ("Failed to short parse "
331 "the NTLMSSP Challenge: (#2)\n"));
336 dump_data(2, in
.data
, in
.length
);
337 talloc_free(mem_ctx
);
338 return NT_STATUS_INVALID_PARAMETER
;
342 if (chal_flags
& NTLMSSP_TARGET_TYPE_SERVER
) {
343 ntlmssp_state
->server
.is_standalone
= true;
345 ntlmssp_state
->server
.is_standalone
= false;
347 /* TODO: parse struct_blob and fill in the rest */
348 ntlmssp_state
->server
.netbios_name
= "";
349 ntlmssp_state
->server
.netbios_domain
= talloc_move(ntlmssp_state
, &server_domain
);
350 ntlmssp_state
->server
.dns_name
= "";
351 ntlmssp_state
->server
.dns_domain
= "";
353 if (challenge_blob
.length
!= 8) {
354 talloc_free(mem_ctx
);
355 return NT_STATUS_INVALID_PARAMETER
;
358 is_anonymous
= cli_credentials_is_anonymous(gensec_security
->credentials
);
359 cli_credentials_get_ntlm_username_domain(gensec_security
->credentials
, mem_ctx
,
362 workstation
= cli_credentials_get_workstation(gensec_security
->credentials
);
365 DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
366 return NT_STATUS_INVALID_PARAMETER
;
369 if (domain
== NULL
) {
370 DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
371 return NT_STATUS_INVALID_PARAMETER
;
374 if (workstation
== NULL
) {
375 DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
376 return NT_STATUS_INVALID_PARAMETER
;
380 ntlmssp_state
->neg_flags
|= NTLMSSP_ANONYMOUS
;
382 * don't use the ccache for anonymous auth
384 ntlmssp_state
->use_ccache
= false;
386 if (ntlmssp_state
->use_ccache
) {
387 struct samr_Password
*nt_hash
= NULL
;
390 * If we have a password given we don't
393 nt_hash
= cli_credentials_get_nt_hash(gensec_security
->credentials
,
395 if (nt_hash
!= NULL
) {
396 ZERO_STRUCTP(nt_hash
);
397 TALLOC_FREE(nt_hash
);
398 ntlmssp_state
->use_ccache
= false;
402 if (ntlmssp_state
->use_ccache
) {
403 struct wbcCredentialCacheParams params
;
404 struct wbcCredentialCacheInfo
*info
= NULL
;
405 struct wbcAuthErrorInfo
*error
= NULL
;
406 struct wbcNamedBlob auth_blobs
[2];
407 const struct wbcBlob
*wbc_auth_blob
= NULL
;
408 const struct wbcBlob
*wbc_session_key
= NULL
;
411 bool new_spnego
= false;
413 params
.account_name
= user
;
414 params
.domain_name
= domain
;
415 params
.level
= WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP
;
417 auth_blobs
[0].name
= "challenge_blob";
418 auth_blobs
[0].flags
= 0;
419 auth_blobs
[0].blob
.data
= in
.data
;
420 auth_blobs
[0].blob
.length
= in
.length
;
421 auth_blobs
[1].name
= "negotiate_blob";
422 auth_blobs
[1].flags
= 0;
423 auth_blobs
[1].blob
.data
= ntlmssp_state
->negotiate_blob
.data
;
424 auth_blobs
[1].blob
.length
= ntlmssp_state
->negotiate_blob
.length
;
425 params
.num_blobs
= ARRAY_SIZE(auth_blobs
);
426 params
.blobs
= auth_blobs
;
428 wbc_status
= wbcCredentialCache(¶ms
, &info
, &error
);
429 wbcFreeMemory(error
);
430 if (!WBC_ERROR_IS_OK(wbc_status
)) {
431 return NT_STATUS_WRONG_CREDENTIAL_HANDLE
;
434 for (i
=0; i
<info
->num_blobs
; i
++) {
435 if (strequal(info
->blobs
[i
].name
, "auth_blob")) {
436 wbc_auth_blob
= &info
->blobs
[i
].blob
;
438 if (strequal(info
->blobs
[i
].name
, "session_key")) {
439 wbc_session_key
= &info
->blobs
[i
].blob
;
441 if (strequal(info
->blobs
[i
].name
, "new_spnego")) {
445 if ((wbc_auth_blob
== NULL
) || (wbc_session_key
== NULL
)) {
447 return NT_STATUS_WRONG_CREDENTIAL_HANDLE
;
450 session_key
= data_blob_talloc(mem_ctx
,
451 wbc_session_key
->data
,
452 wbc_session_key
->length
);
453 if (session_key
.length
!= wbc_session_key
->length
) {
455 return NT_STATUS_NO_MEMORY
;
457 *out
= data_blob_talloc(mem_ctx
,
459 wbc_auth_blob
->length
);
460 if (out
->length
!= wbc_auth_blob
->length
) {
462 return NT_STATUS_NO_MEMORY
;
464 ntlmssp_state
->new_spnego
= new_spnego
;
470 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_NTLM2
) {
471 flags
|= CLI_CRED_NTLM2
;
473 if (ntlmssp_state
->use_ntlmv2
) {
474 flags
|= CLI_CRED_NTLMv2_AUTH
;
476 if (ntlmssp_state
->use_nt_response
) {
477 flags
|= CLI_CRED_NTLM_AUTH
;
479 if (ntlmssp_state
->allow_lm_response
) {
480 flags
|= CLI_CRED_LANMAN_AUTH
;
483 if (target_info
.length
!= 0 && !is_anonymous
) {
484 struct AV_PAIR
*pairs
= NULL
;
486 enum ndr_err_code err
;
487 struct AV_PAIR
*timestamp
= NULL
;
488 struct AV_PAIR
*eol
= NULL
;
490 const char *service
= NULL
;
491 const char *hostname
= NULL
;
493 err
= ndr_pull_struct_blob(&target_info
,
495 &ntlmssp_state
->server
.av_pair_list
,
496 (ndr_pull_flags_fn_t
)ndr_pull_AV_PAIR_LIST
);
497 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
498 return ndr_map_error2ntstatus(err
);
501 count
= ntlmssp_state
->server
.av_pair_list
.count
;
503 * We need room for Flags, SingleHost,
504 * ChannelBindings and Target
506 pairs
= talloc_zero_array(ntlmssp_state
, struct AV_PAIR
,
509 return NT_STATUS_NO_MEMORY
;
512 for (i
= 0; i
< count
; i
++) {
513 pairs
[i
] = ntlmssp_state
->server
.av_pair_list
.pair
[i
];
516 ntlmssp_state
->client
.av_pair_list
.count
= count
;
517 ntlmssp_state
->client
.av_pair_list
.pair
= pairs
;
519 eol
= ndr_ntlmssp_find_av(&ntlmssp_state
->client
.av_pair_list
,
522 return NT_STATUS_INVALID_PARAMETER
;
525 timestamp
= ndr_ntlmssp_find_av(&ntlmssp_state
->client
.av_pair_list
,
527 if (timestamp
!= NULL
) {
528 uint32_t sign_features
=
529 GENSEC_FEATURE_SESSION_KEY
|
530 GENSEC_FEATURE_SIGN
|
533 server_timestamp
= ×tamp
->Value
.AvTimestamp
;
535 if (ntlmssp_state
->force_old_spnego
) {
539 if (gensec_security
->want_features
& sign_features
) {
540 struct AV_PAIR
*av_flags
= NULL
;
542 av_flags
= ndr_ntlmssp_find_av(&ntlmssp_state
->client
.av_pair_list
,
544 if (av_flags
== NULL
) {
549 av_flags
->AvId
= MsvAvFlags
;
550 av_flags
->Value
.AvFlags
= 0;
553 av_flags
->Value
.AvFlags
|= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE
;
554 ntlmssp_state
->new_spnego
= true;
559 struct AV_PAIR
*SingleHost
= NULL
;
567 * This is not really used, but we want to
568 * add some more random bytes and match
571 SingleHost
->AvId
= MsvAvSingleHost
;
572 SingleHost
->Value
.AvSingleHost
.token_info
.Flags
= 0;
573 SingleHost
->Value
.AvSingleHost
.token_info
.TokenIL
= 0;
574 generate_random_buffer(SingleHost
->Value
.AvSingleHost
.token_info
.MachineId
,
575 sizeof(SingleHost
->Value
.AvSingleHost
.token_info
.MachineId
));
576 SingleHost
->Value
.AvSingleHost
.remaining
= data_blob_null
;
580 struct AV_PAIR
*ChannelBindings
= NULL
;
582 ChannelBindings
= eol
;
585 *eol
= *ChannelBindings
;
588 * gensec doesn't support channel bindings yet,
589 * but we want to match Windows on the wire
591 ChannelBindings
->AvId
= MsvChannelBindings
;
592 memset(ChannelBindings
->Value
.ChannelBindings
, 0,
593 sizeof(ChannelBindings
->Value
.ChannelBindings
));
596 service
= gensec_get_target_service(gensec_security
);
597 hostname
= gensec_get_target_hostname(gensec_security
);
598 if (service
!= NULL
&& hostname
!= NULL
) {
599 struct AV_PAIR
*target
= NULL
;
606 target
->AvId
= MsvAvTargetName
;
607 target
->Value
.AvTargetName
= talloc_asprintf(pairs
, "%s/%s",
610 if (target
->Value
.AvTargetName
== NULL
) {
611 return NT_STATUS_NO_MEMORY
;
615 ntlmssp_state
->client
.av_pair_list
.count
= count
;
616 ntlmssp_state
->client
.av_pair_list
.pair
= pairs
;
618 err
= ndr_push_struct_blob(&target_info
,
620 &ntlmssp_state
->client
.av_pair_list
,
621 (ndr_push_flags_fn_t
)ndr_push_AV_PAIR_LIST
);
622 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
623 return NT_STATUS_NO_MEMORY
;
627 nt_status
= cli_credentials_get_ntlm_response(gensec_security
->credentials
, mem_ctx
,
628 &flags
, challenge_blob
,
629 server_timestamp
, target_info
,
630 &lm_response
, &nt_response
,
631 &lm_session_key
, &session_key
);
632 if (!NT_STATUS_IS_OK(nt_status
)) {
636 if (!(flags
& CLI_CRED_LANMAN_AUTH
)) {
637 /* LM Key is still possible, just silly, so we do not
638 * allow it. Fortunetly all LM crypto is off by
639 * default and we require command line options to end
641 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
644 if (!(flags
& CLI_CRED_NTLM2
)) {
645 /* NTLM2 is incompatible... */
646 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_NTLM2
;
649 if ((ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_LM_KEY
)
650 && ntlmssp_state
->allow_lm_key
&& lm_session_key
.length
== 16) {
651 DATA_BLOB new_session_key
= data_blob_talloc(mem_ctx
, NULL
, 16);
652 if (lm_response
.length
== 24) {
653 SMBsesskeygen_lm_sess_key(lm_session_key
.data
, lm_response
.data
,
654 new_session_key
.data
);
656 static const uint8_t zeros
[24];
657 SMBsesskeygen_lm_sess_key(lm_session_key
.data
, zeros
,
658 new_session_key
.data
);
660 session_key
= new_session_key
;
661 dump_data_pw("LM session key\n", session_key
.data
, session_key
.length
);
665 /* Key exchange encryptes a new client-generated session key with
666 the password-derived key */
667 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_KEY_EXCH
) {
668 /* Make up a new session key */
669 uint8_t client_session_key
[16];
670 generate_secret_buffer(client_session_key
, sizeof(client_session_key
));
672 /* Encrypt the new session key with the old one */
673 encrypted_session_key
= data_blob_talloc(ntlmssp_state
,
674 client_session_key
, sizeof(client_session_key
));
675 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key
.data
, encrypted_session_key
.length
);
676 arcfour_crypt(encrypted_session_key
.data
, session_key
.data
, encrypted_session_key
.length
);
677 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key
.data
, encrypted_session_key
.length
);
679 /* Mark the new session key as the 'real' session key */
680 session_key
= data_blob_talloc(mem_ctx
, client_session_key
, sizeof(client_session_key
));
683 /* this generates the actual auth packet */
684 nt_status
= msrpc_gen(mem_ctx
,
685 out
, auth_gen_string
,
688 lm_response
.data
, lm_response
.length
,
689 nt_response
.data
, nt_response
.length
,
693 encrypted_session_key
.data
, encrypted_session_key
.length
,
694 ntlmssp_state
->neg_flags
,
695 version_blob
.data
, version_blob
.length
,
696 mic_blob
.data
, mic_blob
.length
);
697 if (!NT_STATUS_IS_OK(nt_status
)) {
698 talloc_free(mem_ctx
);
703 * We always include the MIC, even without:
704 * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
705 * ntlmssp_state->new_spnego = true;
707 * This matches a Windows client.
709 hmac_md5_init_limK_to_64(session_key
.data
,
712 hmac_md5_update(ntlmssp_state
->negotiate_blob
.data
,
713 ntlmssp_state
->negotiate_blob
.length
,
715 hmac_md5_update(in
.data
, in
.length
, &ctx
);
716 hmac_md5_update(out
->data
, out
->length
, &ctx
);
717 hmac_md5_final(mic_buffer
, &ctx
);
718 memcpy(out
->data
+ NTLMSSP_MIC_OFFSET
, mic_buffer
, NTLMSSP_MIC_SIZE
);
721 data_blob_free(&ntlmssp_state
->negotiate_blob
);
723 ntlmssp_state
->session_key
= session_key
;
724 talloc_steal(ntlmssp_state
, session_key
.data
);
726 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
727 debug_ntlmssp_flags(ntlmssp_state
->neg_flags
);
729 talloc_steal(out_mem_ctx
, out
->data
);
731 ntlmssp_state
->expected_state
= NTLMSSP_DONE
;
733 if (gensec_ntlmssp_have_feature(gensec_security
, GENSEC_FEATURE_SIGN
)) {
734 nt_status
= ntlmssp_sign_init(ntlmssp_state
);
735 if (!NT_STATUS_IS_OK(nt_status
)) {
736 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
737 nt_errstr(nt_status
)));
738 talloc_free(mem_ctx
);
743 talloc_free(mem_ctx
);
747 NTSTATUS
gensec_ntlmssp_client_start(struct gensec_security
*gensec_security
)
749 struct gensec_ntlmssp_context
*gensec_ntlmssp
;
750 struct ntlmssp_state
*ntlmssp_state
;
753 nt_status
= gensec_ntlmssp_start(gensec_security
);
754 NT_STATUS_NOT_OK_RETURN(nt_status
);
757 talloc_get_type_abort(gensec_security
->private_data
,
758 struct gensec_ntlmssp_context
);
760 ntlmssp_state
= talloc_zero(gensec_ntlmssp
,
761 struct ntlmssp_state
);
762 if (!ntlmssp_state
) {
763 return NT_STATUS_NO_MEMORY
;
766 gensec_ntlmssp
->ntlmssp_state
= ntlmssp_state
;
768 ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
770 ntlmssp_state
->role
= NTLMSSP_CLIENT
;
772 ntlmssp_state
->client
.netbios_domain
= lpcfg_workgroup(gensec_security
->settings
->lp_ctx
);
773 ntlmssp_state
->client
.netbios_name
= cli_credentials_get_workstation(gensec_security
->credentials
);
775 ntlmssp_state
->unicode
= gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "unicode", true);
777 ntlmssp_state
->use_nt_response
= gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "send_nt_reponse", true);
779 ntlmssp_state
->allow_lm_response
= lpcfg_client_lanman_auth(gensec_security
->settings
->lp_ctx
);
781 ntlmssp_state
->allow_lm_key
= (ntlmssp_state
->allow_lm_response
782 && (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "allow_lm_key", false)
783 || gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "lm_key", false)));
785 ntlmssp_state
->use_ntlmv2
= lpcfg_client_ntlmv2_auth(gensec_security
->settings
->lp_ctx
);
787 ntlmssp_state
->force_old_spnego
= gensec_setting_bool(gensec_security
->settings
,
788 "ntlmssp_client", "force_old_spnego", false);
790 ntlmssp_state
->expected_state
= NTLMSSP_INITIAL
;
792 ntlmssp_state
->neg_flags
=
793 NTLMSSP_NEGOTIATE_NTLM
|
794 NTLMSSP_NEGOTIATE_VERSION
|
795 NTLMSSP_REQUEST_TARGET
;
797 if (ntlmssp_state
->unicode
) {
798 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_UNICODE
;
800 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_OEM
;
803 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "128bit", true)) {
804 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_128
;
807 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "56bit", false)) {
808 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_56
;
811 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "lm_key", false)) {
812 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_LM_KEY
;
815 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "keyexchange", true)) {
816 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_KEY_EXCH
;
819 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "alwayssign", true)) {
820 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
;
823 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "ntlm2", true)) {
824 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_NTLM2
;
826 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
827 ntlmssp_state
->use_ntlmv2
= false;
830 if (ntlmssp_state
->use_ntlmv2
) {
831 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_NTLM2
;
832 ntlmssp_state
->allow_lm_response
= false;
833 ntlmssp_state
->allow_lm_key
= false;
836 if (ntlmssp_state
->allow_lm_key
) {
837 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_LM_KEY
;
840 if (gensec_security
->want_features
& GENSEC_FEATURE_SESSION_KEY
) {
842 * We need to set this to allow a later SetPassword
843 * via the SAMR pipe to succeed. Strange.... We could
844 * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
846 * Without this, Windows will not create the master key
847 * that it thinks is only used for NTLMSSP signing and
848 * sealing. (It is actually pulled out and used directly)
850 * We don't require this here as some servers (e.g. NetAPP)
851 * doesn't support this.
853 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
855 if (gensec_security
->want_features
& GENSEC_FEATURE_SIGN
) {
856 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
858 if (gensec_security
->want_features
& GENSEC_FEATURE_LDAP_STYLE
) {
860 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
861 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
864 ntlmssp_state
->force_wrap_seal
= true;
866 * We want also work against old Samba servers
867 * which didn't had GENSEC_FEATURE_LDAP_STYLE
868 * we negotiate SEAL too. We may remove this
869 * in a few years. As all servers should have
870 * GENSEC_FEATURE_LDAP_STYLE by then.
872 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SEAL
;
875 if (gensec_security
->want_features
& GENSEC_FEATURE_SEAL
) {
876 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
877 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SEAL
;
879 if (gensec_security
->want_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
880 ntlmssp_state
->use_ccache
= true;
883 ntlmssp_state
->neg_flags
|= ntlmssp_state
->required_flags
;
884 ntlmssp_state
->conf_flags
= ntlmssp_state
->neg_flags
;
889 NTSTATUS
gensec_ntlmssp_resume_ccache_start(struct gensec_security
*gensec_security
)
891 struct gensec_ntlmssp_context
*gensec_ntlmssp
= NULL
;
894 status
= gensec_ntlmssp_client_start(gensec_security
);
895 if (!NT_STATUS_IS_OK(status
)) {
899 gensec_ntlmssp
= talloc_get_type_abort(gensec_security
->private_data
,
900 struct gensec_ntlmssp_context
);
901 gensec_ntlmssp
->ntlmssp_state
->use_ccache
= false;
902 gensec_ntlmssp
->ntlmssp_state
->resume_ccache
= true;
903 gensec_ntlmssp
->ntlmssp_state
->expected_state
= NTLMSSP_NEGOTIATE
;