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 "lib/conn_tdb.h"
36 #include "../libcli/smb/smb_signing.h"
38 /****************************************************************************
39 Add the standard 'Samba' signature to the end of the session setup.
40 ****************************************************************************/
42 static int push_signature(uint8_t **outbuf)
50 fstr_sprintf(native_os, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION,
51 SAMBA_MINOR_NBT_ANNOUNCE_VERSION);
53 tmp = message_push_string(outbuf, native_os, STR_TERMINATE);
55 if (tmp == -1) return -1;
58 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
59 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
63 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
66 if (tmp == -1) return -1;
69 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
71 if (tmp == -1) return -1;
77 /****************************************************************************
78 Do a 'guest' logon, getting back the
79 ****************************************************************************/
81 static NTSTATUS check_guest_password(const struct tsocket_address *remote_address,
82 const struct tsocket_address *local_address,
84 struct auth_session_info **session_info)
86 struct auth4_context *auth_context;
87 struct auth_usersupplied_info *user_info = NULL;
91 DEBUG(3,("Got anonymous request\n"));
93 nt_status = make_auth4_context(talloc_tos(), &auth_context);
94 if (!NT_STATUS_IS_OK(nt_status)) {
98 auth_context->get_ntlm_challenge(auth_context,
101 if (!make_user_info_guest(talloc_tos(), remote_address, local_address,
102 "SMB", &user_info)) {
103 TALLOC_FREE(auth_context);
104 return NT_STATUS_NO_MEMORY;
107 user_info->auth_description = "guest";
109 nt_status = auth_check_password_session_info(auth_context,
110 mem_ctx, user_info, session_info);
111 TALLOC_FREE(user_info);
112 TALLOC_FREE(auth_context);
116 /****************************************************************************
117 Reply to a session setup command.
118 conn POINTER CAN BE NULL HERE !
119 ****************************************************************************/
121 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
125 DATA_BLOB out_blob = data_blob_null;
128 const char *native_os;
129 const char *native_lanman;
130 const char *primary_domain;
131 uint16_t 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 smbXsrv_connection *xconn = req->xconn;
136 struct smbd_server_connection *sconn = req->sconn;
138 bool is_authenticated = false;
139 NTTIME now = timeval_to_nttime(&req->request_time);
140 struct smbXsrv_session *session = NULL;
141 uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
142 uint32_t client_caps = IVAL(req->vwv+10, 0);
143 struct smbXsrv_session_auth0 *auth;
145 DEBUG(3,("Doing spnego session setup\n"));
147 if (!xconn->smb1.sessions.done_sesssetup) {
148 global_client_caps = client_caps;
150 if (!(global_client_caps & CAP_STATUS32)) {
151 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
157 if (data_blob_len == 0) {
158 /* an invalid request */
159 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
163 bufrem = smbreq_bufrem(req, p);
164 /* pull the spnego blob */
165 in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
168 file_save("negotiate.dat", in_blob.data, in_blob.length);
171 p = req->buf + in_blob.length;
173 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
175 native_os = tmp ? tmp : "";
177 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
179 native_lanman = tmp ? tmp : "";
181 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
183 primary_domain = tmp ? tmp : "";
185 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
186 native_os, native_lanman, primary_domain));
188 if ( ra_type == RA_WIN2K ) {
189 /* Vista sets neither the OS or lanman strings */
191 if ( !strlen(native_os) && !strlen(native_lanman) )
192 set_remote_arch(RA_VISTA);
194 /* Windows 2003 doesn't set the native lanman string,
195 but does set primary domain which is a bug I think */
197 if ( !strlen(native_lanman) ) {
198 ra_lanman_string( primary_domain );
200 ra_lanman_string( native_lanman );
202 } else if ( ra_type == RA_VISTA ) {
203 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
204 set_remote_arch(RA_OSX);
209 status = smb1srv_session_lookup(xconn,
212 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
213 reply_force_doserror(req, ERRSRV, ERRbaduid);
216 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
217 status = NT_STATUS_OK;
219 if (NT_STATUS_IS_OK(status)) {
220 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
221 status = NT_STATUS_MORE_PROCESSING_REQUIRED;
222 TALLOC_FREE(session->pending_auth);
224 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
225 reply_nterror(req, nt_status_squash(status));
230 if (session == NULL) {
231 /* create a new session */
232 status = smbXsrv_session_create(xconn,
234 if (!NT_STATUS_IS_OK(status)) {
235 reply_nterror(req, nt_status_squash(status));
240 status = smbXsrv_session_find_auth(session, xconn, now, &auth);
241 if (!NT_STATUS_IS_OK(status)) {
242 status = smbXsrv_session_create_auth(session, xconn, now,
246 if (!NT_STATUS_IS_OK(status)) {
247 reply_nterror(req, nt_status_squash(status));
252 if (auth->gensec == NULL) {
253 status = auth_generic_prepare(session,
254 xconn->remote_address,
255 xconn->local_address,
258 if (!NT_STATUS_IS_OK(status)) {
259 TALLOC_FREE(session);
260 reply_nterror(req, nt_status_squash(status));
264 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
265 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
266 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
268 status = gensec_start_mech_by_oid(auth->gensec,
270 if (!NT_STATUS_IS_OK(status)) {
271 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
272 TALLOC_FREE(session);;
273 reply_nterror(req, nt_status_squash(status));
279 status = gensec_update(auth->gensec,
283 if (!NT_STATUS_IS_OK(status) &&
284 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
285 TALLOC_FREE(session);
286 reply_nterror(req, nt_status_squash(status));
290 if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
291 struct auth_session_info *session_info = NULL;
293 status = gensec_session_info(auth->gensec,
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(1,("Failed to generate session_info "
298 "(user and group token) for session setup: %s\n",
300 data_blob_free(&out_blob);
301 TALLOC_FREE(session);
302 reply_nterror(req, nt_status_squash(status));
306 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
307 action |= SMB_SETUP_GUEST;
310 if (session_info->session_key.length > 0) {
311 struct smbXsrv_session *x = session;
314 * Note: the SMB1 signing key is not truncated to 16 byte!
316 x->global->signing_key =
317 data_blob_dup_talloc(x->global,
318 session_info->session_key);
319 if (x->global->signing_key.data == NULL) {
320 data_blob_free(&out_blob);
321 TALLOC_FREE(session);
322 reply_nterror(req, NT_STATUS_NO_MEMORY);
327 * clear the session key
328 * the first tcon will add setup the application key
330 data_blob_clear_free(&session_info->session_key);
333 session->compat = talloc_zero(session, struct user_struct);
334 if (session->compat == NULL) {
335 data_blob_free(&out_blob);
336 TALLOC_FREE(session);
337 reply_nterror(req, NT_STATUS_NO_MEMORY);
340 session->compat->session = session;
341 session->compat->homes_snum = -1;
342 session->compat->session_info = session_info;
343 session->compat->session_keystr = NULL;
344 session->compat->vuid = session->global->session_wire_id;
345 DLIST_ADD(sconn->users, session->compat);
348 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
349 is_authenticated = true;
350 session->compat->homes_snum =
351 register_homes_share(session_info->unix_info->unix_name);
354 if (srv_is_signing_negotiated(xconn) &&
356 session->global->signing_key.length > 0)
359 * Try and turn on server signing on the first non-guest
362 srv_set_signing(xconn,
363 session->global->signing_key,
367 set_current_user_info(session_info->unix_info->sanitized_username,
368 session_info->unix_info->unix_name,
369 session_info->info->domain_name);
371 session->status = NT_STATUS_OK;
372 session->global->auth_session_info = talloc_move(session->global,
374 session->global->auth_session_info_seqnum += 1;
375 session->global->channels[0].auth_session_info_seqnum =
376 session->global->auth_session_info_seqnum;
377 session->global->auth_time = now;
378 if (client_caps & CAP_DYNAMIC_REAUTH) {
379 session->global->expiration_time =
380 gensec_expire_time(auth->gensec);
382 session->global->expiration_time =
383 GENSEC_EXPIRE_TIME_INFINITY;
386 if (!session_claim(session)) {
387 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
388 (unsigned long long)session->compat->vuid));
389 data_blob_free(&out_blob);
390 TALLOC_FREE(session);
391 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
395 status = smbXsrv_session_update(session);
396 if (!NT_STATUS_IS_OK(status)) {
397 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
398 (unsigned long long)session->compat->vuid,
400 data_blob_free(&out_blob);
401 TALLOC_FREE(session);
402 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
406 if (!xconn->smb1.sessions.done_sesssetup) {
407 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
408 reply_force_doserror(req, ERRSRV, ERRerror);
411 xconn->smb1.sessions.max_send = smb_bufsize;
412 xconn->smb1.sessions.done_sesssetup = true;
415 /* current_user_info is changed on new vuid */
416 reload_services(sconn, conn_snum_used, true);
417 } else if (NT_STATUS_IS_OK(status)) {
418 struct auth_session_info *session_info = NULL;
420 status = gensec_session_info(auth->gensec,
423 if (!NT_STATUS_IS_OK(status)) {
424 DEBUG(1,("Failed to generate session_info "
425 "(user and group token) for session setup: %s\n",
427 data_blob_free(&out_blob);
428 TALLOC_FREE(session);
429 reply_nterror(req, nt_status_squash(status));
433 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
434 action |= SMB_SETUP_GUEST;
438 * Keep the application key
440 data_blob_clear_free(&session_info->session_key);
441 session_info->session_key =
442 session->global->auth_session_info->session_key;
443 talloc_steal(session_info, session_info->session_key.data);
444 TALLOC_FREE(session->global->auth_session_info);
446 session->compat->session_info = session_info;
448 session->compat->vuid = session->global->session_wire_id;
450 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
451 session->compat->homes_snum =
452 register_homes_share(session_info->unix_info->unix_name);
455 set_current_user_info(session_info->unix_info->sanitized_username,
456 session_info->unix_info->unix_name,
457 session_info->info->domain_name);
459 session->status = NT_STATUS_OK;
460 session->global->auth_session_info = talloc_move(session->global,
462 session->global->auth_session_info_seqnum += 1;
463 session->global->channels[0].auth_session_info_seqnum =
464 session->global->auth_session_info_seqnum;
465 session->global->auth_time = now;
466 if (client_caps & CAP_DYNAMIC_REAUTH) {
467 session->global->expiration_time =
468 gensec_expire_time(auth->gensec);
470 session->global->expiration_time =
471 GENSEC_EXPIRE_TIME_INFINITY;
474 status = smbXsrv_session_update(session);
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
477 (unsigned long long)session->compat->vuid,
479 data_blob_free(&out_blob);
480 TALLOC_FREE(session);
481 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
485 conn_clear_vuid_caches(sconn, session->compat->vuid);
487 /* current_user_info is changed on new vuid */
488 reload_services(sconn, conn_snum_used, true);
491 vuid = session->global->session_wire_id;
493 reply_outbuf(req, 4, 0);
495 SSVAL(req->outbuf, smb_uid, vuid);
496 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
497 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
498 SSVAL(req->outbuf, smb_vwv2, action);
499 SSVAL(req->outbuf, smb_vwv3, out_blob.length);
501 if (message_push_blob(&req->outbuf, out_blob) == -1) {
502 data_blob_free(&out_blob);
503 TALLOC_FREE(session);
504 reply_nterror(req, NT_STATUS_NO_MEMORY);
507 data_blob_free(&out_blob);
509 if (push_signature(&req->outbuf) == -1) {
510 TALLOC_FREE(session);
511 reply_nterror(req, NT_STATUS_NO_MEMORY);
516 /****************************************************************************
517 On new VC == 0, shutdown *all* old connections and users.
518 It seems that only NT4.x does this. At W2K and above (XP etc.).
519 a new session setup with VC==0 is ignored.
520 ****************************************************************************/
522 struct shutdown_state {
524 struct messaging_context *msg_ctx;
527 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
530 struct shutdown_state *state = (struct shutdown_state *)private_data;
531 struct server_id self_pid = messaging_server_id(state->msg_ctx);
532 struct server_id pid = session->channels[0].server_id;
533 const char *addr = session->channels[0].remote_address;
534 struct server_id_buf tmp;
536 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
537 server_id_str_buf(pid, &tmp), addr));
539 if (!process_exists(pid)) {
540 DEBUG(10, ("process does not exist\n"));
544 if (serverid_equal(&pid, &self_pid)) {
545 DEBUG(10, ("It's me\n"));
550 * here we use strstr() because 'addr'
551 * (session->channels[0].remote_address)
552 * contains a string like:
553 * 'ipv4:127.0.0.1:48163'
555 if (strstr(addr, state->ip) == NULL) {
556 DEBUG(10, ("%s does not match %s\n", state->ip, addr));
560 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
561 "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
564 messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
569 static void setup_new_vc_session(struct smbd_server_connection *sconn)
571 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
572 "compatible we would close all old resources.\n"));
575 invalidate_all_vuids();
577 if (lp_reset_on_zero_vc()) {
579 struct shutdown_state state;
581 addr = tsocket_address_inet_addr_string(
582 sconn->remote_address, talloc_tos());
587 state.msg_ctx = sconn->msg_ctx;
588 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
593 /****************************************************************************
594 Reply to a session setup command.
595 ****************************************************************************/
597 void reply_sesssetup_and_X(struct smb_request *req)
600 uint16_t smb_bufsize;
603 DATA_BLOB plaintext_password;
606 fstring sub_user; /* Sanitised username for substituion */
608 const char *native_os;
609 const char *native_lanman;
610 const char *primary_domain;
611 struct auth_usersupplied_info *user_info = NULL;
612 struct auth_session_info *session_info = NULL;
613 uint16_t smb_flag2 = req->flags2;
615 bool is_authenticated = false;
616 NTTIME now = timeval_to_nttime(&req->request_time);
617 struct smbXsrv_session *session = NULL;
619 struct smbXsrv_connection *xconn = req->xconn;
620 struct smbd_server_connection *sconn = req->sconn;
621 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
622 bool signing_allowed = false;
623 bool signing_mandatory = smb_signing_is_mandatory(
624 xconn->smb1.signing_state);
626 START_PROFILE(SMBsesssetupX);
628 ZERO_STRUCT(lm_resp);
629 ZERO_STRUCT(nt_resp);
630 ZERO_STRUCT(plaintext_password);
632 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
634 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
635 signing_allowed = true;
637 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
638 signing_mandatory = true;
642 * We can call srv_set_signing_negotiated() each time.
643 * It finds out when it needs to turn into a noop
646 srv_set_signing_negotiated(xconn,
650 /* a SPNEGO session setup has 12 command words, whereas a normal
651 NT1 session setup has 13. See the cifs spec. */
652 if (req->wct == 12 &&
653 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
655 if (!xconn->smb1.negprot.spnego) {
656 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
657 "at SPNEGO session setup when it was not "
659 reply_nterror(req, nt_status_squash(
660 NT_STATUS_LOGON_FAILURE));
661 END_PROFILE(SMBsesssetupX);
665 if (SVAL(req->vwv+4, 0) == 0) {
666 setup_new_vc_session(req->sconn);
669 reply_sesssetup_and_X_spnego(req);
670 END_PROFILE(SMBsesssetupX);
674 smb_bufsize = SVAL(req->vwv+2, 0);
676 if (get_Protocol() < PROTOCOL_NT1) {
677 uint16_t passlen1 = SVAL(req->vwv+7, 0);
679 /* Never do NT status codes with protocols before NT1 as we
680 * don't get client caps. */
681 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
683 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
684 reply_nterror(req, nt_status_squash(
685 NT_STATUS_INVALID_PARAMETER));
686 END_PROFILE(SMBsesssetupX);
691 lm_resp = data_blob(req->buf, passlen1);
693 plaintext_password = data_blob(req->buf, passlen1+1);
694 /* Ensure null termination */
695 plaintext_password.data[passlen1] = 0;
698 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
699 req->buf + passlen1, STR_TERMINATE);
700 user = tmp ? tmp : "";
705 uint16_t passlen1 = SVAL(req->vwv+7, 0);
706 uint16_t passlen2 = SVAL(req->vwv+8, 0);
707 enum remote_arch_types ra_type = get_remote_arch();
708 const uint8_t *p = req->buf;
709 const uint8_t *save_p = req->buf;
712 if (!xconn->smb1.sessions.done_sesssetup) {
713 global_client_caps = IVAL(req->vwv+11, 0);
715 if (!(global_client_caps & CAP_STATUS32)) {
716 remove_from_common_flags2(
717 FLAGS2_32_BIT_ERROR_CODES);
720 /* client_caps is used as final determination if
721 * client is NT or Win95. This is needed to return
722 * the correct error codes in some circumstances.
725 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
726 ra_type == RA_WIN95) {
727 if(!(global_client_caps & (CAP_NT_SMBS|
729 set_remote_arch( RA_WIN95);
735 /* both Win95 and WinNT stuff up the password
736 * lengths for non-encrypting systems. Uggh.
738 if passlen1==24 its a win95 system, and its setting
739 the password length incorrectly. Luckily it still
740 works with the default code because Win95 will null
741 terminate the password anyway
743 if passlen1>0 and passlen2>0 then maybe its a NT box
744 and its setting passlen2 to some random value which
745 really stuffs things up. we need to fix that one. */
747 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
753 /* check for nasty tricks */
754 if (passlen1 > MAX_PASS_LEN
755 || passlen1 > smbreq_bufrem(req, p)) {
756 reply_nterror(req, nt_status_squash(
757 NT_STATUS_INVALID_PARAMETER));
758 END_PROFILE(SMBsesssetupX);
762 if (passlen2 > MAX_PASS_LEN
763 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
764 reply_nterror(req, nt_status_squash(
765 NT_STATUS_INVALID_PARAMETER));
766 END_PROFILE(SMBsesssetupX);
770 /* Save the lanman2 password and the NT md4 password. */
772 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
777 lm_resp = data_blob(p, passlen1);
778 nt_resp = data_blob(p+passlen1, passlen2);
781 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
783 if (unic && (passlen2 == 0) && passlen1) {
784 /* Only a ascii plaintext password was sent. */
785 (void)srvstr_pull_talloc(talloc_tos(),
791 STR_TERMINATE|STR_ASCII);
793 (void)srvstr_pull_talloc(talloc_tos(),
798 unic ? passlen2 : passlen1,
802 reply_nterror(req, nt_status_squash(
803 NT_STATUS_INVALID_PARAMETER));
804 END_PROFILE(SMBsesssetupX);
807 plaintext_password = data_blob(pass, strlen(pass)+1);
810 p += passlen1 + passlen2;
812 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
814 user = tmp ? tmp : "";
816 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
818 domain = tmp ? tmp : "";
820 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
822 native_os = tmp ? tmp : "";
824 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
826 native_lanman = tmp ? tmp : "";
828 /* not documented or decoded by Ethereal but there is one more
829 * string in the extra bytes which is the same as the
830 * PrimaryDomain when using extended security. Windows NT 4
831 * and 2003 use this string to store the native lanman string.
832 * Windows 9x does not include a string here at all so we have
833 * to check if we have any extra bytes left */
835 byte_count = SVAL(req->vwv+13, 0);
836 if ( PTR_DIFF(p, save_p) < byte_count) {
837 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
839 primary_domain = tmp ? tmp : "";
841 primary_domain = talloc_strdup(talloc_tos(), "null");
844 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
845 "PrimaryDomain=[%s]\n",
846 domain, native_os, native_lanman, primary_domain));
848 if ( ra_type == RA_WIN2K ) {
849 if ( strlen(native_lanman) == 0 )
850 ra_lanman_string( primary_domain );
852 ra_lanman_string( native_lanman );
857 if (SVAL(req->vwv+4, 0) == 0) {
858 setup_new_vc_session(req->sconn);
861 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
862 domain, user, get_remote_machine_name()));
865 if (xconn->smb1.negprot.spnego) {
867 /* This has to be here, because this is a perfectly
868 * valid behaviour for guest logons :-( */
870 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
871 "at 'normal' session setup after "
872 "negotiating spnego.\n"));
873 reply_nterror(req, nt_status_squash(
874 NT_STATUS_LOGON_FAILURE));
875 END_PROFILE(SMBsesssetupX);
878 fstrcpy(sub_user, user);
880 fstrcpy(sub_user, "");
883 sub_set_smb_name(sub_user);
885 reload_services(sconn, conn_snum_used, true);
889 nt_status = check_guest_password(sconn->remote_address,
890 sconn->local_address,
893 } else if (doencrypt) {
894 struct auth4_context *negprot_auth_context = NULL;
895 negprot_auth_context = xconn->smb1.negprot.auth_context;
896 if (!negprot_auth_context) {
897 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
898 "session setup without negprot denied!\n"));
899 reply_nterror(req, nt_status_squash(
900 NT_STATUS_LOGON_FAILURE));
901 END_PROFILE(SMBsesssetupX);
904 nt_status = make_user_info_for_reply_enc(talloc_tos(),
907 sconn->remote_address,
908 sconn->local_address,
911 user_info->auth_description = "bare-NTLM";
913 if (NT_STATUS_IS_OK(nt_status)) {
914 nt_status = auth_check_password_session_info(negprot_auth_context,
915 req, user_info, &session_info);
918 struct auth4_context *plaintext_auth_context = NULL;
920 nt_status = make_auth4_context(
921 talloc_tos(), &plaintext_auth_context);
923 if (NT_STATUS_IS_OK(nt_status)) {
926 plaintext_auth_context->get_ntlm_challenge(
927 plaintext_auth_context, chal);
929 if (!make_user_info_for_reply(talloc_tos(),
932 sconn->remote_address,
933 sconn->local_address,
936 plaintext_password)) {
937 nt_status = NT_STATUS_NO_MEMORY;
940 user_info->auth_description = "plaintext";
942 if (NT_STATUS_IS_OK(nt_status)) {
943 nt_status = auth_check_password_session_info(plaintext_auth_context,
944 req, user_info, &session_info);
946 TALLOC_FREE(plaintext_auth_context);
950 TALLOC_FREE(user_info);
952 if (!NT_STATUS_IS_OK(nt_status)) {
953 data_blob_free(&nt_resp);
954 data_blob_free(&lm_resp);
955 data_blob_clear_free(&plaintext_password);
956 reply_nterror(req, nt_status_squash(nt_status));
957 END_PROFILE(SMBsesssetupX);
961 data_blob_clear_free(&plaintext_password);
963 /* it's ok - setup a reply */
964 reply_outbuf(req, 3, 0);
965 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
966 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
968 if (get_Protocol() >= PROTOCOL_NT1) {
969 push_signature(&req->outbuf);
970 /* perhaps grab OS version here?? */
973 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
974 action |= SMB_SETUP_GUEST;
977 /* register the name and uid as being validated, so further connections
978 to a uid can get through without a password, on the same VC */
980 nt_status = smbXsrv_session_create(xconn,
982 if (!NT_STATUS_IS_OK(nt_status)) {
983 data_blob_free(&nt_resp);
984 data_blob_free(&lm_resp);
985 reply_nterror(req, nt_status_squash(nt_status));
986 END_PROFILE(SMBsesssetupX);
990 if (session_info->session_key.length > 0) {
991 uint8_t session_key[16];
994 * Note: the SMB1 signing key is not truncated to 16 byte!
996 session->global->signing_key =
997 data_blob_dup_talloc(session->global,
998 session_info->session_key);
999 if (session->global->signing_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 * The application key is truncated/padded to 16 bytes
1011 ZERO_STRUCT(session_key);
1012 memcpy(session_key, session->global->signing_key.data,
1013 MIN(session->global->signing_key.length,
1014 sizeof(session_key)));
1015 session->global->application_key =
1016 data_blob_talloc(session->global,
1018 sizeof(session_key));
1019 ZERO_STRUCT(session_key);
1020 if (session->global->application_key.data == NULL) {
1021 data_blob_free(&nt_resp);
1022 data_blob_free(&lm_resp);
1023 TALLOC_FREE(session);
1024 reply_nterror(req, NT_STATUS_NO_MEMORY);
1025 END_PROFILE(SMBsesssetupX);
1030 * Place the application key into the session_info
1032 data_blob_clear_free(&session_info->session_key);
1033 session_info->session_key = data_blob_dup_talloc(session_info,
1034 session->global->application_key);
1035 if (session_info->session_key.data == NULL) {
1036 data_blob_free(&nt_resp);
1037 data_blob_free(&lm_resp);
1038 TALLOC_FREE(session);
1039 reply_nterror(req, NT_STATUS_NO_MEMORY);
1040 END_PROFILE(SMBsesssetupX);
1045 session->compat = talloc_zero(session, struct user_struct);
1046 if (session->compat == NULL) {
1047 data_blob_free(&nt_resp);
1048 data_blob_free(&lm_resp);
1049 TALLOC_FREE(session);
1050 reply_nterror(req, NT_STATUS_NO_MEMORY);
1051 END_PROFILE(SMBsesssetupX);
1054 session->compat->session = session;
1055 session->compat->homes_snum = -1;
1056 session->compat->session_info = session_info;
1057 session->compat->session_keystr = NULL;
1058 session->compat->vuid = session->global->session_wire_id;
1059 DLIST_ADD(sconn->users, session->compat);
1062 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1063 is_authenticated = true;
1064 session->compat->homes_snum =
1065 register_homes_share(session_info->unix_info->unix_name);
1068 if (srv_is_signing_negotiated(xconn) &&
1070 session->global->signing_key.length > 0)
1073 * Try and turn on server signing on the first non-guest
1076 srv_set_signing(xconn,
1077 session->global->signing_key,
1078 nt_resp.data ? nt_resp : lm_resp);
1081 set_current_user_info(session_info->unix_info->sanitized_username,
1082 session_info->unix_info->unix_name,
1083 session_info->info->domain_name);
1085 session->status = NT_STATUS_OK;
1086 session->global->auth_session_info = talloc_move(session->global,
1088 session->global->auth_session_info_seqnum += 1;
1089 session->global->channels[0].auth_session_info_seqnum =
1090 session->global->auth_session_info_seqnum;
1091 session->global->auth_time = now;
1092 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1094 nt_status = smbXsrv_session_update(session);
1095 if (!NT_STATUS_IS_OK(nt_status)) {
1096 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1097 (unsigned long long)session->compat->vuid,
1098 nt_errstr(nt_status)));
1099 data_blob_free(&nt_resp);
1100 data_blob_free(&lm_resp);
1101 TALLOC_FREE(session);
1102 reply_nterror(req, nt_status_squash(nt_status));
1103 END_PROFILE(SMBsesssetupX);
1107 if (!session_claim(session)) {
1108 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1109 (unsigned long long)session->compat->vuid));
1110 data_blob_free(&nt_resp);
1111 data_blob_free(&lm_resp);
1112 TALLOC_FREE(session);
1113 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1114 END_PROFILE(SMBsesssetupX);
1118 /* current_user_info is changed on new vuid */
1119 reload_services(sconn, conn_snum_used, true);
1121 sess_vuid = session->global->session_wire_id;
1123 data_blob_free(&nt_resp);
1124 data_blob_free(&lm_resp);
1126 SSVAL(req->outbuf,smb_vwv2,action);
1127 SSVAL(req->outbuf,smb_uid,sess_vuid);
1128 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1129 req->vuid = sess_vuid;
1131 if (!xconn->smb1.sessions.done_sesssetup) {
1132 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1133 reply_force_doserror(req, ERRSRV, ERRerror);
1134 END_PROFILE(SMBsesssetupX);
1137 xconn->smb1.sessions.max_send = smb_bufsize;
1138 xconn->smb1.sessions.done_sesssetup = true;
1141 END_PROFILE(SMBsesssetupX);