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 "smbd/globals.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "librpc/gen_ndr/messaging.h"
32 /* For split krb5 SPNEGO blobs. */
33 struct pending_auth_data {
34 struct pending_auth_data *prev, *next;
35 uint16 vuid; /* Tag for this entry. */
36 uint16 smbpid; /* Alternate tag for this entry. */
38 DATA_BLOB partial_data;
42 on a logon error possibly map the error to success if "map to guest"
45 NTSTATUS do_map_to_guest(NTSTATUS status,
46 struct auth_serversupplied_info **server_info,
47 const char *user, const char *domain)
49 user = user ? user : "";
50 domain = domain ? domain : "";
52 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
53 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
54 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
55 DEBUG(3,("No such user %s [%s] - using guest account\n",
57 status = make_server_info_guest(NULL, server_info);
61 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
62 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
63 DEBUG(3,("Registered username %s for guest access\n",
65 status = make_server_info_guest(NULL, server_info);
72 /****************************************************************************
73 Add the standard 'Samba' signature to the end of the session setup.
74 ****************************************************************************/
76 static int push_signature(uint8 **outbuf)
83 tmp = message_push_string(outbuf, "Unix", STR_TERMINATE);
85 if (tmp == -1) return -1;
88 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
89 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
93 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
96 if (tmp == -1) return -1;
99 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
101 if (tmp == -1) return -1;
107 /****************************************************************************
108 Send a security blob via a session setup reply.
109 ****************************************************************************/
111 static void reply_sesssetup_blob(struct smb_request *req,
115 if (!NT_STATUS_IS_OK(nt_status) &&
116 !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
117 reply_nterror(req, nt_status_squash(nt_status));
121 nt_status = nt_status_squash(nt_status);
122 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
123 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
124 SSVAL(req->outbuf, smb_vwv3, blob.length);
126 if ((message_push_blob(&req->outbuf, blob) == -1)
127 || (push_signature(&req->outbuf) == -1)) {
128 reply_nterror(req, NT_STATUS_NO_MEMORY);
132 /****************************************************************************
133 Do a 'guest' logon, getting back the
134 ****************************************************************************/
136 static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
138 struct auth_context *auth_context;
139 struct auth_usersupplied_info *user_info = NULL;
142 unsigned char chal[8];
146 DEBUG(3,("Got anonymous request\n"));
148 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context,
153 if (!make_user_info_guest(&user_info)) {
154 TALLOC_FREE(auth_context);
155 return NT_STATUS_NO_MEMORY;
158 nt_status = auth_context->check_ntlm_password(auth_context,
161 TALLOC_FREE(auth_context);
162 free_user_info(&user_info);
170 /* Experiment that failed. See "only happens with a KDC" comment below. */
171 /****************************************************************************
172 Cerate a clock skew error blob for a Windows client.
173 ****************************************************************************/
175 static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
177 krb5_context context = NULL;
178 krb5_error_code kerr = 0;
180 krb5_principal host_princ = NULL;
181 char *host_princ_s = NULL;
184 *pblob_out = data_blob_null;
186 initialize_krb5_error_table();
187 kerr = krb5_init_context(&context);
191 /* Create server principal. */
192 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
196 strlower_m(host_princ_s);
198 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
200 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed "
201 "for name %s: Error %s\n",
202 host_princ_s, error_message(kerr) ));
206 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW,
209 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error "
210 "failed: Error %s\n",
211 error_message(kerr) ));
215 *pblob_out = data_blob(reply.data, reply.length);
216 kerberos_free_data_contents(context,&reply);
222 SAFE_FREE(host_princ_s);
225 krb5_free_principal(context, host_princ);
227 krb5_free_context(context);
232 /****************************************************************************
233 Reply to a session setup spnego negotiate packet for kerberos.
234 ****************************************************************************/
236 static void reply_spnego_kerberos(struct smb_request *req,
240 bool *p_invalidate_vuid)
244 char *client, *p, *domain;
245 fstring netbios_domain_name;
248 int sess_vuid = req->vuid;
249 NTSTATUS ret = NT_STATUS_OK;
250 DATA_BLOB ap_rep, ap_rep_wrapped, response;
251 struct auth_serversupplied_info *server_info = NULL;
252 DATA_BLOB session_key = data_blob_null;
254 DATA_BLOB nullblob = data_blob_null;
255 fstring real_username;
256 bool map_domainuser_to_guest = False;
257 bool username_was_mapped;
258 struct PAC_LOGON_INFO *logon_info = NULL;
259 struct smbd_server_connection *sconn = req->sconn;
263 ZERO_STRUCT(ap_rep_wrapped);
264 ZERO_STRUCT(response);
266 /* Normally we will always invalidate the intermediate vuid. */
267 *p_invalidate_vuid = True;
269 mem_ctx = talloc_init("reply_spnego_kerberos");
270 if (mem_ctx == NULL) {
271 reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY));
275 if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
276 talloc_destroy(mem_ctx);
277 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
281 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket,
282 &client, &logon_info, &ap_rep,
285 data_blob_free(&ticket);
287 if (!NT_STATUS_IS_OK(ret)) {
289 /* Experiment that failed.
290 * See "only happens with a KDC" comment below. */
292 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
295 * Windows in this case returns
296 * NT_STATUS_MORE_PROCESSING_REQUIRED
297 * with a negTokenTarg blob containing an krb5_error
298 * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW.
299 * The client then fixes its clock and continues rather
300 * than giving an error. JRA.
301 * -- Looks like this only happens with a KDC. JRA.
304 bool ok = make_krb5_skew_error(&ap_rep);
306 talloc_destroy(mem_ctx);
307 return ERROR_NT(nt_status_squash(
308 NT_STATUS_LOGON_FAILURE));
310 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
312 response = spnego_gen_auth_response(&ap_rep_wrapped,
313 ret, OID_KERBEROS5_OLD);
314 reply_sesssetup_blob(conn, inbuf, outbuf, response,
315 NT_STATUS_MORE_PROCESSING_REQUIRED);
318 * In this one case we don't invalidate the
319 * intermediate vuid as we're expecting the client
320 * to re-use it for the next sessionsetupX packet. JRA.
323 *p_invalidate_vuid = False;
325 data_blob_free(&ap_rep);
326 data_blob_free(&ap_rep_wrapped);
327 data_blob_free(&response);
328 talloc_destroy(mem_ctx);
329 return -1; /* already replied */
332 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
333 ret = NT_STATUS_LOGON_FAILURE;
336 DEBUG(1,("Failed to verify incoming ticket with error %s!\n",
338 talloc_destroy(mem_ctx);
339 reply_nterror(req, nt_status_squash(ret));
343 DEBUG(3,("Ticket name is [%s]\n", client));
345 p = strchr_m(client, '@');
347 DEBUG(3,("Doesn't look like a valid principal\n"));
348 data_blob_free(&ap_rep);
349 data_blob_free(&session_key);
350 talloc_destroy(mem_ctx);
351 reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
357 /* save the PAC data if we have it */
360 netsamlogon_cache_store( client, &logon_info->info3 );
363 if (!strequal(p+1, lp_realm())) {
364 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
365 if (!lp_allow_trusted_domains()) {
366 data_blob_free(&ap_rep);
367 data_blob_free(&session_key);
368 talloc_destroy(mem_ctx);
369 reply_nterror(req, nt_status_squash(
370 NT_STATUS_LOGON_FAILURE));
375 /* this gives a fully qualified user name (ie. with full realm).
376 that leads to very long usernames, but what else can we do? */
380 if (logon_info && logon_info->info3.base.domain.string) {
381 fstrcpy(netbios_domain_name,
382 logon_info->info3.base.domain.string);
383 domain = netbios_domain_name;
384 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
388 /* If we have winbind running, we can (and must) shorten the
389 username by using the short netbios name. Otherwise we will
390 have inconsistent user names. With Kerberos, we get the
391 fully qualified realm, with ntlmssp we get the short
392 name. And even w2k3 does use ntlmssp if you for example
393 connect to an ip address. */
396 struct wbcDomainInfo *info = NULL;
398 DEBUG(10, ("Mapping [%s] to short name\n", domain));
400 wbc_status = wbcDomainInfo(domain, &info);
402 if (WBC_ERROR_IS_OK(wbc_status)) {
404 fstrcpy(netbios_domain_name,
408 domain = netbios_domain_name;
409 DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
411 DEBUG(3, ("Could not find short name: %s\n",
412 wbcErrorString(wbc_status)));
416 fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
418 /* lookup the passwd struct, create a new user if necessary */
420 username_was_mapped = map_username(user);
422 pw = smb_getpwnam( mem_ctx, user, real_username, True );
425 /* if a real user check pam account restrictions */
426 /* only really perfomed if "obey pam restriction" is true */
427 /* do this before an eventual mapping to guest occurs */
428 ret = smb_pam_accountcheck(pw->pw_name);
429 if ( !NT_STATUS_IS_OK(ret)) {
430 DEBUG(1,("PAM account restriction "
431 "prevents user login\n"));
432 data_blob_free(&ap_rep);
433 data_blob_free(&session_key);
434 TALLOC_FREE(mem_ctx);
435 reply_nterror(req, nt_status_squash(ret));
442 /* this was originally the behavior of Samba 2.2, if a user
443 did not have a local uid but has been authenticated, then
444 map them to a guest account */
446 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
447 map_domainuser_to_guest = True;
448 fstrcpy(user,lp_guestaccount());
449 pw = smb_getpwnam( mem_ctx, user, real_username, True );
452 /* extra sanity check that the guest account is valid */
455 DEBUG(1,("Username %s is invalid on this system\n",
457 data_blob_free(&ap_rep);
458 data_blob_free(&session_key);
459 TALLOC_FREE(mem_ctx);
460 reply_nterror(req, nt_status_squash(
461 NT_STATUS_LOGON_FAILURE));
466 /* setup the string used by %U */
468 sub_set_smb_name( real_username );
469 reload_services(True);
471 if ( map_domainuser_to_guest ) {
472 make_server_info_guest(NULL, &server_info);
473 } else if (logon_info) {
474 /* pass the unmapped username here since map_username()
475 will be called again from inside make_server_info_info3() */
477 ret = make_server_info_info3(mem_ctx, client, domain,
478 &server_info, &logon_info->info3);
479 if ( !NT_STATUS_IS_OK(ret) ) {
480 DEBUG(1,("make_server_info_info3 failed: %s!\n",
482 data_blob_free(&ap_rep);
483 data_blob_free(&session_key);
484 TALLOC_FREE(mem_ctx);
485 reply_nterror(req, nt_status_squash(ret));
491 * We didn't get a PAC, we have to make up the user
492 * ourselves. Try to ask the pdb backend to provide
493 * SID consistency with ntlmssp session setup
495 struct samu *sampass;
497 sampass = samu_new(talloc_tos());
498 if (sampass == NULL) {
499 ret = NT_STATUS_NO_MEMORY;
500 data_blob_free(&ap_rep);
501 data_blob_free(&session_key);
502 TALLOC_FREE(mem_ctx);
503 reply_nterror(req, nt_status_squash(ret));
507 if (pdb_getsampwnam(sampass, real_username)) {
508 DEBUG(10, ("found user %s in passdb, calling "
509 "make_server_info_sam\n", real_username));
510 ret = make_server_info_sam(&server_info, sampass);
511 TALLOC_FREE(sampass);
514 * User not in passdb, make it up artificially
516 TALLOC_FREE(sampass);
517 DEBUG(10, ("didn't find user %s in passdb, calling "
518 "make_server_info_pw\n", real_username));
519 ret = make_server_info_pw(&server_info, real_username,
523 if ( !NT_STATUS_IS_OK(ret) ) {
524 DEBUG(1,("make_server_info_[sam|pw] failed: %s!\n",
526 data_blob_free(&ap_rep);
527 data_blob_free(&session_key);
528 TALLOC_FREE(mem_ctx);
529 reply_nterror(req, nt_status_squash(ret));
533 /* make_server_info_pw does not set the domain. Without this
534 * we end up with the local netbios name in substitutions for
537 if (server_info->info3 != NULL) {
538 server_info->info3->base.domain.string =
539 talloc_strdup(server_info->info3, domain);
543 server_info->nss_token |= username_was_mapped;
545 /* we need to build the token for the user. make_server_info_guest()
548 if ( !server_info->ptok ) {
549 ret = create_local_token( server_info );
550 if ( !NT_STATUS_IS_OK(ret) ) {
551 DEBUG(10,("failed to create local token: %s\n",
553 data_blob_free(&ap_rep);
554 data_blob_free(&session_key);
555 TALLOC_FREE( mem_ctx );
556 TALLOC_FREE( server_info );
557 reply_nterror(req, nt_status_squash(ret));
562 if (!is_partial_auth_vuid(sconn, sess_vuid)) {
563 sess_vuid = register_initial_vuid(sconn);
566 data_blob_free(&server_info->user_session_key);
567 server_info->user_session_key = session_key;
568 talloc_steal(server_info, session_key.data);
570 session_key = data_blob_null;
572 /* register_existing_vuid keeps the server info */
573 /* register_existing_vuid takes ownership of session_key on success,
574 * no need to free after this on success. A better interface would copy
577 sess_vuid = register_existing_vuid(sconn,
583 reply_outbuf(req, 4, 0);
584 SSVAL(req->outbuf,smb_uid,sess_vuid);
586 if (sess_vuid == UID_FIELD_INVALID ) {
587 ret = NT_STATUS_LOGON_FAILURE;
589 /* current_user_info is changed on new vuid */
590 reload_services( True );
592 SSVAL(req->outbuf, smb_vwv3, 0);
594 if (server_info->guest) {
595 SSVAL(req->outbuf,smb_vwv2,1);
598 SSVAL(req->outbuf, smb_uid, sess_vuid);
600 /* Successful logon. Keep this vuid. */
601 *p_invalidate_vuid = False;
604 /* wrap that up in a nice GSS-API wrapping */
605 if (NT_STATUS_IS_OK(ret)) {
606 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
609 ap_rep_wrapped = data_blob_null;
611 response = spnego_gen_auth_response(&ap_rep_wrapped, ret,
613 reply_sesssetup_blob(req, response, ret);
615 data_blob_free(&ap_rep);
616 data_blob_free(&ap_rep_wrapped);
617 data_blob_free(&response);
618 TALLOC_FREE(mem_ctx);
623 /****************************************************************************
624 Send a session setup reply, wrapped in SPNEGO.
625 Get vuid and check first.
626 End the NTLMSSP exchange context if we are OK/complete fail
627 This should be split into two functions, one to handle each
628 leg of the NTLM auth steps.
629 ***************************************************************************/
631 static void reply_spnego_ntlmssp(struct smb_request *req,
633 struct auth_ntlmssp_state **auth_ntlmssp_state,
634 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
638 bool do_invalidate = true;
640 struct auth_serversupplied_info *server_info = NULL;
641 struct smbd_server_connection *sconn = req->sconn;
643 if (NT_STATUS_IS_OK(nt_status)) {
644 nt_status = auth_ntlmssp_steal_server_info(talloc_tos(),
645 (*auth_ntlmssp_state), &server_info);
647 /* Note that this server_info won't have a session
648 * key. But for map to guest, that's exactly the right
649 * thing - we can't reasonably guess the key the
650 * client wants, as the password was wrong */
651 nt_status = do_map_to_guest(nt_status,
653 auth_ntlmssp_get_username(*auth_ntlmssp_state),
654 auth_ntlmssp_get_domain(*auth_ntlmssp_state));
657 reply_outbuf(req, 4, 0);
659 SSVAL(req->outbuf, smb_uid, vuid);
661 if (NT_STATUS_IS_OK(nt_status)) {
662 DATA_BLOB nullblob = data_blob_null;
664 if (!is_partial_auth_vuid(sconn, vuid)) {
665 nt_status = NT_STATUS_LOGON_FAILURE;
669 /* register_existing_vuid keeps the server info */
670 if (register_existing_vuid(sconn, vuid,
671 server_info, nullblob,
672 auth_ntlmssp_get_username(*auth_ntlmssp_state)) !=
674 /* The problem is, *auth_ntlmssp_state points
675 * into the vuser this will have
676 * talloc_free()'ed in
677 * register_existing_vuid() */
678 do_invalidate = false;
679 nt_status = NT_STATUS_LOGON_FAILURE;
683 /* current_user_info is changed on new vuid */
684 reload_services( True );
686 SSVAL(req->outbuf, smb_vwv3, 0);
688 if (server_info->guest) {
689 SSVAL(req->outbuf,smb_vwv2,1);
696 response = spnego_gen_auth_response(ntlmssp_blob,
699 response = *ntlmssp_blob;
702 reply_sesssetup_blob(req, response, nt_status);
704 data_blob_free(&response);
707 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
708 and the other end, that we are not finished yet. */
710 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
711 /* NB. This is *NOT* an error case. JRA */
713 TALLOC_FREE(*auth_ntlmssp_state);
714 if (!NT_STATUS_IS_OK(nt_status)) {
715 /* Kill the intermediate vuid */
716 invalidate_vuid(sconn, vuid);
722 /****************************************************************************
723 Is this a krb5 mechanism ?
724 ****************************************************************************/
726 NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in,
727 DATA_BLOB *pblob_out,
730 char *OIDs[ASN1_MAX_OIDS];
732 NTSTATUS ret = NT_STATUS_OK;
734 *kerb_mechOID = NULL;
736 /* parse out the OIDs and the first sec blob */
737 if (!spnego_parse_negTokenInit(blob_in, OIDs, NULL, pblob_out)) {
738 return NT_STATUS_LOGON_FAILURE;
741 /* only look at the first OID for determining the mechToken --
742 according to RFC2478, we should choose the one we want
743 and renegotiate, but i smell a client bug here..
745 Problem observed when connecting to a member (samba box)
746 of an AD domain as a user in a Samba domain. Samba member
747 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
748 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
749 NTLMSSP mechtoken. --jerry */
752 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
753 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
754 *kerb_mechOID = SMB_STRDUP(OIDs[0]);
755 if (*kerb_mechOID == NULL) {
756 ret = NT_STATUS_NO_MEMORY;
761 for (i=0;OIDs[i];i++) {
762 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
763 talloc_free(OIDs[i]);
768 /****************************************************************************
769 Fall back from krb5 to NTLMSSP.
770 ****************************************************************************/
772 static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
777 reply_outbuf(req, 4, 0);
778 SSVAL(req->outbuf,smb_uid,vuid);
780 DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
781 "but set to downgrade to NTLMSSP\n"));
783 response = spnego_gen_auth_response(NULL,
784 NT_STATUS_MORE_PROCESSING_REQUIRED,
786 reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
787 data_blob_free(&response);
790 /****************************************************************************
791 Reply to a session setup spnego negotiate packet.
792 ****************************************************************************/
794 static void reply_spnego_negotiate(struct smb_request *req,
797 struct auth_ntlmssp_state **auth_ntlmssp_state)
801 char *kerb_mech = NULL;
803 struct smbd_server_connection *sconn = req->sconn;
805 status = parse_spnego_mechanisms(blob1, &secblob, &kerb_mech);
806 if (!NT_STATUS_IS_OK(status)) {
807 /* Kill the intermediate vuid */
808 invalidate_vuid(sconn, vuid);
809 reply_nterror(req, nt_status_squash(status));
813 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n",
814 (unsigned long)secblob.length));
817 if (kerb_mech && ((lp_security()==SEC_ADS) ||
818 USE_KERBEROS_KEYTAB) ) {
819 bool destroy_vuid = True;
820 reply_spnego_kerberos(req, &secblob, kerb_mech,
821 vuid, &destroy_vuid);
822 data_blob_free(&secblob);
824 /* Kill the intermediate vuid */
825 invalidate_vuid(sconn, vuid);
827 SAFE_FREE(kerb_mech);
832 if (*auth_ntlmssp_state) {
833 TALLOC_FREE(*auth_ntlmssp_state);
837 data_blob_free(&secblob);
838 /* The mechtoken is a krb5 ticket, but
839 * we need to fall back to NTLM. */
840 reply_spnego_downgrade_to_ntlmssp(req, vuid);
841 SAFE_FREE(kerb_mech);
845 status = auth_ntlmssp_start(auth_ntlmssp_state);
846 if (!NT_STATUS_IS_OK(status)) {
847 /* Kill the intermediate vuid */
848 invalidate_vuid(sconn, vuid);
849 reply_nterror(req, nt_status_squash(status));
853 status = auth_ntlmssp_update(*auth_ntlmssp_state,
856 data_blob_free(&secblob);
858 reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
859 &chal, status, OID_NTLMSSP, true);
861 data_blob_free(&chal);
863 /* already replied */
867 /****************************************************************************
868 Reply to a session setup spnego auth packet.
869 ****************************************************************************/
871 static void reply_spnego_auth(struct smb_request *req,
874 struct auth_ntlmssp_state **auth_ntlmssp_state)
876 DATA_BLOB auth = data_blob_null;
877 DATA_BLOB auth_reply = data_blob_null;
878 DATA_BLOB secblob = data_blob_null;
879 NTSTATUS status = NT_STATUS_LOGON_FAILURE;
880 struct smbd_server_connection *sconn = req->sconn;
882 if (!spnego_parse_auth(blob1, &auth)) {
884 file_save("auth.dat", blob1.data, blob1.length);
886 /* Kill the intermediate vuid */
887 invalidate_vuid(sconn, vuid);
889 reply_nterror(req, nt_status_squash(
890 NT_STATUS_LOGON_FAILURE));
894 if (auth.data[0] == ASN1_APPLICATION(0)) {
895 /* Might be a second negTokenTarg packet */
896 char *kerb_mech = NULL;
898 status = parse_spnego_mechanisms(auth, &secblob, &kerb_mech);
900 if (!NT_STATUS_IS_OK(status)) {
901 /* Kill the intermediate vuid */
902 invalidate_vuid(sconn, vuid);
903 reply_nterror(req, nt_status_squash(status));
907 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
908 (unsigned long)secblob.length));
910 if (kerb_mech && ((lp_security()==SEC_ADS) ||
911 USE_KERBEROS_KEYTAB)) {
912 bool destroy_vuid = True;
913 reply_spnego_kerberos(req, &secblob, kerb_mech,
914 vuid, &destroy_vuid);
915 data_blob_free(&secblob);
916 data_blob_free(&auth);
918 /* Kill the intermediate vuid */
919 invalidate_vuid(sconn, vuid);
921 SAFE_FREE(kerb_mech);
925 /* Can't blunder into NTLMSSP auth if we have
929 /* Kill the intermediate vuid */
930 invalidate_vuid(sconn, vuid);
931 DEBUG(3,("reply_spnego_auth: network "
932 "misconfiguration, client sent us a "
933 "krb5 ticket and kerberos security "
935 reply_nterror(req, nt_status_squash(
936 NT_STATUS_LOGON_FAILURE));
937 SAFE_FREE(kerb_mech);
941 /* If we get here it wasn't a negTokenTarg auth packet. */
942 data_blob_free(&secblob);
944 if (!*auth_ntlmssp_state) {
945 status = auth_ntlmssp_start(auth_ntlmssp_state);
946 if (!NT_STATUS_IS_OK(status)) {
947 /* Kill the intermediate vuid */
948 invalidate_vuid(sconn, vuid);
949 reply_nterror(req, nt_status_squash(status));
954 status = auth_ntlmssp_update(*auth_ntlmssp_state,
957 data_blob_free(&auth);
959 /* Don't send the mechid as we've already sent this (RFC4178). */
961 reply_spnego_ntlmssp(req, vuid,
963 &auth_reply, status, NULL, true);
965 data_blob_free(&auth_reply);
967 /* and tell smbd that we have already replied to this packet */
971 /****************************************************************************
972 Delete an entry on the list.
973 ****************************************************************************/
975 static void delete_partial_auth(struct smbd_server_connection *sconn,
976 struct pending_auth_data *pad)
981 DLIST_REMOVE(sconn->smb1.pd_list, pad);
982 data_blob_free(&pad->partial_data);
986 /****************************************************************************
987 Search for a partial SPNEGO auth fragment matching an smbpid.
988 ****************************************************************************/
990 static struct pending_auth_data *get_pending_auth_data(
991 struct smbd_server_connection *sconn,
994 struct pending_auth_data *pad;
996 * NOTE: using the smbpid here is completely wrong...
998 * 3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
1000 for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
1001 if (pad->smbpid == smbpid) {
1008 /****************************************************************************
1009 Check the size of an SPNEGO blob. If we need more return
1010 NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow
1011 the blob to be more than 64k.
1012 ****************************************************************************/
1014 static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
1015 uint16 smbpid, uint16 vuid,
1018 struct pending_auth_data *pad = NULL;
1020 size_t needed_len = 0;
1022 pad = get_pending_auth_data(sconn, smbpid);
1024 /* Ensure we have some data. */
1025 if (pblob->length == 0) {
1026 /* Caller can cope. */
1027 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
1028 delete_partial_auth(sconn, pad);
1029 return NT_STATUS_OK;
1032 /* Were we waiting for more data ? */
1035 size_t copy_len = MIN(65536, pblob->length);
1037 /* Integer wrap paranoia.... */
1039 if (pad->partial_data.length + copy_len <
1040 pad->partial_data.length ||
1041 pad->partial_data.length + copy_len < copy_len) {
1043 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1044 "pad->partial_data.length = %u, "
1046 (unsigned int)pad->partial_data.length,
1047 (unsigned int)copy_len ));
1049 delete_partial_auth(sconn, pad);
1050 return NT_STATUS_INVALID_PARAMETER;
1053 DEBUG(10,("check_spnego_blob_complete: "
1054 "pad->partial_data.length = %u, "
1055 "pad->needed_len = %u, "
1057 "pblob->length = %u,\n",
1058 (unsigned int)pad->partial_data.length,
1059 (unsigned int)pad->needed_len,
1060 (unsigned int)copy_len,
1061 (unsigned int)pblob->length ));
1063 tmp_blob = data_blob(NULL,
1064 pad->partial_data.length + copy_len);
1066 /* Concatenate the two (up to copy_len) bytes. */
1067 memcpy(tmp_blob.data,
1068 pad->partial_data.data,
1069 pad->partial_data.length);
1070 memcpy(tmp_blob.data + pad->partial_data.length,
1074 /* Replace the partial data. */
1075 data_blob_free(&pad->partial_data);
1076 pad->partial_data = tmp_blob;
1077 ZERO_STRUCT(tmp_blob);
1080 if (pblob->length >= pad->needed_len) {
1081 /* Yes, replace pblob. */
1082 data_blob_free(pblob);
1083 *pblob = pad->partial_data;
1084 ZERO_STRUCT(pad->partial_data);
1085 delete_partial_auth(sconn, pad);
1086 return NT_STATUS_OK;
1089 /* Still need more data. */
1090 pad->needed_len -= copy_len;
1091 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1094 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
1095 (pblob->data[0] != ASN1_CONTEXT(1))) {
1096 /* Not something we can determine the
1099 return NT_STATUS_OK;
1102 /* This is a new SPNEGO sessionsetup - see if
1103 * the data given in this blob is enough.
1106 data = asn1_init(NULL);
1108 return NT_STATUS_NO_MEMORY;
1111 asn1_load(data, *pblob);
1112 asn1_start_tag(data, pblob->data[0]);
1113 if (data->has_error || data->nesting == NULL) {
1115 /* Let caller catch. */
1116 return NT_STATUS_OK;
1119 /* Integer wrap paranoia.... */
1121 if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
1122 data->nesting->taglen + data->nesting->start < data->nesting->start) {
1124 DEBUG(2,("check_spnego_blob_complete: integer wrap "
1125 "data.nesting->taglen = %u, "
1126 "data.nesting->start = %u\n",
1127 (unsigned int)data->nesting->taglen,
1128 (unsigned int)data->nesting->start ));
1131 return NT_STATUS_INVALID_PARAMETER;
1134 /* Total length of the needed asn1 is the tag length
1135 * plus the current offset. */
1137 needed_len = data->nesting->taglen + data->nesting->start;
1140 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
1141 "pblob->length = %u\n",
1142 (unsigned int)needed_len,
1143 (unsigned int)pblob->length ));
1145 if (needed_len <= pblob->length) {
1146 /* Nothing to do - blob is complete. */
1147 return NT_STATUS_OK;
1150 /* Refuse the blob if it's bigger than 64k. */
1151 if (needed_len > 65536) {
1152 DEBUG(2,("check_spnego_blob_complete: needed_len "
1154 (unsigned int)needed_len ));
1155 return NT_STATUS_INVALID_PARAMETER;
1158 /* We must store this blob until complete. */
1159 if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) {
1160 return NT_STATUS_NO_MEMORY;
1162 pad->needed_len = needed_len - pblob->length;
1163 pad->partial_data = data_blob(pblob->data, pblob->length);
1164 if (pad->partial_data.data == NULL) {
1166 return NT_STATUS_NO_MEMORY;
1168 pad->smbpid = smbpid;
1170 DLIST_ADD(sconn->smb1.pd_list, pad);
1172 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1175 /****************************************************************************
1176 Reply to a session setup command.
1177 conn POINTER CAN BE NULL HERE !
1178 ****************************************************************************/
1180 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
1186 const char *native_os;
1187 const char *native_lanman;
1188 const char *primary_domain;
1190 uint16 data_blob_len = SVAL(req->vwv+7, 0);
1191 enum remote_arch_types ra_type = get_remote_arch();
1192 int vuid = req->vuid;
1193 user_struct *vuser = NULL;
1194 NTSTATUS status = NT_STATUS_OK;
1195 uint16 smbpid = req->smbpid;
1196 struct smbd_server_connection *sconn = req->sconn;
1198 DEBUG(3,("Doing spnego session setup\n"));
1200 if (global_client_caps == 0) {
1201 global_client_caps = IVAL(req->vwv+10, 0);
1203 if (!(global_client_caps & CAP_STATUS32)) {
1204 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1211 if (data_blob_len == 0) {
1212 /* an invalid request */
1213 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1217 bufrem = smbreq_bufrem(req, p);
1218 /* pull the spnego blob */
1219 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
1222 file_save("negotiate.dat", blob1.data, blob1.length);
1225 p2 = (char *)req->buf + blob1.length;
1227 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1229 native_os = tmp ? tmp : "";
1231 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1233 native_lanman = tmp ? tmp : "";
1235 p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
1237 primary_domain = tmp ? tmp : "";
1239 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
1240 native_os, native_lanman, primary_domain));
1242 if ( ra_type == RA_WIN2K ) {
1243 /* Vista sets neither the OS or lanman strings */
1245 if ( !strlen(native_os) && !strlen(native_lanman) )
1246 set_remote_arch(RA_VISTA);
1248 /* Windows 2003 doesn't set the native lanman string,
1249 but does set primary domain which is a bug I think */
1251 if ( !strlen(native_lanman) ) {
1252 ra_lanman_string( primary_domain );
1254 ra_lanman_string( native_lanman );
1258 /* Did we get a valid vuid ? */
1259 if (!is_partial_auth_vuid(sconn, vuid)) {
1260 /* No, then try and see if this is an intermediate sessionsetup
1261 * for a large SPNEGO packet. */
1262 struct pending_auth_data *pad;
1263 pad = get_pending_auth_data(sconn, smbpid);
1265 DEBUG(10,("reply_sesssetup_and_X_spnego: found "
1266 "pending vuid %u\n",
1267 (unsigned int)pad->vuid ));
1272 /* Do we have a valid vuid now ? */
1273 if (!is_partial_auth_vuid(sconn, vuid)) {
1274 /* No, start a new authentication setup. */
1275 vuid = register_initial_vuid(sconn);
1276 if (vuid == UID_FIELD_INVALID) {
1277 data_blob_free(&blob1);
1278 reply_nterror(req, nt_status_squash(
1279 NT_STATUS_INVALID_PARAMETER));
1284 vuser = get_partial_auth_user_struct(sconn, vuid);
1285 /* This MUST be valid. */
1287 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
1290 /* Large (greater than 4k) SPNEGO blobs are split into multiple
1291 * sessionsetup requests as the Windows limit on the security blob
1292 * field is 4k. Bug #4400. JRA.
1295 status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
1296 if (!NT_STATUS_IS_OK(status)) {
1297 if (!NT_STATUS_EQUAL(status,
1298 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1299 /* Real error - kill the intermediate vuid */
1300 invalidate_vuid(sconn, vuid);
1302 data_blob_free(&blob1);
1303 reply_nterror(req, nt_status_squash(status));
1307 if (blob1.data[0] == ASN1_APPLICATION(0)) {
1309 /* its a negTokenTarg packet */
1311 reply_spnego_negotiate(req, vuid, blob1,
1312 &vuser->auth_ntlmssp_state);
1313 data_blob_free(&blob1);
1317 if (blob1.data[0] == ASN1_CONTEXT(1)) {
1319 /* its a auth packet */
1321 reply_spnego_auth(req, vuid, blob1,
1322 &vuser->auth_ntlmssp_state);
1323 data_blob_free(&blob1);
1327 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
1330 if (!vuser->auth_ntlmssp_state) {
1331 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 /* Kill the intermediate vuid */
1334 invalidate_vuid(sconn, vuid);
1335 data_blob_free(&blob1);
1336 reply_nterror(req, nt_status_squash(status));
1341 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
1344 data_blob_free(&blob1);
1346 reply_spnego_ntlmssp(req, vuid,
1347 &vuser->auth_ntlmssp_state,
1348 &chal, status, OID_NTLMSSP, false);
1349 data_blob_free(&chal);
1353 /* what sort of packet is this? */
1354 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
1356 data_blob_free(&blob1);
1358 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1361 /****************************************************************************
1362 On new VC == 0, shutdown *all* old connections and users.
1363 It seems that only NT4.x does this. At W2K and above (XP etc.).
1364 a new session setup with VC==0 is ignored.
1365 ****************************************************************************/
1367 struct shutdown_state {
1369 struct messaging_context *msg_ctx;
1372 static int shutdown_other_smbds(const struct connections_key *key,
1373 const struct connections_data *crec,
1376 struct shutdown_state *state = (struct shutdown_state *)private_data;
1378 if (!process_exists(crec->pid)) {
1382 if (procid_is_me(&crec->pid)) {
1386 if (strcmp(state->ip, crec->addr) != 0) {
1390 DEBUG(0,("shutdown_other_smbds: shutting down pid %u "
1391 "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid),
1394 messaging_send(state->msg_ctx, crec->pid, MSG_SHUTDOWN,
1399 static void setup_new_vc_session(struct messaging_context *msg_ctx)
1401 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
1402 "compatible we would close all old resources.\n"));
1405 invalidate_all_vuids();
1407 if (lp_reset_on_zero_vc()) {
1408 char addr[INET6_ADDRSTRLEN];
1409 struct shutdown_state state;
1411 state.ip = client_addr(get_client_fd(),addr,sizeof(addr));
1412 state.msg_ctx = msg_ctx;
1413 connections_forall_read(shutdown_other_smbds, &state);
1417 /****************************************************************************
1418 Reply to a session setup command.
1419 ****************************************************************************/
1421 void reply_sesssetup_and_X(struct smb_request *req)
1427 DATA_BLOB plaintext_password;
1430 fstring sub_user; /* Sanitised username for substituion */
1432 const char *native_os;
1433 const char *native_lanman;
1434 const char *primary_domain;
1435 struct auth_usersupplied_info *user_info = NULL;
1436 struct auth_serversupplied_info *server_info = NULL;
1437 uint16 smb_flag2 = req->flags2;
1440 struct smbd_server_connection *sconn = req->sconn;
1442 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
1444 START_PROFILE(SMBsesssetupX);
1446 ZERO_STRUCT(lm_resp);
1447 ZERO_STRUCT(nt_resp);
1448 ZERO_STRUCT(plaintext_password);
1450 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
1452 /* a SPNEGO session setup has 12 command words, whereas a normal
1453 NT1 session setup has 13. See the cifs spec. */
1454 if (req->wct == 12 &&
1455 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
1457 if (!sconn->smb1.negprot.spnego) {
1458 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1459 "at SPNEGO session setup when it was not "
1461 reply_nterror(req, nt_status_squash(
1462 NT_STATUS_LOGON_FAILURE));
1463 END_PROFILE(SMBsesssetupX);
1467 if (SVAL(req->vwv+4, 0) == 0) {
1468 setup_new_vc_session(req->sconn->msg_ctx);
1471 reply_sesssetup_and_X_spnego(req);
1472 END_PROFILE(SMBsesssetupX);
1476 smb_bufsize = SVAL(req->vwv+2, 0);
1478 if (get_Protocol() < PROTOCOL_NT1) {
1479 uint16 passlen1 = SVAL(req->vwv+7, 0);
1481 /* Never do NT status codes with protocols before NT1 as we
1482 * don't get client caps. */
1483 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
1485 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
1486 reply_nterror(req, nt_status_squash(
1487 NT_STATUS_INVALID_PARAMETER));
1488 END_PROFILE(SMBsesssetupX);
1493 lm_resp = data_blob(req->buf, passlen1);
1495 plaintext_password = data_blob(req->buf, passlen1+1);
1496 /* Ensure null termination */
1497 plaintext_password.data[passlen1] = 0;
1500 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
1501 req->buf + passlen1, STR_TERMINATE);
1502 user = tmp ? tmp : "";
1507 uint16 passlen1 = SVAL(req->vwv+7, 0);
1508 uint16 passlen2 = SVAL(req->vwv+8, 0);
1509 enum remote_arch_types ra_type = get_remote_arch();
1510 const uint8_t *p = req->buf;
1511 const uint8_t *save_p = req->buf;
1515 if(global_client_caps == 0) {
1516 global_client_caps = IVAL(req->vwv+11, 0);
1518 if (!(global_client_caps & CAP_STATUS32)) {
1519 remove_from_common_flags2(
1520 FLAGS2_32_BIT_ERROR_CODES);
1523 /* client_caps is used as final determination if
1524 * client is NT or Win95. This is needed to return
1525 * the correct error codes in some circumstances.
1528 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
1529 ra_type == RA_WIN95) {
1530 if(!(global_client_caps & (CAP_NT_SMBS|
1532 set_remote_arch( RA_WIN95);
1538 /* both Win95 and WinNT stuff up the password
1539 * lengths for non-encrypting systems. Uggh.
1541 if passlen1==24 its a win95 system, and its setting
1542 the password length incorrectly. Luckily it still
1543 works with the default code because Win95 will null
1544 terminate the password anyway
1546 if passlen1>0 and passlen2>0 then maybe its a NT box
1547 and its setting passlen2 to some random value which
1548 really stuffs things up. we need to fix that one. */
1550 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
1556 /* check for nasty tricks */
1557 if (passlen1 > MAX_PASS_LEN
1558 || passlen1 > smbreq_bufrem(req, p)) {
1559 reply_nterror(req, nt_status_squash(
1560 NT_STATUS_INVALID_PARAMETER));
1561 END_PROFILE(SMBsesssetupX);
1565 if (passlen2 > MAX_PASS_LEN
1566 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
1567 reply_nterror(req, nt_status_squash(
1568 NT_STATUS_INVALID_PARAMETER));
1569 END_PROFILE(SMBsesssetupX);
1573 /* Save the lanman2 password and the NT md4 password. */
1575 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
1580 lm_resp = data_blob(p, passlen1);
1581 nt_resp = data_blob(p+passlen1, passlen2);
1582 } else if (lp_security() != SEC_SHARE) {
1584 * In share level we should ignore any passwords, so
1585 * only read them if we're not.
1588 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
1590 if (unic && (passlen2 == 0) && passlen1) {
1591 /* Only a ascii plaintext password was sent. */
1592 (void)srvstr_pull_talloc(talloc_tos(),
1598 STR_TERMINATE|STR_ASCII);
1600 (void)srvstr_pull_talloc(talloc_tos(),
1605 unic ? passlen2 : passlen1,
1609 reply_nterror(req, nt_status_squash(
1610 NT_STATUS_INVALID_PARAMETER));
1611 END_PROFILE(SMBsesssetupX);
1614 plaintext_password = data_blob(pass, strlen(pass)+1);
1617 p += passlen1 + passlen2;
1619 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1621 user = tmp ? tmp : "";
1623 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1625 domain = tmp ? tmp : "";
1627 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1629 native_os = tmp ? tmp : "";
1631 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1633 native_lanman = tmp ? tmp : "";
1635 /* not documented or decoded by Ethereal but there is one more
1636 * string in the extra bytes which is the same as the
1637 * PrimaryDomain when using extended security. Windows NT 4
1638 * and 2003 use this string to store the native lanman string.
1639 * Windows 9x does not include a string here at all so we have
1640 * to check if we have any extra bytes left */
1642 byte_count = SVAL(req->vwv+13, 0);
1643 if ( PTR_DIFF(p, save_p) < byte_count) {
1644 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
1646 primary_domain = tmp ? tmp : "";
1648 primary_domain = talloc_strdup(talloc_tos(), "null");
1651 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
1652 "PrimaryDomain=[%s]\n",
1653 domain, native_os, native_lanman, primary_domain));
1655 if ( ra_type == RA_WIN2K ) {
1656 if ( strlen(native_lanman) == 0 )
1657 ra_lanman_string( primary_domain );
1659 ra_lanman_string( native_lanman );
1664 if (SVAL(req->vwv+4, 0) == 0) {
1665 setup_new_vc_session(req->sconn->msg_ctx);
1668 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
1669 domain, user, get_remote_machine_name()));
1672 if (sconn->smb1.negprot.spnego) {
1674 /* This has to be here, because this is a perfectly
1675 * valid behaviour for guest logons :-( */
1677 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
1678 "at 'normal' session setup after "
1679 "negotiating spnego.\n"));
1680 reply_nterror(req, nt_status_squash(
1681 NT_STATUS_LOGON_FAILURE));
1682 END_PROFILE(SMBsesssetupX);
1685 fstrcpy(sub_user, user);
1687 fstrcpy(sub_user, lp_guestaccount());
1690 sub_set_smb_name(sub_user);
1692 reload_services(True);
1694 if (lp_security() == SEC_SHARE) {
1695 /* In share level we should ignore any passwords */
1697 data_blob_free(&lm_resp);
1698 data_blob_free(&nt_resp);
1699 data_blob_clear_free(&plaintext_password);
1701 map_username(sub_user);
1702 add_session_user(sconn, sub_user);
1703 add_session_workgroup(sconn, domain);
1704 /* Then force it to null for the benfit of the code below */
1710 nt_status = check_guest_password(&server_info);
1712 } else if (doencrypt) {
1713 struct auth_context *negprot_auth_context = NULL;
1714 negprot_auth_context = sconn->smb1.negprot.auth_context;
1715 if (!negprot_auth_context) {
1716 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
1717 "session setup without negprot denied!\n"));
1718 reply_nterror(req, nt_status_squash(
1719 NT_STATUS_LOGON_FAILURE));
1720 END_PROFILE(SMBsesssetupX);
1723 nt_status = make_user_info_for_reply_enc(&user_info, user,
1726 if (NT_STATUS_IS_OK(nt_status)) {
1727 nt_status = negprot_auth_context->check_ntlm_password(
1728 negprot_auth_context,
1733 struct auth_context *plaintext_auth_context = NULL;
1735 nt_status = make_auth_context_subsystem(
1736 &plaintext_auth_context);
1738 if (NT_STATUS_IS_OK(nt_status)) {
1741 plaintext_auth_context->get_ntlm_challenge(
1742 plaintext_auth_context, chal);
1744 if (!make_user_info_for_reply(&user_info,
1746 plaintext_password)) {
1747 nt_status = NT_STATUS_NO_MEMORY;
1750 if (NT_STATUS_IS_OK(nt_status)) {
1751 nt_status = plaintext_auth_context->check_ntlm_password(
1752 plaintext_auth_context,
1756 TALLOC_FREE(plaintext_auth_context);
1761 free_user_info(&user_info);
1763 if (!NT_STATUS_IS_OK(nt_status)) {
1764 nt_status = do_map_to_guest(nt_status, &server_info,
1768 if (!NT_STATUS_IS_OK(nt_status)) {
1769 data_blob_free(&nt_resp);
1770 data_blob_free(&lm_resp);
1771 data_blob_clear_free(&plaintext_password);
1772 reply_nterror(req, nt_status_squash(nt_status));
1773 END_PROFILE(SMBsesssetupX);
1777 /* Ensure we can't possible take a code path leading to a
1780 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
1781 END_PROFILE(SMBsesssetupX);
1785 if (!server_info->ptok) {
1786 nt_status = create_local_token(server_info);
1788 if (!NT_STATUS_IS_OK(nt_status)) {
1789 DEBUG(10, ("create_local_token failed: %s\n",
1790 nt_errstr(nt_status)));
1791 data_blob_free(&nt_resp);
1792 data_blob_free(&lm_resp);
1793 data_blob_clear_free(&plaintext_password);
1794 reply_nterror(req, nt_status_squash(nt_status));
1795 END_PROFILE(SMBsesssetupX);
1800 data_blob_clear_free(&plaintext_password);
1802 /* it's ok - setup a reply */
1803 reply_outbuf(req, 3, 0);
1804 if (get_Protocol() >= PROTOCOL_NT1) {
1805 push_signature(&req->outbuf);
1806 /* perhaps grab OS version here?? */
1809 if (server_info->guest) {
1810 SSVAL(req->outbuf,smb_vwv2,1);
1813 /* register the name and uid as being validated, so further connections
1814 to a uid can get through without a password, on the same VC */
1816 if (lp_security() == SEC_SHARE) {
1817 sess_vuid = UID_FIELD_INVALID;
1818 TALLOC_FREE(server_info);
1820 /* Ignore the initial vuid. */
1821 sess_vuid = register_initial_vuid(sconn);
1822 if (sess_vuid == UID_FIELD_INVALID) {
1823 data_blob_free(&nt_resp);
1824 data_blob_free(&lm_resp);
1825 reply_nterror(req, nt_status_squash(
1826 NT_STATUS_LOGON_FAILURE));
1827 END_PROFILE(SMBsesssetupX);
1830 /* register_existing_vuid keeps the server info */
1831 sess_vuid = register_existing_vuid(sconn, sess_vuid,
1833 nt_resp.data ? nt_resp : lm_resp,
1835 if (sess_vuid == UID_FIELD_INVALID) {
1836 data_blob_free(&nt_resp);
1837 data_blob_free(&lm_resp);
1838 reply_nterror(req, nt_status_squash(
1839 NT_STATUS_LOGON_FAILURE));
1840 END_PROFILE(SMBsesssetupX);
1844 /* current_user_info is changed on new vuid */
1845 reload_services( True );
1848 data_blob_free(&nt_resp);
1849 data_blob_free(&lm_resp);
1851 SSVAL(req->outbuf,smb_uid,sess_vuid);
1852 SSVAL(req->inbuf,smb_uid,sess_vuid);
1853 req->vuid = sess_vuid;
1855 if (!sconn->smb1.sessions.done_sesssetup) {
1856 sconn->smb1.sessions.max_send =
1857 MIN(sconn->smb1.sessions.max_send,smb_bufsize);
1859 sconn->smb1.sessions.done_sesssetup = true;
1861 END_PROFILE(SMBsesssetupX);