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 "lib/util/server_id.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
32 #include "smbprofile.h"
33 #include "../libcli/security/security.h"
34 #include "auth/gensec/gensec.h"
35 #include "../libcli/smb/smb_signing.h"
36 #include "lib/util/string_wrappers.h"
37 #include "source3/lib/substitute.h"
39 /****************************************************************************
40 Add the standard 'Samba' signature to the end of the session setup.
41 ****************************************************************************/
43 static int push_signature(uint8_t **outbuf
)
51 fstr_sprintf(native_os
, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
,
52 SAMBA_MINOR_NBT_ANNOUNCE_VERSION
);
54 tmp
= message_push_string(outbuf
, native_os
, STR_TERMINATE
);
56 if (tmp
== -1) return -1;
59 if (asprintf(&lanman
, "Samba %s", samba_version_string()) != -1) {
60 tmp
= message_push_string(outbuf
, lanman
, STR_TERMINATE
);
64 tmp
= message_push_string(outbuf
, "Samba", STR_TERMINATE
);
67 if (tmp
== -1) return -1;
70 tmp
= message_push_string(outbuf
, lp_workgroup(), STR_TERMINATE
);
72 if (tmp
== -1) return -1;
78 /****************************************************************************
79 Reply to a session setup command.
80 conn POINTER CAN BE NULL HERE !
81 ****************************************************************************/
83 static void reply_sesssetup_and_X_spnego(struct smb_request
*req
)
87 DATA_BLOB out_blob
= data_blob_null
;
90 const char *native_os
;
91 const char *native_lanman
;
92 const char *primary_domain
;
93 uint16_t data_blob_len
= SVAL(req
->vwv
+7, 0);
94 enum remote_arch_types ra_type
= get_remote_arch();
95 uint64_t vuid
= req
->vuid
;
96 NTSTATUS status
= NT_STATUS_OK
;
97 struct smbXsrv_connection
*xconn
= req
->xconn
;
98 struct smbd_server_connection
*sconn
= req
->sconn
;
100 bool is_authenticated
= false;
101 NTTIME now
= timeval_to_nttime(&req
->request_time
);
102 struct smbXsrv_session
*session
= NULL
;
103 uint16_t smb_bufsize
= SVAL(req
->vwv
+2, 0);
104 uint32_t client_caps
= IVAL(req
->vwv
+10, 0);
105 struct smbXsrv_session_auth0
*auth
;
107 DEBUG(3,("Doing spnego session setup\n"));
109 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
110 global_client_caps
= client_caps
;
112 if (!(global_client_caps
& CAP_STATUS32
)) {
113 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
119 if (data_blob_len
== 0) {
120 /* an invalid request */
121 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
125 bufrem
= smbreq_bufrem(req
, p
);
126 /* pull the spnego blob */
127 in_blob
= data_blob_const(p
, MIN(bufrem
, data_blob_len
));
130 file_save("negotiate.dat", in_blob
.data
, in_blob
.length
);
133 p
= req
->buf
+ in_blob
.length
;
135 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
137 native_os
= tmp
? tmp
: "";
139 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
141 native_lanman
= tmp
? tmp
: "";
143 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
145 primary_domain
= tmp
? tmp
: "";
147 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
148 native_os
, native_lanman
, primary_domain
));
150 if ( ra_type
== RA_WIN2K
) {
151 /* Vista sets neither the OS or lanman strings */
153 if ( !strlen(native_os
) && !strlen(native_lanman
) )
154 set_remote_arch(RA_VISTA
);
156 /* Windows 2003 doesn't set the native lanman string,
157 but does set primary domain which is a bug I think */
159 if ( !strlen(native_lanman
) ) {
160 ra_lanman_string( primary_domain
);
162 ra_lanman_string( native_lanman
);
164 } else if ( ra_type
== RA_VISTA
) {
165 if ( strncmp(native_os
, "Mac OS X", 8) == 0 ) {
166 set_remote_arch(RA_OSX
);
171 status
= smb1srv_session_lookup(xconn
,
174 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
175 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
178 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
179 status
= NT_STATUS_OK
;
181 if (NT_STATUS_IS_OK(status
)) {
182 session
->status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
183 status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
184 TALLOC_FREE(session
->pending_auth
);
186 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
187 reply_nterror(req
, nt_status_squash(status
));
192 if (session
== NULL
) {
193 /* create a new session */
194 status
= smbXsrv_session_create(xconn
,
196 if (!NT_STATUS_IS_OK(status
)) {
197 reply_nterror(req
, nt_status_squash(status
));
202 status
= smbXsrv_session_find_auth(session
, xconn
, now
, &auth
);
203 if (!NT_STATUS_IS_OK(status
)) {
204 status
= smbXsrv_session_create_auth(session
, xconn
, now
,
208 if (!NT_STATUS_IS_OK(status
)) {
209 reply_nterror(req
, nt_status_squash(status
));
214 if (auth
->gensec
== NULL
) {
215 status
= auth_generic_prepare(session
,
216 xconn
->remote_address
,
217 xconn
->local_address
,
220 if (!NT_STATUS_IS_OK(status
)) {
221 TALLOC_FREE(session
);
222 reply_nterror(req
, nt_status_squash(status
));
226 gensec_want_feature(auth
->gensec
, GENSEC_FEATURE_SESSION_KEY
);
227 gensec_want_feature(auth
->gensec
, GENSEC_FEATURE_UNIX_TOKEN
);
228 gensec_want_feature(auth
->gensec
, GENSEC_FEATURE_SMB_TRANSPORT
);
230 status
= gensec_start_mech_by_oid(auth
->gensec
,
232 if (!NT_STATUS_IS_OK(status
)) {
233 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
234 TALLOC_FREE(session
);;
235 reply_nterror(req
, nt_status_squash(status
));
241 status
= gensec_update(auth
->gensec
,
245 if (!NT_STATUS_IS_OK(status
) &&
246 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
247 TALLOC_FREE(session
);
248 reply_nterror(req
, nt_status_squash(status
));
252 if (NT_STATUS_IS_OK(status
) && session
->global
->auth_session_info
== NULL
) {
253 struct auth_session_info
*session_info
= NULL
;
255 status
= gensec_session_info(auth
->gensec
,
258 if (!NT_STATUS_IS_OK(status
)) {
259 DEBUG(1,("Failed to generate session_info "
260 "(user and group token) for session setup: %s\n",
262 data_blob_free(&out_blob
);
263 TALLOC_FREE(session
);
264 reply_nterror(req
, nt_status_squash(status
));
268 if (security_session_user_level(session_info
, NULL
) == SECURITY_GUEST
) {
269 action
|= SMB_SETUP_GUEST
;
272 session
->global
->signing_algo
= SMB2_SIGNING_MD5_SMB1
;
273 session
->global
->encryption_cipher
= 0;
274 session
->global
->channels
[0].signing_algo
=
275 session
->global
->signing_algo
;
276 session
->global
->channels
[0].encryption_cipher
=
277 session
->global
->encryption_cipher
;
279 if (session_info
->session_key
.length
> 0) {
280 struct smbXsrv_session
*x
= session
;
282 status
= smb2_signing_key_sign_create(x
->global
,
283 x
->global
->signing_algo
,
284 &session_info
->session_key
,
285 NULL
, /* no derivation */
286 &x
->global
->signing_key
);
287 if (!NT_STATUS_IS_OK(status
)) {
288 data_blob_free(&out_blob
);
289 TALLOC_FREE(session
);
290 reply_nterror(req
, status
);
293 x
->global
->signing_key_blob
= x
->global
->signing_key
->blob
;
296 * clear the session key
297 * the first tcon will add setup the application key
299 data_blob_clear_free(&session_info
->session_key
);
304 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
305 is_authenticated
= true;
306 session
->homes_snum
=
307 register_homes_share(session_info
->unix_info
->unix_name
);
310 if (smb1_srv_is_signing_negotiated(xconn
) &&
312 smb2_signing_key_valid(session
->global
->signing_key
))
315 * Try and turn on server signing on the first non-guest
318 smb1_srv_set_signing(xconn
,
319 session
->global
->signing_key
->blob
,
323 set_current_user_info(session_info
->unix_info
->sanitized_username
,
324 session_info
->unix_info
->unix_name
,
325 session_info
->info
->domain_name
);
327 session
->status
= NT_STATUS_OK
;
328 session
->global
->auth_session_info
= talloc_move(session
->global
,
330 session
->global
->auth_session_info_seqnum
+= 1;
331 session
->global
->channels
[0].auth_session_info_seqnum
=
332 session
->global
->auth_session_info_seqnum
;
333 session
->global
->auth_time
= now
;
334 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
335 session
->global
->expiration_time
=
336 gensec_expire_time(auth
->gensec
);
338 session
->global
->expiration_time
=
339 GENSEC_EXPIRE_TIME_INFINITY
;
342 if (!session_claim(session
)) {
343 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
344 (unsigned long long)session
->global
->session_wire_id
));
345 data_blob_free(&out_blob
);
346 TALLOC_FREE(session
);
347 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
351 status
= smbXsrv_session_update(session
);
352 if (!NT_STATUS_IS_OK(status
)) {
353 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
354 (unsigned long long)session
->global
->session_wire_id
,
356 data_blob_free(&out_blob
);
357 TALLOC_FREE(session
);
358 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
362 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
363 if (smb_bufsize
< SMB_BUFFER_SIZE_MIN
) {
364 reply_force_doserror(req
, ERRSRV
, ERRerror
);
367 xconn
->smb1
.sessions
.max_send
= smb_bufsize
;
368 xconn
->smb1
.sessions
.done_sesssetup
= true;
371 /* current_user_info is changed on new vuid */
372 reload_services(sconn
, conn_snum_used
, true);
373 } else if (NT_STATUS_IS_OK(status
)) {
374 struct auth_session_info
*session_info
= NULL
;
376 status
= gensec_session_info(auth
->gensec
,
379 if (!NT_STATUS_IS_OK(status
)) {
380 DEBUG(1,("Failed to generate session_info "
381 "(user and group token) for session setup: %s\n",
383 data_blob_free(&out_blob
);
384 TALLOC_FREE(session
);
385 reply_nterror(req
, nt_status_squash(status
));
389 if (security_session_user_level(session_info
, NULL
) == SECURITY_GUEST
) {
390 action
|= SMB_SETUP_GUEST
;
394 * Keep the application key
396 data_blob_clear_free(&session_info
->session_key
);
397 session_info
->session_key
=
398 session
->global
->auth_session_info
->session_key
;
399 talloc_steal(session_info
, session_info
->session_key
.data
);
400 TALLOC_FREE(session
->global
->auth_session_info
);
402 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
403 session
->homes_snum
=
404 register_homes_share(session_info
->unix_info
->unix_name
);
407 set_current_user_info(session_info
->unix_info
->sanitized_username
,
408 session_info
->unix_info
->unix_name
,
409 session_info
->info
->domain_name
);
411 session
->status
= NT_STATUS_OK
;
412 session
->global
->auth_session_info
= talloc_move(session
->global
,
414 session
->global
->auth_session_info_seqnum
+= 1;
415 session
->global
->channels
[0].auth_session_info_seqnum
=
416 session
->global
->auth_session_info_seqnum
;
417 session
->global
->auth_time
= now
;
418 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
419 session
->global
->expiration_time
=
420 gensec_expire_time(auth
->gensec
);
422 session
->global
->expiration_time
=
423 GENSEC_EXPIRE_TIME_INFINITY
;
426 status
= smbXsrv_session_update(session
);
427 if (!NT_STATUS_IS_OK(status
)) {
428 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
429 (unsigned long long)session
->global
->session_wire_id
,
431 data_blob_free(&out_blob
);
432 TALLOC_FREE(session
);
433 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
437 conn_clear_vuid_caches(sconn
, session
->global
->session_wire_id
);
439 /* current_user_info is changed on new vuid */
440 reload_services(sconn
, conn_snum_used
, true);
443 vuid
= session
->global
->session_wire_id
;
445 reply_smb1_outbuf(req
, 4, 0);
447 SSVAL(req
->outbuf
, smb_uid
, vuid
);
448 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(status
));
449 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
450 SSVAL(req
->outbuf
, smb_vwv2
, action
);
451 SSVAL(req
->outbuf
, smb_vwv3
, out_blob
.length
);
453 if (message_push_blob(&req
->outbuf
, out_blob
) == -1) {
454 data_blob_free(&out_blob
);
455 TALLOC_FREE(session
);
456 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
459 data_blob_free(&out_blob
);
461 if (push_signature(&req
->outbuf
) == -1) {
462 TALLOC_FREE(session
);
463 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
468 /****************************************************************************
469 On new VC == 0, shutdown *all* old connections and users.
470 It seems that only NT4.x does this. At W2K and above (XP etc.).
471 a new session setup with VC==0 is ignored.
472 ****************************************************************************/
474 struct shutdown_state
{
477 struct messaging_context
*msg_ctx
;
480 static int shutdown_other_smbds(struct smbXsrv_session_global0
*session
,
483 struct shutdown_state
*state
= (struct shutdown_state
*)private_data
;
484 struct server_id self_pid
= messaging_server_id(state
->msg_ctx
);
485 struct server_id pid
= session
->channels
[0].server_id
;
486 const char *addr
= session
->channels
[0].remote_address
;
487 const char *port_colon
;
489 struct server_id_buf tmp
;
491 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
492 server_id_str_buf(pid
, &tmp
), addr
));
494 if (!process_exists(pid
)) {
495 DEBUG(10, ("process does not exist\n"));
499 if (server_id_equal(&pid
, &self_pid
)) {
500 DEBUG(10, ("It's me\n"));
504 port_colon
= strrchr(addr
, ':');
505 if (port_colon
== NULL
) {
506 DBG_DEBUG("addr %s in contains no port\n", addr
);
509 addr_len
= port_colon
- addr
;
511 if ((addr_len
!= state
->ip_length
) ||
512 (strncmp(addr
, state
->ip
, state
->ip_length
) != 0)) {
513 DEBUG(10, ("%s (%zu) does not match %s (%zu)\n",
514 state
->ip
, state
->ip_length
, addr
, addr_len
));
518 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
519 "(IP %s)\n", (unsigned int)procid_to_pid(&pid
),
522 messaging_send(state
->msg_ctx
, pid
, MSG_SHUTDOWN
,
527 static void setup_new_vc_session(struct smbd_server_connection
*sconn
)
529 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
530 "compatible we would close all old resources.\n"));
532 if (lp_reset_on_zero_vc()) {
534 const char *port_colon
;
535 struct shutdown_state state
;
537 addr
= tsocket_address_string(
538 sconn
->remote_address
, talloc_tos());
544 port_colon
= strrchr(addr
, ':');
545 if (port_colon
== NULL
) {
548 state
.ip_length
= port_colon
- addr
;
549 state
.msg_ctx
= sconn
->msg_ctx
;
550 smbXsrv_session_global_traverse(shutdown_other_smbds
, &state
);
555 /****************************************************************************
556 Reply to a session setup command.
557 ****************************************************************************/
559 struct reply_sesssetup_and_X_state
{
560 struct smb_request
*req
;
561 struct auth4_context
*auth_context
;
562 struct auth_usersupplied_info
*user_info
;
567 DATA_BLOB plaintext_password
;
570 static int reply_sesssetup_and_X_state_destructor(
571 struct reply_sesssetup_and_X_state
*state
)
573 data_blob_clear_free(&state
->nt_resp
);
574 data_blob_clear_free(&state
->lm_resp
);
575 data_blob_clear_free(&state
->plaintext_password
);
579 void reply_sesssetup_and_X(struct smb_request
*req
)
581 struct reply_sesssetup_and_X_state
*state
= NULL
;
583 uint16_t smb_bufsize
;
585 fstring sub_user
; /* Sanitised username for substitution */
586 const char *native_os
;
587 const char *native_lanman
;
588 const char *primary_domain
;
589 struct auth_session_info
*session_info
= NULL
;
590 uint16_t smb_flag2
= req
->flags2
;
592 bool is_authenticated
= false;
593 NTTIME now
= timeval_to_nttime(&req
->request_time
);
594 struct smbXsrv_session
*session
= NULL
;
596 struct smbXsrv_connection
*xconn
= req
->xconn
;
597 struct smbd_server_connection
*sconn
= req
->sconn
;
598 bool doencrypt
= xconn
->smb1
.negprot
.encrypted_passwords
;
599 bool signing_allowed
= false;
600 bool signing_mandatory
= smb1_signing_is_mandatory(
601 xconn
->smb1
.signing_state
);
603 START_PROFILE(SMBsesssetupX
);
605 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
607 state
= talloc_zero(req
, struct reply_sesssetup_and_X_state
);
609 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
610 END_PROFILE(SMBsesssetupX
);
614 talloc_set_destructor(state
, reply_sesssetup_and_X_state_destructor
);
616 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
) {
617 signing_allowed
= true;
619 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) {
620 signing_mandatory
= true;
624 * We can call smb1_srv_set_signing_negotiated() each time.
625 * It finds out when it needs to turn into a noop
628 smb1_srv_set_signing_negotiated(xconn
,
632 /* a SPNEGO session setup has 12 command words, whereas a normal
633 NT1 session setup has 13. See the cifs spec. */
634 if (req
->wct
== 12 &&
635 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
637 if (!xconn
->smb1
.negprot
.spnego
) {
638 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
639 "at SPNEGO session setup when it was not "
641 reply_nterror(req
, nt_status_squash(
642 NT_STATUS_LOGON_FAILURE
));
643 END_PROFILE(SMBsesssetupX
);
647 if (SVAL(req
->vwv
+4, 0) == 0) {
648 setup_new_vc_session(req
->sconn
);
651 reply_sesssetup_and_X_spnego(req
);
652 END_PROFILE(SMBsesssetupX
);
656 smb_bufsize
= SVAL(req
->vwv
+2, 0);
658 if (xconn
->protocol
< PROTOCOL_NT1
) {
659 uint16_t passlen1
= SVAL(req
->vwv
+7, 0);
661 /* Never do NT status codes with protocols before NT1 as we
662 * don't get client caps. */
663 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
665 if ((passlen1
> MAX_PASS_LEN
) || (passlen1
> req
->buflen
)) {
666 reply_nterror(req
, nt_status_squash(
667 NT_STATUS_INVALID_PARAMETER
));
668 END_PROFILE(SMBsesssetupX
);
673 state
->lm_resp
= data_blob_talloc(state
,
677 state
->plaintext_password
= data_blob_talloc(state
,
680 /* Ensure null termination */
681 state
->plaintext_password
.data
[passlen1
] = 0;
684 srvstr_pull_req_talloc(state
, req
, &tmp
,
685 req
->buf
+ passlen1
, STR_TERMINATE
);
686 state
->user
= tmp
? tmp
: "";
691 uint16_t passlen1
= SVAL(req
->vwv
+7, 0);
692 uint16_t passlen2
= SVAL(req
->vwv
+8, 0);
693 enum remote_arch_types ra_type
= get_remote_arch();
694 const uint8_t *p
= req
->buf
;
695 const uint8_t *save_p
= req
->buf
;
698 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
699 global_client_caps
= IVAL(req
->vwv
+11, 0);
701 if (!(global_client_caps
& CAP_STATUS32
)) {
702 remove_from_common_flags2(
703 FLAGS2_32_BIT_ERROR_CODES
);
706 /* client_caps is used as final determination if
707 * client is NT or Win95. This is needed to return
708 * the correct error codes in some circumstances.
711 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
712 ra_type
== RA_WIN95
) {
713 if(!(global_client_caps
& (CAP_NT_SMBS
|
715 set_remote_arch( RA_WIN95
);
721 /* both Win95 and WinNT stuff up the password
722 * lengths for non-encrypting systems. Uggh.
724 if passlen1==24 its a win95 system, and its setting
725 the password length incorrectly. Luckily it still
726 works with the default code because Win95 will null
727 terminate the password anyway
729 if passlen1>0 and passlen2>0 then maybe its a NT box
730 and its setting passlen2 to some random value which
731 really stuffs things up. we need to fix that one. */
733 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
739 /* check for nasty tricks */
740 if (passlen1
> MAX_PASS_LEN
741 || passlen1
> smbreq_bufrem(req
, p
)) {
742 reply_nterror(req
, nt_status_squash(
743 NT_STATUS_INVALID_PARAMETER
));
744 END_PROFILE(SMBsesssetupX
);
748 if (passlen2
> MAX_PASS_LEN
749 || passlen2
> smbreq_bufrem(req
, p
+passlen1
)) {
750 reply_nterror(req
, nt_status_squash(
751 NT_STATUS_INVALID_PARAMETER
));
752 END_PROFILE(SMBsesssetupX
);
756 /* Save the lanman2 password and the NT md4 password. */
758 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
763 state
->lm_resp
= data_blob_talloc(state
, p
, passlen1
);
764 state
->nt_resp
= data_blob_talloc(state
, p
+passlen1
, passlen2
);
767 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
769 if (unic
&& (passlen2
== 0) && passlen1
) {
770 /* Only a ascii plaintext password was sent. */
771 (void)srvstr_pull_talloc(state
,
777 STR_TERMINATE
|STR_ASCII
);
779 (void)srvstr_pull_talloc(state
,
784 unic
? passlen2
: passlen1
,
788 reply_nterror(req
, nt_status_squash(
789 NT_STATUS_INVALID_PARAMETER
));
790 END_PROFILE(SMBsesssetupX
);
793 state
->plaintext_password
= data_blob_talloc(state
,
798 p
+= passlen1
+ passlen2
;
800 p
+= srvstr_pull_req_talloc(state
, req
, &tmp
, p
,
802 state
->user
= tmp
? tmp
: "";
804 p
+= srvstr_pull_req_talloc(state
, req
, &tmp
, p
,
806 state
->domain
= tmp
? tmp
: "";
808 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
810 native_os
= tmp
? tmp
: "";
812 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
814 native_lanman
= tmp
? tmp
: "";
816 /* not documented or decoded by Ethereal but there is one more
817 * string in the extra bytes which is the same as the
818 * PrimaryDomain when using extended security. Windows NT 4
819 * and 2003 use this string to store the native lanman string.
820 * Windows 9x does not include a string here at all so we have
821 * to check if we have any extra bytes left */
823 byte_count
= SVAL(req
->vwv
+13, 0);
824 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
825 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
827 primary_domain
= tmp
? tmp
: "";
829 primary_domain
= talloc_strdup(talloc_tos(), "null");
832 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
833 "PrimaryDomain=[%s]\n",
834 state
->domain
, native_os
, native_lanman
, primary_domain
));
836 if ( ra_type
== RA_WIN2K
) {
837 if ( strlen(native_lanman
) == 0 )
838 ra_lanman_string( primary_domain
);
840 ra_lanman_string( native_lanman
);
845 if (SVAL(req
->vwv
+4, 0) == 0) {
846 setup_new_vc_session(req
->sconn
);
849 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
850 state
->domain
, state
->user
, get_remote_machine_name()));
853 if (xconn
->smb1
.negprot
.spnego
) {
855 /* This has to be here, because this is a perfectly
856 * valid behaviour for guest logons :-( */
858 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
859 "at 'normal' session setup after "
860 "negotiating spnego.\n"));
861 reply_nterror(req
, nt_status_squash(
862 NT_STATUS_LOGON_FAILURE
));
863 END_PROFILE(SMBsesssetupX
);
866 fstrcpy(sub_user
, state
->user
);
868 fstrcpy(sub_user
, "");
872 DEBUG(3,("Got anonymous request\n"));
874 nt_status
= make_auth4_context(state
, &state
->auth_context
);
875 if (NT_STATUS_IS_OK(nt_status
)) {
878 state
->auth_context
->get_ntlm_challenge(
879 state
->auth_context
, chal
);
881 if (!make_user_info_guest(state
,
882 sconn
->remote_address
,
883 sconn
->local_address
,
884 "SMB", &state
->user_info
)) {
885 nt_status
= NT_STATUS_NO_MEMORY
;
888 if (NT_STATUS_IS_OK(nt_status
)) {
889 state
->user_info
->auth_description
= "guest";
892 } else if (doencrypt
) {
893 state
->auth_context
= xconn
->smb1
.negprot
.auth_context
;
894 if (state
->auth_context
== NULL
) {
895 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
896 "session setup without negprot denied!\n"));
897 reply_nterror(req
, nt_status_squash(
898 NT_STATUS_LOGON_FAILURE
));
899 END_PROFILE(SMBsesssetupX
);
902 nt_status
= make_user_info_for_reply_enc(state
,
906 sconn
->remote_address
,
907 sconn
->local_address
,
912 if (NT_STATUS_IS_OK(nt_status
)) {
913 state
->user_info
->auth_description
= "bare-NTLM";
916 nt_status
= make_auth4_context(state
, &state
->auth_context
);
917 if (NT_STATUS_IS_OK(nt_status
)) {
920 state
->auth_context
->get_ntlm_challenge(
921 state
->auth_context
, chal
);
923 if (!make_user_info_for_reply(state
,
927 sconn
->remote_address
,
928 sconn
->local_address
,
931 state
->plaintext_password
)) {
932 nt_status
= NT_STATUS_NO_MEMORY
;
935 if (NT_STATUS_IS_OK(nt_status
)) {
936 state
->user_info
->auth_description
= "plaintext";
941 if (!NT_STATUS_IS_OK(nt_status
)) {
942 reply_nterror(req
, nt_status_squash(nt_status
));
943 END_PROFILE(SMBsesssetupX
);
947 nt_status
= auth_check_password_session_info(state
->auth_context
,
948 req
, state
->user_info
,
950 TALLOC_FREE(state
->user_info
);
951 if (!NT_STATUS_IS_OK(nt_status
)) {
952 reply_nterror(req
, nt_status_squash(nt_status
));
953 END_PROFILE(SMBsesssetupX
);
957 /* it's ok - setup a reply */
958 reply_smb1_outbuf(req
, 3, 0);
959 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
960 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
962 if (xconn
->protocol
>= PROTOCOL_NT1
) {
963 push_signature(&req
->outbuf
);
964 /* perhaps grab OS version here?? */
967 if (security_session_user_level(session_info
, NULL
) == SECURITY_GUEST
) {
968 action
|= SMB_SETUP_GUEST
;
971 /* register the name and uid as being validated, so further connections
972 to a uid can get through without a password, on the same VC */
974 nt_status
= smbXsrv_session_create(xconn
,
976 if (!NT_STATUS_IS_OK(nt_status
)) {
977 reply_nterror(req
, nt_status_squash(nt_status
));
978 END_PROFILE(SMBsesssetupX
);
982 session
->global
->signing_algo
= SMB2_SIGNING_MD5_SMB1
;
983 session
->global
->encryption_cipher
= 0;
984 session
->global
->channels
[0].signing_algo
=
985 session
->global
->signing_algo
;
986 session
->global
->channels
[0].encryption_cipher
=
987 session
->global
->encryption_cipher
;
989 if (session_info
->session_key
.length
> 0) {
990 struct smbXsrv_session
*x
= session
;
991 uint8_t session_key
[16];
994 status
= smb2_signing_key_sign_create(x
->global
,
995 x
->global
->signing_algo
,
996 &session_info
->session_key
,
997 NULL
, /* no derivation */
998 &x
->global
->signing_key
);
999 if (!NT_STATUS_IS_OK(status
)) {
1000 TALLOC_FREE(session
);
1001 reply_nterror(req
, status
);
1002 END_PROFILE(SMBsesssetupX
);
1005 x
->global
->signing_key_blob
= x
->global
->signing_key
->blob
;
1008 * The application key is truncated/padded to 16 bytes
1010 ZERO_STRUCT(session_key
);
1011 memcpy(session_key
, session
->global
->signing_key_blob
.data
,
1012 MIN(session
->global
->signing_key_blob
.length
,
1013 sizeof(session_key
)));
1014 session
->global
->application_key_blob
=
1015 data_blob_talloc(session
->global
,
1017 sizeof(session_key
));
1018 ZERO_STRUCT(session_key
);
1019 if (session
->global
->application_key_blob
.data
== NULL
) {
1020 TALLOC_FREE(session
);
1021 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1022 END_PROFILE(SMBsesssetupX
);
1025 talloc_keep_secret(session
->global
->application_key_blob
.data
);
1028 * Place the application key into the session_info
1030 data_blob_clear_free(&session_info
->session_key
);
1031 session_info
->session_key
= data_blob_dup_talloc(session_info
,
1032 session
->global
->application_key_blob
);
1033 if (session_info
->session_key
.data
== NULL
) {
1034 TALLOC_FREE(session
);
1035 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1036 END_PROFILE(SMBsesssetupX
);
1039 talloc_keep_secret(session_info
->session_key
.data
);
1044 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
1045 is_authenticated
= true;
1046 session
->homes_snum
=
1047 register_homes_share(session_info
->unix_info
->unix_name
);
1050 if (smb1_srv_is_signing_negotiated(xconn
) &&
1052 smb2_signing_key_valid(session
->global
->signing_key
))
1055 * Try and turn on server signing on the first non-guest
1058 smb1_srv_set_signing(xconn
,
1059 session
->global
->signing_key
->blob
,
1060 state
->nt_resp
.data
? state
->nt_resp
: state
->lm_resp
);
1063 set_current_user_info(session_info
->unix_info
->sanitized_username
,
1064 session_info
->unix_info
->unix_name
,
1065 session_info
->info
->domain_name
);
1067 session
->status
= NT_STATUS_OK
;
1068 session
->global
->auth_session_info
= talloc_move(session
->global
,
1070 session
->global
->auth_session_info_seqnum
+= 1;
1071 session
->global
->channels
[0].auth_session_info_seqnum
=
1072 session
->global
->auth_session_info_seqnum
;
1073 session
->global
->auth_time
= now
;
1074 session
->global
->expiration_time
= GENSEC_EXPIRE_TIME_INFINITY
;
1076 nt_status
= smbXsrv_session_update(session
);
1077 if (!NT_STATUS_IS_OK(nt_status
)) {
1078 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1079 (unsigned long long)session
->global
->session_wire_id
,
1080 nt_errstr(nt_status
)));
1081 TALLOC_FREE(session
);
1082 reply_nterror(req
, nt_status_squash(nt_status
));
1083 END_PROFILE(SMBsesssetupX
);
1087 if (!session_claim(session
)) {
1088 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1089 (unsigned long long)session
->global
->session_wire_id
));
1090 TALLOC_FREE(session
);
1091 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
1092 END_PROFILE(SMBsesssetupX
);
1096 /* current_user_info is changed on new vuid */
1097 reload_services(sconn
, conn_snum_used
, true);
1099 sess_vuid
= session
->global
->session_wire_id
;
1101 SSVAL(req
->outbuf
,smb_vwv2
,action
);
1102 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
1103 SSVAL(discard_const_p(char, req
->inbuf
),smb_uid
,sess_vuid
);
1104 req
->vuid
= sess_vuid
;
1106 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
1107 if (smb_bufsize
< SMB_BUFFER_SIZE_MIN
) {
1108 reply_force_doserror(req
, ERRSRV
, ERRerror
);
1109 END_PROFILE(SMBsesssetupX
);
1112 xconn
->smb1
.sessions
.max_send
= smb_bufsize
;
1113 xconn
->smb1
.sessions
.done_sesssetup
= true;
1117 END_PROFILE(SMBsesssetupX
);