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 Reply to a session setup command.
79 conn POINTER CAN BE NULL HERE !
80 ****************************************************************************/
82 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
86 DATA_BLOB out_blob = data_blob_null;
89 const char *native_os;
90 const char *native_lanman;
91 const char *primary_domain;
92 uint16_t data_blob_len = SVAL(req->vwv+7, 0);
93 enum remote_arch_types ra_type = get_remote_arch();
94 uint64_t vuid = req->vuid;
95 NTSTATUS status = NT_STATUS_OK;
96 struct smbXsrv_connection *xconn = req->xconn;
97 struct smbd_server_connection *sconn = req->sconn;
99 bool is_authenticated = false;
100 NTTIME now = timeval_to_nttime(&req->request_time);
101 struct smbXsrv_session *session = NULL;
102 uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
103 uint32_t client_caps = IVAL(req->vwv+10, 0);
104 struct smbXsrv_session_auth0 *auth;
106 DEBUG(3,("Doing spnego session setup\n"));
108 if (!xconn->smb1.sessions.done_sesssetup) {
109 global_client_caps = client_caps;
111 if (!(global_client_caps & CAP_STATUS32)) {
112 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
118 if (data_blob_len == 0) {
119 /* an invalid request */
120 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
124 bufrem = smbreq_bufrem(req, p);
125 /* pull the spnego blob */
126 in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
129 file_save("negotiate.dat", in_blob.data, in_blob.length);
132 p = req->buf + in_blob.length;
134 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
136 native_os = tmp ? tmp : "";
138 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
140 native_lanman = tmp ? tmp : "";
142 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
144 primary_domain = tmp ? tmp : "";
146 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
147 native_os, native_lanman, primary_domain));
149 if ( ra_type == RA_WIN2K ) {
150 /* Vista sets neither the OS or lanman strings */
152 if ( !strlen(native_os) && !strlen(native_lanman) )
153 set_remote_arch(RA_VISTA);
155 /* Windows 2003 doesn't set the native lanman string,
156 but does set primary domain which is a bug I think */
158 if ( !strlen(native_lanman) ) {
159 ra_lanman_string( primary_domain );
161 ra_lanman_string( native_lanman );
163 } else if ( ra_type == RA_VISTA ) {
164 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
165 set_remote_arch(RA_OSX);
170 status = smb1srv_session_lookup(xconn,
173 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
174 reply_force_doserror(req, ERRSRV, ERRbaduid);
177 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
178 status = NT_STATUS_OK;
180 if (NT_STATUS_IS_OK(status)) {
181 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
182 status = NT_STATUS_MORE_PROCESSING_REQUIRED;
183 TALLOC_FREE(session->pending_auth);
185 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
186 reply_nterror(req, nt_status_squash(status));
191 if (session == NULL) {
192 /* create a new session */
193 status = smbXsrv_session_create(xconn,
195 if (!NT_STATUS_IS_OK(status)) {
196 reply_nterror(req, nt_status_squash(status));
201 status = smbXsrv_session_find_auth(session, xconn, now, &auth);
202 if (!NT_STATUS_IS_OK(status)) {
203 status = smbXsrv_session_create_auth(session, xconn, now,
207 if (!NT_STATUS_IS_OK(status)) {
208 reply_nterror(req, nt_status_squash(status));
213 if (auth->gensec == NULL) {
214 status = auth_generic_prepare(session,
215 xconn->remote_address,
216 xconn->local_address,
219 if (!NT_STATUS_IS_OK(status)) {
220 TALLOC_FREE(session);
221 reply_nterror(req, nt_status_squash(status));
225 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
226 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
227 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
229 status = gensec_start_mech_by_oid(auth->gensec,
231 if (!NT_STATUS_IS_OK(status)) {
232 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
233 TALLOC_FREE(session);;
234 reply_nterror(req, nt_status_squash(status));
240 status = gensec_update(auth->gensec,
244 if (!NT_STATUS_IS_OK(status) &&
245 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
246 TALLOC_FREE(session);
247 reply_nterror(req, nt_status_squash(status));
251 if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
252 struct auth_session_info *session_info = NULL;
254 status = gensec_session_info(auth->gensec,
257 if (!NT_STATUS_IS_OK(status)) {
258 DEBUG(1,("Failed to generate session_info "
259 "(user and group token) for session setup: %s\n",
261 data_blob_free(&out_blob);
262 TALLOC_FREE(session);
263 reply_nterror(req, nt_status_squash(status));
267 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
268 action |= SMB_SETUP_GUEST;
271 if (session_info->session_key.length > 0) {
272 struct smbXsrv_session *x = session;
275 * Note: the SMB1 signing key is not truncated to 16 byte!
277 x->global->signing_key =
278 data_blob_dup_talloc(x->global,
279 session_info->session_key);
280 if (x->global->signing_key.data == NULL) {
281 data_blob_free(&out_blob);
282 TALLOC_FREE(session);
283 reply_nterror(req, NT_STATUS_NO_MEMORY);
288 * clear the session key
289 * the first tcon will add setup the application key
291 data_blob_clear_free(&session_info->session_key);
294 session->compat = talloc_zero(session, struct user_struct);
295 if (session->compat == NULL) {
296 data_blob_free(&out_blob);
297 TALLOC_FREE(session);
298 reply_nterror(req, NT_STATUS_NO_MEMORY);
301 session->compat->session = session;
302 session->compat->homes_snum = -1;
303 session->compat->session_info = session_info;
304 session->compat->session_keystr = NULL;
305 session->compat->vuid = session->global->session_wire_id;
306 DLIST_ADD(sconn->users, session->compat);
309 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
310 is_authenticated = true;
311 session->compat->homes_snum =
312 register_homes_share(session_info->unix_info->unix_name);
315 if (srv_is_signing_negotiated(xconn) &&
317 session->global->signing_key.length > 0)
320 * Try and turn on server signing on the first non-guest
323 srv_set_signing(xconn,
324 session->global->signing_key,
328 set_current_user_info(session_info->unix_info->sanitized_username,
329 session_info->unix_info->unix_name,
330 session_info->info->domain_name);
332 session->status = NT_STATUS_OK;
333 session->global->auth_session_info = talloc_move(session->global,
335 session->global->auth_session_info_seqnum += 1;
336 session->global->channels[0].auth_session_info_seqnum =
337 session->global->auth_session_info_seqnum;
338 session->global->auth_time = now;
339 if (client_caps & CAP_DYNAMIC_REAUTH) {
340 session->global->expiration_time =
341 gensec_expire_time(auth->gensec);
343 session->global->expiration_time =
344 GENSEC_EXPIRE_TIME_INFINITY;
347 if (!session_claim(session)) {
348 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
349 (unsigned long long)session->compat->vuid));
350 data_blob_free(&out_blob);
351 TALLOC_FREE(session);
352 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
356 status = smbXsrv_session_update(session);
357 if (!NT_STATUS_IS_OK(status)) {
358 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
359 (unsigned long long)session->compat->vuid,
361 data_blob_free(&out_blob);
362 TALLOC_FREE(session);
363 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
367 if (!xconn->smb1.sessions.done_sesssetup) {
368 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
369 reply_force_doserror(req, ERRSRV, ERRerror);
372 xconn->smb1.sessions.max_send = smb_bufsize;
373 xconn->smb1.sessions.done_sesssetup = true;
376 /* current_user_info is changed on new vuid */
377 reload_services(sconn, conn_snum_used, true);
378 } else if (NT_STATUS_IS_OK(status)) {
379 struct auth_session_info *session_info = NULL;
381 status = gensec_session_info(auth->gensec,
384 if (!NT_STATUS_IS_OK(status)) {
385 DEBUG(1,("Failed to generate session_info "
386 "(user and group token) for session setup: %s\n",
388 data_blob_free(&out_blob);
389 TALLOC_FREE(session);
390 reply_nterror(req, nt_status_squash(status));
394 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
395 action |= SMB_SETUP_GUEST;
399 * Keep the application key
401 data_blob_clear_free(&session_info->session_key);
402 session_info->session_key =
403 session->global->auth_session_info->session_key;
404 talloc_steal(session_info, session_info->session_key.data);
405 TALLOC_FREE(session->global->auth_session_info);
407 session->compat->session_info = session_info;
409 session->compat->vuid = session->global->session_wire_id;
411 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
412 session->compat->homes_snum =
413 register_homes_share(session_info->unix_info->unix_name);
416 set_current_user_info(session_info->unix_info->sanitized_username,
417 session_info->unix_info->unix_name,
418 session_info->info->domain_name);
420 session->status = NT_STATUS_OK;
421 session->global->auth_session_info = talloc_move(session->global,
423 session->global->auth_session_info_seqnum += 1;
424 session->global->channels[0].auth_session_info_seqnum =
425 session->global->auth_session_info_seqnum;
426 session->global->auth_time = now;
427 if (client_caps & CAP_DYNAMIC_REAUTH) {
428 session->global->expiration_time =
429 gensec_expire_time(auth->gensec);
431 session->global->expiration_time =
432 GENSEC_EXPIRE_TIME_INFINITY;
435 status = smbXsrv_session_update(session);
436 if (!NT_STATUS_IS_OK(status)) {
437 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
438 (unsigned long long)session->compat->vuid,
440 data_blob_free(&out_blob);
441 TALLOC_FREE(session);
442 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
446 conn_clear_vuid_caches(sconn, session->compat->vuid);
448 /* current_user_info is changed on new vuid */
449 reload_services(sconn, conn_snum_used, true);
452 vuid = session->global->session_wire_id;
454 reply_outbuf(req, 4, 0);
456 SSVAL(req->outbuf, smb_uid, vuid);
457 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
458 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
459 SSVAL(req->outbuf, smb_vwv2, action);
460 SSVAL(req->outbuf, smb_vwv3, out_blob.length);
462 if (message_push_blob(&req->outbuf, out_blob) == -1) {
463 data_blob_free(&out_blob);
464 TALLOC_FREE(session);
465 reply_nterror(req, NT_STATUS_NO_MEMORY);
468 data_blob_free(&out_blob);
470 if (push_signature(&req->outbuf) == -1) {
471 TALLOC_FREE(session);
472 reply_nterror(req, NT_STATUS_NO_MEMORY);
477 /****************************************************************************
478 On new VC == 0, shutdown *all* old connections and users.
479 It seems that only NT4.x does this. At W2K and above (XP etc.).
480 a new session setup with VC==0 is ignored.
481 ****************************************************************************/
483 struct shutdown_state {
485 struct messaging_context *msg_ctx;
488 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
491 struct shutdown_state *state = (struct shutdown_state *)private_data;
492 struct server_id self_pid = messaging_server_id(state->msg_ctx);
493 struct server_id pid = session->channels[0].server_id;
494 const char *addr = session->channels[0].remote_address;
495 struct server_id_buf tmp;
497 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
498 server_id_str_buf(pid, &tmp), addr));
500 if (!process_exists(pid)) {
501 DEBUG(10, ("process does not exist\n"));
505 if (serverid_equal(&pid, &self_pid)) {
506 DEBUG(10, ("It's me\n"));
511 * here we use strstr() because 'addr'
512 * (session->channels[0].remote_address)
513 * contains a string like:
514 * 'ipv4:127.0.0.1:48163'
516 if (strstr(addr, state->ip) == NULL) {
517 DEBUG(10, ("%s does not match %s\n", state->ip, addr));
521 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
522 "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
525 messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
530 static void setup_new_vc_session(struct smbd_server_connection *sconn)
532 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
533 "compatible we would close all old resources.\n"));
536 invalidate_all_vuids();
538 if (lp_reset_on_zero_vc()) {
540 struct shutdown_state state;
542 addr = tsocket_address_inet_addr_string(
543 sconn->remote_address, talloc_tos());
548 state.msg_ctx = sconn->msg_ctx;
549 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
554 /****************************************************************************
555 Reply to a session setup command.
556 ****************************************************************************/
558 void reply_sesssetup_and_X(struct smb_request *req)
561 uint16_t smb_bufsize;
564 DATA_BLOB plaintext_password;
567 fstring sub_user; /* Sanitised username for substituion */
569 const char *native_os;
570 const char *native_lanman;
571 const char *primary_domain;
572 struct auth_usersupplied_info *user_info = NULL;
573 struct auth_session_info *session_info = NULL;
574 uint16_t smb_flag2 = req->flags2;
576 bool is_authenticated = false;
577 NTTIME now = timeval_to_nttime(&req->request_time);
578 struct smbXsrv_session *session = NULL;
580 struct smbXsrv_connection *xconn = req->xconn;
581 struct smbd_server_connection *sconn = req->sconn;
582 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
583 bool signing_allowed = false;
584 bool signing_mandatory = smb_signing_is_mandatory(
585 xconn->smb1.signing_state);
587 START_PROFILE(SMBsesssetupX);
589 ZERO_STRUCT(lm_resp);
590 ZERO_STRUCT(nt_resp);
591 ZERO_STRUCT(plaintext_password);
593 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
595 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
596 signing_allowed = true;
598 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
599 signing_mandatory = true;
603 * We can call srv_set_signing_negotiated() each time.
604 * It finds out when it needs to turn into a noop
607 srv_set_signing_negotiated(xconn,
611 /* a SPNEGO session setup has 12 command words, whereas a normal
612 NT1 session setup has 13. See the cifs spec. */
613 if (req->wct == 12 &&
614 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
616 if (!xconn->smb1.negprot.spnego) {
617 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
618 "at SPNEGO session setup when it was not "
620 reply_nterror(req, nt_status_squash(
621 NT_STATUS_LOGON_FAILURE));
622 END_PROFILE(SMBsesssetupX);
626 if (SVAL(req->vwv+4, 0) == 0) {
627 setup_new_vc_session(req->sconn);
630 reply_sesssetup_and_X_spnego(req);
631 END_PROFILE(SMBsesssetupX);
635 smb_bufsize = SVAL(req->vwv+2, 0);
637 if (get_Protocol() < PROTOCOL_NT1) {
638 uint16_t passlen1 = SVAL(req->vwv+7, 0);
640 /* Never do NT status codes with protocols before NT1 as we
641 * don't get client caps. */
642 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
644 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
645 reply_nterror(req, nt_status_squash(
646 NT_STATUS_INVALID_PARAMETER));
647 END_PROFILE(SMBsesssetupX);
652 lm_resp = data_blob(req->buf, passlen1);
654 plaintext_password = data_blob(req->buf, passlen1+1);
655 /* Ensure null termination */
656 plaintext_password.data[passlen1] = 0;
659 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
660 req->buf + passlen1, STR_TERMINATE);
661 user = tmp ? tmp : "";
666 uint16_t passlen1 = SVAL(req->vwv+7, 0);
667 uint16_t passlen2 = SVAL(req->vwv+8, 0);
668 enum remote_arch_types ra_type = get_remote_arch();
669 const uint8_t *p = req->buf;
670 const uint8_t *save_p = req->buf;
673 if (!xconn->smb1.sessions.done_sesssetup) {
674 global_client_caps = IVAL(req->vwv+11, 0);
676 if (!(global_client_caps & CAP_STATUS32)) {
677 remove_from_common_flags2(
678 FLAGS2_32_BIT_ERROR_CODES);
681 /* client_caps is used as final determination if
682 * client is NT or Win95. This is needed to return
683 * the correct error codes in some circumstances.
686 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
687 ra_type == RA_WIN95) {
688 if(!(global_client_caps & (CAP_NT_SMBS|
690 set_remote_arch( RA_WIN95);
696 /* both Win95 and WinNT stuff up the password
697 * lengths for non-encrypting systems. Uggh.
699 if passlen1==24 its a win95 system, and its setting
700 the password length incorrectly. Luckily it still
701 works with the default code because Win95 will null
702 terminate the password anyway
704 if passlen1>0 and passlen2>0 then maybe its a NT box
705 and its setting passlen2 to some random value which
706 really stuffs things up. we need to fix that one. */
708 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
714 /* check for nasty tricks */
715 if (passlen1 > MAX_PASS_LEN
716 || passlen1 > smbreq_bufrem(req, p)) {
717 reply_nterror(req, nt_status_squash(
718 NT_STATUS_INVALID_PARAMETER));
719 END_PROFILE(SMBsesssetupX);
723 if (passlen2 > MAX_PASS_LEN
724 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
725 reply_nterror(req, nt_status_squash(
726 NT_STATUS_INVALID_PARAMETER));
727 END_PROFILE(SMBsesssetupX);
731 /* Save the lanman2 password and the NT md4 password. */
733 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
738 lm_resp = data_blob(p, passlen1);
739 nt_resp = data_blob(p+passlen1, passlen2);
742 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
744 if (unic && (passlen2 == 0) && passlen1) {
745 /* Only a ascii plaintext password was sent. */
746 (void)srvstr_pull_talloc(talloc_tos(),
752 STR_TERMINATE|STR_ASCII);
754 (void)srvstr_pull_talloc(talloc_tos(),
759 unic ? passlen2 : passlen1,
763 reply_nterror(req, nt_status_squash(
764 NT_STATUS_INVALID_PARAMETER));
765 END_PROFILE(SMBsesssetupX);
768 plaintext_password = data_blob(pass, strlen(pass)+1);
771 p += passlen1 + passlen2;
773 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
775 user = tmp ? tmp : "";
777 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
779 domain = tmp ? tmp : "";
781 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
783 native_os = tmp ? tmp : "";
785 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
787 native_lanman = tmp ? tmp : "";
789 /* not documented or decoded by Ethereal but there is one more
790 * string in the extra bytes which is the same as the
791 * PrimaryDomain when using extended security. Windows NT 4
792 * and 2003 use this string to store the native lanman string.
793 * Windows 9x does not include a string here at all so we have
794 * to check if we have any extra bytes left */
796 byte_count = SVAL(req->vwv+13, 0);
797 if ( PTR_DIFF(p, save_p) < byte_count) {
798 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
800 primary_domain = tmp ? tmp : "";
802 primary_domain = talloc_strdup(talloc_tos(), "null");
805 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
806 "PrimaryDomain=[%s]\n",
807 domain, native_os, native_lanman, primary_domain));
809 if ( ra_type == RA_WIN2K ) {
810 if ( strlen(native_lanman) == 0 )
811 ra_lanman_string( primary_domain );
813 ra_lanman_string( native_lanman );
818 if (SVAL(req->vwv+4, 0) == 0) {
819 setup_new_vc_session(req->sconn);
822 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
823 domain, user, get_remote_machine_name()));
826 if (xconn->smb1.negprot.spnego) {
828 /* This has to be here, because this is a perfectly
829 * valid behaviour for guest logons :-( */
831 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
832 "at 'normal' session setup after "
833 "negotiating spnego.\n"));
834 reply_nterror(req, nt_status_squash(
835 NT_STATUS_LOGON_FAILURE));
836 END_PROFILE(SMBsesssetupX);
839 fstrcpy(sub_user, user);
841 fstrcpy(sub_user, "");
844 sub_set_smb_name(sub_user);
846 reload_services(sconn, conn_snum_used, true);
849 struct auth4_context *auth_context = NULL;
851 DEBUG(3,("Got anonymous request\n"));
853 nt_status = make_auth4_context(talloc_tos(), &auth_context);
854 if (NT_STATUS_IS_OK(nt_status)) {
857 auth_context->get_ntlm_challenge(auth_context,
860 if (!make_user_info_guest(talloc_tos(),
861 sconn->remote_address,
862 sconn->local_address,
863 "SMB", &user_info)) {
864 nt_status = NT_STATUS_NO_MEMORY;
867 if (NT_STATUS_IS_OK(nt_status)) {
868 user_info->auth_description = "guest";
869 nt_status = auth_check_password_session_info(
874 TALLOC_FREE(auth_context);
876 } else if (doencrypt) {
877 struct auth4_context *negprot_auth_context = NULL;
878 negprot_auth_context = xconn->smb1.negprot.auth_context;
879 if (!negprot_auth_context) {
880 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
881 "session setup without negprot denied!\n"));
882 reply_nterror(req, nt_status_squash(
883 NT_STATUS_LOGON_FAILURE));
884 END_PROFILE(SMBsesssetupX);
887 nt_status = make_user_info_for_reply_enc(talloc_tos(),
890 sconn->remote_address,
891 sconn->local_address,
895 if (NT_STATUS_IS_OK(nt_status)) {
896 user_info->auth_description = "bare-NTLM";
897 nt_status = auth_check_password_session_info(negprot_auth_context,
898 req, user_info, &session_info);
901 struct auth4_context *plaintext_auth_context = NULL;
903 nt_status = make_auth4_context(
904 talloc_tos(), &plaintext_auth_context);
906 if (NT_STATUS_IS_OK(nt_status)) {
909 plaintext_auth_context->get_ntlm_challenge(
910 plaintext_auth_context, chal);
912 if (!make_user_info_for_reply(talloc_tos(),
915 sconn->remote_address,
916 sconn->local_address,
919 plaintext_password)) {
920 nt_status = NT_STATUS_NO_MEMORY;
923 if (NT_STATUS_IS_OK(nt_status)) {
924 user_info->auth_description = "plaintext";
925 nt_status = auth_check_password_session_info(plaintext_auth_context,
926 req, user_info, &session_info);
928 TALLOC_FREE(plaintext_auth_context);
932 TALLOC_FREE(user_info);
934 if (!NT_STATUS_IS_OK(nt_status)) {
935 data_blob_free(&nt_resp);
936 data_blob_free(&lm_resp);
937 data_blob_clear_free(&plaintext_password);
938 reply_nterror(req, nt_status_squash(nt_status));
939 END_PROFILE(SMBsesssetupX);
943 data_blob_clear_free(&plaintext_password);
945 /* it's ok - setup a reply */
946 reply_outbuf(req, 3, 0);
947 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
948 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
950 if (get_Protocol() >= PROTOCOL_NT1) {
951 push_signature(&req->outbuf);
952 /* perhaps grab OS version here?? */
955 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
956 action |= SMB_SETUP_GUEST;
959 /* register the name and uid as being validated, so further connections
960 to a uid can get through without a password, on the same VC */
962 nt_status = smbXsrv_session_create(xconn,
964 if (!NT_STATUS_IS_OK(nt_status)) {
965 data_blob_free(&nt_resp);
966 data_blob_free(&lm_resp);
967 reply_nterror(req, nt_status_squash(nt_status));
968 END_PROFILE(SMBsesssetupX);
972 if (session_info->session_key.length > 0) {
973 uint8_t session_key[16];
976 * Note: the SMB1 signing key is not truncated to 16 byte!
978 session->global->signing_key =
979 data_blob_dup_talloc(session->global,
980 session_info->session_key);
981 if (session->global->signing_key.data == NULL) {
982 data_blob_free(&nt_resp);
983 data_blob_free(&lm_resp);
984 TALLOC_FREE(session);
985 reply_nterror(req, NT_STATUS_NO_MEMORY);
986 END_PROFILE(SMBsesssetupX);
991 * The application key is truncated/padded to 16 bytes
993 ZERO_STRUCT(session_key);
994 memcpy(session_key, session->global->signing_key.data,
995 MIN(session->global->signing_key.length,
996 sizeof(session_key)));
997 session->global->application_key =
998 data_blob_talloc(session->global,
1000 sizeof(session_key));
1001 ZERO_STRUCT(session_key);
1002 if (session->global->application_key.data == NULL) {
1003 data_blob_free(&nt_resp);
1004 data_blob_free(&lm_resp);
1005 TALLOC_FREE(session);
1006 reply_nterror(req, NT_STATUS_NO_MEMORY);
1007 END_PROFILE(SMBsesssetupX);
1012 * Place the application key into the session_info
1014 data_blob_clear_free(&session_info->session_key);
1015 session_info->session_key = data_blob_dup_talloc(session_info,
1016 session->global->application_key);
1017 if (session_info->session_key.data == NULL) {
1018 data_blob_free(&nt_resp);
1019 data_blob_free(&lm_resp);
1020 TALLOC_FREE(session);
1021 reply_nterror(req, NT_STATUS_NO_MEMORY);
1022 END_PROFILE(SMBsesssetupX);
1027 session->compat = talloc_zero(session, struct user_struct);
1028 if (session->compat == NULL) {
1029 data_blob_free(&nt_resp);
1030 data_blob_free(&lm_resp);
1031 TALLOC_FREE(session);
1032 reply_nterror(req, NT_STATUS_NO_MEMORY);
1033 END_PROFILE(SMBsesssetupX);
1036 session->compat->session = session;
1037 session->compat->homes_snum = -1;
1038 session->compat->session_info = session_info;
1039 session->compat->session_keystr = NULL;
1040 session->compat->vuid = session->global->session_wire_id;
1041 DLIST_ADD(sconn->users, session->compat);
1044 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1045 is_authenticated = true;
1046 session->compat->homes_snum =
1047 register_homes_share(session_info->unix_info->unix_name);
1050 if (srv_is_signing_negotiated(xconn) &&
1052 session->global->signing_key.length > 0)
1055 * Try and turn on server signing on the first non-guest
1058 srv_set_signing(xconn,
1059 session->global->signing_key,
1060 nt_resp.data ? nt_resp : lm_resp);
1063 set_current_user_info(session_info->unix_info->sanitized_username,
1064 session_info->unix_info->unix_name,
1065 session_info->info->domain_name);
1067 session->status = NT_STATUS_OK;
1068 session->global->auth_session_info = talloc_move(session->global,
1070 session->global->auth_session_info_seqnum += 1;
1071 session->global->channels[0].auth_session_info_seqnum =
1072 session->global->auth_session_info_seqnum;
1073 session->global->auth_time = now;
1074 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1076 nt_status = smbXsrv_session_update(session);
1077 if (!NT_STATUS_IS_OK(nt_status)) {
1078 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1079 (unsigned long long)session->compat->vuid,
1080 nt_errstr(nt_status)));
1081 data_blob_free(&nt_resp);
1082 data_blob_free(&lm_resp);
1083 TALLOC_FREE(session);
1084 reply_nterror(req, nt_status_squash(nt_status));
1085 END_PROFILE(SMBsesssetupX);
1089 if (!session_claim(session)) {
1090 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1091 (unsigned long long)session->compat->vuid));
1092 data_blob_free(&nt_resp);
1093 data_blob_free(&lm_resp);
1094 TALLOC_FREE(session);
1095 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1096 END_PROFILE(SMBsesssetupX);
1100 /* current_user_info is changed on new vuid */
1101 reload_services(sconn, conn_snum_used, true);
1103 sess_vuid = session->global->session_wire_id;
1105 data_blob_free(&nt_resp);
1106 data_blob_free(&lm_resp);
1108 SSVAL(req->outbuf,smb_vwv2,action);
1109 SSVAL(req->outbuf,smb_uid,sess_vuid);
1110 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1111 req->vuid = sess_vuid;
1113 if (!xconn->smb1.sessions.done_sesssetup) {
1114 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1115 reply_force_doserror(req, ERRSRV, ERRerror);
1116 END_PROFILE(SMBsesssetupX);
1119 xconn->smb1.sessions.max_send = smb_bufsize;
1120 xconn->smb1.sessions.done_sesssetup = true;
1123 END_PROFILE(SMBsesssetupX);