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 "smbd/smbd.h"
28 #include "smbd/globals.h"
31 #include "smbprofile.h"
32 #include "../libcli/security/security.h"
33 #include "auth/gensec/gensec.h"
34 #include "lib/conn_tdb.h"
35 #include "../libcli/smb/smb_signing.h"
37 /****************************************************************************
38 Add the standard 'Samba' signature to the end of the session setup.
39 ****************************************************************************/
41 static int push_signature(uint8_t **outbuf)
49 fstr_sprintf(native_os, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION,
50 SAMBA_MINOR_NBT_ANNOUNCE_VERSION);
52 tmp = message_push_string(outbuf, native_os, STR_TERMINATE);
54 if (tmp == -1) return -1;
57 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
58 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
62 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
65 if (tmp == -1) return -1;
68 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
70 if (tmp == -1) return -1;
76 /****************************************************************************
77 Do a 'guest' logon, getting back the
78 ****************************************************************************/
80 static NTSTATUS check_guest_password(const struct tsocket_address *remote_address,
82 struct auth_session_info **session_info)
84 struct auth4_context *auth_context;
85 struct auth_usersupplied_info *user_info = NULL;
89 DEBUG(3,("Got anonymous request\n"));
91 nt_status = make_auth4_context(talloc_tos(), &auth_context);
92 if (!NT_STATUS_IS_OK(nt_status)) {
96 auth_context->get_ntlm_challenge(auth_context,
99 if (!make_user_info_guest(talloc_tos(), remote_address, &user_info)) {
100 TALLOC_FREE(auth_context);
101 return NT_STATUS_NO_MEMORY;
104 nt_status = auth_check_password_session_info(auth_context,
105 mem_ctx, user_info, session_info);
106 TALLOC_FREE(user_info);
107 TALLOC_FREE(auth_context);
111 /****************************************************************************
112 Reply to a session setup command.
113 conn POINTER CAN BE NULL HERE !
114 ****************************************************************************/
116 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
120 DATA_BLOB out_blob = data_blob_null;
123 const char *native_os;
124 const char *native_lanman;
125 const char *primary_domain;
126 uint16_t data_blob_len = SVAL(req->vwv+7, 0);
127 enum remote_arch_types ra_type = get_remote_arch();
128 uint64_t vuid = req->vuid;
129 NTSTATUS status = NT_STATUS_OK;
130 struct smbXsrv_connection *xconn = req->xconn;
131 struct smbd_server_connection *sconn = req->sconn;
133 NTTIME now = timeval_to_nttime(&req->request_time);
134 struct smbXsrv_session *session = NULL;
135 uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
136 uint32_t client_caps = IVAL(req->vwv+10, 0);
137 struct smbXsrv_session_auth0 *auth;
139 DEBUG(3,("Doing spnego session setup\n"));
141 if (!xconn->smb1.sessions.done_sesssetup) {
142 global_client_caps = client_caps;
144 if (!(global_client_caps & CAP_STATUS32)) {
145 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
151 if (data_blob_len == 0) {
152 /* an invalid request */
153 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
157 bufrem = smbreq_bufrem(req, p);
158 /* pull the spnego blob */
159 in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
162 file_save("negotiate.dat", in_blob.data, in_blob.length);
165 p = req->buf + in_blob.length;
167 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
169 native_os = tmp ? tmp : "";
171 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
173 native_lanman = tmp ? tmp : "";
175 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
177 primary_domain = tmp ? tmp : "";
179 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
180 native_os, native_lanman, primary_domain));
182 if ( ra_type == RA_WIN2K ) {
183 /* Vista sets neither the OS or lanman strings */
185 if ( !strlen(native_os) && !strlen(native_lanman) )
186 set_remote_arch(RA_VISTA);
188 /* Windows 2003 doesn't set the native lanman string,
189 but does set primary domain which is a bug I think */
191 if ( !strlen(native_lanman) ) {
192 ra_lanman_string( primary_domain );
194 ra_lanman_string( native_lanman );
196 } else if ( ra_type == RA_VISTA ) {
197 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
198 set_remote_arch(RA_OSX);
203 status = smb1srv_session_lookup(xconn,
206 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
207 reply_force_doserror(req, ERRSRV, ERRbaduid);
210 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
211 status = NT_STATUS_OK;
213 if (NT_STATUS_IS_OK(status)) {
214 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
215 status = NT_STATUS_MORE_PROCESSING_REQUIRED;
216 TALLOC_FREE(session->pending_auth);
218 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
219 reply_nterror(req, nt_status_squash(status));
224 if (session == NULL) {
225 /* create a new session */
226 status = smbXsrv_session_create(xconn,
228 if (!NT_STATUS_IS_OK(status)) {
229 reply_nterror(req, nt_status_squash(status));
234 status = smbXsrv_session_find_auth(session, xconn, now, &auth);
235 if (!NT_STATUS_IS_OK(status)) {
236 status = smbXsrv_session_create_auth(session, xconn, now,
240 if (!NT_STATUS_IS_OK(status)) {
241 reply_nterror(req, nt_status_squash(status));
246 if (auth->gensec == NULL) {
247 status = auth_generic_prepare(session, xconn->remote_address,
249 if (!NT_STATUS_IS_OK(status)) {
250 TALLOC_FREE(session);
251 reply_nterror(req, nt_status_squash(status));
255 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
256 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
258 status = gensec_start_mech_by_oid(auth->gensec,
260 if (!NT_STATUS_IS_OK(status)) {
261 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
262 TALLOC_FREE(session);;
263 reply_nterror(req, nt_status_squash(status));
269 status = gensec_update(auth->gensec,
273 if (!NT_STATUS_IS_OK(status) &&
274 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
275 TALLOC_FREE(session);
276 reply_nterror(req, nt_status_squash(status));
280 if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
281 struct auth_session_info *session_info = NULL;
283 status = gensec_session_info(auth->gensec,
286 if (!NT_STATUS_IS_OK(status)) {
287 DEBUG(1,("Failed to generate session_info "
288 "(user and group token) for session setup: %s\n",
290 data_blob_free(&out_blob);
291 TALLOC_FREE(session);
292 reply_nterror(req, nt_status_squash(status));
296 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
297 action |= SMB_SETUP_GUEST;
300 if (session_info->session_key.length > 0) {
301 struct smbXsrv_session *x = session;
304 * Note: the SMB1 signing key is not truncated to 16 byte!
306 x->global->signing_key =
307 data_blob_dup_talloc(x->global,
308 session_info->session_key);
309 if (x->global->signing_key.data == NULL) {
310 data_blob_free(&out_blob);
311 TALLOC_FREE(session);
312 reply_nterror(req, NT_STATUS_NO_MEMORY);
317 * clear the session key
318 * the first tcon will add setup the application key
320 data_blob_clear_free(&session_info->session_key);
323 session->compat = talloc_zero(session, struct user_struct);
324 if (session->compat == NULL) {
325 data_blob_free(&out_blob);
326 TALLOC_FREE(session);
327 reply_nterror(req, NT_STATUS_NO_MEMORY);
330 session->compat->session = session;
331 session->compat->homes_snum = -1;
332 session->compat->session_info = session_info;
333 session->compat->session_keystr = NULL;
334 session->compat->vuid = session->global->session_wire_id;
335 DLIST_ADD(sconn->users, session->compat);
338 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
339 session->compat->homes_snum =
340 register_homes_share(session_info->unix_info->unix_name);
343 if (srv_is_signing_negotiated(xconn) &&
345 session->global->signing_key.length > 0)
348 * Try and turn on server signing on the first non-guest
351 srv_set_signing(xconn,
352 session->global->signing_key,
356 set_current_user_info(session_info->unix_info->sanitized_username,
357 session_info->unix_info->unix_name,
358 session_info->info->domain_name);
360 session->status = NT_STATUS_OK;
361 session->global->auth_session_info = talloc_move(session->global,
363 session->global->auth_session_info_seqnum += 1;
364 session->global->channels[0].auth_session_info_seqnum =
365 session->global->auth_session_info_seqnum;
366 session->global->auth_time = now;
367 if (client_caps & CAP_DYNAMIC_REAUTH) {
368 session->global->expiration_time =
369 gensec_expire_time(auth->gensec);
371 session->global->expiration_time =
372 GENSEC_EXPIRE_TIME_INFINITY;
375 if (!session_claim(session)) {
376 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
377 (unsigned long long)session->compat->vuid));
378 data_blob_free(&out_blob);
379 TALLOC_FREE(session);
380 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
384 status = smbXsrv_session_update(session);
385 if (!NT_STATUS_IS_OK(status)) {
386 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
387 (unsigned long long)session->compat->vuid,
389 data_blob_free(&out_blob);
390 TALLOC_FREE(session);
391 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
395 if (!xconn->smb1.sessions.done_sesssetup) {
396 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
397 reply_force_doserror(req, ERRSRV, ERRerror);
400 xconn->smb1.sessions.max_send = smb_bufsize;
401 xconn->smb1.sessions.done_sesssetup = true;
404 /* current_user_info is changed on new vuid */
405 reload_services(sconn, conn_snum_used, true);
406 } else if (NT_STATUS_IS_OK(status)) {
407 struct auth_session_info *session_info = NULL;
409 status = gensec_session_info(auth->gensec,
412 if (!NT_STATUS_IS_OK(status)) {
413 DEBUG(1,("Failed to generate session_info "
414 "(user and group token) for session setup: %s\n",
416 data_blob_free(&out_blob);
417 TALLOC_FREE(session);
418 reply_nterror(req, nt_status_squash(status));
422 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
423 action |= SMB_SETUP_GUEST;
427 * Keep the application key
429 data_blob_clear_free(&session_info->session_key);
430 session_info->session_key =
431 session->global->auth_session_info->session_key;
432 talloc_steal(session_info, session_info->session_key.data);
433 TALLOC_FREE(session->global->auth_session_info);
435 session->compat->session_info = session_info;
437 session->compat->vuid = session->global->session_wire_id;
439 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
440 session->compat->homes_snum =
441 register_homes_share(session_info->unix_info->unix_name);
444 set_current_user_info(session_info->unix_info->sanitized_username,
445 session_info->unix_info->unix_name,
446 session_info->info->domain_name);
448 session->status = NT_STATUS_OK;
449 session->global->auth_session_info = talloc_move(session->global,
451 session->global->auth_session_info_seqnum += 1;
452 session->global->channels[0].auth_session_info_seqnum =
453 session->global->auth_session_info_seqnum;
454 session->global->auth_time = now;
455 if (client_caps & CAP_DYNAMIC_REAUTH) {
456 session->global->expiration_time =
457 gensec_expire_time(auth->gensec);
459 session->global->expiration_time =
460 GENSEC_EXPIRE_TIME_INFINITY;
463 status = smbXsrv_session_update(session);
464 if (!NT_STATUS_IS_OK(status)) {
465 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
466 (unsigned long long)session->compat->vuid,
468 data_blob_free(&out_blob);
469 TALLOC_FREE(session);
470 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
474 conn_clear_vuid_caches(sconn, session->compat->vuid);
476 /* current_user_info is changed on new vuid */
477 reload_services(sconn, conn_snum_used, true);
480 vuid = session->global->session_wire_id;
482 reply_outbuf(req, 4, 0);
484 SSVAL(req->outbuf, smb_uid, vuid);
485 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
486 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
487 SSVAL(req->outbuf, smb_vwv2, action);
488 SSVAL(req->outbuf, smb_vwv3, out_blob.length);
490 if (message_push_blob(&req->outbuf, out_blob) == -1) {
491 data_blob_free(&out_blob);
492 TALLOC_FREE(session);
493 reply_nterror(req, NT_STATUS_NO_MEMORY);
496 data_blob_free(&out_blob);
498 if (push_signature(&req->outbuf) == -1) {
499 TALLOC_FREE(session);
500 reply_nterror(req, NT_STATUS_NO_MEMORY);
505 /****************************************************************************
506 On new VC == 0, shutdown *all* old connections and users.
507 It seems that only NT4.x does this. At W2K and above (XP etc.).
508 a new session setup with VC==0 is ignored.
509 ****************************************************************************/
511 struct shutdown_state {
513 struct messaging_context *msg_ctx;
516 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
519 struct shutdown_state *state = (struct shutdown_state *)private_data;
520 struct server_id self_pid = messaging_server_id(state->msg_ctx);
521 struct server_id pid = session->channels[0].server_id;
522 const char *addr = session->channels[0].remote_address;
523 struct server_id_buf tmp;
525 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
526 server_id_str_buf(pid, &tmp), addr));
528 if (!process_exists(pid)) {
529 DEBUG(10, ("process does not exist\n"));
533 if (serverid_equal(&pid, &self_pid)) {
534 DEBUG(10, ("It's me\n"));
539 * here we use strstr() because 'addr'
540 * (session->channels[0].remote_address)
541 * contains a string like:
542 * 'ipv4:127.0.0.1:48163'
544 if (strstr(addr, state->ip) == NULL) {
545 DEBUG(10, ("%s does not match %s\n", state->ip, addr));
549 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
550 "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
553 messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
558 static void setup_new_vc_session(struct smbd_server_connection *sconn)
560 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
561 "compatible we would close all old resources.\n"));
564 invalidate_all_vuids();
566 if (lp_reset_on_zero_vc()) {
568 struct shutdown_state state;
570 addr = tsocket_address_inet_addr_string(
571 sconn->remote_address, talloc_tos());
576 state.msg_ctx = sconn->msg_ctx;
577 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
582 /****************************************************************************
583 Reply to a session setup command.
584 ****************************************************************************/
586 void reply_sesssetup_and_X(struct smb_request *req)
589 uint16_t smb_bufsize;
592 DATA_BLOB plaintext_password;
595 fstring sub_user; /* Sanitised username for substituion */
597 const char *native_os;
598 const char *native_lanman;
599 const char *primary_domain;
600 struct auth_usersupplied_info *user_info = NULL;
601 struct auth_session_info *session_info = NULL;
602 uint16_t smb_flag2 = req->flags2;
604 NTTIME now = timeval_to_nttime(&req->request_time);
605 struct smbXsrv_session *session = NULL;
607 struct smbXsrv_connection *xconn = req->xconn;
608 struct smbd_server_connection *sconn = req->sconn;
609 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
610 bool signing_allowed = false;
611 bool signing_mandatory = smb_signing_is_mandatory(
612 xconn->smb1.signing_state);
614 START_PROFILE(SMBsesssetupX);
616 ZERO_STRUCT(lm_resp);
617 ZERO_STRUCT(nt_resp);
618 ZERO_STRUCT(plaintext_password);
620 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
622 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
623 signing_allowed = true;
625 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
626 signing_mandatory = true;
630 * We can call srv_set_signing_negotiated() each time.
631 * It finds out when it needs to turn into a noop
634 srv_set_signing_negotiated(xconn,
638 /* a SPNEGO session setup has 12 command words, whereas a normal
639 NT1 session setup has 13. See the cifs spec. */
640 if (req->wct == 12 &&
641 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
643 if (!xconn->smb1.negprot.spnego) {
644 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
645 "at SPNEGO session setup when it was not "
647 reply_nterror(req, nt_status_squash(
648 NT_STATUS_LOGON_FAILURE));
649 END_PROFILE(SMBsesssetupX);
653 if (SVAL(req->vwv+4, 0) == 0) {
654 setup_new_vc_session(req->sconn);
657 reply_sesssetup_and_X_spnego(req);
658 END_PROFILE(SMBsesssetupX);
662 smb_bufsize = SVAL(req->vwv+2, 0);
664 if (get_Protocol() < PROTOCOL_NT1) {
665 uint16_t passlen1 = SVAL(req->vwv+7, 0);
667 /* Never do NT status codes with protocols before NT1 as we
668 * don't get client caps. */
669 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
671 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
672 reply_nterror(req, nt_status_squash(
673 NT_STATUS_INVALID_PARAMETER));
674 END_PROFILE(SMBsesssetupX);
679 lm_resp = data_blob(req->buf, passlen1);
681 plaintext_password = data_blob(req->buf, passlen1+1);
682 /* Ensure null termination */
683 plaintext_password.data[passlen1] = 0;
686 srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
687 req->buf + passlen1, STR_TERMINATE);
688 user = tmp ? tmp : "";
693 uint16_t passlen1 = SVAL(req->vwv+7, 0);
694 uint16_t passlen2 = SVAL(req->vwv+8, 0);
695 enum remote_arch_types ra_type = get_remote_arch();
696 const uint8_t *p = req->buf;
697 const uint8_t *save_p = req->buf;
700 if (!xconn->smb1.sessions.done_sesssetup) {
701 global_client_caps = IVAL(req->vwv+11, 0);
703 if (!(global_client_caps & CAP_STATUS32)) {
704 remove_from_common_flags2(
705 FLAGS2_32_BIT_ERROR_CODES);
708 /* client_caps is used as final determination if
709 * client is NT or Win95. This is needed to return
710 * the correct error codes in some circumstances.
713 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
714 ra_type == RA_WIN95) {
715 if(!(global_client_caps & (CAP_NT_SMBS|
717 set_remote_arch( RA_WIN95);
723 /* both Win95 and WinNT stuff up the password
724 * lengths for non-encrypting systems. Uggh.
726 if passlen1==24 its a win95 system, and its setting
727 the password length incorrectly. Luckily it still
728 works with the default code because Win95 will null
729 terminate the password anyway
731 if passlen1>0 and passlen2>0 then maybe its a NT box
732 and its setting passlen2 to some random value which
733 really stuffs things up. we need to fix that one. */
735 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
741 /* check for nasty tricks */
742 if (passlen1 > MAX_PASS_LEN
743 || passlen1 > smbreq_bufrem(req, p)) {
744 reply_nterror(req, nt_status_squash(
745 NT_STATUS_INVALID_PARAMETER));
746 END_PROFILE(SMBsesssetupX);
750 if (passlen2 > MAX_PASS_LEN
751 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
752 reply_nterror(req, nt_status_squash(
753 NT_STATUS_INVALID_PARAMETER));
754 END_PROFILE(SMBsesssetupX);
758 /* Save the lanman2 password and the NT md4 password. */
760 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
765 lm_resp = data_blob(p, passlen1);
766 nt_resp = data_blob(p+passlen1, passlen2);
769 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
771 if (unic && (passlen2 == 0) && passlen1) {
772 /* Only a ascii plaintext password was sent. */
773 (void)srvstr_pull_talloc(talloc_tos(),
779 STR_TERMINATE|STR_ASCII);
781 (void)srvstr_pull_talloc(talloc_tos(),
786 unic ? passlen2 : passlen1,
790 reply_nterror(req, nt_status_squash(
791 NT_STATUS_INVALID_PARAMETER));
792 END_PROFILE(SMBsesssetupX);
795 plaintext_password = data_blob(pass, strlen(pass)+1);
798 p += passlen1 + passlen2;
800 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
802 user = tmp ? tmp : "";
804 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
806 domain = tmp ? tmp : "";
808 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
810 native_os = tmp ? tmp : "";
812 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
814 native_lanman = tmp ? tmp : "";
816 /* not documented or decoded by Ethereal but there is one more
817 * string in the extra bytes which is the same as the
818 * PrimaryDomain when using extended security. Windows NT 4
819 * and 2003 use this string to store the native lanman string.
820 * Windows 9x does not include a string here at all so we have
821 * to check if we have any extra bytes left */
823 byte_count = SVAL(req->vwv+13, 0);
824 if ( PTR_DIFF(p, save_p) < byte_count) {
825 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
827 primary_domain = tmp ? tmp : "";
829 primary_domain = talloc_strdup(talloc_tos(), "null");
832 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
833 "PrimaryDomain=[%s]\n",
834 domain, native_os, native_lanman, primary_domain));
836 if ( ra_type == RA_WIN2K ) {
837 if ( strlen(native_lanman) == 0 )
838 ra_lanman_string( primary_domain );
840 ra_lanman_string( native_lanman );
845 if (SVAL(req->vwv+4, 0) == 0) {
846 setup_new_vc_session(req->sconn);
849 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
850 domain, user, get_remote_machine_name()));
853 if (xconn->smb1.negprot.spnego) {
855 /* This has to be here, because this is a perfectly
856 * valid behaviour for guest logons :-( */
858 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
859 "at 'normal' session setup after "
860 "negotiating spnego.\n"));
861 reply_nterror(req, nt_status_squash(
862 NT_STATUS_LOGON_FAILURE));
863 END_PROFILE(SMBsesssetupX);
866 fstrcpy(sub_user, user);
868 fstrcpy(sub_user, "");
871 sub_set_smb_name(sub_user);
873 reload_services(sconn, conn_snum_used, true);
877 nt_status = check_guest_password(sconn->remote_address, req, &session_info);
879 } else if (doencrypt) {
880 struct auth4_context *negprot_auth_context = NULL;
881 negprot_auth_context = xconn->smb1.negprot.auth_context;
882 if (!negprot_auth_context) {
883 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
884 "session setup without negprot denied!\n"));
885 reply_nterror(req, nt_status_squash(
886 NT_STATUS_LOGON_FAILURE));
887 END_PROFILE(SMBsesssetupX);
890 nt_status = make_user_info_for_reply_enc(talloc_tos(),
893 sconn->remote_address,
895 if (NT_STATUS_IS_OK(nt_status)) {
896 nt_status = auth_check_password_session_info(negprot_auth_context,
897 req, user_info, &session_info);
900 struct auth4_context *plaintext_auth_context = NULL;
902 nt_status = make_auth4_context(
903 talloc_tos(), &plaintext_auth_context);
905 if (NT_STATUS_IS_OK(nt_status)) {
908 plaintext_auth_context->get_ntlm_challenge(
909 plaintext_auth_context, chal);
911 if (!make_user_info_for_reply(talloc_tos(),
914 sconn->remote_address,
916 plaintext_password)) {
917 nt_status = NT_STATUS_NO_MEMORY;
920 if (NT_STATUS_IS_OK(nt_status)) {
921 nt_status = auth_check_password_session_info(plaintext_auth_context,
922 req, user_info, &session_info);
924 TALLOC_FREE(plaintext_auth_context);
928 TALLOC_FREE(user_info);
930 if (!NT_STATUS_IS_OK(nt_status)) {
931 data_blob_free(&nt_resp);
932 data_blob_free(&lm_resp);
933 data_blob_clear_free(&plaintext_password);
934 reply_nterror(req, nt_status_squash(nt_status));
935 END_PROFILE(SMBsesssetupX);
939 data_blob_clear_free(&plaintext_password);
941 /* it's ok - setup a reply */
942 reply_outbuf(req, 3, 0);
943 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
944 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
946 if (get_Protocol() >= PROTOCOL_NT1) {
947 push_signature(&req->outbuf);
948 /* perhaps grab OS version here?? */
951 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
952 action |= SMB_SETUP_GUEST;
955 /* register the name and uid as being validated, so further connections
956 to a uid can get through without a password, on the same VC */
958 nt_status = smbXsrv_session_create(xconn,
960 if (!NT_STATUS_IS_OK(nt_status)) {
961 data_blob_free(&nt_resp);
962 data_blob_free(&lm_resp);
963 reply_nterror(req, nt_status_squash(nt_status));
964 END_PROFILE(SMBsesssetupX);
968 if (session_info->session_key.length > 0) {
969 uint8_t session_key[16];
972 * Note: the SMB1 signing key is not truncated to 16 byte!
974 session->global->signing_key =
975 data_blob_dup_talloc(session->global,
976 session_info->session_key);
977 if (session->global->signing_key.data == NULL) {
978 data_blob_free(&nt_resp);
979 data_blob_free(&lm_resp);
980 TALLOC_FREE(session);
981 reply_nterror(req, NT_STATUS_NO_MEMORY);
982 END_PROFILE(SMBsesssetupX);
987 * The application key is truncated/padded to 16 bytes
989 ZERO_STRUCT(session_key);
990 memcpy(session_key, session->global->signing_key.data,
991 MIN(session->global->signing_key.length,
992 sizeof(session_key)));
993 session->global->application_key =
994 data_blob_talloc(session->global,
996 sizeof(session_key));
997 ZERO_STRUCT(session_key);
998 if (session->global->application_key.data == NULL) {
999 data_blob_free(&nt_resp);
1000 data_blob_free(&lm_resp);
1001 TALLOC_FREE(session);
1002 reply_nterror(req, NT_STATUS_NO_MEMORY);
1003 END_PROFILE(SMBsesssetupX);
1008 * Place the application key into the session_info
1010 data_blob_clear_free(&session_info->session_key);
1011 session_info->session_key = data_blob_dup_talloc(session_info,
1012 session->global->application_key);
1013 if (session_info->session_key.data == NULL) {
1014 data_blob_free(&nt_resp);
1015 data_blob_free(&lm_resp);
1016 TALLOC_FREE(session);
1017 reply_nterror(req, NT_STATUS_NO_MEMORY);
1018 END_PROFILE(SMBsesssetupX);
1023 session->compat = talloc_zero(session, struct user_struct);
1024 if (session->compat == NULL) {
1025 data_blob_free(&nt_resp);
1026 data_blob_free(&lm_resp);
1027 TALLOC_FREE(session);
1028 reply_nterror(req, NT_STATUS_NO_MEMORY);
1029 END_PROFILE(SMBsesssetupX);
1032 session->compat->session = session;
1033 session->compat->homes_snum = -1;
1034 session->compat->session_info = session_info;
1035 session->compat->session_keystr = NULL;
1036 session->compat->vuid = session->global->session_wire_id;
1037 DLIST_ADD(sconn->users, session->compat);
1040 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1041 session->compat->homes_snum =
1042 register_homes_share(session_info->unix_info->unix_name);
1045 if (srv_is_signing_negotiated(xconn) &&
1047 session->global->signing_key.length > 0)
1050 * Try and turn on server signing on the first non-guest
1053 srv_set_signing(xconn,
1054 session->global->signing_key,
1055 nt_resp.data ? nt_resp : lm_resp);
1058 set_current_user_info(session_info->unix_info->sanitized_username,
1059 session_info->unix_info->unix_name,
1060 session_info->info->domain_name);
1062 session->status = NT_STATUS_OK;
1063 session->global->auth_session_info = talloc_move(session->global,
1065 session->global->auth_session_info_seqnum += 1;
1066 session->global->channels[0].auth_session_info_seqnum =
1067 session->global->auth_session_info_seqnum;
1068 session->global->auth_time = now;
1069 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1071 nt_status = smbXsrv_session_update(session);
1072 if (!NT_STATUS_IS_OK(nt_status)) {
1073 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1074 (unsigned long long)session->compat->vuid,
1075 nt_errstr(nt_status)));
1076 data_blob_free(&nt_resp);
1077 data_blob_free(&lm_resp);
1078 TALLOC_FREE(session);
1079 reply_nterror(req, nt_status_squash(nt_status));
1080 END_PROFILE(SMBsesssetupX);
1084 if (!session_claim(session)) {
1085 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1086 (unsigned long long)session->compat->vuid));
1087 data_blob_free(&nt_resp);
1088 data_blob_free(&lm_resp);
1089 TALLOC_FREE(session);
1090 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1091 END_PROFILE(SMBsesssetupX);
1095 /* current_user_info is changed on new vuid */
1096 reload_services(sconn, conn_snum_used, true);
1098 sess_vuid = session->global->session_wire_id;
1100 data_blob_free(&nt_resp);
1101 data_blob_free(&lm_resp);
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;
1118 END_PROFILE(SMBsesssetupX);