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"));
535 if (lp_reset_on_zero_vc()) {
537 struct shutdown_state state;
539 addr = tsocket_address_inet_addr_string(
540 sconn->remote_address, talloc_tos());
545 state.msg_ctx = sconn->msg_ctx;
546 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
551 /****************************************************************************
552 Reply to a session setup command.
553 ****************************************************************************/
555 struct reply_sesssetup_and_X_state {
556 struct smb_request *req;
557 struct auth4_context *auth_context;
558 struct auth_usersupplied_info *user_info;
563 DATA_BLOB plaintext_password;
566 static int reply_sesssetup_and_X_state_destructor(
567 struct reply_sesssetup_and_X_state *state)
569 data_blob_clear_free(&state->nt_resp);
570 data_blob_clear_free(&state->lm_resp);
571 data_blob_clear_free(&state->plaintext_password);
575 void reply_sesssetup_and_X(struct smb_request *req)
577 struct reply_sesssetup_and_X_state *state = NULL;
579 uint16_t smb_bufsize;
581 fstring sub_user; /* Sanitised username for substituion */
582 const char *native_os;
583 const char *native_lanman;
584 const char *primary_domain;
585 struct auth_session_info *session_info = NULL;
586 uint16_t smb_flag2 = req->flags2;
588 bool is_authenticated = false;
589 NTTIME now = timeval_to_nttime(&req->request_time);
590 struct smbXsrv_session *session = NULL;
592 struct smbXsrv_connection *xconn = req->xconn;
593 struct smbd_server_connection *sconn = req->sconn;
594 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
595 bool signing_allowed = false;
596 bool signing_mandatory = smb_signing_is_mandatory(
597 xconn->smb1.signing_state);
599 START_PROFILE(SMBsesssetupX);
601 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
603 state = talloc_zero(req, struct reply_sesssetup_and_X_state);
605 reply_nterror(req, NT_STATUS_NO_MEMORY);
606 END_PROFILE(SMBsesssetupX);
610 talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
612 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
613 signing_allowed = true;
615 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
616 signing_mandatory = true;
620 * We can call srv_set_signing_negotiated() each time.
621 * It finds out when it needs to turn into a noop
624 srv_set_signing_negotiated(xconn,
628 /* a SPNEGO session setup has 12 command words, whereas a normal
629 NT1 session setup has 13. See the cifs spec. */
630 if (req->wct == 12 &&
631 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
633 if (!xconn->smb1.negprot.spnego) {
634 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
635 "at SPNEGO session setup when it was not "
637 reply_nterror(req, nt_status_squash(
638 NT_STATUS_LOGON_FAILURE));
639 END_PROFILE(SMBsesssetupX);
643 if (SVAL(req->vwv+4, 0) == 0) {
644 setup_new_vc_session(req->sconn);
647 reply_sesssetup_and_X_spnego(req);
648 END_PROFILE(SMBsesssetupX);
652 smb_bufsize = SVAL(req->vwv+2, 0);
654 if (get_Protocol() < PROTOCOL_NT1) {
655 uint16_t passlen1 = SVAL(req->vwv+7, 0);
657 /* Never do NT status codes with protocols before NT1 as we
658 * don't get client caps. */
659 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
661 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
662 reply_nterror(req, nt_status_squash(
663 NT_STATUS_INVALID_PARAMETER));
664 END_PROFILE(SMBsesssetupX);
669 state->lm_resp = data_blob_talloc(state,
673 state->plaintext_password = data_blob_talloc(state,
676 /* Ensure null termination */
677 state->plaintext_password.data[passlen1] = 0;
680 srvstr_pull_req_talloc(state, req, &tmp,
681 req->buf + passlen1, STR_TERMINATE);
682 state->user = tmp ? tmp : "";
687 uint16_t passlen1 = SVAL(req->vwv+7, 0);
688 uint16_t passlen2 = SVAL(req->vwv+8, 0);
689 enum remote_arch_types ra_type = get_remote_arch();
690 const uint8_t *p = req->buf;
691 const uint8_t *save_p = req->buf;
694 if (!xconn->smb1.sessions.done_sesssetup) {
695 global_client_caps = IVAL(req->vwv+11, 0);
697 if (!(global_client_caps & CAP_STATUS32)) {
698 remove_from_common_flags2(
699 FLAGS2_32_BIT_ERROR_CODES);
702 /* client_caps is used as final determination if
703 * client is NT or Win95. This is needed to return
704 * the correct error codes in some circumstances.
707 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
708 ra_type == RA_WIN95) {
709 if(!(global_client_caps & (CAP_NT_SMBS|
711 set_remote_arch( RA_WIN95);
717 /* both Win95 and WinNT stuff up the password
718 * lengths for non-encrypting systems. Uggh.
720 if passlen1==24 its a win95 system, and its setting
721 the password length incorrectly. Luckily it still
722 works with the default code because Win95 will null
723 terminate the password anyway
725 if passlen1>0 and passlen2>0 then maybe its a NT box
726 and its setting passlen2 to some random value which
727 really stuffs things up. we need to fix that one. */
729 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
735 /* check for nasty tricks */
736 if (passlen1 > MAX_PASS_LEN
737 || passlen1 > smbreq_bufrem(req, p)) {
738 reply_nterror(req, nt_status_squash(
739 NT_STATUS_INVALID_PARAMETER));
740 END_PROFILE(SMBsesssetupX);
744 if (passlen2 > MAX_PASS_LEN
745 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
746 reply_nterror(req, nt_status_squash(
747 NT_STATUS_INVALID_PARAMETER));
748 END_PROFILE(SMBsesssetupX);
752 /* Save the lanman2 password and the NT md4 password. */
754 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
759 state->lm_resp = data_blob_talloc(state, p, passlen1);
760 state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
763 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
765 if (unic && (passlen2 == 0) && passlen1) {
766 /* Only a ascii plaintext password was sent. */
767 (void)srvstr_pull_talloc(state,
773 STR_TERMINATE|STR_ASCII);
775 (void)srvstr_pull_talloc(state,
780 unic ? passlen2 : passlen1,
784 reply_nterror(req, nt_status_squash(
785 NT_STATUS_INVALID_PARAMETER));
786 END_PROFILE(SMBsesssetupX);
789 state->plaintext_password = data_blob_talloc(state,
794 p += passlen1 + passlen2;
796 p += srvstr_pull_req_talloc(state, req, &tmp, p,
798 state->user = tmp ? tmp : "";
800 p += srvstr_pull_req_talloc(state, req, &tmp, p,
802 state->domain = tmp ? tmp : "";
804 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
806 native_os = tmp ? tmp : "";
808 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
810 native_lanman = tmp ? tmp : "";
812 /* not documented or decoded by Ethereal but there is one more
813 * string in the extra bytes which is the same as the
814 * PrimaryDomain when using extended security. Windows NT 4
815 * and 2003 use this string to store the native lanman string.
816 * Windows 9x does not include a string here at all so we have
817 * to check if we have any extra bytes left */
819 byte_count = SVAL(req->vwv+13, 0);
820 if ( PTR_DIFF(p, save_p) < byte_count) {
821 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
823 primary_domain = tmp ? tmp : "";
825 primary_domain = talloc_strdup(talloc_tos(), "null");
828 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
829 "PrimaryDomain=[%s]\n",
830 state->domain, native_os, native_lanman, primary_domain));
832 if ( ra_type == RA_WIN2K ) {
833 if ( strlen(native_lanman) == 0 )
834 ra_lanman_string( primary_domain );
836 ra_lanman_string( native_lanman );
841 if (SVAL(req->vwv+4, 0) == 0) {
842 setup_new_vc_session(req->sconn);
845 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
846 state->domain, state->user, get_remote_machine_name()));
849 if (xconn->smb1.negprot.spnego) {
851 /* This has to be here, because this is a perfectly
852 * valid behaviour for guest logons :-( */
854 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
855 "at 'normal' session setup after "
856 "negotiating spnego.\n"));
857 reply_nterror(req, nt_status_squash(
858 NT_STATUS_LOGON_FAILURE));
859 END_PROFILE(SMBsesssetupX);
862 fstrcpy(sub_user, state->user);
864 fstrcpy(sub_user, "");
867 sub_set_smb_name(sub_user);
869 reload_services(sconn, conn_snum_used, true);
872 DEBUG(3,("Got anonymous request\n"));
874 nt_status = make_auth4_context(state, &state->auth_context);
875 if (NT_STATUS_IS_OK(nt_status)) {
878 state->auth_context->get_ntlm_challenge(
879 state->auth_context, chal);
881 if (!make_user_info_guest(state,
882 sconn->remote_address,
883 sconn->local_address,
884 "SMB", &state->user_info)) {
885 nt_status = NT_STATUS_NO_MEMORY;
888 if (NT_STATUS_IS_OK(nt_status)) {
889 state->user_info->auth_description = "guest";
892 } else if (doencrypt) {
893 state->auth_context = xconn->smb1.negprot.auth_context;
894 if (state->auth_context == NULL) {
895 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
896 "session setup without negprot denied!\n"));
897 reply_nterror(req, nt_status_squash(
898 NT_STATUS_LOGON_FAILURE));
899 END_PROFILE(SMBsesssetupX);
902 nt_status = make_user_info_for_reply_enc(state,
906 sconn->remote_address,
907 sconn->local_address,
912 if (NT_STATUS_IS_OK(nt_status)) {
913 state->user_info->auth_description = "bare-NTLM";
916 nt_status = make_auth4_context(state, &state->auth_context);
917 if (NT_STATUS_IS_OK(nt_status)) {
920 state->auth_context->get_ntlm_challenge(
921 state->auth_context, chal);
923 if (!make_user_info_for_reply(state,
927 sconn->remote_address,
928 sconn->local_address,
931 state->plaintext_password)) {
932 nt_status = NT_STATUS_NO_MEMORY;
935 if (NT_STATUS_IS_OK(nt_status)) {
936 state->user_info->auth_description = "plaintext";
941 if (!NT_STATUS_IS_OK(nt_status)) {
942 reply_nterror(req, nt_status_squash(nt_status));
943 END_PROFILE(SMBsesssetupX);
947 nt_status = auth_check_password_session_info(state->auth_context,
948 req, state->user_info,
950 TALLOC_FREE(state->user_info);
951 if (!NT_STATUS_IS_OK(nt_status)) {
952 reply_nterror(req, nt_status_squash(nt_status));
953 END_PROFILE(SMBsesssetupX);
957 /* it's ok - setup a reply */
958 reply_outbuf(req, 3, 0);
959 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
960 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
962 if (get_Protocol() >= PROTOCOL_NT1) {
963 push_signature(&req->outbuf);
964 /* perhaps grab OS version here?? */
967 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
968 action |= SMB_SETUP_GUEST;
971 /* register the name and uid as being validated, so further connections
972 to a uid can get through without a password, on the same VC */
974 nt_status = smbXsrv_session_create(xconn,
976 if (!NT_STATUS_IS_OK(nt_status)) {
977 reply_nterror(req, nt_status_squash(nt_status));
978 END_PROFILE(SMBsesssetupX);
982 if (session_info->session_key.length > 0) {
983 uint8_t session_key[16];
986 * Note: the SMB1 signing key is not truncated to 16 byte!
988 session->global->signing_key =
989 data_blob_dup_talloc(session->global,
990 session_info->session_key);
991 if (session->global->signing_key.data == NULL) {
992 TALLOC_FREE(session);
993 reply_nterror(req, NT_STATUS_NO_MEMORY);
994 END_PROFILE(SMBsesssetupX);
999 * The application key is truncated/padded to 16 bytes
1001 ZERO_STRUCT(session_key);
1002 memcpy(session_key, session->global->signing_key.data,
1003 MIN(session->global->signing_key.length,
1004 sizeof(session_key)));
1005 session->global->application_key =
1006 data_blob_talloc(session->global,
1008 sizeof(session_key));
1009 ZERO_STRUCT(session_key);
1010 if (session->global->application_key.data == NULL) {
1011 TALLOC_FREE(session);
1012 reply_nterror(req, NT_STATUS_NO_MEMORY);
1013 END_PROFILE(SMBsesssetupX);
1018 * Place the application key into the session_info
1020 data_blob_clear_free(&session_info->session_key);
1021 session_info->session_key = data_blob_dup_talloc(session_info,
1022 session->global->application_key);
1023 if (session_info->session_key.data == NULL) {
1024 TALLOC_FREE(session);
1025 reply_nterror(req, NT_STATUS_NO_MEMORY);
1026 END_PROFILE(SMBsesssetupX);
1031 session->compat = talloc_zero(session, struct user_struct);
1032 if (session->compat == NULL) {
1033 TALLOC_FREE(session);
1034 reply_nterror(req, NT_STATUS_NO_MEMORY);
1035 END_PROFILE(SMBsesssetupX);
1038 session->compat->session = session;
1039 session->compat->homes_snum = -1;
1040 session->compat->session_info = session_info;
1041 session->compat->session_keystr = NULL;
1042 session->compat->vuid = session->global->session_wire_id;
1043 DLIST_ADD(sconn->users, session->compat);
1046 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1047 is_authenticated = true;
1048 session->compat->homes_snum =
1049 register_homes_share(session_info->unix_info->unix_name);
1052 if (srv_is_signing_negotiated(xconn) &&
1054 session->global->signing_key.length > 0)
1057 * Try and turn on server signing on the first non-guest
1060 srv_set_signing(xconn,
1061 session->global->signing_key,
1062 state->nt_resp.data ? state->nt_resp : state->lm_resp);
1065 set_current_user_info(session_info->unix_info->sanitized_username,
1066 session_info->unix_info->unix_name,
1067 session_info->info->domain_name);
1069 session->status = NT_STATUS_OK;
1070 session->global->auth_session_info = talloc_move(session->global,
1072 session->global->auth_session_info_seqnum += 1;
1073 session->global->channels[0].auth_session_info_seqnum =
1074 session->global->auth_session_info_seqnum;
1075 session->global->auth_time = now;
1076 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1078 nt_status = smbXsrv_session_update(session);
1079 if (!NT_STATUS_IS_OK(nt_status)) {
1080 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1081 (unsigned long long)session->compat->vuid,
1082 nt_errstr(nt_status)));
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 TALLOC_FREE(session);
1093 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1094 END_PROFILE(SMBsesssetupX);
1098 /* current_user_info is changed on new vuid */
1099 reload_services(sconn, conn_snum_used, true);
1101 sess_vuid = session->global->session_wire_id;
1103 SSVAL(req->outbuf,smb_vwv2,action);
1104 SSVAL(req->outbuf,smb_uid,sess_vuid);
1105 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1106 req->vuid = sess_vuid;
1108 if (!xconn->smb1.sessions.done_sesssetup) {
1109 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1110 reply_force_doserror(req, ERRSRV, ERRerror);
1111 END_PROFILE(SMBsesssetupX);
1114 xconn->smb1.sessions.max_send = smb_bufsize;
1115 xconn->smb1.sessions.done_sesssetup = true;
1119 END_PROFILE(SMBsesssetupX);