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"
40 #define DBGC_CLASS DBGC_AUTH
42 /*********************************************************************
44 *********************************************************************/
47 * Next state function for the Initial packet
49 * @param ntlmssp_state NTLMSSP State
50 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context
51 * @param in A NULL data blob (input ignored)
52 * @param out The initial negotiate request to the server, as an talloc()ed DATA_BLOB, on out_mem_ctx
53 * @return Errors or NT_STATUS_OK.
56 NTSTATUS
ntlmssp_client_initial(struct gensec_security
*gensec_security
,
57 TALLOC_CTX
*out_mem_ctx
,
58 DATA_BLOB in
, DATA_BLOB
*out
)
60 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
61 talloc_get_type_abort(gensec_security
->private_data
,
62 struct gensec_ntlmssp_context
);
63 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
65 const DATA_BLOB version_blob
= ntlmssp_version_blob();
67 /* generate the ntlmssp negotiate packet */
68 status
= msrpc_gen(out_mem_ctx
,
72 ntlmssp_state
->neg_flags
,
75 version_blob
.data
, version_blob
.length
);
76 if (!NT_STATUS_IS_OK(status
)) {
77 DEBUG(0, ("ntlmssp_client_initial: failed to generate "
78 "ntlmssp negotiate packet\n"));
82 if (DEBUGLEVEL
>= 10) {
83 struct NEGOTIATE_MESSAGE
*negotiate
= talloc(
84 ntlmssp_state
, struct NEGOTIATE_MESSAGE
);
85 if (negotiate
!= NULL
) {
86 status
= ntlmssp_pull_NEGOTIATE_MESSAGE(
87 out
, negotiate
, negotiate
);
88 if (NT_STATUS_IS_OK(status
)) {
89 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE
,
92 TALLOC_FREE(negotiate
);
96 ntlmssp_state
->negotiate_blob
= data_blob_dup_talloc(ntlmssp_state
,
98 if (ntlmssp_state
->negotiate_blob
.length
!= out
->length
) {
99 return NT_STATUS_NO_MEMORY
;
102 ntlmssp_state
->expected_state
= NTLMSSP_CHALLENGE
;
104 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
107 NTSTATUS
gensec_ntlmssp_resume_ccache(struct gensec_security
*gensec_security
,
108 TALLOC_CTX
*out_mem_ctx
,
109 DATA_BLOB in
, DATA_BLOB
*out
)
111 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
112 talloc_get_type_abort(gensec_security
->private_data
,
113 struct gensec_ntlmssp_context
);
114 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
115 uint32_t neg_flags
= 0;
116 uint32_t ntlmssp_command
;
120 *out
= data_blob_null
;
122 if (in
.length
== 0) {
124 * This is compat code for older callers
125 * which were missing the "initial_blob"/"negotiate_blob".
127 * That means we can't calculate the NTLMSSP_MIC
128 * field correctly and need to force the
129 * old_spnego behaviour.
131 DEBUG(10, ("%s: in.length==%u force_old_spnego!\n",
132 __func__
, (unsigned int)in
.length
));
133 ntlmssp_state
->force_old_spnego
= true;
134 ntlmssp_state
->neg_flags
|= ntlmssp_state
->required_flags
;
135 ntlmssp_state
->required_flags
= 0;
136 ntlmssp_state
->expected_state
= NTLMSSP_CHALLENGE
;
137 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
140 /* parse the NTLMSSP packet */
142 if (in
.length
> UINT16_MAX
) {
143 DEBUG(1, ("%s: reject large request of length %u\n",
144 __func__
, (unsigned int)in
.length
));
145 return NT_STATUS_INVALID_PARAMETER
;
148 ok
= msrpc_parse(ntlmssp_state
, &in
, "Cdd",
153 DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n",
154 __func__
, (unsigned int)in
.length
));
155 dump_data(2, in
.data
, in
.length
);
156 return NT_STATUS_INVALID_PARAMETER
;
159 if (ntlmssp_command
!= NTLMSSP_NEGOTIATE
) {
160 DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n",
161 __func__
, (unsigned int)in
.length
));
162 dump_data(2, in
.data
, in
.length
);
163 return NT_STATUS_INVALID_PARAMETER
;
166 ntlmssp_state
->neg_flags
= neg_flags
;
167 DEBUG(3, ("Imported Negotiate flags:\n"));
168 debug_ntlmssp_flags(neg_flags
);
170 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_UNICODE
) {
171 ntlmssp_state
->unicode
= true;
173 ntlmssp_state
->unicode
= false;
176 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SIGN
) {
177 gensec_security
->want_features
|= GENSEC_FEATURE_SIGN
;
180 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_SEAL
) {
181 gensec_security
->want_features
|= GENSEC_FEATURE_SEAL
;
184 ntlmssp_state
->conf_flags
= ntlmssp_state
->neg_flags
;
185 ntlmssp_state
->required_flags
= 0;
187 if (DEBUGLEVEL
>= 10) {
188 struct NEGOTIATE_MESSAGE
*negotiate
= talloc(
189 ntlmssp_state
, struct NEGOTIATE_MESSAGE
);
190 if (negotiate
!= NULL
) {
191 status
= ntlmssp_pull_NEGOTIATE_MESSAGE(
192 &in
, negotiate
, negotiate
);
193 if (NT_STATUS_IS_OK(status
)) {
194 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE
,
197 TALLOC_FREE(negotiate
);
201 ntlmssp_state
->negotiate_blob
= data_blob_dup_talloc(ntlmssp_state
,
203 if (ntlmssp_state
->negotiate_blob
.length
!= in
.length
) {
204 return NT_STATUS_NO_MEMORY
;
207 ntlmssp_state
->expected_state
= NTLMSSP_CHALLENGE
;
209 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
213 * Next state function for the Challenge Packet. Generate an auth packet.
215 * @param gensec_security GENSEC state
216 * @param out_mem_ctx Memory context for *out
217 * @param in The server challnege, as a DATA_BLOB. reply.data must be NULL
218 * @param out The next request (auth packet) to the server, as an allocated DATA_BLOB, on the out_mem_ctx context
219 * @return Errors or NT_STATUS_OK.
222 NTSTATUS
ntlmssp_client_challenge(struct gensec_security
*gensec_security
,
223 TALLOC_CTX
*out_mem_ctx
,
224 const DATA_BLOB in
, DATA_BLOB
*out
)
226 struct gensec_ntlmssp_context
*gensec_ntlmssp
=
227 talloc_get_type_abort(gensec_security
->private_data
,
228 struct gensec_ntlmssp_context
);
229 struct ntlmssp_state
*ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
230 uint32_t chal_flags
, ntlmssp_command
, unkn1
= 0, unkn2
= 0;
231 DATA_BLOB server_domain_blob
;
232 DATA_BLOB challenge_blob
;
233 DATA_BLOB target_info
= data_blob(NULL
, 0);
235 const char *chal_parse_string
;
236 const char *chal_parse_string_short
= NULL
;
237 const char *auth_gen_string
;
238 DATA_BLOB lm_response
= data_blob(NULL
, 0);
239 DATA_BLOB nt_response
= data_blob(NULL
, 0);
240 DATA_BLOB session_key
= data_blob(NULL
, 0);
241 DATA_BLOB lm_session_key
= data_blob(NULL
, 0);
242 DATA_BLOB encrypted_session_key
= data_blob(NULL
, 0);
245 const char *user
= NULL
, *domain
= NULL
, *workstation
= NULL
;
246 bool is_anonymous
= false;
247 const DATA_BLOB version_blob
= ntlmssp_version_blob();
248 const NTTIME
*server_timestamp
= NULL
;
249 uint8_t mic_buffer
[NTLMSSP_MIC_SIZE
] = { 0, };
250 DATA_BLOB mic_blob
= data_blob_const(mic_buffer
, sizeof(mic_buffer
));
253 TALLOC_CTX
*mem_ctx
= talloc_new(out_mem_ctx
);
255 return NT_STATUS_NO_MEMORY
;
258 if (!msrpc_parse(mem_ctx
,
264 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
265 dump_data(2, in
.data
, in
.length
);
266 talloc_free(mem_ctx
);
268 return NT_STATUS_INVALID_PARAMETER
;
271 data_blob_free(&server_domain_blob
);
273 DEBUG(3, ("Got challenge flags:\n"));
274 debug_ntlmssp_flags(chal_flags
);
276 nt_status
= ntlmssp_handle_neg_flags(ntlmssp_state
,
277 chal_flags
, "challenge");
278 if (!NT_STATUS_IS_OK(nt_status
)) {
282 if (ntlmssp_state
->unicode
) {
283 if (chal_flags
& NTLMSSP_NEGOTIATE_TARGET_INFO
) {
284 chal_parse_string
= "CdUdbddB";
286 chal_parse_string
= "CdUdbdd";
287 chal_parse_string_short
= "CdUdb";
289 auth_gen_string
= "CdBBUUUBdbb";
291 if (chal_flags
& NTLMSSP_NEGOTIATE_TARGET_INFO
) {
292 chal_parse_string
= "CdAdbddB";
294 chal_parse_string
= "CdAdbdd";
295 chal_parse_string_short
= "CdAdb";
298 auth_gen_string
= "CdBBAAABdbb";
301 if (!msrpc_parse(mem_ctx
,
302 &in
, chal_parse_string
,
313 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
315 if (chal_parse_string_short
!= NULL
) {
317 * In the case where NTLMSSP_NEGOTIATE_TARGET_INFO
318 * is not used, some NTLMSSP servers don't return
319 * the unused unkn1 and unkn2 fields.
321 * https://bugzilla.samba.org/show_bug.cgi?id=10016
323 * Try and parse again without them.
325 ok
= msrpc_parse(mem_ctx
,
326 &in
, chal_parse_string_short
,
333 DEBUG(1, ("Failed to short parse "
334 "the NTLMSSP Challenge: (#2)\n"));
339 dump_data(2, in
.data
, in
.length
);
340 talloc_free(mem_ctx
);
341 return NT_STATUS_INVALID_PARAMETER
;
345 if (chal_flags
& NTLMSSP_TARGET_TYPE_SERVER
) {
346 ntlmssp_state
->server
.is_standalone
= true;
348 ntlmssp_state
->server
.is_standalone
= false;
350 /* TODO: parse struct_blob and fill in the rest */
351 ntlmssp_state
->server
.netbios_name
= "";
352 ntlmssp_state
->server
.netbios_domain
= talloc_move(ntlmssp_state
, &server_domain
);
353 ntlmssp_state
->server
.dns_name
= "";
354 ntlmssp_state
->server
.dns_domain
= "";
356 if (challenge_blob
.length
!= 8) {
357 talloc_free(mem_ctx
);
358 return NT_STATUS_INVALID_PARAMETER
;
361 is_anonymous
= cli_credentials_is_anonymous(gensec_security
->credentials
);
362 cli_credentials_get_ntlm_username_domain(gensec_security
->credentials
, mem_ctx
,
365 workstation
= cli_credentials_get_workstation(gensec_security
->credentials
);
368 DEBUG(10, ("User is NULL, returning INVALID_PARAMETER\n"));
369 return NT_STATUS_INVALID_PARAMETER
;
372 if (domain
== NULL
) {
373 DEBUG(10, ("Domain is NULL, returning INVALID_PARAMETER\n"));
374 return NT_STATUS_INVALID_PARAMETER
;
377 if (workstation
== NULL
) {
378 DEBUG(10, ("Workstation is NULL, returning INVALID_PARAMETER\n"));
379 return NT_STATUS_INVALID_PARAMETER
;
383 ntlmssp_state
->neg_flags
|= NTLMSSP_ANONYMOUS
;
385 * don't use the ccache for anonymous auth
387 ntlmssp_state
->use_ccache
= false;
389 if (ntlmssp_state
->use_ccache
) {
390 struct samr_Password
*nt_hash
= NULL
;
393 * If we have a password given we don't
396 nt_hash
= cli_credentials_get_nt_hash(gensec_security
->credentials
,
398 if (nt_hash
!= NULL
) {
399 ZERO_STRUCTP(nt_hash
);
400 TALLOC_FREE(nt_hash
);
401 ntlmssp_state
->use_ccache
= false;
405 if (ntlmssp_state
->use_ccache
) {
406 struct wbcCredentialCacheParams params
;
407 struct wbcCredentialCacheInfo
*info
= NULL
;
408 struct wbcAuthErrorInfo
*error
= NULL
;
409 struct wbcNamedBlob auth_blobs
[2];
410 const struct wbcBlob
*wbc_auth_blob
= NULL
;
411 const struct wbcBlob
*wbc_session_key
= NULL
;
414 bool new_spnego
= false;
416 params
.account_name
= user
;
417 params
.domain_name
= domain
;
418 params
.level
= WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP
;
420 auth_blobs
[0].name
= "challenge_blob";
421 auth_blobs
[0].flags
= 0;
422 auth_blobs
[0].blob
.data
= in
.data
;
423 auth_blobs
[0].blob
.length
= in
.length
;
424 auth_blobs
[1].name
= "negotiate_blob";
425 auth_blobs
[1].flags
= 0;
426 auth_blobs
[1].blob
.data
= ntlmssp_state
->negotiate_blob
.data
;
427 auth_blobs
[1].blob
.length
= ntlmssp_state
->negotiate_blob
.length
;
428 params
.num_blobs
= ARRAY_SIZE(auth_blobs
);
429 params
.blobs
= auth_blobs
;
431 wbc_status
= wbcCredentialCache(¶ms
, &info
, &error
);
432 wbcFreeMemory(error
);
433 if (!WBC_ERROR_IS_OK(wbc_status
)) {
434 return NT_STATUS_WRONG_CREDENTIAL_HANDLE
;
437 for (i
=0; i
<info
->num_blobs
; i
++) {
438 if (strequal(info
->blobs
[i
].name
, "auth_blob")) {
439 wbc_auth_blob
= &info
->blobs
[i
].blob
;
441 if (strequal(info
->blobs
[i
].name
, "session_key")) {
442 wbc_session_key
= &info
->blobs
[i
].blob
;
444 if (strequal(info
->blobs
[i
].name
, "new_spnego")) {
448 if ((wbc_auth_blob
== NULL
) || (wbc_session_key
== NULL
)) {
450 return NT_STATUS_WRONG_CREDENTIAL_HANDLE
;
453 session_key
= data_blob_talloc(mem_ctx
,
454 wbc_session_key
->data
,
455 wbc_session_key
->length
);
456 if (session_key
.length
!= wbc_session_key
->length
) {
458 return NT_STATUS_NO_MEMORY
;
460 *out
= data_blob_talloc(mem_ctx
,
462 wbc_auth_blob
->length
);
463 if (out
->length
!= wbc_auth_blob
->length
) {
465 return NT_STATUS_NO_MEMORY
;
467 ntlmssp_state
->new_spnego
= new_spnego
;
473 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_NTLM2
) {
474 flags
|= CLI_CRED_NTLM2
;
476 if (ntlmssp_state
->use_ntlmv2
) {
477 flags
|= CLI_CRED_NTLMv2_AUTH
;
479 if (ntlmssp_state
->use_nt_response
) {
480 flags
|= CLI_CRED_NTLM_AUTH
;
482 if (ntlmssp_state
->allow_lm_response
) {
483 flags
|= CLI_CRED_LANMAN_AUTH
;
486 if (target_info
.length
!= 0 && !is_anonymous
) {
487 struct AV_PAIR
*pairs
= NULL
;
489 enum ndr_err_code err
;
490 struct AV_PAIR
*timestamp
= NULL
;
491 struct AV_PAIR
*eol
= NULL
;
493 const char *service
= NULL
;
494 const char *hostname
= NULL
;
496 err
= ndr_pull_struct_blob(&target_info
,
498 &ntlmssp_state
->server
.av_pair_list
,
499 (ndr_pull_flags_fn_t
)ndr_pull_AV_PAIR_LIST
);
500 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
501 return ndr_map_error2ntstatus(err
);
504 count
= ntlmssp_state
->server
.av_pair_list
.count
;
506 * We need room for Flags, SingleHost,
507 * ChannelBindings and Target
509 pairs
= talloc_zero_array(ntlmssp_state
, struct AV_PAIR
,
512 return NT_STATUS_NO_MEMORY
;
515 for (i
= 0; i
< count
; i
++) {
516 pairs
[i
] = ntlmssp_state
->server
.av_pair_list
.pair
[i
];
519 ntlmssp_state
->client
.av_pair_list
.count
= count
;
520 ntlmssp_state
->client
.av_pair_list
.pair
= pairs
;
522 eol
= ndr_ntlmssp_find_av(&ntlmssp_state
->client
.av_pair_list
,
525 return NT_STATUS_INVALID_PARAMETER
;
528 timestamp
= ndr_ntlmssp_find_av(&ntlmssp_state
->client
.av_pair_list
,
530 if (timestamp
!= NULL
) {
531 uint32_t sign_features
=
532 GENSEC_FEATURE_SESSION_KEY
|
533 GENSEC_FEATURE_SIGN
|
536 server_timestamp
= ×tamp
->Value
.AvTimestamp
;
538 if (ntlmssp_state
->force_old_spnego
) {
542 if (gensec_security
->want_features
& sign_features
) {
543 struct AV_PAIR
*av_flags
= NULL
;
545 av_flags
= ndr_ntlmssp_find_av(&ntlmssp_state
->client
.av_pair_list
,
547 if (av_flags
== NULL
) {
552 av_flags
->AvId
= MsvAvFlags
;
553 av_flags
->Value
.AvFlags
= 0;
556 av_flags
->Value
.AvFlags
|= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE
;
557 ntlmssp_state
->new_spnego
= true;
562 struct AV_PAIR
*SingleHost
= NULL
;
570 * This is not really used, but we want to
571 * add some more random bytes and match
574 SingleHost
->AvId
= MsvAvSingleHost
;
575 SingleHost
->Value
.AvSingleHost
.token_info
.Flags
= 0;
576 SingleHost
->Value
.AvSingleHost
.token_info
.TokenIL
= 0;
577 generate_random_buffer(SingleHost
->Value
.AvSingleHost
.token_info
.MachineId
,
578 sizeof(SingleHost
->Value
.AvSingleHost
.token_info
.MachineId
));
579 SingleHost
->Value
.AvSingleHost
.remaining
= data_blob_null
;
583 struct AV_PAIR
*ChannelBindings
= NULL
;
585 ChannelBindings
= eol
;
588 *eol
= *ChannelBindings
;
591 * gensec doesn't support channel bindings yet,
592 * but we want to match Windows on the wire
594 ChannelBindings
->AvId
= MsvChannelBindings
;
595 memset(ChannelBindings
->Value
.ChannelBindings
, 0,
596 sizeof(ChannelBindings
->Value
.ChannelBindings
));
599 service
= gensec_get_target_service(gensec_security
);
600 hostname
= gensec_get_target_hostname(gensec_security
);
601 if (service
!= NULL
&& hostname
!= NULL
) {
602 struct AV_PAIR
*target
= NULL
;
609 target
->AvId
= MsvAvTargetName
;
610 target
->Value
.AvTargetName
= talloc_asprintf(pairs
, "%s/%s",
613 if (target
->Value
.AvTargetName
== NULL
) {
614 return NT_STATUS_NO_MEMORY
;
618 ntlmssp_state
->client
.av_pair_list
.count
= count
;
619 ntlmssp_state
->client
.av_pair_list
.pair
= pairs
;
621 err
= ndr_push_struct_blob(&target_info
,
623 &ntlmssp_state
->client
.av_pair_list
,
624 (ndr_push_flags_fn_t
)ndr_push_AV_PAIR_LIST
);
625 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
626 return NT_STATUS_NO_MEMORY
;
630 nt_status
= cli_credentials_get_ntlm_response(gensec_security
->credentials
, mem_ctx
,
631 &flags
, challenge_blob
,
632 server_timestamp
, target_info
,
633 &lm_response
, &nt_response
,
634 &lm_session_key
, &session_key
);
635 if (!NT_STATUS_IS_OK(nt_status
)) {
639 if (!(flags
& CLI_CRED_LANMAN_AUTH
)) {
640 /* LM Key is still possible, just silly, so we do not
641 * allow it. Fortunetly all LM crypto is off by
642 * default and we require command line options to end
644 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_LM_KEY
;
647 if (!(flags
& CLI_CRED_NTLM2
)) {
648 /* NTLM2 is incompatible... */
649 ntlmssp_state
->neg_flags
&= ~NTLMSSP_NEGOTIATE_NTLM2
;
652 if ((ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_LM_KEY
)
653 && ntlmssp_state
->allow_lm_key
&& lm_session_key
.length
== 16) {
654 DATA_BLOB new_session_key
= data_blob_talloc(mem_ctx
, NULL
, 16);
655 if (lm_response
.length
== 24) {
656 SMBsesskeygen_lm_sess_key(lm_session_key
.data
, lm_response
.data
,
657 new_session_key
.data
);
659 static const uint8_t zeros
[24];
660 SMBsesskeygen_lm_sess_key(lm_session_key
.data
, zeros
,
661 new_session_key
.data
);
663 session_key
= new_session_key
;
664 dump_data_pw("LM session key\n", session_key
.data
, session_key
.length
);
668 /* Key exchange encryptes a new client-generated session key with
669 the password-derived key */
670 if (ntlmssp_state
->neg_flags
& NTLMSSP_NEGOTIATE_KEY_EXCH
) {
671 /* Make up a new session key */
672 uint8_t client_session_key
[16];
673 generate_secret_buffer(client_session_key
, sizeof(client_session_key
));
675 /* Encrypt the new session key with the old one */
676 encrypted_session_key
= data_blob_talloc(ntlmssp_state
,
677 client_session_key
, sizeof(client_session_key
));
678 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key
.data
, encrypted_session_key
.length
);
679 arcfour_crypt(encrypted_session_key
.data
, session_key
.data
, encrypted_session_key
.length
);
680 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key
.data
, encrypted_session_key
.length
);
682 /* Mark the new session key as the 'real' session key */
683 session_key
= data_blob_talloc(mem_ctx
, client_session_key
, sizeof(client_session_key
));
686 /* this generates the actual auth packet */
687 nt_status
= msrpc_gen(mem_ctx
,
688 out
, auth_gen_string
,
691 lm_response
.data
, lm_response
.length
,
692 nt_response
.data
, nt_response
.length
,
696 encrypted_session_key
.data
, encrypted_session_key
.length
,
697 ntlmssp_state
->neg_flags
,
698 version_blob
.data
, version_blob
.length
,
699 mic_blob
.data
, mic_blob
.length
);
700 if (!NT_STATUS_IS_OK(nt_status
)) {
701 talloc_free(mem_ctx
);
706 * We always include the MIC, even without:
707 * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
708 * ntlmssp_state->new_spnego = true;
710 * This matches a Windows client.
712 hmac_md5_init_limK_to_64(session_key
.data
,
715 hmac_md5_update(ntlmssp_state
->negotiate_blob
.data
,
716 ntlmssp_state
->negotiate_blob
.length
,
718 hmac_md5_update(in
.data
, in
.length
, &ctx
);
719 hmac_md5_update(out
->data
, out
->length
, &ctx
);
720 hmac_md5_final(mic_buffer
, &ctx
);
721 memcpy(out
->data
+ NTLMSSP_MIC_OFFSET
, mic_buffer
, NTLMSSP_MIC_SIZE
);
724 data_blob_free(&ntlmssp_state
->negotiate_blob
);
726 ntlmssp_state
->session_key
= session_key
;
727 talloc_steal(ntlmssp_state
, session_key
.data
);
729 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
730 debug_ntlmssp_flags(ntlmssp_state
->neg_flags
);
732 talloc_steal(out_mem_ctx
, out
->data
);
734 ntlmssp_state
->expected_state
= NTLMSSP_DONE
;
736 if (gensec_ntlmssp_have_feature(gensec_security
, GENSEC_FEATURE_SIGN
)) {
737 nt_status
= ntlmssp_sign_init(ntlmssp_state
);
738 if (!NT_STATUS_IS_OK(nt_status
)) {
739 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
740 nt_errstr(nt_status
)));
741 talloc_free(mem_ctx
);
746 talloc_free(mem_ctx
);
750 NTSTATUS
gensec_ntlmssp_client_start(struct gensec_security
*gensec_security
)
752 struct gensec_ntlmssp_context
*gensec_ntlmssp
;
753 struct ntlmssp_state
*ntlmssp_state
;
756 nt_status
= gensec_ntlmssp_start(gensec_security
);
757 NT_STATUS_NOT_OK_RETURN(nt_status
);
760 talloc_get_type_abort(gensec_security
->private_data
,
761 struct gensec_ntlmssp_context
);
763 ntlmssp_state
= talloc_zero(gensec_ntlmssp
,
764 struct ntlmssp_state
);
765 if (!ntlmssp_state
) {
766 return NT_STATUS_NO_MEMORY
;
769 gensec_ntlmssp
->ntlmssp_state
= ntlmssp_state
;
771 ntlmssp_state
= gensec_ntlmssp
->ntlmssp_state
;
773 ntlmssp_state
->role
= NTLMSSP_CLIENT
;
775 ntlmssp_state
->client
.netbios_domain
= lpcfg_workgroup(gensec_security
->settings
->lp_ctx
);
776 ntlmssp_state
->client
.netbios_name
= cli_credentials_get_workstation(gensec_security
->credentials
);
778 ntlmssp_state
->unicode
= gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "unicode", true);
780 ntlmssp_state
->use_nt_response
= \
781 gensec_setting_bool(gensec_security
->settings
,
786 ntlmssp_state
->allow_lm_response
= lpcfg_client_lanman_auth(gensec_security
->settings
->lp_ctx
);
788 ntlmssp_state
->allow_lm_key
= (ntlmssp_state
->allow_lm_response
789 && (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "allow_lm_key", false)
790 || gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "lm_key", false)));
792 ntlmssp_state
->use_ntlmv2
= lpcfg_client_ntlmv2_auth(gensec_security
->settings
->lp_ctx
);
794 ntlmssp_state
->force_old_spnego
= gensec_setting_bool(gensec_security
->settings
,
795 "ntlmssp_client", "force_old_spnego", false);
797 ntlmssp_state
->expected_state
= NTLMSSP_INITIAL
;
799 ntlmssp_state
->neg_flags
=
800 NTLMSSP_NEGOTIATE_NTLM
|
801 NTLMSSP_NEGOTIATE_VERSION
|
802 NTLMSSP_REQUEST_TARGET
;
804 if (ntlmssp_state
->unicode
) {
805 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_UNICODE
;
807 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_OEM
;
810 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "128bit", true)) {
811 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_128
;
814 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "56bit", false)) {
815 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_56
;
818 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "lm_key", false)) {
819 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_LM_KEY
;
822 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "keyexchange", true)) {
823 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_KEY_EXCH
;
826 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "alwayssign", true)) {
827 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
;
830 if (gensec_setting_bool(gensec_security
->settings
, "ntlmssp_client", "ntlm2", true)) {
831 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_NTLM2
;
833 /* apparently we can't do ntlmv2 if we don't do ntlm2 */
834 ntlmssp_state
->use_ntlmv2
= false;
837 if (ntlmssp_state
->use_ntlmv2
) {
838 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_NTLM2
;
839 ntlmssp_state
->allow_lm_response
= false;
840 ntlmssp_state
->allow_lm_key
= false;
843 if (ntlmssp_state
->allow_lm_key
) {
844 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_LM_KEY
;
847 if (gensec_security
->want_features
& GENSEC_FEATURE_SESSION_KEY
) {
849 * We need to set this to allow a later SetPassword
850 * via the SAMR pipe to succeed. Strange.... We could
851 * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
853 * Without this, Windows will not create the master key
854 * that it thinks is only used for NTLMSSP signing and
855 * sealing. (It is actually pulled out and used directly)
857 * We don't require this here as some servers (e.g. NetAPP)
858 * doesn't support this.
860 ntlmssp_state
->neg_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
862 if (gensec_security
->want_features
& GENSEC_FEATURE_SIGN
) {
863 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
865 if (gensec_security
->want_features
& GENSEC_FEATURE_LDAP_STYLE
) {
867 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
868 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
871 ntlmssp_state
->force_wrap_seal
= true;
874 if (ntlmssp_state
->force_wrap_seal
) {
878 * We want also work against old Samba servers
879 * which didn't had GENSEC_FEATURE_LDAP_STYLE
880 * we negotiate SEAL too. We may remove this
881 * in a few years. As all servers should have
882 * GENSEC_FEATURE_LDAP_STYLE by then.
884 ret
= gensec_setting_bool(gensec_security
->settings
,
886 "ldap_style_send_seal",
889 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SEAL
;
892 if (gensec_security
->want_features
& GENSEC_FEATURE_SEAL
) {
893 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
894 ntlmssp_state
->required_flags
|= NTLMSSP_NEGOTIATE_SEAL
;
896 if (gensec_security
->want_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
897 ntlmssp_state
->use_ccache
= true;
900 ntlmssp_state
->neg_flags
|= ntlmssp_state
->required_flags
;
901 ntlmssp_state
->conf_flags
= ntlmssp_state
->neg_flags
;
906 NTSTATUS
gensec_ntlmssp_resume_ccache_start(struct gensec_security
*gensec_security
)
908 struct gensec_ntlmssp_context
*gensec_ntlmssp
= NULL
;
911 status
= gensec_ntlmssp_client_start(gensec_security
);
912 if (!NT_STATUS_IS_OK(status
)) {
916 gensec_ntlmssp
= talloc_get_type_abort(gensec_security
->private_data
,
917 struct gensec_ntlmssp_context
);
918 gensec_ntlmssp
->ntlmssp_state
->use_ccache
= false;
919 gensec_ntlmssp
->ntlmssp_state
->resume_ccache
= true;
920 gensec_ntlmssp
->ntlmssp_state
->expected_state
= NTLMSSP_NEGOTIATE
;