vfs_gpfs: Move call to load GPFS library
[Samba.git] / source3 / smbd / smb1_sesssetup.c
blobfe4519aef20b3984e330e176787b3cbe177baa9b
1 /*
2 Unix SMB/CIFS implementation.
3 handle SMBsessionsetup
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/>.
25 #include "includes.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "lib/util/server_id.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "auth.h"
31 #include "messages.h"
32 #include "smbprofile.h"
33 #include "../libcli/security/security.h"
34 #include "auth/gensec/gensec.h"
35 #include "../libcli/smb/smb_signing.h"
36 #include "lib/util/string_wrappers.h"
37 #include "source3/lib/substitute.h"
39 /****************************************************************************
40 Add the standard 'Samba' signature to the end of the session setup.
41 ****************************************************************************/
43 static int push_signature(uint8_t **outbuf)
45 char *lanman;
46 int result, tmp;
47 fstring native_os;
49 result = 0;
51 fstr_sprintf(native_os, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION,
52 SAMBA_MINOR_NBT_ANNOUNCE_VERSION);
54 tmp = message_push_string(outbuf, native_os, STR_TERMINATE);
56 if (tmp == -1) return -1;
57 result += tmp;
59 if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
60 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
61 SAFE_FREE(lanman);
63 else {
64 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
67 if (tmp == -1) return -1;
68 result += tmp;
70 tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
72 if (tmp == -1) return -1;
73 result += tmp;
75 return result;
78 /****************************************************************************
79 Reply to a session setup command.
80 conn POINTER CAN BE NULL HERE !
81 ****************************************************************************/
83 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
85 const uint8_t *p;
86 DATA_BLOB in_blob;
87 DATA_BLOB out_blob = data_blob_null;
88 size_t bufrem;
89 char *tmp;
90 const char *native_os;
91 const char *native_lanman;
92 const char *primary_domain;
93 uint16_t data_blob_len = SVAL(req->vwv+7, 0);
94 enum remote_arch_types ra_type = get_remote_arch();
95 uint64_t vuid = req->vuid;
96 NTSTATUS status = NT_STATUS_OK;
97 struct smbXsrv_connection *xconn = req->xconn;
98 struct smbd_server_connection *sconn = req->sconn;
99 uint16_t action = 0;
100 bool is_authenticated = false;
101 NTTIME now = timeval_to_nttime(&req->request_time);
102 struct smbXsrv_session *session = NULL;
103 uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
104 uint32_t client_caps = IVAL(req->vwv+10, 0);
105 struct smbXsrv_session_auth0 *auth;
107 DEBUG(3,("Doing spnego session setup\n"));
109 if (!xconn->smb1.sessions.done_sesssetup) {
110 global_client_caps = client_caps;
112 if (!(global_client_caps & CAP_STATUS32)) {
113 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
117 p = req->buf;
119 if (data_blob_len == 0) {
120 /* an invalid request */
121 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
122 return;
125 bufrem = smbreq_bufrem(req, p);
126 /* pull the spnego blob */
127 in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
129 #if 0
130 file_save("negotiate.dat", in_blob.data, in_blob.length);
131 #endif
133 p = req->buf + in_blob.length;
135 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
136 STR_TERMINATE);
137 native_os = tmp ? tmp : "";
139 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
140 STR_TERMINATE);
141 native_lanman = tmp ? tmp : "";
143 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
144 STR_TERMINATE);
145 primary_domain = tmp ? tmp : "";
147 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
148 native_os, native_lanman, primary_domain));
150 if ( ra_type == RA_WIN2K ) {
151 /* Vista sets neither the OS or lanman strings */
153 if ( !strlen(native_os) && !strlen(native_lanman) )
154 set_remote_arch(RA_VISTA);
156 /* Windows 2003 doesn't set the native lanman string,
157 but does set primary domain which is a bug I think */
159 if ( !strlen(native_lanman) ) {
160 ra_lanman_string( primary_domain );
161 } else {
162 ra_lanman_string( native_lanman );
164 } else if ( ra_type == RA_VISTA ) {
165 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
166 set_remote_arch(RA_OSX);
170 if (vuid != 0) {
171 status = smb1srv_session_lookup(xconn,
172 vuid, now,
173 &session);
174 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
175 reply_force_doserror(req, ERRSRV, ERRbaduid);
176 return;
178 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
179 status = NT_STATUS_OK;
181 if (NT_STATUS_IS_OK(status)) {
182 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
183 status = NT_STATUS_MORE_PROCESSING_REQUIRED;
184 TALLOC_FREE(session->pending_auth);
186 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
187 reply_nterror(req, nt_status_squash(status));
188 return;
192 if (session == NULL) {
193 /* create a new session */
194 status = smbXsrv_session_create(xconn,
195 now, &session);
196 if (!NT_STATUS_IS_OK(status)) {
197 reply_nterror(req, nt_status_squash(status));
198 return;
202 status = smbXsrv_session_find_auth(session, xconn, now, &auth);
203 if (!NT_STATUS_IS_OK(status)) {
204 status = smbXsrv_session_create_auth(session, xconn, now,
205 0, /* flags */
206 0, /* security */
207 &auth);
208 if (!NT_STATUS_IS_OK(status)) {
209 reply_nterror(req, nt_status_squash(status));
210 return;
214 if (auth->gensec == NULL) {
215 status = auth_generic_prepare(session,
216 xconn->remote_address,
217 xconn->local_address,
218 "SMB",
219 &auth->gensec);
220 if (!NT_STATUS_IS_OK(status)) {
221 TALLOC_FREE(session);
222 reply_nterror(req, nt_status_squash(status));
223 return;
226 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
227 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
228 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
230 status = gensec_start_mech_by_oid(auth->gensec,
231 GENSEC_OID_SPNEGO);
232 if (!NT_STATUS_IS_OK(status)) {
233 DEBUG(0, ("Failed to start SPNEGO handler!\n"));
234 TALLOC_FREE(session);;
235 reply_nterror(req, nt_status_squash(status));
236 return;
240 become_root();
241 status = gensec_update(auth->gensec,
242 talloc_tos(),
243 in_blob, &out_blob);
244 unbecome_root();
245 if (!NT_STATUS_IS_OK(status) &&
246 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
247 TALLOC_FREE(session);
248 reply_nterror(req, nt_status_squash(status));
249 return;
252 if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
253 struct auth_session_info *session_info = NULL;
255 status = gensec_session_info(auth->gensec,
256 session,
257 &session_info);
258 if (!NT_STATUS_IS_OK(status)) {
259 DEBUG(1,("Failed to generate session_info "
260 "(user and group token) for session setup: %s\n",
261 nt_errstr(status)));
262 data_blob_free(&out_blob);
263 TALLOC_FREE(session);
264 reply_nterror(req, nt_status_squash(status));
265 return;
268 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
269 action |= SMB_SETUP_GUEST;
272 session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
273 session->global->encryption_cipher = 0;
274 session->global->channels[0].signing_algo =
275 session->global->signing_algo;
276 session->global->channels[0].encryption_cipher =
277 session->global->encryption_cipher;
279 if (session_info->session_key.length > 0) {
280 struct smbXsrv_session *x = session;
282 status = smb2_signing_key_sign_create(x->global,
283 x->global->signing_algo,
284 &session_info->session_key,
285 NULL, /* no derivation */
286 &x->global->signing_key);
287 if (!NT_STATUS_IS_OK(status)) {
288 data_blob_free(&out_blob);
289 TALLOC_FREE(session);
290 reply_nterror(req, status);
291 return;
293 x->global->signing_key_blob = x->global->signing_key->blob;
296 * clear the session key
297 * the first tcon will add setup the application key
299 data_blob_clear_free(&session_info->session_key);
302 sconn->num_users++;
304 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
305 is_authenticated = true;
306 session->homes_snum =
307 register_homes_share(session_info->unix_info->unix_name);
310 if (smb1_srv_is_signing_negotiated(xconn) &&
311 is_authenticated &&
312 smb2_signing_key_valid(session->global->signing_key))
315 * Try and turn on server signing on the first non-guest
316 * sessionsetup.
318 smb1_srv_set_signing(xconn,
319 session->global->signing_key->blob,
320 data_blob_null);
323 set_current_user_info(session_info->unix_info->sanitized_username,
324 session_info->unix_info->unix_name,
325 session_info->info->domain_name);
327 session->status = NT_STATUS_OK;
328 session->global->auth_session_info = talloc_move(session->global,
329 &session_info);
330 session->global->auth_session_info_seqnum += 1;
331 session->global->channels[0].auth_session_info_seqnum =
332 session->global->auth_session_info_seqnum;
333 session->global->auth_time = now;
334 if (client_caps & CAP_DYNAMIC_REAUTH) {
335 session->global->expiration_time =
336 gensec_expire_time(auth->gensec);
337 } else {
338 session->global->expiration_time =
339 GENSEC_EXPIRE_TIME_INFINITY;
342 if (!session_claim(session)) {
343 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
344 (unsigned long long)session->global->session_wire_id));
345 data_blob_free(&out_blob);
346 TALLOC_FREE(session);
347 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
348 return;
351 status = smbXsrv_session_update(session);
352 if (!NT_STATUS_IS_OK(status)) {
353 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
354 (unsigned long long)session->global->session_wire_id,
355 nt_errstr(status)));
356 data_blob_free(&out_blob);
357 TALLOC_FREE(session);
358 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
359 return;
362 if (!xconn->smb1.sessions.done_sesssetup) {
363 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
364 reply_force_doserror(req, ERRSRV, ERRerror);
365 return;
367 xconn->smb1.sessions.max_send = smb_bufsize;
368 xconn->smb1.sessions.done_sesssetup = true;
371 /* current_user_info is changed on new vuid */
372 reload_services(sconn, conn_snum_used, true);
373 } else if (NT_STATUS_IS_OK(status)) {
374 struct auth_session_info *session_info = NULL;
376 status = gensec_session_info(auth->gensec,
377 session,
378 &session_info);
379 if (!NT_STATUS_IS_OK(status)) {
380 DEBUG(1,("Failed to generate session_info "
381 "(user and group token) for session setup: %s\n",
382 nt_errstr(status)));
383 data_blob_free(&out_blob);
384 TALLOC_FREE(session);
385 reply_nterror(req, nt_status_squash(status));
386 return;
389 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
390 action |= SMB_SETUP_GUEST;
394 * Keep the application key
396 data_blob_clear_free(&session_info->session_key);
397 session_info->session_key =
398 session->global->auth_session_info->session_key;
399 talloc_steal(session_info, session_info->session_key.data);
400 TALLOC_FREE(session->global->auth_session_info);
402 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
403 session->homes_snum =
404 register_homes_share(session_info->unix_info->unix_name);
407 set_current_user_info(session_info->unix_info->sanitized_username,
408 session_info->unix_info->unix_name,
409 session_info->info->domain_name);
411 session->status = NT_STATUS_OK;
412 session->global->auth_session_info = talloc_move(session->global,
413 &session_info);
414 session->global->auth_session_info_seqnum += 1;
415 session->global->channels[0].auth_session_info_seqnum =
416 session->global->auth_session_info_seqnum;
417 session->global->auth_time = now;
418 if (client_caps & CAP_DYNAMIC_REAUTH) {
419 session->global->expiration_time =
420 gensec_expire_time(auth->gensec);
421 } else {
422 session->global->expiration_time =
423 GENSEC_EXPIRE_TIME_INFINITY;
426 status = smbXsrv_session_update(session);
427 if (!NT_STATUS_IS_OK(status)) {
428 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
429 (unsigned long long)session->global->session_wire_id,
430 nt_errstr(status)));
431 data_blob_free(&out_blob);
432 TALLOC_FREE(session);
433 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
434 return;
437 conn_clear_vuid_caches(sconn, session->global->session_wire_id);
439 /* current_user_info is changed on new vuid */
440 reload_services(sconn, conn_snum_used, true);
443 vuid = session->global->session_wire_id;
445 reply_smb1_outbuf(req, 4, 0);
447 SSVAL(req->outbuf, smb_uid, vuid);
448 SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
449 SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
450 SSVAL(req->outbuf, smb_vwv2, action);
451 SSVAL(req->outbuf, smb_vwv3, out_blob.length);
453 if (message_push_blob(&req->outbuf, out_blob) == -1) {
454 data_blob_free(&out_blob);
455 TALLOC_FREE(session);
456 reply_nterror(req, NT_STATUS_NO_MEMORY);
457 return;
459 data_blob_free(&out_blob);
461 if (push_signature(&req->outbuf) == -1) {
462 TALLOC_FREE(session);
463 reply_nterror(req, NT_STATUS_NO_MEMORY);
464 return;
468 /****************************************************************************
469 On new VC == 0, shutdown *all* old connections and users.
470 It seems that only NT4.x does this. At W2K and above (XP etc.).
471 a new session setup with VC==0 is ignored.
472 ****************************************************************************/
474 struct shutdown_state {
475 const char *ip;
476 size_t ip_length;
477 struct messaging_context *msg_ctx;
480 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
481 void *private_data)
483 struct shutdown_state *state = (struct shutdown_state *)private_data;
484 struct server_id self_pid = messaging_server_id(state->msg_ctx);
485 struct server_id pid = session->channels[0].server_id;
486 const char *addr = session->channels[0].remote_address;
487 const char *port_colon;
488 size_t addr_len;
489 struct server_id_buf tmp;
491 DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
492 server_id_str_buf(pid, &tmp), addr));
494 if (!process_exists(pid)) {
495 DEBUG(10, ("process does not exist\n"));
496 return 0;
499 if (server_id_equal(&pid, &self_pid)) {
500 DEBUG(10, ("It's me\n"));
501 return 0;
504 port_colon = strrchr(addr, ':');
505 if (port_colon == NULL) {
506 DBG_DEBUG("addr %s in contains no port\n", addr);
507 return 0;
509 addr_len = port_colon - addr;
511 if ((addr_len != state->ip_length) ||
512 (strncmp(addr, state->ip, state->ip_length) != 0)) {
513 DEBUG(10, ("%s (%zu) does not match %s (%zu)\n",
514 state->ip, state->ip_length, addr, addr_len));
515 return 0;
518 DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
519 "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
520 state->ip));
522 messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
523 &data_blob_null);
524 return 0;
527 static void setup_new_vc_session(struct smbd_server_connection *sconn)
529 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
530 "compatible we would close all old resources.\n"));
532 if (lp_reset_on_zero_vc()) {
533 char *addr;
534 const char *port_colon;
535 struct shutdown_state state;
537 addr = tsocket_address_string(
538 sconn->remote_address, talloc_tos());
539 if (addr == NULL) {
540 return;
542 state.ip = addr;
544 port_colon = strrchr(addr, ':');
545 if (port_colon == NULL) {
546 return;
548 state.ip_length = port_colon - addr;
549 state.msg_ctx = sconn->msg_ctx;
550 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
551 TALLOC_FREE(addr);
555 /****************************************************************************
556 Reply to a session setup command.
557 ****************************************************************************/
559 struct reply_sesssetup_and_X_state {
560 struct smb_request *req;
561 struct auth4_context *auth_context;
562 struct auth_usersupplied_info *user_info;
563 const char *user;
564 const char *domain;
565 DATA_BLOB lm_resp;
566 DATA_BLOB nt_resp;
567 DATA_BLOB plaintext_password;
570 static int reply_sesssetup_and_X_state_destructor(
571 struct reply_sesssetup_and_X_state *state)
573 data_blob_clear_free(&state->nt_resp);
574 data_blob_clear_free(&state->lm_resp);
575 data_blob_clear_free(&state->plaintext_password);
576 return 0;
579 void reply_sesssetup_and_X(struct smb_request *req)
581 struct reply_sesssetup_and_X_state *state = NULL;
582 uint64_t sess_vuid;
583 uint16_t smb_bufsize;
584 char *tmp;
585 fstring sub_user; /* Sanitised username for substitution */
586 const char *native_os;
587 const char *native_lanman;
588 const char *primary_domain;
589 struct auth_session_info *session_info = NULL;
590 uint16_t smb_flag2 = req->flags2;
591 uint16_t action = 0;
592 bool is_authenticated = false;
593 NTTIME now = timeval_to_nttime(&req->request_time);
594 struct smbXsrv_session *session = NULL;
595 NTSTATUS nt_status;
596 struct smbXsrv_connection *xconn = req->xconn;
597 struct smbd_server_connection *sconn = req->sconn;
598 bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
599 bool signing_allowed = false;
600 bool signing_mandatory = smb1_signing_is_mandatory(
601 xconn->smb1.signing_state);
603 START_PROFILE(SMBsesssetupX);
605 DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
607 state = talloc_zero(req, struct reply_sesssetup_and_X_state);
608 if (state == NULL) {
609 reply_nterror(req, NT_STATUS_NO_MEMORY);
610 END_PROFILE(SMBsesssetupX);
611 return;
613 state->req = req;
614 talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
616 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
617 signing_allowed = true;
619 if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
620 signing_mandatory = true;
624 * We can call smb1_srv_set_signing_negotiated() each time.
625 * It finds out when it needs to turn into a noop
626 * itself.
628 smb1_srv_set_signing_negotiated(xconn,
629 signing_allowed,
630 signing_mandatory);
632 /* a SPNEGO session setup has 12 command words, whereas a normal
633 NT1 session setup has 13. See the cifs spec. */
634 if (req->wct == 12 &&
635 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
637 if (!xconn->smb1.negprot.spnego) {
638 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
639 "at SPNEGO session setup when it was not "
640 "negotiated.\n"));
641 reply_nterror(req, nt_status_squash(
642 NT_STATUS_LOGON_FAILURE));
643 END_PROFILE(SMBsesssetupX);
644 return;
647 if (SVAL(req->vwv+4, 0) == 0) {
648 setup_new_vc_session(req->sconn);
651 reply_sesssetup_and_X_spnego(req);
652 END_PROFILE(SMBsesssetupX);
653 return;
656 smb_bufsize = SVAL(req->vwv+2, 0);
658 if (xconn->protocol < PROTOCOL_NT1) {
659 uint16_t passlen1 = SVAL(req->vwv+7, 0);
661 /* Never do NT status codes with protocols before NT1 as we
662 * don't get client caps. */
663 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
665 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
666 reply_nterror(req, nt_status_squash(
667 NT_STATUS_INVALID_PARAMETER));
668 END_PROFILE(SMBsesssetupX);
669 return;
672 if (doencrypt) {
673 state->lm_resp = data_blob_talloc(state,
674 req->buf,
675 passlen1);
676 } else {
677 state->plaintext_password = data_blob_talloc(state,
678 req->buf,
679 passlen1+1);
680 /* Ensure null termination */
681 state->plaintext_password.data[passlen1] = 0;
684 srvstr_pull_req_talloc(state, req, &tmp,
685 req->buf + passlen1, STR_TERMINATE);
686 state->user = tmp ? tmp : "";
688 state->domain = "";
690 } else {
691 uint16_t passlen1 = SVAL(req->vwv+7, 0);
692 uint16_t passlen2 = SVAL(req->vwv+8, 0);
693 enum remote_arch_types ra_type = get_remote_arch();
694 const uint8_t *p = req->buf;
695 const uint8_t *save_p = req->buf;
696 uint16_t byte_count;
698 if (!xconn->smb1.sessions.done_sesssetup) {
699 global_client_caps = IVAL(req->vwv+11, 0);
701 if (!(global_client_caps & CAP_STATUS32)) {
702 remove_from_common_flags2(
703 FLAGS2_32_BIT_ERROR_CODES);
706 /* client_caps is used as final determination if
707 * client is NT or Win95. This is needed to return
708 * the correct error codes in some circumstances.
711 if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
712 ra_type == RA_WIN95) {
713 if(!(global_client_caps & (CAP_NT_SMBS|
714 CAP_STATUS32))) {
715 set_remote_arch( RA_WIN95);
720 if (!doencrypt) {
721 /* both Win95 and WinNT stuff up the password
722 * lengths for non-encrypting systems. Uggh.
724 if passlen1==24 its a win95 system, and its setting
725 the password length incorrectly. Luckily it still
726 works with the default code because Win95 will null
727 terminate the password anyway
729 if passlen1>0 and passlen2>0 then maybe its a NT box
730 and its setting passlen2 to some random value which
731 really stuffs things up. we need to fix that one. */
733 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
734 passlen2 != 1) {
735 passlen2 = 0;
739 /* check for nasty tricks */
740 if (passlen1 > MAX_PASS_LEN
741 || passlen1 > smbreq_bufrem(req, p)) {
742 reply_nterror(req, nt_status_squash(
743 NT_STATUS_INVALID_PARAMETER));
744 END_PROFILE(SMBsesssetupX);
745 return;
748 if (passlen2 > MAX_PASS_LEN
749 || passlen2 > smbreq_bufrem(req, p+passlen1)) {
750 reply_nterror(req, nt_status_squash(
751 NT_STATUS_INVALID_PARAMETER));
752 END_PROFILE(SMBsesssetupX);
753 return;
756 /* Save the lanman2 password and the NT md4 password. */
758 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
759 doencrypt = False;
762 if (doencrypt) {
763 state->lm_resp = data_blob_talloc(state, p, passlen1);
764 state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
765 } else {
766 char *pass = NULL;
767 bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
769 if (unic && (passlen2 == 0) && passlen1) {
770 /* Only a ascii plaintext password was sent. */
771 (void)srvstr_pull_talloc(state,
772 req->inbuf,
773 req->flags2,
774 &pass,
775 req->buf,
776 passlen1,
777 STR_TERMINATE|STR_ASCII);
778 } else {
779 (void)srvstr_pull_talloc(state,
780 req->inbuf,
781 req->flags2,
782 &pass,
783 req->buf,
784 unic ? passlen2 : passlen1,
785 STR_TERMINATE);
787 if (!pass) {
788 reply_nterror(req, nt_status_squash(
789 NT_STATUS_INVALID_PARAMETER));
790 END_PROFILE(SMBsesssetupX);
791 return;
793 state->plaintext_password = data_blob_talloc(state,
794 pass,
795 strlen(pass)+1);
798 p += passlen1 + passlen2;
800 p += srvstr_pull_req_talloc(state, req, &tmp, p,
801 STR_TERMINATE);
802 state->user = tmp ? tmp : "";
804 p += srvstr_pull_req_talloc(state, req, &tmp, p,
805 STR_TERMINATE);
806 state->domain = tmp ? tmp : "";
808 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
809 STR_TERMINATE);
810 native_os = tmp ? tmp : "";
812 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
813 STR_TERMINATE);
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,
826 STR_TERMINATE);
827 primary_domain = tmp ? tmp : "";
828 } else {
829 primary_domain = talloc_strdup(talloc_tos(), "null");
832 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
833 "PrimaryDomain=[%s]\n",
834 state->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 );
839 else
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 state->domain, state->user, get_remote_machine_name()));
852 if (*state->user) {
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);
864 return;
866 fstrcpy(sub_user, state->user);
867 } else {
868 fstrcpy(sub_user, "");
871 if (!*state->user) {
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)) {
876 uint8_t chal[8];
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);
900 return;
902 nt_status = make_user_info_for_reply_enc(state,
903 &state->user_info,
904 state->user,
905 state->domain,
906 sconn->remote_address,
907 sconn->local_address,
908 "SMB",
909 state->lm_resp,
910 state->nt_resp);
912 if (NT_STATUS_IS_OK(nt_status)) {
913 state->user_info->auth_description = "bare-NTLM";
915 } else {
916 nt_status = make_auth4_context(state, &state->auth_context);
917 if (NT_STATUS_IS_OK(nt_status)) {
918 uint8_t chal[8];
920 state->auth_context->get_ntlm_challenge(
921 state->auth_context, chal);
923 if (!make_user_info_for_reply(state,
924 &state->user_info,
925 state->user,
926 state->domain,
927 sconn->remote_address,
928 sconn->local_address,
929 "SMB",
930 chal,
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);
944 return;
947 nt_status = auth_check_password_session_info(state->auth_context,
948 req, state->user_info,
949 &session_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);
954 return;
957 /* it's ok - setup a reply */
958 reply_smb1_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 (xconn->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,
975 now, &session);
976 if (!NT_STATUS_IS_OK(nt_status)) {
977 reply_nterror(req, nt_status_squash(nt_status));
978 END_PROFILE(SMBsesssetupX);
979 return;
982 session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
983 session->global->encryption_cipher = 0;
984 session->global->channels[0].signing_algo =
985 session->global->signing_algo;
986 session->global->channels[0].encryption_cipher =
987 session->global->encryption_cipher;
989 if (session_info->session_key.length > 0) {
990 struct smbXsrv_session *x = session;
991 uint8_t session_key[16];
992 NTSTATUS status;
994 status = smb2_signing_key_sign_create(x->global,
995 x->global->signing_algo,
996 &session_info->session_key,
997 NULL, /* no derivation */
998 &x->global->signing_key);
999 if (!NT_STATUS_IS_OK(status)) {
1000 TALLOC_FREE(session);
1001 reply_nterror(req, status);
1002 END_PROFILE(SMBsesssetupX);
1003 return;
1005 x->global->signing_key_blob = x->global->signing_key->blob;
1008 * The application key is truncated/padded to 16 bytes
1010 ZERO_STRUCT(session_key);
1011 memcpy(session_key, session->global->signing_key_blob.data,
1012 MIN(session->global->signing_key_blob.length,
1013 sizeof(session_key)));
1014 session->global->application_key_blob =
1015 data_blob_talloc(session->global,
1016 session_key,
1017 sizeof(session_key));
1018 ZERO_STRUCT(session_key);
1019 if (session->global->application_key_blob.data == NULL) {
1020 TALLOC_FREE(session);
1021 reply_nterror(req, NT_STATUS_NO_MEMORY);
1022 END_PROFILE(SMBsesssetupX);
1023 return;
1025 talloc_keep_secret(session->global->application_key_blob.data);
1028 * Place the application key into the session_info
1030 data_blob_clear_free(&session_info->session_key);
1031 session_info->session_key = data_blob_dup_talloc(session_info,
1032 session->global->application_key_blob);
1033 if (session_info->session_key.data == NULL) {
1034 TALLOC_FREE(session);
1035 reply_nterror(req, NT_STATUS_NO_MEMORY);
1036 END_PROFILE(SMBsesssetupX);
1037 return;
1039 talloc_keep_secret(session_info->session_key.data);
1042 sconn->num_users++;
1044 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1045 is_authenticated = true;
1046 session->homes_snum =
1047 register_homes_share(session_info->unix_info->unix_name);
1050 if (smb1_srv_is_signing_negotiated(xconn) &&
1051 is_authenticated &&
1052 smb2_signing_key_valid(session->global->signing_key))
1055 * Try and turn on server signing on the first non-guest
1056 * sessionsetup.
1058 smb1_srv_set_signing(xconn,
1059 session->global->signing_key->blob,
1060 state->nt_resp.data ? state->nt_resp : state->lm_resp);
1063 set_current_user_info(session_info->unix_info->sanitized_username,
1064 session_info->unix_info->unix_name,
1065 session_info->info->domain_name);
1067 session->status = NT_STATUS_OK;
1068 session->global->auth_session_info = talloc_move(session->global,
1069 &session_info);
1070 session->global->auth_session_info_seqnum += 1;
1071 session->global->channels[0].auth_session_info_seqnum =
1072 session->global->auth_session_info_seqnum;
1073 session->global->auth_time = now;
1074 session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1076 nt_status = smbXsrv_session_update(session);
1077 if (!NT_STATUS_IS_OK(nt_status)) {
1078 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1079 (unsigned long long)session->global->session_wire_id,
1080 nt_errstr(nt_status)));
1081 TALLOC_FREE(session);
1082 reply_nterror(req, nt_status_squash(nt_status));
1083 END_PROFILE(SMBsesssetupX);
1084 return;
1087 if (!session_claim(session)) {
1088 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1089 (unsigned long long)session->global->session_wire_id));
1090 TALLOC_FREE(session);
1091 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1092 END_PROFILE(SMBsesssetupX);
1093 return;
1096 /* current_user_info is changed on new vuid */
1097 reload_services(sconn, conn_snum_used, true);
1099 sess_vuid = session->global->session_wire_id;
1101 SSVAL(req->outbuf,smb_vwv2,action);
1102 SSVAL(req->outbuf,smb_uid,sess_vuid);
1103 SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1104 req->vuid = sess_vuid;
1106 if (!xconn->smb1.sessions.done_sesssetup) {
1107 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1108 reply_force_doserror(req, ERRSRV, ERRerror);
1109 END_PROFILE(SMBsesssetupX);
1110 return;
1112 xconn->smb1.sessions.max_send = smb_bufsize;
1113 xconn->smb1.sessions.done_sesssetup = true;
1116 TALLOC_FREE(state);
1117 END_PROFILE(SMBsesssetupX);