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