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 DBG_ERR("%s: NT_STATUS_REQUEST_NOT_ACCEPTED HERE\n", __location__);
846 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
847 return tevent_req_post(req, ev);
850 if (!smb2req->xconn->client->server_multi_channel_enabled) {
851 DBG_ERR("%s: NT_STATUS_REQUEST_NOT_ACCEPTED HERE\n", __location__);
852 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
853 return tevent_req_post(req, ev);
856 if (in_session_id == 0) {
857 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
858 return tevent_req_post(req, ev);
861 if (smb2req->session == NULL) {
862 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
863 return tevent_req_post(req, ev);
866 if (!smb2req->do_signing) {
867 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
868 return tevent_req_post(req, ev);
871 status = smbXsrv_session_find_channel(smb2req->session,
874 if (NT_STATUS_IS_OK(status)) {
875 if (!smb2_signing_key_valid(c->signing_key)) {
878 DBG_ERR("%s: NT_STATUS_REQUEST_NOT_ACCEPTED HERE\n", __location__);
879 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
880 return tevent_req_post(req, ev);
884 * OLD: 3.00 NEW 3.02 => INVALID_PARAMETER
885 * OLD: 3.02 NEW 3.00 => INVALID_PARAMETER
886 * OLD: 2.10 NEW 3.02 => ACCESS_DENIED
887 * OLD: 3.02 NEW 2.10 => ACCESS_DENIED
889 if (smb2req->session->global->connection_dialect
890 < SMB2_DIALECT_REVISION_222)
892 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
893 return tevent_req_post(req, ev);
895 if (smb2req->xconn->smb2.server.dialect
896 < SMB2_DIALECT_REVISION_222)
898 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
899 return tevent_req_post(req, ev);
901 if (smb2req->session->global->connection_dialect
902 != smb2req->xconn->smb2.server.dialect)
904 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
905 return tevent_req_post(req, ev);
908 seclvl = security_session_user_level(
909 smb2req->session->global->auth_session_info,
911 if (seclvl < SECURITY_USER) {
912 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
913 return tevent_req_post(req, ev);
916 status = smbXsrv_session_add_channel(smb2req->session,
919 if (!NT_STATUS_IS_OK(status)) {
920 tevent_req_nterror(req, status);
921 return tevent_req_post(req, ev);
924 status = smbXsrv_session_update(smb2req->session);
925 if (!NT_STATUS_IS_OK(status)) {
926 tevent_req_nterror(req, status);
927 return tevent_req_post(req, ev);
933 if (state->in_session_id == 0) {
934 /* create a new session */
935 status = smbXsrv_session_create(state->smb2req->xconn,
936 now, &state->session);
937 if (tevent_req_nterror(req, status)) {
938 return tevent_req_post(req, ev);
940 smb2req->session = state->session;
942 if (smb2req->session == NULL) {
943 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
944 return tevent_req_post(req, ev);
947 state->session = smb2req->session;
948 status = state->session->status;
949 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
950 status = NT_STATUS_OK;
952 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
953 status = NT_STATUS_OK;
955 if (tevent_req_nterror(req, status)) {
956 return tevent_req_post(req, ev);
958 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
959 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
963 status = smbXsrv_session_find_channel(smb2req->session,
965 if (!NT_STATUS_IS_OK(status)) {
966 tevent_req_nterror(req, status);
967 return tevent_req_post(req, ev);
970 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
972 if (!NT_STATUS_IS_OK(status)) {
973 status = smbXsrv_session_create_auth(state->session,
975 in_flags, in_security_mode,
977 if (tevent_req_nterror(req, status)) {
978 return tevent_req_post(req, ev);
982 if (state->auth->gensec == NULL) {
983 status = auth_generic_prepare(state->auth,
984 state->smb2req->xconn->remote_address,
985 state->smb2req->xconn->local_address,
987 &state->auth->gensec);
988 if (tevent_req_nterror(req, status)) {
989 return tevent_req_post(req, ev);
992 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
993 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
994 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
996 status = gensec_start_mech_by_oid(state->auth->gensec,
998 if (tevent_req_nterror(req, status)) {
999 return tevent_req_post(req, ev);
1003 status = smbXsrv_session_update(state->session);
1004 if (tevent_req_nterror(req, status)) {
1005 return tevent_req_post(req, ev);
1009 subreq = gensec_update_send(state, state->ev,
1010 state->auth->gensec,
1011 state->in_security_buffer);
1013 if (tevent_req_nomem(subreq, req)) {
1014 return tevent_req_post(req, ev);
1016 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
1021 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
1023 struct tevent_req *req =
1024 tevent_req_callback_data(subreq,
1026 struct smbd_smb2_session_setup_state *state =
1027 tevent_req_data(req,
1028 struct smbd_smb2_session_setup_state);
1032 status = gensec_update_recv(subreq, state,
1033 &state->out_security_buffer);
1035 TALLOC_FREE(subreq);
1036 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
1037 !NT_STATUS_IS_OK(status)) {
1038 tevent_req_nterror(req, status);
1042 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1043 state->out_session_id = state->session->global->session_wire_id;
1044 state->smb2req->preauth = state->auth->preauth;
1045 tevent_req_nterror(req, status);
1049 status = gensec_session_info(state->auth->gensec,
1051 &state->session_info);
1052 if (tevent_req_nterror(req, status)) {
1056 if ((state->in_previous_session_id != 0) &&
1057 (state->session->global->session_wire_id !=
1058 state->in_previous_session_id))
1060 subreq = smb2srv_session_close_previous_send(state, state->ev,
1061 state->smb2req->xconn,
1062 state->session_info,
1063 state->in_previous_session_id,
1064 state->session->global->session_wire_id);
1065 if (tevent_req_nomem(subreq, req)) {
1068 tevent_req_set_callback(subreq,
1069 smbd_smb2_session_setup_previous_done,
1074 smbd_smb2_session_setup_auth_return(req);
1077 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
1079 struct tevent_req *req =
1080 tevent_req_callback_data(subreq,
1084 status = smb2srv_session_close_previous_recv(subreq);
1085 TALLOC_FREE(subreq);
1086 if (tevent_req_nterror(req, status)) {
1090 smbd_smb2_session_setup_auth_return(req);
1093 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
1095 struct smbd_smb2_session_setup_state *state =
1096 tevent_req_data(req,
1097 struct smbd_smb2_session_setup_state);
1100 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1101 status = smbd_smb2_bind_auth_return(state->session,
1104 state->session_info,
1105 &state->out_session_flags,
1106 &state->out_session_id);
1107 if (tevent_req_nterror(req, status)) {
1110 tevent_req_done(req);
1114 if (state->session->global->auth_session_info != NULL) {
1115 status = smbd_smb2_reauth_generic_return(state->session,
1118 state->session_info,
1119 &state->out_session_flags,
1120 &state->out_session_id);
1121 if (tevent_req_nterror(req, status)) {
1124 tevent_req_done(req);
1128 status = smbd_smb2_auth_generic_return(state->session,
1131 state->in_security_mode,
1132 state->session_info,
1133 &state->out_session_flags,
1134 &state->out_session_id);
1135 if (tevent_req_nterror(req, status)) {
1139 tevent_req_done(req);
1143 static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1144 uint16_t *out_session_flags,
1145 TALLOC_CTX *mem_ctx,
1146 DATA_BLOB *out_security_buffer,
1147 uint64_t *out_session_id)
1149 struct smbd_smb2_session_setup_state *state =
1150 tevent_req_data(req,
1151 struct smbd_smb2_session_setup_state);
1154 if (tevent_req_is_nterror(req, &status)) {
1155 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1156 tevent_req_received(req);
1157 return nt_status_squash(status);
1160 status = NT_STATUS_OK;
1163 *out_session_flags = state->out_session_flags;
1164 *out_security_buffer = state->out_security_buffer;
1165 *out_session_id = state->out_session_id;
1167 talloc_steal(mem_ctx, out_security_buffer->data);
1168 tevent_req_received(req);
1172 struct smbd_smb2_session_setup_wrap_state {
1173 struct tevent_context *ev;
1174 struct smbd_smb2_request *smb2req;
1175 uint64_t in_session_id;
1177 uint8_t in_security_mode;
1178 uint64_t in_previous_session_id;
1179 DATA_BLOB in_security_buffer;
1180 uint16_t out_session_flags;
1181 DATA_BLOB out_security_buffer;
1182 uint64_t out_session_id;
1186 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1187 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1189 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1190 struct tevent_context *ev,
1191 struct smbd_smb2_request *smb2req,
1192 uint64_t in_session_id,
1194 uint8_t in_security_mode,
1195 uint64_t in_previous_session_id,
1196 DATA_BLOB in_security_buffer)
1198 struct tevent_req *req;
1199 struct smbd_smb2_session_setup_wrap_state *state;
1200 struct tevent_req *subreq;
1202 req = tevent_req_create(mem_ctx, &state,
1203 struct smbd_smb2_session_setup_wrap_state);
1208 state->smb2req = smb2req;
1209 state->in_session_id = in_session_id;
1210 state->in_flags = in_flags;
1211 state->in_security_mode = in_security_mode;
1212 state->in_previous_session_id = in_previous_session_id;
1213 state->in_security_buffer = in_security_buffer;
1215 subreq = smbd_smb2_session_setup_send(state, state->ev,
1217 state->in_session_id,
1219 state->in_security_mode,
1220 state->in_previous_session_id,
1221 state->in_security_buffer);
1222 if (tevent_req_nomem(subreq, req)) {
1223 return tevent_req_post(req, ev);
1225 tevent_req_set_callback(subreq,
1226 smbd_smb2_session_setup_wrap_setup_done, req);
1231 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1233 struct tevent_req *req =
1234 tevent_req_callback_data(subreq,
1236 struct smbd_smb2_session_setup_wrap_state *state =
1237 tevent_req_data(req,
1238 struct smbd_smb2_session_setup_wrap_state);
1241 status = smbd_smb2_session_setup_recv(subreq,
1242 &state->out_session_flags,
1244 &state->out_security_buffer,
1245 &state->out_session_id);
1246 TALLOC_FREE(subreq);
1247 if (NT_STATUS_IS_OK(status)) {
1248 tevent_req_done(req);
1251 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1252 tevent_req_nterror(req, status);
1256 if (state->smb2req->session == NULL) {
1257 tevent_req_nterror(req, status);
1261 state->error = status;
1263 subreq = smb2srv_session_shutdown_send(state, state->ev,
1264 state->smb2req->session,
1266 if (tevent_req_nomem(subreq, req)) {
1269 tevent_req_set_callback(subreq,
1270 smbd_smb2_session_setup_wrap_shutdown_done,
1274 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1276 struct tevent_req *req =
1277 tevent_req_callback_data(subreq,
1279 struct smbd_smb2_session_setup_wrap_state *state =
1280 tevent_req_data(req,
1281 struct smbd_smb2_session_setup_wrap_state);
1284 status = smb2srv_session_shutdown_recv(subreq);
1285 TALLOC_FREE(subreq);
1286 if (tevent_req_nterror(req, status)) {
1291 * we may need to sign the response, so we need to keep
1292 * the session until the response is sent to the wire.
1294 talloc_steal(state->smb2req, state->smb2req->session);
1296 tevent_req_nterror(req, state->error);
1299 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1300 uint16_t *out_session_flags,
1301 TALLOC_CTX *mem_ctx,
1302 DATA_BLOB *out_security_buffer,
1303 uint64_t *out_session_id)
1305 struct smbd_smb2_session_setup_wrap_state *state =
1306 tevent_req_data(req,
1307 struct smbd_smb2_session_setup_wrap_state);
1310 if (tevent_req_is_nterror(req, &status)) {
1311 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1312 tevent_req_received(req);
1313 return nt_status_squash(status);
1316 status = NT_STATUS_OK;
1319 *out_session_flags = state->out_session_flags;
1320 *out_security_buffer = state->out_security_buffer;
1321 *out_session_id = state->out_session_id;
1323 talloc_steal(mem_ctx, out_security_buffer->data);
1324 tevent_req_received(req);
1328 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1329 struct tevent_context *ev,
1330 struct smbd_smb2_request *smb2req);
1331 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1332 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1334 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1337 struct tevent_req *subreq = NULL;
1339 status = smbd_smb2_request_verify_sizes(req, 0x04);
1340 if (!NT_STATUS_IS_OK(status)) {
1341 return smbd_smb2_request_error(req, status);
1344 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1345 if (subreq == NULL) {
1346 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1348 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1351 * Avoid sending a STATUS_PENDING message, it's very likely
1352 * the client won't expect that.
1354 return smbd_smb2_request_pending_queue(req, subreq, 0);
1357 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1359 struct smbd_smb2_request *smb2req =
1360 tevent_req_callback_data(subreq,
1361 struct smbd_smb2_request);
1366 status = smbd_smb2_logoff_recv(subreq);
1367 TALLOC_FREE(subreq);
1368 if (!NT_STATUS_IS_OK(status)) {
1369 error = smbd_smb2_request_error(smb2req, status);
1370 if (!NT_STATUS_IS_OK(error)) {
1371 smbd_server_connection_terminate(smb2req->xconn,
1378 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1379 if (outbody.data == NULL) {
1380 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1381 if (!NT_STATUS_IS_OK(error)) {
1382 smbd_server_connection_terminate(smb2req->xconn,
1389 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1390 SSVAL(outbody.data, 0x02, 0); /* reserved */
1392 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1393 if (!NT_STATUS_IS_OK(error)) {
1394 smbd_server_connection_terminate(smb2req->xconn,
1400 struct smbd_smb2_logoff_state {
1401 struct smbd_smb2_request *smb2req;
1404 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1406 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1407 struct tevent_context *ev,
1408 struct smbd_smb2_request *smb2req)
1410 struct tevent_req *req;
1411 struct smbd_smb2_logoff_state *state;
1412 struct tevent_req *subreq;
1414 req = tevent_req_create(mem_ctx, &state,
1415 struct smbd_smb2_logoff_state);
1419 state->smb2req = smb2req;
1421 subreq = smb2srv_session_shutdown_send(state, ev,
1424 if (tevent_req_nomem(subreq, req)) {
1425 return tevent_req_post(req, ev);
1427 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1432 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1434 struct tevent_req *req = tevent_req_callback_data(
1435 subreq, struct tevent_req);
1436 struct smbd_smb2_logoff_state *state = tevent_req_data(
1437 req, struct smbd_smb2_logoff_state);
1440 const struct GUID *client_guid =
1441 &state->smb2req->session->client->connections->smb2.client.guid;
1443 status = smb2srv_session_shutdown_recv(subreq);
1444 if (tevent_req_nterror(req, status)) {
1447 TALLOC_FREE(subreq);
1449 if (!GUID_all_zero(client_guid)) {
1450 ok = remote_arch_cache_delete(client_guid);
1452 /* Most likely not an error, but not in cache */
1453 DBG_DEBUG("Deletion from remote arch cache failed\n");
1458 * As we've been awoken, we may have changed
1459 * uid in the meantime. Ensure we're still
1460 * root (SMB2_OP_LOGOFF has .as_root = true).
1462 change_to_root_user();
1464 status = smbXsrv_session_logoff(state->smb2req->session);
1465 if (tevent_req_nterror(req, status)) {
1470 * we may need to sign the response, so we need to keep
1471 * the session until the response is sent to the wire.
1473 talloc_steal(state->smb2req, state->smb2req->session);
1475 tevent_req_done(req);
1478 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1480 return tevent_req_simple_recv_ntstatus(req);