smbd: Convert refuse_symlink_fsp() to bool
[samba4-gss.git] / source3 / smbd / smb2_sesssetup.c
blobd4140af2f1f3776ed70c4074a5f708c999983ed4
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;
275 } else {
277 * Remember we got one authenticated session on the connection
278 * in order to allow SMB3 decryption to happen
279 * (sadly even for future anonymous connections).
281 xconn->smb2.got_authenticated_session = true;
284 if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
285 DEBUG(1,("reject guest session as encryption is required\n"));
286 return NT_STATUS_ACCESS_DENIED;
289 if (xconn->smb2.server.cipher == 0) {
290 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
291 DEBUG(1,("reject session with dialect[0x%04X] "
292 "as encryption is required\n",
293 xconn->smb2.server.dialect));
294 return NT_STATUS_ACCESS_DENIED;
297 x->global->signing_algo = xconn->smb2.server.sign_algo;
298 x->global->encryption_cipher = xconn->smb2.server.cipher;
299 if (*out_session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
301 * A fallback to guest can't do any encryption
303 x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
306 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
307 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
310 status = smb2_signing_key_sign_create(x->global,
311 x->global->signing_algo,
312 &session_info->session_key,
313 derivations.signing,
314 &x->global->signing_key);
315 if (!NT_STATUS_IS_OK(status)) {
316 return status;
318 x->global->signing_key_blob = x->global->signing_key->blob;
320 if (x->global->encryption_cipher != SMB2_ENCRYPTION_NONE) {
321 size_t nonce_size;
323 status = smb2_signing_key_cipher_create(x->global,
324 x->global->encryption_cipher,
325 &session_info->session_key,
326 derivations.cipher_s2c,
327 &x->global->encryption_key);
328 if (!NT_STATUS_IS_OK(status)) {
329 return status;
331 x->global->encryption_key_blob = x->global->encryption_key->blob;
333 status = smb2_signing_key_cipher_create(x->global,
334 x->global->encryption_cipher,
335 &session_info->session_key,
336 derivations.cipher_c2s,
337 &x->global->decryption_key);
338 if (!NT_STATUS_IS_OK(status)) {
339 return status;
341 x->global->decryption_key_blob = x->global->decryption_key->blob;
344 * CCM and GCM algorithms must never have their
345 * nonce wrap, or the security of the whole
346 * communication and the keys is destroyed.
347 * We must drop the connection once we have
348 * transferred too much data.
350 * NOTE: We assume nonces greater than 8 bytes.
352 generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
353 sizeof(x->nonce_high_random));
354 switch (xconn->smb2.server.cipher) {
355 case SMB2_ENCRYPTION_AES128_CCM:
356 nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
357 break;
358 case SMB2_ENCRYPTION_AES128_GCM:
359 nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
360 break;
361 case SMB2_ENCRYPTION_AES256_CCM:
362 nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
363 break;
364 case SMB2_ENCRYPTION_AES256_GCM:
365 nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
366 break;
367 default:
368 nonce_size = 0;
369 break;
371 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
372 x->nonce_high = 0;
373 x->nonce_low = 0;
376 status = smb2_signing_key_sign_create(x->global,
377 x->global->signing_algo,
378 &session_info->session_key,
379 derivations.application,
380 &x->global->application_key);
381 if (!NT_STATUS_IS_OK(status)) {
382 return status;
384 x->global->application_key_blob = x->global->application_key->blob;
386 if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
387 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
388 DEBUGADD(0, ("Session Id "));
389 dump_data(0, (uint8_t*)&session->global->session_wire_id,
390 sizeof(session->global->session_wire_id));
391 DEBUGADD(0, ("Session Key "));
392 dump_data(0, session_info->session_key.data,
393 session_info->session_key.length);
394 DEBUGADD(0, ("Signing Algo: %u\n", x->global->signing_algo));
395 DEBUGADD(0, ("Signing Key "));
396 dump_data(0, x->global->signing_key_blob.data,
397 x->global->signing_key_blob.length);
398 DEBUGADD(0, ("App Key "));
399 dump_data(0, x->global->application_key_blob.data,
400 x->global->application_key_blob.length);
402 /* In server code, ServerIn is the decryption key */
404 DEBUGADD(0, ("Cipher Algo: %u\n", x->global->encryption_cipher));
405 DEBUGADD(0, ("ServerIn Key "));
406 dump_data(0, x->global->decryption_key_blob.data,
407 x->global->decryption_key_blob.length);
408 DEBUGADD(0, ("ServerOut Key "));
409 dump_data(0, x->global->encryption_key_blob.data,
410 x->global->encryption_key_blob.length);
413 status = smb2_signing_key_copy(x->global->channels,
414 x->global->signing_key,
415 &x->global->channels[0].signing_key);
416 if (!NT_STATUS_IS_OK(status)) {
417 return status;
419 x->global->channels[0].signing_key_blob =
420 x->global->channels[0].signing_key->blob;
421 x->global->channels[0].signing_algo = x->global->signing_algo;
422 x->global->channels[0].encryption_cipher = x->global->encryption_cipher;
424 data_blob_clear_free(&session_info->session_key);
425 session_info->session_key = data_blob_dup_talloc(session_info,
426 x->global->application_key_blob);
427 if (session_info->session_key.data == NULL) {
428 return NT_STATUS_NO_MEMORY;
430 talloc_keep_secret(session_info->session_key.data);
432 smb2req->sconn->num_users++;
434 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
435 session->homes_snum =
436 register_homes_share(session_info->unix_info->unix_name);
439 set_current_user_info(session_info->unix_info->sanitized_username,
440 session_info->unix_info->unix_name,
441 session_info->info->domain_name);
443 reload_services(smb2req->sconn, conn_snum_used, true);
445 session->status = NT_STATUS_OK;
446 session->global->auth_session_info = talloc_move(session->global,
447 &session_info);
448 session->global->auth_session_info_seqnum += 1;
449 for (i=0; i < session->global->num_channels; i++) {
450 struct smbXsrv_channel_global0 *_c =
451 &session->global->channels[i];
453 _c->auth_session_info_seqnum =
454 session->global->auth_session_info_seqnum;
456 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
457 session->global->expiration_time = gensec_expire_time(auth->gensec);
459 if (!session_claim(session)) {
460 DEBUG(1, ("smb2: Failed to claim session "
461 "for vuid=%llu\n",
462 (unsigned long long)session->global->session_wire_id));
463 return NT_STATUS_LOGON_FAILURE;
466 TALLOC_FREE(auth);
467 status = smbXsrv_session_update(session);
468 if (!NT_STATUS_IS_OK(status)) {
469 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
470 (unsigned long long)session->global->session_wire_id,
471 nt_errstr(status)));
472 return NT_STATUS_LOGON_FAILURE;
476 * we attach the session to the request
477 * so that the response can be signed
479 if (!guest) {
480 smb2req->do_signing = true;
483 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
485 *out_session_id = session->global->session_wire_id;
486 smb2req->last_session_id = session->global->session_wire_id;
488 return NT_STATUS_OK;
491 static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
492 struct smbXsrv_session_auth0 **_auth,
493 struct smbd_smb2_request *smb2req,
494 struct auth_session_info *session_info,
495 uint16_t *out_session_flags,
496 uint64_t *out_session_id)
498 NTSTATUS status;
499 struct smbXsrv_session *x = session;
500 struct smbXsrv_session_auth0 *auth = *_auth;
501 struct smbXsrv_connection *xconn = smb2req->xconn;
502 size_t i;
504 *_auth = NULL;
506 data_blob_clear_free(&session_info->session_key);
507 session_info->session_key = data_blob_dup_talloc(session_info,
508 x->global->application_key_blob);
509 if (session_info->session_key.data == NULL) {
510 return NT_STATUS_NO_MEMORY;
512 talloc_keep_secret(session_info->session_key.data);
514 session->homes_snum =
515 register_homes_share(session_info->unix_info->unix_name);
517 set_current_user_info(session_info->unix_info->sanitized_username,
518 session_info->unix_info->unix_name,
519 session_info->info->domain_name);
521 reload_services(smb2req->sconn, conn_snum_used, true);
523 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
524 smb2req->do_signing = true;
527 session->status = NT_STATUS_OK;
528 TALLOC_FREE(session->global->auth_session_info);
529 session->global->auth_session_info = talloc_move(session->global,
530 &session_info);
531 session->global->auth_session_info_seqnum += 1;
532 for (i=0; i < session->global->num_channels; i++) {
533 struct smbXsrv_channel_global0 *_c =
534 &session->global->channels[i];
536 _c->auth_session_info_seqnum =
537 session->global->auth_session_info_seqnum;
539 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
540 session->global->expiration_time = gensec_expire_time(auth->gensec);
542 TALLOC_FREE(auth);
543 status = smbXsrv_session_update(session);
544 if (!NT_STATUS_IS_OK(status)) {
545 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
546 (unsigned long long)session->global->session_wire_id,
547 nt_errstr(status)));
548 return NT_STATUS_LOGON_FAILURE;
551 conn_clear_vuid_caches(xconn->client->sconn,
552 session->global->session_wire_id);
554 *out_session_id = session->global->session_wire_id;
556 return NT_STATUS_OK;
559 static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
560 struct smbXsrv_session_auth0 **_auth,
561 struct smbd_smb2_request *smb2req,
562 struct auth_session_info *session_info,
563 uint16_t *out_session_flags,
564 uint64_t *out_session_id)
566 NTSTATUS status;
567 struct smbXsrv_session *x = session;
568 struct smbXsrv_session_auth0 *auth = *_auth;
569 struct smbXsrv_connection *xconn = smb2req->xconn;
570 struct smbXsrv_channel_global0 *c = NULL;
571 size_t i;
572 struct smb2_signing_derivations derivations = {
573 .signing = NULL,
575 DATA_BLOB preauth_hash = data_blob_null;
576 bool ok;
578 *_auth = NULL;
580 if (xconn->protocol >= PROTOCOL_SMB3_11) {
581 struct smbXsrv_preauth *preauth;
582 gnutls_hash_hd_t hash_hnd = NULL;
583 int rc;
585 preauth = talloc_move(smb2req, &auth->preauth);
587 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
588 if (rc < 0) {
589 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
592 rc = gnutls_hash(hash_hnd,
593 preauth->sha512_value,
594 sizeof(preauth->sha512_value));
595 if (rc < 0) {
596 gnutls_hash_deinit(hash_hnd, NULL);
597 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
599 for (i = 1; i < smb2req->in.vector_count; i++) {
600 rc = gnutls_hash(hash_hnd,
601 smb2req->in.vector[i].iov_base,
602 smb2req->in.vector[i].iov_len);
603 if (rc < 0) {
604 gnutls_hash_deinit(hash_hnd, NULL);
605 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
608 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
610 preauth_hash = data_blob_const(preauth->sha512_value,
611 sizeof(preauth->sha512_value));
614 smb2_signing_derivations_fill_const_stack(&derivations,
615 xconn->protocol,
616 preauth_hash);
618 status = smbXsrv_session_find_channel(session, xconn, &c);
619 if (!NT_STATUS_IS_OK(status)) {
620 return status;
623 ok = security_token_is_sid(session_info->security_token,
624 &x->global->auth_session_info->security_token->sids[0]);
625 if (!ok) {
626 return NT_STATUS_ACCESS_DENIED;
629 if (session_info->session_key.length == 0) {
630 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
631 return NT_STATUS_NOT_SUPPORTED;
634 c->signing_algo = xconn->smb2.server.sign_algo;
635 c->encryption_cipher = xconn->smb2.server.cipher;
637 status = smb2_signing_key_sign_create(x->global->channels,
638 c->signing_algo,
639 &session_info->session_key,
640 derivations.signing,
641 &c->signing_key);
642 if (!NT_STATUS_IS_OK(status)) {
643 return status;
645 c->signing_key_blob = c->signing_key->blob;
647 TALLOC_FREE(auth);
648 status = smbXsrv_session_update(session);
649 if (!NT_STATUS_IS_OK(status)) {
650 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
651 (unsigned long long)session->global->session_wire_id,
652 nt_errstr(status)));
653 return NT_STATUS_LOGON_FAILURE;
657 * Remember we got one authenticated session on the connection
658 * in order to allow SMB3 decryption to happen
660 xconn->smb2.got_authenticated_session = true;
662 *out_session_id = session->global->session_wire_id;
664 return NT_STATUS_OK;
667 struct smbd_smb2_session_setup_state {
668 struct tevent_context *ev;
669 struct smbd_smb2_request *smb2req;
670 uint64_t in_session_id;
671 uint8_t in_flags;
672 uint8_t in_security_mode;
673 uint64_t in_previous_session_id;
674 DATA_BLOB in_security_buffer;
675 struct smbXsrv_session *session;
676 struct smbXsrv_session_auth0 *auth;
677 struct auth_session_info *session_info;
678 uint16_t out_session_flags;
679 DATA_BLOB out_security_buffer;
680 uint64_t out_session_id;
683 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
684 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
685 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
687 static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
688 struct tevent_context *ev,
689 struct smbd_smb2_request *smb2req,
690 uint64_t in_session_id,
691 uint8_t in_flags,
692 uint8_t in_security_mode,
693 uint64_t in_previous_session_id,
694 DATA_BLOB in_security_buffer)
696 struct tevent_req *req;
697 struct smbd_smb2_session_setup_state *state;
698 NTSTATUS status;
699 NTTIME now = timeval_to_nttime(&smb2req->request_time);
700 struct tevent_req *subreq;
701 struct smbXsrv_channel_global0 *c = NULL;
702 enum security_user_level seclvl;
704 req = tevent_req_create(mem_ctx, &state,
705 struct smbd_smb2_session_setup_state);
706 if (req == NULL) {
707 return NULL;
709 state->ev = ev;
710 state->smb2req = smb2req;
711 state->in_session_id = in_session_id;
712 state->in_flags = in_flags;
713 state->in_security_mode = in_security_mode;
714 state->in_previous_session_id = in_previous_session_id;
715 state->in_security_buffer = in_security_buffer;
717 if (in_flags & SMB2_SESSION_FLAG_BINDING) {
718 if (in_session_id == 0) {
719 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
720 return tevent_req_post(req, ev);
723 if (smb2req->session == NULL) {
724 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
725 return tevent_req_post(req, ev);
728 if ((smb2req->session->global->signing_algo >= SMB2_SIGNING_AES128_GMAC) &&
729 (smb2req->xconn->smb2.server.sign_algo != smb2req->session->global->signing_algo))
731 tevent_req_nterror(req, NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
732 return tevent_req_post(req, ev);
734 if ((smb2req->xconn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) &&
735 (smb2req->session->global->signing_algo != smb2req->xconn->smb2.server.sign_algo))
737 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
738 return tevent_req_post(req, ev);
741 if (smb2req->xconn->protocol < PROTOCOL_SMB3_00) {
742 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
743 return tevent_req_post(req, ev);
746 if (!smb2req->xconn->client->server_multi_channel_enabled) {
747 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
748 return tevent_req_post(req, ev);
751 if (!smb2req->do_signing) {
752 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
753 return tevent_req_post(req, ev);
756 if (smb2req->session->global->connection_dialect
757 != smb2req->xconn->smb2.server.dialect)
759 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
760 return tevent_req_post(req, ev);
763 if (smb2req->session->global->encryption_cipher
764 != smb2req->xconn->smb2.server.cipher)
766 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
767 return tevent_req_post(req, ev);
770 status = smb2req->session->status;
771 if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
773 * This comes from smb2srv_session_lookup_global().
774 * And it's a cross node/cross smbd session bind,
775 * which can't work in our architecture.
777 * Returning NT_STATUS_REQUEST_NOT_ACCEPTED is better
778 * than NT_STATUS_USER_SESSION_DELETED in order to
779 * avoid a completely new session.
781 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
782 return tevent_req_post(req, ev);
785 status = smbXsrv_session_find_channel(smb2req->session,
786 smb2req->xconn,
787 &c);
788 if (NT_STATUS_IS_OK(status)) {
789 if (!smb2_signing_key_valid(c->signing_key)) {
790 goto auth;
792 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
793 return tevent_req_post(req, ev);
796 seclvl = security_session_user_level(
797 smb2req->session->global->auth_session_info,
798 NULL);
799 if (seclvl < SECURITY_USER) {
800 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
801 return tevent_req_post(req, ev);
804 status = smbXsrv_session_add_channel(smb2req->session,
805 smb2req->xconn,
806 now,
807 &c);
808 if (tevent_req_nterror(req, status)) {
809 return tevent_req_post(req, ev);
812 status = smbXsrv_session_update(smb2req->session);
813 if (tevent_req_nterror(req, status)) {
814 return tevent_req_post(req, ev);
818 auth:
820 if (state->in_session_id == 0) {
821 /* create a new session */
822 status = smbXsrv_session_create(state->smb2req->xconn,
823 now, &state->session);
824 if (tevent_req_nterror(req, status)) {
825 return tevent_req_post(req, ev);
827 smb2req->session = state->session;
828 } else {
829 if (smb2req->session == NULL) {
830 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
831 return tevent_req_post(req, ev);
834 state->session = smb2req->session;
835 status = state->session->status;
836 if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
838 * This comes from smb2srv_session_lookup_global().
840 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
841 return tevent_req_post(req, ev);
843 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
844 status = NT_STATUS_OK;
846 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
847 status = NT_STATUS_OK;
849 if (tevent_req_nterror(req, status)) {
850 return tevent_req_post(req, ev);
854 status = smbXsrv_session_find_channel(smb2req->session,
855 smb2req->xconn, &c);
856 if (tevent_req_nterror(req, status)) {
857 return tevent_req_post(req, ev);
860 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
861 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
864 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
865 now, &state->auth);
866 if (!NT_STATUS_IS_OK(status)) {
867 status = smbXsrv_session_create_auth(state->session,
868 smb2req->xconn, now,
869 in_flags, in_security_mode,
870 &state->auth);
871 if (tevent_req_nterror(req, status)) {
872 return tevent_req_post(req, ev);
876 if (state->auth->gensec == NULL) {
877 status = auth_generic_prepare(state->auth,
878 state->smb2req->xconn->remote_address,
879 state->smb2req->xconn->local_address,
880 "SMB2",
881 &state->auth->gensec);
882 if (tevent_req_nterror(req, status)) {
883 return tevent_req_post(req, ev);
886 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
887 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
888 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
890 status = gensec_start_mech_by_oid(state->auth->gensec,
891 GENSEC_OID_SPNEGO);
892 if (tevent_req_nterror(req, status)) {
893 return tevent_req_post(req, ev);
897 status = smbXsrv_session_update(state->session);
898 if (tevent_req_nterror(req, status)) {
899 return tevent_req_post(req, ev);
902 become_root();
903 subreq = gensec_update_send(state, state->ev,
904 state->auth->gensec,
905 state->in_security_buffer);
906 unbecome_root();
907 if (tevent_req_nomem(subreq, req)) {
908 return tevent_req_post(req, ev);
910 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
912 return req;
915 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
917 struct tevent_req *req =
918 tevent_req_callback_data(subreq,
919 struct tevent_req);
920 struct smbd_smb2_session_setup_state *state =
921 tevent_req_data(req,
922 struct smbd_smb2_session_setup_state);
923 NTSTATUS status;
925 become_root();
926 status = gensec_update_recv(subreq, state,
927 &state->out_security_buffer);
928 unbecome_root();
929 TALLOC_FREE(subreq);
930 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
931 !NT_STATUS_IS_OK(status)) {
932 tevent_req_nterror(req, status);
933 return;
936 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
937 state->out_session_id = state->session->global->session_wire_id;
938 state->smb2req->preauth = state->auth->preauth;
939 tevent_req_nterror(req, status);
940 return;
943 status = gensec_session_info(state->auth->gensec,
944 state,
945 &state->session_info);
946 if (tevent_req_nterror(req, status)) {
947 return;
950 if ((state->in_previous_session_id != 0) &&
951 (state->session->global->session_wire_id !=
952 state->in_previous_session_id))
954 subreq = smb2srv_session_close_previous_send(state, state->ev,
955 state->smb2req->xconn,
956 state->session_info,
957 state->in_previous_session_id,
958 state->session->global->session_wire_id);
959 if (tevent_req_nomem(subreq, req)) {
960 return;
962 tevent_req_set_callback(subreq,
963 smbd_smb2_session_setup_previous_done,
964 req);
965 return;
968 smbd_smb2_session_setup_auth_return(req);
971 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
973 struct tevent_req *req =
974 tevent_req_callback_data(subreq,
975 struct tevent_req);
976 NTSTATUS status;
978 status = smb2srv_session_close_previous_recv(subreq);
979 TALLOC_FREE(subreq);
980 if (tevent_req_nterror(req, status)) {
981 return;
984 smbd_smb2_session_setup_auth_return(req);
987 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
989 struct smbd_smb2_session_setup_state *state =
990 tevent_req_data(req,
991 struct smbd_smb2_session_setup_state);
992 NTSTATUS status;
994 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
995 status = smbd_smb2_bind_auth_return(state->session,
996 &state->auth,
997 state->smb2req,
998 state->session_info,
999 &state->out_session_flags,
1000 &state->out_session_id);
1001 if (tevent_req_nterror(req, status)) {
1002 return;
1004 tevent_req_done(req);
1005 return;
1008 if (state->session->global->auth_session_info != NULL) {
1009 status = smbd_smb2_reauth_generic_return(state->session,
1010 &state->auth,
1011 state->smb2req,
1012 state->session_info,
1013 &state->out_session_flags,
1014 &state->out_session_id);
1015 if (tevent_req_nterror(req, status)) {
1016 return;
1018 tevent_req_done(req);
1019 return;
1022 status = smbd_smb2_auth_generic_return(state->session,
1023 &state->auth,
1024 state->smb2req,
1025 state->in_security_mode,
1026 state->session_info,
1027 &state->out_session_flags,
1028 &state->out_session_id);
1029 if (tevent_req_nterror(req, status)) {
1030 return;
1033 tevent_req_done(req);
1034 return;
1037 static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1038 uint16_t *out_session_flags,
1039 TALLOC_CTX *mem_ctx,
1040 DATA_BLOB *out_security_buffer,
1041 uint64_t *out_session_id)
1043 struct smbd_smb2_session_setup_state *state =
1044 tevent_req_data(req,
1045 struct smbd_smb2_session_setup_state);
1046 NTSTATUS status;
1048 if (tevent_req_is_nterror(req, &status)) {
1049 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1050 tevent_req_received(req);
1051 return nt_status_squash(status);
1053 } else {
1054 status = NT_STATUS_OK;
1057 *out_session_flags = state->out_session_flags;
1058 *out_security_buffer = state->out_security_buffer;
1059 *out_session_id = state->out_session_id;
1061 talloc_steal(mem_ctx, out_security_buffer->data);
1062 tevent_req_received(req);
1063 return status;
1066 struct smbd_smb2_session_setup_wrap_state {
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 uint16_t out_session_flags;
1075 DATA_BLOB out_security_buffer;
1076 uint64_t out_session_id;
1077 NTSTATUS error;
1080 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1081 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1083 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1084 struct tevent_context *ev,
1085 struct smbd_smb2_request *smb2req,
1086 uint64_t in_session_id,
1087 uint8_t in_flags,
1088 uint8_t in_security_mode,
1089 uint64_t in_previous_session_id,
1090 DATA_BLOB in_security_buffer)
1092 struct tevent_req *req;
1093 struct smbd_smb2_session_setup_wrap_state *state;
1094 struct tevent_req *subreq;
1096 req = tevent_req_create(mem_ctx, &state,
1097 struct smbd_smb2_session_setup_wrap_state);
1098 if (req == NULL) {
1099 return NULL;
1101 state->ev = ev;
1102 state->smb2req = smb2req;
1103 state->in_session_id = in_session_id;
1104 state->in_flags = in_flags;
1105 state->in_security_mode = in_security_mode;
1106 state->in_previous_session_id = in_previous_session_id;
1107 state->in_security_buffer = in_security_buffer;
1109 subreq = smbd_smb2_session_setup_send(state, state->ev,
1110 state->smb2req,
1111 state->in_session_id,
1112 state->in_flags,
1113 state->in_security_mode,
1114 state->in_previous_session_id,
1115 state->in_security_buffer);
1116 if (tevent_req_nomem(subreq, req)) {
1117 return tevent_req_post(req, ev);
1119 tevent_req_set_callback(subreq,
1120 smbd_smb2_session_setup_wrap_setup_done, req);
1122 return req;
1125 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1127 struct tevent_req *req =
1128 tevent_req_callback_data(subreq,
1129 struct tevent_req);
1130 struct smbd_smb2_session_setup_wrap_state *state =
1131 tevent_req_data(req,
1132 struct smbd_smb2_session_setup_wrap_state);
1133 NTSTATUS status;
1135 status = smbd_smb2_session_setup_recv(subreq,
1136 &state->out_session_flags,
1137 state,
1138 &state->out_security_buffer,
1139 &state->out_session_id);
1140 TALLOC_FREE(subreq);
1141 if (NT_STATUS_IS_OK(status)) {
1142 tevent_req_done(req);
1143 return;
1145 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1146 tevent_req_nterror(req, status);
1147 return;
1150 if (state->smb2req->session == NULL) {
1151 tevent_req_nterror(req, status);
1152 return;
1155 state->error = status;
1157 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1158 status = smbXsrv_session_remove_channel(state->smb2req->session,
1159 state->smb2req->xconn);
1160 if (tevent_req_nterror(req, status)) {
1161 return;
1163 tevent_req_nterror(req, state->error);
1164 return;
1167 if (NT_STATUS_EQUAL(state->error, NT_STATUS_USER_SESSION_DELETED)) {
1168 tevent_req_nterror(req, state->error);
1169 return;
1172 subreq = smb2srv_session_shutdown_send(state, state->ev,
1173 state->smb2req->session,
1174 state->smb2req);
1175 if (tevent_req_nomem(subreq, req)) {
1176 return;
1178 tevent_req_set_callback(subreq,
1179 smbd_smb2_session_setup_wrap_shutdown_done,
1180 req);
1183 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1185 struct tevent_req *req =
1186 tevent_req_callback_data(subreq,
1187 struct tevent_req);
1188 struct smbd_smb2_session_setup_wrap_state *state =
1189 tevent_req_data(req,
1190 struct smbd_smb2_session_setup_wrap_state);
1191 NTSTATUS status;
1193 status = smb2srv_session_shutdown_recv(subreq);
1194 TALLOC_FREE(subreq);
1195 if (tevent_req_nterror(req, status)) {
1196 return;
1200 * we may need to sign the response, so we need to keep
1201 * the session until the response is sent to the wire.
1203 talloc_steal(state->smb2req, state->smb2req->session);
1205 tevent_req_nterror(req, state->error);
1208 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1209 uint16_t *out_session_flags,
1210 TALLOC_CTX *mem_ctx,
1211 DATA_BLOB *out_security_buffer,
1212 uint64_t *out_session_id)
1214 struct smbd_smb2_session_setup_wrap_state *state =
1215 tevent_req_data(req,
1216 struct smbd_smb2_session_setup_wrap_state);
1217 NTSTATUS status;
1219 if (tevent_req_is_nterror(req, &status)) {
1220 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1221 tevent_req_received(req);
1222 return nt_status_squash(status);
1224 } else {
1225 status = NT_STATUS_OK;
1228 *out_session_flags = state->out_session_flags;
1229 *out_security_buffer = state->out_security_buffer;
1230 *out_session_id = state->out_session_id;
1232 talloc_steal(mem_ctx, out_security_buffer->data);
1233 tevent_req_received(req);
1234 return status;
1237 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1238 struct tevent_context *ev,
1239 struct smbd_smb2_request *smb2req);
1240 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1241 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1243 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1245 NTSTATUS status;
1246 struct tevent_req *subreq = NULL;
1248 status = smbd_smb2_request_verify_sizes(req, 0x04);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 return smbd_smb2_request_error(req, status);
1253 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1254 if (subreq == NULL) {
1255 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1257 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1260 * Avoid sending a STATUS_PENDING message, it's very likely
1261 * the client won't expect that.
1263 return smbd_smb2_request_pending_queue(req, subreq, 0);
1266 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1268 struct smbd_smb2_request *smb2req =
1269 tevent_req_callback_data(subreq,
1270 struct smbd_smb2_request);
1271 DATA_BLOB outbody;
1272 NTSTATUS status;
1273 NTSTATUS error;
1275 status = smbd_smb2_logoff_recv(subreq);
1276 TALLOC_FREE(subreq);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 error = smbd_smb2_request_error(smb2req, status);
1279 if (!NT_STATUS_IS_OK(error)) {
1280 smbd_server_connection_terminate(smb2req->xconn,
1281 nt_errstr(error));
1282 return;
1284 return;
1287 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1288 if (outbody.data == NULL) {
1289 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1290 if (!NT_STATUS_IS_OK(error)) {
1291 smbd_server_connection_terminate(smb2req->xconn,
1292 nt_errstr(error));
1293 return;
1295 return;
1298 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1299 SSVAL(outbody.data, 0x02, 0); /* reserved */
1301 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1302 if (!NT_STATUS_IS_OK(error)) {
1303 smbd_server_connection_terminate(smb2req->xconn,
1304 nt_errstr(error));
1305 return;
1309 struct smbd_smb2_logoff_state {
1310 struct smbd_smb2_request *smb2req;
1313 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1315 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1316 struct tevent_context *ev,
1317 struct smbd_smb2_request *smb2req)
1319 struct tevent_req *req;
1320 struct smbd_smb2_logoff_state *state;
1321 struct tevent_req *subreq;
1323 req = tevent_req_create(mem_ctx, &state,
1324 struct smbd_smb2_logoff_state);
1325 if (req == NULL) {
1326 return NULL;
1328 state->smb2req = smb2req;
1330 subreq = smb2srv_session_shutdown_send(state, ev,
1331 smb2req->session,
1332 smb2req);
1333 if (tevent_req_nomem(subreq, req)) {
1334 return tevent_req_post(req, ev);
1336 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1338 return req;
1341 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1343 struct tevent_req *req = tevent_req_callback_data(
1344 subreq, struct tevent_req);
1345 struct smbd_smb2_logoff_state *state = tevent_req_data(
1346 req, struct smbd_smb2_logoff_state);
1347 NTSTATUS status;
1348 bool ok;
1349 const struct GUID *client_guid =
1350 &state->smb2req->session->client->global->client_guid;
1352 status = smb2srv_session_shutdown_recv(subreq);
1353 if (tevent_req_nterror(req, status)) {
1354 return;
1356 TALLOC_FREE(subreq);
1358 if (!GUID_all_zero(client_guid)) {
1359 ok = remote_arch_cache_delete(client_guid);
1360 if (!ok) {
1361 /* Most likely not an error, but not in cache */
1362 DBG_DEBUG("Deletion from remote arch cache failed\n");
1367 * As we've been awoken, we may have changed
1368 * uid in the meantime. Ensure we're still
1369 * root (SMB2_OP_LOGOFF has .as_root = true).
1371 change_to_root_user();
1373 status = smbXsrv_session_logoff(state->smb2req->session);
1374 if (tevent_req_nterror(req, status)) {
1375 return;
1379 * we may need to sign the response, so we need to keep
1380 * the session until the response is sent to the wire.
1382 talloc_steal(state->smb2req, state->smb2req->session);
1384 tevent_req_done(req);
1387 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1389 return tevent_req_simple_recv_ntstatus(req);