smbdotconf: add client ldap sasl wrapping = {starttls,ldaps}
[samba.git] / source3 / smbd / smb2_sesssetup.c
blob3005385ac9ceeb391762cb0c2b9d7a3b231baf08
1 /*
2 Unix SMB/CIFS implementation.
3 Core SMB2 server
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
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.
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.
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/>.
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"
34 #include "lib/crypto/gnutls_helpers.h"
35 #include <gnutls/gnutls.h>
36 #include <gnutls/crypto.h>
38 #undef DBGC_CLASS
39 #define DBGC_CLASS DBGC_SMB2
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);
55 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
57 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
59 const uint8_t *inhdr;
60 const uint8_t *inbody;
61 uint64_t in_session_id;
62 uint8_t in_flags;
63 uint8_t in_security_mode;
64 uint64_t in_previous_session_id;
65 uint16_t in_security_offset;
66 uint16_t in_security_length;
67 DATA_BLOB in_security_buffer;
68 NTSTATUS status;
69 struct tevent_req *subreq;
71 status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
72 if (!NT_STATUS_IS_OK(status)) {
73 return smbd_smb2_request_error(smb2req, status);
75 inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
76 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
78 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
80 in_flags = CVAL(inbody, 0x02);
81 in_security_mode = CVAL(inbody, 0x03);
82 /* Capabilities = IVAL(inbody, 0x04) */
83 /* Channel = IVAL(inbody, 0x08) */
84 in_security_offset = SVAL(inbody, 0x0C);
85 in_security_length = SVAL(inbody, 0x0E);
86 in_previous_session_id = BVAL(inbody, 0x10);
88 if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
89 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
92 if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
93 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
96 in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
97 in_security_buffer.length = in_security_length;
99 subreq = smbd_smb2_session_setup_wrap_send(smb2req,
100 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 if (subreq == NULL) {
108 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
110 tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
113 * Avoid sending a STATUS_PENDING message, which
114 * matches a Windows Server and avoids problems with
115 * MacOS clients.
117 * Even after 90 seconds a Windows Server doesn't return
118 * STATUS_PENDING if using NTLMSSP against a non reachable
119 * trusted domain.
121 return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
124 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
126 struct smbd_smb2_request *smb2req =
127 tevent_req_callback_data(subreq,
128 struct smbd_smb2_request);
129 uint8_t *outhdr;
130 DATA_BLOB outbody;
131 DATA_BLOB outdyn;
132 uint16_t out_session_flags = 0;
133 uint64_t out_session_id = 0;
134 uint16_t out_security_offset;
135 DATA_BLOB out_security_buffer = data_blob_null;
136 NTSTATUS status;
137 NTSTATUS error; /* transport error */
139 status = smbd_smb2_session_setup_wrap_recv(subreq,
140 &out_session_flags,
141 smb2req,
142 &out_security_buffer,
143 &out_session_id);
144 TALLOC_FREE(subreq);
145 if (!NT_STATUS_IS_OK(status) &&
146 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
147 status = nt_status_squash(status);
148 error = smbd_smb2_request_error(smb2req, status);
149 if (!NT_STATUS_IS_OK(error)) {
150 smbd_server_connection_terminate(smb2req->xconn,
151 nt_errstr(error));
152 return;
154 return;
157 out_security_offset = SMB2_HDR_BODY + 0x08;
159 outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
161 outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
162 if (outbody.data == NULL) {
163 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
164 if (!NT_STATUS_IS_OK(error)) {
165 smbd_server_connection_terminate(smb2req->xconn,
166 nt_errstr(error));
167 return;
169 return;
172 SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
174 SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
175 SSVAL(outbody.data, 0x02,
176 out_session_flags); /* session flags */
177 SSVAL(outbody.data, 0x04,
178 out_security_offset); /* security buffer offset */
179 SSVAL(outbody.data, 0x06,
180 out_security_buffer.length); /* security buffer length */
182 outdyn = out_security_buffer;
184 error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
185 __location__);
186 if (!NT_STATUS_IS_OK(error)) {
187 smbd_server_connection_terminate(smb2req->xconn,
188 nt_errstr(error));
189 return;
193 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)
201 NTSTATUS status;
202 bool guest = false;
203 struct smbXsrv_session *x = session;
204 struct smbXsrv_session_auth0 *auth = *_auth;
205 struct smbXsrv_connection *xconn = smb2req->xconn;
206 size_t i;
207 struct smb2_signing_derivations derivations = {
208 .signing = NULL,
210 DATA_BLOB preauth_hash = data_blob_null;
212 *_auth = NULL;
214 if (xconn->protocol >= PROTOCOL_SMB3_11) {
215 struct smbXsrv_preauth *preauth;
216 gnutls_hash_hd_t hash_hnd;
217 int rc;
219 preauth = talloc_move(smb2req, &auth->preauth);
221 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
222 if (rc < 0) {
223 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
225 rc = gnutls_hash(hash_hnd,
226 preauth->sha512_value,
227 sizeof(preauth->sha512_value));
228 if (rc < 0) {
229 gnutls_hash_deinit(hash_hnd, NULL);
230 return NT_STATUS_ACCESS_DENIED;
232 for (i = 1; i < smb2req->in.vector_count; i++) {
233 rc = gnutls_hash(hash_hnd,
234 smb2req->in.vector[i].iov_base,
235 smb2req->in.vector[i].iov_len);
236 if (rc < 0) {
237 gnutls_hash_deinit(hash_hnd, NULL);
238 return NT_STATUS_ACCESS_DENIED;
241 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
243 preauth_hash = data_blob_const(preauth->sha512_value,
244 sizeof(preauth->sha512_value));
247 smb2_signing_derivations_fill_const_stack(&derivations,
248 xconn->protocol,
249 preauth_hash);
251 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
252 (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
254 x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
257 if ((lp_server_smb_encrypt(-1) >= SMB_ENCRYPTION_DESIRED) &&
258 (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
259 x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
262 if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_REQUIRED) {
263 x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
264 SMBXSRV_ENCRYPTION_DESIRED;
267 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
268 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
269 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
271 /* force no signing */
272 x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
273 /* we map anonymous to guest internally */
274 guest = true;
277 if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
278 DEBUG(1,("reject guest session as encryption is required\n"));
279 return NT_STATUS_ACCESS_DENIED;
282 if (xconn->smb2.server.cipher == 0) {
283 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
284 DEBUG(1,("reject session with dialect[0x%04X] "
285 "as encryption is required\n",
286 xconn->smb2.server.dialect));
287 return NT_STATUS_ACCESS_DENIED;
290 x->global->signing_algo = xconn->smb2.server.sign_algo;
291 x->global->encryption_cipher = xconn->smb2.server.cipher;
292 if (guest) {
293 x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
296 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
297 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
300 status = smb2_signing_key_sign_create(x->global,
301 x->global->signing_algo,
302 &session_info->session_key,
303 derivations.signing,
304 &x->global->signing_key);
305 if (!NT_STATUS_IS_OK(status)) {
306 return status;
308 x->global->signing_key_blob = x->global->signing_key->blob;
310 if (x->global->encryption_cipher != SMB2_ENCRYPTION_NONE) {
311 size_t nonce_size;
313 status = smb2_signing_key_cipher_create(x->global,
314 x->global->encryption_cipher,
315 &session_info->session_key,
316 derivations.cipher_s2c,
317 &x->global->encryption_key);
318 if (!NT_STATUS_IS_OK(status)) {
319 return status;
321 x->global->encryption_key_blob = x->global->encryption_key->blob;
323 status = smb2_signing_key_cipher_create(x->global,
324 x->global->encryption_cipher,
325 &session_info->session_key,
326 derivations.cipher_c2s,
327 &x->global->decryption_key);
328 if (!NT_STATUS_IS_OK(status)) {
329 return status;
331 x->global->decryption_key_blob = x->global->decryption_key->blob;
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.
340 * NOTE: We assume nonces greater than 8 bytes.
342 generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
343 sizeof(x->nonce_high_random));
344 switch (xconn->smb2.server.cipher) {
345 case SMB2_ENCRYPTION_AES128_CCM:
346 nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
347 break;
348 case SMB2_ENCRYPTION_AES128_GCM:
349 nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
350 break;
351 case SMB2_ENCRYPTION_AES256_CCM:
352 nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
353 break;
354 case SMB2_ENCRYPTION_AES256_GCM:
355 nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
356 break;
357 default:
358 nonce_size = 0;
359 break;
361 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
362 x->nonce_high = 0;
363 x->nonce_low = 0;
366 status = smb2_signing_key_sign_create(x->global,
367 x->global->signing_algo,
368 &session_info->session_key,
369 derivations.application,
370 &x->global->application_key);
371 if (!NT_STATUS_IS_OK(status)) {
372 return status;
374 x->global->application_key_blob = x->global->application_key->blob;
376 if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
377 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
378 DEBUGADD(0, ("Session Id "));
379 dump_data(0, (uint8_t*)&session->global->session_wire_id,
380 sizeof(session->global->session_wire_id));
381 DEBUGADD(0, ("Session Key "));
382 dump_data(0, session_info->session_key.data,
383 session_info->session_key.length);
384 DEBUGADD(0, ("Signing Algo: %u\n", x->global->signing_algo));
385 DEBUGADD(0, ("Signing Key "));
386 dump_data(0, x->global->signing_key_blob.data,
387 x->global->signing_key_blob.length);
388 DEBUGADD(0, ("App Key "));
389 dump_data(0, x->global->application_key_blob.data,
390 x->global->application_key_blob.length);
392 /* In server code, ServerIn is the decryption key */
394 DEBUGADD(0, ("Cipher Algo: %u\n", x->global->encryption_cipher));
395 DEBUGADD(0, ("ServerIn Key "));
396 dump_data(0, x->global->decryption_key_blob.data,
397 x->global->decryption_key_blob.length);
398 DEBUGADD(0, ("ServerOut Key "));
399 dump_data(0, x->global->encryption_key_blob.data,
400 x->global->encryption_key_blob.length);
403 status = smb2_signing_key_copy(x->global->channels,
404 x->global->signing_key,
405 &x->global->channels[0].signing_key);
406 if (!NT_STATUS_IS_OK(status)) {
407 return status;
409 x->global->channels[0].signing_key_blob =
410 x->global->channels[0].signing_key->blob;
411 x->global->channels[0].signing_algo = x->global->signing_algo;
412 x->global->channels[0].encryption_cipher = x->global->encryption_cipher;
414 data_blob_clear_free(&session_info->session_key);
415 session_info->session_key = data_blob_dup_talloc(session_info,
416 x->global->application_key_blob);
417 if (session_info->session_key.data == NULL) {
418 return NT_STATUS_NO_MEMORY;
420 talloc_keep_secret(session_info->session_key.data);
422 smb2req->sconn->num_users++;
424 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
425 session->homes_snum =
426 register_homes_share(session_info->unix_info->unix_name);
429 set_current_user_info(session_info->unix_info->sanitized_username,
430 session_info->unix_info->unix_name,
431 session_info->info->domain_name);
433 reload_services(smb2req->sconn, conn_snum_used, true);
435 session->status = NT_STATUS_OK;
436 session->global->auth_session_info = talloc_move(session->global,
437 &session_info);
438 session->global->auth_session_info_seqnum += 1;
439 for (i=0; i < session->global->num_channels; i++) {
440 struct smbXsrv_channel_global0 *_c =
441 &session->global->channels[i];
443 _c->auth_session_info_seqnum =
444 session->global->auth_session_info_seqnum;
446 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
447 session->global->expiration_time = gensec_expire_time(auth->gensec);
449 if (!session_claim(session)) {
450 DEBUG(1, ("smb2: Failed to claim session "
451 "for vuid=%llu\n",
452 (unsigned long long)session->global->session_wire_id));
453 return NT_STATUS_LOGON_FAILURE;
456 TALLOC_FREE(auth);
457 status = smbXsrv_session_update(session);
458 if (!NT_STATUS_IS_OK(status)) {
459 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 return NT_STATUS_LOGON_FAILURE;
466 * we attach the session to the request
467 * so that the response can be signed
469 if (!guest) {
470 smb2req->do_signing = true;
473 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
475 *out_session_id = session->global->session_wire_id;
476 smb2req->last_session_id = session->global->session_wire_id;
478 return NT_STATUS_OK;
481 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)
488 NTSTATUS status;
489 struct smbXsrv_session *x = session;
490 struct smbXsrv_session_auth0 *auth = *_auth;
491 struct smbXsrv_connection *xconn = smb2req->xconn;
492 size_t i;
494 *_auth = NULL;
496 data_blob_clear_free(&session_info->session_key);
497 session_info->session_key = data_blob_dup_talloc(session_info,
498 x->global->application_key_blob);
499 if (session_info->session_key.data == NULL) {
500 return NT_STATUS_NO_MEMORY;
502 talloc_keep_secret(session_info->session_key.data);
504 session->homes_snum =
505 register_homes_share(session_info->unix_info->unix_name);
507 set_current_user_info(session_info->unix_info->sanitized_username,
508 session_info->unix_info->unix_name,
509 session_info->info->domain_name);
511 reload_services(smb2req->sconn, conn_snum_used, true);
513 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
514 smb2req->do_signing = true;
517 session->status = NT_STATUS_OK;
518 TALLOC_FREE(session->global->auth_session_info);
519 session->global->auth_session_info = talloc_move(session->global,
520 &session_info);
521 session->global->auth_session_info_seqnum += 1;
522 for (i=0; i < session->global->num_channels; i++) {
523 struct smbXsrv_channel_global0 *_c =
524 &session->global->channels[i];
526 _c->auth_session_info_seqnum =
527 session->global->auth_session_info_seqnum;
529 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
530 session->global->expiration_time = gensec_expire_time(auth->gensec);
532 TALLOC_FREE(auth);
533 status = smbXsrv_session_update(session);
534 if (!NT_STATUS_IS_OK(status)) {
535 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 return NT_STATUS_LOGON_FAILURE;
541 conn_clear_vuid_caches(xconn->client->sconn,
542 session->global->session_wire_id);
544 *out_session_id = session->global->session_wire_id;
546 return NT_STATUS_OK;
549 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)
556 NTSTATUS status;
557 struct smbXsrv_session *x = session;
558 struct smbXsrv_session_auth0 *auth = *_auth;
559 struct smbXsrv_connection *xconn = smb2req->xconn;
560 struct smbXsrv_channel_global0 *c = NULL;
561 size_t i;
562 struct smb2_signing_derivations derivations = {
563 .signing = NULL,
565 DATA_BLOB preauth_hash = data_blob_null;
566 bool ok;
568 *_auth = NULL;
570 if (xconn->protocol >= PROTOCOL_SMB3_11) {
571 struct smbXsrv_preauth *preauth;
572 gnutls_hash_hd_t hash_hnd = NULL;
573 int rc;
575 preauth = talloc_move(smb2req, &auth->preauth);
577 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
578 if (rc < 0) {
579 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
582 rc = gnutls_hash(hash_hnd,
583 preauth->sha512_value,
584 sizeof(preauth->sha512_value));
585 if (rc < 0) {
586 gnutls_hash_deinit(hash_hnd, NULL);
587 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
589 for (i = 1; i < smb2req->in.vector_count; i++) {
590 rc = gnutls_hash(hash_hnd,
591 smb2req->in.vector[i].iov_base,
592 smb2req->in.vector[i].iov_len);
593 if (rc < 0) {
594 gnutls_hash_deinit(hash_hnd, NULL);
595 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
598 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
600 preauth_hash = data_blob_const(preauth->sha512_value,
601 sizeof(preauth->sha512_value));
604 smb2_signing_derivations_fill_const_stack(&derivations,
605 xconn->protocol,
606 preauth_hash);
608 status = smbXsrv_session_find_channel(session, xconn, &c);
609 if (!NT_STATUS_IS_OK(status)) {
610 return status;
613 ok = security_token_is_sid(session_info->security_token,
614 &x->global->auth_session_info->security_token->sids[0]);
615 if (!ok) {
616 return NT_STATUS_ACCESS_DENIED;
619 if (session_info->session_key.length == 0) {
620 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
621 return NT_STATUS_NOT_SUPPORTED;
624 c->signing_algo = xconn->smb2.server.sign_algo;
625 c->encryption_cipher = xconn->smb2.server.cipher;
627 status = smb2_signing_key_sign_create(x->global->channels,
628 c->signing_algo,
629 &session_info->session_key,
630 derivations.signing,
631 &c->signing_key);
632 if (!NT_STATUS_IS_OK(status)) {
633 return status;
635 c->signing_key_blob = c->signing_key->blob;
637 TALLOC_FREE(auth);
638 status = smbXsrv_session_update(session);
639 if (!NT_STATUS_IS_OK(status)) {
640 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 return NT_STATUS_LOGON_FAILURE;
646 *out_session_id = session->global->session_wire_id;
648 return NT_STATUS_OK;
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;
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);
671 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)
680 struct tevent_req *req;
681 struct smbd_smb2_session_setup_state *state;
682 NTSTATUS status;
683 NTTIME now = timeval_to_nttime(&smb2req->request_time);
684 struct tevent_req *subreq;
685 struct smbXsrv_channel_global0 *c = NULL;
686 enum security_user_level seclvl;
688 req = tevent_req_create(mem_ctx, &state,
689 struct smbd_smb2_session_setup_state);
690 if (req == NULL) {
691 return NULL;
693 state->ev = ev;
694 state->smb2req = smb2req;
695 state->in_session_id = in_session_id;
696 state->in_flags = in_flags;
697 state->in_security_mode = in_security_mode;
698 state->in_previous_session_id = in_previous_session_id;
699 state->in_security_buffer = in_security_buffer;
701 if (in_flags & SMB2_SESSION_FLAG_BINDING) {
702 if (in_session_id == 0) {
703 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
704 return tevent_req_post(req, ev);
707 if (smb2req->session == NULL) {
708 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
709 return tevent_req_post(req, ev);
712 if ((smb2req->session->global->signing_algo >= SMB2_SIGNING_AES128_GMAC) &&
713 (smb2req->xconn->smb2.server.sign_algo != smb2req->session->global->signing_algo))
715 tevent_req_nterror(req, NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
716 return tevent_req_post(req, ev);
718 if ((smb2req->xconn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) &&
719 (smb2req->session->global->signing_algo != smb2req->xconn->smb2.server.sign_algo))
721 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
722 return tevent_req_post(req, ev);
725 if (smb2req->xconn->protocol < PROTOCOL_SMB3_00) {
726 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
727 return tevent_req_post(req, ev);
730 if (!smb2req->xconn->client->server_multi_channel_enabled) {
731 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
732 return tevent_req_post(req, ev);
735 if (!smb2req->do_signing) {
736 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
737 return tevent_req_post(req, ev);
740 if (smb2req->session->global->connection_dialect
741 != smb2req->xconn->smb2.server.dialect)
743 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
744 return tevent_req_post(req, ev);
747 if (smb2req->session->global->encryption_cipher
748 != smb2req->xconn->smb2.server.cipher)
750 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
751 return tevent_req_post(req, ev);
754 status = smb2req->session->status;
755 if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
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.
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.
765 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
766 return tevent_req_post(req, ev);
769 status = smbXsrv_session_find_channel(smb2req->session,
770 smb2req->xconn,
771 &c);
772 if (NT_STATUS_IS_OK(status)) {
773 if (!smb2_signing_key_valid(c->signing_key)) {
774 goto auth;
776 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
777 return tevent_req_post(req, ev);
780 seclvl = security_session_user_level(
781 smb2req->session->global->auth_session_info,
782 NULL);
783 if (seclvl < SECURITY_USER) {
784 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
785 return tevent_req_post(req, ev);
788 status = smbXsrv_session_add_channel(smb2req->session,
789 smb2req->xconn,
790 now,
791 &c);
792 if (tevent_req_nterror(req, status)) {
793 return tevent_req_post(req, ev);
796 status = smbXsrv_session_update(smb2req->session);
797 if (tevent_req_nterror(req, status)) {
798 return tevent_req_post(req, ev);
802 auth:
804 if (state->in_session_id == 0) {
805 /* create a new session */
806 status = smbXsrv_session_create(state->smb2req->xconn,
807 now, &state->session);
808 if (tevent_req_nterror(req, status)) {
809 return tevent_req_post(req, ev);
811 smb2req->session = state->session;
812 } else {
813 if (smb2req->session == NULL) {
814 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
815 return tevent_req_post(req, ev);
818 state->session = smb2req->session;
819 status = state->session->status;
820 if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
822 * This comes from smb2srv_session_lookup_global().
824 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
825 return tevent_req_post(req, ev);
827 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
828 status = NT_STATUS_OK;
830 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
831 status = NT_STATUS_OK;
833 if (tevent_req_nterror(req, status)) {
834 return tevent_req_post(req, ev);
838 status = smbXsrv_session_find_channel(smb2req->session,
839 smb2req->xconn, &c);
840 if (tevent_req_nterror(req, status)) {
841 return tevent_req_post(req, ev);
844 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
845 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
848 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
849 now, &state->auth);
850 if (!NT_STATUS_IS_OK(status)) {
851 status = smbXsrv_session_create_auth(state->session,
852 smb2req->xconn, now,
853 in_flags, in_security_mode,
854 &state->auth);
855 if (tevent_req_nterror(req, status)) {
856 return tevent_req_post(req, ev);
860 if (state->auth->gensec == NULL) {
861 status = auth_generic_prepare(state->auth,
862 state->smb2req->xconn->remote_address,
863 state->smb2req->xconn->local_address,
864 "SMB2",
865 &state->auth->gensec);
866 if (tevent_req_nterror(req, status)) {
867 return tevent_req_post(req, ev);
870 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
871 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
872 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
874 status = gensec_start_mech_by_oid(state->auth->gensec,
875 GENSEC_OID_SPNEGO);
876 if (tevent_req_nterror(req, status)) {
877 return tevent_req_post(req, ev);
881 status = smbXsrv_session_update(state->session);
882 if (tevent_req_nterror(req, status)) {
883 return tevent_req_post(req, ev);
886 become_root();
887 subreq = gensec_update_send(state, state->ev,
888 state->auth->gensec,
889 state->in_security_buffer);
890 unbecome_root();
891 if (tevent_req_nomem(subreq, req)) {
892 return tevent_req_post(req, ev);
894 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
896 return req;
899 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
901 struct tevent_req *req =
902 tevent_req_callback_data(subreq,
903 struct tevent_req);
904 struct smbd_smb2_session_setup_state *state =
905 tevent_req_data(req,
906 struct smbd_smb2_session_setup_state);
907 NTSTATUS status;
909 become_root();
910 status = gensec_update_recv(subreq, state,
911 &state->out_security_buffer);
912 unbecome_root();
913 TALLOC_FREE(subreq);
914 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
915 !NT_STATUS_IS_OK(status)) {
916 tevent_req_nterror(req, status);
917 return;
920 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
921 state->out_session_id = state->session->global->session_wire_id;
922 state->smb2req->preauth = state->auth->preauth;
923 tevent_req_nterror(req, status);
924 return;
927 status = gensec_session_info(state->auth->gensec,
928 state,
929 &state->session_info);
930 if (tevent_req_nterror(req, status)) {
931 return;
934 if ((state->in_previous_session_id != 0) &&
935 (state->session->global->session_wire_id !=
936 state->in_previous_session_id))
938 subreq = smb2srv_session_close_previous_send(state, state->ev,
939 state->smb2req->xconn,
940 state->session_info,
941 state->in_previous_session_id,
942 state->session->global->session_wire_id);
943 if (tevent_req_nomem(subreq, req)) {
944 return;
946 tevent_req_set_callback(subreq,
947 smbd_smb2_session_setup_previous_done,
948 req);
949 return;
952 smbd_smb2_session_setup_auth_return(req);
955 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
957 struct tevent_req *req =
958 tevent_req_callback_data(subreq,
959 struct tevent_req);
960 NTSTATUS status;
962 status = smb2srv_session_close_previous_recv(subreq);
963 TALLOC_FREE(subreq);
964 if (tevent_req_nterror(req, status)) {
965 return;
968 smbd_smb2_session_setup_auth_return(req);
971 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
973 struct smbd_smb2_session_setup_state *state =
974 tevent_req_data(req,
975 struct smbd_smb2_session_setup_state);
976 NTSTATUS status;
978 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
979 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 if (tevent_req_nterror(req, status)) {
986 return;
988 tevent_req_done(req);
989 return;
992 if (state->session->global->auth_session_info != NULL) {
993 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 if (tevent_req_nterror(req, status)) {
1000 return;
1002 tevent_req_done(req);
1003 return;
1006 status = smbd_smb2_auth_generic_return(state->session,
1007 &state->auth,
1008 state->smb2req,
1009 state->in_security_mode,
1010 state->session_info,
1011 &state->out_session_flags,
1012 &state->out_session_id);
1013 if (tevent_req_nterror(req, status)) {
1014 return;
1017 tevent_req_done(req);
1018 return;
1021 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)
1027 struct smbd_smb2_session_setup_state *state =
1028 tevent_req_data(req,
1029 struct smbd_smb2_session_setup_state);
1030 NTSTATUS status;
1032 if (tevent_req_is_nterror(req, &status)) {
1033 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1034 tevent_req_received(req);
1035 return nt_status_squash(status);
1037 } else {
1038 status = NT_STATUS_OK;
1041 *out_session_flags = state->out_session_flags;
1042 *out_security_buffer = state->out_security_buffer;
1043 *out_session_id = state->out_session_id;
1045 talloc_steal(mem_ctx, out_security_buffer->data);
1046 tevent_req_received(req);
1047 return status;
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;
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);
1067 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)
1076 struct tevent_req *req;
1077 struct smbd_smb2_session_setup_wrap_state *state;
1078 struct tevent_req *subreq;
1080 req = tevent_req_create(mem_ctx, &state,
1081 struct smbd_smb2_session_setup_wrap_state);
1082 if (req == NULL) {
1083 return NULL;
1085 state->ev = ev;
1086 state->smb2req = smb2req;
1087 state->in_session_id = in_session_id;
1088 state->in_flags = in_flags;
1089 state->in_security_mode = in_security_mode;
1090 state->in_previous_session_id = in_previous_session_id;
1091 state->in_security_buffer = in_security_buffer;
1093 subreq = smbd_smb2_session_setup_send(state, state->ev,
1094 state->smb2req,
1095 state->in_session_id,
1096 state->in_flags,
1097 state->in_security_mode,
1098 state->in_previous_session_id,
1099 state->in_security_buffer);
1100 if (tevent_req_nomem(subreq, req)) {
1101 return tevent_req_post(req, ev);
1103 tevent_req_set_callback(subreq,
1104 smbd_smb2_session_setup_wrap_setup_done, req);
1106 return req;
1109 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1111 struct tevent_req *req =
1112 tevent_req_callback_data(subreq,
1113 struct tevent_req);
1114 struct smbd_smb2_session_setup_wrap_state *state =
1115 tevent_req_data(req,
1116 struct smbd_smb2_session_setup_wrap_state);
1117 NTSTATUS status;
1119 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 TALLOC_FREE(subreq);
1125 if (NT_STATUS_IS_OK(status)) {
1126 tevent_req_done(req);
1127 return;
1129 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1130 tevent_req_nterror(req, status);
1131 return;
1134 if (state->smb2req->session == NULL) {
1135 tevent_req_nterror(req, status);
1136 return;
1139 state->error = status;
1141 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1142 status = smbXsrv_session_remove_channel(state->smb2req->session,
1143 state->smb2req->xconn);
1144 if (tevent_req_nterror(req, status)) {
1145 return;
1147 tevent_req_nterror(req, state->error);
1148 return;
1151 if (NT_STATUS_EQUAL(state->error, NT_STATUS_USER_SESSION_DELETED)) {
1152 tevent_req_nterror(req, state->error);
1153 return;
1156 subreq = smb2srv_session_shutdown_send(state, state->ev,
1157 state->smb2req->session,
1158 state->smb2req);
1159 if (tevent_req_nomem(subreq, req)) {
1160 return;
1162 tevent_req_set_callback(subreq,
1163 smbd_smb2_session_setup_wrap_shutdown_done,
1164 req);
1167 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1169 struct tevent_req *req =
1170 tevent_req_callback_data(subreq,
1171 struct tevent_req);
1172 struct smbd_smb2_session_setup_wrap_state *state =
1173 tevent_req_data(req,
1174 struct smbd_smb2_session_setup_wrap_state);
1175 NTSTATUS status;
1177 status = smb2srv_session_shutdown_recv(subreq);
1178 TALLOC_FREE(subreq);
1179 if (tevent_req_nterror(req, status)) {
1180 return;
1184 * we may need to sign the response, so we need to keep
1185 * the session until the response is sent to the wire.
1187 talloc_steal(state->smb2req, state->smb2req->session);
1189 tevent_req_nterror(req, state->error);
1192 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)
1198 struct smbd_smb2_session_setup_wrap_state *state =
1199 tevent_req_data(req,
1200 struct smbd_smb2_session_setup_wrap_state);
1201 NTSTATUS status;
1203 if (tevent_req_is_nterror(req, &status)) {
1204 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1205 tevent_req_received(req);
1206 return nt_status_squash(status);
1208 } else {
1209 status = NT_STATUS_OK;
1212 *out_session_flags = state->out_session_flags;
1213 *out_security_buffer = state->out_security_buffer;
1214 *out_session_id = state->out_session_id;
1216 talloc_steal(mem_ctx, out_security_buffer->data);
1217 tevent_req_received(req);
1218 return status;
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);
1227 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1229 NTSTATUS status;
1230 struct tevent_req *subreq = NULL;
1232 status = smbd_smb2_request_verify_sizes(req, 0x04);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 return smbd_smb2_request_error(req, status);
1237 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1238 if (subreq == NULL) {
1239 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1241 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1244 * Avoid sending a STATUS_PENDING message, it's very likely
1245 * the client won't expect that.
1247 return smbd_smb2_request_pending_queue(req, subreq, 0);
1250 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1252 struct smbd_smb2_request *smb2req =
1253 tevent_req_callback_data(subreq,
1254 struct smbd_smb2_request);
1255 DATA_BLOB outbody;
1256 NTSTATUS status;
1257 NTSTATUS error;
1259 status = smbd_smb2_logoff_recv(subreq);
1260 TALLOC_FREE(subreq);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 error = smbd_smb2_request_error(smb2req, status);
1263 if (!NT_STATUS_IS_OK(error)) {
1264 smbd_server_connection_terminate(smb2req->xconn,
1265 nt_errstr(error));
1266 return;
1268 return;
1271 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1272 if (outbody.data == NULL) {
1273 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1274 if (!NT_STATUS_IS_OK(error)) {
1275 smbd_server_connection_terminate(smb2req->xconn,
1276 nt_errstr(error));
1277 return;
1279 return;
1282 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1283 SSVAL(outbody.data, 0x02, 0); /* reserved */
1285 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1286 if (!NT_STATUS_IS_OK(error)) {
1287 smbd_server_connection_terminate(smb2req->xconn,
1288 nt_errstr(error));
1289 return;
1293 struct smbd_smb2_logoff_state {
1294 struct smbd_smb2_request *smb2req;
1297 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1299 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1300 struct tevent_context *ev,
1301 struct smbd_smb2_request *smb2req)
1303 struct tevent_req *req;
1304 struct smbd_smb2_logoff_state *state;
1305 struct tevent_req *subreq;
1307 req = tevent_req_create(mem_ctx, &state,
1308 struct smbd_smb2_logoff_state);
1309 if (req == NULL) {
1310 return NULL;
1312 state->smb2req = smb2req;
1314 subreq = smb2srv_session_shutdown_send(state, ev,
1315 smb2req->session,
1316 smb2req);
1317 if (tevent_req_nomem(subreq, req)) {
1318 return tevent_req_post(req, ev);
1320 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1322 return req;
1325 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1327 struct tevent_req *req = tevent_req_callback_data(
1328 subreq, struct tevent_req);
1329 struct smbd_smb2_logoff_state *state = tevent_req_data(
1330 req, struct smbd_smb2_logoff_state);
1331 NTSTATUS status;
1332 bool ok;
1333 const struct GUID *client_guid =
1334 &state->smb2req->session->client->global->client_guid;
1336 status = smb2srv_session_shutdown_recv(subreq);
1337 if (tevent_req_nterror(req, status)) {
1338 return;
1340 TALLOC_FREE(subreq);
1342 if (!GUID_all_zero(client_guid)) {
1343 ok = remote_arch_cache_delete(client_guid);
1344 if (!ok) {
1345 /* Most likely not an error, but not in cache */
1346 DBG_DEBUG("Deletion from remote arch cache failed\n");
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).
1355 change_to_root_user();
1357 status = smbXsrv_session_logoff(state->smb2req->session);
1358 if (tevent_req_nterror(req, status)) {
1359 return;
1363 * we may need to sign the response, so we need to keep
1364 * the session until the response is sent to the wire.
1366 talloc_steal(state->smb2req, state->smb2req->session);
1368 tevent_req_done(req);
1371 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1373 return tevent_req_simple_recv_ntstatus(req);