source: vendor/current/source3/smbd/smb2_sesssetup.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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