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