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 47649 : 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 47649 : status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
71 47649 : if (!NT_STATUS_IS_OK(status)) {
72 0 : return smbd_smb2_request_error(smb2req, status);
73 : }
74 47649 : inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
75 47649 : inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
76 :
77 47649 : in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
78 :
79 47649 : in_flags = CVAL(inbody, 0x02);
80 47649 : in_security_mode = CVAL(inbody, 0x03);
81 : /* Capabilities = IVAL(inbody, 0x04) */
82 : /* Channel = IVAL(inbody, 0x08) */
83 47649 : in_security_offset = SVAL(inbody, 0x0C);
84 47649 : in_security_length = SVAL(inbody, 0x0E);
85 47649 : in_previous_session_id = BVAL(inbody, 0x10);
86 :
87 47649 : 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 47649 : 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 47649 : in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
96 47649 : in_security_buffer.length = in_security_length;
97 :
98 48759 : subreq = smbd_smb2_session_setup_wrap_send(smb2req,
99 47649 : 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 47649 : if (subreq == NULL) {
107 0 : return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
108 : }
109 47649 : 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 47649 : return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
121 : }
122 :
123 47649 : static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
124 : {
125 1110 : struct smbd_smb2_request *smb2req =
126 47649 : 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 47649 : uint16_t out_session_flags = 0;
132 47649 : uint64_t out_session_id = 0;
133 1110 : uint16_t out_security_offset;
134 47649 : DATA_BLOB out_security_buffer = data_blob_null;
135 1110 : NTSTATUS status;
136 1110 : NTSTATUS error; /* transport error */
137 :
138 47649 : status = smbd_smb2_session_setup_wrap_recv(subreq,
139 : &out_session_flags,
140 : smb2req,
141 : &out_security_buffer,
142 : &out_session_id);
143 47649 : TALLOC_FREE(subreq);
144 47649 : if (!NT_STATUS_IS_OK(status) &&
145 22847 : !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
146 3959 : status = nt_status_squash(status);
147 3959 : error = smbd_smb2_request_error(smb2req, status);
148 3959 : if (!NT_STATUS_IS_OK(error)) {
149 0 : smbd_server_connection_terminate(smb2req->xconn,
150 : nt_errstr(error));
151 3664 : return;
152 : }
153 3664 : return;
154 : }
155 :
156 43690 : out_security_offset = SMB2_HDR_BODY + 0x08;
157 :
158 43690 : outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
159 :
160 43690 : outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
161 43690 : 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 43690 : SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
172 :
173 43690 : SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
174 43690 : SSVAL(outbody.data, 0x02,
175 : out_session_flags); /* session flags */
176 43690 : SSVAL(outbody.data, 0x04,
177 : out_security_offset); /* security buffer offset */
178 43690 : SSVAL(outbody.data, 0x06,
179 : out_security_buffer.length); /* security buffer length */
180 :
181 43690 : outdyn = out_security_buffer;
182 :
183 43690 : error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
184 : __location__);
185 43690 : 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 23298 : 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 23298 : bool guest = false;
202 23298 : struct smbXsrv_session *x = session;
203 23298 : struct smbXsrv_session_auth0 *auth = *_auth;
204 23298 : struct smbXsrv_connection *xconn = smb2req->xconn;
205 625 : size_t i;
206 23298 : struct smb2_signing_derivations derivations = {
207 : .signing = NULL,
208 : };
209 23298 : DATA_BLOB preauth_hash = data_blob_null;
210 :
211 23298 : *_auth = NULL;
212 :
213 23298 : 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 20751 : preauth = talloc_move(smb2req, &auth->preauth);
219 :
220 20751 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
221 20751 : if (rc < 0) {
222 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
223 : }
224 21354 : rc = gnutls_hash(hash_hnd,
225 20751 : preauth->sha512_value,
226 : sizeof(preauth->sha512_value));
227 20751 : if (rc < 0) {
228 0 : gnutls_hash_deinit(hash_hnd, NULL);
229 0 : return NT_STATUS_ACCESS_DENIED;
230 : }
231 103755 : for (i = 1; i < smb2req->in.vector_count; i++) {
232 85416 : rc = gnutls_hash(hash_hnd,
233 83004 : smb2req->in.vector[i].iov_base,
234 83004 : smb2req->in.vector[i].iov_len);
235 83004 : if (rc < 0) {
236 0 : gnutls_hash_deinit(hash_hnd, NULL);
237 0 : return NT_STATUS_ACCESS_DENIED;
238 : }
239 : }
240 20751 : gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
241 :
242 20751 : preauth_hash = data_blob_const(preauth->sha512_value,
243 : sizeof(preauth->sha512_value));
244 : }
245 :
246 23298 : smb2_signing_derivations_fill_const_stack(&derivations,
247 : xconn->protocol,
248 : preauth_hash);
249 :
250 23298 : if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
251 14057 : (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
252 : {
253 11283 : x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
254 : }
255 :
256 23298 : 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 23298 : 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 23298 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
267 747 : 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 747 : x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
272 : /* we map anonymous to guest internally */
273 747 : guest = true;
274 : }
275 :
276 22675 : 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 23298 : if (xconn->smb2.server.cipher == 0) {
282 2693 : 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 23298 : x->global->signing_algo = xconn->smb2.server.sign_algo;
290 23298 : x->global->encryption_cipher = xconn->smb2.server.cipher;
291 23298 : if (guest) {
292 747 : x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
293 : }
294 :
295 23298 : if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
296 0 : *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
297 : }
298 :
299 23923 : status = smb2_signing_key_sign_create(x->global,
300 23298 : x->global->signing_algo,
301 23298 : &session_info->session_key,
302 : derivations.signing,
303 22673 : &x->global->signing_key);
304 23298 : if (!NT_STATUS_IS_OK(status)) {
305 0 : return status;
306 : }
307 23298 : x->global->signing_key_blob = x->global->signing_key->blob;
308 :
309 23298 : if (x->global->encryption_cipher != SMB2_ENCRYPTION_NONE) {
310 609 : size_t nonce_size;
311 :
312 20547 : status = smb2_signing_key_cipher_create(x->global,
313 19329 : x->global->encryption_cipher,
314 19938 : &session_info->session_key,
315 : derivations.cipher_s2c,
316 19329 : &x->global->encryption_key);
317 19938 : if (!NT_STATUS_IS_OK(status)) {
318 0 : return status;
319 : }
320 19938 : x->global->encryption_key_blob = x->global->encryption_key->blob;
321 :
322 20547 : status = smb2_signing_key_cipher_create(x->global,
323 19938 : x->global->encryption_cipher,
324 19938 : &session_info->session_key,
325 : derivations.cipher_c2s,
326 19329 : &x->global->decryption_key);
327 19938 : if (!NT_STATUS_IS_OK(status)) {
328 0 : return status;
329 : }
330 19938 : 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 19938 : generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
342 : sizeof(x->nonce_high_random));
343 19938 : 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 19786 : case SMB2_ENCRYPTION_AES128_GCM:
348 19786 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
349 19786 : 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 19938 : x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
361 19938 : x->nonce_high = 0;
362 19938 : x->nonce_low = 0;
363 : }
364 :
365 23923 : status = smb2_signing_key_sign_create(x->global,
366 23298 : x->global->signing_algo,
367 23298 : &session_info->session_key,
368 : derivations.application,
369 23298 : &x->global->application_key);
370 23298 : if (!NT_STATUS_IS_OK(status)) {
371 0 : return status;
372 : }
373 23298 : x->global->application_key_blob = x->global->application_key->blob;
374 :
375 23298 : 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 23923 : status = smb2_signing_key_copy(x->global->channels,
403 23298 : x->global->signing_key,
404 23298 : &x->global->channels[0].signing_key);
405 23298 : if (!NT_STATUS_IS_OK(status)) {
406 0 : return status;
407 : }
408 23298 : x->global->channels[0].signing_key_blob =
409 23298 : x->global->channels[0].signing_key->blob;
410 23298 : x->global->channels[0].signing_algo = x->global->signing_algo;
411 23298 : x->global->channels[0].encryption_cipher = x->global->encryption_cipher;
412 :
413 23298 : data_blob_clear_free(&session_info->session_key);
414 23298 : session_info->session_key = data_blob_dup_talloc(session_info,
415 : x->global->application_key_blob);
416 23298 : if (session_info->session_key.data == NULL) {
417 0 : return NT_STATUS_NO_MEMORY;
418 : }
419 23298 : talloc_keep_secret(session_info->session_key.data);
420 :
421 23298 : smb2req->sconn->num_users++;
422 :
423 23298 : if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
424 23174 : session->homes_snum =
425 22551 : register_homes_share(session_info->unix_info->unix_name);
426 : }
427 :
428 23298 : set_current_user_info(session_info->unix_info->sanitized_username,
429 23298 : session_info->unix_info->unix_name,
430 23298 : session_info->info->domain_name);
431 :
432 23298 : reload_services(smb2req->sconn, conn_snum_used, true);
433 :
434 23298 : session->status = NT_STATUS_OK;
435 23298 : session->global->auth_session_info = talloc_move(session->global,
436 : &session_info);
437 23298 : session->global->auth_session_info_seqnum += 1;
438 46596 : for (i=0; i < session->global->num_channels; i++) {
439 23298 : struct smbXsrv_channel_global0 *_c =
440 23298 : &session->global->channels[i];
441 :
442 23298 : _c->auth_session_info_seqnum =
443 22673 : session->global->auth_session_info_seqnum;
444 : }
445 23298 : session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
446 23298 : session->global->expiration_time = gensec_expire_time(auth->gensec);
447 :
448 23298 : 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 23298 : TALLOC_FREE(auth);
456 23298 : status = smbXsrv_session_update(session);
457 23298 : 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 23298 : if (!guest) {
469 22551 : smb2req->do_signing = true;
470 : }
471 :
472 23298 : global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
473 :
474 23298 : *out_session_id = session->global->session_wire_id;
475 23298 : smb2req->last_session_id = session->global->session_wire_id;
476 :
477 23298 : 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 927 : 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 927 : struct smbXsrv_session *x = session;
557 927 : struct smbXsrv_session_auth0 *auth = *_auth;
558 927 : struct smbXsrv_connection *xconn = smb2req->xconn;
559 927 : struct smbXsrv_channel_global0 *c = NULL;
560 20 : size_t i;
561 927 : struct smb2_signing_derivations derivations = {
562 : .signing = NULL,
563 : };
564 927 : DATA_BLOB preauth_hash = data_blob_null;
565 20 : bool ok;
566 :
567 927 : *_auth = NULL;
568 :
569 927 : if (xconn->protocol >= PROTOCOL_SMB3_11) {
570 20 : struct smbXsrv_preauth *preauth;
571 927 : gnutls_hash_hd_t hash_hnd = NULL;
572 20 : int rc;
573 :
574 927 : preauth = talloc_move(smb2req, &auth->preauth);
575 :
576 927 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
577 927 : if (rc < 0) {
578 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
579 : }
580 :
581 947 : rc = gnutls_hash(hash_hnd,
582 927 : preauth->sha512_value,
583 : sizeof(preauth->sha512_value));
584 927 : 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 4635 : for (i = 1; i < smb2req->in.vector_count; i++) {
589 3788 : rc = gnutls_hash(hash_hnd,
590 3708 : smb2req->in.vector[i].iov_base,
591 3708 : smb2req->in.vector[i].iov_len);
592 3708 : 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 927 : gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
598 :
599 927 : preauth_hash = data_blob_const(preauth->sha512_value,
600 : sizeof(preauth->sha512_value));
601 : }
602 :
603 927 : smb2_signing_derivations_fill_const_stack(&derivations,
604 : xconn->protocol,
605 : preauth_hash);
606 :
607 927 : status = smbXsrv_session_find_channel(session, xconn, &c);
608 927 : if (!NT_STATUS_IS_OK(status)) {
609 0 : return status;
610 : }
611 :
612 947 : ok = security_token_is_sid(session_info->security_token,
613 927 : &x->global->auth_session_info->security_token->sids[0]);
614 927 : if (!ok) {
615 8 : return NT_STATUS_ACCESS_DENIED;
616 : }
617 :
618 919 : 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 919 : c->signing_algo = xconn->smb2.server.sign_algo;
624 919 : c->encryption_cipher = xconn->smb2.server.cipher;
625 :
626 937 : status = smb2_signing_key_sign_create(x->global->channels,
627 901 : c->signing_algo,
628 919 : &session_info->session_key,
629 : derivations.signing,
630 901 : &c->signing_key);
631 919 : if (!NT_STATUS_IS_OK(status)) {
632 0 : return status;
633 : }
634 919 : c->signing_key_blob = c->signing_key->blob;
635 :
636 919 : TALLOC_FREE(auth);
637 919 : status = smbXsrv_session_update(session);
638 919 : 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 919 : *out_session_id = session->global->session_wire_id;
646 :
647 919 : 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 47649 : 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 47649 : NTTIME now = timeval_to_nttime(&smb2req->request_time);
683 1110 : struct tevent_req *subreq;
684 47649 : struct smbXsrv_channel_global0 *c = NULL;
685 1110 : enum security_user_level seclvl;
686 :
687 47649 : req = tevent_req_create(mem_ctx, &state,
688 : struct smbd_smb2_session_setup_state);
689 47649 : if (req == NULL) {
690 0 : return NULL;
691 : }
692 47649 : state->ev = ev;
693 47649 : state->smb2req = smb2req;
694 47649 : state->in_session_id = in_session_id;
695 47649 : state->in_flags = in_flags;
696 47649 : state->in_security_mode = in_security_mode;
697 47649 : state->in_previous_session_id = in_previous_session_id;
698 47649 : state->in_security_buffer = in_security_buffer;
699 :
700 47649 : if (in_flags & SMB2_SESSION_FLAG_BINDING) {
701 2326 : 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 2326 : 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 2326 : if ((smb2req->session->global->signing_algo >= SMB2_SIGNING_AES128_GMAC) &&
712 1796 : (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 2046 : if ((smb2req->xconn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) &&
718 1712 : (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 1766 : 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 1666 : 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 1666 : 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 1666 : if (smb2req->session->global->connection_dialect
740 1666 : != 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 1578 : if (smb2req->session->global->encryption_cipher
747 1578 : != 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 1530 : status = smb2req->session->status;
754 1530 : 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 1506 : status = smbXsrv_session_find_channel(smb2req->session,
769 1472 : smb2req->xconn,
770 : &c);
771 1506 : if (NT_STATUS_IS_OK(status)) {
772 565 : if (!smb2_signing_key_valid(c->signing_key)) {
773 565 : 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 963 : seclvl = security_session_user_level(
780 941 : smb2req->session->global->auth_session_info,
781 : NULL);
782 941 : 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 941 : status = smbXsrv_session_add_channel(smb2req->session,
788 : smb2req->xconn,
789 : now,
790 : &c);
791 941 : if (tevent_req_nterror(req, status)) {
792 4 : return tevent_req_post(req, ev);
793 : }
794 :
795 937 : status = smbXsrv_session_update(smb2req->session);
796 937 : if (tevent_req_nterror(req, status)) {
797 0 : return tevent_req_post(req, ev);
798 : }
799 : }
800 :
801 46260 : auth:
802 :
803 46825 : if (state->in_session_id == 0) {
804 : /* create a new session */
805 25588 : status = smbXsrv_session_create(state->smb2req->xconn,
806 24961 : now, &state->session);
807 25588 : if (tevent_req_nterror(req, status)) {
808 0 : return tevent_req_post(req, ev);
809 : }
810 25588 : smb2req->session = state->session;
811 : } else {
812 21237 : 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 21237 : state->session = smb2req->session;
818 21237 : status = state->session->status;
819 21237 : 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 20645 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
827 30 : status = NT_STATUS_OK;
828 : }
829 20645 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
830 18766 : status = NT_STATUS_OK;
831 : }
832 20645 : if (tevent_req_nterror(req, status)) {
833 0 : return tevent_req_post(req, ev);
834 : }
835 : }
836 :
837 47093 : status = smbXsrv_session_find_channel(smb2req->session,
838 46233 : smb2req->xconn, &c);
839 46233 : if (tevent_req_nterror(req, status)) {
840 204 : return tevent_req_post(req, ev);
841 : }
842 :
843 46029 : if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
844 44527 : state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
845 : }
846 :
847 46855 : status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
848 46029 : now, &state->auth);
849 46029 : if (!NT_STATUS_IS_OK(status)) {
850 27376 : status = smbXsrv_session_create_auth(state->session,
851 : smb2req->xconn, now,
852 : in_flags, in_security_mode,
853 26698 : &state->auth);
854 26698 : if (tevent_req_nterror(req, status)) {
855 0 : return tevent_req_post(req, ev);
856 : }
857 : }
858 :
859 46029 : if (state->auth->gensec == NULL) {
860 27376 : status = auth_generic_prepare(state->auth,
861 26020 : state->smb2req->xconn->remote_address,
862 26698 : state->smb2req->xconn->local_address,
863 : "SMB2",
864 26020 : &state->auth->gensec);
865 26698 : if (tevent_req_nterror(req, status)) {
866 0 : return tevent_req_post(req, ev);
867 : }
868 :
869 26698 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
870 26698 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
871 26698 : gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
872 :
873 26698 : status = gensec_start_mech_by_oid(state->auth->gensec,
874 : GENSEC_OID_SPNEGO);
875 26698 : if (tevent_req_nterror(req, status)) {
876 0 : return tevent_req_post(req, ev);
877 : }
878 : }
879 :
880 46029 : status = smbXsrv_session_update(state->session);
881 46029 : if (tevent_req_nterror(req, status)) {
882 0 : return tevent_req_post(req, ev);
883 : }
884 :
885 46029 : become_root();
886 46855 : subreq = gensec_update_send(state, state->ev,
887 46029 : state->auth->gensec,
888 46029 : state->in_security_buffer);
889 46029 : unbecome_root();
890 46029 : if (tevent_req_nomem(subreq, req)) {
891 0 : return tevent_req_post(req, ev);
892 : }
893 46029 : tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
894 :
895 46029 : return req;
896 : }
897 :
898 46029 : static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
899 : {
900 826 : struct tevent_req *req =
901 46029 : tevent_req_callback_data(subreq,
902 : struct tevent_req);
903 826 : struct smbd_smb2_session_setup_state *state =
904 46029 : tevent_req_data(req,
905 : struct smbd_smb2_session_setup_state);
906 826 : NTSTATUS status;
907 :
908 46029 : become_root();
909 46029 : status = gensec_update_recv(subreq, state,
910 : &state->out_security_buffer);
911 46029 : unbecome_root();
912 46029 : TALLOC_FREE(subreq);
913 46029 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
914 26698 : !NT_STATUS_IS_OK(status)) {
915 2324 : tevent_req_nterror(req, status);
916 2324 : return;
917 : }
918 :
919 43705 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
920 19331 : state->out_session_id = state->session->global->session_wire_id;
921 19331 : state->smb2req->preauth = state->auth->preauth;
922 19331 : tevent_req_nterror(req, status);
923 19331 : return;
924 : }
925 :
926 24374 : status = gensec_session_info(state->auth->gensec,
927 : state,
928 : &state->session_info);
929 24374 : if (tevent_req_nterror(req, status)) {
930 7 : return;
931 : }
932 :
933 24367 : 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 24265 : 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 24367 : static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
971 : {
972 669 : struct smbd_smb2_session_setup_state *state =
973 24367 : tevent_req_data(req,
974 : struct smbd_smb2_session_setup_state);
975 669 : NTSTATUS status;
976 :
977 24367 : if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
978 927 : 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 927 : if (tevent_req_nterror(req, status)) {
985 6 : return;
986 : }
987 919 : tevent_req_done(req);
988 919 : return;
989 : }
990 :
991 23440 : 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 23298 : status = smbd_smb2_auth_generic_return(state->session,
1006 : &state->auth,
1007 : state->smb2req,
1008 23298 : state->in_security_mode,
1009 : state->session_info,
1010 : &state->out_session_flags,
1011 : &state->out_session_id);
1012 23298 : if (tevent_req_nterror(req, status)) {
1013 0 : return;
1014 : }
1015 :
1016 23298 : tevent_req_done(req);
1017 23298 : return;
1018 : }
1019 :
1020 47649 : 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 47649 : tevent_req_data(req,
1028 : struct smbd_smb2_session_setup_state);
1029 1110 : NTSTATUS status;
1030 :
1031 47649 : if (tevent_req_is_nterror(req, &status)) {
1032 23290 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1033 3959 : tevent_req_received(req);
1034 3959 : return nt_status_squash(status);
1035 : }
1036 : } else {
1037 24359 : status = NT_STATUS_OK;
1038 : }
1039 :
1040 43690 : *out_session_flags = state->out_session_flags;
1041 43690 : *out_security_buffer = state->out_security_buffer;
1042 43690 : *out_session_id = state->out_session_id;
1043 :
1044 43690 : talloc_steal(mem_ctx, out_security_buffer->data);
1045 43690 : tevent_req_received(req);
1046 43690 : 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 47649 : 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 47649 : req = tevent_req_create(mem_ctx, &state,
1080 : struct smbd_smb2_session_setup_wrap_state);
1081 47649 : if (req == NULL) {
1082 0 : return NULL;
1083 : }
1084 47649 : state->ev = ev;
1085 47649 : state->smb2req = smb2req;
1086 47649 : state->in_session_id = in_session_id;
1087 47649 : state->in_flags = in_flags;
1088 47649 : state->in_security_mode = in_security_mode;
1089 47649 : state->in_previous_session_id = in_previous_session_id;
1090 47649 : state->in_security_buffer = in_security_buffer;
1091 :
1092 47649 : subreq = smbd_smb2_session_setup_send(state, state->ev,
1093 46539 : state->smb2req,
1094 46539 : state->in_session_id,
1095 46539 : state->in_flags,
1096 46539 : state->in_security_mode,
1097 46539 : state->in_previous_session_id,
1098 46539 : state->in_security_buffer);
1099 47649 : if (tevent_req_nomem(subreq, req)) {
1100 0 : return tevent_req_post(req, ev);
1101 : }
1102 47649 : tevent_req_set_callback(subreq,
1103 : smbd_smb2_session_setup_wrap_setup_done, req);
1104 :
1105 47649 : return req;
1106 : }
1107 :
1108 47649 : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1109 : {
1110 1110 : struct tevent_req *req =
1111 47649 : tevent_req_callback_data(subreq,
1112 : struct tevent_req);
1113 1110 : struct smbd_smb2_session_setup_wrap_state *state =
1114 47649 : tevent_req_data(req,
1115 : struct smbd_smb2_session_setup_wrap_state);
1116 1110 : NTSTATUS status;
1117 :
1118 47649 : 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 47649 : TALLOC_FREE(subreq);
1124 47649 : if (NT_STATUS_IS_OK(status)) {
1125 24359 : tevent_req_done(req);
1126 44892 : return;
1127 : }
1128 23290 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1129 19331 : tevent_req_nterror(req, status);
1130 19331 : return;
1131 : }
1132 :
1133 3959 : if (state->smb2req->session == NULL) {
1134 0 : tevent_req_nterror(req, status);
1135 0 : return;
1136 : }
1137 :
1138 3959 : state->error = status;
1139 :
1140 3959 : 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 3117 : 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 2321 : subreq = smb2srv_session_shutdown_send(state, state->ev,
1156 2314 : state->smb2req->session,
1157 : state->smb2req);
1158 2321 : if (tevent_req_nomem(subreq, req)) {
1159 0 : return;
1160 : }
1161 2321 : tevent_req_set_callback(subreq,
1162 : smbd_smb2_session_setup_wrap_shutdown_done,
1163 : req);
1164 : }
1165 :
1166 2321 : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1167 : {
1168 7 : struct tevent_req *req =
1169 2321 : tevent_req_callback_data(subreq,
1170 : struct tevent_req);
1171 7 : struct smbd_smb2_session_setup_wrap_state *state =
1172 2321 : tevent_req_data(req,
1173 : struct smbd_smb2_session_setup_wrap_state);
1174 7 : NTSTATUS status;
1175 :
1176 2321 : status = smb2srv_session_shutdown_recv(subreq);
1177 2321 : TALLOC_FREE(subreq);
1178 2321 : 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 2321 : talloc_steal(state->smb2req, state->smb2req->session);
1187 :
1188 2321 : tevent_req_nterror(req, state->error);
1189 : }
1190 :
1191 47649 : 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 47649 : tevent_req_data(req,
1199 : struct smbd_smb2_session_setup_wrap_state);
1200 1110 : NTSTATUS status;
1201 :
1202 47649 : if (tevent_req_is_nterror(req, &status)) {
1203 23290 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1204 3959 : tevent_req_received(req);
1205 3959 : return nt_status_squash(status);
1206 : }
1207 : } else {
1208 24359 : status = NT_STATUS_OK;
1209 : }
1210 :
1211 43690 : *out_session_flags = state->out_session_flags;
1212 43690 : *out_security_buffer = state->out_security_buffer;
1213 43690 : *out_session_id = state->out_session_id;
1214 :
1215 43690 : talloc_steal(mem_ctx, out_security_buffer->data);
1216 43690 : tevent_req_received(req);
1217 43690 : 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 : }
|