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 struct reply_sesssetup_and_X_state {
559 struct smb_request *req;
564 DATA_BLOB plaintext_password;
567 static int reply_sesssetup_and_X_state_destructor(
568 struct reply_sesssetup_and_X_state *state)
570 data_blob_clear_free(&state->nt_resp);
571 data_blob_clear_free(&state->lm_resp);
572 data_blob_clear_free(&state->plaintext_password);
576 void reply_sesssetup_and_X(struct smb_request *req)
578 struct reply_sesssetup_and_X_state *state = NULL;
580 uint16_t smb_bufsize;
582 fstring sub_user; /* Sanitised username for substituion */
583 const char *native_os;
584 const char *native_lanman;
585 const char *primary_domain;
586 struct auth_usersupplied_info *user_info = NULL;
587 struct auth_session_info *session_info = NULL;
588 uint16_t smb_flag2 = req->flags2;
590 bool is_authenticated = false;
591 NTTIME now = timeval_to_nttime(&req->request_time);
592 struct smbXsrv_session *session = NULL;
594 struct smbXsrv_connection *xconn = req->xconn;
595 struct smbd_server_connection *sconn = req->sconn;
596 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
597 bool signing_allowed = false;
598 bool signing_mandatory = smb_signing_is_mandatory(
599 xconn->smb1.signing_state);
601 START_PROFILE(SMBsesssetupX);
603 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
605 state = talloc_zero(req, struct reply_sesssetup_and_X_state);
607 reply_nterror(req, NT_STATUS_NO_MEMORY);
608 END_PROFILE(SMBsesssetupX);
612 talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
614 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
615 signing_allowed = true;
617 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
618 signing_mandatory = true;
622 * We can call srv_set_signing_negotiated() each time.
623 * It finds out when it needs to turn into a noop
626 srv_set_signing_negotiated(xconn,
630 /* a SPNEGO session setup has 12 command words, whereas a normal
631 NT1 session setup has 13. See the cifs spec. */
632 if (req->wct == 12 &&
633 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
635 if (!xconn->smb1.negprot.spnego) {
636 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
637 "at SPNEGO session setup when it was not "
639 reply_nterror(req, nt_status_squash(
640 NT_STATUS_LOGON_FAILURE));
641 END_PROFILE(SMBsesssetupX);
645 if (SVAL(req->vwv+4, 0) == 0) {
646 setup_new_vc_session(req->sconn);
649 reply_sesssetup_and_X_spnego(req);
650 END_PROFILE(SMBsesssetupX);
654 smb_bufsize = SVAL(req->vwv+2, 0);
656 if (get_Protocol() < PROTOCOL_NT1) {
657 uint16_t passlen1 = SVAL(req->vwv+7, 0);
659 /* Never do NT status codes with protocols before NT1 as we
660 * don't get client caps. */
661 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
663 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
664 reply_nterror(req, nt_status_squash(
665 NT_STATUS_INVALID_PARAMETER));
666 END_PROFILE(SMBsesssetupX);
671 state->lm_resp = data_blob_talloc(state,
675 state->plaintext_password = data_blob_talloc(state,
678 /* Ensure null termination */
679 state->plaintext_password.data[passlen1] = 0;
682 srvstr_pull_req_talloc(state, req, &tmp,
683 req->buf + passlen1, STR_TERMINATE);
684 state->user = tmp ? tmp : "";
689 uint16_t passlen1 = SVAL(req->vwv+7, 0);
690 uint16_t passlen2 = SVAL(req->vwv+8, 0);
691 enum remote_arch_types ra_type = get_remote_arch();
692 const uint8_t *p = req->buf;
693 const uint8_t *save_p = req->buf;
696 if (!xconn->smb1.sessions.done_sesssetup) {
697 global_client_caps = IVAL(req->vwv+11, 0);
699 if (!(global_client_caps & CAP_STATUS32)) {
700 remove_from_common_flags2(
701 FLAGS2_32_BIT_ERROR_CODES);
704 /* client_caps is used as final determination if
705 * client is NT or Win95. This is needed to return
706 * the correct error codes in some circumstances.
709 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
710 ra_type == RA_WIN95) {
711 if(!(global_client_caps & (CAP_NT_SMBS|
713 set_remote_arch( RA_WIN95);
719 /* both Win95 and WinNT stuff up the password
720 * lengths for non-encrypting systems. Uggh.
722 if passlen1==24 its a win95 system, and its setting
723 the password length incorrectly. Luckily it still
724 works with the default code because Win95 will null
725 terminate the password anyway
727 if passlen1>0 and passlen2>0 then maybe its a NT box
728 and its setting passlen2 to some random value which
729 really stuffs things up. we need to fix that one. */
731 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
737 /* check for nasty tricks */
738 if (passlen1 > MAX_PASS_LEN
739 || passlen1 > smbreq_bufrem(req, p)) {
740 reply_nterror(req, nt_status_squash(
741 NT_STATUS_INVALID_PARAMETER));
742 END_PROFILE(SMBsesssetupX);
746 if (passlen2 > MAX_PASS_LEN
747 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
748 reply_nterror(req, nt_status_squash(
749 NT_STATUS_INVALID_PARAMETER));
750 END_PROFILE(SMBsesssetupX);
754 /* Save the lanman2 password and the NT md4 password. */
756 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
761 state->lm_resp = data_blob_talloc(state, p, passlen1);
762 state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
765 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
767 if (unic && (passlen2 == 0) && passlen1) {
768 /* Only a ascii plaintext password was sent. */
769 (void)srvstr_pull_talloc(state,
775 STR_TERMINATE|STR_ASCII);
777 (void)srvstr_pull_talloc(state,
782 unic ? passlen2 : passlen1,
786 reply_nterror(req, nt_status_squash(
787 NT_STATUS_INVALID_PARAMETER));
788 END_PROFILE(SMBsesssetupX);
791 state->plaintext_password = data_blob_talloc(state,
796 p += passlen1 + passlen2;
798 p += srvstr_pull_req_talloc(state, req, &tmp, p,
800 state->user = tmp ? tmp : "";
802 p += srvstr_pull_req_talloc(state, req, &tmp, p,
804 state->domain = tmp ? tmp : "";
806 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
808 native_os = tmp ? tmp : "";
810 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
812 native_lanman = tmp ? tmp : "";
814 /* not documented or decoded by Ethereal but there is one more
815 * string in the extra bytes which is the same as the
816 * PrimaryDomain when using extended security. Windows NT 4
817 * and 2003 use this string to store the native lanman string.
818 * Windows 9x does not include a string here at all so we have
819 * to check if we have any extra bytes left */
821 byte_count = SVAL(req->vwv+13, 0);
822 if ( PTR_DIFF(p, save_p) < byte_count) {
823 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
825 primary_domain = tmp ? tmp : "";
827 primary_domain = talloc_strdup(talloc_tos(), "null");
830 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
831 "PrimaryDomain=[%s]\n",
832 state->domain, native_os, native_lanman, primary_domain));
834 if ( ra_type == RA_WIN2K ) {
835 if ( strlen(native_lanman) == 0 )
836 ra_lanman_string( primary_domain );
838 ra_lanman_string( native_lanman );
843 if (SVAL(req->vwv+4, 0) == 0) {
844 setup_new_vc_session(req->sconn);
847 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
848 state->domain, state->user, get_remote_machine_name()));
851 if (xconn->smb1.negprot.spnego) {
853 /* This has to be here, because this is a perfectly
854 * valid behaviour for guest logons :-( */
856 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
857 "at 'normal' session setup after "
858 "negotiating spnego.\n"));
859 reply_nterror(req, nt_status_squash(
860 NT_STATUS_LOGON_FAILURE));
861 END_PROFILE(SMBsesssetupX);
864 fstrcpy(sub_user, state->user);
866 fstrcpy(sub_user, "");
869 sub_set_smb_name(sub_user);
871 reload_services(sconn, conn_snum_used, true);
874 struct auth4_context *auth_context = NULL;
876 DEBUG(3,("Got anonymous request\n"));
878 nt_status = make_auth4_context(state, &auth_context);
879 if (NT_STATUS_IS_OK(nt_status)) {
882 auth_context->get_ntlm_challenge(auth_context,
885 if (!make_user_info_guest(state,
886 sconn->remote_address,
887 sconn->local_address,
888 "SMB", &user_info)) {
889 nt_status = NT_STATUS_NO_MEMORY;
892 if (NT_STATUS_IS_OK(nt_status)) {
893 user_info->auth_description = "guest";
894 nt_status = auth_check_password_session_info(
899 TALLOC_FREE(auth_context);
901 } else if (doencrypt) {
902 struct auth4_context *negprot_auth_context = NULL;
903 negprot_auth_context = xconn->smb1.negprot.auth_context;
904 if (!negprot_auth_context) {
905 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
906 "session setup without negprot denied!\n"));
907 reply_nterror(req, nt_status_squash(
908 NT_STATUS_LOGON_FAILURE));
909 END_PROFILE(SMBsesssetupX);
912 nt_status = make_user_info_for_reply_enc(state,
916 sconn->remote_address,
917 sconn->local_address,
922 if (NT_STATUS_IS_OK(nt_status)) {
923 user_info->auth_description = "bare-NTLM";
924 nt_status = auth_check_password_session_info(negprot_auth_context,
925 req, user_info, &session_info);
928 struct auth4_context *plaintext_auth_context = NULL;
930 nt_status = make_auth4_context(
931 state, &plaintext_auth_context);
933 if (NT_STATUS_IS_OK(nt_status)) {
936 plaintext_auth_context->get_ntlm_challenge(
937 plaintext_auth_context, chal);
939 if (!make_user_info_for_reply(state,
943 sconn->remote_address,
944 sconn->local_address,
947 state->plaintext_password)) {
948 nt_status = NT_STATUS_NO_MEMORY;
951 if (NT_STATUS_IS_OK(nt_status)) {
952 user_info->auth_description = "plaintext";
953 nt_status = auth_check_password_session_info(plaintext_auth_context,
954 req, user_info, &session_info);
956 TALLOC_FREE(plaintext_auth_context);
960 TALLOC_FREE(user_info);
962 if (!NT_STATUS_IS_OK(nt_status)) {
963 reply_nterror(req, nt_status_squash(nt_status));
964 END_PROFILE(SMBsesssetupX);
968 /* it's ok - setup a reply */
969 reply_outbuf(req, 3, 0);
970 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
971 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
973 if (get_Protocol() >= PROTOCOL_NT1) {
974 push_signature(&req->outbuf);
975 /* perhaps grab OS version here?? */
978 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
979 action |= SMB_SETUP_GUEST;
982 /* register the name and uid as being validated, so further connections
983 to a uid can get through without a password, on the same VC */
985 nt_status = smbXsrv_session_create(xconn,
987 if (!NT_STATUS_IS_OK(nt_status)) {
988 reply_nterror(req, nt_status_squash(nt_status));
989 END_PROFILE(SMBsesssetupX);
993 if (session_info->session_key.length > 0) {
994 uint8_t session_key[16];
997 * Note: the SMB1 signing key is not truncated to 16 byte!
999 session->global->signing_key =
1000 data_blob_dup_talloc(session->global,
1001 session_info->session_key);
1002 if (session->global->signing_key.data == NULL) {
1003 TALLOC_FREE(session);
1004 reply_nterror(req, NT_STATUS_NO_MEMORY);
1005 END_PROFILE(SMBsesssetupX);
1010 * The application key is truncated/padded to 16 bytes
1012 ZERO_STRUCT(session_key);
1013 memcpy(session_key, session->global->signing_key.data,
1014 MIN(session->global->signing_key.length,
1015 sizeof(session_key)));
1016 session->global->application_key =
1017 data_blob_talloc(session->global,
1019 sizeof(session_key));
1020 ZERO_STRUCT(session_key);
1021 if (session->global->application_key.data == NULL) {
1022 TALLOC_FREE(session);
1023 reply_nterror(req, NT_STATUS_NO_MEMORY);
1024 END_PROFILE(SMBsesssetupX);
1029 * Place the application key into the session_info
1031 data_blob_clear_free(&session_info->session_key);
1032 session_info->session_key = data_blob_dup_talloc(session_info,
1033 session->global->application_key);
1034 if (session_info->session_key.data == NULL) {
1035 TALLOC_FREE(session);
1036 reply_nterror(req, NT_STATUS_NO_MEMORY);
1037 END_PROFILE(SMBsesssetupX);
1042 session->compat = talloc_zero(session, struct user_struct);
1043 if (session->compat == NULL) {
1044 TALLOC_FREE(session);
1045 reply_nterror(req, NT_STATUS_NO_MEMORY);
1046 END_PROFILE(SMBsesssetupX);
1049 session->compat->session = session;
1050 session->compat->homes_snum = -1;
1051 session->compat->session_info = session_info;
1052 session->compat->session_keystr = NULL;
1053 session->compat->vuid = session->global->session_wire_id;
1054 DLIST_ADD(sconn->users, session->compat);
1057 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1058 is_authenticated = true;
1059 session->compat->homes_snum =
1060 register_homes_share(session_info->unix_info->unix_name);
1063 if (srv_is_signing_negotiated(xconn) &&
1065 session->global->signing_key.length > 0)
1068 * Try and turn on server signing on the first non-guest
1071 srv_set_signing(xconn,
1072 session->global->signing_key,
1073 state->nt_resp.data ? state->nt_resp : state->lm_resp);
1076 set_current_user_info(session_info->unix_info->sanitized_username,
1077 session_info->unix_info->unix_name,
1078 session_info->info->domain_name);
1080 session->status = NT_STATUS_OK;
1081 session->global->auth_session_info = talloc_move(session->global,
1083 session->global->auth_session_info_seqnum += 1;
1084 session->global->channels[0].auth_session_info_seqnum =
1085 session->global->auth_session_info_seqnum;
1086 session->global->auth_time = now;
1087 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1089 nt_status = smbXsrv_session_update(session);
1090 if (!NT_STATUS_IS_OK(nt_status)) {
1091 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1092 (unsigned long long)session->compat->vuid,
1093 nt_errstr(nt_status)));
1094 TALLOC_FREE(session);
1095 reply_nterror(req, nt_status_squash(nt_status));
1096 END_PROFILE(SMBsesssetupX);
1100 if (!session_claim(session)) {
1101 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1102 (unsigned long long)session->compat->vuid));
1103 TALLOC_FREE(session);
1104 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1105 END_PROFILE(SMBsesssetupX);
1109 /* current_user_info is changed on new vuid */
1110 reload_services(sconn, conn_snum_used, true);
1112 sess_vuid = session->global->session_wire_id;
1114 SSVAL(req->outbuf,smb_vwv2,action);
1115 SSVAL(req->outbuf,smb_uid,sess_vuid);
1116 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1117 req->vuid = sess_vuid;
1119 if (!xconn->smb1.sessions.done_sesssetup) {
1120 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1121 reply_force_doserror(req, ERRSRV, ERRerror);
1122 END_PROFILE(SMBsesssetupX);
1125 xconn->smb1.sessions.max_send = smb_bufsize;
1126 xconn->smb1.sessions.done_sesssetup = true;
1130 END_PROFILE(SMBsesssetupX);