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;
130 uint16 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 smbd_server_connection *sconn = req->sconn;
136 NTTIME now = timeval_to_nttime(&req->request_time);
137 struct smbXsrv_session *session = NULL;
138 uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
139 uint32_t client_caps = IVAL(req->vwv+10, 0);
141 DEBUG(3,("Doing spnego session setup\n"));
143 if (!sconn->smb1.sessions.done_sesssetup) {
144 global_client_caps = client_caps;
146 if (!(global_client_caps & CAP_STATUS32)) {
147 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
153 if (data_blob_len == 0) {
154 /* an invalid request */
155 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
159 bufrem = smbreq_bufrem(req, p);
160 /* pull the spnego blob */
161 in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
164 file_save("negotiate.dat", in_blob.data, in_blob.length);
167 p = req->buf + in_blob.length;
169 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
171 native_os = tmp ? tmp : "";
173 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
175 native_lanman = tmp ? tmp : "";
177 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
179 primary_domain = tmp ? tmp : "";
181 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
182 native_os, native_lanman, primary_domain));
184 if ( ra_type == RA_WIN2K ) {
185 /* Vista sets neither the OS or lanman strings */
187 if ( !strlen(native_os) && !strlen(native_lanman) )
188 set_remote_arch(RA_VISTA);
190 /* Windows 2003 doesn't set the native lanman string,
191 but does set primary domain which is a bug I think */
193 if ( !strlen(native_lanman) ) {
194 ra_lanman_string( primary_domain );
196 ra_lanman_string( native_lanman );
198 } else if ( ra_type == RA_VISTA ) {
199 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
200 set_remote_arch(RA_OSX);
205 status = smb1srv_session_lookup(sconn->conn,
208 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
209 reply_force_doserror(req, ERRSRV, ERRbaduid);
212 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
213 status = NT_STATUS_OK;
215 if (NT_STATUS_IS_OK(status)) {
216 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
217 status = NT_STATUS_MORE_PROCESSING_REQUIRED;
218 TALLOC_FREE(session->gensec);
220 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
221 reply_nterror(req, nt_status_squash(status));
226 if (session == NULL) {
227 /* create a new session */
228 status = smbXsrv_session_create(sconn->conn,
230 if (!NT_STATUS_IS_OK(status)) {
231 reply_nterror(req, nt_status_squash(status));
236 if (!session->gensec) {
237 status = auth_generic_prepare(session, sconn->remote_address,
239 if (!NT_STATUS_IS_OK(status)) {
240 TALLOC_FREE(session);
241 reply_nterror(req, nt_status_squash(status));
245 gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
246 gensec_want_feature(session->gensec, GENSEC_FEATURE_UNIX_TOKEN);
248 status = gensec_start_mech_by_oid(session->gensec,
250 if (!NT_STATUS_IS_OK(status)) {
251 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
252 TALLOC_FREE(session);;
253 reply_nterror(req, nt_status_squash(status));
259 status = gensec_update(session->gensec,
263 if (!NT_STATUS_IS_OK(status) &&
264 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
265 TALLOC_FREE(session);
266 reply_nterror(req, nt_status_squash(status));
270 if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
271 struct auth_session_info *session_info = NULL;
273 status = gensec_session_info(session->gensec,
276 if (!NT_STATUS_IS_OK(status)) {
277 DEBUG(1,("Failed to generate session_info "
278 "(user and group token) for session setup: %s\n",
280 data_blob_free(&out_blob);
281 TALLOC_FREE(session);
282 reply_nterror(req, nt_status_squash(status));
286 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
290 if (session_info->session_key.length > 0) {
291 struct smbXsrv_session *x = session;
294 * Note: the SMB1 signing key is not truncated to 16 byte!
296 x->global->signing_key =
297 data_blob_dup_talloc(x->global,
298 session_info->session_key);
299 if (x->global->signing_key.data == NULL) {
300 data_blob_free(&out_blob);
301 TALLOC_FREE(session);
302 reply_nterror(req, NT_STATUS_NO_MEMORY);
307 * clear the session key
308 * the first tcon will add setup the application key
310 data_blob_clear_free(&session_info->session_key);
313 session->compat = talloc_zero(session, struct user_struct);
314 if (session->compat == NULL) {
315 data_blob_free(&out_blob);
316 TALLOC_FREE(session);
317 reply_nterror(req, NT_STATUS_NO_MEMORY);
320 session->compat->session = session;
321 session->compat->homes_snum = -1;
322 session->compat->session_info = session_info;
323 session->compat->session_keystr = NULL;
324 session->compat->vuid = session->global->session_wire_id;
325 DLIST_ADD(sconn->users, session->compat);
328 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
329 session->compat->homes_snum =
330 register_homes_share(session_info->unix_info->unix_name);
333 if (srv_is_signing_negotiated(sconn) &&
335 session->global->signing_key.length > 0)
338 * Try and turn on server signing on the first non-guest
341 srv_set_signing(sconn,
342 session->global->signing_key,
346 set_current_user_info(session_info->unix_info->sanitized_username,
347 session_info->unix_info->unix_name,
348 session_info->info->domain_name);
350 session->status = NT_STATUS_OK;
351 session->global->auth_session_info = talloc_move(session->global,
353 session->global->auth_session_info_seqnum += 1;
354 session->global->channels[0].auth_session_info_seqnum =
355 session->global->auth_session_info_seqnum;
356 if (client_caps & CAP_DYNAMIC_REAUTH) {
357 session->global->expiration_time =
358 gensec_expire_time(session->gensec);
360 session->global->expiration_time =
361 GENSEC_EXPIRE_TIME_INFINITY;
364 if (!session_claim(session)) {
365 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
366 (unsigned long long)session->compat->vuid));
367 data_blob_free(&out_blob);
368 TALLOC_FREE(session);
369 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
373 status = smbXsrv_session_update(session);
374 if (!NT_STATUS_IS_OK(status)) {
375 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
376 (unsigned long long)session->compat->vuid,
378 data_blob_free(&out_blob);
379 TALLOC_FREE(session);
380 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
384 if (!sconn->smb1.sessions.done_sesssetup) {
385 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
386 reply_force_doserror(req, ERRSRV, ERRerror);
389 sconn->smb1.sessions.max_send = smb_bufsize;
390 sconn->smb1.sessions.done_sesssetup = true;
393 /* current_user_info is changed on new vuid */
394 reload_services(sconn, conn_snum_used, true);
395 } else if (NT_STATUS_IS_OK(status)) {
396 struct auth_session_info *session_info = NULL;
398 status = gensec_session_info(session->gensec,
401 if (!NT_STATUS_IS_OK(status)) {
402 DEBUG(1,("Failed to generate session_info "
403 "(user and group token) for session setup: %s\n",
405 data_blob_free(&out_blob);
406 TALLOC_FREE(session);
407 reply_nterror(req, nt_status_squash(status));
411 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
416 * Keep the application key
418 data_blob_clear_free(&session_info->session_key);
419 session_info->session_key =
420 session->global->auth_session_info->session_key;
421 talloc_steal(session_info, session_info->session_key.data);
422 TALLOC_FREE(session->global->auth_session_info);
424 session->compat->session_info = session_info;
426 session->compat->vuid = session->global->session_wire_id;
428 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
429 session->compat->homes_snum =
430 register_homes_share(session_info->unix_info->unix_name);
433 set_current_user_info(session_info->unix_info->sanitized_username,
434 session_info->unix_info->unix_name,
435 session_info->info->domain_name);
437 session->status = NT_STATUS_OK;
438 session->global->auth_session_info = talloc_move(session->global,
440 session->global->auth_session_info_seqnum += 1;
441 session->global->channels[0].auth_session_info_seqnum =
442 session->global->auth_session_info_seqnum;
443 if (client_caps & CAP_DYNAMIC_REAUTH) {
444 session->global->expiration_time =
445 gensec_expire_time(session->gensec);
447 session->global->expiration_time =
448 GENSEC_EXPIRE_TIME_INFINITY;
451 status = smbXsrv_session_update(session);
452 if (!NT_STATUS_IS_OK(status)) {
453 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
454 (unsigned long long)session->compat->vuid,
456 data_blob_free(&out_blob);
457 TALLOC_FREE(session);
458 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
462 conn_clear_vuid_caches(sconn, session->compat->vuid);
464 /* current_user_info is changed on new vuid */
465 reload_services(sconn, conn_snum_used, true);
468 vuid = session->global->session_wire_id;
470 reply_outbuf(req, 4, 0);
472 SSVAL(req->outbuf, smb_uid, vuid);
473 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
474 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
475 SSVAL(req->outbuf, smb_vwv2, action);
476 SSVAL(req->outbuf, smb_vwv3, out_blob.length);
478 if (message_push_blob(&req->outbuf, out_blob) == -1) {
479 data_blob_free(&out_blob);
480 TALLOC_FREE(session);
481 reply_nterror(req, NT_STATUS_NO_MEMORY);
484 data_blob_free(&out_blob);
486 if (push_signature(&req->outbuf) == -1) {
487 TALLOC_FREE(session);
488 reply_nterror(req, NT_STATUS_NO_MEMORY);
493 /****************************************************************************
494 On new VC == 0, shutdown *all* old connections and users.
495 It seems that only NT4.x does this. At W2K and above (XP etc.).
496 a new session setup with VC==0 is ignored.
497 ****************************************************************************/
499 struct shutdown_state {
501 struct messaging_context *msg_ctx;
504 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
507 struct shutdown_state *state = (struct shutdown_state *)private_data;
508 struct server_id self_pid = messaging_server_id(state->msg_ctx);
509 struct server_id pid = session->channels[0].server_id;
510 const char *addr = session->channels[0].remote_address;
512 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
513 server_id_str(talloc_tos(), &pid), addr));
515 if (!process_exists(pid)) {
516 DEBUG(10, ("process does not exist\n"));
520 if (serverid_equal(&pid, &self_pid)) {
521 DEBUG(10, ("It's me\n"));
526 * here we use strstr() because 'addr'
527 * (session->channels[0].remote_address)
528 * contains a string like:
529 * 'ipv4:127.0.0.1:48163'
531 if (strstr(addr, state->ip) == NULL) {
532 DEBUG(10, ("%s does not match %s\n", state->ip, addr));
536 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
537 "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
540 messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
545 static void setup_new_vc_session(struct smbd_server_connection *sconn)
547 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
548 "compatible we would close all old resources.\n"));
551 invalidate_all_vuids();
553 if (lp_reset_on_zero_vc()) {
555 struct shutdown_state state;
557 addr = tsocket_address_inet_addr_string(
558 sconn->remote_address, talloc_tos());
563 state.msg_ctx = sconn->msg_ctx;
564 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
569 /****************************************************************************
570 Reply to a session setup command.
571 ****************************************************************************/
573 void reply_sesssetup_and_X(struct smb_request *req)
576 uint16_t smb_bufsize;
579 DATA_BLOB plaintext_password;
582 fstring sub_user; /* Sanitised username for substituion */
584 const char *native_os;
585 const char *native_lanman;
586 const char *primary_domain;
587 struct auth_usersupplied_info *user_info = NULL;
588 struct auth_session_info *session_info = NULL;
589 uint16 smb_flag2 = req->flags2;
591 NTTIME now = timeval_to_nttime(&req->request_time);
592 struct smbXsrv_session *session = NULL;
595 struct smbd_server_connection *sconn = req->sconn;
597 bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
598 bool signing_allowed = false;
599 bool signing_mandatory = false;
601 START_PROFILE(SMBsesssetupX);
603 ZERO_STRUCT(lm_resp);
604 ZERO_STRUCT(nt_resp);
605 ZERO_STRUCT(plaintext_password);
607 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
609 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
610 signing_allowed = true;
612 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
613 signing_mandatory = true;
617 * We can call srv_set_signing_negotiated() each time.
618 * It finds out when it needs to turn into a noop
621 srv_set_signing_negotiated(req->sconn,
625 /* a SPNEGO session setup has 12 command words, whereas a normal
626 NT1 session setup has 13. See the cifs spec. */
627 if (req->wct == 12 &&
628 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
630 if (!sconn->smb1.negprot.spnego) {
631 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
632 "at SPNEGO session setup when it was not "
634 reply_nterror(req, nt_status_squash(
635 NT_STATUS_LOGON_FAILURE));
636 END_PROFILE(SMBsesssetupX);
640 if (SVAL(req->vwv+4, 0) == 0) {
641 setup_new_vc_session(req->sconn);
644 reply_sesssetup_and_X_spnego(req);
645 END_PROFILE(SMBsesssetupX);
649 smb_bufsize = SVAL(req->vwv+2, 0);
651 if (get_Protocol() < PROTOCOL_NT1) {
652 uint16 passlen1 = SVAL(req->vwv+7, 0);
654 /* Never do NT status codes with protocols before NT1 as we
655 * don't get client caps. */
656 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
658 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
659 reply_nterror(req, nt_status_squash(
660 NT_STATUS_INVALID_PARAMETER));
661 END_PROFILE(SMBsesssetupX);
666 lm_resp = data_blob(req->buf, passlen1);
668 plaintext_password = data_blob(req->buf, passlen1+1);
669 /* Ensure null termination */
670 plaintext_password.data[passlen1] = 0;
673 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
674 req->buf + passlen1, STR_TERMINATE);
675 user = tmp ? tmp : "";
680 uint16 passlen1 = SVAL(req->vwv+7, 0);
681 uint16 passlen2 = SVAL(req->vwv+8, 0);
682 enum remote_arch_types ra_type = get_remote_arch();
683 const uint8_t *p = req->buf;
684 const uint8_t *save_p = req->buf;
687 if (!sconn->smb1.sessions.done_sesssetup) {
688 global_client_caps = IVAL(req->vwv+11, 0);
690 if (!(global_client_caps & CAP_STATUS32)) {
691 remove_from_common_flags2(
692 FLAGS2_32_BIT_ERROR_CODES);
695 /* client_caps is used as final determination if
696 * client is NT or Win95. This is needed to return
697 * the correct error codes in some circumstances.
700 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
701 ra_type == RA_WIN95) {
702 if(!(global_client_caps & (CAP_NT_SMBS|
704 set_remote_arch( RA_WIN95);
710 /* both Win95 and WinNT stuff up the password
711 * lengths for non-encrypting systems. Uggh.
713 if passlen1==24 its a win95 system, and its setting
714 the password length incorrectly. Luckily it still
715 works with the default code because Win95 will null
716 terminate the password anyway
718 if passlen1>0 and passlen2>0 then maybe its a NT box
719 and its setting passlen2 to some random value which
720 really stuffs things up. we need to fix that one. */
722 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
728 /* check for nasty tricks */
729 if (passlen1 > MAX_PASS_LEN
730 || passlen1 > smbreq_bufrem(req, p)) {
731 reply_nterror(req, nt_status_squash(
732 NT_STATUS_INVALID_PARAMETER));
733 END_PROFILE(SMBsesssetupX);
737 if (passlen2 > MAX_PASS_LEN
738 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
739 reply_nterror(req, nt_status_squash(
740 NT_STATUS_INVALID_PARAMETER));
741 END_PROFILE(SMBsesssetupX);
745 /* Save the lanman2 password and the NT md4 password. */
747 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
752 lm_resp = data_blob(p, passlen1);
753 nt_resp = data_blob(p+passlen1, passlen2);
756 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
758 if (unic && (passlen2 == 0) && passlen1) {
759 /* Only a ascii plaintext password was sent. */
760 (void)srvstr_pull_talloc(talloc_tos(),
766 STR_TERMINATE|STR_ASCII);
768 (void)srvstr_pull_talloc(talloc_tos(),
773 unic ? passlen2 : passlen1,
777 reply_nterror(req, nt_status_squash(
778 NT_STATUS_INVALID_PARAMETER));
779 END_PROFILE(SMBsesssetupX);
782 plaintext_password = data_blob(pass, strlen(pass)+1);
785 p += passlen1 + passlen2;
787 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
789 user = tmp ? tmp : "";
791 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
793 domain = tmp ? tmp : "";
795 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
797 native_os = tmp ? tmp : "";
799 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
801 native_lanman = tmp ? tmp : "";
803 /* not documented or decoded by Ethereal but there is one more
804 * string in the extra bytes which is the same as the
805 * PrimaryDomain when using extended security. Windows NT 4
806 * and 2003 use this string to store the native lanman string.
807 * Windows 9x does not include a string here at all so we have
808 * to check if we have any extra bytes left */
810 byte_count = SVAL(req->vwv+13, 0);
811 if ( PTR_DIFF(p, save_p) < byte_count) {
812 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
814 primary_domain = tmp ? tmp : "";
816 primary_domain = talloc_strdup(talloc_tos(), "null");
819 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
820 "PrimaryDomain=[%s]\n",
821 domain, native_os, native_lanman, primary_domain));
823 if ( ra_type == RA_WIN2K ) {
824 if ( strlen(native_lanman) == 0 )
825 ra_lanman_string( primary_domain );
827 ra_lanman_string( native_lanman );
832 if (SVAL(req->vwv+4, 0) == 0) {
833 setup_new_vc_session(req->sconn);
836 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
837 domain, user, get_remote_machine_name()));
840 if (sconn->smb1.negprot.spnego) {
842 /* This has to be here, because this is a perfectly
843 * valid behaviour for guest logons :-( */
845 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
846 "at 'normal' session setup after "
847 "negotiating spnego.\n"));
848 reply_nterror(req, nt_status_squash(
849 NT_STATUS_LOGON_FAILURE));
850 END_PROFILE(SMBsesssetupX);
853 fstrcpy(sub_user, user);
855 fstrcpy(sub_user, "");
858 sub_set_smb_name(sub_user);
860 reload_services(sconn, conn_snum_used, true);
864 nt_status = check_guest_password(sconn->remote_address, req, &session_info);
866 } else if (doencrypt) {
867 struct auth4_context *negprot_auth_context = NULL;
868 negprot_auth_context = sconn->smb1.negprot.auth_context;
869 if (!negprot_auth_context) {
870 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
871 "session setup without negprot denied!\n"));
872 reply_nterror(req, nt_status_squash(
873 NT_STATUS_LOGON_FAILURE));
874 END_PROFILE(SMBsesssetupX);
877 nt_status = make_user_info_for_reply_enc(&user_info, user,
879 sconn->remote_address,
881 if (NT_STATUS_IS_OK(nt_status)) {
882 nt_status = auth_check_password_session_info(negprot_auth_context,
883 req, user_info, &session_info);
886 struct auth4_context *plaintext_auth_context = NULL;
888 nt_status = make_auth4_context(
889 talloc_tos(), &plaintext_auth_context);
891 if (NT_STATUS_IS_OK(nt_status)) {
894 plaintext_auth_context->get_ntlm_challenge(
895 plaintext_auth_context, chal);
897 if (!make_user_info_for_reply(&user_info,
899 sconn->remote_address,
901 plaintext_password)) {
902 nt_status = NT_STATUS_NO_MEMORY;
905 if (NT_STATUS_IS_OK(nt_status)) {
906 nt_status = auth_check_password_session_info(plaintext_auth_context,
907 req, user_info, &session_info);
909 TALLOC_FREE(plaintext_auth_context);
913 free_user_info(&user_info);
915 if (!NT_STATUS_IS_OK(nt_status)) {
916 data_blob_free(&nt_resp);
917 data_blob_free(&lm_resp);
918 data_blob_clear_free(&plaintext_password);
919 reply_nterror(req, nt_status_squash(nt_status));
920 END_PROFILE(SMBsesssetupX);
924 data_blob_clear_free(&plaintext_password);
926 /* it's ok - setup a reply */
927 reply_outbuf(req, 3, 0);
928 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
929 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
931 if (get_Protocol() >= PROTOCOL_NT1) {
932 push_signature(&req->outbuf);
933 /* perhaps grab OS version here?? */
936 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
940 /* register the name and uid as being validated, so further connections
941 to a uid can get through without a password, on the same VC */
943 nt_status = smbXsrv_session_create(sconn->conn,
945 if (!NT_STATUS_IS_OK(nt_status)) {
946 data_blob_free(&nt_resp);
947 data_blob_free(&lm_resp);
948 reply_nterror(req, nt_status_squash(nt_status));
949 END_PROFILE(SMBsesssetupX);
953 if (session_info->session_key.length > 0) {
954 uint8_t session_key[16];
957 * Note: the SMB1 signing key is not truncated to 16 byte!
959 session->global->signing_key =
960 data_blob_dup_talloc(session->global,
961 session_info->session_key);
962 if (session->global->signing_key.data == NULL) {
963 data_blob_free(&nt_resp);
964 data_blob_free(&lm_resp);
965 TALLOC_FREE(session);
966 reply_nterror(req, NT_STATUS_NO_MEMORY);
967 END_PROFILE(SMBsesssetupX);
972 * The application key is truncated/padded to 16 bytes
974 ZERO_STRUCT(session_key);
975 memcpy(session_key, session->global->signing_key.data,
976 MIN(session->global->signing_key.length,
977 sizeof(session_key)));
978 session->global->application_key =
979 data_blob_talloc(session->global,
981 sizeof(session_key));
982 ZERO_STRUCT(session_key);
983 if (session->global->application_key.data == NULL) {
984 data_blob_free(&nt_resp);
985 data_blob_free(&lm_resp);
986 TALLOC_FREE(session);
987 reply_nterror(req, NT_STATUS_NO_MEMORY);
988 END_PROFILE(SMBsesssetupX);
993 * Place the application key into the session_info
995 data_blob_clear_free(&session_info->session_key);
996 session_info->session_key = data_blob_dup_talloc(session_info,
997 session->global->application_key);
998 if (session_info->session_key.data == NULL) {
999 data_blob_free(&nt_resp);
1000 data_blob_free(&lm_resp);
1001 TALLOC_FREE(session);
1002 reply_nterror(req, NT_STATUS_NO_MEMORY);
1003 END_PROFILE(SMBsesssetupX);
1008 session->compat = talloc_zero(session, struct user_struct);
1009 if (session->compat == NULL) {
1010 data_blob_free(&nt_resp);
1011 data_blob_free(&lm_resp);
1012 TALLOC_FREE(session);
1013 reply_nterror(req, NT_STATUS_NO_MEMORY);
1014 END_PROFILE(SMBsesssetupX);
1017 session->compat->session = session;
1018 session->compat->homes_snum = -1;
1019 session->compat->session_info = session_info;
1020 session->compat->session_keystr = NULL;
1021 session->compat->vuid = session->global->session_wire_id;
1022 DLIST_ADD(sconn->users, session->compat);
1025 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1026 session->compat->homes_snum =
1027 register_homes_share(session_info->unix_info->unix_name);
1030 if (srv_is_signing_negotiated(sconn) &&
1032 session->global->signing_key.length > 0)
1035 * Try and turn on server signing on the first non-guest
1038 srv_set_signing(sconn,
1039 session->global->signing_key,
1040 nt_resp.data ? nt_resp : lm_resp);
1043 set_current_user_info(session_info->unix_info->sanitized_username,
1044 session_info->unix_info->unix_name,
1045 session_info->info->domain_name);
1047 session->status = NT_STATUS_OK;
1048 session->global->auth_session_info = talloc_move(session->global,
1050 session->global->auth_session_info_seqnum += 1;
1051 session->global->channels[0].auth_session_info_seqnum =
1052 session->global->auth_session_info_seqnum;
1053 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1055 nt_status = smbXsrv_session_update(session);
1056 if (!NT_STATUS_IS_OK(nt_status)) {
1057 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1058 (unsigned long long)session->compat->vuid,
1059 nt_errstr(nt_status)));
1060 data_blob_free(&nt_resp);
1061 data_blob_free(&lm_resp);
1062 TALLOC_FREE(session);
1063 reply_nterror(req, nt_status_squash(nt_status));
1064 END_PROFILE(SMBsesssetupX);
1068 if (!session_claim(session)) {
1069 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1070 (unsigned long long)session->compat->vuid));
1071 data_blob_free(&nt_resp);
1072 data_blob_free(&lm_resp);
1073 TALLOC_FREE(session);
1074 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1075 END_PROFILE(SMBsesssetupX);
1079 /* current_user_info is changed on new vuid */
1080 reload_services(sconn, conn_snum_used, true);
1082 sess_vuid = session->global->session_wire_id;
1084 data_blob_free(&nt_resp);
1085 data_blob_free(&lm_resp);
1087 SSVAL(req->outbuf,smb_vwv2,action);
1088 SSVAL(req->outbuf,smb_uid,sess_vuid);
1089 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1090 req->vuid = sess_vuid;
1092 if (!sconn->smb1.sessions.done_sesssetup) {
1093 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1094 reply_force_doserror(req, ERRSRV, ERRerror);
1095 END_PROFILE(SMBsesssetupX);
1098 sconn->smb1.sessions.max_send = smb_bufsize;
1099 sconn->smb1.sessions.done_sesssetup = true;
1102 END_PROFILE(SMBsesssetupX);