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 46331 : NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
57 : {
58 1110 : const uint8_t *inhdr;
59 1110 : const uint8_t *inbody;
60 1110 : uint64_t in_session_id;
61 1110 : uint8_t in_flags;
62 1110 : uint8_t in_security_mode;
63 1110 : uint64_t in_previous_session_id;
64 1110 : uint16_t in_security_offset;
65 1110 : uint16_t in_security_length;
66 1110 : DATA_BLOB in_security_buffer;
67 1110 : NTSTATUS status;
68 1110 : struct tevent_req *subreq;
69 :
70 46331 : status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
71 46331 : if (!NT_STATUS_IS_OK(status)) {
72 0 : return smbd_smb2_request_error(smb2req, status);
73 : }
74 46331 : inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
75 46331 : inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
76 :
77 46331 : in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
78 :
79 46331 : in_flags = CVAL(inbody, 0x02);
80 46331 : in_security_mode = CVAL(inbody, 0x03);
81 : /* Capabilities = IVAL(inbody, 0x04) */
82 : /* Channel = IVAL(inbody, 0x08) */
83 46331 : in_security_offset = SVAL(inbody, 0x0C);
84 46331 : in_security_length = SVAL(inbody, 0x0E);
85 46331 : in_previous_session_id = BVAL(inbody, 0x10);
86 :
87 46331 : 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 46331 : 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 46331 : in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
96 46331 : in_security_buffer.length = in_security_length;
97 :
98 47441 : subreq = smbd_smb2_session_setup_wrap_send(smb2req,
99 46331 : 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 46331 : if (subreq == NULL) {
107 0 : return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
108 : }
109 46331 : 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 46331 : return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
121 : }
122 :
123 46331 : static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
124 : {
125 1110 : struct smbd_smb2_request *smb2req =
126 46331 : tevent_req_callback_data(subreq,
127 : struct smbd_smb2_request);
128 1110 : uint8_t *outhdr;
129 1110 : DATA_BLOB outbody;
130 1110 : DATA_BLOB outdyn;
131 46331 : uint16_t out_session_flags = 0;
132 46331 : uint64_t out_session_id = 0;
133 1110 : uint16_t out_security_offset;
134 46331 : DATA_BLOB out_security_buffer = data_blob_null;
135 1110 : NTSTATUS status;
136 1110 : NTSTATUS error; /* transport error */
137 :
138 46331 : status = smbd_smb2_session_setup_wrap_recv(subreq,
139 : &out_session_flags,
140 : smb2req,
141 : &out_security_buffer,
142 : &out_session_id);
143 46331 : TALLOC_FREE(subreq);
144 46331 : if (!NT_STATUS_IS_OK(status) &&
145 21583 : !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
146 3424 : status = nt_status_squash(status);
147 3424 : error = smbd_smb2_request_error(smb2req, status);
148 3424 : if (!NT_STATUS_IS_OK(error)) {
149 0 : smbd_server_connection_terminate(smb2req->xconn,
150 : nt_errstr(error));
151 3129 : return;
152 : }
153 3129 : return;
154 : }
155 :
156 42907 : out_security_offset = SMB2_HDR_BODY + 0x08;
157 :
158 42907 : outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
159 :
160 42907 : outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
161 42907 : 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 42907 : SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
172 :
173 42907 : SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
174 42907 : SSVAL(outbody.data, 0x02,
175 : out_session_flags); /* session flags */
176 42907 : SSVAL(outbody.data, 0x04,
177 : out_security_offset); /* security buffer offset */
178 42907 : SSVAL(outbody.data, 0x06,
179 : out_security_buffer.length); /* security buffer length */
180 :
181 42907 : outdyn = out_security_buffer;
182 :
183 42907 : error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
184 : __location__);
185 42907 : 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 23275 : 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 625 : NTSTATUS status;
201 23275 : bool guest = false;
202 23275 : struct smbXsrv_session *x = session;
203 23275 : struct smbXsrv_session_auth0 *auth = *_auth;
204 23275 : struct smbXsrv_connection *xconn = smb2req->xconn;
205 625 : size_t i;
206 23275 : struct smb2_signing_derivations derivations = {
207 : .signing = NULL,
208 : };
209 23275 : DATA_BLOB preauth_hash = data_blob_null;
210 :
211 23275 : *_auth = NULL;
212 :
213 23275 : if (xconn->protocol >= PROTOCOL_SMB3_11) {
214 603 : struct smbXsrv_preauth *preauth;
215 603 : gnutls_hash_hd_t hash_hnd;
216 603 : int rc;
217 :
218 20742 : preauth = talloc_move(smb2req, &auth->preauth);
219 :
220 20742 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
221 20742 : if (rc < 0) {
222 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
223 : }
224 21345 : rc = gnutls_hash(hash_hnd,
225 20742 : preauth->sha512_value,
226 : sizeof(preauth->sha512_value));
227 20742 : if (rc < 0) {
228 0 : gnutls_hash_deinit(hash_hnd, NULL);
229 0 : return NT_STATUS_ACCESS_DENIED;
230 : }
231 103710 : for (i = 1; i < smb2req->in.vector_count; i++) {
232 85380 : rc = gnutls_hash(hash_hnd,
233 82968 : smb2req->in.vector[i].iov_base,
234 82968 : smb2req->in.vector[i].iov_len);
235 82968 : if (rc < 0) {
236 0 : gnutls_hash_deinit(hash_hnd, NULL);
237 0 : return NT_STATUS_ACCESS_DENIED;
238 : }
239 : }
240 20742 : gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
241 :
242 20742 : preauth_hash = data_blob_const(preauth->sha512_value,
243 : sizeof(preauth->sha512_value));
244 : }
245 :
246 23275 : smb2_signing_derivations_fill_const_stack(&derivations,
247 : xconn->protocol,
248 : preauth_hash);
249 :
250 23275 : if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
251 13899 : (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
252 : {
253 11414 : x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
254 : }
255 :
256 23275 : 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 23275 : 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 23275 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
267 735 : if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
268 22 : *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
269 : }
270 : /* force no signing */
271 735 : x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
272 : /* we map anonymous to guest internally */
273 735 : guest = true;
274 : }
275 :
276 22652 : 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 23275 : if (xconn->smb2.server.cipher == 0) {
282 2679 : 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 23275 : x->global->signing_algo = xconn->smb2.server.sign_algo;
290 23275 : x->global->encryption_cipher = xconn->smb2.server.cipher;
291 23275 : if (guest) {
292 735 : x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
293 : }
294 :
295 23275 : if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
296 0 : *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
297 : }
298 :
299 23900 : status = smb2_signing_key_sign_create(x->global,
300 23275 : x->global->signing_algo,
301 23275 : &session_info->session_key,
302 : derivations.signing,
303 22650 : &x->global->signing_key);
304 23275 : if (!NT_STATUS_IS_OK(status)) {
305 0 : return status;
306 : }
307 23275 : x->global->signing_key_blob = x->global->signing_key->blob;
308 :
309 23275 : if (x->global->encryption_cipher != SMB2_ENCRYPTION_NONE) {
310 609 : size_t nonce_size;
311 :
312 20542 : status = smb2_signing_key_cipher_create(x->global,
313 19324 : x->global->encryption_cipher,
314 19933 : &session_info->session_key,
315 : derivations.cipher_s2c,
316 19324 : &x->global->encryption_key);
317 19933 : if (!NT_STATUS_IS_OK(status)) {
318 0 : return status;
319 : }
320 19933 : x->global->encryption_key_blob = x->global->encryption_key->blob;
321 :
322 20542 : status = smb2_signing_key_cipher_create(x->global,
323 19933 : x->global->encryption_cipher,
324 19933 : &session_info->session_key,
325 : derivations.cipher_c2s,
326 19324 : &x->global->decryption_key);
327 19933 : if (!NT_STATUS_IS_OK(status)) {
328 0 : return status;
329 : }
330 19933 : 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 : * transferred too much data.
338 : *
339 : * NOTE: We assume nonces greater than 8 bytes.
340 : */
341 19933 : generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
342 : sizeof(x->nonce_high_random));
343 19933 : switch (xconn->smb2.server.cipher) {
344 110 : case SMB2_ENCRYPTION_AES128_CCM:
345 110 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
346 110 : break;
347 19781 : case SMB2_ENCRYPTION_AES128_GCM:
348 19781 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
349 19781 : break;
350 10 : case SMB2_ENCRYPTION_AES256_CCM:
351 10 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
352 10 : break;
353 12 : case SMB2_ENCRYPTION_AES256_GCM:
354 12 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
355 12 : break;
356 0 : default:
357 0 : nonce_size = 0;
358 0 : break;
359 : }
360 19933 : x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
361 19933 : x->nonce_high = 0;
362 19933 : x->nonce_low = 0;
363 : }
364 :
365 23900 : status = smb2_signing_key_sign_create(x->global,
366 23275 : x->global->signing_algo,
367 23275 : &session_info->session_key,
368 : derivations.application,
369 23275 : &x->global->application_key);
370 23275 : if (!NT_STATUS_IS_OK(status)) {
371 0 : return status;
372 : }
373 23275 : x->global->application_key_blob = x->global->application_key->blob;
374 :
375 23275 : 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 23900 : status = smb2_signing_key_copy(x->global->channels,
403 23275 : x->global->signing_key,
404 23275 : &x->global->channels[0].signing_key);
405 23275 : if (!NT_STATUS_IS_OK(status)) {
406 0 : return status;
407 : }
408 23275 : x->global->channels[0].signing_key_blob =
409 23275 : x->global->channels[0].signing_key->blob;
410 23275 : x->global->channels[0].signing_algo = x->global->signing_algo;
411 23275 : x->global->channels[0].encryption_cipher = x->global->encryption_cipher;
412 :
413 23275 : data_blob_clear_free(&session_info->session_key);
414 23275 : session_info->session_key = data_blob_dup_talloc(session_info,
415 : x->global->application_key_blob);
416 23275 : if (session_info->session_key.data == NULL) {
417 0 : return NT_STATUS_NO_MEMORY;
418 : }
419 23275 : talloc_keep_secret(session_info->session_key.data);
420 :
421 23275 : smb2req->sconn->num_users++;
422 :
423 23275 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
424 23163 : session->homes_snum =
425 22540 : register_homes_share(session_info->unix_info->unix_name);
426 : }
427 :
428 23275 : set_current_user_info(session_info->unix_info->sanitized_username,
429 23275 : session_info->unix_info->unix_name,
430 23275 : session_info->info->domain_name);
431 :
432 23275 : reload_services(smb2req->sconn, conn_snum_used, true);
433 :
434 23275 : session->status = NT_STATUS_OK;
435 23275 : session->global->auth_session_info = talloc_move(session->global,
436 : &session_info);
437 23275 : session->global->auth_session_info_seqnum += 1;
438 46550 : for (i=0; i < session->global->num_channels; i++) {
439 23275 : struct smbXsrv_channel_global0 *_c =
440 23275 : &session->global->channels[i];
441 :
442 23275 : _c->auth_session_info_seqnum =
443 22650 : session->global->auth_session_info_seqnum;
444 : }
445 23275 : session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
446 23275 : session->global->expiration_time = gensec_expire_time(auth->gensec);
447 :
448 23275 : 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 23275 : TALLOC_FREE(auth);
456 23275 : status = smbXsrv_session_update(session);
457 23275 : 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 23275 : if (!guest) {
469 22540 : smb2req->do_signing = true;
470 : }
471 :
472 23275 : global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
473 :
474 23275 : *out_session_id = session->global->session_wire_id;
475 23275 : smb2req->last_session_id = session->global->session_wire_id;
476 :
477 23275 : return NT_STATUS_OK;
478 : }
479 :
480 142 : 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 24 : NTSTATUS status;
488 142 : struct smbXsrv_session *x = session;
489 142 : struct smbXsrv_session_auth0 *auth = *_auth;
490 142 : struct smbXsrv_connection *xconn = smb2req->xconn;
491 24 : size_t i;
492 :
493 142 : *_auth = NULL;
494 :
495 142 : data_blob_clear_free(&session_info->session_key);
496 142 : session_info->session_key = data_blob_dup_talloc(session_info,
497 : x->global->application_key_blob);
498 142 : if (session_info->session_key.data == NULL) {
499 0 : return NT_STATUS_NO_MEMORY;
500 : }
501 142 : talloc_keep_secret(session_info->session_key.data);
502 :
503 166 : session->homes_snum =
504 142 : register_homes_share(session_info->unix_info->unix_name);
505 :
506 142 : set_current_user_info(session_info->unix_info->sanitized_username,
507 142 : session_info->unix_info->unix_name,
508 142 : session_info->info->domain_name);
509 :
510 142 : reload_services(smb2req->sconn, conn_snum_used, true);
511 :
512 142 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
513 94 : smb2req->do_signing = true;
514 : }
515 :
516 142 : session->status = NT_STATUS_OK;
517 142 : TALLOC_FREE(session->global->auth_session_info);
518 142 : session->global->auth_session_info = talloc_move(session->global,
519 : &session_info);
520 142 : session->global->auth_session_info_seqnum += 1;
521 284 : for (i=0; i < session->global->num_channels; i++) {
522 142 : struct smbXsrv_channel_global0 *_c =
523 142 : &session->global->channels[i];
524 :
525 142 : _c->auth_session_info_seqnum =
526 118 : session->global->auth_session_info_seqnum;
527 : }
528 142 : session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
529 142 : session->global->expiration_time = gensec_expire_time(auth->gensec);
530 :
531 142 : TALLOC_FREE(auth);
532 142 : status = smbXsrv_session_update(session);
533 142 : 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 142 : conn_clear_vuid_caches(xconn->client->sconn,
541 142 : session->global->session_wire_id);
542 :
543 142 : *out_session_id = session->global->session_wire_id;
544 :
545 142 : return NT_STATUS_OK;
546 : }
547 :
548 896 : 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 20 : NTSTATUS status;
556 896 : struct smbXsrv_session *x = session;
557 896 : struct smbXsrv_session_auth0 *auth = *_auth;
558 896 : struct smbXsrv_connection *xconn = smb2req->xconn;
559 896 : struct smbXsrv_channel_global0 *c = NULL;
560 20 : size_t i;
561 896 : struct smb2_signing_derivations derivations = {
562 : .signing = NULL,
563 : };
564 896 : DATA_BLOB preauth_hash = data_blob_null;
565 20 : bool ok;
566 :
567 896 : *_auth = NULL;
568 :
569 896 : if (xconn->protocol >= PROTOCOL_SMB3_11) {
570 20 : struct smbXsrv_preauth *preauth;
571 896 : gnutls_hash_hd_t hash_hnd = NULL;
572 20 : int rc;
573 :
574 896 : preauth = talloc_move(smb2req, &auth->preauth);
575 :
576 896 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
577 896 : if (rc < 0) {
578 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
579 : }
580 :
581 916 : rc = gnutls_hash(hash_hnd,
582 896 : preauth->sha512_value,
583 : sizeof(preauth->sha512_value));
584 896 : 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 4480 : for (i = 1; i < smb2req->in.vector_count; i++) {
589 3664 : rc = gnutls_hash(hash_hnd,
590 3584 : smb2req->in.vector[i].iov_base,
591 3584 : smb2req->in.vector[i].iov_len);
592 3584 : 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 896 : gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
598 :
599 896 : preauth_hash = data_blob_const(preauth->sha512_value,
600 : sizeof(preauth->sha512_value));
601 : }
602 :
603 896 : smb2_signing_derivations_fill_const_stack(&derivations,
604 : xconn->protocol,
605 : preauth_hash);
606 :
607 896 : status = smbXsrv_session_find_channel(session, xconn, &c);
608 896 : if (!NT_STATUS_IS_OK(status)) {
609 0 : return status;
610 : }
611 :
612 916 : ok = security_token_is_sid(session_info->security_token,
613 896 : &x->global->auth_session_info->security_token->sids[0]);
614 896 : if (!ok) {
615 8 : return NT_STATUS_ACCESS_DENIED;
616 : }
617 :
618 888 : 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 888 : c->signing_algo = xconn->smb2.server.sign_algo;
624 888 : c->encryption_cipher = xconn->smb2.server.cipher;
625 :
626 906 : status = smb2_signing_key_sign_create(x->global->channels,
627 870 : c->signing_algo,
628 888 : &session_info->session_key,
629 : derivations.signing,
630 870 : &c->signing_key);
631 888 : if (!NT_STATUS_IS_OK(status)) {
632 0 : return status;
633 : }
634 888 : c->signing_key_blob = c->signing_key->blob;
635 :
636 888 : TALLOC_FREE(auth);
637 888 : status = smbXsrv_session_update(session);
638 888 : 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 888 : *out_session_id = session->global->session_wire_id;
646 :
647 888 : 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 46331 : 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 1110 : struct tevent_req *req;
680 1110 : struct smbd_smb2_session_setup_state *state;
681 1110 : NTSTATUS status;
682 46331 : NTTIME now = timeval_to_nttime(&smb2req->request_time);
683 1110 : struct tevent_req *subreq;
684 46331 : struct smbXsrv_channel_global0 *c = NULL;
685 1110 : enum security_user_level seclvl;
686 :
687 46331 : req = tevent_req_create(mem_ctx, &state,
688 : struct smbd_smb2_session_setup_state);
689 46331 : if (req == NULL) {
690 0 : return NULL;
691 : }
692 46331 : state->ev = ev;
693 46331 : state->smb2req = smb2req;
694 46331 : state->in_session_id = in_session_id;
695 46331 : state->in_flags = in_flags;
696 46331 : state->in_security_mode = in_security_mode;
697 46331 : state->in_previous_session_id = in_previous_session_id;
698 46331 : state->in_security_buffer = in_security_buffer;
699 :
700 46331 : if (in_flags & SMB2_SESSION_FLAG_BINDING) {
701 2264 : 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 2264 : 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 2264 : if ((smb2req->session->global->signing_algo >= SMB2_SIGNING_AES128_GMAC) &&
712 1734 : (smb2req->xconn->smb2.server.sign_algo != smb2req->session->global->signing_algo))
713 : {
714 280 : tevent_req_nterror(req, NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
715 280 : return tevent_req_post(req, ev);
716 : }
717 1984 : if ((smb2req->xconn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) &&
718 1650 : (smb2req->session->global->signing_algo != smb2req->xconn->smb2.server.sign_algo))
719 : {
720 280 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
721 280 : return tevent_req_post(req, ev);
722 : }
723 :
724 1704 : if (smb2req->xconn->protocol < PROTOCOL_SMB3_00) {
725 100 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
726 100 : return tevent_req_post(req, ev);
727 : }
728 :
729 1604 : 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 1604 : 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 1604 : if (smb2req->session->global->connection_dialect
740 1604 : != smb2req->xconn->smb2.server.dialect)
741 : {
742 88 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
743 88 : return tevent_req_post(req, ev);
744 : }
745 :
746 1516 : if (smb2req->session->global->encryption_cipher
747 1516 : != smb2req->xconn->smb2.server.cipher)
748 : {
749 48 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
750 48 : return tevent_req_post(req, ev);
751 : }
752 :
753 1468 : status = smb2req->session->status;
754 1468 : if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
755 : /*
756 : * This comes from smb2srv_session_lookup_global().
757 : * And it's a cross node/cross smbd session bind,
758 : * which can't work in our architecture.
759 : *
760 : * Returning NT_STATUS_REQUEST_NOT_ACCEPTED is better
761 : * than NT_STATUS_USER_SESSION_DELETED in order to
762 : * avoid a completely new session.
763 : */
764 24 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
765 24 : return tevent_req_post(req, ev);
766 : }
767 :
768 1444 : status = smbXsrv_session_find_channel(smb2req->session,
769 1410 : smb2req->xconn,
770 : &c);
771 1444 : if (NT_STATUS_IS_OK(status)) {
772 534 : if (!smb2_signing_key_valid(c->signing_key)) {
773 534 : goto auth;
774 : }
775 0 : tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
776 0 : return tevent_req_post(req, ev);
777 : }
778 :
779 932 : seclvl = security_session_user_level(
780 910 : smb2req->session->global->auth_session_info,
781 : NULL);
782 910 : if (seclvl < SECURITY_USER) {
783 0 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
784 0 : return tevent_req_post(req, ev);
785 : }
786 :
787 910 : status = smbXsrv_session_add_channel(smb2req->session,
788 : smb2req->xconn,
789 : now,
790 : &c);
791 910 : if (tevent_req_nterror(req, status)) {
792 4 : return tevent_req_post(req, ev);
793 : }
794 :
795 906 : status = smbXsrv_session_update(smb2req->session);
796 906 : if (tevent_req_nterror(req, status)) {
797 0 : return tevent_req_post(req, ev);
798 : }
799 : }
800 :
801 44973 : auth:
802 :
803 45507 : if (state->in_session_id == 0) {
804 : /* create a new session */
805 25030 : status = smbXsrv_session_create(state->smb2req->xconn,
806 24403 : now, &state->session);
807 25030 : if (tevent_req_nterror(req, status)) {
808 0 : return tevent_req_post(req, ev);
809 : }
810 25030 : smb2req->session = state->session;
811 : } else {
812 20477 : if (smb2req->session == NULL) {
813 0 : tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
814 0 : return tevent_req_post(req, ev);
815 : }
816 :
817 20477 : state->session = smb2req->session;
818 20477 : status = state->session->status;
819 20477 : if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
820 : /*
821 : * This comes from smb2srv_session_lookup_global().
822 : */
823 592 : tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
824 592 : return tevent_req_post(req, ev);
825 : }
826 19885 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
827 30 : status = NT_STATUS_OK;
828 : }
829 19885 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
830 18068 : status = NT_STATUS_OK;
831 : }
832 19885 : if (tevent_req_nterror(req, status)) {
833 0 : return tevent_req_post(req, ev);
834 : }
835 : }
836 :
837 45775 : status = smbXsrv_session_find_channel(smb2req->session,
838 44915 : smb2req->xconn, &c);
839 44915 : if (tevent_req_nterror(req, status)) {
840 204 : return tevent_req_post(req, ev);
841 : }
842 :
843 44711 : if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
844 43271 : state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
845 : }
846 :
847 45537 : status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
848 44711 : now, &state->auth);
849 44711 : if (!NT_STATUS_IS_OK(status)) {
850 26787 : status = smbXsrv_session_create_auth(state->session,
851 : smb2req->xconn, now,
852 : in_flags, in_security_mode,
853 26109 : &state->auth);
854 26109 : if (tevent_req_nterror(req, status)) {
855 0 : return tevent_req_post(req, ev);
856 : }
857 : }
858 :
859 44711 : if (state->auth->gensec == NULL) {
860 26787 : status = auth_generic_prepare(state->auth,
861 25431 : state->smb2req->xconn->remote_address,
862 26109 : state->smb2req->xconn->local_address,
863 : "SMB2",
864 25431 : &state->auth->gensec);
865 26109 : if (tevent_req_nterror(req, status)) {
866 0 : return tevent_req_post(req, ev);
867 : }
868 :
869 26109 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
870 26109 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
871 26109 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
872 :
873 26109 : status = gensec_start_mech_by_oid(state->auth->gensec,
874 : GENSEC_OID_SPNEGO);
875 26109 : if (tevent_req_nterror(req, status)) {
876 0 : return tevent_req_post(req, ev);
877 : }
878 : }
879 :
880 44711 : status = smbXsrv_session_update(state->session);
881 44711 : if (tevent_req_nterror(req, status)) {
882 0 : return tevent_req_post(req, ev);
883 : }
884 :
885 44711 : become_root();
886 45537 : subreq = gensec_update_send(state, state->ev,
887 44711 : state->auth->gensec,
888 44711 : state->in_security_buffer);
889 44711 : unbecome_root();
890 44711 : if (tevent_req_nomem(subreq, req)) {
891 0 : return tevent_req_post(req, ev);
892 : }
893 44711 : tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
894 :
895 44711 : return req;
896 : }
897 :
898 44711 : static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
899 : {
900 826 : struct tevent_req *req =
901 44711 : tevent_req_callback_data(subreq,
902 : struct tevent_req);
903 826 : struct smbd_smb2_session_setup_state *state =
904 44711 : tevent_req_data(req,
905 : struct smbd_smb2_session_setup_state);
906 826 : NTSTATUS status;
907 :
908 44711 : become_root();
909 44711 : status = gensec_update_recv(subreq, state,
910 : &state->out_security_buffer);
911 44711 : unbecome_root();
912 44711 : TALLOC_FREE(subreq);
913 44711 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
914 26109 : !NT_STATUS_IS_OK(status)) {
915 1789 : tevent_req_nterror(req, status);
916 1789 : return;
917 : }
918 :
919 42922 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
920 18602 : state->out_session_id = state->session->global->session_wire_id;
921 18602 : state->smb2req->preauth = state->auth->preauth;
922 18602 : tevent_req_nterror(req, status);
923 18602 : return;
924 : }
925 :
926 24320 : status = gensec_session_info(state->auth->gensec,
927 : state,
928 : &state->session_info);
929 24320 : if (tevent_req_nterror(req, status)) {
930 7 : return;
931 : }
932 :
933 24313 : if ((state->in_previous_session_id != 0) &&
934 102 : (state->session->global->session_wire_id !=
935 98 : state->in_previous_session_id))
936 : {
937 106 : subreq = smb2srv_session_close_previous_send(state, state->ev,
938 102 : state->smb2req->xconn,
939 : state->session_info,
940 : state->in_previous_session_id,
941 98 : state->session->global->session_wire_id);
942 102 : if (tevent_req_nomem(subreq, req)) {
943 0 : return;
944 : }
945 102 : tevent_req_set_callback(subreq,
946 : smbd_smb2_session_setup_previous_done,
947 : req);
948 102 : return;
949 : }
950 :
951 24211 : smbd_smb2_session_setup_auth_return(req);
952 : }
953 :
954 102 : static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
955 : {
956 4 : struct tevent_req *req =
957 102 : tevent_req_callback_data(subreq,
958 : struct tevent_req);
959 4 : NTSTATUS status;
960 :
961 102 : status = smb2srv_session_close_previous_recv(subreq);
962 102 : TALLOC_FREE(subreq);
963 102 : if (tevent_req_nterror(req, status)) {
964 0 : return;
965 : }
966 :
967 102 : smbd_smb2_session_setup_auth_return(req);
968 : }
969 :
970 24313 : static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
971 : {
972 669 : struct smbd_smb2_session_setup_state *state =
973 24313 : tevent_req_data(req,
974 : struct smbd_smb2_session_setup_state);
975 669 : NTSTATUS status;
976 :
977 24313 : if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
978 896 : status = smbd_smb2_bind_auth_return(state->session,
979 : &state->auth,
980 : state->smb2req,
981 : state->session_info,
982 : &state->out_session_flags,
983 : &state->out_session_id);
984 896 : if (tevent_req_nterror(req, status)) {
985 6 : return;
986 : }
987 888 : tevent_req_done(req);
988 888 : return;
989 : }
990 :
991 23417 : if (state->session->global->auth_session_info != NULL) {
992 142 : status = smbd_smb2_reauth_generic_return(state->session,
993 : &state->auth,
994 : state->smb2req,
995 : state->session_info,
996 : &state->out_session_flags,
997 : &state->out_session_id);
998 142 : if (tevent_req_nterror(req, status)) {
999 0 : return;
1000 : }
1001 142 : tevent_req_done(req);
1002 142 : return;
1003 : }
1004 :
1005 23275 : status = smbd_smb2_auth_generic_return(state->session,
1006 : &state->auth,
1007 : state->smb2req,
1008 23275 : state->in_security_mode,
1009 : state->session_info,
1010 : &state->out_session_flags,
1011 : &state->out_session_id);
1012 23275 : if (tevent_req_nterror(req, status)) {
1013 0 : return;
1014 : }
1015 :
1016 23275 : tevent_req_done(req);
1017 23275 : return;
1018 : }
1019 :
1020 46331 : static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1021 : uint16_t *out_session_flags,
1022 : TALLOC_CTX *mem_ctx,
1023 : DATA_BLOB *out_security_buffer,
1024 : uint64_t *out_session_id)
1025 : {
1026 1110 : struct smbd_smb2_session_setup_state *state =
1027 46331 : tevent_req_data(req,
1028 : struct smbd_smb2_session_setup_state);
1029 1110 : NTSTATUS status;
1030 :
1031 46331 : if (tevent_req_is_nterror(req, &status)) {
1032 22026 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1033 3424 : tevent_req_received(req);
1034 3424 : return nt_status_squash(status);
1035 : }
1036 : } else {
1037 24305 : status = NT_STATUS_OK;
1038 : }
1039 :
1040 42907 : *out_session_flags = state->out_session_flags;
1041 42907 : *out_security_buffer = state->out_security_buffer;
1042 42907 : *out_session_id = state->out_session_id;
1043 :
1044 42907 : talloc_steal(mem_ctx, out_security_buffer->data);
1045 42907 : tevent_req_received(req);
1046 42907 : return status;
1047 : }
1048 :
1049 : struct smbd_smb2_session_setup_wrap_state {
1050 : struct tevent_context *ev;
1051 : struct smbd_smb2_request *smb2req;
1052 : uint64_t in_session_id;
1053 : uint8_t in_flags;
1054 : uint8_t in_security_mode;
1055 : uint64_t in_previous_session_id;
1056 : DATA_BLOB in_security_buffer;
1057 : uint16_t out_session_flags;
1058 : DATA_BLOB out_security_buffer;
1059 : uint64_t out_session_id;
1060 : NTSTATUS error;
1061 : };
1062 :
1063 : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1064 : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1065 :
1066 46331 : static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
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 : {
1075 1110 : struct tevent_req *req;
1076 1110 : struct smbd_smb2_session_setup_wrap_state *state;
1077 1110 : struct tevent_req *subreq;
1078 :
1079 46331 : req = tevent_req_create(mem_ctx, &state,
1080 : struct smbd_smb2_session_setup_wrap_state);
1081 46331 : if (req == NULL) {
1082 0 : return NULL;
1083 : }
1084 46331 : state->ev = ev;
1085 46331 : state->smb2req = smb2req;
1086 46331 : state->in_session_id = in_session_id;
1087 46331 : state->in_flags = in_flags;
1088 46331 : state->in_security_mode = in_security_mode;
1089 46331 : state->in_previous_session_id = in_previous_session_id;
1090 46331 : state->in_security_buffer = in_security_buffer;
1091 :
1092 46331 : subreq = smbd_smb2_session_setup_send(state, state->ev,
1093 45221 : state->smb2req,
1094 45221 : state->in_session_id,
1095 45221 : state->in_flags,
1096 45221 : state->in_security_mode,
1097 45221 : state->in_previous_session_id,
1098 45221 : state->in_security_buffer);
1099 46331 : if (tevent_req_nomem(subreq, req)) {
1100 0 : return tevent_req_post(req, ev);
1101 : }
1102 46331 : tevent_req_set_callback(subreq,
1103 : smbd_smb2_session_setup_wrap_setup_done, req);
1104 :
1105 46331 : return req;
1106 : }
1107 :
1108 46331 : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1109 : {
1110 1110 : struct tevent_req *req =
1111 46331 : tevent_req_callback_data(subreq,
1112 : struct tevent_req);
1113 1110 : struct smbd_smb2_session_setup_wrap_state *state =
1114 46331 : tevent_req_data(req,
1115 : struct smbd_smb2_session_setup_wrap_state);
1116 1110 : NTSTATUS status;
1117 :
1118 46331 : status = smbd_smb2_session_setup_recv(subreq,
1119 : &state->out_session_flags,
1120 : state,
1121 : &state->out_security_buffer,
1122 : &state->out_session_id);
1123 46331 : TALLOC_FREE(subreq);
1124 46331 : if (NT_STATUS_IS_OK(status)) {
1125 24305 : tevent_req_done(req);
1126 44109 : return;
1127 : }
1128 22026 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1129 18602 : tevent_req_nterror(req, status);
1130 18602 : return;
1131 : }
1132 :
1133 3424 : if (state->smb2req->session == NULL) {
1134 0 : tevent_req_nterror(req, status);
1135 0 : return;
1136 : }
1137 :
1138 3424 : state->error = status;
1139 :
1140 3424 : if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1141 842 : status = smbXsrv_session_remove_channel(state->smb2req->session,
1142 694 : state->smb2req->xconn);
1143 842 : if (tevent_req_nterror(req, status)) {
1144 0 : return;
1145 : }
1146 842 : tevent_req_nterror(req, state->error);
1147 842 : return;
1148 : }
1149 :
1150 2582 : if (NT_STATUS_EQUAL(state->error, NT_STATUS_USER_SESSION_DELETED)) {
1151 796 : tevent_req_nterror(req, state->error);
1152 796 : return;
1153 : }
1154 :
1155 1786 : subreq = smb2srv_session_shutdown_send(state, state->ev,
1156 1779 : state->smb2req->session,
1157 : state->smb2req);
1158 1786 : if (tevent_req_nomem(subreq, req)) {
1159 0 : return;
1160 : }
1161 1786 : tevent_req_set_callback(subreq,
1162 : smbd_smb2_session_setup_wrap_shutdown_done,
1163 : req);
1164 : }
1165 :
1166 1786 : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1167 : {
1168 7 : struct tevent_req *req =
1169 1786 : tevent_req_callback_data(subreq,
1170 : struct tevent_req);
1171 7 : struct smbd_smb2_session_setup_wrap_state *state =
1172 1786 : tevent_req_data(req,
1173 : struct smbd_smb2_session_setup_wrap_state);
1174 7 : NTSTATUS status;
1175 :
1176 1786 : status = smb2srv_session_shutdown_recv(subreq);
1177 1786 : TALLOC_FREE(subreq);
1178 1786 : if (tevent_req_nterror(req, status)) {
1179 0 : return;
1180 : }
1181 :
1182 : /*
1183 : * we may need to sign the response, so we need to keep
1184 : * the session until the response is sent to the wire.
1185 : */
1186 1786 : talloc_steal(state->smb2req, state->smb2req->session);
1187 :
1188 1786 : tevent_req_nterror(req, state->error);
1189 : }
1190 :
1191 46331 : static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1192 : uint16_t *out_session_flags,
1193 : TALLOC_CTX *mem_ctx,
1194 : DATA_BLOB *out_security_buffer,
1195 : uint64_t *out_session_id)
1196 : {
1197 1110 : struct smbd_smb2_session_setup_wrap_state *state =
1198 46331 : tevent_req_data(req,
1199 : struct smbd_smb2_session_setup_wrap_state);
1200 1110 : NTSTATUS status;
1201 :
1202 46331 : if (tevent_req_is_nterror(req, &status)) {
1203 22026 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1204 3424 : tevent_req_received(req);
1205 3424 : return nt_status_squash(status);
1206 : }
1207 : } else {
1208 24305 : status = NT_STATUS_OK;
1209 : }
1210 :
1211 42907 : *out_session_flags = state->out_session_flags;
1212 42907 : *out_security_buffer = state->out_security_buffer;
1213 42907 : *out_session_id = state->out_session_id;
1214 :
1215 42907 : talloc_steal(mem_ctx, out_security_buffer->data);
1216 42907 : tevent_req_received(req);
1217 42907 : return status;
1218 : }
1219 :
1220 : static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1221 : struct tevent_context *ev,
1222 : struct smbd_smb2_request *smb2req);
1223 : static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1224 : static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1225 :
1226 159 : NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1227 : {
1228 6 : NTSTATUS status;
1229 159 : struct tevent_req *subreq = NULL;
1230 :
1231 159 : status = smbd_smb2_request_verify_sizes(req, 0x04);
1232 159 : if (!NT_STATUS_IS_OK(status)) {
1233 0 : return smbd_smb2_request_error(req, status);
1234 : }
1235 :
1236 159 : subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1237 159 : if (subreq == NULL) {
1238 0 : return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1239 : }
1240 159 : tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1241 :
1242 : /*
1243 : * Avoid sending a STATUS_PENDING message, it's very likely
1244 : * the client won't expect that.
1245 : */
1246 159 : return smbd_smb2_request_pending_queue(req, subreq, 0);
1247 : }
1248 :
1249 159 : static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1250 : {
1251 6 : struct smbd_smb2_request *smb2req =
1252 159 : tevent_req_callback_data(subreq,
1253 : struct smbd_smb2_request);
1254 6 : DATA_BLOB outbody;
1255 6 : NTSTATUS status;
1256 6 : NTSTATUS error;
1257 :
1258 165 : status = smbd_smb2_logoff_recv(subreq);
1259 159 : TALLOC_FREE(subreq);
1260 159 : if (!NT_STATUS_IS_OK(status)) {
1261 0 : error = smbd_smb2_request_error(smb2req, status);
1262 0 : if (!NT_STATUS_IS_OK(error)) {
1263 0 : smbd_server_connection_terminate(smb2req->xconn,
1264 : nt_errstr(error));
1265 0 : return;
1266 : }
1267 0 : return;
1268 : }
1269 :
1270 159 : outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1271 159 : if (outbody.data == NULL) {
1272 0 : error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1273 0 : if (!NT_STATUS_IS_OK(error)) {
1274 0 : smbd_server_connection_terminate(smb2req->xconn,
1275 : nt_errstr(error));
1276 0 : return;
1277 : }
1278 0 : return;
1279 : }
1280 :
1281 159 : SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1282 159 : SSVAL(outbody.data, 0x02, 0); /* reserved */
1283 :
1284 159 : error = smbd_smb2_request_done(smb2req, outbody, NULL);
1285 159 : if (!NT_STATUS_IS_OK(error)) {
1286 0 : smbd_server_connection_terminate(smb2req->xconn,
1287 : nt_errstr(error));
1288 0 : return;
1289 : }
1290 : }
1291 :
1292 : struct smbd_smb2_logoff_state {
1293 : struct smbd_smb2_request *smb2req;
1294 : };
1295 :
1296 : static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1297 :
1298 159 : static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1299 : struct tevent_context *ev,
1300 : struct smbd_smb2_request *smb2req)
1301 : {
1302 6 : struct tevent_req *req;
1303 6 : struct smbd_smb2_logoff_state *state;
1304 6 : struct tevent_req *subreq;
1305 :
1306 159 : req = tevent_req_create(mem_ctx, &state,
1307 : struct smbd_smb2_logoff_state);
1308 159 : if (req == NULL) {
1309 0 : return NULL;
1310 : }
1311 159 : state->smb2req = smb2req;
1312 :
1313 159 : subreq = smb2srv_session_shutdown_send(state, ev,
1314 : smb2req->session,
1315 : smb2req);
1316 159 : if (tevent_req_nomem(subreq, req)) {
1317 0 : return tevent_req_post(req, ev);
1318 : }
1319 159 : tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1320 :
1321 159 : return req;
1322 : }
1323 :
1324 159 : static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1325 : {
1326 159 : struct tevent_req *req = tevent_req_callback_data(
1327 : subreq, struct tevent_req);
1328 159 : struct smbd_smb2_logoff_state *state = tevent_req_data(
1329 : req, struct smbd_smb2_logoff_state);
1330 6 : NTSTATUS status;
1331 6 : bool ok;
1332 159 : const struct GUID *client_guid =
1333 159 : &state->smb2req->session->client->global->client_guid;
1334 :
1335 159 : status = smb2srv_session_shutdown_recv(subreq);
1336 159 : if (tevent_req_nterror(req, status)) {
1337 0 : return;
1338 : }
1339 159 : TALLOC_FREE(subreq);
1340 :
1341 159 : if (!GUID_all_zero(client_guid)) {
1342 147 : ok = remote_arch_cache_delete(client_guid);
1343 147 : if (!ok) {
1344 : /* Most likely not an error, but not in cache */
1345 135 : DBG_DEBUG("Deletion from remote arch cache failed\n");
1346 : }
1347 : }
1348 :
1349 : /*
1350 : * As we've been awoken, we may have changed
1351 : * uid in the meantime. Ensure we're still
1352 : * root (SMB2_OP_LOGOFF has .as_root = true).
1353 : */
1354 159 : change_to_root_user();
1355 :
1356 159 : status = smbXsrv_session_logoff(state->smb2req->session);
1357 159 : if (tevent_req_nterror(req, status)) {
1358 0 : return;
1359 : }
1360 :
1361 : /*
1362 : * we may need to sign the response, so we need to keep
1363 : * the session until the response is sent to the wire.
1364 : */
1365 159 : talloc_steal(state->smb2req, state->smb2req->session);
1366 :
1367 159 : tevent_req_done(req);
1368 : }
1369 :
1370 159 : static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1371 : {
1372 159 : return tevent_req_simple_recv_ntstatus(req);
1373 : }
|