Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Core SMB2 server
4 :
5 : Copyright (C) Stefan Metzmacher 2009
6 : Copyright (C) Jeremy Allison 2010
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "smbd/smbd.h"
24 : #include "smbd/globals.h"
25 : #include "source3/smbd/smbXsrv_session.h"
26 : #include "../libcli/smb/smb_common.h"
27 : #include "../auth/gensec/gensec.h"
28 : #include "auth.h"
29 : #include "../lib/tsocket/tsocket.h"
30 : #include "../libcli/security/security.h"
31 : #include "../lib/util/tevent_ntstatus.h"
32 : #include "source3/lib/substitute.h"
33 :
34 : #include "lib/crypto/gnutls_helpers.h"
35 : #include <gnutls/gnutls.h>
36 : #include <gnutls/crypto.h>
37 :
38 : #undef DBGC_CLASS
39 : #define DBGC_CLASS DBGC_SMB2
40 :
41 : static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
42 : struct tevent_context *ev,
43 : struct smbd_smb2_request *smb2req,
44 : uint64_t in_session_id,
45 : uint8_t in_flags,
46 : uint8_t in_security_mode,
47 : uint64_t in_previous_session_id,
48 : DATA_BLOB in_security_buffer);
49 : static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
50 : uint16_t *out_session_flags,
51 : TALLOC_CTX *mem_ctx,
52 : DATA_BLOB *out_security_buffer,
53 : uint64_t *out_session_id);
54 :
55 : static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
56 :
57 47605 : NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
58 : {
59 1151 : const uint8_t *inhdr;
60 1151 : const uint8_t *inbody;
61 1151 : uint64_t in_session_id;
62 1151 : uint8_t in_flags;
63 1151 : uint8_t in_security_mode;
64 1151 : uint64_t in_previous_session_id;
65 1151 : uint16_t in_security_offset;
66 1151 : uint16_t in_security_length;
67 1151 : DATA_BLOB in_security_buffer;
68 1151 : NTSTATUS status;
69 1151 : struct tevent_req *subreq;
70 :
71 47605 : status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
72 47605 : if (!NT_STATUS_IS_OK(status)) {
73 0 : return smbd_smb2_request_error(smb2req, status);
74 : }
75 47605 : inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
76 47605 : inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
77 :
78 47605 : in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
79 :
80 47605 : in_flags = CVAL(inbody, 0x02);
81 47605 : in_security_mode = CVAL(inbody, 0x03);
82 : /* Capabilities = IVAL(inbody, 0x04) */
83 : /* Channel = IVAL(inbody, 0x08) */
84 47605 : in_security_offset = SVAL(inbody, 0x0C);
85 47605 : in_security_length = SVAL(inbody, 0x0E);
86 47605 : in_previous_session_id = BVAL(inbody, 0x10);
87 :
88 47605 : if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
89 0 : return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
90 : }
91 :
92 47605 : if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
93 0 : return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
94 : }
95 :
96 47605 : in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
97 47605 : in_security_buffer.length = in_security_length;
98 :
99 48756 : subreq = smbd_smb2_session_setup_wrap_send(smb2req,
100 47605 : smb2req->sconn->ev_ctx,
101 : smb2req,
102 : in_session_id,
103 : in_flags,
104 : in_security_mode,
105 : in_previous_session_id,
106 : in_security_buffer);
107 47605 : if (subreq == NULL) {
108 0 : return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
109 : }
110 47605 : tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
111 :
112 : /*
113 : * Avoid sending a STATUS_PENDING message, which
114 : * matches a Windows Server and avoids problems with
115 : * MacOS clients.
116 : *
117 : * Even after 90 seconds a Windows Server doesn't return
118 : * STATUS_PENDING if using NTLMSSP against a non reachable
119 : * trusted domain.
120 : */
121 47605 : return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
122 : }
123 :
124 47605 : static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
125 : {
126 1151 : struct smbd_smb2_request *smb2req =
127 47605 : tevent_req_callback_data(subreq,
128 : struct smbd_smb2_request);
129 1151 : uint8_t *outhdr;
130 1151 : DATA_BLOB outbody;
131 1151 : DATA_BLOB outdyn;
132 47605 : uint16_t out_session_flags = 0;
133 47605 : uint64_t out_session_id = 0;
134 1151 : uint16_t out_security_offset;
135 47605 : DATA_BLOB out_security_buffer = data_blob_null;
136 1151 : NTSTATUS status;
137 1151 : NTSTATUS error; /* transport error */
138 :
139 47605 : status = smbd_smb2_session_setup_wrap_recv(subreq,
140 : &out_session_flags,
141 : smb2req,
142 : &out_security_buffer,
143 : &out_session_id);
144 47605 : TALLOC_FREE(subreq);
145 47605 : if (!NT_STATUS_IS_OK(status) &&
146 22265 : !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
147 3385 : status = nt_status_squash(status);
148 3385 : error = smbd_smb2_request_error(smb2req, status);
149 3385 : if (!NT_STATUS_IS_OK(error)) {
150 0 : smbd_server_connection_terminate(smb2req->xconn,
151 : nt_errstr(error));
152 3090 : return;
153 : }
154 3090 : return;
155 : }
156 :
157 44220 : out_security_offset = SMB2_HDR_BODY + 0x08;
158 :
159 44220 : outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
160 :
161 44220 : outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
162 44220 : if (outbody.data == NULL) {
163 0 : error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
164 0 : if (!NT_STATUS_IS_OK(error)) {
165 0 : smbd_server_connection_terminate(smb2req->xconn,
166 : nt_errstr(error));
167 0 : return;
168 : }
169 0 : return;
170 : }
171 :
172 44220 : SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
173 :
174 44220 : SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
175 44220 : SSVAL(outbody.data, 0x02,
176 : out_session_flags); /* session flags */
177 44220 : SSVAL(outbody.data, 0x04,
178 : out_security_offset); /* security buffer offset */
179 44220 : SSVAL(outbody.data, 0x06,
180 : out_security_buffer.length); /* security buffer length */
181 :
182 44220 : outdyn = out_security_buffer;
183 :
184 44220 : error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
185 : __location__);
186 44220 : if (!NT_STATUS_IS_OK(error)) {
187 0 : smbd_server_connection_terminate(smb2req->xconn,
188 : nt_errstr(error));
189 0 : return;
190 : }
191 : }
192 :
193 23850 : static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
194 : struct smbXsrv_session_auth0 **_auth,
195 : struct smbd_smb2_request *smb2req,
196 : uint8_t in_security_mode,
197 : struct auth_session_info *session_info,
198 : uint16_t *out_session_flags,
199 : uint64_t *out_session_id)
200 : {
201 649 : NTSTATUS status;
202 23850 : bool guest = false;
203 23850 : struct smbXsrv_session *x = session;
204 23850 : struct smbXsrv_session_auth0 *auth = *_auth;
205 23850 : struct smbXsrv_connection *xconn = smb2req->xconn;
206 649 : size_t i;
207 23850 : struct smb2_signing_derivations derivations = {
208 : .signing = NULL,
209 : };
210 23850 : DATA_BLOB preauth_hash = data_blob_null;
211 :
212 23850 : *_auth = NULL;
213 :
214 23850 : if (xconn->protocol >= PROTOCOL_SMB3_11) {
215 627 : struct smbXsrv_preauth *preauth;
216 627 : gnutls_hash_hd_t hash_hnd;
217 627 : int rc;
218 :
219 21495 : preauth = talloc_move(smb2req, &auth->preauth);
220 :
221 21495 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
222 21495 : if (rc < 0) {
223 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
224 : }
225 22122 : rc = gnutls_hash(hash_hnd,
226 21495 : preauth->sha512_value,
227 : sizeof(preauth->sha512_value));
228 21495 : if (rc < 0) {
229 0 : gnutls_hash_deinit(hash_hnd, NULL);
230 0 : return NT_STATUS_ACCESS_DENIED;
231 : }
232 107475 : for (i = 1; i < smb2req->in.vector_count; i++) {
233 88488 : rc = gnutls_hash(hash_hnd,
234 85980 : smb2req->in.vector[i].iov_base,
235 85980 : smb2req->in.vector[i].iov_len);
236 85980 : if (rc < 0) {
237 0 : gnutls_hash_deinit(hash_hnd, NULL);
238 0 : return NT_STATUS_ACCESS_DENIED;
239 : }
240 : }
241 21495 : gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
242 :
243 21495 : preauth_hash = data_blob_const(preauth->sha512_value,
244 : sizeof(preauth->sha512_value));
245 : }
246 :
247 23850 : smb2_signing_derivations_fill_const_stack(&derivations,
248 : xconn->protocol,
249 : preauth_hash);
250 :
251 23850 : if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
252 14528 : (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
253 : {
254 11404 : x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
255 : }
256 :
257 23850 : if ((lp_server_smb_encrypt(-1) >= SMB_ENCRYPTION_DESIRED) &&
258 0 : (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
259 0 : x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
260 : }
261 :
262 23850 : if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_REQUIRED) {
263 0 : x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
264 : SMBXSRV_ENCRYPTION_DESIRED;
265 : }
266 :
267 23850 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
268 933 : if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
269 22 : *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
270 : }
271 : /* force no signing */
272 933 : x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
273 : /* we map anonymous to guest internally */
274 933 : guest = true;
275 : } else {
276 : /*
277 : * Remember we got one authenticated session on the connection
278 : * in order to allow SMB3 decryption to happen
279 : * (sadly even for future anonymous connections).
280 : */
281 22917 : xconn->smb2.got_authenticated_session = true;
282 : }
283 :
284 23850 : if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
285 0 : DEBUG(1,("reject guest session as encryption is required\n"));
286 0 : return NT_STATUS_ACCESS_DENIED;
287 : }
288 :
289 23850 : if (xconn->smb2.server.cipher == 0) {
290 2501 : if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
291 0 : DEBUG(1,("reject session with dialect[0x%04X] "
292 : "as encryption is required\n",
293 : xconn->smb2.server.dialect));
294 0 : return NT_STATUS_ACCESS_DENIED;
295 : }
296 : }
297 23850 : x->global->signing_algo = xconn->smb2.server.sign_algo;
298 23850 : x->global->encryption_cipher = xconn->smb2.server.cipher;
299 23850 : if (*out_session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
300 : /*
301 : * A fallback to guest can't do any encryption
302 : */
303 22 : x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
304 : }
305 :
306 23850 : if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
307 0 : *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
308 : }
309 :
310 24499 : status = smb2_signing_key_sign_create(x->global,
311 23850 : x->global->signing_algo,
312 23850 : &session_info->session_key,
313 : derivations.signing,
314 23201 : &x->global->signing_key);
315 23850 : if (!NT_STATUS_IS_OK(status)) {
316 0 : return status;
317 : }
318 23850 : x->global->signing_key_blob = x->global->signing_key->blob;
319 :
320 23850 : if (x->global->encryption_cipher != SMB2_ENCRYPTION_NONE) {
321 635 : size_t nonce_size;
322 :
323 21962 : status = smb2_signing_key_cipher_create(x->global,
324 20692 : x->global->encryption_cipher,
325 21327 : &session_info->session_key,
326 : derivations.cipher_s2c,
327 20692 : &x->global->encryption_key);
328 21327 : if (!NT_STATUS_IS_OK(status)) {
329 0 : return status;
330 : }
331 21327 : x->global->encryption_key_blob = x->global->encryption_key->blob;
332 :
333 21962 : status = smb2_signing_key_cipher_create(x->global,
334 21327 : x->global->encryption_cipher,
335 21327 : &session_info->session_key,
336 : derivations.cipher_c2s,
337 20692 : &x->global->decryption_key);
338 21327 : if (!NT_STATUS_IS_OK(status)) {
339 0 : return status;
340 : }
341 21327 : x->global->decryption_key_blob = x->global->decryption_key->blob;
342 :
343 : /*
344 : * CCM and GCM algorithms must never have their
345 : * nonce wrap, or the security of the whole
346 : * communication and the keys is destroyed.
347 : * We must drop the connection once we have
348 : * transferred too much data.
349 : *
350 : * NOTE: We assume nonces greater than 8 bytes.
351 : */
352 21327 : generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
353 : sizeof(x->nonce_high_random));
354 21327 : switch (xconn->smb2.server.cipher) {
355 110 : case SMB2_ENCRYPTION_AES128_CCM:
356 110 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
357 110 : break;
358 21175 : case SMB2_ENCRYPTION_AES128_GCM:
359 21175 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
360 21175 : break;
361 10 : case SMB2_ENCRYPTION_AES256_CCM:
362 10 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
363 10 : break;
364 12 : case SMB2_ENCRYPTION_AES256_GCM:
365 12 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
366 12 : break;
367 0 : default:
368 0 : nonce_size = 0;
369 0 : break;
370 : }
371 21327 : x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
372 21327 : x->nonce_high = 0;
373 21327 : x->nonce_low = 0;
374 : }
375 :
376 24499 : status = smb2_signing_key_sign_create(x->global,
377 23850 : x->global->signing_algo,
378 23850 : &session_info->session_key,
379 : derivations.application,
380 23850 : &x->global->application_key);
381 23850 : if (!NT_STATUS_IS_OK(status)) {
382 0 : return status;
383 : }
384 23850 : x->global->application_key_blob = x->global->application_key->blob;
385 :
386 23850 : if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
387 0 : DEBUG(0, ("debug encryption: dumping generated session keys\n"));
388 0 : DEBUGADD(0, ("Session Id "));
389 0 : dump_data(0, (uint8_t*)&session->global->session_wire_id,
390 : sizeof(session->global->session_wire_id));
391 0 : DEBUGADD(0, ("Session Key "));
392 0 : dump_data(0, session_info->session_key.data,
393 0 : session_info->session_key.length);
394 0 : DEBUGADD(0, ("Signing Algo: %u\n", x->global->signing_algo));
395 0 : DEBUGADD(0, ("Signing Key "));
396 0 : dump_data(0, x->global->signing_key_blob.data,
397 0 : x->global->signing_key_blob.length);
398 0 : DEBUGADD(0, ("App Key "));
399 0 : dump_data(0, x->global->application_key_blob.data,
400 0 : x->global->application_key_blob.length);
401 :
402 : /* In server code, ServerIn is the decryption key */
403 :
404 0 : DEBUGADD(0, ("Cipher Algo: %u\n", x->global->encryption_cipher));
405 0 : DEBUGADD(0, ("ServerIn Key "));
406 0 : dump_data(0, x->global->decryption_key_blob.data,
407 0 : x->global->decryption_key_blob.length);
408 0 : DEBUGADD(0, ("ServerOut Key "));
409 0 : dump_data(0, x->global->encryption_key_blob.data,
410 0 : x->global->encryption_key_blob.length);
411 : }
412 :
413 24499 : status = smb2_signing_key_copy(x->global->channels,
414 23850 : x->global->signing_key,
415 23850 : &x->global->channels[0].signing_key);
416 23850 : if (!NT_STATUS_IS_OK(status)) {
417 0 : return status;
418 : }
419 23850 : x->global->channels[0].signing_key_blob =
420 23850 : x->global->channels[0].signing_key->blob;
421 23850 : x->global->channels[0].signing_algo = x->global->signing_algo;
422 23850 : x->global->channels[0].encryption_cipher = x->global->encryption_cipher;
423 :
424 23850 : data_blob_clear_free(&session_info->session_key);
425 23850 : session_info->session_key = data_blob_dup_talloc(session_info,
426 : x->global->application_key_blob);
427 23850 : if (session_info->session_key.data == NULL) {
428 0 : return NT_STATUS_NO_MEMORY;
429 : }
430 23850 : talloc_keep_secret(session_info->session_key.data);
431 :
432 23850 : smb2req->sconn->num_users++;
433 :
434 23850 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
435 23554 : session->homes_snum =
436 22917 : register_homes_share(session_info->unix_info->unix_name);
437 : }
438 :
439 23850 : set_current_user_info(session_info->unix_info->sanitized_username,
440 23850 : session_info->unix_info->unix_name,
441 23850 : session_info->info->domain_name);
442 :
443 23850 : reload_services(smb2req->sconn, conn_snum_used, true);
444 :
445 23850 : session->status = NT_STATUS_OK;
446 23850 : session->global->auth_session_info = talloc_move(session->global,
447 : &session_info);
448 23850 : session->global->auth_session_info_seqnum += 1;
449 47700 : for (i=0; i < session->global->num_channels; i++) {
450 23850 : struct smbXsrv_channel_global0 *_c =
451 23850 : &session->global->channels[i];
452 :
453 23850 : _c->auth_session_info_seqnum =
454 23201 : session->global->auth_session_info_seqnum;
455 : }
456 23850 : session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
457 23850 : session->global->expiration_time = gensec_expire_time(auth->gensec);
458 :
459 23850 : if (!session_claim(session)) {
460 0 : DEBUG(1, ("smb2: Failed to claim session "
461 : "for vuid=%llu\n",
462 : (unsigned long long)session->global->session_wire_id));
463 0 : return NT_STATUS_LOGON_FAILURE;
464 : }
465 :
466 23850 : TALLOC_FREE(auth);
467 23850 : status = smbXsrv_session_update(session);
468 23850 : if (!NT_STATUS_IS_OK(status)) {
469 0 : DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
470 : (unsigned long long)session->global->session_wire_id,
471 : nt_errstr(status)));
472 0 : return NT_STATUS_LOGON_FAILURE;
473 : }
474 :
475 : /*
476 : * we attach the session to the request
477 : * so that the response can be signed
478 : */
479 23850 : if (!guest) {
480 22917 : smb2req->do_signing = true;
481 : }
482 :
483 23850 : global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
484 :
485 23850 : *out_session_id = session->global->session_wire_id;
486 23850 : smb2req->last_session_id = session->global->session_wire_id;
487 :
488 23850 : return NT_STATUS_OK;
489 : }
490 :
491 142 : static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
492 : struct smbXsrv_session_auth0 **_auth,
493 : struct smbd_smb2_request *smb2req,
494 : struct auth_session_info *session_info,
495 : uint16_t *out_session_flags,
496 : uint64_t *out_session_id)
497 : {
498 24 : NTSTATUS status;
499 142 : struct smbXsrv_session *x = session;
500 142 : struct smbXsrv_session_auth0 *auth = *_auth;
501 142 : struct smbXsrv_connection *xconn = smb2req->xconn;
502 24 : size_t i;
503 :
504 142 : *_auth = NULL;
505 :
506 142 : data_blob_clear_free(&session_info->session_key);
507 142 : session_info->session_key = data_blob_dup_talloc(session_info,
508 : x->global->application_key_blob);
509 142 : if (session_info->session_key.data == NULL) {
510 0 : return NT_STATUS_NO_MEMORY;
511 : }
512 142 : talloc_keep_secret(session_info->session_key.data);
513 :
514 166 : session->homes_snum =
515 142 : register_homes_share(session_info->unix_info->unix_name);
516 :
517 142 : set_current_user_info(session_info->unix_info->sanitized_username,
518 142 : session_info->unix_info->unix_name,
519 142 : session_info->info->domain_name);
520 :
521 142 : reload_services(smb2req->sconn, conn_snum_used, true);
522 :
523 142 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
524 94 : smb2req->do_signing = true;
525 : }
526 :
527 142 : session->status = NT_STATUS_OK;
528 142 : TALLOC_FREE(session->global->auth_session_info);
529 142 : session->global->auth_session_info = talloc_move(session->global,
530 : &session_info);
531 142 : session->global->auth_session_info_seqnum += 1;
532 284 : for (i=0; i < session->global->num_channels; i++) {
533 142 : struct smbXsrv_channel_global0 *_c =
534 142 : &session->global->channels[i];
535 :
536 142 : _c->auth_session_info_seqnum =
537 118 : session->global->auth_session_info_seqnum;
538 : }
539 142 : session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
540 142 : session->global->expiration_time = gensec_expire_time(auth->gensec);
541 :
542 142 : TALLOC_FREE(auth);
543 142 : status = smbXsrv_session_update(session);
544 142 : if (!NT_STATUS_IS_OK(status)) {
545 0 : DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
546 : (unsigned long long)session->global->session_wire_id,
547 : nt_errstr(status)));
548 0 : return NT_STATUS_LOGON_FAILURE;
549 : }
550 :
551 142 : conn_clear_vuid_caches(xconn->client->sconn,
552 142 : session->global->session_wire_id);
553 :
554 142 : *out_session_id = session->global->session_wire_id;
555 :
556 142 : return NT_STATUS_OK;
557 : }
558 :
559 896 : static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
560 : struct smbXsrv_session_auth0 **_auth,
561 : struct smbd_smb2_request *smb2req,
562 : struct auth_session_info *session_info,
563 : uint16_t *out_session_flags,
564 : uint64_t *out_session_id)
565 : {
566 20 : NTSTATUS status;
567 896 : struct smbXsrv_session *x = session;
568 896 : struct smbXsrv_session_auth0 *auth = *_auth;
569 896 : struct smbXsrv_connection *xconn = smb2req->xconn;
570 896 : struct smbXsrv_channel_global0 *c = NULL;
571 20 : size_t i;
572 896 : struct smb2_signing_derivations derivations = {
573 : .signing = NULL,
574 : };
575 896 : DATA_BLOB preauth_hash = data_blob_null;
576 20 : bool ok;
577 :
578 896 : *_auth = NULL;
579 :
580 896 : if (xconn->protocol >= PROTOCOL_SMB3_11) {
581 20 : struct smbXsrv_preauth *preauth;
582 896 : gnutls_hash_hd_t hash_hnd = NULL;
583 20 : int rc;
584 :
585 896 : preauth = talloc_move(smb2req, &auth->preauth);
586 :
587 896 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
588 896 : if (rc < 0) {
589 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
590 : }
591 :
592 916 : rc = gnutls_hash(hash_hnd,
593 896 : preauth->sha512_value,
594 : sizeof(preauth->sha512_value));
595 896 : if (rc < 0) {
596 0 : gnutls_hash_deinit(hash_hnd, NULL);
597 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
598 : }
599 4480 : for (i = 1; i < smb2req->in.vector_count; i++) {
600 3664 : rc = gnutls_hash(hash_hnd,
601 3584 : smb2req->in.vector[i].iov_base,
602 3584 : smb2req->in.vector[i].iov_len);
603 3584 : if (rc < 0) {
604 0 : gnutls_hash_deinit(hash_hnd, NULL);
605 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
606 : }
607 : }
608 896 : gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
609 :
610 896 : preauth_hash = data_blob_const(preauth->sha512_value,
611 : sizeof(preauth->sha512_value));
612 : }
613 :
614 896 : smb2_signing_derivations_fill_const_stack(&derivations,
615 : xconn->protocol,
616 : preauth_hash);
617 :
618 896 : status = smbXsrv_session_find_channel(session, xconn, &c);
619 896 : if (!NT_STATUS_IS_OK(status)) {
620 0 : return status;
621 : }
622 :
623 916 : ok = security_token_is_sid(session_info->security_token,
624 896 : &x->global->auth_session_info->security_token->sids[0]);
625 896 : if (!ok) {
626 8 : return NT_STATUS_ACCESS_DENIED;
627 : }
628 :
629 888 : if (session_info->session_key.length == 0) {
630 : /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
631 0 : return NT_STATUS_NOT_SUPPORTED;
632 : }
633 :
634 888 : c->signing_algo = xconn->smb2.server.sign_algo;
635 888 : c->encryption_cipher = xconn->smb2.server.cipher;
636 :
637 906 : status = smb2_signing_key_sign_create(x->global->channels,
638 870 : c->signing_algo,
639 888 : &session_info->session_key,
640 : derivations.signing,
641 870 : &c->signing_key);
642 888 : if (!NT_STATUS_IS_OK(status)) {
643 0 : return status;
644 : }
645 888 : c->signing_key_blob = c->signing_key->blob;
646 :
647 888 : TALLOC_FREE(auth);
648 888 : status = smbXsrv_session_update(session);
649 888 : if (!NT_STATUS_IS_OK(status)) {
650 0 : DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
651 : (unsigned long long)session->global->session_wire_id,
652 : nt_errstr(status)));
653 0 : return NT_STATUS_LOGON_FAILURE;
654 : }
655 :
656 : /*
657 : * Remember we got one authenticated session on the connection
658 : * in order to allow SMB3 decryption to happen
659 : */
660 888 : xconn->smb2.got_authenticated_session = true;
661 :
662 888 : *out_session_id = session->global->session_wire_id;
663 :
664 888 : return NT_STATUS_OK;
665 : }
666 :
667 : struct smbd_smb2_session_setup_state {
668 : struct tevent_context *ev;
669 : struct smbd_smb2_request *smb2req;
670 : uint64_t in_session_id;
671 : uint8_t in_flags;
672 : uint8_t in_security_mode;
673 : uint64_t in_previous_session_id;
674 : DATA_BLOB in_security_buffer;
675 : struct smbXsrv_session *session;
676 : struct smbXsrv_session_auth0 *auth;
677 : struct auth_session_info *session_info;
678 : uint16_t out_session_flags;
679 : DATA_BLOB out_security_buffer;
680 : uint64_t out_session_id;
681 : };
682 :
683 : static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
684 : static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
685 : static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
686 :
687 47605 : static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
688 : struct tevent_context *ev,
689 : struct smbd_smb2_request *smb2req,
690 : uint64_t in_session_id,
691 : uint8_t in_flags,
692 : uint8_t in_security_mode,
693 : uint64_t in_previous_session_id,
694 : DATA_BLOB in_security_buffer)
695 : {
696 1151 : struct tevent_req *req;
697 1151 : struct smbd_smb2_session_setup_state *state;
698 1151 : NTSTATUS status;
699 47605 : NTTIME now = timeval_to_nttime(&smb2req->request_time);
700 1151 : struct tevent_req *subreq;
701 47605 : struct smbXsrv_channel_global0 *c = NULL;
702 1151 : enum security_user_level seclvl;
703 :
704 47605 : req = tevent_req_create(mem_ctx, &state,
705 : struct smbd_smb2_session_setup_state);
706 47605 : if (req == NULL) {
707 0 : return NULL;
708 : }
709 47605 : state->ev = ev;
710 47605 : state->smb2req = smb2req;
711 47605 : state->in_session_id = in_session_id;
712 47605 : state->in_flags = in_flags;
713 47605 : state->in_security_mode = in_security_mode;
714 47605 : state->in_previous_session_id = in_previous_session_id;
715 47605 : state->in_security_buffer = in_security_buffer;
716 :
717 47605 : if (in_flags & SMB2_SESSION_FLAG_BINDING) {
718 2264 : if (in_session_id == 0) {
719 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
720 0 : return tevent_req_post(req, ev);
721 : }
722 :
723 2264 : if (smb2req->session == NULL) {
724 0 : tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
725 0 : return tevent_req_post(req, ev);
726 : }
727 :
728 2264 : if ((smb2req->session->global->signing_algo >= SMB2_SIGNING_AES128_GMAC) &&
729 1734 : (smb2req->xconn->smb2.server.sign_algo != smb2req->session->global->signing_algo))
730 : {
731 280 : tevent_req_nterror(req, NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
732 280 : return tevent_req_post(req, ev);
733 : }
734 1984 : if ((smb2req->xconn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) &&
735 1650 : (smb2req->session->global->signing_algo != smb2req->xconn->smb2.server.sign_algo))
736 : {
737 280 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
738 280 : return tevent_req_post(req, ev);
739 : }
740 :
741 1704 : if (smb2req->xconn->protocol < PROTOCOL_SMB3_00) {
742 100 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
743 100 : return tevent_req_post(req, ev);
744 : }
745 :
746 1604 : if (!smb2req->xconn->client->server_multi_channel_enabled) {
747 0 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
748 0 : return tevent_req_post(req, ev);
749 : }
750 :
751 1604 : if (!smb2req->do_signing) {
752 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
753 0 : return tevent_req_post(req, ev);
754 : }
755 :
756 1604 : if (smb2req->session->global->connection_dialect
757 1604 : != smb2req->xconn->smb2.server.dialect)
758 : {
759 88 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
760 88 : return tevent_req_post(req, ev);
761 : }
762 :
763 1516 : if (smb2req->session->global->encryption_cipher
764 1516 : != smb2req->xconn->smb2.server.cipher)
765 : {
766 48 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
767 48 : return tevent_req_post(req, ev);
768 : }
769 :
770 1468 : status = smb2req->session->status;
771 1468 : if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
772 : /*
773 : * This comes from smb2srv_session_lookup_global().
774 : * And it's a cross node/cross smbd session bind,
775 : * which can't work in our architecture.
776 : *
777 : * Returning NT_STATUS_REQUEST_NOT_ACCEPTED is better
778 : * than NT_STATUS_USER_SESSION_DELETED in order to
779 : * avoid a completely new session.
780 : */
781 24 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
782 24 : return tevent_req_post(req, ev);
783 : }
784 :
785 1444 : status = smbXsrv_session_find_channel(smb2req->session,
786 1410 : smb2req->xconn,
787 : &c);
788 1444 : if (NT_STATUS_IS_OK(status)) {
789 534 : if (!smb2_signing_key_valid(c->signing_key)) {
790 534 : goto auth;
791 : }
792 0 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
793 0 : return tevent_req_post(req, ev);
794 : }
795 :
796 932 : seclvl = security_session_user_level(
797 910 : smb2req->session->global->auth_session_info,
798 : NULL);
799 910 : if (seclvl < SECURITY_USER) {
800 0 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
801 0 : return tevent_req_post(req, ev);
802 : }
803 :
804 910 : status = smbXsrv_session_add_channel(smb2req->session,
805 : smb2req->xconn,
806 : now,
807 : &c);
808 910 : if (tevent_req_nterror(req, status)) {
809 4 : return tevent_req_post(req, ev);
810 : }
811 :
812 906 : status = smbXsrv_session_update(smb2req->session);
813 906 : if (tevent_req_nterror(req, status)) {
814 0 : return tevent_req_post(req, ev);
815 : }
816 : }
817 :
818 46247 : auth:
819 :
820 46781 : if (state->in_session_id == 0) {
821 : /* create a new session */
822 25566 : status = smbXsrv_session_create(state->smb2req->xconn,
823 24915 : now, &state->session);
824 25566 : if (tevent_req_nterror(req, status)) {
825 0 : return tevent_req_post(req, ev);
826 : }
827 25566 : smb2req->session = state->session;
828 : } else {
829 21215 : if (smb2req->session == NULL) {
830 0 : tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
831 0 : return tevent_req_post(req, ev);
832 : }
833 :
834 21215 : state->session = smb2req->session;
835 21215 : status = state->session->status;
836 21215 : if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
837 : /*
838 : * This comes from smb2srv_session_lookup_global().
839 : */
840 592 : tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
841 592 : return tevent_req_post(req, ev);
842 : }
843 20623 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
844 30 : status = NT_STATUS_OK;
845 : }
846 20623 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
847 18806 : status = NT_STATUS_OK;
848 : }
849 20623 : if (tevent_req_nterror(req, status)) {
850 0 : return tevent_req_post(req, ev);
851 : }
852 : }
853 :
854 47090 : status = smbXsrv_session_find_channel(smb2req->session,
855 46189 : smb2req->xconn, &c);
856 46189 : if (tevent_req_nterror(req, status)) {
857 204 : return tevent_req_post(req, ev);
858 : }
859 :
860 45985 : if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
861 44545 : state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
862 : }
863 :
864 46852 : status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
865 45985 : now, &state->auth);
866 45985 : if (!NT_STATUS_IS_OK(status)) {
867 27347 : status = smbXsrv_session_create_auth(state->session,
868 : smb2req->xconn, now,
869 : in_flags, in_security_mode,
870 26645 : &state->auth);
871 26645 : if (tevent_req_nterror(req, status)) {
872 0 : return tevent_req_post(req, ev);
873 : }
874 : }
875 :
876 45985 : if (state->auth->gensec == NULL) {
877 27347 : status = auth_generic_prepare(state->auth,
878 25943 : state->smb2req->xconn->remote_address,
879 26645 : state->smb2req->xconn->local_address,
880 : "SMB2",
881 25943 : &state->auth->gensec);
882 26645 : if (tevent_req_nterror(req, status)) {
883 0 : return tevent_req_post(req, ev);
884 : }
885 :
886 26645 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
887 26645 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
888 26645 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
889 :
890 26645 : status = gensec_start_mech_by_oid(state->auth->gensec,
891 : GENSEC_OID_SPNEGO);
892 26645 : if (tevent_req_nterror(req, status)) {
893 0 : return tevent_req_post(req, ev);
894 : }
895 : }
896 :
897 45985 : status = smbXsrv_session_update(state->session);
898 45985 : if (tevent_req_nterror(req, status)) {
899 0 : return tevent_req_post(req, ev);
900 : }
901 :
902 45985 : become_root();
903 46852 : subreq = gensec_update_send(state, state->ev,
904 45985 : state->auth->gensec,
905 45985 : state->in_security_buffer);
906 45985 : unbecome_root();
907 45985 : if (tevent_req_nomem(subreq, req)) {
908 0 : return tevent_req_post(req, ev);
909 : }
910 45985 : tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
911 :
912 45985 : return req;
913 : }
914 :
915 45985 : static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
916 : {
917 867 : struct tevent_req *req =
918 45985 : tevent_req_callback_data(subreq,
919 : struct tevent_req);
920 867 : struct smbd_smb2_session_setup_state *state =
921 45985 : tevent_req_data(req,
922 : struct smbd_smb2_session_setup_state);
923 867 : NTSTATUS status;
924 :
925 45985 : become_root();
926 45985 : status = gensec_update_recv(subreq, state,
927 : &state->out_security_buffer);
928 45985 : unbecome_root();
929 45985 : TALLOC_FREE(subreq);
930 45985 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
931 26645 : !NT_STATUS_IS_OK(status)) {
932 1750 : tevent_req_nterror(req, status);
933 1750 : return;
934 : }
935 :
936 44235 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
937 19340 : state->out_session_id = state->session->global->session_wire_id;
938 19340 : state->smb2req->preauth = state->auth->preauth;
939 19340 : tevent_req_nterror(req, status);
940 19340 : return;
941 : }
942 :
943 24895 : status = gensec_session_info(state->auth->gensec,
944 : state,
945 : &state->session_info);
946 24895 : if (tevent_req_nterror(req, status)) {
947 7 : return;
948 : }
949 :
950 24888 : if ((state->in_previous_session_id != 0) &&
951 102 : (state->session->global->session_wire_id !=
952 98 : state->in_previous_session_id))
953 : {
954 106 : subreq = smb2srv_session_close_previous_send(state, state->ev,
955 102 : state->smb2req->xconn,
956 : state->session_info,
957 : state->in_previous_session_id,
958 98 : state->session->global->session_wire_id);
959 102 : if (tevent_req_nomem(subreq, req)) {
960 0 : return;
961 : }
962 102 : tevent_req_set_callback(subreq,
963 : smbd_smb2_session_setup_previous_done,
964 : req);
965 102 : return;
966 : }
967 :
968 24786 : smbd_smb2_session_setup_auth_return(req);
969 : }
970 :
971 102 : static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
972 : {
973 4 : struct tevent_req *req =
974 102 : tevent_req_callback_data(subreq,
975 : struct tevent_req);
976 4 : NTSTATUS status;
977 :
978 102 : status = smb2srv_session_close_previous_recv(subreq);
979 102 : TALLOC_FREE(subreq);
980 102 : if (tevent_req_nterror(req, status)) {
981 0 : return;
982 : }
983 :
984 102 : smbd_smb2_session_setup_auth_return(req);
985 : }
986 :
987 24888 : static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
988 : {
989 693 : struct smbd_smb2_session_setup_state *state =
990 24888 : tevent_req_data(req,
991 : struct smbd_smb2_session_setup_state);
992 693 : NTSTATUS status;
993 :
994 24888 : if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
995 896 : status = smbd_smb2_bind_auth_return(state->session,
996 : &state->auth,
997 : state->smb2req,
998 : state->session_info,
999 : &state->out_session_flags,
1000 : &state->out_session_id);
1001 896 : if (tevent_req_nterror(req, status)) {
1002 6 : return;
1003 : }
1004 888 : tevent_req_done(req);
1005 888 : return;
1006 : }
1007 :
1008 23992 : if (state->session->global->auth_session_info != NULL) {
1009 142 : status = smbd_smb2_reauth_generic_return(state->session,
1010 : &state->auth,
1011 : state->smb2req,
1012 : state->session_info,
1013 : &state->out_session_flags,
1014 : &state->out_session_id);
1015 142 : if (tevent_req_nterror(req, status)) {
1016 0 : return;
1017 : }
1018 142 : tevent_req_done(req);
1019 142 : return;
1020 : }
1021 :
1022 23850 : status = smbd_smb2_auth_generic_return(state->session,
1023 : &state->auth,
1024 : state->smb2req,
1025 23850 : state->in_security_mode,
1026 : state->session_info,
1027 : &state->out_session_flags,
1028 : &state->out_session_id);
1029 23850 : if (tevent_req_nterror(req, status)) {
1030 0 : return;
1031 : }
1032 :
1033 23850 : tevent_req_done(req);
1034 23850 : return;
1035 : }
1036 :
1037 47605 : static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1038 : uint16_t *out_session_flags,
1039 : TALLOC_CTX *mem_ctx,
1040 : DATA_BLOB *out_security_buffer,
1041 : uint64_t *out_session_id)
1042 : {
1043 1151 : struct smbd_smb2_session_setup_state *state =
1044 47605 : tevent_req_data(req,
1045 : struct smbd_smb2_session_setup_state);
1046 1151 : NTSTATUS status;
1047 :
1048 47605 : if (tevent_req_is_nterror(req, &status)) {
1049 22725 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1050 3385 : tevent_req_received(req);
1051 3385 : return nt_status_squash(status);
1052 : }
1053 : } else {
1054 24880 : status = NT_STATUS_OK;
1055 : }
1056 :
1057 44220 : *out_session_flags = state->out_session_flags;
1058 44220 : *out_security_buffer = state->out_security_buffer;
1059 44220 : *out_session_id = state->out_session_id;
1060 :
1061 44220 : talloc_steal(mem_ctx, out_security_buffer->data);
1062 44220 : tevent_req_received(req);
1063 44220 : return status;
1064 : }
1065 :
1066 : struct smbd_smb2_session_setup_wrap_state {
1067 : struct tevent_context *ev;
1068 : struct smbd_smb2_request *smb2req;
1069 : uint64_t in_session_id;
1070 : uint8_t in_flags;
1071 : uint8_t in_security_mode;
1072 : uint64_t in_previous_session_id;
1073 : DATA_BLOB in_security_buffer;
1074 : uint16_t out_session_flags;
1075 : DATA_BLOB out_security_buffer;
1076 : uint64_t out_session_id;
1077 : NTSTATUS error;
1078 : };
1079 :
1080 : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1081 : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1082 :
1083 47605 : static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1084 : struct tevent_context *ev,
1085 : struct smbd_smb2_request *smb2req,
1086 : uint64_t in_session_id,
1087 : uint8_t in_flags,
1088 : uint8_t in_security_mode,
1089 : uint64_t in_previous_session_id,
1090 : DATA_BLOB in_security_buffer)
1091 : {
1092 1151 : struct tevent_req *req;
1093 1151 : struct smbd_smb2_session_setup_wrap_state *state;
1094 1151 : struct tevent_req *subreq;
1095 :
1096 47605 : req = tevent_req_create(mem_ctx, &state,
1097 : struct smbd_smb2_session_setup_wrap_state);
1098 47605 : if (req == NULL) {
1099 0 : return NULL;
1100 : }
1101 47605 : state->ev = ev;
1102 47605 : state->smb2req = smb2req;
1103 47605 : state->in_session_id = in_session_id;
1104 47605 : state->in_flags = in_flags;
1105 47605 : state->in_security_mode = in_security_mode;
1106 47605 : state->in_previous_session_id = in_previous_session_id;
1107 47605 : state->in_security_buffer = in_security_buffer;
1108 :
1109 47605 : subreq = smbd_smb2_session_setup_send(state, state->ev,
1110 46454 : state->smb2req,
1111 46454 : state->in_session_id,
1112 46454 : state->in_flags,
1113 46454 : state->in_security_mode,
1114 46454 : state->in_previous_session_id,
1115 46454 : state->in_security_buffer);
1116 47605 : if (tevent_req_nomem(subreq, req)) {
1117 0 : return tevent_req_post(req, ev);
1118 : }
1119 47605 : tevent_req_set_callback(subreq,
1120 : smbd_smb2_session_setup_wrap_setup_done, req);
1121 :
1122 47605 : return req;
1123 : }
1124 :
1125 47605 : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1126 : {
1127 1151 : struct tevent_req *req =
1128 47605 : tevent_req_callback_data(subreq,
1129 : struct tevent_req);
1130 1151 : struct smbd_smb2_session_setup_wrap_state *state =
1131 47605 : tevent_req_data(req,
1132 : struct smbd_smb2_session_setup_wrap_state);
1133 1151 : NTSTATUS status;
1134 :
1135 47605 : status = smbd_smb2_session_setup_recv(subreq,
1136 : &state->out_session_flags,
1137 : state,
1138 : &state->out_security_buffer,
1139 : &state->out_session_id);
1140 47605 : TALLOC_FREE(subreq);
1141 47605 : if (NT_STATUS_IS_OK(status)) {
1142 24880 : tevent_req_done(req);
1143 45405 : return;
1144 : }
1145 22725 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1146 19340 : tevent_req_nterror(req, status);
1147 19340 : return;
1148 : }
1149 :
1150 3385 : if (state->smb2req->session == NULL) {
1151 0 : tevent_req_nterror(req, status);
1152 0 : return;
1153 : }
1154 :
1155 3385 : state->error = status;
1156 :
1157 3385 : if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1158 842 : status = smbXsrv_session_remove_channel(state->smb2req->session,
1159 694 : state->smb2req->xconn);
1160 842 : if (tevent_req_nterror(req, status)) {
1161 0 : return;
1162 : }
1163 842 : tevent_req_nterror(req, state->error);
1164 842 : return;
1165 : }
1166 :
1167 2543 : if (NT_STATUS_EQUAL(state->error, NT_STATUS_USER_SESSION_DELETED)) {
1168 796 : tevent_req_nterror(req, state->error);
1169 796 : return;
1170 : }
1171 :
1172 1747 : subreq = smb2srv_session_shutdown_send(state, state->ev,
1173 1740 : state->smb2req->session,
1174 : state->smb2req);
1175 1747 : if (tevent_req_nomem(subreq, req)) {
1176 0 : return;
1177 : }
1178 1747 : tevent_req_set_callback(subreq,
1179 : smbd_smb2_session_setup_wrap_shutdown_done,
1180 : req);
1181 : }
1182 :
1183 1747 : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1184 : {
1185 7 : struct tevent_req *req =
1186 1747 : tevent_req_callback_data(subreq,
1187 : struct tevent_req);
1188 7 : struct smbd_smb2_session_setup_wrap_state *state =
1189 1747 : tevent_req_data(req,
1190 : struct smbd_smb2_session_setup_wrap_state);
1191 7 : NTSTATUS status;
1192 :
1193 1747 : status = smb2srv_session_shutdown_recv(subreq);
1194 1747 : TALLOC_FREE(subreq);
1195 1747 : if (tevent_req_nterror(req, status)) {
1196 0 : return;
1197 : }
1198 :
1199 : /*
1200 : * we may need to sign the response, so we need to keep
1201 : * the session until the response is sent to the wire.
1202 : */
1203 1747 : talloc_steal(state->smb2req, state->smb2req->session);
1204 :
1205 1747 : tevent_req_nterror(req, state->error);
1206 : }
1207 :
1208 47605 : static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1209 : uint16_t *out_session_flags,
1210 : TALLOC_CTX *mem_ctx,
1211 : DATA_BLOB *out_security_buffer,
1212 : uint64_t *out_session_id)
1213 : {
1214 1151 : struct smbd_smb2_session_setup_wrap_state *state =
1215 47605 : tevent_req_data(req,
1216 : struct smbd_smb2_session_setup_wrap_state);
1217 1151 : NTSTATUS status;
1218 :
1219 47605 : if (tevent_req_is_nterror(req, &status)) {
1220 22725 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1221 3385 : tevent_req_received(req);
1222 3385 : return nt_status_squash(status);
1223 : }
1224 : } else {
1225 24880 : status = NT_STATUS_OK;
1226 : }
1227 :
1228 44220 : *out_session_flags = state->out_session_flags;
1229 44220 : *out_security_buffer = state->out_security_buffer;
1230 44220 : *out_session_id = state->out_session_id;
1231 :
1232 44220 : talloc_steal(mem_ctx, out_security_buffer->data);
1233 44220 : tevent_req_received(req);
1234 44220 : return status;
1235 : }
1236 :
1237 : static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1238 : struct tevent_context *ev,
1239 : struct smbd_smb2_request *smb2req);
1240 : static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1241 : static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1242 :
1243 159 : NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1244 : {
1245 6 : NTSTATUS status;
1246 159 : struct tevent_req *subreq = NULL;
1247 :
1248 159 : status = smbd_smb2_request_verify_sizes(req, 0x04);
1249 159 : if (!NT_STATUS_IS_OK(status)) {
1250 0 : return smbd_smb2_request_error(req, status);
1251 : }
1252 :
1253 159 : subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1254 159 : if (subreq == NULL) {
1255 0 : return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1256 : }
1257 159 : tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1258 :
1259 : /*
1260 : * Avoid sending a STATUS_PENDING message, it's very likely
1261 : * the client won't expect that.
1262 : */
1263 159 : return smbd_smb2_request_pending_queue(req, subreq, 0);
1264 : }
1265 :
1266 159 : static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1267 : {
1268 6 : struct smbd_smb2_request *smb2req =
1269 159 : tevent_req_callback_data(subreq,
1270 : struct smbd_smb2_request);
1271 6 : DATA_BLOB outbody;
1272 6 : NTSTATUS status;
1273 6 : NTSTATUS error;
1274 :
1275 165 : status = smbd_smb2_logoff_recv(subreq);
1276 159 : TALLOC_FREE(subreq);
1277 159 : if (!NT_STATUS_IS_OK(status)) {
1278 0 : error = smbd_smb2_request_error(smb2req, status);
1279 0 : if (!NT_STATUS_IS_OK(error)) {
1280 0 : smbd_server_connection_terminate(smb2req->xconn,
1281 : nt_errstr(error));
1282 0 : return;
1283 : }
1284 0 : return;
1285 : }
1286 :
1287 159 : outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1288 159 : if (outbody.data == NULL) {
1289 0 : error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1290 0 : if (!NT_STATUS_IS_OK(error)) {
1291 0 : smbd_server_connection_terminate(smb2req->xconn,
1292 : nt_errstr(error));
1293 0 : return;
1294 : }
1295 0 : return;
1296 : }
1297 :
1298 159 : SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1299 159 : SSVAL(outbody.data, 0x02, 0); /* reserved */
1300 :
1301 159 : error = smbd_smb2_request_done(smb2req, outbody, NULL);
1302 159 : if (!NT_STATUS_IS_OK(error)) {
1303 0 : smbd_server_connection_terminate(smb2req->xconn,
1304 : nt_errstr(error));
1305 0 : return;
1306 : }
1307 : }
1308 :
1309 : struct smbd_smb2_logoff_state {
1310 : struct smbd_smb2_request *smb2req;
1311 : };
1312 :
1313 : static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1314 :
1315 159 : static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1316 : struct tevent_context *ev,
1317 : struct smbd_smb2_request *smb2req)
1318 : {
1319 6 : struct tevent_req *req;
1320 6 : struct smbd_smb2_logoff_state *state;
1321 6 : struct tevent_req *subreq;
1322 :
1323 159 : req = tevent_req_create(mem_ctx, &state,
1324 : struct smbd_smb2_logoff_state);
1325 159 : if (req == NULL) {
1326 0 : return NULL;
1327 : }
1328 159 : state->smb2req = smb2req;
1329 :
1330 159 : subreq = smb2srv_session_shutdown_send(state, ev,
1331 : smb2req->session,
1332 : smb2req);
1333 159 : if (tevent_req_nomem(subreq, req)) {
1334 0 : return tevent_req_post(req, ev);
1335 : }
1336 159 : tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1337 :
1338 159 : return req;
1339 : }
1340 :
1341 159 : static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1342 : {
1343 159 : struct tevent_req *req = tevent_req_callback_data(
1344 : subreq, struct tevent_req);
1345 159 : struct smbd_smb2_logoff_state *state = tevent_req_data(
1346 : req, struct smbd_smb2_logoff_state);
1347 6 : NTSTATUS status;
1348 6 : bool ok;
1349 159 : const struct GUID *client_guid =
1350 159 : &state->smb2req->session->client->global->client_guid;
1351 :
1352 159 : status = smb2srv_session_shutdown_recv(subreq);
1353 159 : if (tevent_req_nterror(req, status)) {
1354 0 : return;
1355 : }
1356 159 : TALLOC_FREE(subreq);
1357 :
1358 159 : if (!GUID_all_zero(client_guid)) {
1359 147 : ok = remote_arch_cache_delete(client_guid);
1360 147 : if (!ok) {
1361 : /* Most likely not an error, but not in cache */
1362 135 : DBG_DEBUG("Deletion from remote arch cache failed\n");
1363 : }
1364 : }
1365 :
1366 : /*
1367 : * As we've been awoken, we may have changed
1368 : * uid in the meantime. Ensure we're still
1369 : * root (SMB2_OP_LOGOFF has .as_root = true).
1370 : */
1371 159 : change_to_root_user();
1372 :
1373 159 : status = smbXsrv_session_logoff(state->smb2req->session);
1374 159 : if (tevent_req_nterror(req, status)) {
1375 0 : return;
1376 : }
1377 :
1378 : /*
1379 : * we may need to sign the response, so we need to keep
1380 : * the session until the response is sent to the wire.
1381 : */
1382 159 : talloc_steal(state->smb2req, state->smb2req->session);
1383 :
1384 159 : tevent_req_done(req);
1385 : }
1386 :
1387 159 : static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1388 : {
1389 159 : return tevent_req_simple_recv_ntstatus(req);
1390 : }
|