2 Unix SMB/CIFS implementation.
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/>.
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../auth/gensec/gensec.h"
28 #include "../lib/tsocket/tsocket.h"
29 #include "../libcli/security/security.h"
30 #include "../lib/util/tevent_ntstatus.h"
32 #include "lib/crypto/gnutls_helpers.h"
33 #include <gnutls/gnutls.h>
34 #include <gnutls/crypto.h>
37 #define DBGC_CLASS DBGC_SMB2
39 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
40 struct tevent_context *ev,
41 struct smbd_smb2_request *smb2req,
42 uint64_t in_session_id,
44 uint8_t in_security_mode,
45 uint64_t in_previous_session_id,
46 DATA_BLOB in_security_buffer);
47 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
48 uint16_t *out_session_flags,
50 DATA_BLOB *out_security_buffer,
51 uint64_t *out_session_id);
53 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
55 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
58 const uint8_t *inbody;
59 uint64_t in_session_id;
61 uint8_t in_security_mode;
62 uint64_t in_previous_session_id;
63 uint16_t in_security_offset;
64 uint16_t in_security_length;
65 DATA_BLOB in_security_buffer;
67 struct tevent_req *subreq;
69 status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
70 if (!NT_STATUS_IS_OK(status)) {
71 return smbd_smb2_request_error(smb2req, status);
73 inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
74 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
76 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
78 in_flags = CVAL(inbody, 0x02);
79 in_security_mode = CVAL(inbody, 0x03);
80 /* Capabilities = IVAL(inbody, 0x04) */
81 /* Channel = IVAL(inbody, 0x08) */
82 in_security_offset = SVAL(inbody, 0x0C);
83 in_security_length = SVAL(inbody, 0x0E);
84 in_previous_session_id = BVAL(inbody, 0x10);
86 if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
87 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
90 if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
91 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
94 in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
95 in_security_buffer.length = in_security_length;
97 subreq = smbd_smb2_session_setup_wrap_send(smb2req,
98 smb2req->sconn->ev_ctx,
103 in_previous_session_id,
105 if (subreq == NULL) {
106 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
108 tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
111 * Avoid sending a STATUS_PENDING message, which
112 * matches a Windows Server and avoids problems with
115 * Even after 90 seconds a Windows Server doesn't return
116 * STATUS_PENDING if using NTLMSSP against a non reachable
119 return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
122 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
124 struct smbd_smb2_request *smb2req =
125 tevent_req_callback_data(subreq,
126 struct smbd_smb2_request);
130 uint16_t out_session_flags = 0;
131 uint64_t out_session_id = 0;
132 uint16_t out_security_offset;
133 DATA_BLOB out_security_buffer = data_blob_null;
135 NTSTATUS error; /* transport error */
137 status = smbd_smb2_session_setup_wrap_recv(subreq,
140 &out_security_buffer,
143 if (!NT_STATUS_IS_OK(status) &&
144 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
145 status = nt_status_squash(status);
146 error = smbd_smb2_request_error(smb2req, status);
147 if (!NT_STATUS_IS_OK(error)) {
148 smbd_server_connection_terminate(smb2req->xconn,
155 out_security_offset = SMB2_HDR_BODY + 0x08;
157 outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
159 outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
160 if (outbody.data == NULL) {
161 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
162 if (!NT_STATUS_IS_OK(error)) {
163 smbd_server_connection_terminate(smb2req->xconn,
170 SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
172 SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
173 SSVAL(outbody.data, 0x02,
174 out_session_flags); /* session flags */
175 SSVAL(outbody.data, 0x04,
176 out_security_offset); /* security buffer offset */
177 SSVAL(outbody.data, 0x06,
178 out_security_buffer.length); /* security buffer length */
180 outdyn = out_security_buffer;
182 error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
184 if (!NT_STATUS_IS_OK(error)) {
185 smbd_server_connection_terminate(smb2req->xconn,
191 static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
192 struct smbXsrv_session_auth0 **_auth,
193 struct smbd_smb2_request *smb2req,
194 uint8_t in_security_mode,
195 struct auth_session_info *session_info,
196 uint16_t *out_session_flags,
197 uint64_t *out_session_id)
201 uint8_t session_key[16];
202 struct smbXsrv_session *x = session;
203 struct smbXsrv_session_auth0 *auth = *_auth;
204 struct smbXsrv_connection *xconn = smb2req->xconn;
211 struct _derivation signing;
212 struct _derivation encryption;
213 struct _derivation decryption;
214 struct _derivation application;
219 if (xconn->protocol >= PROTOCOL_SMB3_10) {
220 struct smbXsrv_preauth *preauth;
221 struct _derivation *d;
223 gnutls_hash_hd_t hash_hnd;
226 preauth = talloc_move(smb2req, &auth->preauth);
228 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
230 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
232 rc = gnutls_hash(hash_hnd,
233 preauth->sha512_value,
234 sizeof(preauth->sha512_value));
236 gnutls_hash_deinit(hash_hnd, NULL);
237 return NT_STATUS_ACCESS_DENIED;
239 for (i = 1; i < smb2req->in.vector_count; i++) {
240 rc = gnutls_hash(hash_hnd,
241 smb2req->in.vector[i].iov_base,
242 smb2req->in.vector[i].iov_len);
244 gnutls_hash_deinit(hash_hnd, NULL);
245 return NT_STATUS_ACCESS_DENIED;
248 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
250 p = data_blob_const(preauth->sha512_value,
251 sizeof(preauth->sha512_value));
253 d = &derivation.signing;
254 d->label = data_blob_string_const_null("SMBSigningKey");
257 d = &derivation.decryption;
258 d->label = data_blob_string_const_null("SMBC2SCipherKey");
261 d = &derivation.encryption;
262 d->label = data_blob_string_const_null("SMBS2CCipherKey");
265 d = &derivation.application;
266 d->label = data_blob_string_const_null("SMBAppKey");
269 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
270 struct _derivation *d;
272 d = &derivation.signing;
273 d->label = data_blob_string_const_null("SMB2AESCMAC");
274 d->context = data_blob_string_const_null("SmbSign");
276 d = &derivation.decryption;
277 d->label = data_blob_string_const_null("SMB2AESCCM");
278 d->context = data_blob_string_const_null("ServerIn ");
280 d = &derivation.encryption;
281 d->label = data_blob_string_const_null("SMB2AESCCM");
282 d->context = data_blob_string_const_null("ServerOut");
284 d = &derivation.application;
285 d->label = data_blob_string_const_null("SMB2APP");
286 d->context = data_blob_string_const_null("SmbRpc");
289 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
290 (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
292 x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
295 if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
296 (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
297 x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
300 if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
301 x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
302 SMBXSRV_ENCRYPTION_DESIRED;
305 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
306 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
307 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
309 /* force no signing */
310 x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
311 /* we map anonymous to guest internally */
315 if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
316 DEBUG(1,("reject guest session as encryption is required\n"));
317 return NT_STATUS_ACCESS_DENIED;
320 if (xconn->smb2.server.cipher == 0) {
321 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
322 DEBUG(1,("reject session with dialect[0x%04X] "
323 "as encryption is required\n",
324 xconn->smb2.server.dialect));
325 return NT_STATUS_ACCESS_DENIED;
328 x->global->channels[0].encryption_cipher = xconn->smb2.server.cipher;
331 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
332 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
335 ZERO_STRUCT(session_key);
336 memcpy(session_key, session_info->session_key.data,
337 MIN(session_info->session_key.length, sizeof(session_key)));
339 x->global->signing_key = talloc_zero(x->global,
340 struct smb2_signing_key);
341 if (x->global->signing_key == NULL) {
342 ZERO_STRUCT(session_key);
343 return NT_STATUS_NO_MEMORY;
345 talloc_set_destructor(x->global->signing_key,
346 smb2_signing_key_destructor);
348 x->global->signing_key->blob =
349 x->global->signing_key_blob =
350 data_blob_talloc(x->global,
352 sizeof(session_key));
353 if (!smb2_signing_key_valid(x->global->signing_key)) {
354 ZERO_STRUCT(session_key);
355 return NT_STATUS_NO_MEMORY;
358 if (xconn->protocol >= PROTOCOL_SMB2_24) {
359 struct _derivation *d = &derivation.signing;
361 status = smb2_key_derivation(session_key, sizeof(session_key),
362 d->label.data, d->label.length,
363 d->context.data, d->context.length,
364 x->global->signing_key->blob.data);
365 if (!NT_STATUS_IS_OK(status)) {
370 if (xconn->protocol >= PROTOCOL_SMB2_24) {
371 struct _derivation *d = &derivation.decryption;
373 x->global->decryption_key =
374 talloc_zero(x->global, struct smb2_signing_key);
375 if (x->global->decryption_key == NULL) {
376 ZERO_STRUCT(session_key);
377 return NT_STATUS_NO_MEMORY;
380 x->global->decryption_key->blob =
381 x->global->decryption_key_blob =
382 data_blob_talloc(x->global->decryption_key,
384 sizeof(session_key));
385 if (!smb2_signing_key_valid(x->global->decryption_key)) {
386 ZERO_STRUCT(session_key);
387 return NT_STATUS_NO_MEMORY;
389 talloc_keep_secret(x->global->decryption_key->blob.data);
391 status = smb2_key_derivation(session_key, sizeof(session_key),
392 d->label.data, d->label.length,
393 d->context.data, d->context.length,
394 x->global->decryption_key->blob.data);
395 if (!NT_STATUS_IS_OK(status)) {
400 if (xconn->protocol >= PROTOCOL_SMB2_24) {
401 struct _derivation *d = &derivation.encryption;
404 x->global->encryption_key =
405 talloc_zero(x->global, struct smb2_signing_key);
406 if (x->global->encryption_key == NULL) {
407 ZERO_STRUCT(session_key);
408 return NT_STATUS_NO_MEMORY;
411 x->global->encryption_key->blob =
412 x->global->encryption_key_blob =
413 data_blob_talloc(x->global->encryption_key,
415 sizeof(session_key));
416 if (!smb2_signing_key_valid(x->global->encryption_key)) {
417 ZERO_STRUCT(session_key);
418 return NT_STATUS_NO_MEMORY;
420 talloc_keep_secret(x->global->encryption_key->blob.data);
422 status = smb2_key_derivation(session_key, sizeof(session_key),
423 d->label.data, d->label.length,
424 d->context.data, d->context.length,
425 x->global->encryption_key->blob.data);
426 if (!NT_STATUS_IS_OK(status)) {
431 * CCM and GCM algorithms must never have their
432 * nonce wrap, or the security of the whole
433 * communication and the keys is destroyed.
434 * We must drop the connection once we have
435 * transfered too much data.
437 * NOTE: We assume nonces greater than 8 bytes.
439 generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
440 sizeof(x->nonce_high_random));
441 switch (xconn->smb2.server.cipher) {
442 case SMB2_ENCRYPTION_AES128_CCM:
443 nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
445 case SMB2_ENCRYPTION_AES128_GCM:
446 nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
452 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
457 x->global->application_key =
458 data_blob_dup_talloc(x->global, x->global->signing_key->blob);
459 if (x->global->application_key.data == NULL) {
460 ZERO_STRUCT(session_key);
461 return NT_STATUS_NO_MEMORY;
463 talloc_keep_secret(x->global->application_key.data);
465 if (xconn->protocol >= PROTOCOL_SMB2_24) {
466 struct _derivation *d = &derivation.application;
468 status = smb2_key_derivation(session_key, sizeof(session_key),
469 d->label.data, d->label.length,
470 d->context.data, d->context.length,
471 x->global->application_key.data);
472 if (!NT_STATUS_IS_OK(status)) {
477 if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
478 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
479 DEBUGADD(0, ("Session Id "));
480 dump_data(0, (uint8_t*)&session->global->session_wire_id,
481 sizeof(session->global->session_wire_id));
482 DEBUGADD(0, ("Session Key "));
483 dump_data(0, session_key, sizeof(session_key));
484 DEBUGADD(0, ("Signing Key "));
485 dump_data(0, x->global->signing_key->blob.data,
486 x->global->signing_key->blob.length);
487 DEBUGADD(0, ("App Key "));
488 dump_data(0, x->global->application_key.data,
489 x->global->application_key.length);
491 /* In server code, ServerIn is the decryption key */
493 DEBUGADD(0, ("ServerIn Key "));
494 dump_data(0, x->global->decryption_key->blob.data,
495 x->global->decryption_key->blob.length);
496 DEBUGADD(0, ("ServerOut Key "));
497 dump_data(0, x->global->encryption_key->blob.data,
498 x->global->encryption_key->blob.length);
501 ZERO_STRUCT(session_key);
503 x->global->channels[0].signing_key =
504 talloc_zero(x->global->channels, struct smb2_signing_key);
505 if (x->global->channels[0].signing_key == NULL) {
506 return NT_STATUS_NO_MEMORY;
508 talloc_set_destructor(x->global->channels[0].signing_key,
509 smb2_signing_key_destructor);
511 x->global->channels[0].signing_key->blob =
512 x->global->channels[0].signing_key_blob =
513 data_blob_dup_talloc(x->global->channels[0].signing_key,
514 x->global->signing_key->blob);
515 if (!smb2_signing_key_valid(x->global->channels[0].signing_key)) {
516 return NT_STATUS_NO_MEMORY;
518 talloc_keep_secret(x->global->channels[0].signing_key->blob.data);
520 data_blob_clear_free(&session_info->session_key);
521 session_info->session_key = data_blob_dup_talloc(session_info,
522 x->global->application_key);
523 if (session_info->session_key.data == NULL) {
524 return NT_STATUS_NO_MEMORY;
526 talloc_keep_secret(session_info->session_key.data);
528 smb2req->sconn->num_users++;
530 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
531 session->homes_snum =
532 register_homes_share(session_info->unix_info->unix_name);
535 set_current_user_info(session_info->unix_info->sanitized_username,
536 session_info->unix_info->unix_name,
537 session_info->info->domain_name);
539 reload_services(smb2req->sconn, conn_snum_used, true);
541 session->status = NT_STATUS_OK;
542 session->global->auth_session_info = talloc_move(session->global,
544 session->global->auth_session_info_seqnum += 1;
545 for (i=0; i < session->global->num_channels; i++) {
546 struct smbXsrv_channel_global0 *_c =
547 &session->global->channels[i];
549 _c->auth_session_info_seqnum =
550 session->global->auth_session_info_seqnum;
552 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
553 session->global->expiration_time = gensec_expire_time(auth->gensec);
555 if (!session_claim(session)) {
556 DEBUG(1, ("smb2: Failed to claim session "
558 (unsigned long long)session->global->session_wire_id));
559 return NT_STATUS_LOGON_FAILURE;
563 status = smbXsrv_session_update(session);
564 if (!NT_STATUS_IS_OK(status)) {
565 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
566 (unsigned long long)session->global->session_wire_id,
568 return NT_STATUS_LOGON_FAILURE;
572 * we attach the session to the request
573 * so that the response can be signed
576 smb2req->do_signing = true;
579 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
581 *out_session_id = session->global->session_wire_id;
582 smb2req->last_session_id = session->global->session_wire_id;
587 static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
588 struct smbXsrv_session_auth0 **_auth,
589 struct smbd_smb2_request *smb2req,
590 struct auth_session_info *session_info,
591 uint16_t *out_session_flags,
592 uint64_t *out_session_id)
595 struct smbXsrv_session *x = session;
596 struct smbXsrv_session_auth0 *auth = *_auth;
597 struct smbXsrv_connection *xconn = smb2req->xconn;
602 data_blob_clear_free(&session_info->session_key);
603 session_info->session_key = data_blob_dup_talloc(session_info,
604 x->global->application_key);
605 if (session_info->session_key.data == NULL) {
606 return NT_STATUS_NO_MEMORY;
608 talloc_keep_secret(session_info->session_key.data);
610 session->homes_snum =
611 register_homes_share(session_info->unix_info->unix_name);
613 set_current_user_info(session_info->unix_info->sanitized_username,
614 session_info->unix_info->unix_name,
615 session_info->info->domain_name);
617 reload_services(smb2req->sconn, conn_snum_used, true);
619 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
620 smb2req->do_signing = true;
623 session->status = NT_STATUS_OK;
624 TALLOC_FREE(session->global->auth_session_info);
625 session->global->auth_session_info = talloc_move(session->global,
627 session->global->auth_session_info_seqnum += 1;
628 for (i=0; i < session->global->num_channels; i++) {
629 struct smbXsrv_channel_global0 *_c =
630 &session->global->channels[i];
632 _c->auth_session_info_seqnum =
633 session->global->auth_session_info_seqnum;
635 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
636 session->global->expiration_time = gensec_expire_time(auth->gensec);
639 status = smbXsrv_session_update(session);
640 if (!NT_STATUS_IS_OK(status)) {
641 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
642 (unsigned long long)session->global->session_wire_id,
644 return NT_STATUS_LOGON_FAILURE;
647 conn_clear_vuid_caches(xconn->client->sconn,
648 session->global->session_wire_id);
650 *out_session_id = session->global->session_wire_id;
655 static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
656 struct smbXsrv_session_auth0 **_auth,
657 struct smbd_smb2_request *smb2req,
658 struct auth_session_info *session_info,
659 uint16_t *out_session_flags,
660 uint64_t *out_session_id)
663 struct smbXsrv_session *x = session;
664 struct smbXsrv_session_auth0 *auth = *_auth;
665 struct smbXsrv_connection *xconn = smb2req->xconn;
666 struct smbXsrv_channel_global0 *c = NULL;
667 uint8_t session_key[16];
674 struct _derivation signing;
680 if (xconn->protocol >= PROTOCOL_SMB3_10) {
681 struct smbXsrv_preauth *preauth;
682 struct _derivation *d;
684 gnutls_hash_hd_t hash_hnd = NULL;
687 preauth = talloc_move(smb2req, &auth->preauth);
689 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
691 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
694 rc = gnutls_hash(hash_hnd,
695 preauth->sha512_value,
696 sizeof(preauth->sha512_value));
698 gnutls_hash_deinit(hash_hnd, NULL);
699 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
701 for (i = 1; i < smb2req->in.vector_count; i++) {
702 rc = gnutls_hash(hash_hnd,
703 smb2req->in.vector[i].iov_base,
704 smb2req->in.vector[i].iov_len);
706 gnutls_hash_deinit(hash_hnd, NULL);
707 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
710 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
712 p = data_blob_const(preauth->sha512_value,
713 sizeof(preauth->sha512_value));
715 d = &derivation.signing;
716 d->label = data_blob_string_const_null("SMBSigningKey");
719 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
720 struct _derivation *d;
722 d = &derivation.signing;
723 d->label = data_blob_string_const_null("SMB2AESCMAC");
724 d->context = data_blob_string_const_null("SmbSign");
727 status = smbXsrv_session_find_channel(session, xconn, &c);
728 if (!NT_STATUS_IS_OK(status)) {
732 ok = security_token_is_sid(session_info->security_token,
733 &x->global->auth_session_info->security_token->sids[0]);
735 return NT_STATUS_NOT_SUPPORTED;
738 if (session_info->session_key.length == 0) {
739 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
740 return NT_STATUS_NOT_SUPPORTED;
743 ZERO_STRUCT(session_key);
744 memcpy(session_key, session_info->session_key.data,
745 MIN(session_info->session_key.length, sizeof(session_key)));
747 c->signing_key = talloc_zero(x->global, struct smb2_signing_key);
748 if (c->signing_key == NULL) {
749 ZERO_STRUCT(session_key);
750 return NT_STATUS_NO_MEMORY;
752 talloc_set_destructor(c->signing_key,
753 smb2_signing_key_destructor);
755 c->signing_key->blob =
756 c->signing_key_blob =
757 data_blob_talloc(c->signing_key,
759 sizeof(session_key));
760 if (!smb2_signing_key_valid(c->signing_key)) {
761 ZERO_STRUCT(session_key);
762 return NT_STATUS_NO_MEMORY;
764 talloc_keep_secret(c->signing_key->blob.data);
766 if (xconn->protocol >= PROTOCOL_SMB2_24) {
767 struct _derivation *d = &derivation.signing;
769 status = smb2_key_derivation(session_key, sizeof(session_key),
770 d->label.data, d->label.length,
771 d->context.data, d->context.length,
772 c->signing_key->blob.data);
773 if (!NT_STATUS_IS_OK(status)) {
777 ZERO_STRUCT(session_key);
780 status = smbXsrv_session_update(session);
781 if (!NT_STATUS_IS_OK(status)) {
782 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
783 (unsigned long long)session->global->session_wire_id,
785 return NT_STATUS_LOGON_FAILURE;
788 *out_session_id = session->global->session_wire_id;
793 struct smbd_smb2_session_setup_state {
794 struct tevent_context *ev;
795 struct smbd_smb2_request *smb2req;
796 uint64_t in_session_id;
798 uint8_t in_security_mode;
799 uint64_t in_previous_session_id;
800 DATA_BLOB in_security_buffer;
801 struct smbXsrv_session *session;
802 struct smbXsrv_session_auth0 *auth;
803 struct auth_session_info *session_info;
804 uint16_t out_session_flags;
805 DATA_BLOB out_security_buffer;
806 uint64_t out_session_id;
809 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
810 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
811 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
813 static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
814 struct tevent_context *ev,
815 struct smbd_smb2_request *smb2req,
816 uint64_t in_session_id,
818 uint8_t in_security_mode,
819 uint64_t in_previous_session_id,
820 DATA_BLOB in_security_buffer)
822 struct tevent_req *req;
823 struct smbd_smb2_session_setup_state *state;
825 NTTIME now = timeval_to_nttime(&smb2req->request_time);
826 struct tevent_req *subreq;
827 struct smbXsrv_channel_global0 *c = NULL;
828 enum security_user_level seclvl;
830 req = tevent_req_create(mem_ctx, &state,
831 struct smbd_smb2_session_setup_state);
836 state->smb2req = smb2req;
837 state->in_session_id = in_session_id;
838 state->in_flags = in_flags;
839 state->in_security_mode = in_security_mode;
840 state->in_previous_session_id = in_previous_session_id;
841 state->in_security_buffer = in_security_buffer;
843 if (in_flags & SMB2_SESSION_FLAG_BINDING) {
844 if (smb2req->xconn->protocol < PROTOCOL_SMB2_22) {
845 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
846 return tevent_req_post(req, ev);
849 if (!smb2req->xconn->client->server_multi_channel_enabled) {
850 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
851 return tevent_req_post(req, ev);
854 if (in_session_id == 0) {
855 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
856 return tevent_req_post(req, ev);
859 if (smb2req->session == NULL) {
860 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
861 return tevent_req_post(req, ev);
864 if (!smb2req->do_signing) {
865 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
866 return tevent_req_post(req, ev);
869 status = smbXsrv_session_find_channel(smb2req->session,
872 if (NT_STATUS_IS_OK(status)) {
873 if (!smb2_signing_key_valid(c->signing_key)) {
876 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
877 return tevent_req_post(req, ev);
881 * OLD: 3.00 NEW 3.02 => INVALID_PARAMETER
882 * OLD: 3.02 NEW 3.00 => INVALID_PARAMETER
883 * OLD: 2.10 NEW 3.02 => ACCESS_DENIED
884 * OLD: 3.02 NEW 2.10 => ACCESS_DENIED
886 if (smb2req->session->global->connection_dialect
887 < SMB2_DIALECT_REVISION_222)
889 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
890 return tevent_req_post(req, ev);
892 if (smb2req->xconn->smb2.server.dialect
893 < SMB2_DIALECT_REVISION_222)
895 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
896 return tevent_req_post(req, ev);
898 if (smb2req->session->global->connection_dialect
899 != smb2req->xconn->smb2.server.dialect)
901 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
902 return tevent_req_post(req, ev);
905 seclvl = security_session_user_level(
906 smb2req->session->global->auth_session_info,
908 if (seclvl < SECURITY_USER) {
909 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
910 return tevent_req_post(req, ev);
913 status = smbXsrv_session_add_channel(smb2req->session,
917 if (!NT_STATUS_IS_OK(status)) {
918 tevent_req_nterror(req, status);
919 return tevent_req_post(req, ev);
922 status = smbXsrv_session_update(smb2req->session);
923 if (!NT_STATUS_IS_OK(status)) {
924 tevent_req_nterror(req, status);
925 return tevent_req_post(req, ev);
931 if (state->in_session_id == 0) {
932 /* create a new session */
933 status = smbXsrv_session_create(state->smb2req->xconn,
934 now, &state->session);
935 if (tevent_req_nterror(req, status)) {
936 return tevent_req_post(req, ev);
938 smb2req->session = state->session;
940 if (smb2req->session == NULL) {
941 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
942 return tevent_req_post(req, ev);
945 state->session = smb2req->session;
946 status = state->session->status;
947 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
948 status = NT_STATUS_OK;
950 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
951 status = NT_STATUS_OK;
953 if (tevent_req_nterror(req, status)) {
954 return tevent_req_post(req, ev);
956 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
957 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
961 status = smbXsrv_session_find_channel(smb2req->session,
963 if (!NT_STATUS_IS_OK(status)) {
964 tevent_req_nterror(req, status);
965 return tevent_req_post(req, ev);
968 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
970 if (!NT_STATUS_IS_OK(status)) {
971 status = smbXsrv_session_create_auth(state->session,
973 in_flags, in_security_mode,
975 if (tevent_req_nterror(req, status)) {
976 return tevent_req_post(req, ev);
980 if (state->auth->gensec == NULL) {
981 status = auth_generic_prepare(state->auth,
982 state->smb2req->xconn->remote_address,
983 state->smb2req->xconn->local_address,
985 &state->auth->gensec);
986 if (tevent_req_nterror(req, status)) {
987 return tevent_req_post(req, ev);
990 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
991 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
992 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
994 status = gensec_start_mech_by_oid(state->auth->gensec,
996 if (tevent_req_nterror(req, status)) {
997 return tevent_req_post(req, ev);
1001 status = smbXsrv_session_update(state->session);
1002 if (tevent_req_nterror(req, status)) {
1003 return tevent_req_post(req, ev);
1007 subreq = gensec_update_send(state, state->ev,
1008 state->auth->gensec,
1009 state->in_security_buffer);
1011 if (tevent_req_nomem(subreq, req)) {
1012 return tevent_req_post(req, ev);
1014 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
1019 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
1021 struct tevent_req *req =
1022 tevent_req_callback_data(subreq,
1024 struct smbd_smb2_session_setup_state *state =
1025 tevent_req_data(req,
1026 struct smbd_smb2_session_setup_state);
1030 status = gensec_update_recv(subreq, state,
1031 &state->out_security_buffer);
1033 TALLOC_FREE(subreq);
1034 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
1035 !NT_STATUS_IS_OK(status)) {
1036 tevent_req_nterror(req, status);
1040 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1041 state->out_session_id = state->session->global->session_wire_id;
1042 state->smb2req->preauth = state->auth->preauth;
1043 tevent_req_nterror(req, status);
1047 status = gensec_session_info(state->auth->gensec,
1049 &state->session_info);
1050 if (tevent_req_nterror(req, status)) {
1054 if ((state->in_previous_session_id != 0) &&
1055 (state->session->global->session_wire_id !=
1056 state->in_previous_session_id))
1058 subreq = smb2srv_session_close_previous_send(state, state->ev,
1059 state->smb2req->xconn,
1060 state->session_info,
1061 state->in_previous_session_id,
1062 state->session->global->session_wire_id);
1063 if (tevent_req_nomem(subreq, req)) {
1066 tevent_req_set_callback(subreq,
1067 smbd_smb2_session_setup_previous_done,
1072 smbd_smb2_session_setup_auth_return(req);
1075 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
1077 struct tevent_req *req =
1078 tevent_req_callback_data(subreq,
1082 status = smb2srv_session_close_previous_recv(subreq);
1083 TALLOC_FREE(subreq);
1084 if (tevent_req_nterror(req, status)) {
1088 smbd_smb2_session_setup_auth_return(req);
1091 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
1093 struct smbd_smb2_session_setup_state *state =
1094 tevent_req_data(req,
1095 struct smbd_smb2_session_setup_state);
1098 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1099 status = smbd_smb2_bind_auth_return(state->session,
1102 state->session_info,
1103 &state->out_session_flags,
1104 &state->out_session_id);
1105 if (tevent_req_nterror(req, status)) {
1108 tevent_req_done(req);
1112 if (state->session->global->auth_session_info != NULL) {
1113 status = smbd_smb2_reauth_generic_return(state->session,
1116 state->session_info,
1117 &state->out_session_flags,
1118 &state->out_session_id);
1119 if (tevent_req_nterror(req, status)) {
1122 tevent_req_done(req);
1126 status = smbd_smb2_auth_generic_return(state->session,
1129 state->in_security_mode,
1130 state->session_info,
1131 &state->out_session_flags,
1132 &state->out_session_id);
1133 if (tevent_req_nterror(req, status)) {
1137 tevent_req_done(req);
1141 static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1142 uint16_t *out_session_flags,
1143 TALLOC_CTX *mem_ctx,
1144 DATA_BLOB *out_security_buffer,
1145 uint64_t *out_session_id)
1147 struct smbd_smb2_session_setup_state *state =
1148 tevent_req_data(req,
1149 struct smbd_smb2_session_setup_state);
1152 if (tevent_req_is_nterror(req, &status)) {
1153 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1154 tevent_req_received(req);
1155 return nt_status_squash(status);
1158 status = NT_STATUS_OK;
1161 *out_session_flags = state->out_session_flags;
1162 *out_security_buffer = state->out_security_buffer;
1163 *out_session_id = state->out_session_id;
1165 talloc_steal(mem_ctx, out_security_buffer->data);
1166 tevent_req_received(req);
1170 struct smbd_smb2_session_setup_wrap_state {
1171 struct tevent_context *ev;
1172 struct smbd_smb2_request *smb2req;
1173 uint64_t in_session_id;
1175 uint8_t in_security_mode;
1176 uint64_t in_previous_session_id;
1177 DATA_BLOB in_security_buffer;
1178 uint16_t out_session_flags;
1179 DATA_BLOB out_security_buffer;
1180 uint64_t out_session_id;
1184 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1185 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1187 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1188 struct tevent_context *ev,
1189 struct smbd_smb2_request *smb2req,
1190 uint64_t in_session_id,
1192 uint8_t in_security_mode,
1193 uint64_t in_previous_session_id,
1194 DATA_BLOB in_security_buffer)
1196 struct tevent_req *req;
1197 struct smbd_smb2_session_setup_wrap_state *state;
1198 struct tevent_req *subreq;
1200 req = tevent_req_create(mem_ctx, &state,
1201 struct smbd_smb2_session_setup_wrap_state);
1206 state->smb2req = smb2req;
1207 state->in_session_id = in_session_id;
1208 state->in_flags = in_flags;
1209 state->in_security_mode = in_security_mode;
1210 state->in_previous_session_id = in_previous_session_id;
1211 state->in_security_buffer = in_security_buffer;
1213 subreq = smbd_smb2_session_setup_send(state, state->ev,
1215 state->in_session_id,
1217 state->in_security_mode,
1218 state->in_previous_session_id,
1219 state->in_security_buffer);
1220 if (tevent_req_nomem(subreq, req)) {
1221 return tevent_req_post(req, ev);
1223 tevent_req_set_callback(subreq,
1224 smbd_smb2_session_setup_wrap_setup_done, req);
1229 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1231 struct tevent_req *req =
1232 tevent_req_callback_data(subreq,
1234 struct smbd_smb2_session_setup_wrap_state *state =
1235 tevent_req_data(req,
1236 struct smbd_smb2_session_setup_wrap_state);
1239 status = smbd_smb2_session_setup_recv(subreq,
1240 &state->out_session_flags,
1242 &state->out_security_buffer,
1243 &state->out_session_id);
1244 TALLOC_FREE(subreq);
1245 if (NT_STATUS_IS_OK(status)) {
1246 tevent_req_done(req);
1249 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1250 tevent_req_nterror(req, status);
1254 if (state->smb2req->session == NULL) {
1255 tevent_req_nterror(req, status);
1259 state->error = status;
1261 subreq = smb2srv_session_shutdown_send(state, state->ev,
1262 state->smb2req->session,
1264 if (tevent_req_nomem(subreq, req)) {
1267 tevent_req_set_callback(subreq,
1268 smbd_smb2_session_setup_wrap_shutdown_done,
1272 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1274 struct tevent_req *req =
1275 tevent_req_callback_data(subreq,
1277 struct smbd_smb2_session_setup_wrap_state *state =
1278 tevent_req_data(req,
1279 struct smbd_smb2_session_setup_wrap_state);
1282 status = smb2srv_session_shutdown_recv(subreq);
1283 TALLOC_FREE(subreq);
1284 if (tevent_req_nterror(req, status)) {
1289 * we may need to sign the response, so we need to keep
1290 * the session until the response is sent to the wire.
1292 talloc_steal(state->smb2req, state->smb2req->session);
1294 tevent_req_nterror(req, state->error);
1297 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1298 uint16_t *out_session_flags,
1299 TALLOC_CTX *mem_ctx,
1300 DATA_BLOB *out_security_buffer,
1301 uint64_t *out_session_id)
1303 struct smbd_smb2_session_setup_wrap_state *state =
1304 tevent_req_data(req,
1305 struct smbd_smb2_session_setup_wrap_state);
1308 if (tevent_req_is_nterror(req, &status)) {
1309 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1310 tevent_req_received(req);
1311 return nt_status_squash(status);
1314 status = NT_STATUS_OK;
1317 *out_session_flags = state->out_session_flags;
1318 *out_security_buffer = state->out_security_buffer;
1319 *out_session_id = state->out_session_id;
1321 talloc_steal(mem_ctx, out_security_buffer->data);
1322 tevent_req_received(req);
1326 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1327 struct tevent_context *ev,
1328 struct smbd_smb2_request *smb2req);
1329 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1330 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1332 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1335 struct tevent_req *subreq = NULL;
1337 status = smbd_smb2_request_verify_sizes(req, 0x04);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 return smbd_smb2_request_error(req, status);
1342 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1343 if (subreq == NULL) {
1344 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1346 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1349 * Avoid sending a STATUS_PENDING message, it's very likely
1350 * the client won't expect that.
1352 return smbd_smb2_request_pending_queue(req, subreq, 0);
1355 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1357 struct smbd_smb2_request *smb2req =
1358 tevent_req_callback_data(subreq,
1359 struct smbd_smb2_request);
1364 status = smbd_smb2_logoff_recv(subreq);
1365 TALLOC_FREE(subreq);
1366 if (!NT_STATUS_IS_OK(status)) {
1367 error = smbd_smb2_request_error(smb2req, status);
1368 if (!NT_STATUS_IS_OK(error)) {
1369 smbd_server_connection_terminate(smb2req->xconn,
1376 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1377 if (outbody.data == NULL) {
1378 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1379 if (!NT_STATUS_IS_OK(error)) {
1380 smbd_server_connection_terminate(smb2req->xconn,
1387 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1388 SSVAL(outbody.data, 0x02, 0); /* reserved */
1390 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1391 if (!NT_STATUS_IS_OK(error)) {
1392 smbd_server_connection_terminate(smb2req->xconn,
1398 struct smbd_smb2_logoff_state {
1399 struct smbd_smb2_request *smb2req;
1402 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1404 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1405 struct tevent_context *ev,
1406 struct smbd_smb2_request *smb2req)
1408 struct tevent_req *req;
1409 struct smbd_smb2_logoff_state *state;
1410 struct tevent_req *subreq;
1412 req = tevent_req_create(mem_ctx, &state,
1413 struct smbd_smb2_logoff_state);
1417 state->smb2req = smb2req;
1419 subreq = smb2srv_session_shutdown_send(state, ev,
1422 if (tevent_req_nomem(subreq, req)) {
1423 return tevent_req_post(req, ev);
1425 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1430 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1432 struct tevent_req *req = tevent_req_callback_data(
1433 subreq, struct tevent_req);
1434 struct smbd_smb2_logoff_state *state = tevent_req_data(
1435 req, struct smbd_smb2_logoff_state);
1438 const struct GUID *client_guid =
1439 &state->smb2req->session->client->global->client_guid;
1441 status = smb2srv_session_shutdown_recv(subreq);
1442 if (tevent_req_nterror(req, status)) {
1445 TALLOC_FREE(subreq);
1447 if (!GUID_all_zero(client_guid)) {
1448 ok = remote_arch_cache_delete(client_guid);
1450 /* Most likely not an error, but not in cache */
1451 DBG_DEBUG("Deletion from remote arch cache failed\n");
1456 * As we've been awoken, we may have changed
1457 * uid in the meantime. Ensure we're still
1458 * root (SMB2_OP_LOGOFF has .as_root = true).
1460 change_to_root_user();
1462 status = smbXsrv_session_logoff(state->smb2req->session);
1463 if (tevent_req_nterror(req, status)) {
1468 * we may need to sign the response, so we need to keep
1469 * the session until the response is sent to the wire.
1471 talloc_steal(state->smb2req, state->smb2req->session);
1473 tevent_req_done(req);
1476 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1478 return tevent_req_simple_recv_ntstatus(req);