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_t **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(talloc_tos(), 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 TALLOC_FREE(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
;
130 uint16_t data_blob_len
= SVAL(req
->vwv
+7, 0);
131 enum remote_arch_types ra_type
= get_remote_arch();
132 uint64_t vuid
= req
->vuid
;
133 NTSTATUS status
= NT_STATUS_OK
;
134 struct smbXsrv_connection
*xconn
= req
->xconn
;
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);
141 struct smbXsrv_session_auth0
*auth
;
143 DEBUG(3,("Doing spnego session setup\n"));
145 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
146 global_client_caps
= client_caps
;
148 if (!(global_client_caps
& CAP_STATUS32
)) {
149 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
155 if (data_blob_len
== 0) {
156 /* an invalid request */
157 reply_nterror(req
, nt_status_squash(NT_STATUS_LOGON_FAILURE
));
161 bufrem
= smbreq_bufrem(req
, p
);
162 /* pull the spnego blob */
163 in_blob
= data_blob_const(p
, MIN(bufrem
, data_blob_len
));
166 file_save("negotiate.dat", in_blob
.data
, in_blob
.length
);
169 p
= req
->buf
+ in_blob
.length
;
171 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
173 native_os
= tmp
? tmp
: "";
175 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
177 native_lanman
= tmp
? tmp
: "";
179 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
181 primary_domain
= tmp
? tmp
: "";
183 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
184 native_os
, native_lanman
, primary_domain
));
186 if ( ra_type
== RA_WIN2K
) {
187 /* Vista sets neither the OS or lanman strings */
189 if ( !strlen(native_os
) && !strlen(native_lanman
) )
190 set_remote_arch(RA_VISTA
);
192 /* Windows 2003 doesn't set the native lanman string,
193 but does set primary domain which is a bug I think */
195 if ( !strlen(native_lanman
) ) {
196 ra_lanman_string( primary_domain
);
198 ra_lanman_string( native_lanman
);
200 } else if ( ra_type
== RA_VISTA
) {
201 if ( strncmp(native_os
, "Mac OS X", 8) == 0 ) {
202 set_remote_arch(RA_OSX
);
207 status
= smb1srv_session_lookup(xconn
,
210 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
211 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
214 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
215 status
= NT_STATUS_OK
;
217 if (NT_STATUS_IS_OK(status
)) {
218 session
->status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
219 status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
220 TALLOC_FREE(session
->pending_auth
);
222 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
223 reply_nterror(req
, nt_status_squash(status
));
228 if (session
== NULL
) {
229 /* create a new session */
230 status
= smbXsrv_session_create(xconn
,
232 if (!NT_STATUS_IS_OK(status
)) {
233 reply_nterror(req
, nt_status_squash(status
));
238 status
= smbXsrv_session_find_auth(session
, xconn
, now
, &auth
);
239 if (!NT_STATUS_IS_OK(status
)) {
240 status
= smbXsrv_session_create_auth(session
, xconn
, now
,
244 if (!NT_STATUS_IS_OK(status
)) {
245 reply_nterror(req
, nt_status_squash(status
));
250 if (auth
->gensec
== NULL
) {
251 status
= auth_generic_prepare(session
, xconn
->remote_address
,
253 if (!NT_STATUS_IS_OK(status
)) {
254 TALLOC_FREE(session
);
255 reply_nterror(req
, nt_status_squash(status
));
259 gensec_want_feature(auth
->gensec
, GENSEC_FEATURE_SESSION_KEY
);
260 gensec_want_feature(auth
->gensec
, GENSEC_FEATURE_UNIX_TOKEN
);
262 status
= gensec_start_mech_by_oid(auth
->gensec
,
264 if (!NT_STATUS_IS_OK(status
)) {
265 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
266 TALLOC_FREE(session
);;
267 reply_nterror(req
, nt_status_squash(status
));
273 status
= gensec_update(auth
->gensec
,
277 if (!NT_STATUS_IS_OK(status
) &&
278 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
279 TALLOC_FREE(session
);
280 reply_nterror(req
, nt_status_squash(status
));
284 if (NT_STATUS_IS_OK(status
) && session
->global
->auth_session_info
== NULL
) {
285 struct auth_session_info
*session_info
= NULL
;
287 status
= gensec_session_info(auth
->gensec
,
290 if (!NT_STATUS_IS_OK(status
)) {
291 DEBUG(1,("Failed to generate session_info "
292 "(user and group token) for session setup: %s\n",
294 data_blob_free(&out_blob
);
295 TALLOC_FREE(session
);
296 reply_nterror(req
, nt_status_squash(status
));
300 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
304 if (session_info
->session_key
.length
> 0) {
305 struct smbXsrv_session
*x
= session
;
308 * Note: the SMB1 signing key is not truncated to 16 byte!
310 x
->global
->signing_key
=
311 data_blob_dup_talloc(x
->global
,
312 session_info
->session_key
);
313 if (x
->global
->signing_key
.data
== NULL
) {
314 data_blob_free(&out_blob
);
315 TALLOC_FREE(session
);
316 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
321 * clear the session key
322 * the first tcon will add setup the application key
324 data_blob_clear_free(&session_info
->session_key
);
327 session
->compat
= talloc_zero(session
, struct user_struct
);
328 if (session
->compat
== NULL
) {
329 data_blob_free(&out_blob
);
330 TALLOC_FREE(session
);
331 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
334 session
->compat
->session
= session
;
335 session
->compat
->homes_snum
= -1;
336 session
->compat
->session_info
= session_info
;
337 session
->compat
->session_keystr
= NULL
;
338 session
->compat
->vuid
= session
->global
->session_wire_id
;
339 DLIST_ADD(sconn
->users
, session
->compat
);
342 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
343 session
->compat
->homes_snum
=
344 register_homes_share(session_info
->unix_info
->unix_name
);
347 if (srv_is_signing_negotiated(xconn
) &&
349 session
->global
->signing_key
.length
> 0)
352 * Try and turn on server signing on the first non-guest
355 srv_set_signing(xconn
,
356 session
->global
->signing_key
,
360 set_current_user_info(session_info
->unix_info
->sanitized_username
,
361 session_info
->unix_info
->unix_name
,
362 session_info
->info
->domain_name
);
364 session
->status
= NT_STATUS_OK
;
365 session
->global
->auth_session_info
= talloc_move(session
->global
,
367 session
->global
->auth_session_info_seqnum
+= 1;
368 session
->global
->channels
[0].auth_session_info_seqnum
=
369 session
->global
->auth_session_info_seqnum
;
370 session
->global
->auth_time
= now
;
371 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
372 session
->global
->expiration_time
=
373 gensec_expire_time(auth
->gensec
);
375 session
->global
->expiration_time
=
376 GENSEC_EXPIRE_TIME_INFINITY
;
379 if (!session_claim(session
)) {
380 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
381 (unsigned long long)session
->compat
->vuid
));
382 data_blob_free(&out_blob
);
383 TALLOC_FREE(session
);
384 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
388 status
= smbXsrv_session_update(session
);
389 if (!NT_STATUS_IS_OK(status
)) {
390 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
391 (unsigned long long)session
->compat
->vuid
,
393 data_blob_free(&out_blob
);
394 TALLOC_FREE(session
);
395 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
399 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
400 if (smb_bufsize
< SMB_BUFFER_SIZE_MIN
) {
401 reply_force_doserror(req
, ERRSRV
, ERRerror
);
404 xconn
->smb1
.sessions
.max_send
= smb_bufsize
;
405 xconn
->smb1
.sessions
.done_sesssetup
= true;
408 /* current_user_info is changed on new vuid */
409 reload_services(sconn
, conn_snum_used
, true);
410 } else if (NT_STATUS_IS_OK(status
)) {
411 struct auth_session_info
*session_info
= NULL
;
413 status
= gensec_session_info(auth
->gensec
,
416 if (!NT_STATUS_IS_OK(status
)) {
417 DEBUG(1,("Failed to generate session_info "
418 "(user and group token) for session setup: %s\n",
420 data_blob_free(&out_blob
);
421 TALLOC_FREE(session
);
422 reply_nterror(req
, nt_status_squash(status
));
426 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
431 * Keep the application key
433 data_blob_clear_free(&session_info
->session_key
);
434 session_info
->session_key
=
435 session
->global
->auth_session_info
->session_key
;
436 talloc_steal(session_info
, session_info
->session_key
.data
);
437 TALLOC_FREE(session
->global
->auth_session_info
);
439 session
->compat
->session_info
= session_info
;
441 session
->compat
->vuid
= session
->global
->session_wire_id
;
443 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
444 session
->compat
->homes_snum
=
445 register_homes_share(session_info
->unix_info
->unix_name
);
448 set_current_user_info(session_info
->unix_info
->sanitized_username
,
449 session_info
->unix_info
->unix_name
,
450 session_info
->info
->domain_name
);
452 session
->status
= NT_STATUS_OK
;
453 session
->global
->auth_session_info
= talloc_move(session
->global
,
455 session
->global
->auth_session_info_seqnum
+= 1;
456 session
->global
->channels
[0].auth_session_info_seqnum
=
457 session
->global
->auth_session_info_seqnum
;
458 session
->global
->auth_time
= now
;
459 if (client_caps
& CAP_DYNAMIC_REAUTH
) {
460 session
->global
->expiration_time
=
461 gensec_expire_time(auth
->gensec
);
463 session
->global
->expiration_time
=
464 GENSEC_EXPIRE_TIME_INFINITY
;
467 status
= smbXsrv_session_update(session
);
468 if (!NT_STATUS_IS_OK(status
)) {
469 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
470 (unsigned long long)session
->compat
->vuid
,
472 data_blob_free(&out_blob
);
473 TALLOC_FREE(session
);
474 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
478 conn_clear_vuid_caches(sconn
, session
->compat
->vuid
);
480 /* current_user_info is changed on new vuid */
481 reload_services(sconn
, conn_snum_used
, true);
484 vuid
= session
->global
->session_wire_id
;
486 reply_outbuf(req
, 4, 0);
488 SSVAL(req
->outbuf
, smb_uid
, vuid
);
489 SIVAL(req
->outbuf
, smb_rcls
, NT_STATUS_V(status
));
490 SSVAL(req
->outbuf
, smb_vwv0
, 0xFF); /* no chaining possible */
491 SSVAL(req
->outbuf
, smb_vwv2
, action
);
492 SSVAL(req
->outbuf
, smb_vwv3
, out_blob
.length
);
494 if (message_push_blob(&req
->outbuf
, out_blob
) == -1) {
495 data_blob_free(&out_blob
);
496 TALLOC_FREE(session
);
497 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
500 data_blob_free(&out_blob
);
502 if (push_signature(&req
->outbuf
) == -1) {
503 TALLOC_FREE(session
);
504 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
509 /****************************************************************************
510 On new VC == 0, shutdown *all* old connections and users.
511 It seems that only NT4.x does this. At W2K and above (XP etc.).
512 a new session setup with VC==0 is ignored.
513 ****************************************************************************/
515 struct shutdown_state
{
517 struct messaging_context
*msg_ctx
;
520 static int shutdown_other_smbds(struct smbXsrv_session_global0
*session
,
523 struct shutdown_state
*state
= (struct shutdown_state
*)private_data
;
524 struct server_id self_pid
= messaging_server_id(state
->msg_ctx
);
525 struct server_id pid
= session
->channels
[0].server_id
;
526 const char *addr
= session
->channels
[0].remote_address
;
527 struct server_id_buf tmp
;
529 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
530 server_id_str_buf(pid
, &tmp
), addr
));
532 if (!process_exists(pid
)) {
533 DEBUG(10, ("process does not exist\n"));
537 if (serverid_equal(&pid
, &self_pid
)) {
538 DEBUG(10, ("It's me\n"));
543 * here we use strstr() because 'addr'
544 * (session->channels[0].remote_address)
545 * contains a string like:
546 * 'ipv4:127.0.0.1:48163'
548 if (strstr(addr
, state
->ip
) == NULL
) {
549 DEBUG(10, ("%s does not match %s\n", state
->ip
, addr
));
553 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
554 "(IP %s)\n", (unsigned int)procid_to_pid(&pid
),
557 messaging_send(state
->msg_ctx
, pid
, MSG_SHUTDOWN
,
562 static void setup_new_vc_session(struct smbd_server_connection
*sconn
)
564 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
565 "compatible we would close all old resources.\n"));
568 invalidate_all_vuids();
570 if (lp_reset_on_zero_vc()) {
572 struct shutdown_state state
;
574 addr
= tsocket_address_inet_addr_string(
575 sconn
->remote_address
, talloc_tos());
580 state
.msg_ctx
= sconn
->msg_ctx
;
581 smbXsrv_session_global_traverse(shutdown_other_smbds
, &state
);
586 /****************************************************************************
587 Reply to a session setup command.
588 ****************************************************************************/
590 void reply_sesssetup_and_X(struct smb_request
*req
)
593 uint16_t smb_bufsize
;
596 DATA_BLOB plaintext_password
;
599 fstring sub_user
; /* Sanitised username for substituion */
601 const char *native_os
;
602 const char *native_lanman
;
603 const char *primary_domain
;
604 struct auth_usersupplied_info
*user_info
= NULL
;
605 struct auth_session_info
*session_info
= NULL
;
606 uint16_t smb_flag2
= req
->flags2
;
608 NTTIME now
= timeval_to_nttime(&req
->request_time
);
609 struct smbXsrv_session
*session
= NULL
;
611 struct smbXsrv_connection
*xconn
= req
->xconn
;
612 struct smbd_server_connection
*sconn
= req
->sconn
;
613 bool doencrypt
= xconn
->smb1
.negprot
.encrypted_passwords
;
614 bool signing_allowed
= false;
615 bool signing_mandatory
= false;
617 START_PROFILE(SMBsesssetupX
);
619 ZERO_STRUCT(lm_resp
);
620 ZERO_STRUCT(nt_resp
);
621 ZERO_STRUCT(plaintext_password
);
623 DEBUG(3,("wct=%d flg2=0x%x\n", req
->wct
, req
->flags2
));
625 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
) {
626 signing_allowed
= true;
628 if (req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) {
629 signing_mandatory
= true;
633 * We can call srv_set_signing_negotiated() each time.
634 * It finds out when it needs to turn into a noop
637 srv_set_signing_negotiated(xconn
,
641 /* a SPNEGO session setup has 12 command words, whereas a normal
642 NT1 session setup has 13. See the cifs spec. */
643 if (req
->wct
== 12 &&
644 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
646 if (!xconn
->smb1
.negprot
.spnego
) {
647 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
648 "at SPNEGO session setup when it was not "
650 reply_nterror(req
, nt_status_squash(
651 NT_STATUS_LOGON_FAILURE
));
652 END_PROFILE(SMBsesssetupX
);
656 if (SVAL(req
->vwv
+4, 0) == 0) {
657 setup_new_vc_session(req
->sconn
);
660 reply_sesssetup_and_X_spnego(req
);
661 END_PROFILE(SMBsesssetupX
);
665 smb_bufsize
= SVAL(req
->vwv
+2, 0);
667 if (get_Protocol() < PROTOCOL_NT1
) {
668 uint16_t passlen1
= SVAL(req
->vwv
+7, 0);
670 /* Never do NT status codes with protocols before NT1 as we
671 * don't get client caps. */
672 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES
);
674 if ((passlen1
> MAX_PASS_LEN
) || (passlen1
> req
->buflen
)) {
675 reply_nterror(req
, nt_status_squash(
676 NT_STATUS_INVALID_PARAMETER
));
677 END_PROFILE(SMBsesssetupX
);
682 lm_resp
= data_blob(req
->buf
, passlen1
);
684 plaintext_password
= data_blob(req
->buf
, passlen1
+1);
685 /* Ensure null termination */
686 plaintext_password
.data
[passlen1
] = 0;
689 srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
,
690 req
->buf
+ passlen1
, STR_TERMINATE
);
691 user
= tmp
? tmp
: "";
696 uint16_t passlen1
= SVAL(req
->vwv
+7, 0);
697 uint16_t passlen2
= SVAL(req
->vwv
+8, 0);
698 enum remote_arch_types ra_type
= get_remote_arch();
699 const uint8_t *p
= req
->buf
;
700 const uint8_t *save_p
= req
->buf
;
703 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
704 global_client_caps
= IVAL(req
->vwv
+11, 0);
706 if (!(global_client_caps
& CAP_STATUS32
)) {
707 remove_from_common_flags2(
708 FLAGS2_32_BIT_ERROR_CODES
);
711 /* client_caps is used as final determination if
712 * client is NT or Win95. This is needed to return
713 * the correct error codes in some circumstances.
716 if(ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
||
717 ra_type
== RA_WIN95
) {
718 if(!(global_client_caps
& (CAP_NT_SMBS
|
720 set_remote_arch( RA_WIN95
);
726 /* both Win95 and WinNT stuff up the password
727 * lengths for non-encrypting systems. Uggh.
729 if passlen1==24 its a win95 system, and its setting
730 the password length incorrectly. Luckily it still
731 works with the default code because Win95 will null
732 terminate the password anyway
734 if passlen1>0 and passlen2>0 then maybe its a NT box
735 and its setting passlen2 to some random value which
736 really stuffs things up. we need to fix that one. */
738 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 24 &&
744 /* check for nasty tricks */
745 if (passlen1
> MAX_PASS_LEN
746 || passlen1
> smbreq_bufrem(req
, p
)) {
747 reply_nterror(req
, nt_status_squash(
748 NT_STATUS_INVALID_PARAMETER
));
749 END_PROFILE(SMBsesssetupX
);
753 if (passlen2
> MAX_PASS_LEN
754 || passlen2
> smbreq_bufrem(req
, p
+passlen1
)) {
755 reply_nterror(req
, nt_status_squash(
756 NT_STATUS_INVALID_PARAMETER
));
757 END_PROFILE(SMBsesssetupX
);
761 /* Save the lanman2 password and the NT md4 password. */
763 if ((doencrypt
) && (passlen1
!= 0) && (passlen1
!= 24)) {
768 lm_resp
= data_blob(p
, passlen1
);
769 nt_resp
= data_blob(p
+passlen1
, passlen2
);
772 bool unic
= smb_flag2
& FLAGS2_UNICODE_STRINGS
;
774 if (unic
&& (passlen2
== 0) && passlen1
) {
775 /* Only a ascii plaintext password was sent. */
776 (void)srvstr_pull_talloc(talloc_tos(),
782 STR_TERMINATE
|STR_ASCII
);
784 (void)srvstr_pull_talloc(talloc_tos(),
789 unic
? passlen2
: passlen1
,
793 reply_nterror(req
, nt_status_squash(
794 NT_STATUS_INVALID_PARAMETER
));
795 END_PROFILE(SMBsesssetupX
);
798 plaintext_password
= data_blob(pass
, strlen(pass
)+1);
801 p
+= passlen1
+ passlen2
;
803 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
805 user
= tmp
? tmp
: "";
807 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
809 domain
= tmp
? tmp
: "";
811 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
813 native_os
= tmp
? tmp
: "";
815 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
817 native_lanman
= tmp
? tmp
: "";
819 /* not documented or decoded by Ethereal but there is one more
820 * string in the extra bytes which is the same as the
821 * PrimaryDomain when using extended security. Windows NT 4
822 * and 2003 use this string to store the native lanman string.
823 * Windows 9x does not include a string here at all so we have
824 * to check if we have any extra bytes left */
826 byte_count
= SVAL(req
->vwv
+13, 0);
827 if ( PTR_DIFF(p
, save_p
) < byte_count
) {
828 p
+= srvstr_pull_req_talloc(talloc_tos(), req
, &tmp
, p
,
830 primary_domain
= tmp
? tmp
: "";
832 primary_domain
= talloc_strdup(talloc_tos(), "null");
835 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
836 "PrimaryDomain=[%s]\n",
837 domain
, native_os
, native_lanman
, primary_domain
));
839 if ( ra_type
== RA_WIN2K
) {
840 if ( strlen(native_lanman
) == 0 )
841 ra_lanman_string( primary_domain
);
843 ra_lanman_string( native_lanman
);
848 if (SVAL(req
->vwv
+4, 0) == 0) {
849 setup_new_vc_session(req
->sconn
);
852 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
853 domain
, user
, get_remote_machine_name()));
856 if (xconn
->smb1
.negprot
.spnego
) {
858 /* This has to be here, because this is a perfectly
859 * valid behaviour for guest logons :-( */
861 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
862 "at 'normal' session setup after "
863 "negotiating spnego.\n"));
864 reply_nterror(req
, nt_status_squash(
865 NT_STATUS_LOGON_FAILURE
));
866 END_PROFILE(SMBsesssetupX
);
869 fstrcpy(sub_user
, user
);
871 fstrcpy(sub_user
, "");
874 sub_set_smb_name(sub_user
);
876 reload_services(sconn
, conn_snum_used
, true);
880 nt_status
= check_guest_password(sconn
->remote_address
, req
, &session_info
);
882 } else if (doencrypt
) {
883 struct auth4_context
*negprot_auth_context
= NULL
;
884 negprot_auth_context
= xconn
->smb1
.negprot
.auth_context
;
885 if (!negprot_auth_context
) {
886 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
887 "session setup without negprot denied!\n"));
888 reply_nterror(req
, nt_status_squash(
889 NT_STATUS_LOGON_FAILURE
));
890 END_PROFILE(SMBsesssetupX
);
893 nt_status
= make_user_info_for_reply_enc(talloc_tos(),
896 sconn
->remote_address
,
898 if (NT_STATUS_IS_OK(nt_status
)) {
899 nt_status
= auth_check_password_session_info(negprot_auth_context
,
900 req
, user_info
, &session_info
);
903 struct auth4_context
*plaintext_auth_context
= NULL
;
905 nt_status
= make_auth4_context(
906 talloc_tos(), &plaintext_auth_context
);
908 if (NT_STATUS_IS_OK(nt_status
)) {
911 plaintext_auth_context
->get_ntlm_challenge(
912 plaintext_auth_context
, chal
);
914 if (!make_user_info_for_reply(talloc_tos(),
917 sconn
->remote_address
,
919 plaintext_password
)) {
920 nt_status
= NT_STATUS_NO_MEMORY
;
923 if (NT_STATUS_IS_OK(nt_status
)) {
924 nt_status
= auth_check_password_session_info(plaintext_auth_context
,
925 req
, user_info
, &session_info
);
927 TALLOC_FREE(plaintext_auth_context
);
931 TALLOC_FREE(user_info
);
933 if (!NT_STATUS_IS_OK(nt_status
)) {
934 data_blob_free(&nt_resp
);
935 data_blob_free(&lm_resp
);
936 data_blob_clear_free(&plaintext_password
);
937 reply_nterror(req
, nt_status_squash(nt_status
));
938 END_PROFILE(SMBsesssetupX
);
942 data_blob_clear_free(&plaintext_password
);
944 /* it's ok - setup a reply */
945 reply_outbuf(req
, 3, 0);
946 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
947 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
949 if (get_Protocol() >= PROTOCOL_NT1
) {
950 push_signature(&req
->outbuf
);
951 /* perhaps grab OS version here?? */
954 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
958 /* register the name and uid as being validated, so further connections
959 to a uid can get through without a password, on the same VC */
961 nt_status
= smbXsrv_session_create(xconn
,
963 if (!NT_STATUS_IS_OK(nt_status
)) {
964 data_blob_free(&nt_resp
);
965 data_blob_free(&lm_resp
);
966 reply_nterror(req
, nt_status_squash(nt_status
));
967 END_PROFILE(SMBsesssetupX
);
971 if (session_info
->session_key
.length
> 0) {
972 uint8_t session_key
[16];
975 * Note: the SMB1 signing key is not truncated to 16 byte!
977 session
->global
->signing_key
=
978 data_blob_dup_talloc(session
->global
,
979 session_info
->session_key
);
980 if (session
->global
->signing_key
.data
== NULL
) {
981 data_blob_free(&nt_resp
);
982 data_blob_free(&lm_resp
);
983 TALLOC_FREE(session
);
984 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
985 END_PROFILE(SMBsesssetupX
);
990 * The application key is truncated/padded to 16 bytes
992 ZERO_STRUCT(session_key
);
993 memcpy(session_key
, session
->global
->signing_key
.data
,
994 MIN(session
->global
->signing_key
.length
,
995 sizeof(session_key
)));
996 session
->global
->application_key
=
997 data_blob_talloc(session
->global
,
999 sizeof(session_key
));
1000 ZERO_STRUCT(session_key
);
1001 if (session
->global
->application_key
.data
== NULL
) {
1002 data_blob_free(&nt_resp
);
1003 data_blob_free(&lm_resp
);
1004 TALLOC_FREE(session
);
1005 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1006 END_PROFILE(SMBsesssetupX
);
1011 * Place the application key into the session_info
1013 data_blob_clear_free(&session_info
->session_key
);
1014 session_info
->session_key
= data_blob_dup_talloc(session_info
,
1015 session
->global
->application_key
);
1016 if (session_info
->session_key
.data
== NULL
) {
1017 data_blob_free(&nt_resp
);
1018 data_blob_free(&lm_resp
);
1019 TALLOC_FREE(session
);
1020 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1021 END_PROFILE(SMBsesssetupX
);
1026 session
->compat
= talloc_zero(session
, struct user_struct
);
1027 if (session
->compat
== NULL
) {
1028 data_blob_free(&nt_resp
);
1029 data_blob_free(&lm_resp
);
1030 TALLOC_FREE(session
);
1031 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1032 END_PROFILE(SMBsesssetupX
);
1035 session
->compat
->session
= session
;
1036 session
->compat
->homes_snum
= -1;
1037 session
->compat
->session_info
= session_info
;
1038 session
->compat
->session_keystr
= NULL
;
1039 session
->compat
->vuid
= session
->global
->session_wire_id
;
1040 DLIST_ADD(sconn
->users
, session
->compat
);
1043 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
1044 session
->compat
->homes_snum
=
1045 register_homes_share(session_info
->unix_info
->unix_name
);
1048 if (srv_is_signing_negotiated(xconn
) &&
1050 session
->global
->signing_key
.length
> 0)
1053 * Try and turn on server signing on the first non-guest
1056 srv_set_signing(xconn
,
1057 session
->global
->signing_key
,
1058 nt_resp
.data
? nt_resp
: lm_resp
);
1061 set_current_user_info(session_info
->unix_info
->sanitized_username
,
1062 session_info
->unix_info
->unix_name
,
1063 session_info
->info
->domain_name
);
1065 session
->status
= NT_STATUS_OK
;
1066 session
->global
->auth_session_info
= talloc_move(session
->global
,
1068 session
->global
->auth_session_info_seqnum
+= 1;
1069 session
->global
->channels
[0].auth_session_info_seqnum
=
1070 session
->global
->auth_session_info_seqnum
;
1071 session
->global
->auth_time
= now
;
1072 session
->global
->expiration_time
= GENSEC_EXPIRE_TIME_INFINITY
;
1074 nt_status
= smbXsrv_session_update(session
);
1075 if (!NT_STATUS_IS_OK(nt_status
)) {
1076 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1077 (unsigned long long)session
->compat
->vuid
,
1078 nt_errstr(nt_status
)));
1079 data_blob_free(&nt_resp
);
1080 data_blob_free(&lm_resp
);
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
->compat
->vuid
));
1090 data_blob_free(&nt_resp
);
1091 data_blob_free(&lm_resp
);
1092 TALLOC_FREE(session
);
1093 reply_nterror(req
, NT_STATUS_LOGON_FAILURE
);
1094 END_PROFILE(SMBsesssetupX
);
1098 /* current_user_info is changed on new vuid */
1099 reload_services(sconn
, conn_snum_used
, true);
1101 sess_vuid
= session
->global
->session_wire_id
;
1103 data_blob_free(&nt_resp
);
1104 data_blob_free(&lm_resp
);
1106 SSVAL(req
->outbuf
,smb_vwv2
,action
);
1107 SSVAL(req
->outbuf
,smb_uid
,sess_vuid
);
1108 SSVAL(discard_const_p(char, req
->inbuf
),smb_uid
,sess_vuid
);
1109 req
->vuid
= sess_vuid
;
1111 if (!xconn
->smb1
.sessions
.done_sesssetup
) {
1112 if (smb_bufsize
< SMB_BUFFER_SIZE_MIN
) {
1113 reply_force_doserror(req
, ERRSRV
, ERRerror
);
1114 END_PROFILE(SMBsesssetupX
);
1117 xconn
->smb1
.sessions
.max_send
= smb_bufsize
;
1118 xconn
->smb1
.sessions
.done_sesssetup
= true;
1121 END_PROFILE(SMBsesssetupX
);