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/>.
27 extern struct auth_context
*negprot_global_auth_context
;
28 extern bool global_encrypted_passwords_negotiated
;
29 extern bool global_spnego_negotiated
;
30 extern enum protocol_types Protocol
;
33 uint32 global_client_caps
= 0;
36 on a logon error possibly map the error to success if "map to guest"
39 static NTSTATUS
do_map_to_guest(NTSTATUS status
,
40 auth_serversupplied_info
**server_info
,
41 const char *user
, const char *domain
)
43 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
44 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER
) ||
45 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
)) {
46 DEBUG(3,("No such user %s [%s] - using guest account\n",
48 status
= make_server_info_guest(server_info
);
52 if (NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
53 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
) {
54 DEBUG(3,("Registered username %s for guest access\n",
56 status
= make_server_info_guest(server_info
);
63 /****************************************************************************
64 Add the standard 'Samba' signature to the end of the session setup.
65 ****************************************************************************/
67 static int push_signature(uint8
**outbuf
)
74 tmp
= message_push_string(outbuf
, "Unix", STR_TERMINATE
);
76 if (tmp
== -1) return -1;
79 if (asprintf(&lanman
, "Samba %s", SAMBA_VERSION_STRING
) != -1) {
80 tmp
= message_push_string(outbuf
, lanman
, STR_TERMINATE
);
84 tmp
= message_push_string(outbuf
, "Samba", STR_TERMINATE
);
87 if (tmp
== -1) return -1;
90 tmp
= message_push_string(outbuf
, lp_workgroup(), STR_TERMINATE
);
92 if (tmp
== -1) return -1;
98 /****************************************************************************
99 Start the signing engine if needed. Don't fail signing here.
100 ****************************************************************************/
102 static void sessionsetup_start_signing_engine(
103 const auth_serversupplied_info
*server_info
,
106 if (!server_info
->guest
&& !srv_signing_started()) {
107 /* We need to start the signing engine
108 * here but a W2K client sends the old
109 * "BSRSPYL " signature instead of the
110 * correct one. Subsequent packets will
113 srv_check_sign_mac((char *)inbuf
, False
);
117 /****************************************************************************
118 Send a security blob via a session setup reply.
119 ****************************************************************************/
121 static void reply_sesssetup_blob(connection_struct
*conn
,
122 struct smb_request
*req
,
126 if (!NT_STATUS_IS_OK(nt_status
) &&
127 !NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
128 reply_nterror(req
, nt_status_squash(nt_status
));
130 nt_status
= nt_status_squash(nt_status
);
131 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(nt_status
));
132 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
133 SSVAL(req
->outbuf
, smb_vwv3
, blob
.length
);
135 if ((message_push_blob(&req
->outbuf
, blob
) == -1)
136 || (push_signature(&req
->outbuf
) == -1)) {
137 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
141 show_msg((char *)req
->outbuf
);
142 send_smb(smbd_server_fd(),(char *)req
->outbuf
);
143 TALLOC_FREE(req
->outbuf
);
146 /****************************************************************************
147 Do a 'guest' logon, getting back the
148 ****************************************************************************/
150 static NTSTATUS
check_guest_password(auth_serversupplied_info
**server_info
)
152 struct auth_context
*auth_context
;
153 auth_usersupplied_info
*user_info
= NULL
;
156 unsigned char chal
[8];
160 DEBUG(3,("Got anonymous request\n"));
162 if (!NT_STATUS_IS_OK(nt_status
= make_auth_context_fixed(&auth_context
,
167 if (!make_user_info_guest(&user_info
)) {
168 (auth_context
->free
)(&auth_context
);
169 return NT_STATUS_NO_MEMORY
;
172 nt_status
= auth_context
->check_ntlm_password(auth_context
,
175 (auth_context
->free
)(&auth_context
);
176 free_user_info(&user_info
);
184 /* Experiment that failed. See "only happens with a KDC" comment below. */
185 /****************************************************************************
186 Cerate a clock skew error blob for a Windows client.
187 ****************************************************************************/
189 static bool make_krb5_skew_error(DATA_BLOB
*pblob_out
)
191 krb5_context context
= NULL
;
192 krb5_error_code kerr
= 0;
194 krb5_principal host_princ
= NULL
;
195 char *host_princ_s
= NULL
;
198 *pblob_out
= data_blob_null
;
200 initialize_krb5_error_table();
201 kerr
= krb5_init_context(&context
);
205 /* Create server principal. */
206 asprintf(&host_princ_s
, "%s$@%s", global_myname(), lp_realm());
210 strlower_m(host_princ_s
);
212 kerr
= smb_krb5_parse_name(context
, host_princ_s
, &host_princ
);
214 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
215 "for name %s: Error %s\n",
216 host_princ_s
, error_message(kerr
) ));
220 kerr
= smb_krb5_mk_error(context
, KRB5KRB_AP_ERR_SKEW
,
223 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
224 "failed: Error %s\n",
225 error_message(kerr
) ));
229 *pblob_out
= data_blob(reply
.data
, reply
.length
);
230 kerberos_free_data_contents(context
,&reply
);
236 SAFE_FREE(host_princ_s
);
239 krb5_free_principal(context
, host_princ
);
241 krb5_free_context(context
);
246 /****************************************************************************
247 Reply to a session setup spnego negotiate packet for kerberos.
248 ****************************************************************************/
250 static void reply_spnego_kerberos(connection_struct
*conn
,
251 struct smb_request
*req
,
254 bool *p_invalidate_vuid
)
258 char *client
, *p
, *domain
;
259 fstring netbios_domain_name
;
262 int sess_vuid
= req
->vuid
;
263 NTSTATUS ret
= NT_STATUS_OK
;
265 DATA_BLOB ap_rep
, ap_rep_wrapped
, response
;
266 auth_serversupplied_info
*server_info
= NULL
;
267 DATA_BLOB session_key
= data_blob_null
;
269 DATA_BLOB nullblob
= data_blob_null
;
270 fstring real_username
;
271 bool map_domainuser_to_guest
= False
;
272 bool username_was_mapped
;
273 PAC_LOGON_INFO
*logon_info
= NULL
;
276 ZERO_STRUCT(pac_data
);
278 ZERO_STRUCT(ap_rep_wrapped
);
279 ZERO_STRUCT(response
);
281 /* Normally we will always invalidate the intermediate vuid. */
282 *p_invalidate_vuid
= True
;
284 mem_ctx
= talloc_init("reply_spnego_kerberos");
285 if (mem_ctx
== NULL
) {
286 reply_nterror(req
, nt_status_squash(NT_STATUS_NO_MEMORY
));
290 if (!spnego_parse_krb5_wrap(*secblob
, &ticket
, tok_id
)) {
291 talloc_destroy(mem_ctx
);
292 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
296 ret
= ads_verify_ticket(mem_ctx
, lp_realm(), 0, &ticket
,
297 &client
, &pac_data
, &ap_rep
,
300 data_blob_free(&ticket
);
302 if (!NT_STATUS_IS_OK(ret
)) {
304 /* Experiment that failed.
305 * See "only happens with a KDC" comment below. */
307 if (NT_STATUS_EQUAL(ret
, NT_STATUS_TIME_DIFFERENCE_AT_DC
)) {
310 * Windows in this case returns
311 * NT_STATUS_MORE_PROCESSING_REQUIRED
312 * with a negTokenTarg blob containing an krb5_error
313 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
314 * The client then fixes its clock and continues rather
315 * than giving an error. JRA.
316 * -- Looks like this only happens with a KDC. JRA.
319 bool ok
= make_krb5_skew_error(&ap_rep
);
321 talloc_destroy(mem_ctx
);
322 return ERROR_NT(nt_status_squash(
323 NT_STATUS_LOGON_FAILURE
));
325 ap_rep_wrapped
= spnego_gen_krb5_wrap(ap_rep
,
327 response
= spnego_gen_auth_response(&ap_rep_wrapped
,
328 ret
, OID_KERBEROS5_OLD
);
329 reply_sesssetup_blob(conn
, inbuf
, outbuf
, response
,
330 NT_STATUS_MORE_PROCESSING_REQUIRED
);
333 * In this one case we don't invalidate the
334 * intermediate vuid as we're expecting the client
335 * to re-use it for the next sessionsetupX packet. JRA.
338 *p_invalidate_vuid
= False
;
340 data_blob_free(&ap_rep
);
341 data_blob_free(&ap_rep_wrapped
);
342 data_blob_free(&response
);
343 talloc_destroy(mem_ctx
);
344 return -1; /* already replied */
347 if (!NT_STATUS_EQUAL(ret
, NT_STATUS_TIME_DIFFERENCE_AT_DC
)) {
348 ret
= NT_STATUS_LOGON_FAILURE
;
351 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
353 talloc_destroy(mem_ctx
);
354 reply_nterror(req
, nt_status_squash(ret
));
358 DEBUG(3,("Ticket name is [%s]\n", client
));
360 p
= strchr_m(client
, '@');
362 DEBUG(3,("Doesn't look like a valid principal\n"));
363 data_blob_free(&ap_rep
);
364 data_blob_free(&session_key
);
366 talloc_destroy(mem_ctx
);
367 reply_nterror(req
,nt_status_squash(NT_STATUS_LOGON_FAILURE
));
373 /* save the PAC data if we have it */
376 logon_info
= get_logon_info_from_pac(pac_data
);
378 netsamlogon_cache_store( client
, &logon_info
->info3
);
382 if (!strequal(p
+1, lp_realm())) {
383 DEBUG(3,("Ticket for foreign realm %s@%s\n", client
, p
+1));
384 if (!lp_allow_trusted_domains()) {
385 data_blob_free(&ap_rep
);
386 data_blob_free(&session_key
);
388 talloc_destroy(mem_ctx
);
389 reply_nterror(req
, nt_status_squash(
390 NT_STATUS_LOGON_FAILURE
));
395 /* this gives a fully qualified user name (ie. with full realm).
396 that leads to very long usernames, but what else can we do? */
400 if (logon_info
&& logon_info
->info3
.hdr_logon_dom
.uni_str_len
) {
401 unistr2_to_ascii(netbios_domain_name
,
402 &logon_info
->info3
.uni_logon_dom
,
403 sizeof(netbios_domain_name
));
404 domain
= netbios_domain_name
;
405 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain
));
409 /* If we have winbind running, we can (and must) shorten the
410 username by using the short netbios name. Otherwise we will
411 have inconsistent user names. With Kerberos, we get the
412 fully qualified realm, with ntlmssp we get the short
413 name. And even w2k3 does use ntlmssp if you for example
414 connect to an ip address. */
416 struct winbindd_request wb_request
;
417 struct winbindd_response wb_response
;
418 NSS_STATUS wb_result
;
420 ZERO_STRUCT(wb_request
);
421 ZERO_STRUCT(wb_response
);
423 DEBUG(10, ("Mapping [%s] to short name\n", domain
));
425 fstrcpy(wb_request
.domain_name
, domain
);
427 wb_result
= winbindd_request_response(WINBINDD_DOMAIN_INFO
,
428 &wb_request
, &wb_response
);
430 if (wb_result
== NSS_STATUS_SUCCESS
) {
432 fstrcpy(netbios_domain_name
,
433 wb_response
.data
.domain_info
.name
);
434 domain
= netbios_domain_name
;
436 DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain
));
438 DEBUG(3, ("Could not find short name -- winbind "
443 fstr_sprintf(user
, "%s%c%s", domain
, *lp_winbind_separator(), client
);
445 /* lookup the passwd struct, create a new user if necessary */
447 username_was_mapped
= map_username( user
);
449 pw
= smb_getpwnam( mem_ctx
, user
, real_username
, True
);
452 /* if a real user check pam account restrictions */
453 /* only really perfomed if "obey pam restriction" is true */
454 /* do this before an eventual mappign to guest occurs */
455 ret
= smb_pam_accountcheck(pw
->pw_name
);
456 if ( !NT_STATUS_IS_OK(ret
)) {
457 DEBUG(1,("PAM account restriction "
458 "prevents user login\n"));
459 data_blob_free(&ap_rep
);
460 data_blob_free(&session_key
);
461 TALLOC_FREE(mem_ctx
);
462 reply_nterror(req
, nt_status_squash(ret
));
469 /* this was originally the behavior of Samba 2.2, if a user
470 did not have a local uid but has been authenticated, then
471 map them to a guest account */
473 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID
){
474 map_domainuser_to_guest
= True
;
475 fstrcpy(user
,lp_guestaccount());
476 pw
= smb_getpwnam( mem_ctx
, user
, real_username
, True
);
479 /* extra sanity check that the guest account is valid */
482 DEBUG(1,("Username %s is invalid on this system\n",
485 data_blob_free(&ap_rep
);
486 data_blob_free(&session_key
);
487 TALLOC_FREE(mem_ctx
);
488 reply_nterror(req
, nt_status_squash(
489 NT_STATUS_LOGON_FAILURE
));
494 /* setup the string used by %U */
496 sub_set_smb_name( real_username
);
497 reload_services(True
);
499 if ( map_domainuser_to_guest
) {
500 make_server_info_guest(&server_info
);
501 } else if (logon_info
) {
502 /* pass the unmapped username here since map_username()
503 will be called again from inside make_server_info_info3() */
505 ret
= make_server_info_info3(mem_ctx
, client
, domain
,
506 &server_info
, &logon_info
->info3
);
507 if ( !NT_STATUS_IS_OK(ret
) ) {
508 DEBUG(1,("make_server_info_info3 failed: %s!\n",
511 data_blob_free(&ap_rep
);
512 data_blob_free(&session_key
);
513 TALLOC_FREE(mem_ctx
);
514 reply_nterror(req
, nt_status_squash(ret
));
519 ret
= make_server_info_pw(&server_info
, real_username
, pw
);
521 if ( !NT_STATUS_IS_OK(ret
) ) {
522 DEBUG(1,("make_server_info_pw failed: %s!\n",
525 data_blob_free(&ap_rep
);
526 data_blob_free(&session_key
);
527 TALLOC_FREE(mem_ctx
);
528 reply_nterror(req
, nt_status_squash(ret
));
532 /* make_server_info_pw does not set the domain. Without this
533 * we end up with the local netbios name in substitutions for
536 if (server_info
->sam_account
!= NULL
) {
537 pdb_set_domain(server_info
->sam_account
,
542 server_info
->was_mapped
|= username_was_mapped
;
544 /* we need to build the token for the user. make_server_info_guest()
547 if ( !server_info
->ptok
) {
548 ret
= create_local_token( server_info
);
549 if ( !NT_STATUS_IS_OK(ret
) ) {
551 data_blob_free(&ap_rep
);
552 data_blob_free(&session_key
);
553 TALLOC_FREE( mem_ctx
);
554 TALLOC_FREE( server_info
);
555 reply_nterror(req
, nt_status_squash(ret
));
560 /* register_existing_vuid keeps the server info */
561 /* register_existing_vuid takes ownership of session_key on success,
562 * no need to free after this on success. A better interface would copy
565 if (!is_partial_auth_vuid(sess_vuid
)) {
566 sess_vuid
= register_initial_vuid();
568 sess_vuid
= register_existing_vuid(sess_vuid
,
576 reply_outbuf(req
, 4, 0);
577 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
579 if (sess_vuid
== UID_FIELD_INVALID
) {
580 ret
= NT_STATUS_LOGON_FAILURE
;
581 data_blob_free(&session_key
);
583 /* current_user_info is changed on new vuid */
584 reload_services( True
);
586 SSVAL(req
->outbuf
, smb_vwv3
, 0);
588 if (server_info
->guest
) {
589 SSVAL(req
->outbuf
,smb_vwv2
,1);
592 SSVAL(req
->outbuf
, smb_uid
, sess_vuid
);
594 sessionsetup_start_signing_engine(server_info
, req
->inbuf
);
595 /* Successful logon. Keep this vuid. */
596 *p_invalidate_vuid
= False
;
599 /* wrap that up in a nice GSS-API wrapping */
600 if (NT_STATUS_IS_OK(ret
)) {
601 ap_rep_wrapped
= spnego_gen_krb5_wrap(ap_rep
,
604 ap_rep_wrapped
= data_blob_null
;
606 response
= spnego_gen_auth_response(&ap_rep_wrapped
, ret
,
608 reply_sesssetup_blob(conn
, req
, response
, ret
);
610 data_blob_free(&ap_rep
);
611 data_blob_free(&ap_rep_wrapped
);
612 data_blob_free(&response
);
613 TALLOC_FREE(mem_ctx
);
618 /****************************************************************************
619 Send a session setup reply, wrapped in SPNEGO.
620 Get vuid and check first.
621 End the NTLMSSP exchange context if we are OK/complete fail
622 This should be split into two functions, one to handle each
623 leg of the NTLM auth steps.
624 ***************************************************************************/
626 static void reply_spnego_ntlmssp(connection_struct
*conn
,
627 struct smb_request
*req
,
629 AUTH_NTLMSSP_STATE
**auth_ntlmssp_state
,
630 DATA_BLOB
*ntlmssp_blob
, NTSTATUS nt_status
,
634 struct auth_serversupplied_info
*server_info
= NULL
;
636 if (NT_STATUS_IS_OK(nt_status
)) {
637 server_info
= (*auth_ntlmssp_state
)->server_info
;
639 nt_status
= do_map_to_guest(nt_status
,
641 (*auth_ntlmssp_state
)->ntlmssp_state
->user
,
642 (*auth_ntlmssp_state
)->ntlmssp_state
->domain
);
645 reply_outbuf(req
, 4, 0);
647 SSVAL(req
->outbuf
, smb_uid
, vuid
);
649 if (NT_STATUS_IS_OK(nt_status
)) {
650 DATA_BLOB nullblob
= data_blob_null
;
651 DATA_BLOB session_key
=
653 (*auth_ntlmssp_state
)->ntlmssp_state
->session_key
.data
,
654 (*auth_ntlmssp_state
)->ntlmssp_state
->session_key
.length
);
656 if (!is_partial_auth_vuid(vuid
)) {
657 data_blob_free(&session_key
);
658 nt_status
= NT_STATUS_LOGON_FAILURE
;
661 /* register_existing_vuid keeps the server info */
662 if (register_existing_vuid(vuid
,
664 session_key
, nullblob
,
665 (*auth_ntlmssp_state
)->ntlmssp_state
->user
) !=
667 data_blob_free(&session_key
);
668 nt_status
= NT_STATUS_LOGON_FAILURE
;
672 (*auth_ntlmssp_state
)->server_info
= NULL
;
674 /* current_user_info is changed on new vuid */
675 reload_services( True
);
677 SSVAL(req
->outbuf
, smb_vwv3
, 0);
679 if (server_info
->guest
) {
680 SSVAL(req
->outbuf
,smb_vwv2
,1);
683 sessionsetup_start_signing_engine(server_info
,
684 (uint8
*)req
->inbuf
);
690 response
= spnego_gen_auth_response(ntlmssp_blob
,
691 nt_status
, OID_NTLMSSP
);
693 response
= *ntlmssp_blob
;
696 reply_sesssetup_blob(conn
, req
, response
, nt_status
);
698 data_blob_free(&response
);
701 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
702 and the other end, that we are not finished yet. */
704 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
705 /* NB. This is *NOT* an error case. JRA */
706 auth_ntlmssp_end(auth_ntlmssp_state
);
707 if (!NT_STATUS_IS_OK(nt_status
)) {
708 /* Kill the intermediate vuid */
709 invalidate_vuid(vuid
);
714 /****************************************************************************
715 Is this a krb5 mechanism ?
716 ****************************************************************************/
718 NTSTATUS
parse_spnego_mechanisms(DATA_BLOB blob_in
, DATA_BLOB
*pblob_out
,
721 char *OIDs
[ASN1_MAX_OIDS
];
726 /* parse out the OIDs and the first sec blob */
727 if (!parse_negTokenTarg(blob_in
, OIDs
, pblob_out
)) {
728 return NT_STATUS_LOGON_FAILURE
;
731 /* only look at the first OID for determining the mechToken --
732 according to RFC2478, we should choose the one we want
733 and renegotiate, but i smell a client bug here..
735 Problem observed when connecting to a member (samba box)
736 of an AD domain as a user in a Samba domain. Samba member
737 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
738 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
739 NTLMSSP mechtoken. --jerry */
742 if (strcmp(OID_KERBEROS5
, OIDs
[0]) == 0 ||
743 strcmp(OID_KERBEROS5_OLD
, OIDs
[0]) == 0) {
748 for (i
=0;OIDs
[i
];i
++) {
749 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs
[i
]));
755 /****************************************************************************
756 Reply to a session setup spnego negotiate packet.
757 ****************************************************************************/
759 static void reply_spnego_negotiate(connection_struct
*conn
,
760 struct smb_request
*req
,
763 AUTH_NTLMSSP_STATE
**auth_ntlmssp_state
)
767 bool got_kerberos_mechanism
= False
;
770 status
= parse_spnego_mechanisms(blob1
, &secblob
,
771 &got_kerberos_mechanism
);
772 if (!NT_STATUS_IS_OK(status
)) {
773 /* Kill the intermediate vuid */
774 invalidate_vuid(vuid
);
775 reply_nterror(req
, nt_status_squash(status
));
779 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
780 (unsigned long)secblob
.length
));
783 if ( got_kerberos_mechanism
&& ((lp_security()==SEC_ADS
) ||
784 lp_use_kerberos_keytab()) ) {
785 bool destroy_vuid
= True
;
786 reply_spnego_kerberos(conn
, req
, &secblob
, vuid
,
788 data_blob_free(&secblob
);
790 /* Kill the intermediate vuid */
791 invalidate_vuid(vuid
);
797 if (*auth_ntlmssp_state
) {
798 auth_ntlmssp_end(auth_ntlmssp_state
);
801 status
= auth_ntlmssp_start(auth_ntlmssp_state
);
802 if (!NT_STATUS_IS_OK(status
)) {
803 /* Kill the intermediate vuid */
804 invalidate_vuid(vuid
);
805 reply_nterror(req
, nt_status_squash(status
));
809 status
= auth_ntlmssp_update(*auth_ntlmssp_state
,
812 data_blob_free(&secblob
);
814 reply_spnego_ntlmssp(conn
, req
, vuid
, auth_ntlmssp_state
,
815 &chal
, status
, True
);
817 data_blob_free(&chal
);
819 /* already replied */
823 /****************************************************************************
824 Reply to a session setup spnego auth packet.
825 ****************************************************************************/
827 static void reply_spnego_auth(connection_struct
*conn
,
828 struct smb_request
*req
,
831 AUTH_NTLMSSP_STATE
**auth_ntlmssp_state
)
833 DATA_BLOB auth
= data_blob_null
;
834 DATA_BLOB auth_reply
= data_blob_null
;
835 DATA_BLOB secblob
= data_blob_null
;
836 NTSTATUS status
= NT_STATUS_INVALID_PARAMETER
;
838 if (!spnego_parse_auth(blob1
, &auth
)) {
840 file_save("auth.dat", blob1
.data
, blob1
.length
);
842 /* Kill the intermediate vuid */
843 invalidate_vuid(vuid
);
845 reply_nterror(req
, nt_status_squash(
846 NT_STATUS_INVALID_PARAMETER
));
850 if (auth
.data
[0] == ASN1_APPLICATION(0)) {
851 /* Might be a second negTokenTarg packet */
853 bool got_krb5_mechanism
= False
;
854 status
= parse_spnego_mechanisms(auth
, &secblob
,
855 &got_krb5_mechanism
);
856 if (NT_STATUS_IS_OK(status
)) {
857 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
858 (unsigned long)secblob
.length
));
860 if ( got_krb5_mechanism
&& ((lp_security()==SEC_ADS
) ||
861 lp_use_kerberos_keytab()) ) {
862 bool destroy_vuid
= True
;
863 reply_spnego_kerberos(conn
, req
, &secblob
,
864 vuid
, &destroy_vuid
);
865 data_blob_free(&secblob
);
866 data_blob_free(&auth
);
868 /* Kill the intermediate vuid */
869 invalidate_vuid(vuid
);
877 /* If we get here it wasn't a negTokenTarg auth packet. */
878 data_blob_free(&secblob
);
880 if (!*auth_ntlmssp_state
) {
881 /* Kill the intermediate vuid */
882 invalidate_vuid(vuid
);
884 /* auth before negotiatiate? */
885 reply_nterror(req
, nt_status_squash(
886 NT_STATUS_INVALID_PARAMETER
));
890 status
= auth_ntlmssp_update(*auth_ntlmssp_state
,
893 data_blob_free(&auth
);
895 reply_spnego_ntlmssp(conn
, req
, vuid
,
897 &auth_reply
, status
, True
);
899 data_blob_free(&auth_reply
);
901 /* and tell smbd that we have already replied to this packet */
905 /****************************************************************************
906 List to store partial SPNEGO auth fragments.
907 ****************************************************************************/
909 static struct pending_auth_data
*pd_list
;
911 /****************************************************************************
912 Delete an entry on the list.
913 ****************************************************************************/
915 static void delete_partial_auth(struct pending_auth_data
*pad
)
920 DLIST_REMOVE(pd_list
, pad
);
921 data_blob_free(&pad
->partial_data
);
925 /****************************************************************************
926 Search for a partial SPNEGO auth fragment matching an smbpid.
927 ****************************************************************************/
929 static struct pending_auth_data
*get_pending_auth_data(uint16 smbpid
)
931 struct pending_auth_data
*pad
;
933 for (pad
= pd_list
; pad
; pad
= pad
->next
) {
934 if (pad
->smbpid
== smbpid
) {
941 /****************************************************************************
942 Check the size of an SPNEGO blob. If we need more return
943 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
944 the blob to be more than 64k.
945 ****************************************************************************/
947 static NTSTATUS
check_spnego_blob_complete(uint16 smbpid
, uint16 vuid
,
950 struct pending_auth_data
*pad
= NULL
;
952 size_t needed_len
= 0;
954 pad
= get_pending_auth_data(smbpid
);
956 /* Ensure we have some data. */
957 if (pblob
->length
== 0) {
958 /* Caller can cope. */
959 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
960 delete_partial_auth(pad
);
964 /* Were we waiting for more data ? */
967 size_t copy_len
= MIN(65536, pblob
->length
);
969 /* Integer wrap paranoia.... */
971 if (pad
->partial_data
.length
+ copy_len
<
972 pad
->partial_data
.length
||
973 pad
->partial_data
.length
+ copy_len
< copy_len
) {
975 DEBUG(2,("check_spnego_blob_complete: integer wrap "
976 "pad->partial_data.length = %u, "
978 (unsigned int)pad
->partial_data
.length
,
979 (unsigned int)copy_len
));
981 delete_partial_auth(pad
);
982 return NT_STATUS_INVALID_PARAMETER
;
985 DEBUG(10,("check_spnego_blob_complete: "
986 "pad->partial_data.length = %u, "
987 "pad->needed_len = %u, "
989 "pblob->length = %u,\n",
990 (unsigned int)pad
->partial_data
.length
,
991 (unsigned int)pad
->needed_len
,
992 (unsigned int)copy_len
,
993 (unsigned int)pblob
->length
));
995 tmp_blob
= data_blob(NULL
,
996 pad
->partial_data
.length
+ copy_len
);
998 /* Concatenate the two (up to copy_len) bytes. */
999 memcpy(tmp_blob
.data
,
1000 pad
->partial_data
.data
,
1001 pad
->partial_data
.length
);
1002 memcpy(tmp_blob
.data
+ pad
->partial_data
.length
,
1006 /* Replace the partial data. */
1007 data_blob_free(&pad
->partial_data
);
1008 pad
->partial_data
= tmp_blob
;
1009 ZERO_STRUCT(tmp_blob
);
1012 if (pblob
->length
>= pad
->needed_len
) {
1013 /* Yes, replace pblob. */
1014 data_blob_free(pblob
);
1015 *pblob
= pad
->partial_data
;
1016 ZERO_STRUCT(pad
->partial_data
);
1017 delete_partial_auth(pad
);
1018 return NT_STATUS_OK
;
1021 /* Still need more data. */
1022 pad
->needed_len
-= copy_len
;
1023 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
1026 if ((pblob
->data
[0] != ASN1_APPLICATION(0)) &&
1027 (pblob
->data
[0] != ASN1_CONTEXT(1))) {
1028 /* Not something we can determine the
1031 return NT_STATUS_OK
;
1034 /* This is a new SPNEGO sessionsetup - see if
1035 * the data given in this blob is enough.
1038 asn1_load(&data
, *pblob
);
1039 asn1_start_tag(&data
, pblob
->data
[0]);
1040 if (data
.has_error
|| data
.nesting
== NULL
) {
1042 /* Let caller catch. */
1043 return NT_STATUS_OK
;
1046 /* Integer wrap paranoia.... */
1048 if (data
.nesting
->taglen
+ data
.nesting
->start
< data
.nesting
->taglen
||
1049 data
.nesting
->taglen
+ data
.nesting
->start
< data
.nesting
->start
) {
1051 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1052 "data.nesting->taglen = %u, "
1053 "data.nesting->start = %u\n",
1054 (unsigned int)data
.nesting
->taglen
,
1055 (unsigned int)data
.nesting
->start
));
1058 return NT_STATUS_INVALID_PARAMETER
;
1061 /* Total length of the needed asn1 is the tag length
1062 * plus the current offset. */
1064 needed_len
= data
.nesting
->taglen
+ data
.nesting
->start
;
1067 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
1068 "pblob->length = %u\n",
1069 (unsigned int)needed_len
,
1070 (unsigned int)pblob
->length
));
1072 if (needed_len
<= pblob
->length
) {
1073 /* Nothing to do - blob is complete. */
1074 return NT_STATUS_OK
;
1077 /* Refuse the blob if it's bigger than 64k. */
1078 if (needed_len
> 65536) {
1079 DEBUG(2,("check_spnego_blob_complete: needed_len "
1081 (unsigned int)needed_len
));
1082 return NT_STATUS_INVALID_PARAMETER
;
1085 /* We must store this blob until complete. */
1086 if (!(pad
= SMB_MALLOC_P(struct pending_auth_data
))) {
1087 return NT_STATUS_NO_MEMORY
;
1089 pad
->needed_len
= needed_len
- pblob
->length
;
1090 pad
->partial_data
= data_blob(pblob
->data
, pblob
->length
);
1091 if (pad
->partial_data
.data
== NULL
) {
1093 return NT_STATUS_NO_MEMORY
;
1095 pad
->smbpid
= smbpid
;
1097 DLIST_ADD(pd_list
, pad
);
1099 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
1102 /****************************************************************************
1103 Reply to a session setup command.
1104 conn POINTER CAN BE NULL HERE !
1105 ****************************************************************************/
1107 static void reply_sesssetup_and_X_spnego(connection_struct
*conn
,
1108 struct smb_request
*req
)
1113 fstring native_os
, native_lanman
, primary_domain
;
1115 uint16 data_blob_len
= SVAL(req
->inbuf
, smb_vwv7
);
1116 enum remote_arch_types ra_type
= get_remote_arch();
1117 int vuid
= SVAL(req
->inbuf
,smb_uid
);
1118 user_struct
*vuser
= NULL
;
1119 NTSTATUS status
= NT_STATUS_OK
;
1120 uint16 smbpid
= req
->smbpid
;
1121 uint16 smb_flag2
= req
->flags2
;
1123 DEBUG(3,("Doing spnego session setup\n"));
1125 if (global_client_caps
== 0) {
1126 global_client_caps
= IVAL(req
->inbuf
,smb_vwv10
);
1128 if (!(global_client_caps
& CAP_STATUS32
)) {
1129 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
1134 p
= (uint8
*)smb_buf(req
->inbuf
);
1136 if (data_blob_len
== 0) {
1137 /* an invalid request */
1138 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
1142 bufrem
= smb_bufrem(req
->inbuf
, p
);
1143 /* pull the spnego blob */
1144 blob1
= data_blob(p
, MIN(bufrem
, data_blob_len
));
1147 file_save("negotiate.dat", blob1
.data
, blob1
.length
);
1150 p2
= (char *)req
->inbuf
+ smb_vwv13
+ data_blob_len
;
1151 p2
+= srvstr_pull_buf(req
->inbuf
, smb_flag2
, native_os
, p2
,
1152 sizeof(native_os
), STR_TERMINATE
);
1153 p2
+= srvstr_pull_buf(req
->inbuf
, smb_flag2
, native_lanman
, p2
,
1154 sizeof(native_lanman
), STR_TERMINATE
);
1155 p2
+= srvstr_pull_buf(req
->inbuf
, smb_flag2
, primary_domain
, p2
,
1156 sizeof(primary_domain
), STR_TERMINATE
);
1157 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1158 native_os
, native_lanman
, primary_domain
));
1160 if ( ra_type
== RA_WIN2K
) {
1161 /* Vista sets neither the OS or lanman strings */
1163 if ( !strlen(native_os
) && !strlen(native_lanman
) )
1164 set_remote_arch(RA_VISTA
);
1166 /* Windows 2003 doesn't set the native lanman string,
1167 but does set primary domain which is a bug I think */
1169 if ( !strlen(native_lanman
) ) {
1170 ra_lanman_string( primary_domain
);
1172 ra_lanman_string( native_lanman
);
1176 /* Did we get a valid vuid ? */
1177 if (!is_partial_auth_vuid(vuid
)) {
1178 /* No, then try and see if this is an intermediate sessionsetup
1179 * for a large SPNEGO packet. */
1180 struct pending_auth_data
*pad
= get_pending_auth_data(smbpid
);
1182 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1183 "pending vuid %u\n",
1184 (unsigned int)pad
->vuid
));
1189 /* Do we have a valid vuid now ? */
1190 if (!is_partial_auth_vuid(vuid
)) {
1191 /* No, start a new authentication setup. */
1192 vuid
= register_initial_vuid();
1193 if (vuid
== UID_FIELD_INVALID
) {
1194 data_blob_free(&blob1
);
1195 reply_nterror(req
, nt_status_squash(
1196 NT_STATUS_INVALID_PARAMETER
));
1201 vuser
= get_partial_auth_user_struct(vuid
);
1202 /* This MUST be valid. */
1204 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1207 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1208 * sessionsetup requests as the Windows limit on the security blob
1209 * field is 4k. Bug #4400. JRA.
1212 status
= check_spnego_blob_complete(smbpid
, vuid
, &blob1
);
1213 if (!NT_STATUS_IS_OK(status
)) {
1214 if (!NT_STATUS_EQUAL(status
,
1215 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1216 /* Real error - kill the intermediate vuid */
1217 invalidate_vuid(vuid
);
1219 data_blob_free(&blob1
);
1220 reply_nterror(req
, nt_status_squash(status
));
1224 if (blob1
.data
[0] == ASN1_APPLICATION(0)) {
1226 /* its a negTokenTarg packet */
1228 reply_spnego_negotiate(conn
, req
, vuid
, blob1
,
1229 &vuser
->auth_ntlmssp_state
);
1230 data_blob_free(&blob1
);
1234 if (blob1
.data
[0] == ASN1_CONTEXT(1)) {
1236 /* its a auth packet */
1238 reply_spnego_auth(conn
, req
, vuid
, blob1
,
1239 &vuser
->auth_ntlmssp_state
);
1240 data_blob_free(&blob1
);
1244 if (strncmp((char *)(blob1
.data
), "NTLMSSP", 7) == 0) {
1247 if (!vuser
->auth_ntlmssp_state
) {
1248 status
= auth_ntlmssp_start(&vuser
->auth_ntlmssp_state
);
1249 if (!NT_STATUS_IS_OK(status
)) {
1250 /* Kill the intermediate vuid */
1251 invalidate_vuid(vuid
);
1252 data_blob_free(&blob1
);
1253 reply_nterror(req
, nt_status_squash(status
));
1258 status
= auth_ntlmssp_update(vuser
->auth_ntlmssp_state
,
1261 data_blob_free(&blob1
);
1263 reply_spnego_ntlmssp(conn
, req
, vuid
,
1264 &vuser
->auth_ntlmssp_state
,
1265 &chal
, status
, False
);
1266 data_blob_free(&chal
);
1270 /* what sort of packet is this? */
1271 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1273 data_blob_free(&blob1
);
1275 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
1278 /****************************************************************************
1279 On new VC == 0, shutdown *all* old connections and users.
1280 It seems that only NT4.x does this. At W2K and above (XP etc.).
1281 a new session setup with VC==0 is ignored.
1282 ****************************************************************************/
1284 static int shutdown_other_smbds(struct db_record
*rec
,
1285 const struct connections_key
*key
,
1286 const struct connections_data
*crec
,
1289 const char *ip
= (const char *)private_data
;
1291 if (!process_exists(crec
->pid
)) {
1295 if (procid_is_me(&crec
->pid
)) {
1299 if (strcmp(ip
, crec
->addr
) != 0) {
1303 messaging_send(smbd_messaging_context(), crec
->pid
, MSG_SHUTDOWN
,
1308 static void setup_new_vc_session(void)
1310 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1311 "compatible we would close all old resources.\n"));
1314 invalidate_all_vuids();
1316 if (lp_reset_on_zero_vc()) {
1317 connections_forall(shutdown_other_smbds
,
1318 CONST_DISCARD(void *,client_addr()));
1322 /****************************************************************************
1323 Reply to a session setup command.
1324 ****************************************************************************/
1326 void reply_sesssetup_and_X(connection_struct
*conn
, struct smb_request
*req
)
1332 DATA_BLOB plaintext_password
;
1334 fstring sub_user
; /* Sainitised username for substituion */
1337 fstring native_lanman
;
1338 fstring primary_domain
;
1339 static bool done_sesssetup
= False
;
1340 auth_usersupplied_info
*user_info
= NULL
;
1341 auth_serversupplied_info
*server_info
= NULL
;
1342 uint16 smb_flag2
= req
->flags2
;
1346 bool doencrypt
= global_encrypted_passwords_negotiated
;
1348 DATA_BLOB session_key
;
1350 START_PROFILE(SMBsesssetupX
);
1352 ZERO_STRUCT(lm_resp
);
1353 ZERO_STRUCT(nt_resp
);
1354 ZERO_STRUCT(plaintext_password
);
1356 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
1358 /* a SPNEGO session setup has 12 command words, whereas a normal
1359 NT1 session setup has 13. See the cifs spec. */
1360 if (req
->wct
== 12 &&
1361 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
1363 if (!global_spnego_negotiated
) {
1364 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1365 "at SPNEGO session setup when it was not "
1367 reply_nterror(req
, nt_status_squash(
1368 NT_STATUS_LOGON_FAILURE
));
1369 END_PROFILE(SMBsesssetupX
);
1373 if (SVAL(req
->inbuf
,smb_vwv4
) == 0) {
1374 setup_new_vc_session();
1377 reply_sesssetup_and_X_spnego(conn
, req
);
1378 END_PROFILE(SMBsesssetupX
);
1382 smb_bufsize
= SVAL(req
->inbuf
,smb_vwv2
);
1384 if (Protocol
< PROTOCOL_NT1
) {
1385 uint16 passlen1
= SVAL(req
->inbuf
,smb_vwv7
);
1387 /* Never do NT status codes with protocols before NT1 as we
1388 * don't get client caps. */
1389 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
1391 if ((passlen1
> MAX_PASS_LEN
)
1392 || (passlen1
> smb_bufrem(req
->inbuf
,
1393 smb_buf(req
->inbuf
)))) {
1394 reply_nterror(req
, nt_status_squash(
1395 NT_STATUS_INVALID_PARAMETER
));
1396 END_PROFILE(SMBsesssetupX
);
1401 lm_resp
= data_blob(smb_buf(req
->inbuf
), passlen1
);
1403 plaintext_password
= data_blob(smb_buf(req
->inbuf
),
1405 /* Ensure null termination */
1406 plaintext_password
.data
[passlen1
] = 0;
1409 srvstr_pull_buf(req
->inbuf
, req
->flags2
, user
,
1410 smb_buf(req
->inbuf
)+passlen1
, sizeof(user
),
1415 uint16 passlen1
= SVAL(req
->inbuf
,smb_vwv7
);
1416 uint16 passlen2
= SVAL(req
->inbuf
,smb_vwv8
);
1417 enum remote_arch_types ra_type
= get_remote_arch();
1418 char *p
= smb_buf(req
->inbuf
);
1419 char *save_p
= smb_buf(req
->inbuf
);
1423 if(global_client_caps
== 0) {
1424 global_client_caps
= IVAL(req
->inbuf
,smb_vwv11
);
1426 if (!(global_client_caps
& CAP_STATUS32
)) {
1427 remove_from_common_flags2(
1428 FLAGS2_32_BIT_ERROR_CODES
);
1431 /* client_caps is used as final determination if
1432 * client is NT or Win95. This is needed to return
1433 * the correct error codes in some circumstances.
1436 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
1437 ra_type
== RA_WIN95
) {
1438 if(!(global_client_caps
& (CAP_NT_SMBS
|
1440 set_remote_arch( RA_WIN95
);
1446 /* both Win95 and WinNT stuff up the password
1447 * lengths for non-encrypting systems. Uggh.
1449 if passlen1==24 its a win95 system, and its setting
1450 the password length incorrectly. Luckily it still
1451 works with the default code because Win95 will null
1452 terminate the password anyway
1454 if passlen1>0 and passlen2>0 then maybe its a NT box
1455 and its setting passlen2 to some random value which
1456 really stuffs things up. we need to fix that one. */
1458 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
1464 /* check for nasty tricks */
1465 if (passlen1
> MAX_PASS_LEN
1466 || passlen1
> smb_bufrem(req
->inbuf
, p
)) {
1467 reply_nterror(req
, nt_status_squash(
1468 NT_STATUS_INVALID_PARAMETER
));
1469 END_PROFILE(SMBsesssetupX
);
1473 if (passlen2
> MAX_PASS_LEN
1474 || passlen2
> smb_bufrem(req
->inbuf
, p
+passlen1
)) {
1475 reply_nterror(req
, nt_status_squash(
1476 NT_STATUS_INVALID_PARAMETER
));
1477 END_PROFILE(SMBsesssetupX
);
1481 /* Save the lanman2 password and the NT md4 password. */
1483 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
1488 lm_resp
= data_blob(p
, passlen1
);
1489 nt_resp
= data_blob(p
+passlen1
, passlen2
);
1492 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
1495 /* This was the previous fix. Not sure if it's still
1497 if ((ra_type
== RA_WINNT
) && (passlen2
== 0)
1498 && unic
&& passlen1
) {
1499 /* NT4.0 stuffs up plaintext unicode password
1501 srvstr_pull(inbuf
, pass
, smb_buf(inbuf
) + 1,
1502 sizeof(pass
), passlen1
, STR_TERMINATE
);
1505 if (unic
&& (passlen2
== 0) && passlen1
) {
1506 /* Only a ascii plaintext password was sent. */
1507 srvstr_pull(req
->inbuf
, req
->flags2
, pass
,
1508 smb_buf(req
->inbuf
), sizeof(pass
),
1509 passlen1
, STR_TERMINATE
|STR_ASCII
);
1511 srvstr_pull(req
->inbuf
, req
->flags2
, pass
,
1512 smb_buf(req
->inbuf
), sizeof(pass
),
1513 unic
? passlen2
: passlen1
,
1516 plaintext_password
= data_blob(pass
, strlen(pass
)+1);
1519 p
+= passlen1
+ passlen2
;
1520 p
+= srvstr_pull_buf(req
->inbuf
, req
->flags2
, user
, p
,
1521 sizeof(user
), STR_TERMINATE
);
1522 p
+= srvstr_pull_buf(req
->inbuf
, req
->flags2
, domain
, p
,
1523 sizeof(domain
), STR_TERMINATE
);
1524 p
+= srvstr_pull_buf(req
->inbuf
, req
->flags2
, native_os
,
1525 p
, sizeof(native_os
), STR_TERMINATE
);
1526 p
+= srvstr_pull_buf(req
->inbuf
, req
->flags2
,
1527 native_lanman
, p
, sizeof(native_lanman
),
1530 /* not documented or decoded by Ethereal but there is one more
1531 * string in the extra bytes which is the same as the
1532 * PrimaryDomain when using extended security. Windows NT 4
1533 * and 2003 use this string to store the native lanman string.
1534 * Windows 9x does not include a string here at all so we have
1535 * to check if we have any extra bytes left */
1537 byte_count
= SVAL(req
->inbuf
, smb_vwv13
);
1538 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
1539 p
+= srvstr_pull_buf(req
->inbuf
, req
->flags2
,
1541 sizeof(primary_domain
),
1544 fstrcpy( primary_domain
, "null" );
1547 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1548 "PrimaryDomain=[%s]\n",
1549 domain
, native_os
, native_lanman
, primary_domain
));
1551 if ( ra_type
== RA_WIN2K
) {
1552 if ( strlen(native_lanman
) == 0 )
1553 ra_lanman_string( primary_domain
);
1555 ra_lanman_string( native_lanman
);
1560 if (SVAL(req
->inbuf
,smb_vwv4
) == 0) {
1561 setup_new_vc_session();
1564 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1565 domain
, user
, get_remote_machine_name()));
1568 if (global_spnego_negotiated
) {
1570 /* This has to be here, because this is a perfectly
1571 * valid behaviour for guest logons :-( */
1573 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1574 "at 'normal' session setup after "
1575 "negotiating spnego.\n"));
1576 reply_nterror(req
, nt_status_squash(
1577 NT_STATUS_LOGON_FAILURE
));
1578 END_PROFILE(SMBsesssetupX
);
1581 fstrcpy(sub_user
, user
);
1583 fstrcpy(sub_user
, lp_guestaccount());
1586 sub_set_smb_name(sub_user
);
1588 reload_services(True
);
1590 if (lp_security() == SEC_SHARE
) {
1591 /* in share level we should ignore any passwords */
1593 data_blob_free(&lm_resp
);
1594 data_blob_free(&nt_resp
);
1595 data_blob_clear_free(&plaintext_password
);
1597 map_username(sub_user
);
1598 add_session_user(sub_user
);
1599 add_session_workgroup(domain
);
1600 /* Then force it to null for the benfit of the code below */
1606 nt_status
= check_guest_password(&server_info
);
1608 } else if (doencrypt
) {
1609 if (!negprot_global_auth_context
) {
1610 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1611 "session setup without negprot denied!\n"));
1612 reply_nterror(req
, nt_status_squash(
1613 NT_STATUS_LOGON_FAILURE
));
1614 END_PROFILE(SMBsesssetupX
);
1617 nt_status
= make_user_info_for_reply_enc(&user_info
, user
,
1620 if (NT_STATUS_IS_OK(nt_status
)) {
1621 nt_status
= negprot_global_auth_context
->check_ntlm_password(
1622 negprot_global_auth_context
,
1627 struct auth_context
*plaintext_auth_context
= NULL
;
1630 nt_status
= make_auth_context_subsystem(
1631 &plaintext_auth_context
);
1633 if (NT_STATUS_IS_OK(nt_status
)) {
1634 chal
= plaintext_auth_context
->get_ntlm_challenge(
1635 plaintext_auth_context
);
1637 if (!make_user_info_for_reply(&user_info
,
1639 plaintext_password
)) {
1640 nt_status
= NT_STATUS_NO_MEMORY
;
1643 if (NT_STATUS_IS_OK(nt_status
)) {
1644 nt_status
= plaintext_auth_context
->check_ntlm_password(
1645 plaintext_auth_context
,
1649 (plaintext_auth_context
->free
)(
1650 &plaintext_auth_context
);
1655 free_user_info(&user_info
);
1657 if (!NT_STATUS_IS_OK(nt_status
)) {
1658 nt_status
= do_map_to_guest(nt_status
, &server_info
,
1662 if (!NT_STATUS_IS_OK(nt_status
)) {
1663 data_blob_free(&nt_resp
);
1664 data_blob_free(&lm_resp
);
1665 data_blob_clear_free(&plaintext_password
);
1666 reply_nterror(req
, nt_status_squash(nt_status
));
1667 END_PROFILE(SMBsesssetupX
);
1671 /* Ensure we can't possible take a code path leading to a
1674 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
1675 END_PROFILE(SMBsesssetupX
);
1679 nt_status
= create_local_token(server_info
);
1680 if (!NT_STATUS_IS_OK(nt_status
)) {
1681 DEBUG(10, ("create_local_token failed: %s\n",
1682 nt_errstr(nt_status
)));
1683 data_blob_free(&nt_resp
);
1684 data_blob_free(&lm_resp
);
1685 data_blob_clear_free(&plaintext_password
);
1686 reply_nterror(req
, nt_status_squash(nt_status
));
1687 END_PROFILE(SMBsesssetupX
);
1691 if (server_info
->user_session_key
.data
) {
1692 session_key
= data_blob(server_info
->user_session_key
.data
,
1693 server_info
->user_session_key
.length
);
1695 session_key
= data_blob_null
;
1698 data_blob_clear_free(&plaintext_password
);
1700 /* it's ok - setup a reply */
1701 reply_outbuf(req
, 3, 0);
1702 if (Protocol
>= PROTOCOL_NT1
) {
1703 push_signature(&req
->outbuf
);
1704 /* perhaps grab OS version here?? */
1707 if (server_info
->guest
) {
1708 SSVAL(req
->outbuf
,smb_vwv2
,1);
1711 /* register the name and uid as being validated, so further connections
1712 to a uid can get through without a password, on the same VC */
1714 if (lp_security() == SEC_SHARE
) {
1715 sess_vuid
= UID_FIELD_INVALID
;
1716 data_blob_free(&session_key
);
1717 TALLOC_FREE(server_info
);
1719 /* Ignore the initial vuid. */
1720 sess_vuid
= register_initial_vuid();
1721 if (sess_vuid
== UID_FIELD_INVALID
) {
1722 data_blob_free(&nt_resp
);
1723 data_blob_free(&lm_resp
);
1724 data_blob_free(&session_key
);
1725 reply_nterror(req
, nt_status_squash(
1726 NT_STATUS_LOGON_FAILURE
));
1727 END_PROFILE(SMBsesssetupX
);
1730 /* register_existing_vuid keeps the server info */
1731 sess_vuid
= register_existing_vuid(sess_vuid
,
1734 nt_resp
.data
? nt_resp
: lm_resp
,
1736 if (sess_vuid
== UID_FIELD_INVALID
) {
1737 data_blob_free(&nt_resp
);
1738 data_blob_free(&lm_resp
);
1739 data_blob_free(&session_key
);
1740 reply_nterror(req
, nt_status_squash(
1741 NT_STATUS_LOGON_FAILURE
));
1742 END_PROFILE(SMBsesssetupX
);
1746 /* current_user_info is changed on new vuid */
1747 reload_services( True
);
1749 sessionsetup_start_signing_engine(server_info
, req
->inbuf
);
1752 data_blob_free(&nt_resp
);
1753 data_blob_free(&lm_resp
);
1755 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
1756 SSVAL(req
->inbuf
,smb_uid
,sess_vuid
);
1758 if (!done_sesssetup
)
1759 max_send
= MIN(max_send
,smb_bufsize
);
1761 done_sesssetup
= True
;
1763 END_PROFILE(SMBsesssetupX
);