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,
83 struct auth_session_info **session_info)
85 struct auth4_context *auth_context;
86 struct auth_usersupplied_info *user_info = NULL;
90 DEBUG(3,("Got anonymous request\n"));
92 nt_status = make_auth4_context(talloc_tos(), &auth_context);
93 if (!NT_STATUS_IS_OK(nt_status)) {
97 auth_context->get_ntlm_challenge(auth_context,
100 if (!make_user_info_guest(talloc_tos(), remote_address, &user_info)) {
101 TALLOC_FREE(auth_context);
102 return NT_STATUS_NO_MEMORY;
105 nt_status = auth_check_password_session_info(auth_context,
106 mem_ctx, user_info, session_info);
107 TALLOC_FREE(user_info);
108 TALLOC_FREE(auth_context);
112 /****************************************************************************
113 Reply to a session setup command.
114 conn POINTER CAN BE NULL HERE !
115 ****************************************************************************/
117 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
121 DATA_BLOB out_blob = data_blob_null;
124 const char *native_os;
125 const char *native_lanman;
126 const char *primary_domain;
127 uint16_t data_blob_len = SVAL(req->vwv+7, 0);
128 enum remote_arch_types ra_type = get_remote_arch();
129 uint64_t vuid = req->vuid;
130 NTSTATUS status = NT_STATUS_OK;
131 struct smbXsrv_connection *xconn = req->xconn;
132 struct smbd_server_connection *sconn = req->sconn;
134 bool is_authenticated = false;
135 NTTIME now = timeval_to_nttime(&req->request_time);
136 struct smbXsrv_session *session = NULL;
137 uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
138 uint32_t client_caps = IVAL(req->vwv+10, 0);
139 struct smbXsrv_session_auth0 *auth;
141 DEBUG(3,("Doing spnego session setup\n"));
143 if (!xconn->smb1.sessions.done_sesssetup) {
144 global_client_caps = client_caps;
146 if (!(global_client_caps & CAP_STATUS32)) {
147 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
153 if (data_blob_len == 0) {
154 /* an invalid request */
155 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
159 bufrem = smbreq_bufrem(req, p);
160 /* pull the spnego blob */
161 in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
164 file_save("negotiate.dat", in_blob.data, in_blob.length);
167 p = req->buf + in_blob.length;
169 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
171 native_os = tmp ? tmp : "";
173 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
175 native_lanman = tmp ? tmp : "";
177 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
179 primary_domain = tmp ? tmp : "";
181 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
182 native_os, native_lanman, primary_domain));
184 if ( ra_type == RA_WIN2K ) {
185 /* Vista sets neither the OS or lanman strings */
187 if ( !strlen(native_os) && !strlen(native_lanman) )
188 set_remote_arch(RA_VISTA);
190 /* Windows 2003 doesn't set the native lanman string,
191 but does set primary domain which is a bug I think */
193 if ( !strlen(native_lanman) ) {
194 ra_lanman_string( primary_domain );
196 ra_lanman_string( native_lanman );
198 } else if ( ra_type == RA_VISTA ) {
199 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
200 set_remote_arch(RA_OSX);
205 status = smb1srv_session_lookup(xconn,
208 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
209 reply_force_doserror(req, ERRSRV, ERRbaduid);
212 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
213 status = NT_STATUS_OK;
215 if (NT_STATUS_IS_OK(status)) {
216 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
217 status = NT_STATUS_MORE_PROCESSING_REQUIRED;
218 TALLOC_FREE(session->pending_auth);
220 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
221 reply_nterror(req, nt_status_squash(status));
226 if (session == NULL) {
227 /* create a new session */
228 status = smbXsrv_session_create(xconn,
230 if (!NT_STATUS_IS_OK(status)) {
231 reply_nterror(req, nt_status_squash(status));
236 status = smbXsrv_session_find_auth(session, xconn, now, &auth);
237 if (!NT_STATUS_IS_OK(status)) {
238 status = smbXsrv_session_create_auth(session, xconn, now,
242 if (!NT_STATUS_IS_OK(status)) {
243 reply_nterror(req, nt_status_squash(status));
248 if (auth->gensec == NULL) {
249 status = auth_generic_prepare(session, xconn->remote_address,
252 if (!NT_STATUS_IS_OK(status)) {
253 TALLOC_FREE(session);
254 reply_nterror(req, nt_status_squash(status));
258 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
259 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
261 status = gensec_start_mech_by_oid(auth->gensec,
263 if (!NT_STATUS_IS_OK(status)) {
264 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
265 TALLOC_FREE(session);;
266 reply_nterror(req, nt_status_squash(status));
272 status = gensec_update(auth->gensec,
276 if (!NT_STATUS_IS_OK(status) &&
277 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
278 TALLOC_FREE(session);
279 reply_nterror(req, nt_status_squash(status));
283 if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
284 struct auth_session_info *session_info = NULL;
286 status = gensec_session_info(auth->gensec,
289 if (!NT_STATUS_IS_OK(status)) {
290 DEBUG(1,("Failed to generate session_info "
291 "(user and group token) for session setup: %s\n",
293 data_blob_free(&out_blob);
294 TALLOC_FREE(session);
295 reply_nterror(req, nt_status_squash(status));
299 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
300 action |= SMB_SETUP_GUEST;
303 if (session_info->session_key.length > 0) {
304 struct smbXsrv_session *x = session;
307 * Note: the SMB1 signing key is not truncated to 16 byte!
309 x->global->signing_key =
310 data_blob_dup_talloc(x->global,
311 session_info->session_key);
312 if (x->global->signing_key.data == NULL) {
313 data_blob_free(&out_blob);
314 TALLOC_FREE(session);
315 reply_nterror(req, NT_STATUS_NO_MEMORY);
320 * clear the session key
321 * the first tcon will add setup the application key
323 data_blob_clear_free(&session_info->session_key);
326 session->compat = talloc_zero(session, struct user_struct);
327 if (session->compat == NULL) {
328 data_blob_free(&out_blob);
329 TALLOC_FREE(session);
330 reply_nterror(req, NT_STATUS_NO_MEMORY);
333 session->compat->session = session;
334 session->compat->homes_snum = -1;
335 session->compat->session_info = session_info;
336 session->compat->session_keystr = NULL;
337 session->compat->vuid = session->global->session_wire_id;
338 DLIST_ADD(sconn->users, session->compat);
341 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
342 is_authenticated = true;
343 session->compat->homes_snum =
344 register_homes_share(session_info->unix_info->unix_name);
347 if (srv_is_signing_negotiated(xconn) &&
349 session->global->signing_key.length > 0)
352 * Try and turn on server signing on the first non-guest
355 srv_set_signing(xconn,
356 session->global->signing_key,
360 set_current_user_info(session_info->unix_info->sanitized_username,
361 session_info->unix_info->unix_name,
362 session_info->info->domain_name);
364 session->status = NT_STATUS_OK;
365 session->global->auth_session_info = talloc_move(session->global,
367 session->global->auth_session_info_seqnum += 1;
368 session->global->channels[0].auth_session_info_seqnum =
369 session->global->auth_session_info_seqnum;
370 session->global->auth_time = now;
371 if (client_caps & CAP_DYNAMIC_REAUTH) {
372 session->global->expiration_time =
373 gensec_expire_time(auth->gensec);
375 session->global->expiration_time =
376 GENSEC_EXPIRE_TIME_INFINITY;
379 if (!session_claim(session)) {
380 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
381 (unsigned long long)session->compat->vuid));
382 data_blob_free(&out_blob);
383 TALLOC_FREE(session);
384 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
388 status = smbXsrv_session_update(session);
389 if (!NT_STATUS_IS_OK(status)) {
390 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
391 (unsigned long long)session->compat->vuid,
393 data_blob_free(&out_blob);
394 TALLOC_FREE(session);
395 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
399 if (!xconn->smb1.sessions.done_sesssetup) {
400 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
401 reply_force_doserror(req, ERRSRV, ERRerror);
404 xconn->smb1.sessions.max_send = smb_bufsize;
405 xconn->smb1.sessions.done_sesssetup = true;
408 /* current_user_info is changed on new vuid */
409 reload_services(sconn, conn_snum_used, true);
410 } else if (NT_STATUS_IS_OK(status)) {
411 struct auth_session_info *session_info = NULL;
413 status = gensec_session_info(auth->gensec,
416 if (!NT_STATUS_IS_OK(status)) {
417 DEBUG(1,("Failed to generate session_info "
418 "(user and group token) for session setup: %s\n",
420 data_blob_free(&out_blob);
421 TALLOC_FREE(session);
422 reply_nterror(req, nt_status_squash(status));
426 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
427 action |= SMB_SETUP_GUEST;
431 * Keep the application key
433 data_blob_clear_free(&session_info->session_key);
434 session_info->session_key =
435 session->global->auth_session_info->session_key;
436 talloc_steal(session_info, session_info->session_key.data);
437 TALLOC_FREE(session->global->auth_session_info);
439 session->compat->session_info = session_info;
441 session->compat->vuid = session->global->session_wire_id;
443 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
444 session->compat->homes_snum =
445 register_homes_share(session_info->unix_info->unix_name);
448 set_current_user_info(session_info->unix_info->sanitized_username,
449 session_info->unix_info->unix_name,
450 session_info->info->domain_name);
452 session->status = NT_STATUS_OK;
453 session->global->auth_session_info = talloc_move(session->global,
455 session->global->auth_session_info_seqnum += 1;
456 session->global->channels[0].auth_session_info_seqnum =
457 session->global->auth_session_info_seqnum;
458 session->global->auth_time = now;
459 if (client_caps & CAP_DYNAMIC_REAUTH) {
460 session->global->expiration_time =
461 gensec_expire_time(auth->gensec);
463 session->global->expiration_time =
464 GENSEC_EXPIRE_TIME_INFINITY;
467 status = smbXsrv_session_update(session);
468 if (!NT_STATUS_IS_OK(status)) {
469 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
470 (unsigned long long)session->compat->vuid,
472 data_blob_free(&out_blob);
473 TALLOC_FREE(session);
474 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
478 conn_clear_vuid_caches(sconn, session->compat->vuid);
480 /* current_user_info is changed on new vuid */
481 reload_services(sconn, conn_snum_used, true);
484 vuid = session->global->session_wire_id;
486 reply_outbuf(req, 4, 0);
488 SSVAL(req->outbuf, smb_uid, vuid);
489 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
490 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
491 SSVAL(req->outbuf, smb_vwv2, action);
492 SSVAL(req->outbuf, smb_vwv3, out_blob.length);
494 if (message_push_blob(&req->outbuf, out_blob) == -1) {
495 data_blob_free(&out_blob);
496 TALLOC_FREE(session);
497 reply_nterror(req, NT_STATUS_NO_MEMORY);
500 data_blob_free(&out_blob);
502 if (push_signature(&req->outbuf) == -1) {
503 TALLOC_FREE(session);
504 reply_nterror(req, NT_STATUS_NO_MEMORY);
509 /****************************************************************************
510 On new VC == 0, shutdown *all* old connections and users.
511 It seems that only NT4.x does this. At W2K and above (XP etc.).
512 a new session setup with VC==0 is ignored.
513 ****************************************************************************/
515 struct shutdown_state {
517 struct messaging_context *msg_ctx;
520 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
523 struct shutdown_state *state = (struct shutdown_state *)private_data;
524 struct server_id self_pid = messaging_server_id(state->msg_ctx);
525 struct server_id pid = session->channels[0].server_id;
526 const char *addr = session->channels[0].remote_address;
527 struct server_id_buf tmp;
529 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
530 server_id_str_buf(pid, &tmp), addr));
532 if (!process_exists(pid)) {
533 DEBUG(10, ("process does not exist\n"));
537 if (serverid_equal(&pid, &self_pid)) {
538 DEBUG(10, ("It's me\n"));
543 * here we use strstr() because 'addr'
544 * (session->channels[0].remote_address)
545 * contains a string like:
546 * 'ipv4:127.0.0.1:48163'
548 if (strstr(addr, state->ip) == NULL) {
549 DEBUG(10, ("%s does not match %s\n", state->ip, addr));
553 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
554 "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
557 messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
562 static void setup_new_vc_session(struct smbd_server_connection *sconn)
564 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
565 "compatible we would close all old resources.\n"));
568 invalidate_all_vuids();
570 if (lp_reset_on_zero_vc()) {
572 struct shutdown_state state;
574 addr = tsocket_address_inet_addr_string(
575 sconn->remote_address, talloc_tos());
580 state.msg_ctx = sconn->msg_ctx;
581 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
586 /****************************************************************************
587 Reply to a session setup command.
588 ****************************************************************************/
590 void reply_sesssetup_and_X(struct smb_request *req)
593 uint16_t smb_bufsize;
596 DATA_BLOB plaintext_password;
599 fstring sub_user; /* Sanitised username for substituion */
601 const char *native_os;
602 const char *native_lanman;
603 const char *primary_domain;
604 struct auth_usersupplied_info *user_info = NULL;
605 struct auth_session_info *session_info = NULL;
606 uint16_t smb_flag2 = req->flags2;
608 bool is_authenticated = false;
609 NTTIME now = timeval_to_nttime(&req->request_time);
610 struct smbXsrv_session *session = NULL;
612 struct smbXsrv_connection *xconn = req->xconn;
613 struct smbd_server_connection *sconn = req->sconn;
614 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
615 bool signing_allowed = false;
616 bool signing_mandatory = smb_signing_is_mandatory(
617 xconn->smb1.signing_state);
619 START_PROFILE(SMBsesssetupX);
621 ZERO_STRUCT(lm_resp);
622 ZERO_STRUCT(nt_resp);
623 ZERO_STRUCT(plaintext_password);
625 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
627 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
628 signing_allowed = true;
630 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
631 signing_mandatory = true;
635 * We can call srv_set_signing_negotiated() each time.
636 * It finds out when it needs to turn into a noop
639 srv_set_signing_negotiated(xconn,
643 /* a SPNEGO session setup has 12 command words, whereas a normal
644 NT1 session setup has 13. See the cifs spec. */
645 if (req->wct == 12 &&
646 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
648 if (!xconn->smb1.negprot.spnego) {
649 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
650 "at SPNEGO session setup when it was not "
652 reply_nterror(req, nt_status_squash(
653 NT_STATUS_LOGON_FAILURE));
654 END_PROFILE(SMBsesssetupX);
658 if (SVAL(req->vwv+4, 0) == 0) {
659 setup_new_vc_session(req->sconn);
662 reply_sesssetup_and_X_spnego(req);
663 END_PROFILE(SMBsesssetupX);
667 smb_bufsize = SVAL(req->vwv+2, 0);
669 if (get_Protocol() < PROTOCOL_NT1) {
670 uint16_t passlen1 = SVAL(req->vwv+7, 0);
672 /* Never do NT status codes with protocols before NT1 as we
673 * don't get client caps. */
674 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
676 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
677 reply_nterror(req, nt_status_squash(
678 NT_STATUS_INVALID_PARAMETER));
679 END_PROFILE(SMBsesssetupX);
684 lm_resp = data_blob(req->buf, passlen1);
686 plaintext_password = data_blob(req->buf, passlen1+1);
687 /* Ensure null termination */
688 plaintext_password.data[passlen1] = 0;
691 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
692 req->buf + passlen1, STR_TERMINATE);
693 user = tmp ? tmp : "";
698 uint16_t passlen1 = SVAL(req->vwv+7, 0);
699 uint16_t passlen2 = SVAL(req->vwv+8, 0);
700 enum remote_arch_types ra_type = get_remote_arch();
701 const uint8_t *p = req->buf;
702 const uint8_t *save_p = req->buf;
705 if (!xconn->smb1.sessions.done_sesssetup) {
706 global_client_caps = IVAL(req->vwv+11, 0);
708 if (!(global_client_caps & CAP_STATUS32)) {
709 remove_from_common_flags2(
710 FLAGS2_32_BIT_ERROR_CODES);
713 /* client_caps is used as final determination if
714 * client is NT or Win95. This is needed to return
715 * the correct error codes in some circumstances.
718 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
719 ra_type == RA_WIN95) {
720 if(!(global_client_caps & (CAP_NT_SMBS|
722 set_remote_arch( RA_WIN95);
728 /* both Win95 and WinNT stuff up the password
729 * lengths for non-encrypting systems. Uggh.
731 if passlen1==24 its a win95 system, and its setting
732 the password length incorrectly. Luckily it still
733 works with the default code because Win95 will null
734 terminate the password anyway
736 if passlen1>0 and passlen2>0 then maybe its a NT box
737 and its setting passlen2 to some random value which
738 really stuffs things up. we need to fix that one. */
740 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
746 /* check for nasty tricks */
747 if (passlen1 > MAX_PASS_LEN
748 || passlen1 > smbreq_bufrem(req, p)) {
749 reply_nterror(req, nt_status_squash(
750 NT_STATUS_INVALID_PARAMETER));
751 END_PROFILE(SMBsesssetupX);
755 if (passlen2 > MAX_PASS_LEN
756 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
757 reply_nterror(req, nt_status_squash(
758 NT_STATUS_INVALID_PARAMETER));
759 END_PROFILE(SMBsesssetupX);
763 /* Save the lanman2 password and the NT md4 password. */
765 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
770 lm_resp = data_blob(p, passlen1);
771 nt_resp = data_blob(p+passlen1, passlen2);
774 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
776 if (unic && (passlen2 == 0) && passlen1) {
777 /* Only a ascii plaintext password was sent. */
778 (void)srvstr_pull_talloc(talloc_tos(),
784 STR_TERMINATE|STR_ASCII);
786 (void)srvstr_pull_talloc(talloc_tos(),
791 unic ? passlen2 : passlen1,
795 reply_nterror(req, nt_status_squash(
796 NT_STATUS_INVALID_PARAMETER));
797 END_PROFILE(SMBsesssetupX);
800 plaintext_password = data_blob(pass, strlen(pass)+1);
803 p += passlen1 + passlen2;
805 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
807 user = tmp ? tmp : "";
809 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
811 domain = tmp ? tmp : "";
813 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
815 native_os = tmp ? tmp : "";
817 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
819 native_lanman = tmp ? tmp : "";
821 /* not documented or decoded by Ethereal but there is one more
822 * string in the extra bytes which is the same as the
823 * PrimaryDomain when using extended security. Windows NT 4
824 * and 2003 use this string to store the native lanman string.
825 * Windows 9x does not include a string here at all so we have
826 * to check if we have any extra bytes left */
828 byte_count = SVAL(req->vwv+13, 0);
829 if ( PTR_DIFF(p, save_p) < byte_count) {
830 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
832 primary_domain = tmp ? tmp : "";
834 primary_domain = talloc_strdup(talloc_tos(), "null");
837 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
838 "PrimaryDomain=[%s]\n",
839 domain, native_os, native_lanman, primary_domain));
841 if ( ra_type == RA_WIN2K ) {
842 if ( strlen(native_lanman) == 0 )
843 ra_lanman_string( primary_domain );
845 ra_lanman_string( native_lanman );
850 if (SVAL(req->vwv+4, 0) == 0) {
851 setup_new_vc_session(req->sconn);
854 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
855 domain, user, get_remote_machine_name()));
858 if (xconn->smb1.negprot.spnego) {
860 /* This has to be here, because this is a perfectly
861 * valid behaviour for guest logons :-( */
863 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
864 "at 'normal' session setup after "
865 "negotiating spnego.\n"));
866 reply_nterror(req, nt_status_squash(
867 NT_STATUS_LOGON_FAILURE));
868 END_PROFILE(SMBsesssetupX);
871 fstrcpy(sub_user, user);
873 fstrcpy(sub_user, "");
876 sub_set_smb_name(sub_user);
878 reload_services(sconn, conn_snum_used, true);
882 nt_status = check_guest_password(sconn->remote_address, req, &session_info);
884 } else if (doencrypt) {
885 struct auth4_context *negprot_auth_context = NULL;
886 negprot_auth_context = xconn->smb1.negprot.auth_context;
887 if (!negprot_auth_context) {
888 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
889 "session setup without negprot denied!\n"));
890 reply_nterror(req, nt_status_squash(
891 NT_STATUS_LOGON_FAILURE));
892 END_PROFILE(SMBsesssetupX);
895 nt_status = make_user_info_for_reply_enc(talloc_tos(),
898 sconn->remote_address,
900 if (NT_STATUS_IS_OK(nt_status)) {
901 nt_status = auth_check_password_session_info(negprot_auth_context,
902 req, user_info, &session_info);
905 struct auth4_context *plaintext_auth_context = NULL;
907 nt_status = make_auth4_context(
908 talloc_tos(), &plaintext_auth_context);
910 if (NT_STATUS_IS_OK(nt_status)) {
913 plaintext_auth_context->get_ntlm_challenge(
914 plaintext_auth_context, chal);
916 if (!make_user_info_for_reply(talloc_tos(),
919 sconn->remote_address,
921 plaintext_password)) {
922 nt_status = NT_STATUS_NO_MEMORY;
925 if (NT_STATUS_IS_OK(nt_status)) {
926 nt_status = auth_check_password_session_info(plaintext_auth_context,
927 req, user_info, &session_info);
929 TALLOC_FREE(plaintext_auth_context);
933 TALLOC_FREE(user_info);
935 if (!NT_STATUS_IS_OK(nt_status)) {
936 data_blob_free(&nt_resp);
937 data_blob_free(&lm_resp);
938 data_blob_clear_free(&plaintext_password);
939 reply_nterror(req, nt_status_squash(nt_status));
940 END_PROFILE(SMBsesssetupX);
944 data_blob_clear_free(&plaintext_password);
946 /* it's ok - setup a reply */
947 reply_outbuf(req, 3, 0);
948 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
949 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
951 if (get_Protocol() >= PROTOCOL_NT1) {
952 push_signature(&req->outbuf);
953 /* perhaps grab OS version here?? */
956 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
957 action |= SMB_SETUP_GUEST;
960 /* register the name and uid as being validated, so further connections
961 to a uid can get through without a password, on the same VC */
963 nt_status = smbXsrv_session_create(xconn,
965 if (!NT_STATUS_IS_OK(nt_status)) {
966 data_blob_free(&nt_resp);
967 data_blob_free(&lm_resp);
968 reply_nterror(req, nt_status_squash(nt_status));
969 END_PROFILE(SMBsesssetupX);
973 if (session_info->session_key.length > 0) {
974 uint8_t session_key[16];
977 * Note: the SMB1 signing key is not truncated to 16 byte!
979 session->global->signing_key =
980 data_blob_dup_talloc(session->global,
981 session_info->session_key);
982 if (session->global->signing_key.data == NULL) {
983 data_blob_free(&nt_resp);
984 data_blob_free(&lm_resp);
985 TALLOC_FREE(session);
986 reply_nterror(req, NT_STATUS_NO_MEMORY);
987 END_PROFILE(SMBsesssetupX);
992 * The application key is truncated/padded to 16 bytes
994 ZERO_STRUCT(session_key);
995 memcpy(session_key, session->global->signing_key.data,
996 MIN(session->global->signing_key.length,
997 sizeof(session_key)));
998 session->global->application_key =
999 data_blob_talloc(session->global,
1001 sizeof(session_key));
1002 ZERO_STRUCT(session_key);
1003 if (session->global->application_key.data == NULL) {
1004 data_blob_free(&nt_resp);
1005 data_blob_free(&lm_resp);
1006 TALLOC_FREE(session);
1007 reply_nterror(req, NT_STATUS_NO_MEMORY);
1008 END_PROFILE(SMBsesssetupX);
1013 * Place the application key into the session_info
1015 data_blob_clear_free(&session_info->session_key);
1016 session_info->session_key = data_blob_dup_talloc(session_info,
1017 session->global->application_key);
1018 if (session_info->session_key.data == NULL) {
1019 data_blob_free(&nt_resp);
1020 data_blob_free(&lm_resp);
1021 TALLOC_FREE(session);
1022 reply_nterror(req, NT_STATUS_NO_MEMORY);
1023 END_PROFILE(SMBsesssetupX);
1028 session->compat = talloc_zero(session, struct user_struct);
1029 if (session->compat == NULL) {
1030 data_blob_free(&nt_resp);
1031 data_blob_free(&lm_resp);
1032 TALLOC_FREE(session);
1033 reply_nterror(req, NT_STATUS_NO_MEMORY);
1034 END_PROFILE(SMBsesssetupX);
1037 session->compat->session = session;
1038 session->compat->homes_snum = -1;
1039 session->compat->session_info = session_info;
1040 session->compat->session_keystr = NULL;
1041 session->compat->vuid = session->global->session_wire_id;
1042 DLIST_ADD(sconn->users, session->compat);
1045 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1046 is_authenticated = true;
1047 session->compat->homes_snum =
1048 register_homes_share(session_info->unix_info->unix_name);
1051 if (srv_is_signing_negotiated(xconn) &&
1053 session->global->signing_key.length > 0)
1056 * Try and turn on server signing on the first non-guest
1059 srv_set_signing(xconn,
1060 session->global->signing_key,
1061 nt_resp.data ? nt_resp : lm_resp);
1064 set_current_user_info(session_info->unix_info->sanitized_username,
1065 session_info->unix_info->unix_name,
1066 session_info->info->domain_name);
1068 session->status = NT_STATUS_OK;
1069 session->global->auth_session_info = talloc_move(session->global,
1071 session->global->auth_session_info_seqnum += 1;
1072 session->global->channels[0].auth_session_info_seqnum =
1073 session->global->auth_session_info_seqnum;
1074 session->global->auth_time = now;
1075 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1077 nt_status = smbXsrv_session_update(session);
1078 if (!NT_STATUS_IS_OK(nt_status)) {
1079 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1080 (unsigned long long)session->compat->vuid,
1081 nt_errstr(nt_status)));
1082 data_blob_free(&nt_resp);
1083 data_blob_free(&lm_resp);
1084 TALLOC_FREE(session);
1085 reply_nterror(req, nt_status_squash(nt_status));
1086 END_PROFILE(SMBsesssetupX);
1090 if (!session_claim(session)) {
1091 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1092 (unsigned long long)session->compat->vuid));
1093 data_blob_free(&nt_resp);
1094 data_blob_free(&lm_resp);
1095 TALLOC_FREE(session);
1096 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1097 END_PROFILE(SMBsesssetupX);
1101 /* current_user_info is changed on new vuid */
1102 reload_services(sconn, conn_snum_used, true);
1104 sess_vuid = session->global->session_wire_id;
1106 data_blob_free(&nt_resp);
1107 data_blob_free(&lm_resp);
1109 SSVAL(req->outbuf,smb_vwv2,action);
1110 SSVAL(req->outbuf,smb_uid,sess_vuid);
1111 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1112 req->vuid = sess_vuid;
1114 if (!xconn->smb1.sessions.done_sesssetup) {
1115 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1116 reply_force_doserror(req, ERRSRV, ERRerror);
1117 END_PROFILE(SMBsesssetupX);
1120 xconn->smb1.sessions.max_send = smb_bufsize;
1121 xconn->smb1.sessions.done_sesssetup = true;
1124 END_PROFILE(SMBsesssetupX);