2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1998-2001
5 Copyright (C) Andrew Bartlett 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 uint32 global_client_caps = 0;
25 static struct auth_context *ntlmssp_auth_context = NULL;
28 on a logon error possibly map the error to success if "map to guest"
31 static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info,
32 const char *user, const char *domain)
34 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
35 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
36 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
37 DEBUG(3,("No such user %s [%s] - using guest account\n",
39 make_server_info_guest(server_info);
40 status = NT_STATUS_OK;
44 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
45 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
46 DEBUG(3,("Registered username %s for guest access\n",user));
47 make_server_info_guest(server_info);
48 status = NT_STATUS_OK;
56 /****************************************************************************
57 Add the standard 'Samba' signature to the end of the session setup.
58 ****************************************************************************/
59 static void add_signature(char *outbuf)
63 p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
64 p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
65 p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
66 set_message_end(outbuf,p);
69 /****************************************************************************
70 Do a 'guest' logon, getting back the
71 ****************************************************************************/
72 static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
74 struct auth_context *auth_context;
75 auth_usersupplied_info *user_info = NULL;
78 unsigned char chal[8];
82 DEBUG(3,("Got anonymous request\n"));
84 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
88 if (!make_user_info_guest(&user_info)) {
89 (auth_context->free)(&auth_context);
90 return NT_STATUS_NO_MEMORY;
93 nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
94 (auth_context->free)(&auth_context);
95 free_user_info(&user_info);
101 /****************************************************************************
102 reply to a session setup spnego negotiate packet for kerberos
103 ****************************************************************************/
104 static int reply_spnego_kerberos(connection_struct *conn,
105 char *inbuf, char *outbuf,
106 int length, int bufsize,
111 const struct passwd *pw;
116 auth_serversupplied_info *server_info = NULL;
119 if (!spnego_parse_krb5_wrap(*secblob, &ticket)) {
120 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
123 ads = ads_init_simple();
126 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
129 ads->auth.realm = strdup(lp_realm());
131 ret = ads_verify_ticket(ads, &ticket, &client, &auth_data);
132 if (!NT_STATUS_IS_OK(ret)) {
133 DEBUG(1,("Failed to verify incoming ticket!\n"));
135 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
138 DEBUG(3,("Ticket name is [%s]\n", client));
140 p = strchr_m(client, '@');
142 DEBUG(3,("Doesn't look like a valid principal\n"));
144 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
148 if (strcasecmp(p+1, ads->auth.realm) != 0) {
149 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
150 if (!lp_allow_trusted_domains()) {
151 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
153 /* this gives a fully qualified user name (ie. with full realm).
154 that leads to very long usernames, but what else can we do? */
155 asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client);
157 user = strdup(client);
161 /* the password is good - let them in */
162 pw = smb_getpwnam(user,False);
163 if (!pw && !strstr(user, lp_winbind_separator())) {
165 /* try it with a winbind domain prefix */
166 asprintf(&user2, "%s%s%s", lp_workgroup(), lp_winbind_separator(), user);
167 pw = smb_getpwnam(user2,False);
175 DEBUG(1,("Username %s is invalid on this system\n",user));
176 return ERROR_NT(NT_STATUS_NO_SUCH_USER);
179 if (!make_server_info_pw(&server_info,pw)) {
180 DEBUG(1,("make_server_info_from_pw failed!\n"));
181 return ERROR_NT(NT_STATUS_NO_MEMORY);
184 sess_vuid = register_vuid(server_info, user);
187 free_server_info(&server_info);
189 if (sess_vuid == -1) {
190 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
193 set_message(outbuf,4,0,True);
194 SSVAL(outbuf, smb_vwv3, 0);
195 add_signature(outbuf);
197 SSVAL(outbuf,smb_uid,sess_vuid);
198 SSVAL(inbuf,smb_uid,sess_vuid);
200 return chain_reply(inbuf,outbuf,length,bufsize);
205 /****************************************************************************
206 send a security blob via a session setup reply
207 ****************************************************************************/
208 static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
213 set_message(outbuf,4,0,True);
215 /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end
216 that we aren't finished yet */
218 SIVAL(outbuf, smb_rcls, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
219 SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
220 SSVAL(outbuf, smb_vwv3, blob.length);
222 memcpy(p, blob.data, blob.length);
224 p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
225 p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
226 p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
227 set_message_end(outbuf,p);
229 return send_smb(smbd_server_fd(),outbuf);
232 /****************************************************************************
233 reply to a session setup spnego negotiate packet
234 ****************************************************************************/
235 static int reply_spnego_negotiate(connection_struct *conn,
238 int length, int bufsize,
241 char *OIDs[ASN1_MAX_OIDS];
244 uint32 ntlmssp_command, neg_flags, chal_flags;
245 DATA_BLOB chal, spnego_chal, extra_data;
246 const uint8 *cryptkey;
247 BOOL got_kerberos = False;
249 extern pstring global_myname;
251 /* parse out the OIDs and the first sec blob */
252 if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
253 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
256 for (i=0;OIDs[i];i++) {
257 DEBUG(3,("Got OID %s\n", OIDs[i]));
258 if (strcmp(OID_KERBEROS5, OIDs[i]) == 0 ||
259 strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) {
264 DEBUG(3,("Got secblob of size %d\n", secblob.length));
268 int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
269 length, bufsize, &secblob);
270 data_blob_free(&secblob);
275 /* parse the NTLMSSP packet */
277 file_save("secblob.dat", secblob.data, secblob.length);
280 if (!msrpc_parse(&secblob, "CddB",
285 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
288 DEBUG(5, ("Extra data: \n"));
289 dump_data(5, extra_data.data, extra_data.length);
291 data_blob_free(&secblob);
292 data_blob_free(&extra_data);
294 if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
295 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
298 DEBUG(3,("Got neg_flags=0x%08x\n", neg_flags));
300 debug_ntlmssp_flags(neg_flags);
302 if (ntlmssp_auth_context) {
303 (ntlmssp_auth_context->free)(&ntlmssp_auth_context);
306 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&ntlmssp_auth_context))) {
307 return ERROR_NT(nt_status);
310 cryptkey = ntlmssp_auth_context->get_ntlm_challenge(ntlmssp_auth_context);
312 /* Give them the challenge. For now, ignore neg_flags and just
313 return the flags we want. Obviously this is not correct */
315 chal_flags = NTLMSSP_NEGOTIATE_UNICODE |
316 NTLMSSP_NEGOTIATE_LM_KEY |
317 NTLMSSP_NEGOTIATE_NTLM |
318 NTLMSSP_CHAL_TARGET_INFO;
321 DATA_BLOB domain_blob, netbios_blob, realm_blob;
323 msrpc_gen(&domain_blob,
327 msrpc_gen(&netbios_blob,
331 msrpc_gen(&realm_blob,
336 msrpc_gen(&chal, "CddddbBBBB",
343 domain_blob.data, domain_blob.length,
344 domain_blob.data, domain_blob.length,
345 netbios_blob.data, netbios_blob.length,
346 realm_blob.data, realm_blob.length);
348 data_blob_free(&domain_blob);
349 data_blob_free(&netbios_blob);
350 data_blob_free(&realm_blob);
353 if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) {
354 DEBUG(3,("Failed to generate challenge\n"));
355 data_blob_free(&chal);
356 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
359 /* now tell the client to send the auth packet */
360 reply_sesssetup_blob(conn, outbuf, spnego_chal);
362 data_blob_free(&chal);
363 data_blob_free(&spnego_chal);
365 /* and tell smbd that we have already replied to this packet */
370 /****************************************************************************
371 reply to a session setup spnego auth packet
372 ****************************************************************************/
373 static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
374 int length, int bufsize,
378 char *workgroup = NULL, *user = NULL, *machine = NULL;
379 DATA_BLOB lmhash, nthash, sess_key;
380 DATA_BLOB plaintext_password = data_blob(NULL, 0);
381 uint32 ntlmssp_command, neg_flags;
385 uint32 auth_flags = AUTH_FLAG_NONE;
386 auth_usersupplied_info *user_info = NULL;
387 auth_serversupplied_info *server_info = NULL;
389 /* we must have setup the auth context by now */
390 if (!ntlmssp_auth_context) {
391 DEBUG(2,("ntlmssp_auth_context is NULL in reply_spnego_auth\n"));
392 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
395 if (!spnego_parse_auth(blob1, &auth)) {
397 file_save("auth.dat", blob1.data, blob1.length);
399 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
402 /* now the NTLMSSP encoded auth hashes */
403 if (!msrpc_parse(&auth, "CdBBUUUBd",
413 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
416 data_blob_free(&auth);
417 data_blob_free(&sess_key);
419 DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n",
420 user, workgroup, machine, lmhash.length, nthash.length));
422 /* the client has given us its machine name (which we otherwise would not get on port 445).
423 we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
425 set_remote_machine_name(machine);
427 reload_services(True);
430 file_save("nthash1.dat", nthash.data, nthash.length);
431 file_save("lmhash1.dat", lmhash.data, lmhash.length);
435 auth_flags |= AUTH_FLAG_LM_RESP;
438 if (nthash.length == 24) {
439 auth_flags |= AUTH_FLAG_NTLM_RESP;
440 } else if (nthash.length > 24) {
441 auth_flags |= AUTH_FLAG_NTLMv2_RESP;
444 if (!make_user_info_map(&user_info,
450 return ERROR_NT(NT_STATUS_NO_MEMORY);
453 nt_status = ntlmssp_auth_context->check_ntlm_password(ntlmssp_auth_context, user_info, &server_info);
455 if (!NT_STATUS_IS_OK(nt_status)) {
456 nt_status = do_map_to_guest(nt_status, &server_info, user, workgroup);
459 SAFE_FREE(workgroup);
462 (ntlmssp_auth_context->free)(&ntlmssp_auth_context);
464 free_user_info(&user_info);
466 data_blob_free(&lmhash);
468 data_blob_free(&nthash);
470 if (!NT_STATUS_IS_OK(nt_status)) {
472 return ERROR_NT(nt_status_squash(nt_status));
475 as_guest = server_info->guest;
477 sess_vuid = register_vuid(server_info, user);
478 free_server_info(&server_info);
482 if (sess_vuid == -1) {
483 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
486 set_message(outbuf,4,0,True);
487 SSVAL(outbuf, smb_vwv3, 0);
490 SSVAL(outbuf,smb_vwv2,1);
493 add_signature(outbuf);
495 SSVAL(outbuf,smb_uid,sess_vuid);
496 SSVAL(inbuf,smb_uid,sess_vuid);
498 return chain_reply(inbuf,outbuf,length,bufsize);
502 /****************************************************************************
503 reply to a session setup spnego anonymous packet
504 ****************************************************************************/
505 static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf,
506 int length, int bufsize)
509 auth_serversupplied_info *server_info = NULL;
512 nt_status = check_guest_password(&server_info);
514 if (!NT_STATUS_IS_OK(nt_status)) {
515 return ERROR_NT(nt_status_squash(nt_status));
518 sess_vuid = register_vuid(server_info, lp_guestaccount());
520 free_server_info(&server_info);
522 if (sess_vuid == -1) {
523 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
526 set_message(outbuf,4,0,True);
527 SSVAL(outbuf, smb_vwv3, 0);
528 add_signature(outbuf);
530 SSVAL(outbuf,smb_uid,sess_vuid);
531 SSVAL(inbuf,smb_uid,sess_vuid);
533 return chain_reply(inbuf,outbuf,length,bufsize);
537 /****************************************************************************
538 reply to a session setup command
539 ****************************************************************************/
540 static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,char *outbuf,
541 int length,int bufsize)
547 DEBUG(3,("Doing spnego session setup\n"));
549 if (global_client_caps == 0) {
550 global_client_caps = IVAL(inbuf,smb_vwv10);
553 p = (uint8 *)smb_buf(inbuf);
555 if (SVAL(inbuf, smb_vwv7) == 0) {
556 /* an anonymous request */
557 return reply_spnego_anonymous(conn, inbuf, outbuf, length, bufsize);
560 /* pull the spnego blob */
561 blob1 = data_blob(p, SVAL(inbuf, smb_vwv7));
564 file_save("negotiate.dat", blob1.data, blob1.length);
567 if (blob1.data[0] == ASN1_APPLICATION(0)) {
568 /* its a negTokenTarg packet */
569 ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1);
570 data_blob_free(&blob1);
574 if (blob1.data[0] == ASN1_CONTEXT(1)) {
575 /* its a auth packet */
576 ret = reply_spnego_auth(conn, inbuf, outbuf, length, bufsize, blob1);
577 data_blob_free(&blob1);
581 /* what sort of packet is this? */
582 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
584 data_blob_free(&blob1);
586 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
590 /****************************************************************************
591 reply to a session setup command
592 ****************************************************************************/
593 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
594 int length,int bufsize)
600 DATA_BLOB plaintext_password;
602 pstring sub_user; /* Sainitised username for substituion */
605 fstring native_lanman;
606 static BOOL done_sesssetup = False;
607 extern BOOL global_encrypted_passwords_negotiated;
608 extern BOOL global_spnego_negotiated;
610 extern fstring remote_machine;
611 extern userdom_struct current_user_info;
614 auth_usersupplied_info *user_info = NULL;
615 extern struct auth_context *negprot_global_auth_context;
616 auth_serversupplied_info *server_info = NULL;
620 BOOL doencrypt = global_encrypted_passwords_negotiated;
622 START_PROFILE(SMBsesssetupX);
624 ZERO_STRUCT(lm_resp);
625 ZERO_STRUCT(nt_resp);
626 ZERO_STRUCT(plaintext_password);
628 DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));
630 /* a SPNEGO session setup has 12 command words, whereas a normal
631 NT1 session setup has 13. See the cifs spec. */
632 if (CVAL(inbuf, smb_wct) == 12 &&
633 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
634 if (!global_spnego_negotiated) {
635 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n"));
636 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
639 return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize);
642 smb_bufsize = SVAL(inbuf,smb_vwv2);
644 if (Protocol < PROTOCOL_NT1) {
645 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
646 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
647 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
651 lm_resp = data_blob(smb_buf(inbuf), passlen1);
653 plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
654 /* Ensure null termination */
655 plaintext_password.data[passlen1] = 0;
658 srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE);
662 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
663 uint16 passlen2 = SVAL(inbuf,smb_vwv8);
664 enum remote_arch_types ra_type = get_remote_arch();
665 char *p = smb_buf(inbuf);
667 if(global_client_caps == 0)
668 global_client_caps = IVAL(inbuf,smb_vwv11);
670 /* client_caps is used as final determination if client is NT or Win95.
671 This is needed to return the correct error codes in some
675 if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
676 if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
677 set_remote_arch( RA_WIN95);
682 /* both Win95 and WinNT stuff up the password lengths for
683 non-encrypting systems. Uggh.
685 if passlen1==24 its a win95 system, and its setting the
686 password length incorrectly. Luckily it still works with the
687 default code because Win95 will null terminate the password
690 if passlen1>0 and passlen2>0 then maybe its a NT box and its
691 setting passlen2 to some random value which really stuffs
692 things up. we need to fix that one. */
694 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
698 /* check for nasty tricks */
699 if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) {
700 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
703 if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) {
704 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
707 /* Save the lanman2 password and the NT md4 password. */
709 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
714 lm_resp = data_blob(p, passlen1);
715 nt_resp = data_blob(p+passlen1, passlen2);
718 srvstr_pull(inbuf, pass, smb_buf(inbuf),
719 sizeof(pass), passlen1, STR_TERMINATE);
720 plaintext_password = data_blob(pass, strlen(pass)+1);
723 p += passlen1 + passlen2;
724 p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE);
725 p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE);
726 p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE);
727 p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE);
728 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
729 domain,native_os,native_lanman));
732 /* don't allow for weird usernames or domains */
733 alpha_strcpy(user, user, ". _-$", sizeof(user));
734 alpha_strcpy(domain, domain, ". _-", sizeof(domain));
735 if (strstr(user, "..") || strstr(domain,"..")) {
736 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
739 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
742 if (global_spnego_negotiated) {
744 /* This has to be here, becouse this is a perfectly valid behaviour for guest logons :-( */
746 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
747 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
749 pstrcpy(sub_user, user);
751 pstrcpy(sub_user, lp_guestaccount());
754 pstrcpy(current_user_info.smb_name,sub_user);
756 reload_services(True);
758 if (lp_security() == SEC_SHARE) {
759 /* in share level we should ignore any passwords */
761 data_blob_free(&lm_resp);
762 data_blob_free(&nt_resp);
763 data_blob_clear_free(&plaintext_password);
765 map_username(sub_user);
766 add_session_user(sub_user);
767 /* Then force it to null for the benfit of the code below */
773 nt_status = check_guest_password(&server_info);
775 } else if (doencrypt) {
776 if (!make_user_info_for_reply_enc(&user_info,
779 nt_status = NT_STATUS_NO_MEMORY;
781 nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
786 struct auth_context *plaintext_auth_context = NULL;
788 if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
789 chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
791 if (!make_user_info_for_reply(&user_info,
793 plaintext_password)) {
794 nt_status = NT_STATUS_NO_MEMORY;
797 if (NT_STATUS_IS_OK(nt_status)) {
798 nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
802 (plaintext_auth_context->free)(&plaintext_auth_context);
807 free_user_info(&user_info);
809 data_blob_free(&lm_resp);
810 data_blob_free(&nt_resp);
811 data_blob_clear_free(&plaintext_password);
813 if (!NT_STATUS_IS_OK(nt_status)) {
814 nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
817 if (!NT_STATUS_IS_OK(nt_status)) {
818 return ERROR_NT(nt_status_squash(nt_status));
821 /* it's ok - setup a reply */
822 if (Protocol < PROTOCOL_NT1) {
823 set_message(outbuf,3,0,True);
825 set_message(outbuf,3,0,True);
826 add_signature(outbuf);
827 /* perhaps grab OS version here?? */
830 if (server_info->guest) {
831 SSVAL(outbuf,smb_vwv2,1);
834 /* register the name and uid as being validated, so further connections
835 to a uid can get through without a password, on the same VC */
837 sess_vuid = register_vuid(server_info, sub_user);
839 free_server_info(&server_info);
841 if (sess_vuid == -1) {
842 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
846 SSVAL(outbuf,smb_uid,sess_vuid);
847 SSVAL(inbuf,smb_uid,sess_vuid);
850 max_send = MIN(max_send,smb_bufsize);
852 done_sesssetup = True;
854 END_PROFILE(SMBsesssetupX);
855 return chain_reply(inbuf,outbuf,length,bufsize);