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"
39 #include "lib/conn_tdb.h"
41 /****************************************************************************
42 Add the standard 'Samba' signature to the end of the session setup.
43 ****************************************************************************/
45 static int push_signature(uint8
**outbuf
)
52 tmp
= message_push_string(outbuf
, "Unix", STR_TERMINATE
);
54 if (tmp
== -1) return -1;
57 if (asprintf(&lanman
, "Samba %s", samba_version_string()) != -1) {
58 tmp
= message_push_string(outbuf
, lanman
, STR_TERMINATE
);
62 tmp
= message_push_string(outbuf
, "Samba", STR_TERMINATE
);
65 if (tmp
== -1) return -1;
68 tmp
= message_push_string(outbuf
, lp_workgroup(), STR_TERMINATE
);
70 if (tmp
== -1) return -1;
76 /****************************************************************************
77 Do a 'guest' logon, getting back the
78 ****************************************************************************/
80 static NTSTATUS
check_guest_password(const struct tsocket_address
*remote_address
,
82 struct auth_session_info
**session_info
)
84 struct auth4_context
*auth_context
;
85 struct auth_usersupplied_info
*user_info
= NULL
;
89 DEBUG(3,("Got anonymous request\n"));
91 nt_status
= make_auth4_context(talloc_tos(), &auth_context
);
92 if (!NT_STATUS_IS_OK(nt_status
)) {
96 auth_context
->get_ntlm_challenge(auth_context
,
99 if (!make_user_info_guest(remote_address
, &user_info
)) {
100 TALLOC_FREE(auth_context
);
101 return NT_STATUS_NO_MEMORY
;
104 nt_status
= auth_check_password_session_info(auth_context
,
105 mem_ctx
, user_info
, session_info
);
106 free_user_info(&user_info
);
107 TALLOC_FREE(auth_context
);
111 /****************************************************************************
112 Reply to a session setup command.
113 conn POINTER CAN BE NULL HERE !
114 ****************************************************************************/
116 static void reply_sesssetup_and_X_spnego(struct smb_request
*req
)
120 DATA_BLOB out_blob
= data_blob_null
;
123 const char *native_os
;
124 const char *native_lanman
;
125 const char *primary_domain
;
127 uint16 data_blob_len
= SVAL(req
->vwv
+7, 0);
128 enum remote_arch_types ra_type
= get_remote_arch();
129 uint64_t vuid
= req
->vuid
;
130 NTSTATUS status
= NT_STATUS_OK
;
131 struct smbd_server_connection
*sconn
= req
->sconn
;
133 NTTIME now
= timeval_to_nttime(&req
->request_time
);
134 struct smbXsrv_session
*session
= NULL
;
135 uint32_t client_caps
= IVAL(req
->vwv
+10, 0);
137 DEBUG(3,("Doing spnego session setup\n"));
139 if (global_client_caps
== 0) {
140 global_client_caps
= client_caps
;
142 if (!(global_client_caps
& CAP_STATUS32
)) {
143 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
149 if (data_blob_len
== 0) {
150 /* an invalid request */
151 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
155 bufrem
= smbreq_bufrem(req
, p
);
156 /* pull the spnego blob */
157 in_blob
= data_blob_const(p
, MIN(bufrem
, data_blob_len
));
160 file_save("negotiate.dat", in_blob
.data
, in_blob
.length
);
163 p2
= (const char *)req
->buf
+ in_blob
.length
;
165 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
167 native_os
= tmp
? tmp
: "";
169 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
171 native_lanman
= tmp
? tmp
: "";
173 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
175 primary_domain
= tmp
? tmp
: "";
177 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
178 native_os
, native_lanman
, primary_domain
));
180 if ( ra_type
== RA_WIN2K
) {
181 /* Vista sets neither the OS or lanman strings */
183 if ( !strlen(native_os
) && !strlen(native_lanman
) )
184 set_remote_arch(RA_VISTA
);
186 /* Windows 2003 doesn't set the native lanman string,
187 but does set primary domain which is a bug I think */
189 if ( !strlen(native_lanman
) ) {
190 ra_lanman_string( primary_domain
);
192 ra_lanman_string( native_lanman
);
194 } else if ( ra_type
== RA_VISTA
) {
195 if ( strncmp(native_os
, "Mac OS X", 8) == 0 ) {
196 set_remote_arch(RA_OSX
);
201 status
= smb1srv_session_lookup(sconn
->conn
,
204 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
205 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
208 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
209 status
= NT_STATUS_OK
;
211 if (NT_STATUS_IS_OK(status
)) {
212 session
->status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
213 status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
214 TALLOC_FREE(session
->gensec
);
216 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
217 reply_nterror(req
, nt_status_squash(status
));
222 if (session
== NULL
) {
223 /* create a new session */
224 status
= smbXsrv_session_create(sconn
->conn
,
226 if (!NT_STATUS_IS_OK(status
)) {
227 reply_nterror(req
, nt_status_squash(status
));
232 if (!session
->gensec
) {
233 status
= auth_generic_prepare(session
, sconn
->remote_address
,
235 if (!NT_STATUS_IS_OK(status
)) {
236 TALLOC_FREE(session
);
237 reply_nterror(req
, nt_status_squash(status
));
241 gensec_want_feature(session
->gensec
, GENSEC_FEATURE_SESSION_KEY
);
242 gensec_want_feature(session
->gensec
, GENSEC_FEATURE_UNIX_TOKEN
);
244 status
= gensec_start_mech_by_oid(session
->gensec
,
246 if (!NT_STATUS_IS_OK(status
)) {
247 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
248 TALLOC_FREE(session
);;
249 reply_nterror(req
, nt_status_squash(status
));
255 status
= gensec_update(session
->gensec
,
259 if (!NT_STATUS_IS_OK(status
) &&
260 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
261 TALLOC_FREE(session
);
262 reply_nterror(req
, nt_status_squash(status
));
266 if (NT_STATUS_IS_OK(status
) && session
->global
->auth_session_info
== NULL
) {
267 struct auth_session_info
*session_info
= NULL
;
269 status
= gensec_session_info(session
->gensec
,
272 if (!NT_STATUS_IS_OK(status
)) {
273 DEBUG(1,("Failed to generate session_info "
274 "(user and group token) for session setup: %s\n",
276 data_blob_free(&out_blob
);
277 TALLOC_FREE(session
);
278 reply_nterror(req
, nt_status_squash(status
));
282 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
286 session
->compat
= talloc_zero(session
, struct user_struct
);
287 if (session
->compat
== NULL
) {
288 data_blob_free(&out_blob
);
289 TALLOC_FREE(session
);
290 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
293 session
->compat
->session
= session
;
294 session
->compat
->homes_snum
= -1;
295 session
->compat
->session_info
= session_info
;
296 session
->compat
->session_keystr
= NULL
;
297 session
->compat
->vuid
= session
->global
->session_wire_id
;
298 DLIST_ADD(sconn
->users
, session
->compat
);
301 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
302 session
->compat
->homes_snum
=
303 register_homes_share(session_info
->unix_info
->unix_name
);
306 if (!session_claim(sconn
, session
->compat
)) {
307 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
308 (unsigned long long)session
->compat
->vuid
));
309 data_blob_free(&out_blob
);
310 TALLOC_FREE(session
);
311 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
315 if (srv_is_signing_negotiated(sconn
) && action
== 0) {
317 * Try and turn on server signing on the first non-guest
320 srv_set_signing(sconn
,
321 session_info
->session_key
,
325 set_current_user_info(session_info
->unix_info
->sanitized_username
,
326 session_info
->unix_info
->unix_name
,
327 session_info
->info
->domain_name
);
329 session
->status
= NT_STATUS_OK
;
330 session
->global
->auth_session_info
= talloc_move(session
->global
,
332 session
->global
->auth_session_info_seqnum
+= 1;
333 session
->global
->channels
[0].auth_session_info_seqnum
=
334 session
->global
->auth_session_info_seqnum
;
335 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
336 session
->global
->expiration_time
=
337 gensec_expire_time(session
->gensec
);
339 session
->global
->expiration_time
=
340 GENSEC_EXPIRE_TIME_INFINITY
;
343 status
= smbXsrv_session_update(session
);
344 if (!NT_STATUS_IS_OK(status
)) {
345 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
346 (unsigned long long)session
->compat
->vuid
,
348 data_blob_free(&out_blob
);
349 TALLOC_FREE(session
);
350 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
354 /* current_user_info is changed on new vuid */
355 reload_services(sconn
, conn_snum_used
, true);
356 } else if (NT_STATUS_IS_OK(status
)) {
357 struct auth_session_info
*session_info
= NULL
;
359 status
= gensec_session_info(session
->gensec
,
362 if (!NT_STATUS_IS_OK(status
)) {
363 DEBUG(1,("Failed to generate session_info "
364 "(user and group token) for session setup: %s\n",
366 data_blob_free(&out_blob
);
367 TALLOC_FREE(session
);
368 reply_nterror(req
, nt_status_squash(status
));
372 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
376 session
->compat
->session_info
= session_info
;
377 session
->compat
->vuid
= session
->global
->session_wire_id
;
379 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
380 session
->compat
->homes_snum
=
381 register_homes_share(session_info
->unix_info
->unix_name
);
384 set_current_user_info(session_info
->unix_info
->sanitized_username
,
385 session_info
->unix_info
->unix_name
,
386 session_info
->info
->domain_name
);
388 session
->status
= NT_STATUS_OK
;
389 TALLOC_FREE(session
->global
->auth_session_info
);
390 session
->global
->auth_session_info
= session_info
;
391 session
->global
->auth_session_info_seqnum
+= 1;
392 session
->global
->channels
[0].auth_session_info_seqnum
=
393 session
->global
->auth_session_info_seqnum
;
394 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
395 session
->global
->expiration_time
=
396 gensec_expire_time(session
->gensec
);
398 session
->global
->expiration_time
=
399 GENSEC_EXPIRE_TIME_INFINITY
;
402 status
= smbXsrv_session_update(session
);
403 if (!NT_STATUS_IS_OK(status
)) {
404 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
405 (unsigned long long)session
->compat
->vuid
,
407 data_blob_free(&out_blob
);
408 TALLOC_FREE(session
);
409 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
413 conn_clear_vuid_caches(sconn
, session
->compat
->vuid
);
415 /* current_user_info is changed on new vuid */
416 reload_services(sconn
, conn_snum_used
, true);
419 vuid
= session
->global
->session_wire_id
;
421 reply_outbuf(req
, 4, 0);
423 SSVAL(req
->outbuf
, smb_uid
, vuid
);
424 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(status
));
425 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
426 SSVAL(req
->outbuf
, smb_vwv2
, action
);
427 SSVAL(req
->outbuf
, smb_vwv3
, out_blob
.length
);
429 if (message_push_blob(&req
->outbuf
, out_blob
) == -1) {
430 data_blob_free(&out_blob
);
431 TALLOC_FREE(session
);
432 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
435 data_blob_free(&out_blob
);
437 if (push_signature(&req
->outbuf
) == -1) {
438 TALLOC_FREE(session
);
439 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
444 /****************************************************************************
445 On new VC == 0, shutdown *all* old connections and users.
446 It seems that only NT4.x does this. At W2K and above (XP etc.).
447 a new session setup with VC==0 is ignored.
448 ****************************************************************************/
450 struct shutdown_state
{
452 struct messaging_context
*msg_ctx
;
455 static int shutdown_other_smbds(const struct connections_key
*key
,
456 const struct connections_data
*crec
,
459 struct shutdown_state
*state
= (struct shutdown_state
*)private_data
;
460 struct server_id self_pid
= messaging_server_id(state
->msg_ctx
);
462 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
463 server_id_str(talloc_tos(), &crec
->pid
), crec
->addr
));
465 if (!process_exists(crec
->pid
)) {
466 DEBUG(10, ("process does not exist\n"));
470 if (serverid_equal(&crec
->pid
, &self_pid
)) {
471 DEBUG(10, ("It's me\n"));
475 if (strcmp(state
->ip
, crec
->addr
) != 0) {
476 DEBUG(10, ("%s does not match %s\n", state
->ip
, crec
->addr
));
480 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
481 "(IP %s)\n", (unsigned int)procid_to_pid(&crec
->pid
),
484 messaging_send(state
->msg_ctx
, crec
->pid
, MSG_SHUTDOWN
,
489 static void setup_new_vc_session(struct smbd_server_connection
*sconn
)
491 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
492 "compatible we would close all old resources.\n"));
495 invalidate_all_vuids();
497 if (lp_reset_on_zero_vc()) {
499 struct shutdown_state state
;
501 addr
= tsocket_address_inet_addr_string(
502 sconn
->remote_address
, talloc_tos());
507 state
.msg_ctx
= sconn
->msg_ctx
;
508 connections_forall_read(shutdown_other_smbds
, &state
);
513 /****************************************************************************
514 Reply to a session setup command.
515 ****************************************************************************/
517 void reply_sesssetup_and_X(struct smb_request
*req
)
523 DATA_BLOB plaintext_password
;
526 fstring sub_user
; /* Sanitised username for substituion */
528 const char *native_os
;
529 const char *native_lanman
;
530 const char *primary_domain
;
531 struct auth_usersupplied_info
*user_info
= NULL
;
532 struct auth_session_info
*session_info
= NULL
;
533 uint16 smb_flag2
= req
->flags2
;
535 NTTIME now
= timeval_to_nttime(&req
->request_time
);
536 struct smbXsrv_session
*session
= NULL
;
539 struct smbd_server_connection
*sconn
= req
->sconn
;
541 bool doencrypt
= sconn
->smb1
.negprot
.encrypted_passwords
;
542 bool signing_allowed
= false;
543 bool signing_mandatory
= false;
545 START_PROFILE(SMBsesssetupX
);
547 ZERO_STRUCT(lm_resp
);
548 ZERO_STRUCT(nt_resp
);
549 ZERO_STRUCT(plaintext_password
);
551 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
553 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
) {
554 signing_allowed
= true;
556 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) {
557 signing_mandatory
= true;
561 * We can call srv_set_signing_negotiated() each time.
562 * It finds out when it needs to turn into a noop
565 srv_set_signing_negotiated(req
->sconn
,
569 /* a SPNEGO session setup has 12 command words, whereas a normal
570 NT1 session setup has 13. See the cifs spec. */
571 if (req
->wct
== 12 &&
572 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
574 if (!sconn
->smb1
.negprot
.spnego
) {
575 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
576 "at SPNEGO session setup when it was not "
578 reply_nterror(req
, nt_status_squash(
579 NT_STATUS_LOGON_FAILURE
));
580 END_PROFILE(SMBsesssetupX
);
584 if (SVAL(req
->vwv
+4, 0) == 0) {
585 setup_new_vc_session(req
->sconn
);
588 reply_sesssetup_and_X_spnego(req
);
589 END_PROFILE(SMBsesssetupX
);
593 smb_bufsize
= SVAL(req
->vwv
+2, 0);
595 if (get_Protocol() < PROTOCOL_NT1
) {
596 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
598 /* Never do NT status codes with protocols before NT1 as we
599 * don't get client caps. */
600 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
602 if ((passlen1
> MAX_PASS_LEN
) || (passlen1
> req
->buflen
)) {
603 reply_nterror(req
, nt_status_squash(
604 NT_STATUS_INVALID_PARAMETER
));
605 END_PROFILE(SMBsesssetupX
);
610 lm_resp
= data_blob(req
->buf
, passlen1
);
612 plaintext_password
= data_blob(req
->buf
, passlen1
+1);
613 /* Ensure null termination */
614 plaintext_password
.data
[passlen1
] = 0;
617 srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
,
618 req
->buf
+ passlen1
, STR_TERMINATE
);
619 user
= tmp
? tmp
: "";
624 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
625 uint16 passlen2
= SVAL(req
->vwv
+8, 0);
626 enum remote_arch_types ra_type
= get_remote_arch();
627 const uint8_t *p
= req
->buf
;
628 const uint8_t *save_p
= req
->buf
;
632 if(global_client_caps
== 0) {
633 global_client_caps
= IVAL(req
->vwv
+11, 0);
635 if (!(global_client_caps
& CAP_STATUS32
)) {
636 remove_from_common_flags2(
637 FLAGS2_32_BIT_ERROR_CODES
);
640 /* client_caps is used as final determination if
641 * client is NT or Win95. This is needed to return
642 * the correct error codes in some circumstances.
645 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
646 ra_type
== RA_WIN95
) {
647 if(!(global_client_caps
& (CAP_NT_SMBS
|
649 set_remote_arch( RA_WIN95
);
655 /* both Win95 and WinNT stuff up the password
656 * lengths for non-encrypting systems. Uggh.
658 if passlen1==24 its a win95 system, and its setting
659 the password length incorrectly. Luckily it still
660 works with the default code because Win95 will null
661 terminate the password anyway
663 if passlen1>0 and passlen2>0 then maybe its a NT box
664 and its setting passlen2 to some random value which
665 really stuffs things up. we need to fix that one. */
667 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
673 /* check for nasty tricks */
674 if (passlen1
> MAX_PASS_LEN
675 || passlen1
> smbreq_bufrem(req
, p
)) {
676 reply_nterror(req
, nt_status_squash(
677 NT_STATUS_INVALID_PARAMETER
));
678 END_PROFILE(SMBsesssetupX
);
682 if (passlen2
> MAX_PASS_LEN
683 || passlen2
> smbreq_bufrem(req
, p
+passlen1
)) {
684 reply_nterror(req
, nt_status_squash(
685 NT_STATUS_INVALID_PARAMETER
));
686 END_PROFILE(SMBsesssetupX
);
690 /* Save the lanman2 password and the NT md4 password. */
692 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
697 lm_resp
= data_blob(p
, passlen1
);
698 nt_resp
= data_blob(p
+passlen1
, passlen2
);
701 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
703 if (unic
&& (passlen2
== 0) && passlen1
) {
704 /* Only a ascii plaintext password was sent. */
705 (void)srvstr_pull_talloc(talloc_tos(),
711 STR_TERMINATE
|STR_ASCII
);
713 (void)srvstr_pull_talloc(talloc_tos(),
718 unic
? passlen2
: passlen1
,
722 reply_nterror(req
, nt_status_squash(
723 NT_STATUS_INVALID_PARAMETER
));
724 END_PROFILE(SMBsesssetupX
);
727 plaintext_password
= data_blob(pass
, strlen(pass
)+1);
730 p
+= passlen1
+ passlen2
;
732 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
734 user
= tmp
? tmp
: "";
736 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
738 domain
= tmp
? tmp
: "";
740 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
742 native_os
= tmp
? tmp
: "";
744 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
746 native_lanman
= tmp
? tmp
: "";
748 /* not documented or decoded by Ethereal but there is one more
749 * string in the extra bytes which is the same as the
750 * PrimaryDomain when using extended security. Windows NT 4
751 * and 2003 use this string to store the native lanman string.
752 * Windows 9x does not include a string here at all so we have
753 * to check if we have any extra bytes left */
755 byte_count
= SVAL(req
->vwv
+13, 0);
756 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
757 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
759 primary_domain
= tmp
? tmp
: "";
761 primary_domain
= talloc_strdup(talloc_tos(), "null");
764 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
765 "PrimaryDomain=[%s]\n",
766 domain
, native_os
, native_lanman
, primary_domain
));
768 if ( ra_type
== RA_WIN2K
) {
769 if ( strlen(native_lanman
) == 0 )
770 ra_lanman_string( primary_domain
);
772 ra_lanman_string( native_lanman
);
777 if (SVAL(req
->vwv
+4, 0) == 0) {
778 setup_new_vc_session(req
->sconn
);
781 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
782 domain
, user
, get_remote_machine_name()));
785 if (sconn
->smb1
.negprot
.spnego
) {
787 /* This has to be here, because this is a perfectly
788 * valid behaviour for guest logons :-( */
790 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
791 "at 'normal' session setup after "
792 "negotiating spnego.\n"));
793 reply_nterror(req
, nt_status_squash(
794 NT_STATUS_LOGON_FAILURE
));
795 END_PROFILE(SMBsesssetupX
);
798 fstrcpy(sub_user
, user
);
800 fstrcpy(sub_user
, "");
803 sub_set_smb_name(sub_user
);
805 reload_services(sconn
, conn_snum_used
, true);
809 nt_status
= check_guest_password(sconn
->remote_address
, req
, &session_info
);
811 } else if (doencrypt
) {
812 struct auth4_context
*negprot_auth_context
= NULL
;
813 negprot_auth_context
= sconn
->smb1
.negprot
.auth_context
;
814 if (!negprot_auth_context
) {
815 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
816 "session setup without negprot denied!\n"));
817 reply_nterror(req
, nt_status_squash(
818 NT_STATUS_LOGON_FAILURE
));
819 END_PROFILE(SMBsesssetupX
);
822 nt_status
= make_user_info_for_reply_enc(&user_info
, user
,
824 sconn
->remote_address
,
826 if (NT_STATUS_IS_OK(nt_status
)) {
827 nt_status
= auth_check_password_session_info(negprot_auth_context
,
828 req
, user_info
, &session_info
);
831 struct auth4_context
*plaintext_auth_context
= NULL
;
833 nt_status
= make_auth4_context(
834 talloc_tos(), &plaintext_auth_context
);
836 if (NT_STATUS_IS_OK(nt_status
)) {
839 plaintext_auth_context
->get_ntlm_challenge(
840 plaintext_auth_context
, chal
);
842 if (!make_user_info_for_reply(&user_info
,
844 sconn
->remote_address
,
846 plaintext_password
)) {
847 nt_status
= NT_STATUS_NO_MEMORY
;
850 if (NT_STATUS_IS_OK(nt_status
)) {
851 nt_status
= auth_check_password_session_info(plaintext_auth_context
,
852 req
, user_info
, &session_info
);
854 TALLOC_FREE(plaintext_auth_context
);
858 free_user_info(&user_info
);
860 if (!NT_STATUS_IS_OK(nt_status
)) {
861 data_blob_free(&nt_resp
);
862 data_blob_free(&lm_resp
);
863 data_blob_clear_free(&plaintext_password
);
864 reply_nterror(req
, nt_status_squash(nt_status
));
865 END_PROFILE(SMBsesssetupX
);
869 data_blob_clear_free(&plaintext_password
);
871 /* it's ok - setup a reply */
872 reply_outbuf(req
, 3, 0);
873 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
874 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
876 if (get_Protocol() >= PROTOCOL_NT1
) {
877 push_signature(&req
->outbuf
);
878 /* perhaps grab OS version here?? */
881 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
885 /* register the name and uid as being validated, so further connections
886 to a uid can get through without a password, on the same VC */
888 nt_status
= smbXsrv_session_create(sconn
->conn
,
890 if (!NT_STATUS_IS_OK(nt_status
)) {
891 data_blob_free(&nt_resp
);
892 data_blob_free(&lm_resp
);
893 reply_nterror(req
, nt_status_squash(nt_status
));
894 END_PROFILE(SMBsesssetupX
);
898 session
->compat
= talloc_zero(session
, struct user_struct
);
899 if (session
->compat
== NULL
) {
900 data_blob_free(&nt_resp
);
901 data_blob_free(&lm_resp
);
902 TALLOC_FREE(session
);
903 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
904 END_PROFILE(SMBsesssetupX
);
907 session
->compat
->session
= session
;
908 session
->compat
->homes_snum
= -1;
909 session
->compat
->session_info
= session_info
;
910 session
->compat
->session_keystr
= NULL
;
911 session
->compat
->vuid
= session
->global
->session_wire_id
;
912 DLIST_ADD(sconn
->users
, session
->compat
);
915 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
916 session
->compat
->homes_snum
=
917 register_homes_share(session_info
->unix_info
->unix_name
);
920 if (!session_claim(sconn
, session
->compat
)) {
921 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
922 (unsigned long long)session
->compat
->vuid
));
923 data_blob_free(&nt_resp
);
924 data_blob_free(&lm_resp
);
925 TALLOC_FREE(session
);
926 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
927 END_PROFILE(SMBsesssetupX
);
931 if (srv_is_signing_negotiated(sconn
) && action
== 0) {
933 * Try and turn on server signing on the first non-guest
936 srv_set_signing(sconn
,
937 session_info
->session_key
,
938 nt_resp
.data
? nt_resp
: lm_resp
);
941 set_current_user_info(session_info
->unix_info
->sanitized_username
,
942 session_info
->unix_info
->unix_name
,
943 session_info
->info
->domain_name
);
945 session
->status
= NT_STATUS_OK
;
946 session
->global
->auth_session_info
= talloc_move(session
->global
,
948 session
->global
->auth_session_info_seqnum
+= 1;
949 session
->global
->channels
[0].auth_session_info_seqnum
=
950 session
->global
->auth_session_info_seqnum
;
951 session
->global
->expiration_time
= GENSEC_EXPIRE_TIME_INFINITY
;
953 nt_status
= smbXsrv_session_update(session
);
954 if (!NT_STATUS_IS_OK(nt_status
)) {
955 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
956 (unsigned long long)session
->compat
->vuid
,
957 nt_errstr(nt_status
)));
958 data_blob_free(&nt_resp
);
959 data_blob_free(&lm_resp
);
960 TALLOC_FREE(session
);
961 reply_nterror(req
, nt_status_squash(nt_status
));
962 END_PROFILE(SMBsesssetupX
);
966 /* current_user_info is changed on new vuid */
967 reload_services(sconn
, conn_snum_used
, true);
969 sess_vuid
= session
->global
->session_wire_id
;
971 data_blob_free(&nt_resp
);
972 data_blob_free(&lm_resp
);
974 SSVAL(req
->outbuf
,smb_vwv2
,action
);
975 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
976 SSVAL(discard_const_p(char, req
->inbuf
),smb_uid
,sess_vuid
);
977 req
->vuid
= sess_vuid
;
979 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
980 sconn
->smb1
.sessions
.max_send
=
981 MIN(sconn
->smb1
.sessions
.max_send
,smb_bufsize
);
983 sconn
->smb1
.sessions
.done_sesssetup
= true;
985 END_PROFILE(SMBsesssetupX
);