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
)
53 fstr_sprintf(native_os
, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
,
54 SAMBA_MINOR_NBT_ANNOUNCE_VERSION
);
56 tmp
= message_push_string(outbuf
, native_os
, STR_TERMINATE
);
58 if (tmp
== -1) return -1;
61 if (asprintf(&lanman
, "Samba %s", samba_version_string()) != -1) {
62 tmp
= message_push_string(outbuf
, lanman
, STR_TERMINATE
);
66 tmp
= message_push_string(outbuf
, "Samba", STR_TERMINATE
);
69 if (tmp
== -1) return -1;
72 tmp
= message_push_string(outbuf
, lp_workgroup(), STR_TERMINATE
);
74 if (tmp
== -1) return -1;
80 /****************************************************************************
81 Do a 'guest' logon, getting back the
82 ****************************************************************************/
84 static NTSTATUS
check_guest_password(const struct tsocket_address
*remote_address
,
86 struct auth_session_info
**session_info
)
88 struct auth4_context
*auth_context
;
89 struct auth_usersupplied_info
*user_info
= NULL
;
93 DEBUG(3,("Got anonymous request\n"));
95 nt_status
= make_auth4_context(talloc_tos(), &auth_context
);
96 if (!NT_STATUS_IS_OK(nt_status
)) {
100 auth_context
->get_ntlm_challenge(auth_context
,
103 if (!make_user_info_guest(remote_address
, &user_info
)) {
104 TALLOC_FREE(auth_context
);
105 return NT_STATUS_NO_MEMORY
;
108 nt_status
= auth_check_password_session_info(auth_context
,
109 mem_ctx
, user_info
, session_info
);
110 free_user_info(&user_info
);
111 TALLOC_FREE(auth_context
);
115 /****************************************************************************
116 Reply to a session setup command.
117 conn POINTER CAN BE NULL HERE !
118 ****************************************************************************/
120 static void reply_sesssetup_and_X_spnego(struct smb_request
*req
)
124 DATA_BLOB out_blob
= data_blob_null
;
127 const char *native_os
;
128 const char *native_lanman
;
129 const char *primary_domain
;
131 uint16 data_blob_len
= SVAL(req
->vwv
+7, 0);
132 enum remote_arch_types ra_type
= get_remote_arch();
133 uint64_t vuid
= req
->vuid
;
134 NTSTATUS status
= NT_STATUS_OK
;
135 struct smbd_server_connection
*sconn
= req
->sconn
;
137 NTTIME now
= timeval_to_nttime(&req
->request_time
);
138 struct smbXsrv_session
*session
= NULL
;
139 uint16_t smb_bufsize
= SVAL(req
->vwv
+2, 0);
140 uint32_t client_caps
= IVAL(req
->vwv
+10, 0);
142 DEBUG(3,("Doing spnego session setup\n"));
144 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
145 global_client_caps
= client_caps
;
147 if (!(global_client_caps
& CAP_STATUS32
)) {
148 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
154 if (data_blob_len
== 0) {
155 /* an invalid request */
156 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
160 bufrem
= smbreq_bufrem(req
, p
);
161 /* pull the spnego blob */
162 in_blob
= data_blob_const(p
, MIN(bufrem
, data_blob_len
));
165 file_save("negotiate.dat", in_blob
.data
, in_blob
.length
);
168 p2
= (const char *)req
->buf
+ in_blob
.length
;
170 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
172 native_os
= tmp
? tmp
: "";
174 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
176 native_lanman
= tmp
? tmp
: "";
178 p2
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p2
,
180 primary_domain
= tmp
? tmp
: "";
182 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
183 native_os
, native_lanman
, primary_domain
));
185 if ( ra_type
== RA_WIN2K
) {
186 /* Vista sets neither the OS or lanman strings */
188 if ( !strlen(native_os
) && !strlen(native_lanman
) )
189 set_remote_arch(RA_VISTA
);
191 /* Windows 2003 doesn't set the native lanman string,
192 but does set primary domain which is a bug I think */
194 if ( !strlen(native_lanman
) ) {
195 ra_lanman_string( primary_domain
);
197 ra_lanman_string( native_lanman
);
199 } else if ( ra_type
== RA_VISTA
) {
200 if ( strncmp(native_os
, "Mac OS X", 8) == 0 ) {
201 set_remote_arch(RA_OSX
);
206 status
= smb1srv_session_lookup(sconn
->conn
,
209 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
210 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
213 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
214 status
= NT_STATUS_OK
;
216 if (NT_STATUS_IS_OK(status
)) {
217 session
->status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
218 status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
219 TALLOC_FREE(session
->gensec
);
221 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
222 reply_nterror(req
, nt_status_squash(status
));
227 if (session
== NULL
) {
228 /* create a new session */
229 status
= smbXsrv_session_create(sconn
->conn
,
231 if (!NT_STATUS_IS_OK(status
)) {
232 reply_nterror(req
, nt_status_squash(status
));
237 if (!session
->gensec
) {
238 status
= auth_generic_prepare(session
, sconn
->remote_address
,
240 if (!NT_STATUS_IS_OK(status
)) {
241 TALLOC_FREE(session
);
242 reply_nterror(req
, nt_status_squash(status
));
246 gensec_want_feature(session
->gensec
, GENSEC_FEATURE_SESSION_KEY
);
247 gensec_want_feature(session
->gensec
, GENSEC_FEATURE_UNIX_TOKEN
);
249 status
= gensec_start_mech_by_oid(session
->gensec
,
251 if (!NT_STATUS_IS_OK(status
)) {
252 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
253 TALLOC_FREE(session
);;
254 reply_nterror(req
, nt_status_squash(status
));
260 status
= gensec_update(session
->gensec
,
264 if (!NT_STATUS_IS_OK(status
) &&
265 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
266 TALLOC_FREE(session
);
267 reply_nterror(req
, nt_status_squash(status
));
271 if (NT_STATUS_IS_OK(status
) && session
->global
->auth_session_info
== NULL
) {
272 struct auth_session_info
*session_info
= NULL
;
274 status
= gensec_session_info(session
->gensec
,
277 if (!NT_STATUS_IS_OK(status
)) {
278 DEBUG(1,("Failed to generate session_info "
279 "(user and group token) for session setup: %s\n",
281 data_blob_free(&out_blob
);
282 TALLOC_FREE(session
);
283 reply_nterror(req
, nt_status_squash(status
));
287 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
291 if (session_info
->session_key
.length
> 0) {
292 struct smbXsrv_session
*x
= session
;
295 * Note: the SMB1 signing key is not truncated to 16 byte!
297 x
->global
->signing_key
=
298 data_blob_dup_talloc(x
->global
,
299 session_info
->session_key
);
300 if (x
->global
->signing_key
.data
== NULL
) {
301 data_blob_free(&out_blob
);
302 TALLOC_FREE(session
);
303 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
308 * clear the session key
309 * the first tcon will add setup the application key
311 data_blob_clear_free(&session_info
->session_key
);
314 session
->compat
= talloc_zero(session
, struct user_struct
);
315 if (session
->compat
== NULL
) {
316 data_blob_free(&out_blob
);
317 TALLOC_FREE(session
);
318 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
321 session
->compat
->session
= session
;
322 session
->compat
->homes_snum
= -1;
323 session
->compat
->session_info
= session_info
;
324 session
->compat
->session_keystr
= NULL
;
325 session
->compat
->vuid
= session
->global
->session_wire_id
;
326 DLIST_ADD(sconn
->users
, session
->compat
);
329 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
330 session
->compat
->homes_snum
=
331 register_homes_share(session_info
->unix_info
->unix_name
);
334 if (srv_is_signing_negotiated(sconn
) &&
336 session
->global
->signing_key
.length
> 0)
339 * Try and turn on server signing on the first non-guest
342 srv_set_signing(sconn
,
343 session
->global
->signing_key
,
347 set_current_user_info(session_info
->unix_info
->sanitized_username
,
348 session_info
->unix_info
->unix_name
,
349 session_info
->info
->domain_name
);
351 session
->status
= NT_STATUS_OK
;
352 session
->global
->auth_session_info
= talloc_move(session
->global
,
354 session
->global
->auth_session_info_seqnum
+= 1;
355 session
->global
->channels
[0].auth_session_info_seqnum
=
356 session
->global
->auth_session_info_seqnum
;
357 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
358 session
->global
->expiration_time
=
359 gensec_expire_time(session
->gensec
);
361 session
->global
->expiration_time
=
362 GENSEC_EXPIRE_TIME_INFINITY
;
365 if (!session_claim(session
)) {
366 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
367 (unsigned long long)session
->compat
->vuid
));
368 data_blob_free(&out_blob
);
369 TALLOC_FREE(session
);
370 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
374 status
= smbXsrv_session_update(session
);
375 if (!NT_STATUS_IS_OK(status
)) {
376 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
377 (unsigned long long)session
->compat
->vuid
,
379 data_blob_free(&out_blob
);
380 TALLOC_FREE(session
);
381 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
385 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
386 if (smb_bufsize
< SMB_BUFFER_SIZE_MIN
) {
387 reply_force_doserror(req
, ERRSRV
, ERRerror
);
390 sconn
->smb1
.sessions
.max_send
= smb_bufsize
;
391 sconn
->smb1
.sessions
.done_sesssetup
= true;
394 /* current_user_info is changed on new vuid */
395 reload_services(sconn
, conn_snum_used
, true);
396 } else if (NT_STATUS_IS_OK(status
)) {
397 struct auth_session_info
*session_info
= NULL
;
399 status
= gensec_session_info(session
->gensec
,
402 if (!NT_STATUS_IS_OK(status
)) {
403 DEBUG(1,("Failed to generate session_info "
404 "(user and group token) for session setup: %s\n",
406 data_blob_free(&out_blob
);
407 TALLOC_FREE(session
);
408 reply_nterror(req
, nt_status_squash(status
));
412 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
417 * Keep the application key
419 data_blob_clear_free(&session_info
->session_key
);
420 session_info
->session_key
=
421 session
->global
->auth_session_info
->session_key
;
422 talloc_steal(session_info
, session_info
->session_key
.data
);
423 TALLOC_FREE(session
->global
->auth_session_info
);
425 session
->compat
->session_info
= session_info
;
427 session
->compat
->vuid
= session
->global
->session_wire_id
;
429 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
430 session
->compat
->homes_snum
=
431 register_homes_share(session_info
->unix_info
->unix_name
);
434 set_current_user_info(session_info
->unix_info
->sanitized_username
,
435 session_info
->unix_info
->unix_name
,
436 session_info
->info
->domain_name
);
438 session
->status
= NT_STATUS_OK
;
439 session
->global
->auth_session_info
= talloc_move(session
->global
,
441 session
->global
->auth_session_info_seqnum
+= 1;
442 session
->global
->channels
[0].auth_session_info_seqnum
=
443 session
->global
->auth_session_info_seqnum
;
444 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
445 session
->global
->expiration_time
=
446 gensec_expire_time(session
->gensec
);
448 session
->global
->expiration_time
=
449 GENSEC_EXPIRE_TIME_INFINITY
;
452 status
= smbXsrv_session_update(session
);
453 if (!NT_STATUS_IS_OK(status
)) {
454 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
455 (unsigned long long)session
->compat
->vuid
,
457 data_blob_free(&out_blob
);
458 TALLOC_FREE(session
);
459 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
463 conn_clear_vuid_caches(sconn
, session
->compat
->vuid
);
465 /* current_user_info is changed on new vuid */
466 reload_services(sconn
, conn_snum_used
, true);
469 vuid
= session
->global
->session_wire_id
;
471 reply_outbuf(req
, 4, 0);
473 SSVAL(req
->outbuf
, smb_uid
, vuid
);
474 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(status
));
475 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
476 SSVAL(req
->outbuf
, smb_vwv2
, action
);
477 SSVAL(req
->outbuf
, smb_vwv3
, out_blob
.length
);
479 if (message_push_blob(&req
->outbuf
, out_blob
) == -1) {
480 data_blob_free(&out_blob
);
481 TALLOC_FREE(session
);
482 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
485 data_blob_free(&out_blob
);
487 if (push_signature(&req
->outbuf
) == -1) {
488 TALLOC_FREE(session
);
489 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
494 /****************************************************************************
495 On new VC == 0, shutdown *all* old connections and users.
496 It seems that only NT4.x does this. At W2K and above (XP etc.).
497 a new session setup with VC==0 is ignored.
498 ****************************************************************************/
500 struct shutdown_state
{
502 struct messaging_context
*msg_ctx
;
505 static int shutdown_other_smbds(struct smbXsrv_session_global0
*session
,
508 struct shutdown_state
*state
= (struct shutdown_state
*)private_data
;
509 struct server_id self_pid
= messaging_server_id(state
->msg_ctx
);
510 struct server_id pid
= session
->channels
[0].server_id
;
511 const char *addr
= session
->channels
[0].remote_address
;
513 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
514 server_id_str(talloc_tos(), &pid
), addr
));
516 if (!process_exists(pid
)) {
517 DEBUG(10, ("process does not exist\n"));
521 if (serverid_equal(&pid
, &self_pid
)) {
522 DEBUG(10, ("It's me\n"));
527 * here we use strstr() because 'addr'
528 * (session->channels[0].remote_address)
529 * contains a string like:
530 * 'ipv4:127.0.0.1:48163'
532 if (strstr(addr
, state
->ip
) == NULL
) {
533 DEBUG(10, ("%s does not match %s\n", state
->ip
, addr
));
537 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
538 "(IP %s)\n", (unsigned int)procid_to_pid(&pid
),
541 messaging_send(state
->msg_ctx
, pid
, MSG_SHUTDOWN
,
546 static void setup_new_vc_session(struct smbd_server_connection
*sconn
)
548 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
549 "compatible we would close all old resources.\n"));
552 invalidate_all_vuids();
554 if (lp_reset_on_zero_vc()) {
556 struct shutdown_state state
;
558 addr
= tsocket_address_inet_addr_string(
559 sconn
->remote_address
, talloc_tos());
564 state
.msg_ctx
= sconn
->msg_ctx
;
565 smbXsrv_session_global_traverse(shutdown_other_smbds
, &state
);
570 /****************************************************************************
571 Reply to a session setup command.
572 ****************************************************************************/
574 void reply_sesssetup_and_X(struct smb_request
*req
)
577 uint16_t smb_bufsize
;
580 DATA_BLOB plaintext_password
;
583 fstring sub_user
; /* Sanitised username for substituion */
585 const char *native_os
;
586 const char *native_lanman
;
587 const char *primary_domain
;
588 struct auth_usersupplied_info
*user_info
= NULL
;
589 struct auth_session_info
*session_info
= NULL
;
590 uint16 smb_flag2
= req
->flags2
;
592 NTTIME now
= timeval_to_nttime(&req
->request_time
);
593 struct smbXsrv_session
*session
= NULL
;
596 struct smbd_server_connection
*sconn
= req
->sconn
;
598 bool doencrypt
= sconn
->smb1
.negprot
.encrypted_passwords
;
599 bool signing_allowed
= false;
600 bool signing_mandatory
= false;
602 START_PROFILE(SMBsesssetupX
);
604 ZERO_STRUCT(lm_resp
);
605 ZERO_STRUCT(nt_resp
);
606 ZERO_STRUCT(plaintext_password
);
608 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
610 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
) {
611 signing_allowed
= true;
613 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) {
614 signing_mandatory
= true;
618 * We can call srv_set_signing_negotiated() each time.
619 * It finds out when it needs to turn into a noop
622 srv_set_signing_negotiated(req
->sconn
,
626 /* a SPNEGO session setup has 12 command words, whereas a normal
627 NT1 session setup has 13. See the cifs spec. */
628 if (req
->wct
== 12 &&
629 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
631 if (!sconn
->smb1
.negprot
.spnego
) {
632 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
633 "at SPNEGO session setup when it was not "
635 reply_nterror(req
, nt_status_squash(
636 NT_STATUS_LOGON_FAILURE
));
637 END_PROFILE(SMBsesssetupX
);
641 if (SVAL(req
->vwv
+4, 0) == 0) {
642 setup_new_vc_session(req
->sconn
);
645 reply_sesssetup_and_X_spnego(req
);
646 END_PROFILE(SMBsesssetupX
);
650 smb_bufsize
= SVAL(req
->vwv
+2, 0);
652 if (get_Protocol() < PROTOCOL_NT1
) {
653 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
655 /* Never do NT status codes with protocols before NT1 as we
656 * don't get client caps. */
657 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
659 if ((passlen1
> MAX_PASS_LEN
) || (passlen1
> req
->buflen
)) {
660 reply_nterror(req
, nt_status_squash(
661 NT_STATUS_INVALID_PARAMETER
));
662 END_PROFILE(SMBsesssetupX
);
667 lm_resp
= data_blob(req
->buf
, passlen1
);
669 plaintext_password
= data_blob(req
->buf
, passlen1
+1);
670 /* Ensure null termination */
671 plaintext_password
.data
[passlen1
] = 0;
674 srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
,
675 req
->buf
+ passlen1
, STR_TERMINATE
);
676 user
= tmp
? tmp
: "";
681 uint16 passlen1
= SVAL(req
->vwv
+7, 0);
682 uint16 passlen2
= SVAL(req
->vwv
+8, 0);
683 enum remote_arch_types ra_type
= get_remote_arch();
684 const uint8_t *p
= req
->buf
;
685 const uint8_t *save_p
= req
->buf
;
688 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
689 global_client_caps
= IVAL(req
->vwv
+11, 0);
691 if (!(global_client_caps
& CAP_STATUS32
)) {
692 remove_from_common_flags2(
693 FLAGS2_32_BIT_ERROR_CODES
);
696 /* client_caps is used as final determination if
697 * client is NT or Win95. This is needed to return
698 * the correct error codes in some circumstances.
701 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
702 ra_type
== RA_WIN95
) {
703 if(!(global_client_caps
& (CAP_NT_SMBS
|
705 set_remote_arch( RA_WIN95
);
711 /* both Win95 and WinNT stuff up the password
712 * lengths for non-encrypting systems. Uggh.
714 if passlen1==24 its a win95 system, and its setting
715 the password length incorrectly. Luckily it still
716 works with the default code because Win95 will null
717 terminate the password anyway
719 if passlen1>0 and passlen2>0 then maybe its a NT box
720 and its setting passlen2 to some random value which
721 really stuffs things up. we need to fix that one. */
723 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
729 /* check for nasty tricks */
730 if (passlen1
> MAX_PASS_LEN
731 || passlen1
> smbreq_bufrem(req
, p
)) {
732 reply_nterror(req
, nt_status_squash(
733 NT_STATUS_INVALID_PARAMETER
));
734 END_PROFILE(SMBsesssetupX
);
738 if (passlen2
> MAX_PASS_LEN
739 || passlen2
> smbreq_bufrem(req
, p
+passlen1
)) {
740 reply_nterror(req
, nt_status_squash(
741 NT_STATUS_INVALID_PARAMETER
));
742 END_PROFILE(SMBsesssetupX
);
746 /* Save the lanman2 password and the NT md4 password. */
748 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
753 lm_resp
= data_blob(p
, passlen1
);
754 nt_resp
= data_blob(p
+passlen1
, passlen2
);
757 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
759 if (unic
&& (passlen2
== 0) && passlen1
) {
760 /* Only a ascii plaintext password was sent. */
761 (void)srvstr_pull_talloc(talloc_tos(),
767 STR_TERMINATE
|STR_ASCII
);
769 (void)srvstr_pull_talloc(talloc_tos(),
774 unic
? passlen2
: passlen1
,
778 reply_nterror(req
, nt_status_squash(
779 NT_STATUS_INVALID_PARAMETER
));
780 END_PROFILE(SMBsesssetupX
);
783 plaintext_password
= data_blob(pass
, strlen(pass
)+1);
786 p
+= passlen1
+ passlen2
;
788 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
790 user
= tmp
? tmp
: "";
792 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
794 domain
= tmp
? tmp
: "";
796 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
798 native_os
= tmp
? tmp
: "";
800 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
802 native_lanman
= tmp
? tmp
: "";
804 /* not documented or decoded by Ethereal but there is one more
805 * string in the extra bytes which is the same as the
806 * PrimaryDomain when using extended security. Windows NT 4
807 * and 2003 use this string to store the native lanman string.
808 * Windows 9x does not include a string here at all so we have
809 * to check if we have any extra bytes left */
811 byte_count
= SVAL(req
->vwv
+13, 0);
812 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
813 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
815 primary_domain
= tmp
? tmp
: "";
817 primary_domain
= talloc_strdup(talloc_tos(), "null");
820 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
821 "PrimaryDomain=[%s]\n",
822 domain
, native_os
, native_lanman
, primary_domain
));
824 if ( ra_type
== RA_WIN2K
) {
825 if ( strlen(native_lanman
) == 0 )
826 ra_lanman_string( primary_domain
);
828 ra_lanman_string( native_lanman
);
833 if (SVAL(req
->vwv
+4, 0) == 0) {
834 setup_new_vc_session(req
->sconn
);
837 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
838 domain
, user
, get_remote_machine_name()));
841 if (sconn
->smb1
.negprot
.spnego
) {
843 /* This has to be here, because this is a perfectly
844 * valid behaviour for guest logons :-( */
846 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
847 "at 'normal' session setup after "
848 "negotiating spnego.\n"));
849 reply_nterror(req
, nt_status_squash(
850 NT_STATUS_LOGON_FAILURE
));
851 END_PROFILE(SMBsesssetupX
);
854 fstrcpy(sub_user
, user
);
856 fstrcpy(sub_user
, "");
859 sub_set_smb_name(sub_user
);
861 reload_services(sconn
, conn_snum_used
, true);
865 nt_status
= check_guest_password(sconn
->remote_address
, req
, &session_info
);
867 } else if (doencrypt
) {
868 struct auth4_context
*negprot_auth_context
= NULL
;
869 negprot_auth_context
= sconn
->smb1
.negprot
.auth_context
;
870 if (!negprot_auth_context
) {
871 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
872 "session setup without negprot denied!\n"));
873 reply_nterror(req
, nt_status_squash(
874 NT_STATUS_LOGON_FAILURE
));
875 END_PROFILE(SMBsesssetupX
);
878 nt_status
= make_user_info_for_reply_enc(&user_info
, user
,
880 sconn
->remote_address
,
882 if (NT_STATUS_IS_OK(nt_status
)) {
883 nt_status
= auth_check_password_session_info(negprot_auth_context
,
884 req
, user_info
, &session_info
);
887 struct auth4_context
*plaintext_auth_context
= NULL
;
889 nt_status
= make_auth4_context(
890 talloc_tos(), &plaintext_auth_context
);
892 if (NT_STATUS_IS_OK(nt_status
)) {
895 plaintext_auth_context
->get_ntlm_challenge(
896 plaintext_auth_context
, chal
);
898 if (!make_user_info_for_reply(&user_info
,
900 sconn
->remote_address
,
902 plaintext_password
)) {
903 nt_status
= NT_STATUS_NO_MEMORY
;
906 if (NT_STATUS_IS_OK(nt_status
)) {
907 nt_status
= auth_check_password_session_info(plaintext_auth_context
,
908 req
, user_info
, &session_info
);
910 TALLOC_FREE(plaintext_auth_context
);
914 free_user_info(&user_info
);
916 if (!NT_STATUS_IS_OK(nt_status
)) {
917 data_blob_free(&nt_resp
);
918 data_blob_free(&lm_resp
);
919 data_blob_clear_free(&plaintext_password
);
920 reply_nterror(req
, nt_status_squash(nt_status
));
921 END_PROFILE(SMBsesssetupX
);
925 data_blob_clear_free(&plaintext_password
);
927 /* it's ok - setup a reply */
928 reply_outbuf(req
, 3, 0);
929 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
930 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
932 if (get_Protocol() >= PROTOCOL_NT1
) {
933 push_signature(&req
->outbuf
);
934 /* perhaps grab OS version here?? */
937 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
941 /* register the name and uid as being validated, so further connections
942 to a uid can get through without a password, on the same VC */
944 nt_status
= smbXsrv_session_create(sconn
->conn
,
946 if (!NT_STATUS_IS_OK(nt_status
)) {
947 data_blob_free(&nt_resp
);
948 data_blob_free(&lm_resp
);
949 reply_nterror(req
, nt_status_squash(nt_status
));
950 END_PROFILE(SMBsesssetupX
);
954 if (session_info
->session_key
.length
> 0) {
955 uint8_t session_key
[16];
958 * Note: the SMB1 signing key is not truncated to 16 byte!
960 session
->global
->signing_key
=
961 data_blob_dup_talloc(session
->global
,
962 session_info
->session_key
);
963 if (session
->global
->signing_key
.data
== NULL
) {
964 data_blob_free(&nt_resp
);
965 data_blob_free(&lm_resp
);
966 TALLOC_FREE(session
);
967 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
968 END_PROFILE(SMBsesssetupX
);
973 * The application key is truncated/padded to 16 bytes
975 ZERO_STRUCT(session_key
);
976 memcpy(session_key
, session
->global
->signing_key
.data
,
977 MIN(session
->global
->signing_key
.length
,
978 sizeof(session_key
)));
979 session
->global
->application_key
=
980 data_blob_talloc(session
->global
,
982 sizeof(session_key
));
983 ZERO_STRUCT(session_key
);
984 if (session
->global
->application_key
.data
== NULL
) {
985 data_blob_free(&nt_resp
);
986 data_blob_free(&lm_resp
);
987 TALLOC_FREE(session
);
988 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
989 END_PROFILE(SMBsesssetupX
);
994 * Place the application key into the session_info
996 data_blob_clear_free(&session_info
->session_key
);
997 session_info
->session_key
= data_blob_dup_talloc(session_info
,
998 session
->global
->application_key
);
999 if (session_info
->session_key
.data
== NULL
) {
1000 data_blob_free(&nt_resp
);
1001 data_blob_free(&lm_resp
);
1002 TALLOC_FREE(session
);
1003 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1004 END_PROFILE(SMBsesssetupX
);
1009 session
->compat
= talloc_zero(session
, struct user_struct
);
1010 if (session
->compat
== NULL
) {
1011 data_blob_free(&nt_resp
);
1012 data_blob_free(&lm_resp
);
1013 TALLOC_FREE(session
);
1014 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1015 END_PROFILE(SMBsesssetupX
);
1018 session
->compat
->session
= session
;
1019 session
->compat
->homes_snum
= -1;
1020 session
->compat
->session_info
= session_info
;
1021 session
->compat
->session_keystr
= NULL
;
1022 session
->compat
->vuid
= session
->global
->session_wire_id
;
1023 DLIST_ADD(sconn
->users
, session
->compat
);
1026 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
1027 session
->compat
->homes_snum
=
1028 register_homes_share(session_info
->unix_info
->unix_name
);
1031 if (srv_is_signing_negotiated(sconn
) &&
1033 session
->global
->signing_key
.length
> 0)
1036 * Try and turn on server signing on the first non-guest
1039 srv_set_signing(sconn
,
1040 session
->global
->signing_key
,
1041 nt_resp
.data
? nt_resp
: lm_resp
);
1044 set_current_user_info(session_info
->unix_info
->sanitized_username
,
1045 session_info
->unix_info
->unix_name
,
1046 session_info
->info
->domain_name
);
1048 session
->status
= NT_STATUS_OK
;
1049 session
->global
->auth_session_info
= talloc_move(session
->global
,
1051 session
->global
->auth_session_info_seqnum
+= 1;
1052 session
->global
->channels
[0].auth_session_info_seqnum
=
1053 session
->global
->auth_session_info_seqnum
;
1054 session
->global
->expiration_time
= GENSEC_EXPIRE_TIME_INFINITY
;
1056 nt_status
= smbXsrv_session_update(session
);
1057 if (!NT_STATUS_IS_OK(nt_status
)) {
1058 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1059 (unsigned long long)session
->compat
->vuid
,
1060 nt_errstr(nt_status
)));
1061 data_blob_free(&nt_resp
);
1062 data_blob_free(&lm_resp
);
1063 TALLOC_FREE(session
);
1064 reply_nterror(req
, nt_status_squash(nt_status
));
1065 END_PROFILE(SMBsesssetupX
);
1069 if (!session_claim(session
)) {
1070 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1071 (unsigned long long)session
->compat
->vuid
));
1072 data_blob_free(&nt_resp
);
1073 data_blob_free(&lm_resp
);
1074 TALLOC_FREE(session
);
1075 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
1076 END_PROFILE(SMBsesssetupX
);
1080 /* current_user_info is changed on new vuid */
1081 reload_services(sconn
, conn_snum_used
, true);
1083 sess_vuid
= session
->global
->session_wire_id
;
1085 data_blob_free(&nt_resp
);
1086 data_blob_free(&lm_resp
);
1088 SSVAL(req
->outbuf
,smb_vwv2
,action
);
1089 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
1090 SSVAL(discard_const_p(char, req
->inbuf
),smb_uid
,sess_vuid
);
1091 req
->vuid
= sess_vuid
;
1093 if (!sconn
->smb1
.sessions
.done_sesssetup
) {
1094 if (smb_bufsize
< SMB_BUFFER_SIZE_MIN
) {
1095 reply_force_doserror(req
, ERRSRV
, ERRerror
);
1096 END_PROFILE(SMBsesssetupX
);
1099 sconn
->smb1
.sessions
.max_send
= smb_bufsize
;
1100 sconn
->smb1
.sessions
.done_sesssetup
= true;
1103 END_PROFILE(SMBsesssetupX
);