Line data Source code
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
10 :
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.
15 :
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.
20 :
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/>.
23 : */
24 :
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"
38 :
39 : /****************************************************************************
40 : Add the standard 'Samba' signature to the end of the session setup.
41 : ****************************************************************************/
42 :
43 11599 : static int push_signature(uint8_t **outbuf)
44 : {
45 133 : char *lanman;
46 133 : int result, tmp;
47 133 : fstring native_os;
48 :
49 11599 : result = 0;
50 :
51 11599 : fstr_sprintf(native_os, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION,
52 : SAMBA_MINOR_NBT_ANNOUNCE_VERSION);
53 :
54 11599 : tmp = message_push_string(outbuf, native_os, STR_TERMINATE);
55 :
56 11599 : if (tmp == -1) return -1;
57 11599 : result += tmp;
58 :
59 11599 : if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
60 11599 : tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
61 11599 : SAFE_FREE(lanman);
62 : }
63 : else {
64 0 : tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
65 : }
66 :
67 11599 : if (tmp == -1) return -1;
68 11599 : result += tmp;
69 :
70 11599 : tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
71 :
72 11599 : if (tmp == -1) return -1;
73 11599 : result += tmp;
74 :
75 11599 : return result;
76 : }
77 :
78 : /****************************************************************************
79 : Reply to a session setup command.
80 : conn POINTER CAN BE NULL HERE !
81 : ****************************************************************************/
82 :
83 12735 : static void reply_sesssetup_and_X_spnego(struct smb_request *req)
84 : {
85 133 : const uint8_t *p;
86 133 : DATA_BLOB in_blob;
87 12735 : DATA_BLOB out_blob = data_blob_null;
88 133 : size_t bufrem;
89 12735 : char *tmp = NULL;
90 133 : const char *native_os;
91 133 : const char *native_lanman;
92 133 : const char *primary_domain;
93 12735 : uint16_t data_blob_len = SVAL(req->vwv+7, 0);
94 12735 : enum remote_arch_types ra_type = get_remote_arch();
95 12735 : uint64_t vuid = req->vuid;
96 12735 : NTSTATUS status = NT_STATUS_OK;
97 12735 : struct smbXsrv_connection *xconn = req->xconn;
98 12735 : struct smbd_server_connection *sconn = req->sconn;
99 12735 : uint16_t action = 0;
100 12735 : bool is_authenticated = false;
101 12735 : NTTIME now = timeval_to_nttime(&req->request_time);
102 12735 : struct smbXsrv_session *session = NULL;
103 12735 : uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
104 12735 : uint32_t client_caps = IVAL(req->vwv+10, 0);
105 133 : struct smbXsrv_session_auth0 *auth;
106 :
107 12735 : DEBUG(3,("Doing spnego session setup\n"));
108 :
109 12735 : if (!xconn->smb1.sessions.done_sesssetup) {
110 10305 : global_client_caps = client_caps;
111 :
112 10305 : if (!(global_client_caps & CAP_STATUS32)) {
113 0 : remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
114 : }
115 : }
116 :
117 12735 : p = req->buf;
118 :
119 12735 : if (data_blob_len == 0) {
120 : /* an invalid request */
121 0 : reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
122 0 : return;
123 : }
124 :
125 12735 : bufrem = smbreq_bufrem(req, p);
126 : /* pull the spnego blob */
127 12735 : in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
128 :
129 : #if 0
130 : file_save("negotiate.dat", in_blob.data, in_blob.length);
131 : #endif
132 :
133 12735 : p = req->buf + in_blob.length;
134 :
135 12735 : p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
136 : STR_TERMINATE);
137 12735 : native_os = tmp ? tmp : "";
138 :
139 12735 : p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
140 : STR_TERMINATE);
141 12735 : native_lanman = tmp ? tmp : "";
142 :
143 12735 : p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
144 : STR_TERMINATE);
145 12735 : primary_domain = tmp ? tmp : "";
146 :
147 12735 : DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
148 : native_os, native_lanman, primary_domain));
149 :
150 12735 : if ( ra_type == RA_WIN2K ) {
151 : /* Vista sets neither the OS or lanman strings */
152 :
153 0 : if ( !strlen(native_os) && !strlen(native_lanman) )
154 0 : set_remote_arch(RA_VISTA);
155 :
156 : /* Windows 2003 doesn't set the native lanman string,
157 : but does set primary domain which is a bug I think */
158 :
159 0 : if ( !strlen(native_lanman) ) {
160 0 : ra_lanman_string( primary_domain );
161 : } else {
162 0 : ra_lanman_string( native_lanman );
163 : }
164 12735 : } else if ( ra_type == RA_VISTA ) {
165 0 : if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
166 0 : set_remote_arch(RA_OSX);
167 : }
168 : }
169 :
170 12735 : if (vuid != 0) {
171 6026 : status = smb1srv_session_lookup(xconn,
172 : vuid, now,
173 : &session);
174 6026 : if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
175 0 : reply_force_doserror(req, ERRSRV, ERRbaduid);
176 0 : return;
177 : }
178 6026 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
179 4 : status = NT_STATUS_OK;
180 : }
181 6026 : if (NT_STATUS_IS_OK(status)) {
182 36 : session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
183 36 : status = NT_STATUS_MORE_PROCESSING_REQUIRED;
184 36 : TALLOC_FREE(session->pending_auth);
185 : }
186 6026 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
187 0 : reply_nterror(req, nt_status_squash(status));
188 0 : return;
189 : }
190 : }
191 :
192 12735 : if (session == NULL) {
193 : /* create a new session */
194 6709 : status = smbXsrv_session_create(xconn,
195 : now, &session);
196 6709 : if (!NT_STATUS_IS_OK(status)) {
197 0 : reply_nterror(req, nt_status_squash(status));
198 0 : return;
199 : }
200 : }
201 :
202 12735 : status = smbXsrv_session_find_auth(session, xconn, now, &auth);
203 12735 : if (!NT_STATUS_IS_OK(status)) {
204 6745 : status = smbXsrv_session_create_auth(session, xconn, now,
205 : 0, /* flags */
206 : 0, /* security */
207 : &auth);
208 6745 : if (!NT_STATUS_IS_OK(status)) {
209 0 : reply_nterror(req, nt_status_squash(status));
210 0 : return;
211 : }
212 : }
213 :
214 12735 : if (auth->gensec == NULL) {
215 6745 : status = auth_generic_prepare(session,
216 : xconn->remote_address,
217 : xconn->local_address,
218 : "SMB",
219 6612 : &auth->gensec);
220 6745 : if (!NT_STATUS_IS_OK(status)) {
221 0 : TALLOC_FREE(session);
222 0 : reply_nterror(req, nt_status_squash(status));
223 0 : return;
224 : }
225 :
226 6745 : gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
227 6745 : gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
228 6745 : gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
229 :
230 6745 : status = gensec_start_mech_by_oid(auth->gensec,
231 : GENSEC_OID_SPNEGO);
232 6745 : if (!NT_STATUS_IS_OK(status)) {
233 0 : DEBUG(0, ("Failed to start SPNEGO handler!\n"));
234 0 : TALLOC_FREE(session);;
235 0 : reply_nterror(req, nt_status_squash(status));
236 0 : return;
237 : }
238 : }
239 :
240 12735 : become_root();
241 12735 : status = gensec_update(auth->gensec,
242 : talloc_tos(),
243 : in_blob, &out_blob);
244 12735 : unbecome_root();
245 12735 : if (!NT_STATUS_IS_OK(status) &&
246 7192 : !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
247 1198 : TALLOC_FREE(session);
248 1198 : reply_nterror(req, nt_status_squash(status));
249 1198 : return;
250 : }
251 :
252 17034 : if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
253 5507 : struct auth_session_info *session_info = NULL;
254 :
255 5507 : status = gensec_session_info(auth->gensec,
256 : session,
257 : &session_info);
258 5507 : if (!NT_STATUS_IS_OK(status)) {
259 10 : DEBUG(1,("Failed to generate session_info "
260 : "(user and group token) for session setup: %s\n",
261 : nt_errstr(status)));
262 10 : data_blob_free(&out_blob);
263 10 : TALLOC_FREE(session);
264 10 : reply_nterror(req, nt_status_squash(status));
265 10 : return;
266 : }
267 :
268 5497 : if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
269 4 : action |= SMB_SETUP_GUEST;
270 : }
271 :
272 5497 : session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
273 5497 : session->global->encryption_cipher = 0;
274 5497 : session->global->channels[0].signing_algo =
275 5364 : session->global->signing_algo;
276 5497 : session->global->channels[0].encryption_cipher =
277 5364 : session->global->encryption_cipher;
278 :
279 5497 : if (session_info->session_key.length > 0) {
280 5493 : struct smbXsrv_session *x = session;
281 :
282 5626 : status = smb2_signing_key_sign_create(x->global,
283 5360 : x->global->signing_algo,
284 5493 : &session_info->session_key,
285 : NULL, /* no derivation */
286 5360 : &x->global->signing_key);
287 5493 : if (!NT_STATUS_IS_OK(status)) {
288 0 : data_blob_free(&out_blob);
289 0 : TALLOC_FREE(session);
290 0 : reply_nterror(req, status);
291 0 : return;
292 : }
293 5493 : x->global->signing_key_blob = x->global->signing_key->blob;
294 :
295 : /*
296 : * clear the session key
297 : * the first tcon will add setup the application key
298 : */
299 5493 : data_blob_clear_free(&session_info->session_key);
300 : }
301 :
302 5497 : sconn->num_users++;
303 :
304 5497 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
305 5439 : is_authenticated = true;
306 5572 : session->homes_snum =
307 5439 : register_homes_share(session_info->unix_info->unix_name);
308 : }
309 :
310 5497 : if (smb1_srv_is_signing_negotiated(xconn) &&
311 1054 : is_authenticated &&
312 1054 : smb2_signing_key_valid(session->global->signing_key))
313 : {
314 : /*
315 : * Try and turn on server signing on the first non-guest
316 : * sessionsetup.
317 : */
318 1054 : smb1_srv_set_signing(xconn,
319 1054 : session->global->signing_key->blob,
320 : data_blob_null);
321 : }
322 :
323 5497 : set_current_user_info(session_info->unix_info->sanitized_username,
324 5497 : session_info->unix_info->unix_name,
325 5497 : session_info->info->domain_name);
326 :
327 5497 : session->status = NT_STATUS_OK;
328 5497 : session->global->auth_session_info = talloc_move(session->global,
329 : &session_info);
330 5497 : session->global->auth_session_info_seqnum += 1;
331 5497 : session->global->channels[0].auth_session_info_seqnum =
332 5364 : session->global->auth_session_info_seqnum;
333 5497 : session->global->auth_time = now;
334 5497 : if (client_caps & CAP_DYNAMIC_REAUTH) {
335 0 : session->global->expiration_time =
336 0 : gensec_expire_time(auth->gensec);
337 : } else {
338 5497 : session->global->expiration_time =
339 : GENSEC_EXPIRE_TIME_INFINITY;
340 : }
341 :
342 5497 : if (!session_claim(session)) {
343 0 : DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
344 : (unsigned long long)session->global->session_wire_id));
345 0 : data_blob_free(&out_blob);
346 0 : TALLOC_FREE(session);
347 0 : reply_nterror(req, NT_STATUS_LOGON_FAILURE);
348 0 : return;
349 : }
350 :
351 5497 : status = smbXsrv_session_update(session);
352 5497 : if (!NT_STATUS_IS_OK(status)) {
353 0 : 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 0 : data_blob_free(&out_blob);
357 0 : TALLOC_FREE(session);
358 0 : reply_nterror(req, NT_STATUS_LOGON_FAILURE);
359 0 : return;
360 : }
361 :
362 5497 : if (!xconn->smb1.sessions.done_sesssetup) {
363 5477 : if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
364 0 : reply_force_doserror(req, ERRSRV, ERRerror);
365 0 : return;
366 : }
367 5477 : xconn->smb1.sessions.max_send = smb_bufsize;
368 5477 : xconn->smb1.sessions.done_sesssetup = true;
369 : }
370 :
371 : /* current_user_info is changed on new vuid */
372 5497 : reload_services(sconn, conn_snum_used, true);
373 6030 : } else if (NT_STATUS_IS_OK(status)) {
374 36 : struct auth_session_info *session_info = NULL;
375 :
376 36 : status = gensec_session_info(auth->gensec,
377 : session,
378 : &session_info);
379 36 : if (!NT_STATUS_IS_OK(status)) {
380 0 : DEBUG(1,("Failed to generate session_info "
381 : "(user and group token) for session setup: %s\n",
382 : nt_errstr(status)));
383 0 : data_blob_free(&out_blob);
384 0 : TALLOC_FREE(session);
385 0 : reply_nterror(req, nt_status_squash(status));
386 0 : return;
387 : }
388 :
389 36 : if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
390 0 : action |= SMB_SETUP_GUEST;
391 : }
392 :
393 : /*
394 : * Keep the application key
395 : */
396 36 : data_blob_clear_free(&session_info->session_key);
397 36 : session_info->session_key =
398 36 : session->global->auth_session_info->session_key;
399 36 : talloc_steal(session_info, session_info->session_key.data);
400 36 : TALLOC_FREE(session->global->auth_session_info);
401 :
402 36 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
403 22 : session->homes_snum =
404 22 : register_homes_share(session_info->unix_info->unix_name);
405 : }
406 :
407 36 : set_current_user_info(session_info->unix_info->sanitized_username,
408 36 : session_info->unix_info->unix_name,
409 36 : session_info->info->domain_name);
410 :
411 36 : session->status = NT_STATUS_OK;
412 36 : session->global->auth_session_info = talloc_move(session->global,
413 : &session_info);
414 36 : session->global->auth_session_info_seqnum += 1;
415 36 : session->global->channels[0].auth_session_info_seqnum =
416 36 : session->global->auth_session_info_seqnum;
417 36 : session->global->auth_time = now;
418 36 : if (client_caps & CAP_DYNAMIC_REAUTH) {
419 6 : session->global->expiration_time =
420 6 : gensec_expire_time(auth->gensec);
421 : } else {
422 30 : session->global->expiration_time =
423 : GENSEC_EXPIRE_TIME_INFINITY;
424 : }
425 :
426 36 : status = smbXsrv_session_update(session);
427 36 : if (!NT_STATUS_IS_OK(status)) {
428 0 : 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 0 : data_blob_free(&out_blob);
432 0 : TALLOC_FREE(session);
433 0 : reply_nterror(req, NT_STATUS_LOGON_FAILURE);
434 0 : return;
435 : }
436 :
437 36 : conn_clear_vuid_caches(sconn, session->global->session_wire_id);
438 :
439 : /* current_user_info is changed on new vuid */
440 36 : reload_services(sconn, conn_snum_used, true);
441 : }
442 :
443 11527 : vuid = session->global->session_wire_id;
444 :
445 11527 : reply_smb1_outbuf(req, 4, 0);
446 :
447 11527 : SSVAL(req->outbuf, smb_uid, vuid);
448 11527 : SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
449 11527 : SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
450 11527 : SSVAL(req->outbuf, smb_vwv2, action);
451 11527 : SSVAL(req->outbuf, smb_vwv3, out_blob.length);
452 :
453 11527 : if (message_push_blob(&req->outbuf, out_blob) == -1) {
454 0 : data_blob_free(&out_blob);
455 0 : TALLOC_FREE(session);
456 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
457 0 : return;
458 : }
459 11527 : data_blob_free(&out_blob);
460 :
461 11527 : if (push_signature(&req->outbuf) == -1) {
462 0 : TALLOC_FREE(session);
463 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
464 0 : return;
465 : }
466 : }
467 :
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 : ****************************************************************************/
473 :
474 : struct shutdown_state {
475 : const char *ip;
476 : size_t ip_length;
477 : struct messaging_context *msg_ctx;
478 : };
479 :
480 0 : static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
481 : void *private_data)
482 : {
483 0 : struct shutdown_state *state = (struct shutdown_state *)private_data;
484 0 : struct server_id self_pid = messaging_server_id(state->msg_ctx);
485 0 : struct server_id pid = session->channels[0].server_id;
486 0 : const char *addr = session->channels[0].remote_address;
487 0 : const char *port_colon;
488 0 : size_t addr_len;
489 0 : struct server_id_buf tmp;
490 :
491 0 : DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
492 : server_id_str_buf(pid, &tmp), addr));
493 :
494 0 : if (!process_exists(pid)) {
495 0 : DEBUG(10, ("process does not exist\n"));
496 0 : return 0;
497 : }
498 :
499 0 : if (server_id_equal(&pid, &self_pid)) {
500 0 : DEBUG(10, ("It's me\n"));
501 0 : return 0;
502 : }
503 :
504 0 : port_colon = strrchr(addr, ':');
505 0 : if (port_colon == NULL) {
506 0 : DBG_DEBUG("addr %s in contains no port\n", addr);
507 0 : return 0;
508 : }
509 0 : addr_len = port_colon - addr;
510 :
511 0 : if ((addr_len != state->ip_length) ||
512 0 : (strncmp(addr, state->ip, state->ip_length) != 0)) {
513 0 : DEBUG(10, ("%s (%zu) does not match %s (%zu)\n",
514 : state->ip, state->ip_length, addr, addr_len));
515 0 : return 0;
516 : }
517 :
518 0 : DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
519 : "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
520 : state->ip));
521 :
522 0 : messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
523 : &data_blob_null);
524 0 : return 0;
525 : }
526 :
527 0 : static void setup_new_vc_session(struct smbd_server_connection *sconn)
528 : {
529 0 : DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
530 : "compatible we would close all old resources.\n"));
531 :
532 0 : if (lp_reset_on_zero_vc()) {
533 0 : char *addr;
534 0 : const char *port_colon;
535 0 : struct shutdown_state state;
536 :
537 0 : addr = tsocket_address_string(
538 : sconn->remote_address, talloc_tos());
539 0 : if (addr == NULL) {
540 0 : return;
541 : }
542 0 : state.ip = addr;
543 :
544 0 : port_colon = strrchr(addr, ':');
545 0 : if (port_colon == NULL) {
546 0 : return;
547 : }
548 0 : state.ip_length = port_colon - addr;
549 0 : state.msg_ctx = sconn->msg_ctx;
550 0 : smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
551 0 : TALLOC_FREE(addr);
552 : }
553 : }
554 :
555 : /****************************************************************************
556 : Reply to a session setup command.
557 : ****************************************************************************/
558 :
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;
568 : };
569 :
570 12835 : static int reply_sesssetup_and_X_state_destructor(
571 : struct reply_sesssetup_and_X_state *state)
572 : {
573 12835 : data_blob_clear_free(&state->nt_resp);
574 12835 : data_blob_clear_free(&state->lm_resp);
575 12835 : data_blob_clear_free(&state->plaintext_password);
576 12835 : return 0;
577 : }
578 :
579 12835 : void reply_sesssetup_and_X(struct smb_request *req)
580 : {
581 12835 : struct reply_sesssetup_and_X_state *state = NULL;
582 133 : uint64_t sess_vuid;
583 133 : uint16_t smb_bufsize;
584 12835 : char *tmp = NULL;
585 133 : fstring sub_user; /* Sanitised username for substitution */
586 133 : const char *native_os;
587 133 : const char *native_lanman;
588 133 : const char *primary_domain;
589 12835 : struct auth_session_info *session_info = NULL;
590 12835 : uint16_t smb_flag2 = req->flags2;
591 12835 : uint16_t action = 0;
592 12835 : bool is_authenticated = false;
593 12835 : NTTIME now = timeval_to_nttime(&req->request_time);
594 12835 : struct smbXsrv_session *session = NULL;
595 133 : NTSTATUS nt_status;
596 12835 : struct smbXsrv_connection *xconn = req->xconn;
597 12835 : struct smbd_server_connection *sconn = req->sconn;
598 12835 : bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
599 12835 : bool signing_allowed = false;
600 12835 : bool signing_mandatory = smb1_signing_is_mandatory(
601 : xconn->smb1.signing_state);
602 :
603 12835 : START_PROFILE(SMBsesssetupX);
604 :
605 12835 : DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
606 :
607 12835 : state = talloc_zero(req, struct reply_sesssetup_and_X_state);
608 12835 : if (state == NULL) {
609 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
610 0 : END_PROFILE(SMBsesssetupX);
611 0 : return;
612 : }
613 12835 : state->req = req;
614 12835 : talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
615 :
616 12835 : if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
617 809 : signing_allowed = true;
618 : }
619 12835 : if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
620 589 : signing_mandatory = true;
621 : }
622 :
623 : /*
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.
627 : */
628 12835 : smb1_srv_set_signing_negotiated(xconn,
629 : signing_allowed,
630 : signing_mandatory);
631 :
632 : /* a SPNEGO session setup has 12 command words, whereas a normal
633 : NT1 session setup has 13. See the cifs spec. */
634 12835 : if (req->wct == 12 &&
635 12735 : (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
636 :
637 12735 : if (!xconn->smb1.negprot.spnego) {
638 0 : DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
639 : "at SPNEGO session setup when it was not "
640 : "negotiated.\n"));
641 0 : reply_nterror(req, nt_status_squash(
642 : NT_STATUS_LOGON_FAILURE));
643 0 : END_PROFILE(SMBsesssetupX);
644 0 : return;
645 : }
646 :
647 12735 : if (SVAL(req->vwv+4, 0) == 0) {
648 0 : setup_new_vc_session(req->sconn);
649 : }
650 :
651 12735 : reply_sesssetup_and_X_spnego(req);
652 12735 : END_PROFILE(SMBsesssetupX);
653 12735 : return;
654 : }
655 :
656 100 : smb_bufsize = SVAL(req->vwv+2, 0);
657 :
658 100 : if (xconn->protocol < PROTOCOL_NT1) {
659 24 : uint16_t passlen1 = SVAL(req->vwv+7, 0);
660 :
661 : /* Never do NT status codes with protocols before NT1 as we
662 : * don't get client caps. */
663 24 : remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
664 :
665 24 : if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
666 0 : reply_nterror(req, nt_status_squash(
667 : NT_STATUS_INVALID_PARAMETER));
668 0 : END_PROFILE(SMBsesssetupX);
669 0 : return;
670 : }
671 :
672 24 : if (doencrypt) {
673 24 : state->lm_resp = data_blob_talloc(state,
674 : req->buf,
675 : passlen1);
676 : } else {
677 0 : state->plaintext_password = data_blob_talloc(state,
678 : req->buf,
679 : passlen1+1);
680 : /* Ensure null termination */
681 0 : state->plaintext_password.data[passlen1] = 0;
682 : }
683 :
684 24 : srvstr_pull_req_talloc(state, req, &tmp,
685 24 : req->buf + passlen1, STR_TERMINATE);
686 24 : state->user = tmp ? tmp : "";
687 :
688 24 : state->domain = "";
689 :
690 : } else {
691 76 : uint16_t passlen1 = SVAL(req->vwv+7, 0);
692 76 : uint16_t passlen2 = SVAL(req->vwv+8, 0);
693 76 : enum remote_arch_types ra_type = get_remote_arch();
694 76 : const uint8_t *p = req->buf;
695 76 : const uint8_t *save_p = req->buf;
696 0 : uint16_t byte_count;
697 :
698 76 : if (!xconn->smb1.sessions.done_sesssetup) {
699 76 : global_client_caps = IVAL(req->vwv+11, 0);
700 :
701 76 : if (!(global_client_caps & CAP_STATUS32)) {
702 8 : remove_from_common_flags2(
703 : FLAGS2_32_BIT_ERROR_CODES);
704 : }
705 :
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.
709 : */
710 :
711 76 : if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
712 : ra_type == RA_WIN95) {
713 0 : if(!(global_client_caps & (CAP_NT_SMBS|
714 : CAP_STATUS32))) {
715 0 : set_remote_arch( RA_WIN95);
716 : }
717 : }
718 : }
719 :
720 76 : if (!doencrypt) {
721 : /* both Win95 and WinNT stuff up the password
722 : * lengths for non-encrypting systems. Uggh.
723 :
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
728 :
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. */
732 :
733 0 : if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
734 0 : passlen2 != 1) {
735 0 : passlen2 = 0;
736 : }
737 : }
738 :
739 : /* check for nasty tricks */
740 76 : if (passlen1 > MAX_PASS_LEN
741 76 : || passlen1 > smbreq_bufrem(req, p)) {
742 0 : reply_nterror(req, nt_status_squash(
743 : NT_STATUS_INVALID_PARAMETER));
744 0 : END_PROFILE(SMBsesssetupX);
745 0 : return;
746 : }
747 :
748 76 : if (passlen2 > MAX_PASS_LEN
749 76 : || passlen2 > smbreq_bufrem(req, p+passlen1)) {
750 0 : reply_nterror(req, nt_status_squash(
751 : NT_STATUS_INVALID_PARAMETER));
752 0 : END_PROFILE(SMBsesssetupX);
753 0 : return;
754 : }
755 :
756 : /* Save the lanman2 password and the NT md4 password. */
757 :
758 76 : if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
759 2 : doencrypt = False;
760 : }
761 :
762 76 : if (doencrypt) {
763 74 : state->lm_resp = data_blob_talloc(state, p, passlen1);
764 74 : state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
765 : } else {
766 2 : char *pass = NULL;
767 2 : bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
768 :
769 2 : if (unic && (passlen2 == 0) && passlen1) {
770 : /* Only a ascii plaintext password was sent. */
771 0 : (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 2 : (void)srvstr_pull_talloc(state,
780 : req->inbuf,
781 : req->flags2,
782 : &pass,
783 : req->buf,
784 : unic ? passlen2 : passlen1,
785 : STR_TERMINATE);
786 : }
787 2 : if (!pass) {
788 0 : reply_nterror(req, nt_status_squash(
789 : NT_STATUS_INVALID_PARAMETER));
790 0 : END_PROFILE(SMBsesssetupX);
791 0 : return;
792 : }
793 2 : state->plaintext_password = data_blob_talloc(state,
794 : pass,
795 : strlen(pass)+1);
796 : }
797 :
798 76 : p += passlen1 + passlen2;
799 :
800 76 : p += srvstr_pull_req_talloc(state, req, &tmp, p,
801 : STR_TERMINATE);
802 76 : state->user = tmp ? tmp : "";
803 :
804 76 : p += srvstr_pull_req_talloc(state, req, &tmp, p,
805 : STR_TERMINATE);
806 76 : state->domain = tmp ? tmp : "";
807 :
808 76 : p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
809 : STR_TERMINATE);
810 76 : native_os = tmp ? tmp : "";
811 :
812 76 : p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
813 : STR_TERMINATE);
814 76 : native_lanman = tmp ? tmp : "";
815 :
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 */
822 :
823 76 : byte_count = SVAL(req->vwv+13, 0);
824 76 : if ( PTR_DIFF(p, save_p) < byte_count) {
825 0 : p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
826 : STR_TERMINATE);
827 0 : primary_domain = tmp ? tmp : "";
828 : } else {
829 76 : primary_domain = talloc_strdup(talloc_tos(), "null");
830 : }
831 :
832 76 : DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
833 : "PrimaryDomain=[%s]\n",
834 : state->domain, native_os, native_lanman, primary_domain));
835 :
836 76 : if ( ra_type == RA_WIN2K ) {
837 0 : if ( strlen(native_lanman) == 0 )
838 0 : ra_lanman_string( primary_domain );
839 : else
840 0 : ra_lanman_string( native_lanman );
841 : }
842 :
843 : }
844 :
845 100 : if (SVAL(req->vwv+4, 0) == 0) {
846 0 : setup_new_vc_session(req->sconn);
847 : }
848 :
849 100 : DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
850 : state->domain, state->user, get_remote_machine_name()));
851 :
852 100 : if (*state->user) {
853 63 : if (xconn->smb1.negprot.spnego) {
854 :
855 : /* This has to be here, because this is a perfectly
856 : * valid behaviour for guest logons :-( */
857 :
858 0 : DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
859 : "at 'normal' session setup after "
860 : "negotiating spnego.\n"));
861 0 : reply_nterror(req, nt_status_squash(
862 : NT_STATUS_LOGON_FAILURE));
863 0 : END_PROFILE(SMBsesssetupX);
864 0 : return;
865 : }
866 63 : fstrcpy(sub_user, state->user);
867 : } else {
868 37 : fstrcpy(sub_user, "");
869 : }
870 :
871 100 : if (!*state->user) {
872 37 : DEBUG(3,("Got anonymous request\n"));
873 :
874 37 : nt_status = make_auth4_context(state, &state->auth_context);
875 37 : if (NT_STATUS_IS_OK(nt_status)) {
876 0 : uint8_t chal[8];
877 :
878 37 : state->auth_context->get_ntlm_challenge(
879 : state->auth_context, chal);
880 :
881 37 : if (!make_user_info_guest(state,
882 : sconn->remote_address,
883 : sconn->local_address,
884 : "SMB", &state->user_info)) {
885 0 : nt_status = NT_STATUS_NO_MEMORY;
886 : }
887 :
888 37 : if (NT_STATUS_IS_OK(nt_status)) {
889 37 : state->user_info->auth_description = "guest";
890 : }
891 : }
892 63 : } else if (doencrypt) {
893 63 : state->auth_context = xconn->smb1.negprot.auth_context;
894 63 : if (state->auth_context == NULL) {
895 0 : DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
896 : "session setup without negprot denied!\n"));
897 0 : reply_nterror(req, nt_status_squash(
898 : NT_STATUS_LOGON_FAILURE));
899 0 : END_PROFILE(SMBsesssetupX);
900 0 : return;
901 : }
902 63 : 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);
911 :
912 63 : if (NT_STATUS_IS_OK(nt_status)) {
913 61 : state->user_info->auth_description = "bare-NTLM";
914 : }
915 : } else {
916 0 : nt_status = make_auth4_context(state, &state->auth_context);
917 0 : if (NT_STATUS_IS_OK(nt_status)) {
918 0 : uint8_t chal[8];
919 :
920 0 : state->auth_context->get_ntlm_challenge(
921 : state->auth_context, chal);
922 :
923 0 : 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 0 : nt_status = NT_STATUS_NO_MEMORY;
933 : }
934 :
935 0 : if (NT_STATUS_IS_OK(nt_status)) {
936 0 : state->user_info->auth_description = "plaintext";
937 : }
938 : }
939 : }
940 :
941 100 : if (!NT_STATUS_IS_OK(nt_status)) {
942 2 : reply_nterror(req, nt_status_squash(nt_status));
943 2 : END_PROFILE(SMBsesssetupX);
944 2 : return;
945 : }
946 :
947 98 : nt_status = auth_check_password_session_info(state->auth_context,
948 : req, state->user_info,
949 : &session_info);
950 98 : TALLOC_FREE(state->user_info);
951 98 : if (!NT_STATUS_IS_OK(nt_status)) {
952 2 : reply_nterror(req, nt_status_squash(nt_status));
953 2 : END_PROFILE(SMBsesssetupX);
954 2 : return;
955 : }
956 :
957 : /* it's ok - setup a reply */
958 96 : reply_smb1_outbuf(req, 3, 0);
959 96 : SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
960 96 : SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
961 :
962 96 : if (xconn->protocol >= PROTOCOL_NT1) {
963 72 : push_signature(&req->outbuf);
964 : /* perhaps grab OS version here?? */
965 : }
966 :
967 96 : if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
968 1 : action |= SMB_SETUP_GUEST;
969 : }
970 :
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 */
973 :
974 96 : nt_status = smbXsrv_session_create(xconn,
975 : now, &session);
976 96 : if (!NT_STATUS_IS_OK(nt_status)) {
977 0 : reply_nterror(req, nt_status_squash(nt_status));
978 0 : END_PROFILE(SMBsesssetupX);
979 0 : return;
980 : }
981 :
982 96 : session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
983 96 : session->global->encryption_cipher = 0;
984 96 : session->global->channels[0].signing_algo =
985 96 : session->global->signing_algo;
986 96 : session->global->channels[0].encryption_cipher =
987 96 : session->global->encryption_cipher;
988 :
989 96 : if (session_info->session_key.length > 0) {
990 47 : struct smbXsrv_session *x = session;
991 0 : uint8_t session_key[16];
992 0 : NTSTATUS status;
993 :
994 47 : status = smb2_signing_key_sign_create(x->global,
995 47 : x->global->signing_algo,
996 47 : &session_info->session_key,
997 : NULL, /* no derivation */
998 47 : &x->global->signing_key);
999 47 : if (!NT_STATUS_IS_OK(status)) {
1000 0 : TALLOC_FREE(session);
1001 0 : reply_nterror(req, status);
1002 0 : END_PROFILE(SMBsesssetupX);
1003 0 : return;
1004 : }
1005 47 : x->global->signing_key_blob = x->global->signing_key->blob;
1006 :
1007 : /*
1008 : * The application key is truncated/padded to 16 bytes
1009 : */
1010 47 : ZERO_STRUCT(session_key);
1011 47 : memcpy(session_key, session->global->signing_key_blob.data,
1012 47 : MIN(session->global->signing_key_blob.length,
1013 : sizeof(session_key)));
1014 47 : session->global->application_key_blob =
1015 47 : data_blob_talloc(session->global,
1016 : session_key,
1017 : sizeof(session_key));
1018 47 : ZERO_STRUCT(session_key);
1019 47 : if (session->global->application_key_blob.data == NULL) {
1020 0 : TALLOC_FREE(session);
1021 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1022 0 : END_PROFILE(SMBsesssetupX);
1023 0 : return;
1024 : }
1025 47 : talloc_keep_secret(session->global->application_key_blob.data);
1026 :
1027 : /*
1028 : * Place the application key into the session_info
1029 : */
1030 47 : data_blob_clear_free(&session_info->session_key);
1031 47 : session_info->session_key = data_blob_dup_talloc(session_info,
1032 : session->global->application_key_blob);
1033 47 : if (session_info->session_key.data == NULL) {
1034 0 : TALLOC_FREE(session);
1035 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1036 0 : END_PROFILE(SMBsesssetupX);
1037 0 : return;
1038 : }
1039 47 : talloc_keep_secret(session_info->session_key.data);
1040 : }
1041 :
1042 96 : sconn->num_users++;
1043 :
1044 96 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1045 58 : is_authenticated = true;
1046 58 : session->homes_snum =
1047 58 : register_homes_share(session_info->unix_info->unix_name);
1048 : }
1049 :
1050 96 : if (smb1_srv_is_signing_negotiated(xconn) &&
1051 9 : is_authenticated &&
1052 9 : smb2_signing_key_valid(session->global->signing_key))
1053 : {
1054 : /*
1055 : * Try and turn on server signing on the first non-guest
1056 : * sessionsetup.
1057 : */
1058 9 : smb1_srv_set_signing(xconn,
1059 9 : session->global->signing_key->blob,
1060 9 : state->nt_resp.data ? state->nt_resp : state->lm_resp);
1061 : }
1062 :
1063 96 : set_current_user_info(session_info->unix_info->sanitized_username,
1064 96 : session_info->unix_info->unix_name,
1065 96 : session_info->info->domain_name);
1066 :
1067 96 : session->status = NT_STATUS_OK;
1068 96 : session->global->auth_session_info = talloc_move(session->global,
1069 : &session_info);
1070 96 : session->global->auth_session_info_seqnum += 1;
1071 96 : session->global->channels[0].auth_session_info_seqnum =
1072 96 : session->global->auth_session_info_seqnum;
1073 96 : session->global->auth_time = now;
1074 96 : session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1075 :
1076 96 : nt_status = smbXsrv_session_update(session);
1077 96 : if (!NT_STATUS_IS_OK(nt_status)) {
1078 0 : 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 0 : TALLOC_FREE(session);
1082 0 : reply_nterror(req, nt_status_squash(nt_status));
1083 0 : END_PROFILE(SMBsesssetupX);
1084 0 : return;
1085 : }
1086 :
1087 96 : if (!session_claim(session)) {
1088 0 : DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1089 : (unsigned long long)session->global->session_wire_id));
1090 0 : TALLOC_FREE(session);
1091 0 : reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1092 0 : END_PROFILE(SMBsesssetupX);
1093 0 : return;
1094 : }
1095 :
1096 : /* current_user_info is changed on new vuid */
1097 96 : reload_services(sconn, conn_snum_used, true);
1098 :
1099 96 : sess_vuid = session->global->session_wire_id;
1100 :
1101 96 : SSVAL(req->outbuf,smb_vwv2,action);
1102 96 : SSVAL(req->outbuf,smb_uid,sess_vuid);
1103 96 : SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1104 96 : req->vuid = sess_vuid;
1105 :
1106 96 : if (!xconn->smb1.sessions.done_sesssetup) {
1107 96 : if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1108 0 : reply_force_doserror(req, ERRSRV, ERRerror);
1109 0 : END_PROFILE(SMBsesssetupX);
1110 0 : return;
1111 : }
1112 96 : xconn->smb1.sessions.max_send = smb_bufsize;
1113 96 : xconn->smb1.sessions.done_sesssetup = true;
1114 : }
1115 :
1116 96 : TALLOC_FREE(state);
1117 96 : END_PROFILE(SMBsesssetupX);
1118 : }
|