2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1998-2001
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
7 Copyright (C) Luke Howard 2003
8 Copyright (C) Volker Lendecke 2007
9 Copyright (C) Jeremy Allison 2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "../lib/tsocket/tsocket.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "../libcli/auth/spnego.h"
30 #include "../libcli/auth/ntlmssp.h"
31 #include "ntlmssp_wrap.h"
32 #include "../librpc/gen_ndr/krb5pac.h"
33 #include "libads/kerberos_proto.h"
34 #include "../lib/util/asn1.h"
37 #include "smbprofile.h"
39 /* For split krb5 SPNEGO blobs. */
40 struct pending_auth_data
{
41 struct pending_auth_data
*prev
, *next
;
42 uint16 vuid
; /* Tag for this entry. */
43 uint16 smbpid
; /* Alternate tag for this entry. */
45 DATA_BLOB partial_data
;
49 on a logon error possibly map the error to success if "map to guest"
52 NTSTATUS
do_map_to_guest(NTSTATUS status
,
53 struct auth_serversupplied_info
**server_info
,
54 const char *user
, const char *domain
)
56 user
= user
? user
: "";
57 domain
= domain
? domain
: "";
59 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
60 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER
) ||
61 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
)) {
62 DEBUG(3,("No such user %s [%s] - using guest account\n",
64 status
= make_server_info_guest(NULL
, server_info
);
68 if (NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
69 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
) {
70 DEBUG(3,("Registered username %s for guest access\n",
72 status
= make_server_info_guest(NULL
, server_info
);
79 /****************************************************************************
80 Add the standard 'Samba' signature to the end of the session setup.
81 ****************************************************************************/
83 static int push_signature(uint8
**outbuf
)
90 tmp
= message_push_string(outbuf
, "Unix", STR_TERMINATE
);
92 if (tmp
== -1) return -1;
95 if (asprintf(&lanman
, "Samba %s", samba_version_string()) != -1) {
96 tmp
= message_push_string(outbuf
, lanman
, STR_TERMINATE
);
100 tmp
= message_push_string(outbuf
, "Samba", STR_TERMINATE
);
103 if (tmp
== -1) return -1;
106 tmp
= message_push_string(outbuf
, lp_workgroup(), STR_TERMINATE
);
108 if (tmp
== -1) return -1;
114 /****************************************************************************
115 Send a security blob via a session setup reply.
116 ****************************************************************************/
118 static void reply_sesssetup_blob(struct smb_request
*req
,
122 if (!NT_STATUS_IS_OK(nt_status
) &&
123 !NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
124 reply_nterror(req
, nt_status_squash(nt_status
));
128 nt_status
= nt_status_squash(nt_status
);
129 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(nt_status
));
130 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
131 SSVAL(req
->outbuf
, smb_vwv3
, blob
.length
);
133 if ((message_push_blob(&req
->outbuf
, blob
) == -1)
134 || (push_signature(&req
->outbuf
) == -1)) {
135 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
139 /****************************************************************************
140 Do a 'guest' logon, getting back the
141 ****************************************************************************/
143 static NTSTATUS
check_guest_password(struct auth_serversupplied_info
**server_info
)
145 struct auth_context
*auth_context
;
146 struct auth_usersupplied_info
*user_info
= NULL
;
149 static unsigned char chal
[8] = { 0, };
151 DEBUG(3,("Got anonymous request\n"));
153 nt_status
= make_auth_context_fixed(talloc_tos(), &auth_context
, chal
);
154 if (!NT_STATUS_IS_OK(nt_status
)) {
158 if (!make_user_info_guest(&user_info
)) {
159 TALLOC_FREE(auth_context
);
160 return NT_STATUS_NO_MEMORY
;
163 nt_status
= auth_context
->check_ntlm_password(auth_context
,
166 TALLOC_FREE(auth_context
);
167 free_user_info(&user_info
);
175 /* Experiment that failed. See "only happens with a KDC" comment below. */
176 /****************************************************************************
177 Cerate a clock skew error blob for a Windows client.
178 ****************************************************************************/
180 static bool make_krb5_skew_error(DATA_BLOB
*pblob_out
)
182 krb5_context context
= NULL
;
183 krb5_error_code kerr
= 0;
185 krb5_principal host_princ
= NULL
;
186 char *host_princ_s
= NULL
;
189 *pblob_out
= data_blob_null
;
191 initialize_krb5_error_table();
192 kerr
= krb5_init_context(&context
);
196 /* Create server principal. */
197 asprintf(&host_princ_s
, "%s$@%s", global_myname(), lp_realm());
201 strlower_m(host_princ_s
);
203 kerr
= smb_krb5_parse_name(context
, host_princ_s
, &host_princ
);
205 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
206 "for name %s: Error %s\n",
207 host_princ_s
, error_message(kerr
) ));
211 kerr
= smb_krb5_mk_error(context
, KRB5KRB_AP_ERR_SKEW
,
214 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
215 "failed: Error %s\n",
216 error_message(kerr
) ));
220 *pblob_out
= data_blob(reply
.data
, reply
.length
);
221 kerberos_free_data_contents(context
,&reply
);
227 SAFE_FREE(host_princ_s
);
230 krb5_free_principal(context
, host_princ
);
232 krb5_free_context(context
);
237 /****************************************************************************
238 Reply to a session setup spnego negotiate packet for kerberos.
239 ****************************************************************************/
241 static void reply_spnego_kerberos(struct smb_request
*req
,
245 bool *p_invalidate_vuid
)
250 int sess_vuid
= req
->vuid
;
251 NTSTATUS ret
= NT_STATUS_OK
;
252 DATA_BLOB ap_rep
, ap_rep_wrapped
, response
;
253 struct auth_serversupplied_info
*server_info
= NULL
;
254 DATA_BLOB session_key
= data_blob_null
;
256 DATA_BLOB nullblob
= data_blob_null
;
257 bool map_domainuser_to_guest
= False
;
258 bool username_was_mapped
;
259 struct PAC_LOGON_INFO
*logon_info
= NULL
;
260 struct smbd_server_connection
*sconn
= req
->sconn
;
268 ZERO_STRUCT(ap_rep_wrapped
);
269 ZERO_STRUCT(response
);
271 /* Normally we will always invalidate the intermediate vuid. */
272 *p_invalidate_vuid
= True
;
274 mem_ctx
= talloc_init("reply_spnego_kerberos");
275 if (mem_ctx
== NULL
) {
276 reply_nterror(req
, nt_status_squash(NT_STATUS_NO_MEMORY
));
280 if (!spnego_parse_krb5_wrap(mem_ctx
, *secblob
, &ticket
, tok_id
)) {
281 talloc_destroy(mem_ctx
);
282 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
286 ret
= ads_verify_ticket(mem_ctx
, lp_realm(), 0, &ticket
,
287 &principal
, &logon_info
, &ap_rep
,
290 data_blob_free(&ticket
);
292 if (!NT_STATUS_IS_OK(ret
)) {
294 /* Experiment that failed.
295 * See "only happens with a KDC" comment below. */
297 if (NT_STATUS_EQUAL(ret
, NT_STATUS_TIME_DIFFERENCE_AT_DC
)) {
300 * Windows in this case returns
301 * NT_STATUS_MORE_PROCESSING_REQUIRED
302 * with a negTokenTarg blob containing an krb5_error
303 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
304 * The client then fixes its clock and continues rather
305 * than giving an error. JRA.
306 * -- Looks like this only happens with a KDC. JRA.
309 bool ok
= make_krb5_skew_error(&ap_rep
);
311 talloc_destroy(mem_ctx
);
312 return ERROR_NT(nt_status_squash(
313 NT_STATUS_LOGON_FAILURE
));
315 ap_rep_wrapped
= spnego_gen_krb5_wrap(ap_rep
,
317 response
= spnego_gen_auth_response(&ap_rep_wrapped
,
318 ret
, OID_KERBEROS5_OLD
);
319 reply_sesssetup_blob(conn
, inbuf
, outbuf
, response
,
320 NT_STATUS_MORE_PROCESSING_REQUIRED
);
323 * In this one case we don't invalidate the
324 * intermediate vuid as we're expecting the client
325 * to re-use it for the next sessionsetupX packet. JRA.
328 *p_invalidate_vuid
= False
;
330 data_blob_free(&ap_rep
);
331 data_blob_free(&ap_rep_wrapped
);
332 data_blob_free(&response
);
333 talloc_destroy(mem_ctx
);
334 return -1; /* already replied */
337 if (!NT_STATUS_EQUAL(ret
, NT_STATUS_TIME_DIFFERENCE_AT_DC
)) {
338 ret
= NT_STATUS_LOGON_FAILURE
;
341 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
343 talloc_destroy(mem_ctx
);
344 reply_nterror(req
, nt_status_squash(ret
));
348 ret
= get_user_from_kerberos_info(talloc_tos(),
349 sconn
->client_id
.name
,
350 principal
, logon_info
,
351 &username_was_mapped
,
352 &map_domainuser_to_guest
,
354 &real_username
, &pw
);
355 if (!NT_STATUS_IS_OK(ret
)) {
356 data_blob_free(&ap_rep
);
357 data_blob_free(&session_key
);
358 talloc_destroy(mem_ctx
);
359 reply_nterror(req
,nt_status_squash(NT_STATUS_LOGON_FAILURE
));
363 /* save the PAC data if we have it */
365 netsamlogon_cache_store(user
, &logon_info
->info3
);
368 /* setup the string used by %U */
369 sub_set_smb_name(real_username
);
371 /* reload services so that the new %U is taken into account */
372 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
374 ret
= make_server_info_krb5(mem_ctx
,
375 user
, domain
, real_username
, pw
,
376 logon_info
, map_domainuser_to_guest
,
378 if (!NT_STATUS_IS_OK(ret
)) {
379 DEBUG(1, ("make_server_info_krb5 failed!\n"));
380 data_blob_free(&ap_rep
);
381 data_blob_free(&session_key
);
382 TALLOC_FREE(mem_ctx
);
383 reply_nterror(req
, nt_status_squash(ret
));
387 server_info
->nss_token
|= username_was_mapped
;
389 /* we need to build the token for the user. make_server_info_guest()
392 if ( !server_info
->security_token
) {
393 ret
= create_local_token( server_info
);
394 if ( !NT_STATUS_IS_OK(ret
) ) {
395 DEBUG(10,("failed to create local token: %s\n",
397 data_blob_free(&ap_rep
);
398 data_blob_free(&session_key
);
399 TALLOC_FREE( mem_ctx
);
400 TALLOC_FREE( server_info
);
401 reply_nterror(req
, nt_status_squash(ret
));
406 if (!is_partial_auth_vuid(sconn
, sess_vuid
)) {
407 sess_vuid
= register_initial_vuid(sconn
);
410 data_blob_free(&server_info
->user_session_key
);
411 /* Set the kerberos-derived session key onto the server_info */
412 server_info
->user_session_key
= session_key
;
413 talloc_steal(server_info
, session_key
.data
);
415 session_key
= data_blob_null
;
417 /* register_existing_vuid keeps the server info */
418 /* register_existing_vuid takes ownership of session_key on success,
419 * no need to free after this on success. A better interface would copy
422 sess_vuid
= register_existing_vuid(sconn
, sess_vuid
,
423 server_info
, nullblob
, user
);
425 reply_outbuf(req
, 4, 0);
426 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
428 if (sess_vuid
== UID_FIELD_INVALID
) {
429 ret
= NT_STATUS_LOGON_FAILURE
;
431 /* current_user_info is changed on new vuid */
432 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
434 SSVAL(req
->outbuf
, smb_vwv3
, 0);
436 if (server_info
->guest
) {
437 SSVAL(req
->outbuf
,smb_vwv2
,1);
440 SSVAL(req
->outbuf
, smb_uid
, sess_vuid
);
442 /* Successful logon. Keep this vuid. */
443 *p_invalidate_vuid
= False
;
446 /* wrap that up in a nice GSS-API wrapping */
447 if (NT_STATUS_IS_OK(ret
)) {
448 ap_rep_wrapped
= spnego_gen_krb5_wrap(talloc_tos(), ap_rep
,
451 ap_rep_wrapped
= data_blob_null
;
453 response
= spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped
, ret
,
455 reply_sesssetup_blob(req
, response
, ret
);
457 data_blob_free(&ap_rep
);
458 data_blob_free(&ap_rep_wrapped
);
459 data_blob_free(&response
);
460 TALLOC_FREE(mem_ctx
);
465 /****************************************************************************
466 Send a session setup reply, wrapped in SPNEGO.
467 Get vuid and check first.
468 End the NTLMSSP exchange context if we are OK/complete fail
469 This should be split into two functions, one to handle each
470 leg of the NTLM auth steps.
471 ***************************************************************************/
473 static void reply_spnego_ntlmssp(struct smb_request
*req
,
475 struct auth_ntlmssp_state
**auth_ntlmssp_state
,
476 DATA_BLOB
*ntlmssp_blob
, NTSTATUS nt_status
,
480 bool do_invalidate
= true;
482 struct auth_serversupplied_info
*session_info
= NULL
;
483 struct smbd_server_connection
*sconn
= req
->sconn
;
485 if (NT_STATUS_IS_OK(nt_status
)) {
486 nt_status
= auth_ntlmssp_steal_session_info(talloc_tos(),
487 (*auth_ntlmssp_state
), &session_info
);
489 /* Note that this session_info won't have a session
490 * key. But for map to guest, that's exactly the right
491 * thing - we can't reasonably guess the key the
492 * client wants, as the password was wrong */
493 nt_status
= do_map_to_guest(nt_status
,
495 auth_ntlmssp_get_username(*auth_ntlmssp_state
),
496 auth_ntlmssp_get_domain(*auth_ntlmssp_state
));
499 reply_outbuf(req
, 4, 0);
501 SSVAL(req
->outbuf
, smb_uid
, vuid
);
503 if (NT_STATUS_IS_OK(nt_status
)) {
504 DATA_BLOB nullblob
= data_blob_null
;
506 if (!is_partial_auth_vuid(sconn
, vuid
)) {
507 nt_status
= NT_STATUS_LOGON_FAILURE
;
511 /* register_existing_vuid keeps the server info */
512 if (register_existing_vuid(sconn
, vuid
,
513 session_info
, nullblob
,
514 auth_ntlmssp_get_username(*auth_ntlmssp_state
)) !=
516 /* The problem is, *auth_ntlmssp_state points
517 * into the vuser this will have
518 * talloc_free()'ed in
519 * register_existing_vuid() */
520 do_invalidate
= false;
521 nt_status
= NT_STATUS_LOGON_FAILURE
;
525 /* current_user_info is changed on new vuid */
526 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
528 SSVAL(req
->outbuf
, smb_vwv3
, 0);
530 if (session_info
->guest
) {
531 SSVAL(req
->outbuf
,smb_vwv2
,1);
538 response
= spnego_gen_auth_response(talloc_tos(),
542 response
= *ntlmssp_blob
;
545 reply_sesssetup_blob(req
, response
, nt_status
);
547 data_blob_free(&response
);
550 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
551 and the other end, that we are not finished yet. */
553 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
554 /* NB. This is *NOT* an error case. JRA */
556 TALLOC_FREE(*auth_ntlmssp_state
);
557 if (!NT_STATUS_IS_OK(nt_status
)) {
558 /* Kill the intermediate vuid */
559 invalidate_vuid(sconn
, vuid
);
565 /****************************************************************************
566 Is this a krb5 mechanism ?
567 ****************************************************************************/
569 NTSTATUS
parse_spnego_mechanisms(TALLOC_CTX
*ctx
,
571 DATA_BLOB
*pblob_out
,
574 char *OIDs
[ASN1_MAX_OIDS
];
576 NTSTATUS ret
= NT_STATUS_OK
;
578 *kerb_mechOID
= NULL
;
580 /* parse out the OIDs and the first sec blob */
581 if (!spnego_parse_negTokenInit(ctx
, blob_in
, OIDs
, NULL
, pblob_out
) ||
583 return NT_STATUS_LOGON_FAILURE
;
586 /* only look at the first OID for determining the mechToken --
587 according to RFC2478, we should choose the one we want
588 and renegotiate, but i smell a client bug here..
590 Problem observed when connecting to a member (samba box)
591 of an AD domain as a user in a Samba domain. Samba member
592 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
593 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
594 NTLMSSP mechtoken. --jerry */
597 if (strcmp(OID_KERBEROS5
, OIDs
[0]) == 0 ||
598 strcmp(OID_KERBEROS5_OLD
, OIDs
[0]) == 0) {
599 *kerb_mechOID
= talloc_strdup(ctx
, OIDs
[0]);
600 if (*kerb_mechOID
== NULL
) {
601 ret
= NT_STATUS_NO_MEMORY
;
606 for (i
=0;OIDs
[i
];i
++) {
607 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs
[i
]));
608 talloc_free(OIDs
[i
]);
613 /****************************************************************************
614 Fall back from krb5 to NTLMSSP.
615 ****************************************************************************/
617 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request
*req
,
622 reply_outbuf(req
, 4, 0);
623 SSVAL(req
->outbuf
,smb_uid
,vuid
);
625 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
626 "but set to downgrade to NTLMSSP\n"));
628 response
= spnego_gen_auth_response(talloc_tos(), NULL
,
629 NT_STATUS_MORE_PROCESSING_REQUIRED
,
631 reply_sesssetup_blob(req
, response
, NT_STATUS_MORE_PROCESSING_REQUIRED
);
632 data_blob_free(&response
);
635 /****************************************************************************
636 Reply to a session setup spnego negotiate packet.
637 ****************************************************************************/
639 static void reply_spnego_negotiate(struct smb_request
*req
,
642 struct auth_ntlmssp_state
**auth_ntlmssp_state
)
646 char *kerb_mech
= NULL
;
648 struct smbd_server_connection
*sconn
= req
->sconn
;
650 status
= parse_spnego_mechanisms(talloc_tos(),
651 blob1
, &secblob
, &kerb_mech
);
652 if (!NT_STATUS_IS_OK(status
)) {
653 /* Kill the intermediate vuid */
654 invalidate_vuid(sconn
, vuid
);
655 reply_nterror(req
, nt_status_squash(status
));
659 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
660 (unsigned long)secblob
.length
));
663 if (kerb_mech
&& ((lp_security()==SEC_ADS
) ||
664 USE_KERBEROS_KEYTAB
) ) {
665 bool destroy_vuid
= True
;
666 reply_spnego_kerberos(req
, &secblob
, kerb_mech
,
667 vuid
, &destroy_vuid
);
668 data_blob_free(&secblob
);
670 /* Kill the intermediate vuid */
671 invalidate_vuid(sconn
, vuid
);
673 TALLOC_FREE(kerb_mech
);
678 TALLOC_FREE(*auth_ntlmssp_state
);
681 data_blob_free(&secblob
);
682 /* The mechtoken is a krb5 ticket, but
683 * we need to fall back to NTLM. */
684 reply_spnego_downgrade_to_ntlmssp(req
, vuid
);
685 TALLOC_FREE(kerb_mech
);
689 status
= auth_ntlmssp_start(auth_ntlmssp_state
);
690 if (!NT_STATUS_IS_OK(status
)) {
691 /* Kill the intermediate vuid */
692 invalidate_vuid(sconn
, vuid
);
693 reply_nterror(req
, nt_status_squash(status
));
697 status
= auth_ntlmssp_update(*auth_ntlmssp_state
,
700 data_blob_free(&secblob
);
702 reply_spnego_ntlmssp(req
, vuid
, auth_ntlmssp_state
,
703 &chal
, status
, OID_NTLMSSP
, true);
705 data_blob_free(&chal
);
707 /* already replied */
711 /****************************************************************************
712 Reply to a session setup spnego auth packet.
713 ****************************************************************************/
715 static void reply_spnego_auth(struct smb_request
*req
,
718 struct auth_ntlmssp_state
**auth_ntlmssp_state
)
720 DATA_BLOB auth
= data_blob_null
;
721 DATA_BLOB auth_reply
= data_blob_null
;
722 DATA_BLOB secblob
= data_blob_null
;
723 NTSTATUS status
= NT_STATUS_LOGON_FAILURE
;
724 struct smbd_server_connection
*sconn
= req
->sconn
;
726 if (!spnego_parse_auth(talloc_tos(), blob1
, &auth
)) {
728 file_save("auth.dat", blob1
.data
, blob1
.length
);
730 /* Kill the intermediate vuid */
731 invalidate_vuid(sconn
, vuid
);
733 reply_nterror(req
, nt_status_squash(
734 NT_STATUS_LOGON_FAILURE
));
738 if (auth
.data
[0] == ASN1_APPLICATION(0)) {
739 /* Might be a second negTokenTarg packet */
740 char *kerb_mech
= NULL
;
742 status
= parse_spnego_mechanisms(talloc_tos(),
743 auth
, &secblob
, &kerb_mech
);
745 if (!NT_STATUS_IS_OK(status
)) {
746 /* Kill the intermediate vuid */
747 invalidate_vuid(sconn
, vuid
);
748 reply_nterror(req
, nt_status_squash(status
));
752 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
753 (unsigned long)secblob
.length
));
755 if (kerb_mech
&& ((lp_security()==SEC_ADS
) ||
756 USE_KERBEROS_KEYTAB
)) {
757 bool destroy_vuid
= True
;
758 reply_spnego_kerberos(req
, &secblob
, kerb_mech
,
759 vuid
, &destroy_vuid
);
760 data_blob_free(&secblob
);
761 data_blob_free(&auth
);
763 /* Kill the intermediate vuid */
764 invalidate_vuid(sconn
, vuid
);
766 TALLOC_FREE(kerb_mech
);
770 /* Can't blunder into NTLMSSP auth if we have
774 /* Kill the intermediate vuid */
775 invalidate_vuid(sconn
, vuid
);
776 DEBUG(3,("reply_spnego_auth: network "
777 "misconfiguration, client sent us a "
778 "krb5 ticket and kerberos security "
780 reply_nterror(req
, nt_status_squash(
781 NT_STATUS_LOGON_FAILURE
));
782 TALLOC_FREE(kerb_mech
);
786 /* If we get here it wasn't a negTokenTarg auth packet. */
787 data_blob_free(&secblob
);
789 if (!*auth_ntlmssp_state
) {
790 status
= auth_ntlmssp_start(auth_ntlmssp_state
);
791 if (!NT_STATUS_IS_OK(status
)) {
792 /* Kill the intermediate vuid */
793 invalidate_vuid(sconn
, vuid
);
794 reply_nterror(req
, nt_status_squash(status
));
799 status
= auth_ntlmssp_update(*auth_ntlmssp_state
,
802 data_blob_free(&auth
);
804 /* Don't send the mechid as we've already sent this (RFC4178). */
806 reply_spnego_ntlmssp(req
, vuid
,
808 &auth_reply
, status
, NULL
, true);
810 data_blob_free(&auth_reply
);
812 /* and tell smbd that we have already replied to this packet */
816 /****************************************************************************
817 Delete an entry on the list.
818 ****************************************************************************/
820 static void delete_partial_auth(struct smbd_server_connection
*sconn
,
821 struct pending_auth_data
*pad
)
826 DLIST_REMOVE(sconn
->smb1
.pd_list
, pad
);
827 data_blob_free(&pad
->partial_data
);
831 /****************************************************************************
832 Search for a partial SPNEGO auth fragment matching an smbpid.
833 ****************************************************************************/
835 static struct pending_auth_data
*get_pending_auth_data(
836 struct smbd_server_connection
*sconn
,
839 struct pending_auth_data
*pad
;
841 * NOTE: using the smbpid here is completely wrong...
843 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
845 for (pad
= sconn
->smb1
.pd_list
; pad
; pad
= pad
->next
) {
846 if (pad
->smbpid
== smbpid
) {
853 /****************************************************************************
854 Check the size of an SPNEGO blob. If we need more return
855 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
856 the blob to be more than 64k.
857 ****************************************************************************/
859 static NTSTATUS
check_spnego_blob_complete(struct smbd_server_connection
*sconn
,
860 uint16 smbpid
, uint16 vuid
,
863 struct pending_auth_data
*pad
= NULL
;
865 size_t needed_len
= 0;
867 pad
= get_pending_auth_data(sconn
, smbpid
);
869 /* Ensure we have some data. */
870 if (pblob
->length
== 0) {
871 /* Caller can cope. */
872 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
873 delete_partial_auth(sconn
, pad
);
877 /* Were we waiting for more data ? */
880 size_t copy_len
= MIN(65536, pblob
->length
);
882 /* Integer wrap paranoia.... */
884 if (pad
->partial_data
.length
+ copy_len
<
885 pad
->partial_data
.length
||
886 pad
->partial_data
.length
+ copy_len
< copy_len
) {
888 DEBUG(2,("check_spnego_blob_complete: integer wrap "
889 "pad->partial_data.length = %u, "
891 (unsigned int)pad
->partial_data
.length
,
892 (unsigned int)copy_len
));
894 delete_partial_auth(sconn
, pad
);
895 return NT_STATUS_INVALID_PARAMETER
;
898 DEBUG(10,("check_spnego_blob_complete: "
899 "pad->partial_data.length = %u, "
900 "pad->needed_len = %u, "
902 "pblob->length = %u,\n",
903 (unsigned int)pad
->partial_data
.length
,
904 (unsigned int)pad
->needed_len
,
905 (unsigned int)copy_len
,
906 (unsigned int)pblob
->length
));
908 tmp_blob
= data_blob(NULL
,
909 pad
->partial_data
.length
+ copy_len
);
911 /* Concatenate the two (up to copy_len) bytes. */
912 memcpy(tmp_blob
.data
,
913 pad
->partial_data
.data
,
914 pad
->partial_data
.length
);
915 memcpy(tmp_blob
.data
+ pad
->partial_data
.length
,
919 /* Replace the partial data. */
920 data_blob_free(&pad
->partial_data
);
921 pad
->partial_data
= tmp_blob
;
922 ZERO_STRUCT(tmp_blob
);
925 if (pblob
->length
>= pad
->needed_len
) {
926 /* Yes, replace pblob. */
927 data_blob_free(pblob
);
928 *pblob
= pad
->partial_data
;
929 ZERO_STRUCT(pad
->partial_data
);
930 delete_partial_auth(sconn
, pad
);
934 /* Still need more data. */
935 pad
->needed_len
-= copy_len
;
936 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
939 if ((pblob
->data
[0] != ASN1_APPLICATION(0)) &&
940 (pblob
->data
[0] != ASN1_CONTEXT(1))) {
941 /* Not something we can determine the
947 /* This is a new SPNEGO sessionsetup - see if
948 * the data given in this blob is enough.
951 data
= asn1_init(NULL
);
953 return NT_STATUS_NO_MEMORY
;
956 asn1_load(data
, *pblob
);
957 if (asn1_start_tag(data
, pblob
->data
[0])) {
958 /* asn1_start_tag checks if the given
959 length of the blob is enough to complete
960 the tag. If it returns true we know
961 there is nothing to do - the blob is
967 if (data
->nesting
== NULL
) {
968 /* Incorrect tag, allocation failed,
969 or reading the tag length failed.
970 Let the caller catch. */
975 /* Here we know asn1_start_tag() has set data->has_error to true.
976 asn1_tag_remaining() will have failed due to the given blob
977 being too short. We need to work out how short. */
979 /* Integer wrap paranoia.... */
981 if (data
->nesting
->taglen
+ data
->nesting
->start
< data
->nesting
->taglen
||
982 data
->nesting
->taglen
+ data
->nesting
->start
< data
->nesting
->start
) {
984 DEBUG(2,("check_spnego_blob_complete: integer wrap "
985 "data.nesting->taglen = %u, "
986 "data.nesting->start = %u\n",
987 (unsigned int)data
->nesting
->taglen
,
988 (unsigned int)data
->nesting
->start
));
991 return NT_STATUS_INVALID_PARAMETER
;
994 /* Total length of the needed asn1 is the tag length
995 * plus the current offset. */
997 needed_len
= data
->nesting
->taglen
+ data
->nesting
->start
;
1000 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
1001 "pblob->length = %u\n",
1002 (unsigned int)needed_len
,
1003 (unsigned int)pblob
->length
));
1005 if (needed_len
<= pblob
->length
) {
1006 /* Nothing to do - blob is complete. */
1007 /* THIS SHOULD NOT HAPPEN - asn1_start_tag()
1008 above should have caught this !!! */
1009 DEBUG(0,("check_spnego_blob_complete: logic "
1010 "error (needed_len = %u, "
1011 "pblob->length = %u).\n",
1012 (unsigned int)needed_len
,
1013 (unsigned int)pblob
->length
));
1014 return NT_STATUS_OK
;
1017 /* Refuse the blob if it's bigger than 64k. */
1018 if (needed_len
> 65536) {
1019 DEBUG(2,("check_spnego_blob_complete: needed_len "
1021 (unsigned int)needed_len
));
1022 return NT_STATUS_INVALID_PARAMETER
;
1025 /* We must store this blob until complete. */
1026 if (!(pad
= SMB_MALLOC_P(struct pending_auth_data
))) {
1027 return NT_STATUS_NO_MEMORY
;
1029 pad
->needed_len
= needed_len
- pblob
->length
;
1030 pad
->partial_data
= data_blob(pblob
->data
, pblob
->length
);
1031 if (pad
->partial_data
.data
== NULL
) {
1033 return NT_STATUS_NO_MEMORY
;
1035 pad
->smbpid
= smbpid
;
1037 DLIST_ADD(sconn
->smb1
.pd_list
, pad
);
1039 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
1042 /****************************************************************************
1043 Reply to a session setup command.
1044 conn POINTER CAN BE NULL HERE !
1045 ****************************************************************************/
1047 static void reply_sesssetup_and_X_spnego(struct smb_request
*req
)
1053 const char *native_os
;
1054 const char *native_lanman
;
1055 const char *primary_domain
;
1057 uint16 data_blob_len
= SVAL(req
->vwv
+7, 0);
1058 enum remote_arch_types ra_type
= get_remote_arch();
1059 int vuid
= req
->vuid
;
1060 user_struct
*vuser
= NULL
;
1061 NTSTATUS status
= NT_STATUS_OK
;
1062 uint16 smbpid
= req
->smbpid
;
1063 struct smbd_server_connection
*sconn
= req
->sconn
;
1065 DEBUG(3,("Doing spnego session setup\n"));
1067 if (global_client_caps
== 0) {
1068 global_client_caps
= IVAL(req
->vwv
+10, 0);
1070 if (!(global_client_caps
& CAP_STATUS32
)) {
1071 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
1078 if (data_blob_len
== 0) {
1079 /* an invalid request */
1080 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
1084 bufrem
= smbreq_bufrem(req
, p
);
1085 /* pull the spnego blob */
1086 blob1
= data_blob(p
, MIN(bufrem
, data_blob_len
));
1089 file_save("negotiate.dat", blob1
.data
, blob1
.length
);
1092 p2
= (char *)req
->buf
+ blob1
.length
;
1094 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
1096 native_os
= tmp
? tmp
: "";
1098 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
1100 native_lanman
= tmp
? tmp
: "";
1102 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
1104 primary_domain
= tmp
? tmp
: "";
1106 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1107 native_os
, native_lanman
, primary_domain
));
1109 if ( ra_type
== RA_WIN2K
) {
1110 /* Vista sets neither the OS or lanman strings */
1112 if ( !strlen(native_os
) && !strlen(native_lanman
) )
1113 set_remote_arch(RA_VISTA
);
1115 /* Windows 2003 doesn't set the native lanman string,
1116 but does set primary domain which is a bug I think */
1118 if ( !strlen(native_lanman
) ) {
1119 ra_lanman_string( primary_domain
);
1121 ra_lanman_string( native_lanman
);
1123 } else if ( ra_type
== RA_VISTA
) {
1124 if ( strncmp(native_os
, "Mac OS X", 8) == 0 ) {
1125 set_remote_arch(RA_OSX
);
1129 /* Did we get a valid vuid ? */
1130 if (!is_partial_auth_vuid(sconn
, vuid
)) {
1131 /* No, then try and see if this is an intermediate sessionsetup
1132 * for a large SPNEGO packet. */
1133 struct pending_auth_data
*pad
;
1134 pad
= get_pending_auth_data(sconn
, smbpid
);
1136 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1137 "pending vuid %u\n",
1138 (unsigned int)pad
->vuid
));
1143 /* Do we have a valid vuid now ? */
1144 if (!is_partial_auth_vuid(sconn
, vuid
)) {
1145 /* No, start a new authentication setup. */
1146 vuid
= register_initial_vuid(sconn
);
1147 if (vuid
== UID_FIELD_INVALID
) {
1148 data_blob_free(&blob1
);
1149 reply_nterror(req
, nt_status_squash(
1150 NT_STATUS_INVALID_PARAMETER
));
1155 vuser
= get_partial_auth_user_struct(sconn
, vuid
);
1156 /* This MUST be valid. */
1158 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1161 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1162 * sessionsetup requests as the Windows limit on the security blob
1163 * field is 4k. Bug #4400. JRA.
1166 status
= check_spnego_blob_complete(sconn
, smbpid
, vuid
, &blob1
);
1167 if (!NT_STATUS_IS_OK(status
)) {
1168 if (!NT_STATUS_EQUAL(status
,
1169 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1170 /* Real error - kill the intermediate vuid */
1171 invalidate_vuid(sconn
, vuid
);
1173 data_blob_free(&blob1
);
1174 reply_nterror(req
, nt_status_squash(status
));
1178 if (blob1
.data
[0] == ASN1_APPLICATION(0)) {
1180 /* its a negTokenTarg packet */
1182 reply_spnego_negotiate(req
, vuid
, blob1
,
1183 &vuser
->auth_ntlmssp_state
);
1184 data_blob_free(&blob1
);
1188 if (blob1
.data
[0] == ASN1_CONTEXT(1)) {
1190 /* its a auth packet */
1192 reply_spnego_auth(req
, vuid
, blob1
,
1193 &vuser
->auth_ntlmssp_state
);
1194 data_blob_free(&blob1
);
1198 if (strncmp((char *)(blob1
.data
), "NTLMSSP", 7) == 0) {
1201 if (!vuser
->auth_ntlmssp_state
) {
1202 status
= auth_ntlmssp_start(&vuser
->auth_ntlmssp_state
);
1203 if (!NT_STATUS_IS_OK(status
)) {
1204 /* Kill the intermediate vuid */
1205 invalidate_vuid(sconn
, vuid
);
1206 data_blob_free(&blob1
);
1207 reply_nterror(req
, nt_status_squash(status
));
1212 status
= auth_ntlmssp_update(vuser
->auth_ntlmssp_state
,
1215 data_blob_free(&blob1
);
1217 reply_spnego_ntlmssp(req
, vuid
,
1218 &vuser
->auth_ntlmssp_state
,
1219 &chal
, status
, OID_NTLMSSP
, false);
1220 data_blob_free(&chal
);
1224 /* what sort of packet is this? */
1225 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1227 data_blob_free(&blob1
);
1229 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
1232 /****************************************************************************
1233 On new VC == 0, shutdown *all* old connections and users.
1234 It seems that only NT4.x does this. At W2K and above (XP etc.).
1235 a new session setup with VC==0 is ignored.
1236 ****************************************************************************/
1238 struct shutdown_state
{
1240 struct messaging_context
*msg_ctx
;
1243 static int shutdown_other_smbds(const struct connections_key
*key
,
1244 const struct connections_data
*crec
,
1247 struct shutdown_state
*state
= (struct shutdown_state
*)private_data
;
1249 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
1250 procid_str(talloc_tos(), &crec
->pid
), crec
->addr
));
1252 if (!process_exists(crec
->pid
)) {
1253 DEBUG(10, ("process does not exist\n"));
1257 if (procid_is_me(&crec
->pid
)) {
1258 DEBUG(10, ("It's me\n"));
1262 if (strcmp(state
->ip
, crec
->addr
) != 0) {
1263 DEBUG(10, ("%s does not match %s\n", state
->ip
, crec
->addr
));
1267 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
1268 "(IP %s)\n", (unsigned int)procid_to_pid(&crec
->pid
),
1271 messaging_send(state
->msg_ctx
, crec
->pid
, MSG_SHUTDOWN
,
1276 static void setup_new_vc_session(struct smbd_server_connection
*sconn
)
1278 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1279 "compatible we would close all old resources.\n"));
1282 invalidate_all_vuids();
1284 if (lp_reset_on_zero_vc()) {
1286 struct shutdown_state state
;
1288 addr
= tsocket_address_inet_addr_string(
1289 sconn
->remote_address
, talloc_tos());
1294 state
.msg_ctx
= sconn
->msg_ctx
;
1295 connections_forall_read(shutdown_other_smbds
, &state
);
1300 /****************************************************************************
1301 Reply to a session setup command.
1302 ****************************************************************************/
1304 void reply_sesssetup_and_X(struct smb_request
*req
)
1310 DATA_BLOB plaintext_password
;
1313 fstring sub_user
; /* Sanitised username for substituion */
1315 const char *native_os
;
1316 const char *native_lanman
;
1317 const char *primary_domain
;
1318 struct auth_usersupplied_info
*user_info
= NULL
;
1319 struct auth_serversupplied_info
*server_info
= NULL
;
1320 uint16 smb_flag2
= req
->flags2
;
1323 struct smbd_server_connection
*sconn
= req
->sconn
;
1325 bool doencrypt
= sconn
->smb1
.negprot
.encrypted_passwords
;
1327 START_PROFILE(SMBsesssetupX
);
1329 ZERO_STRUCT(lm_resp
);
1330 ZERO_STRUCT(nt_resp
);
1331 ZERO_STRUCT(plaintext_password
);
1333 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
1335 /* a SPNEGO session setup has 12 command words, whereas a normal
1336 NT1 session setup has 13. See the cifs spec. */
1337 if (req
->wct
== 12 &&
1338 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
1340 if (!sconn
->smb1
.negprot
.spnego
) {
1341 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1342 "at SPNEGO session setup when it was not "
1344 reply_nterror(req
, nt_status_squash(
1345 NT_STATUS_LOGON_FAILURE
));
1346 END_PROFILE(SMBsesssetupX
);
1350 if (SVAL(req
->vwv
+4, 0) == 0) {
1351 setup_new_vc_session(req
->sconn
);
1354 reply_sesssetup_and_X_spnego(req
);
1355 END_PROFILE(SMBsesssetupX
);
1359 smb_bufsize
= SVAL(req
->vwv
+2, 0);
1361 if (get_Protocol() < PROTOCOL_NT1
) {
1362 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
1364 /* Never do NT status codes with protocols before NT1 as we
1365 * don't get client caps. */
1366 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
1368 if ((passlen1
> MAX_PASS_LEN
) || (passlen1
> req
->buflen
)) {
1369 reply_nterror(req
, nt_status_squash(
1370 NT_STATUS_INVALID_PARAMETER
));
1371 END_PROFILE(SMBsesssetupX
);
1376 lm_resp
= data_blob(req
->buf
, passlen1
);
1378 plaintext_password
= data_blob(req
->buf
, passlen1
+1);
1379 /* Ensure null termination */
1380 plaintext_password
.data
[passlen1
] = 0;
1383 srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
,
1384 req
->buf
+ passlen1
, STR_TERMINATE
);
1385 user
= tmp
? tmp
: "";
1390 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
1391 uint16 passlen2
= SVAL(req
->vwv
+8, 0);
1392 enum remote_arch_types ra_type
= get_remote_arch();
1393 const uint8_t *p
= req
->buf
;
1394 const uint8_t *save_p
= req
->buf
;
1398 if(global_client_caps
== 0) {
1399 global_client_caps
= IVAL(req
->vwv
+11, 0);
1401 if (!(global_client_caps
& CAP_STATUS32
)) {
1402 remove_from_common_flags2(
1403 FLAGS2_32_BIT_ERROR_CODES
);
1406 /* client_caps is used as final determination if
1407 * client is NT or Win95. This is needed to return
1408 * the correct error codes in some circumstances.
1411 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
1412 ra_type
== RA_WIN95
) {
1413 if(!(global_client_caps
& (CAP_NT_SMBS
|
1415 set_remote_arch( RA_WIN95
);
1421 /* both Win95 and WinNT stuff up the password
1422 * lengths for non-encrypting systems. Uggh.
1424 if passlen1==24 its a win95 system, and its setting
1425 the password length incorrectly. Luckily it still
1426 works with the default code because Win95 will null
1427 terminate the password anyway
1429 if passlen1>0 and passlen2>0 then maybe its a NT box
1430 and its setting passlen2 to some random value which
1431 really stuffs things up. we need to fix that one. */
1433 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
1439 /* check for nasty tricks */
1440 if (passlen1
> MAX_PASS_LEN
1441 || passlen1
> smbreq_bufrem(req
, p
)) {
1442 reply_nterror(req
, nt_status_squash(
1443 NT_STATUS_INVALID_PARAMETER
));
1444 END_PROFILE(SMBsesssetupX
);
1448 if (passlen2
> MAX_PASS_LEN
1449 || passlen2
> smbreq_bufrem(req
, p
+passlen1
)) {
1450 reply_nterror(req
, nt_status_squash(
1451 NT_STATUS_INVALID_PARAMETER
));
1452 END_PROFILE(SMBsesssetupX
);
1456 /* Save the lanman2 password and the NT md4 password. */
1458 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
1463 lm_resp
= data_blob(p
, passlen1
);
1464 nt_resp
= data_blob(p
+passlen1
, passlen2
);
1465 } else if (lp_security() != SEC_SHARE
) {
1467 * In share level we should ignore any passwords, so
1468 * only read them if we're not.
1471 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
1473 if (unic
&& (passlen2
== 0) && passlen1
) {
1474 /* Only a ascii plaintext password was sent. */
1475 (void)srvstr_pull_talloc(talloc_tos(),
1481 STR_TERMINATE
|STR_ASCII
);
1483 (void)srvstr_pull_talloc(talloc_tos(),
1488 unic
? passlen2
: passlen1
,
1492 reply_nterror(req
, nt_status_squash(
1493 NT_STATUS_INVALID_PARAMETER
));
1494 END_PROFILE(SMBsesssetupX
);
1497 plaintext_password
= data_blob(pass
, strlen(pass
)+1);
1500 p
+= passlen1
+ passlen2
;
1502 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
1504 user
= tmp
? tmp
: "";
1506 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
1508 domain
= tmp
? tmp
: "";
1510 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
1512 native_os
= tmp
? tmp
: "";
1514 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
1516 native_lanman
= tmp
? tmp
: "";
1518 /* not documented or decoded by Ethereal but there is one more
1519 * string in the extra bytes which is the same as the
1520 * PrimaryDomain when using extended security. Windows NT 4
1521 * and 2003 use this string to store the native lanman string.
1522 * Windows 9x does not include a string here at all so we have
1523 * to check if we have any extra bytes left */
1525 byte_count
= SVAL(req
->vwv
+13, 0);
1526 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
1527 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
1529 primary_domain
= tmp
? tmp
: "";
1531 primary_domain
= talloc_strdup(talloc_tos(), "null");
1534 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1535 "PrimaryDomain=[%s]\n",
1536 domain
, native_os
, native_lanman
, primary_domain
));
1538 if ( ra_type
== RA_WIN2K
) {
1539 if ( strlen(native_lanman
) == 0 )
1540 ra_lanman_string( primary_domain
);
1542 ra_lanman_string( native_lanman
);
1547 if (SVAL(req
->vwv
+4, 0) == 0) {
1548 setup_new_vc_session(req
->sconn
);
1551 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1552 domain
, user
, get_remote_machine_name()));
1555 if (sconn
->smb1
.negprot
.spnego
) {
1557 /* This has to be here, because this is a perfectly
1558 * valid behaviour for guest logons :-( */
1560 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1561 "at 'normal' session setup after "
1562 "negotiating spnego.\n"));
1563 reply_nterror(req
, nt_status_squash(
1564 NT_STATUS_LOGON_FAILURE
));
1565 END_PROFILE(SMBsesssetupX
);
1568 fstrcpy(sub_user
, user
);
1570 fstrcpy(sub_user
, lp_guestaccount());
1573 sub_set_smb_name(sub_user
);
1575 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
1577 if (lp_security() == SEC_SHARE
) {
1578 char *sub_user_mapped
= NULL
;
1579 /* In share level we should ignore any passwords */
1581 data_blob_free(&lm_resp
);
1582 data_blob_free(&nt_resp
);
1583 data_blob_clear_free(&plaintext_password
);
1585 (void)map_username(talloc_tos(), sub_user
, &sub_user_mapped
);
1586 if (!sub_user_mapped
) {
1587 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1588 END_PROFILE(SMBsesssetupX
);
1591 fstrcpy(sub_user
, sub_user_mapped
);
1592 add_session_user(sconn
, sub_user
);
1593 add_session_workgroup(sconn
, domain
);
1594 /* Then force it to null for the benfit of the code below */
1600 nt_status
= check_guest_password(&server_info
);
1602 } else if (doencrypt
) {
1603 struct auth_context
*negprot_auth_context
= NULL
;
1604 negprot_auth_context
= sconn
->smb1
.negprot
.auth_context
;
1605 if (!negprot_auth_context
) {
1606 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1607 "session setup without negprot denied!\n"));
1608 reply_nterror(req
, nt_status_squash(
1609 NT_STATUS_LOGON_FAILURE
));
1610 END_PROFILE(SMBsesssetupX
);
1613 nt_status
= make_user_info_for_reply_enc(&user_info
, user
,
1616 if (NT_STATUS_IS_OK(nt_status
)) {
1617 nt_status
= negprot_auth_context
->check_ntlm_password(
1618 negprot_auth_context
,
1623 struct auth_context
*plaintext_auth_context
= NULL
;
1625 nt_status
= make_auth_context_subsystem(
1626 talloc_tos(), &plaintext_auth_context
);
1628 if (NT_STATUS_IS_OK(nt_status
)) {
1631 plaintext_auth_context
->get_ntlm_challenge(
1632 plaintext_auth_context
, chal
);
1634 if (!make_user_info_for_reply(&user_info
,
1636 plaintext_password
)) {
1637 nt_status
= NT_STATUS_NO_MEMORY
;
1640 if (NT_STATUS_IS_OK(nt_status
)) {
1641 nt_status
= plaintext_auth_context
->check_ntlm_password(
1642 plaintext_auth_context
,
1646 TALLOC_FREE(plaintext_auth_context
);
1651 free_user_info(&user_info
);
1653 if (!NT_STATUS_IS_OK(nt_status
)) {
1654 nt_status
= do_map_to_guest(nt_status
, &server_info
,
1658 if (!NT_STATUS_IS_OK(nt_status
)) {
1659 data_blob_free(&nt_resp
);
1660 data_blob_free(&lm_resp
);
1661 data_blob_clear_free(&plaintext_password
);
1662 reply_nterror(req
, nt_status_squash(nt_status
));
1663 END_PROFILE(SMBsesssetupX
);
1667 /* Ensure we can't possible take a code path leading to a
1670 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
1671 END_PROFILE(SMBsesssetupX
);
1675 if (!server_info
->security_token
) {
1676 nt_status
= create_local_token(server_info
);
1678 if (!NT_STATUS_IS_OK(nt_status
)) {
1679 DEBUG(10, ("create_local_token failed: %s\n",
1680 nt_errstr(nt_status
)));
1681 data_blob_free(&nt_resp
);
1682 data_blob_free(&lm_resp
);
1683 data_blob_clear_free(&plaintext_password
);
1684 reply_nterror(req
, nt_status_squash(nt_status
));
1685 END_PROFILE(SMBsesssetupX
);
1690 data_blob_clear_free(&plaintext_password
);
1692 /* it's ok - setup a reply */
1693 reply_outbuf(req
, 3, 0);
1694 if (get_Protocol() >= PROTOCOL_NT1
) {
1695 push_signature(&req
->outbuf
);
1696 /* perhaps grab OS version here?? */
1699 if (server_info
->guest
) {
1700 SSVAL(req
->outbuf
,smb_vwv2
,1);
1703 /* register the name and uid as being validated, so further connections
1704 to a uid can get through without a password, on the same VC */
1706 if (lp_security() == SEC_SHARE
) {
1707 sess_vuid
= UID_FIELD_INVALID
;
1708 TALLOC_FREE(server_info
);
1710 /* Ignore the initial vuid. */
1711 sess_vuid
= register_initial_vuid(sconn
);
1712 if (sess_vuid
== UID_FIELD_INVALID
) {
1713 data_blob_free(&nt_resp
);
1714 data_blob_free(&lm_resp
);
1715 reply_nterror(req
, nt_status_squash(
1716 NT_STATUS_LOGON_FAILURE
));
1717 END_PROFILE(SMBsesssetupX
);
1720 /* register_existing_vuid keeps the server info */
1721 sess_vuid
= register_existing_vuid(sconn
, sess_vuid
,
1723 nt_resp
.data
? nt_resp
: lm_resp
,
1725 if (sess_vuid
== UID_FIELD_INVALID
) {
1726 data_blob_free(&nt_resp
);
1727 data_blob_free(&lm_resp
);
1728 reply_nterror(req
, nt_status_squash(
1729 NT_STATUS_LOGON_FAILURE
));
1730 END_PROFILE(SMBsesssetupX
);
1734 /* current_user_info is changed on new vuid */
1735 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
1738 data_blob_free(&nt_resp
);
1739 data_blob_free(&lm_resp
);
1741 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
1742 SSVAL(req
->inbuf
,smb_uid
,sess_vuid
);
1743 req
->vuid
= sess_vuid
;
1745 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
1746 sconn
->smb1
.sessions
.max_send
=
1747 MIN(sconn
->smb1
.sessions
.max_send
,smb_bufsize
);
1749 sconn
->smb1
.sessions
.done_sesssetup
= true;
1751 END_PROFILE(SMBsesssetupX
);