2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1998-2001
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
7 Copyright (C) Luke Howard 2003
8 Copyright (C) Volker Lendecke 2007
9 Copyright (C) Jeremy Allison 2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "../lib/tsocket/tsocket.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "../libcli/auth/spnego.h"
30 #include "../auth/ntlmssp/ntlmssp.h"
31 #include "../librpc/gen_ndr/krb5pac.h"
32 #include "libads/kerberos_proto.h"
33 #include "../lib/util/asn1.h"
36 #include "smbprofile.h"
37 #include "../libcli/security/security.h"
38 #include "auth/gensec/gensec.h"
40 /****************************************************************************
41 Add the standard 'Samba' signature to the end of the session setup.
42 ****************************************************************************/
44 static int push_signature(uint8
**outbuf
)
51 tmp
= message_push_string(outbuf
, "Unix", STR_TERMINATE
);
53 if (tmp
== -1) return -1;
56 if (asprintf(&lanman
, "Samba %s", samba_version_string()) != -1) {
57 tmp
= message_push_string(outbuf
, lanman
, STR_TERMINATE
);
61 tmp
= message_push_string(outbuf
, "Samba", STR_TERMINATE
);
64 if (tmp
== -1) return -1;
67 tmp
= message_push_string(outbuf
, lp_workgroup(), STR_TERMINATE
);
69 if (tmp
== -1) return -1;
75 /****************************************************************************
76 Do a 'guest' logon, getting back the
77 ****************************************************************************/
79 static NTSTATUS
check_guest_password(const struct tsocket_address
*remote_address
,
80 struct auth_serversupplied_info
**server_info
)
82 struct auth_context
*auth_context
;
83 struct auth_usersupplied_info
*user_info
= NULL
;
86 static unsigned char chal
[8] = { 0, };
88 DEBUG(3,("Got anonymous request\n"));
90 nt_status
= make_auth_context_fixed(talloc_tos(), &auth_context
, chal
);
91 if (!NT_STATUS_IS_OK(nt_status
)) {
95 if (!make_user_info_guest(remote_address
, &user_info
)) {
96 TALLOC_FREE(auth_context
);
97 return NT_STATUS_NO_MEMORY
;
100 nt_status
= auth_context
->check_ntlm_password(auth_context
,
103 TALLOC_FREE(auth_context
);
104 free_user_info(&user_info
);
108 /****************************************************************************
109 Reply to a session setup command.
110 conn POINTER CAN BE NULL HERE !
111 ****************************************************************************/
113 static void reply_sesssetup_and_X_spnego(struct smb_request
*req
)
117 DATA_BLOB out_blob
= data_blob_null
;
120 const char *native_os
;
121 const char *native_lanman
;
122 const char *primary_domain
;
124 uint16 data_blob_len
= SVAL(req
->vwv
+7, 0);
125 enum remote_arch_types ra_type
= get_remote_arch();
126 int vuid
= req
->vuid
;
127 user_struct
*vuser
= NULL
;
128 NTSTATUS status
= NT_STATUS_OK
;
129 struct smbd_server_connection
*sconn
= req
->sconn
;
132 DEBUG(3,("Doing spnego session setup\n"));
134 if (global_client_caps
== 0) {
135 global_client_caps
= IVAL(req
->vwv
+10, 0);
137 if (!(global_client_caps
& CAP_STATUS32
)) {
138 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
144 if (data_blob_len
== 0) {
145 /* an invalid request */
146 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
150 bufrem
= smbreq_bufrem(req
, p
);
151 /* pull the spnego blob */
152 in_blob
= data_blob_const(p
, MIN(bufrem
, data_blob_len
));
155 file_save("negotiate.dat", in_blob
.data
, in_blob
.length
);
158 p2
= (const char *)req
->buf
+ in_blob
.length
;
160 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
162 native_os
= tmp
? tmp
: "";
164 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
166 native_lanman
= tmp
? tmp
: "";
168 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
170 primary_domain
= tmp
? tmp
: "";
172 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
173 native_os
, native_lanman
, primary_domain
));
175 if ( ra_type
== RA_WIN2K
) {
176 /* Vista sets neither the OS or lanman strings */
178 if ( !strlen(native_os
) && !strlen(native_lanman
) )
179 set_remote_arch(RA_VISTA
);
181 /* Windows 2003 doesn't set the native lanman string,
182 but does set primary domain which is a bug I think */
184 if ( !strlen(native_lanman
) ) {
185 ra_lanman_string( primary_domain
);
187 ra_lanman_string( native_lanman
);
189 } else if ( ra_type
== RA_VISTA
) {
190 if ( strncmp(native_os
, "Mac OS X", 8) == 0 ) {
191 set_remote_arch(RA_OSX
);
195 vuser
= get_valid_user_struct(sconn
, vuid
);
197 reply_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
201 /* Do we have a valid vuid now ? */
202 if (!is_partial_auth_vuid(sconn
, vuid
)) {
203 /* No, start a new authentication setup. */
204 vuid
= register_initial_vuid(sconn
);
205 if (vuid
== UID_FIELD_INVALID
) {
206 reply_nterror(req
, nt_status_squash(
207 NT_STATUS_INVALID_PARAMETER
));
212 vuser
= get_partial_auth_user_struct(sconn
, vuid
);
213 /* This MUST be valid. */
215 smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
218 if (!vuser
->gensec_security
) {
219 status
= auth_generic_prepare(vuser
, sconn
->remote_address
,
220 &vuser
->gensec_security
);
221 if (!NT_STATUS_IS_OK(status
)) {
222 /* Kill the intermediate vuid */
223 invalidate_vuid(sconn
, vuid
);
224 reply_nterror(req
, nt_status_squash(status
));
228 gensec_want_feature(vuser
->gensec_security
, GENSEC_FEATURE_SESSION_KEY
);
229 gensec_want_feature(vuser
->gensec_security
, GENSEC_FEATURE_UNIX_TOKEN
);
231 status
= gensec_start_mech_by_oid(vuser
->gensec_security
, GENSEC_OID_SPNEGO
);
232 if (!NT_STATUS_IS_OK(status
)) {
233 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
234 /* Kill the intermediate vuid */
235 invalidate_vuid(sconn
, vuid
);
236 reply_nterror(req
, nt_status_squash(status
));
241 status
= gensec_update(vuser
->gensec_security
,
244 if (!NT_STATUS_IS_OK(status
) &&
245 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
246 /* Kill the intermediate vuid */
247 invalidate_vuid(sconn
, vuid
);
248 reply_nterror(req
, nt_status_squash(status
));
252 if (NT_STATUS_IS_OK(status
)) {
253 struct auth_session_info
*session_info
= NULL
;
256 status
= gensec_session_info(vuser
->gensec_security
,
259 if (!NT_STATUS_IS_OK(status
)) {
260 DEBUG(1,("Failed to generate session_info "
261 "(user and group token) for session setup: %s\n",
263 /* Kill the intermediate vuid */
264 data_blob_free(&out_blob
);
265 invalidate_vuid(sconn
, vuid
);
266 reply_nterror(req
, nt_status_squash(status
));
270 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
274 /* register_existing_vuid keeps the server info */
275 tmp_vuid
= register_existing_vuid(sconn
, vuid
,
278 if (tmp_vuid
!= vuid
) {
279 data_blob_free(&out_blob
);
280 invalidate_vuid(sconn
, vuid
);
281 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
285 /* current_user_info is changed on new vuid */
286 reload_services(sconn
, conn_snum_used
, true);
289 reply_outbuf(req
, 4, 0);
291 SSVAL(req
->outbuf
, smb_uid
, vuid
);
292 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(status
));
293 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
294 SSVAL(req
->outbuf
, smb_vwv2
, action
);
295 SSVAL(req
->outbuf
, smb_vwv3
, out_blob
.length
);
297 if (message_push_blob(&req
->outbuf
, out_blob
) == -1) {
298 data_blob_free(&out_blob
);
299 invalidate_vuid(sconn
, vuid
);
300 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
303 data_blob_free(&out_blob
);
305 if (push_signature(&req
->outbuf
) == -1) {
306 invalidate_vuid(sconn
, vuid
);
307 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
312 /****************************************************************************
313 On new VC == 0, shutdown *all* old connections and users.
314 It seems that only NT4.x does this. At W2K and above (XP etc.).
315 a new session setup with VC==0 is ignored.
316 ****************************************************************************/
318 struct shutdown_state
{
320 struct messaging_context
*msg_ctx
;
323 static int shutdown_other_smbds(const struct connections_key
*key
,
324 const struct connections_data
*crec
,
327 struct shutdown_state
*state
= (struct shutdown_state
*)private_data
;
329 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
330 server_id_str(talloc_tos(), &crec
->pid
), crec
->addr
));
332 if (!process_exists(crec
->pid
)) {
333 DEBUG(10, ("process does not exist\n"));
337 if (procid_is_me(&crec
->pid
)) {
338 DEBUG(10, ("It's me\n"));
342 if (strcmp(state
->ip
, crec
->addr
) != 0) {
343 DEBUG(10, ("%s does not match %s\n", state
->ip
, crec
->addr
));
347 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
348 "(IP %s)\n", (unsigned int)procid_to_pid(&crec
->pid
),
351 messaging_send(state
->msg_ctx
, crec
->pid
, MSG_SHUTDOWN
,
356 static void setup_new_vc_session(struct smbd_server_connection
*sconn
)
358 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
359 "compatible we would close all old resources.\n"));
362 invalidate_all_vuids();
364 if (lp_reset_on_zero_vc()) {
366 struct shutdown_state state
;
368 addr
= tsocket_address_inet_addr_string(
369 sconn
->remote_address
, talloc_tos());
374 state
.msg_ctx
= sconn
->msg_ctx
;
375 connections_forall_read(shutdown_other_smbds
, &state
);
380 /****************************************************************************
381 Reply to a session setup command.
382 ****************************************************************************/
384 void reply_sesssetup_and_X(struct smb_request
*req
)
390 DATA_BLOB plaintext_password
;
393 fstring sub_user
; /* Sanitised username for substituion */
395 const char *native_os
;
396 const char *native_lanman
;
397 const char *primary_domain
;
398 struct auth_usersupplied_info
*user_info
= NULL
;
399 struct auth_serversupplied_info
*server_info
= NULL
;
400 struct auth_session_info
*session_info
= NULL
;
401 uint16 smb_flag2
= req
->flags2
;
404 struct smbd_server_connection
*sconn
= req
->sconn
;
406 bool doencrypt
= sconn
->smb1
.negprot
.encrypted_passwords
;
407 bool signing_allowed
= false;
408 bool signing_mandatory
= false;
410 START_PROFILE(SMBsesssetupX
);
412 ZERO_STRUCT(lm_resp
);
413 ZERO_STRUCT(nt_resp
);
414 ZERO_STRUCT(plaintext_password
);
416 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
418 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
) {
419 signing_allowed
= true;
421 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) {
422 signing_mandatory
= true;
426 * We can call srv_set_signing_negotiated() each time.
427 * It finds out when it needs to turn into a noop
430 srv_set_signing_negotiated(req
->sconn
,
434 /* a SPNEGO session setup has 12 command words, whereas a normal
435 NT1 session setup has 13. See the cifs spec. */
436 if (req
->wct
== 12 &&
437 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
439 if (!sconn
->smb1
.negprot
.spnego
) {
440 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
441 "at SPNEGO session setup when it was not "
443 reply_nterror(req
, nt_status_squash(
444 NT_STATUS_LOGON_FAILURE
));
445 END_PROFILE(SMBsesssetupX
);
449 if (SVAL(req
->vwv
+4, 0) == 0) {
450 setup_new_vc_session(req
->sconn
);
453 reply_sesssetup_and_X_spnego(req
);
454 END_PROFILE(SMBsesssetupX
);
458 smb_bufsize
= SVAL(req
->vwv
+2, 0);
460 if (get_Protocol() < PROTOCOL_NT1
) {
461 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
463 /* Never do NT status codes with protocols before NT1 as we
464 * don't get client caps. */
465 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
467 if ((passlen1
> MAX_PASS_LEN
) || (passlen1
> req
->buflen
)) {
468 reply_nterror(req
, nt_status_squash(
469 NT_STATUS_INVALID_PARAMETER
));
470 END_PROFILE(SMBsesssetupX
);
475 lm_resp
= data_blob(req
->buf
, passlen1
);
477 plaintext_password
= data_blob(req
->buf
, passlen1
+1);
478 /* Ensure null termination */
479 plaintext_password
.data
[passlen1
] = 0;
482 srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
,
483 req
->buf
+ passlen1
, STR_TERMINATE
);
484 user
= tmp
? tmp
: "";
489 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
490 uint16 passlen2
= SVAL(req
->vwv
+8, 0);
491 enum remote_arch_types ra_type
= get_remote_arch();
492 const uint8_t *p
= req
->buf
;
493 const uint8_t *save_p
= req
->buf
;
497 if(global_client_caps
== 0) {
498 global_client_caps
= IVAL(req
->vwv
+11, 0);
500 if (!(global_client_caps
& CAP_STATUS32
)) {
501 remove_from_common_flags2(
502 FLAGS2_32_BIT_ERROR_CODES
);
505 /* client_caps is used as final determination if
506 * client is NT or Win95. This is needed to return
507 * the correct error codes in some circumstances.
510 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
511 ra_type
== RA_WIN95
) {
512 if(!(global_client_caps
& (CAP_NT_SMBS
|
514 set_remote_arch( RA_WIN95
);
520 /* both Win95 and WinNT stuff up the password
521 * lengths for non-encrypting systems. Uggh.
523 if passlen1==24 its a win95 system, and its setting
524 the password length incorrectly. Luckily it still
525 works with the default code because Win95 will null
526 terminate the password anyway
528 if passlen1>0 and passlen2>0 then maybe its a NT box
529 and its setting passlen2 to some random value which
530 really stuffs things up. we need to fix that one. */
532 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
538 /* check for nasty tricks */
539 if (passlen1
> MAX_PASS_LEN
540 || passlen1
> smbreq_bufrem(req
, p
)) {
541 reply_nterror(req
, nt_status_squash(
542 NT_STATUS_INVALID_PARAMETER
));
543 END_PROFILE(SMBsesssetupX
);
547 if (passlen2
> MAX_PASS_LEN
548 || passlen2
> smbreq_bufrem(req
, p
+passlen1
)) {
549 reply_nterror(req
, nt_status_squash(
550 NT_STATUS_INVALID_PARAMETER
));
551 END_PROFILE(SMBsesssetupX
);
555 /* Save the lanman2 password and the NT md4 password. */
557 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
562 lm_resp
= data_blob(p
, passlen1
);
563 nt_resp
= data_blob(p
+passlen1
, passlen2
);
566 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
568 if (unic
&& (passlen2
== 0) && passlen1
) {
569 /* Only a ascii plaintext password was sent. */
570 (void)srvstr_pull_talloc(talloc_tos(),
576 STR_TERMINATE
|STR_ASCII
);
578 (void)srvstr_pull_talloc(talloc_tos(),
583 unic
? passlen2
: passlen1
,
587 reply_nterror(req
, nt_status_squash(
588 NT_STATUS_INVALID_PARAMETER
));
589 END_PROFILE(SMBsesssetupX
);
592 plaintext_password
= data_blob(pass
, strlen(pass
)+1);
595 p
+= passlen1
+ passlen2
;
597 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
599 user
= tmp
? tmp
: "";
601 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
603 domain
= tmp
? tmp
: "";
605 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
607 native_os
= tmp
? tmp
: "";
609 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
611 native_lanman
= tmp
? tmp
: "";
613 /* not documented or decoded by Ethereal but there is one more
614 * string in the extra bytes which is the same as the
615 * PrimaryDomain when using extended security. Windows NT 4
616 * and 2003 use this string to store the native lanman string.
617 * Windows 9x does not include a string here at all so we have
618 * to check if we have any extra bytes left */
620 byte_count
= SVAL(req
->vwv
+13, 0);
621 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
622 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
624 primary_domain
= tmp
? tmp
: "";
626 primary_domain
= talloc_strdup(talloc_tos(), "null");
629 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
630 "PrimaryDomain=[%s]\n",
631 domain
, native_os
, native_lanman
, primary_domain
));
633 if ( ra_type
== RA_WIN2K
) {
634 if ( strlen(native_lanman
) == 0 )
635 ra_lanman_string( primary_domain
);
637 ra_lanman_string( native_lanman
);
642 if (SVAL(req
->vwv
+4, 0) == 0) {
643 setup_new_vc_session(req
->sconn
);
646 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
647 domain
, user
, get_remote_machine_name()));
650 if (sconn
->smb1
.negprot
.spnego
) {
652 /* This has to be here, because this is a perfectly
653 * valid behaviour for guest logons :-( */
655 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
656 "at 'normal' session setup after "
657 "negotiating spnego.\n"));
658 reply_nterror(req
, nt_status_squash(
659 NT_STATUS_LOGON_FAILURE
));
660 END_PROFILE(SMBsesssetupX
);
663 fstrcpy(sub_user
, user
);
665 fstrcpy(sub_user
, "");
668 sub_set_smb_name(sub_user
);
670 reload_services(sconn
, conn_snum_used
, true);
674 nt_status
= check_guest_password(sconn
->remote_address
, &server_info
);
676 } else if (doencrypt
) {
677 struct auth_context
*negprot_auth_context
= NULL
;
678 negprot_auth_context
= sconn
->smb1
.negprot
.auth_context
;
679 if (!negprot_auth_context
) {
680 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
681 "session setup without negprot denied!\n"));
682 reply_nterror(req
, nt_status_squash(
683 NT_STATUS_LOGON_FAILURE
));
684 END_PROFILE(SMBsesssetupX
);
687 nt_status
= make_user_info_for_reply_enc(&user_info
, user
,
689 sconn
->remote_address
,
691 if (NT_STATUS_IS_OK(nt_status
)) {
692 nt_status
= negprot_auth_context
->check_ntlm_password(
693 negprot_auth_context
,
698 struct auth_context
*plaintext_auth_context
= NULL
;
700 nt_status
= make_auth_context_subsystem(
701 talloc_tos(), &plaintext_auth_context
);
703 if (NT_STATUS_IS_OK(nt_status
)) {
706 plaintext_auth_context
->get_ntlm_challenge(
707 plaintext_auth_context
, chal
);
709 if (!make_user_info_for_reply(&user_info
,
711 sconn
->remote_address
,
713 plaintext_password
)) {
714 nt_status
= NT_STATUS_NO_MEMORY
;
717 if (NT_STATUS_IS_OK(nt_status
)) {
718 nt_status
= plaintext_auth_context
->check_ntlm_password(
719 plaintext_auth_context
,
723 TALLOC_FREE(plaintext_auth_context
);
728 free_user_info(&user_info
);
730 if (!NT_STATUS_IS_OK(nt_status
)) {
731 nt_status
= do_map_to_guest_server_info(nt_status
, &server_info
,
735 if (!NT_STATUS_IS_OK(nt_status
)) {
736 data_blob_free(&nt_resp
);
737 data_blob_free(&lm_resp
);
738 data_blob_clear_free(&plaintext_password
);
739 reply_nterror(req
, nt_status_squash(nt_status
));
740 END_PROFILE(SMBsesssetupX
);
744 nt_status
= create_local_token(req
, server_info
, NULL
, sub_user
, &session_info
);
745 TALLOC_FREE(server_info
);
747 if (!NT_STATUS_IS_OK(nt_status
)) {
748 DEBUG(10, ("create_local_token failed: %s\n",
749 nt_errstr(nt_status
)));
750 data_blob_free(&nt_resp
);
751 data_blob_free(&lm_resp
);
752 data_blob_clear_free(&plaintext_password
);
753 reply_nterror(req
, nt_status_squash(nt_status
));
754 END_PROFILE(SMBsesssetupX
);
758 data_blob_clear_free(&plaintext_password
);
760 /* it's ok - setup a reply */
761 reply_outbuf(req
, 3, 0);
762 if (get_Protocol() >= PROTOCOL_NT1
) {
763 push_signature(&req
->outbuf
);
764 /* perhaps grab OS version here?? */
767 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
768 SSVAL(req
->outbuf
,smb_vwv2
,1);
771 /* register the name and uid as being validated, so further connections
772 to a uid can get through without a password, on the same VC */
774 /* Ignore the initial vuid. */
775 sess_vuid
= register_initial_vuid(sconn
);
776 if (sess_vuid
== UID_FIELD_INVALID
) {
777 data_blob_free(&nt_resp
);
778 data_blob_free(&lm_resp
);
779 reply_nterror(req
, nt_status_squash(
780 NT_STATUS_LOGON_FAILURE
));
781 END_PROFILE(SMBsesssetupX
);
784 /* register_existing_vuid keeps the session_info */
785 sess_vuid
= register_existing_vuid(sconn
, sess_vuid
,
787 nt_resp
.data
? nt_resp
: lm_resp
);
788 if (sess_vuid
== UID_FIELD_INVALID
) {
789 data_blob_free(&nt_resp
);
790 data_blob_free(&lm_resp
);
791 reply_nterror(req
, nt_status_squash(
792 NT_STATUS_LOGON_FAILURE
));
793 END_PROFILE(SMBsesssetupX
);
797 /* current_user_info is changed on new vuid */
798 reload_services(sconn
, conn_snum_used
, true);
800 data_blob_free(&nt_resp
);
801 data_blob_free(&lm_resp
);
803 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
804 SSVAL(discard_const_p(char, req
->inbuf
),smb_uid
,sess_vuid
);
805 req
->vuid
= sess_vuid
;
807 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
808 sconn
->smb1
.sessions
.max_send
=
809 MIN(sconn
->smb1
.sessions
.max_send
,smb_bufsize
);
811 sconn
->smb1
.sessions
.done_sesssetup
= true;
813 END_PROFILE(SMBsesssetupX
);