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