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"
31 #include "lib/crypto/aes.h"
32 #include "lib/crypto/aes_ccm_128.h"
33 #include "lib/crypto/aes_gcm_128.h"
35 #include "lib/crypto/gnutls_helpers.h"
36 #include <gnutls/gnutls.h>
37 #include <gnutls/crypto.h>
40 #define DBGC_CLASS DBGC_SMB2
42 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
43 struct tevent_context *ev,
44 struct smbd_smb2_request *smb2req,
45 uint64_t in_session_id,
47 uint8_t in_security_mode,
48 uint64_t in_previous_session_id,
49 DATA_BLOB in_security_buffer);
50 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
51 uint16_t *out_session_flags,
53 DATA_BLOB *out_security_buffer,
54 uint64_t *out_session_id);
56 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
58 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
61 const uint8_t *inbody;
62 uint64_t in_session_id;
64 uint8_t in_security_mode;
65 uint64_t in_previous_session_id;
66 uint16_t in_security_offset;
67 uint16_t in_security_length;
68 DATA_BLOB in_security_buffer;
70 struct tevent_req *subreq;
72 status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
73 if (!NT_STATUS_IS_OK(status)) {
74 return smbd_smb2_request_error(smb2req, status);
76 inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
77 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
79 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
81 in_flags = CVAL(inbody, 0x02);
82 in_security_mode = CVAL(inbody, 0x03);
83 /* Capabilities = IVAL(inbody, 0x04) */
84 /* Channel = IVAL(inbody, 0x08) */
85 in_security_offset = SVAL(inbody, 0x0C);
86 in_security_length = SVAL(inbody, 0x0E);
87 in_previous_session_id = BVAL(inbody, 0x10);
89 if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
90 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
93 if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
94 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
97 in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
98 in_security_buffer.length = in_security_length;
100 subreq = smbd_smb2_session_setup_wrap_send(smb2req,
101 smb2req->sconn->ev_ctx,
106 in_previous_session_id,
108 if (subreq == NULL) {
109 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
111 tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
114 * Avoid sending a STATUS_PENDING message, which
115 * matches a Windows Server and avoids problems with
118 * Even after 90 seconds a Windows Server doesn't return
119 * STATUS_PENDING if using NTLMSSP against a non reachable
122 return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
125 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
127 struct smbd_smb2_request *smb2req =
128 tevent_req_callback_data(subreq,
129 struct smbd_smb2_request);
133 uint16_t out_session_flags = 0;
134 uint64_t out_session_id = 0;
135 uint16_t out_security_offset;
136 DATA_BLOB out_security_buffer = data_blob_null;
138 NTSTATUS error; /* transport error */
140 status = smbd_smb2_session_setup_wrap_recv(subreq,
143 &out_security_buffer,
146 if (!NT_STATUS_IS_OK(status) &&
147 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
148 status = nt_status_squash(status);
149 error = smbd_smb2_request_error(smb2req, status);
150 if (!NT_STATUS_IS_OK(error)) {
151 smbd_server_connection_terminate(smb2req->xconn,
158 out_security_offset = SMB2_HDR_BODY + 0x08;
160 outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
162 outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
163 if (outbody.data == NULL) {
164 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
165 if (!NT_STATUS_IS_OK(error)) {
166 smbd_server_connection_terminate(smb2req->xconn,
173 SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
175 SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
176 SSVAL(outbody.data, 0x02,
177 out_session_flags); /* session flags */
178 SSVAL(outbody.data, 0x04,
179 out_security_offset); /* security buffer offset */
180 SSVAL(outbody.data, 0x06,
181 out_security_buffer.length); /* security buffer length */
183 outdyn = out_security_buffer;
185 error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
187 if (!NT_STATUS_IS_OK(error)) {
188 smbd_server_connection_terminate(smb2req->xconn,
194 static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
195 struct smbXsrv_session_auth0 **_auth,
196 struct smbd_smb2_request *smb2req,
197 uint8_t in_security_mode,
198 struct auth_session_info *session_info,
199 uint16_t *out_session_flags,
200 uint64_t *out_session_id)
204 uint8_t session_key[16];
205 struct smbXsrv_session *x = session;
206 struct smbXsrv_session_auth0 *auth = *_auth;
207 struct smbXsrv_connection *xconn = smb2req->xconn;
214 struct _derivation signing;
215 struct _derivation encryption;
216 struct _derivation decryption;
217 struct _derivation application;
222 if (xconn->protocol >= PROTOCOL_SMB3_10) {
223 struct smbXsrv_preauth *preauth;
224 struct _derivation *d;
226 gnutls_hash_hd_t hash_hnd;
229 preauth = talloc_move(smb2req, &auth->preauth);
231 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
233 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
235 rc = gnutls_hash(hash_hnd,
236 preauth->sha512_value,
237 sizeof(preauth->sha512_value));
239 gnutls_hash_deinit(hash_hnd, NULL);
240 return NT_STATUS_ACCESS_DENIED;
242 for (i = 1; i < smb2req->in.vector_count; i++) {
243 rc = gnutls_hash(hash_hnd,
244 smb2req->in.vector[i].iov_base,
245 smb2req->in.vector[i].iov_len);
247 gnutls_hash_deinit(hash_hnd, NULL);
248 return NT_STATUS_ACCESS_DENIED;
251 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
253 p = data_blob_const(preauth->sha512_value,
254 sizeof(preauth->sha512_value));
256 d = &derivation.signing;
257 d->label = data_blob_string_const_null("SMBSigningKey");
260 d = &derivation.decryption;
261 d->label = data_blob_string_const_null("SMBC2SCipherKey");
264 d = &derivation.encryption;
265 d->label = data_blob_string_const_null("SMBS2CCipherKey");
268 d = &derivation.application;
269 d->label = data_blob_string_const_null("SMBAppKey");
272 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
273 struct _derivation *d;
275 d = &derivation.signing;
276 d->label = data_blob_string_const_null("SMB2AESCMAC");
277 d->context = data_blob_string_const_null("SmbSign");
279 d = &derivation.decryption;
280 d->label = data_blob_string_const_null("SMB2AESCCM");
281 d->context = data_blob_string_const_null("ServerIn ");
283 d = &derivation.encryption;
284 d->label = data_blob_string_const_null("SMB2AESCCM");
285 d->context = data_blob_string_const_null("ServerOut");
287 d = &derivation.application;
288 d->label = data_blob_string_const_null("SMB2APP");
289 d->context = data_blob_string_const_null("SmbRpc");
292 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
293 (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
295 x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
298 if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
299 (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
300 x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
303 if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
304 x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
305 SMBXSRV_ENCRYPTION_DESIRED;
308 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
309 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
310 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
312 /* force no signing */
313 x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
314 /* we map anonymous to guest internally */
318 if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
319 DEBUG(1,("reject guest session as encryption is required\n"));
320 return NT_STATUS_ACCESS_DENIED;
323 if (xconn->smb2.server.cipher == 0) {
324 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
325 DEBUG(1,("reject session with dialect[0x%04X] "
326 "as encryption is required\n",
327 xconn->smb2.server.dialect));
328 return NT_STATUS_ACCESS_DENIED;
331 x->global->channels[0].encryption_cipher = xconn->smb2.server.cipher;
334 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
335 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
338 ZERO_STRUCT(session_key);
339 memcpy(session_key, session_info->session_key.data,
340 MIN(session_info->session_key.length, sizeof(session_key)));
342 x->global->signing_key = talloc_zero(x->global,
343 struct smb2_signing_key);
344 if (x->global->signing_key == NULL) {
345 ZERO_STRUCT(session_key);
346 return NT_STATUS_NO_MEMORY;
348 talloc_set_destructor(x->global->signing_key,
349 smb2_signing_key_destructor);
351 x->global->signing_key->blob =
352 x->global->signing_key_blob =
353 data_blob_talloc(x->global,
355 sizeof(session_key));
356 if (!smb2_signing_key_valid(x->global->signing_key)) {
357 ZERO_STRUCT(session_key);
358 return NT_STATUS_NO_MEMORY;
361 if (xconn->protocol >= PROTOCOL_SMB2_24) {
362 struct _derivation *d = &derivation.signing;
364 status = smb2_key_derivation(session_key, sizeof(session_key),
365 d->label.data, d->label.length,
366 d->context.data, d->context.length,
367 x->global->signing_key->blob.data);
368 if (!NT_STATUS_IS_OK(status)) {
373 if (xconn->protocol >= PROTOCOL_SMB2_24) {
374 struct _derivation *d = &derivation.decryption;
376 x->global->decryption_key_blob = data_blob_talloc(x->global,
378 sizeof(session_key));
379 if (x->global->decryption_key_blob.data == NULL) {
380 ZERO_STRUCT(session_key);
381 return NT_STATUS_NO_MEMORY;
384 status = smb2_key_derivation(session_key, sizeof(session_key),
385 d->label.data, d->label.length,
386 d->context.data, d->context.length,
387 x->global->decryption_key_blob.data);
388 if (!NT_STATUS_IS_OK(status)) {
393 if (xconn->protocol >= PROTOCOL_SMB2_24) {
394 struct _derivation *d = &derivation.encryption;
397 x->global->encryption_key_blob = data_blob_talloc(x->global,
399 sizeof(session_key));
400 if (x->global->encryption_key_blob.data == NULL) {
401 ZERO_STRUCT(session_key);
402 return NT_STATUS_NO_MEMORY;
405 status = smb2_key_derivation(session_key, sizeof(session_key),
406 d->label.data, d->label.length,
407 d->context.data, d->context.length,
408 x->global->encryption_key_blob.data);
409 if (!NT_STATUS_IS_OK(status)) {
414 * CCM and GCM algorithms must never have their
415 * nonce wrap, or the security of the whole
416 * communication and the keys is destroyed.
417 * We must drop the connection once we have
418 * transfered too much data.
420 * NOTE: We assume nonces greater than 8 bytes.
422 generate_random_buffer((uint8_t *)&x->nonce_high_random,
423 sizeof(x->nonce_high_random));
424 switch (xconn->smb2.server.cipher) {
425 case SMB2_ENCRYPTION_AES128_CCM:
426 nonce_size = AES_CCM_128_NONCE_SIZE;
428 case SMB2_ENCRYPTION_AES128_GCM:
429 nonce_size = AES_GCM_128_IV_SIZE;
435 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
440 x->global->application_key =
441 data_blob_dup_talloc(x->global, x->global->signing_key->blob);
442 if (x->global->application_key.data == NULL) {
443 ZERO_STRUCT(session_key);
444 return NT_STATUS_NO_MEMORY;
446 talloc_keep_secret(x->global->application_key.data);
448 if (xconn->protocol >= PROTOCOL_SMB2_24) {
449 struct _derivation *d = &derivation.application;
451 status = smb2_key_derivation(session_key, sizeof(session_key),
452 d->label.data, d->label.length,
453 d->context.data, d->context.length,
454 x->global->application_key.data);
455 if (!NT_STATUS_IS_OK(status)) {
460 if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
461 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
462 DEBUGADD(0, ("Session Id "));
463 dump_data(0, (uint8_t*)&session->global->session_wire_id,
464 sizeof(session->global->session_wire_id));
465 DEBUGADD(0, ("Session Key "));
466 dump_data(0, session_key, sizeof(session_key));
467 DEBUGADD(0, ("Signing Key "));
468 dump_data(0, x->global->signing_key->blob.data,
469 x->global->signing_key->blob.length);
470 DEBUGADD(0, ("App Key "));
471 dump_data(0, x->global->application_key.data,
472 x->global->application_key.length);
474 /* In server code, ServerIn is the decryption key */
476 DEBUGADD(0, ("ServerIn Key "));
477 dump_data(0, x->global->decryption_key_blob.data,
478 x->global->decryption_key_blob.length);
479 DEBUGADD(0, ("ServerOut Key "));
480 dump_data(0, x->global->encryption_key_blob.data,
481 x->global->encryption_key_blob.length);
484 ZERO_STRUCT(session_key);
486 x->global->channels[0].signing_key =
487 talloc_zero(x->global->channels, struct smb2_signing_key);
488 if (x->global->channels[0].signing_key == NULL) {
489 return NT_STATUS_NO_MEMORY;
491 talloc_set_destructor(x->global->channels[0].signing_key,
492 smb2_signing_key_destructor);
494 x->global->channels[0].signing_key->blob =
495 x->global->channels[0].signing_key_blob =
496 data_blob_dup_talloc(x->global->channels[0].signing_key,
497 x->global->signing_key->blob);
498 if (!smb2_signing_key_valid(x->global->channels[0].signing_key)) {
499 return NT_STATUS_NO_MEMORY;
501 talloc_keep_secret(x->global->channels[0].signing_key->blob.data);
503 data_blob_clear_free(&session_info->session_key);
504 session_info->session_key = data_blob_dup_talloc(session_info,
505 x->global->application_key);
506 if (session_info->session_key.data == NULL) {
507 return NT_STATUS_NO_MEMORY;
509 talloc_keep_secret(session_info->session_key.data);
511 session->compat = talloc_zero(session, struct user_struct);
512 if (session->compat == NULL) {
513 return NT_STATUS_NO_MEMORY;
515 session->compat->session = session;
516 session->compat->homes_snum = -1;
517 session->compat->session_info = session_info;
518 session->compat->session_keystr = NULL;
519 session->compat->vuid = session->global->session_wire_id;
520 DLIST_ADD(smb2req->sconn->users, session->compat);
521 smb2req->sconn->num_users++;
523 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
524 session->compat->homes_snum =
525 register_homes_share(session_info->unix_info->unix_name);
528 set_current_user_info(session_info->unix_info->sanitized_username,
529 session_info->unix_info->unix_name,
530 session_info->info->domain_name);
532 reload_services(smb2req->sconn, conn_snum_used, true);
534 session->status = NT_STATUS_OK;
535 session->global->auth_session_info = talloc_move(session->global,
537 session->global->auth_session_info_seqnum += 1;
538 for (i=0; i < session->global->num_channels; i++) {
539 struct smbXsrv_channel_global0 *_c =
540 &session->global->channels[i];
542 _c->auth_session_info_seqnum =
543 session->global->auth_session_info_seqnum;
545 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
546 session->global->expiration_time = gensec_expire_time(auth->gensec);
548 if (!session_claim(session)) {
549 DEBUG(1, ("smb2: Failed to claim session "
551 (unsigned long long)session->compat->vuid));
552 return NT_STATUS_LOGON_FAILURE;
556 status = smbXsrv_session_update(session);
557 if (!NT_STATUS_IS_OK(status)) {
558 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
559 (unsigned long long)session->compat->vuid,
561 return NT_STATUS_LOGON_FAILURE;
565 * we attach the session to the request
566 * so that the response can be signed
569 smb2req->do_signing = true;
572 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
574 *out_session_id = session->global->session_wire_id;
575 smb2req->last_session_id = session->global->session_wire_id;
580 static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
581 struct smbXsrv_session_auth0 **_auth,
582 struct smbd_smb2_request *smb2req,
583 struct auth_session_info *session_info,
584 uint16_t *out_session_flags,
585 uint64_t *out_session_id)
588 struct smbXsrv_session *x = session;
589 struct smbXsrv_session_auth0 *auth = *_auth;
590 struct smbXsrv_connection *xconn = smb2req->xconn;
595 data_blob_clear_free(&session_info->session_key);
596 session_info->session_key = data_blob_dup_talloc(session_info,
597 x->global->application_key);
598 if (session_info->session_key.data == NULL) {
599 return NT_STATUS_NO_MEMORY;
601 talloc_keep_secret(session_info->session_key.data);
603 session->compat->session_info = session_info;
604 session->compat->vuid = session->global->session_wire_id;
606 session->compat->homes_snum =
607 register_homes_share(session_info->unix_info->unix_name);
609 set_current_user_info(session_info->unix_info->sanitized_username,
610 session_info->unix_info->unix_name,
611 session_info->info->domain_name);
613 reload_services(smb2req->sconn, conn_snum_used, true);
615 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
616 smb2req->do_signing = true;
619 session->status = NT_STATUS_OK;
620 TALLOC_FREE(session->global->auth_session_info);
621 session->global->auth_session_info = talloc_move(session->global,
623 session->global->auth_session_info_seqnum += 1;
624 for (i=0; i < session->global->num_channels; i++) {
625 struct smbXsrv_channel_global0 *_c =
626 &session->global->channels[i];
628 _c->auth_session_info_seqnum =
629 session->global->auth_session_info_seqnum;
631 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
632 session->global->expiration_time = gensec_expire_time(auth->gensec);
635 status = smbXsrv_session_update(session);
636 if (!NT_STATUS_IS_OK(status)) {
637 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
638 (unsigned long long)session->compat->vuid,
640 return NT_STATUS_LOGON_FAILURE;
643 conn_clear_vuid_caches(xconn->client->sconn, session->compat->vuid);
645 *out_session_id = session->global->session_wire_id;
650 static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
651 struct smbXsrv_session_auth0 **_auth,
652 struct smbd_smb2_request *smb2req,
653 struct auth_session_info *session_info,
654 uint16_t *out_session_flags,
655 uint64_t *out_session_id)
658 struct smbXsrv_session *x = session;
659 struct smbXsrv_session_auth0 *auth = *_auth;
660 struct smbXsrv_connection *xconn = smb2req->xconn;
661 struct smbXsrv_channel_global0 *c = NULL;
662 uint8_t session_key[16];
669 struct _derivation signing;
675 if (xconn->protocol >= PROTOCOL_SMB3_10) {
676 struct smbXsrv_preauth *preauth;
677 struct _derivation *d;
679 gnutls_hash_hd_t hash_hnd = NULL;
682 preauth = talloc_move(smb2req, &auth->preauth);
684 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
686 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
689 rc = gnutls_hash(hash_hnd,
690 preauth->sha512_value,
691 sizeof(preauth->sha512_value));
693 gnutls_hash_deinit(hash_hnd, NULL);
694 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
696 for (i = 1; i < smb2req->in.vector_count; i++) {
697 rc = gnutls_hash(hash_hnd,
698 smb2req->in.vector[i].iov_base,
699 smb2req->in.vector[i].iov_len);
701 gnutls_hash_deinit(hash_hnd, NULL);
702 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
705 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
707 p = data_blob_const(preauth->sha512_value,
708 sizeof(preauth->sha512_value));
710 d = &derivation.signing;
711 d->label = data_blob_string_const_null("SMBSigningKey");
714 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
715 struct _derivation *d;
717 d = &derivation.signing;
718 d->label = data_blob_string_const_null("SMB2AESCMAC");
719 d->context = data_blob_string_const_null("SmbSign");
722 status = smbXsrv_session_find_channel(session, xconn, &c);
723 if (!NT_STATUS_IS_OK(status)) {
727 ok = security_token_is_sid(session_info->security_token,
728 &x->global->auth_session_info->security_token->sids[0]);
730 return NT_STATUS_NOT_SUPPORTED;
733 if (session_info->session_key.length == 0) {
734 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
735 return NT_STATUS_NOT_SUPPORTED;
738 ZERO_STRUCT(session_key);
739 memcpy(session_key, session_info->session_key.data,
740 MIN(session_info->session_key.length, sizeof(session_key)));
742 c->signing_key = talloc_zero(x->global, struct smb2_signing_key);
743 if (c->signing_key == NULL) {
744 ZERO_STRUCT(session_key);
745 return NT_STATUS_NO_MEMORY;
747 talloc_set_destructor(c->signing_key,
748 smb2_signing_key_destructor);
750 c->signing_key->blob =
751 c->signing_key_blob =
752 data_blob_talloc(c->signing_key,
754 sizeof(session_key));
755 if (!smb2_signing_key_valid(c->signing_key)) {
756 ZERO_STRUCT(session_key);
757 return NT_STATUS_NO_MEMORY;
759 talloc_keep_secret(c->signing_key->blob.data);
761 if (xconn->protocol >= PROTOCOL_SMB2_24) {
762 struct _derivation *d = &derivation.signing;
764 status = smb2_key_derivation(session_key, sizeof(session_key),
765 d->label.data, d->label.length,
766 d->context.data, d->context.length,
767 c->signing_key->blob.data);
768 if (!NT_STATUS_IS_OK(status)) {
772 ZERO_STRUCT(session_key);
775 status = smbXsrv_session_update(session);
776 if (!NT_STATUS_IS_OK(status)) {
777 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
778 (unsigned long long)session->compat->vuid,
780 return NT_STATUS_LOGON_FAILURE;
783 *out_session_id = session->global->session_wire_id;
788 struct smbd_smb2_session_setup_state {
789 struct tevent_context *ev;
790 struct smbd_smb2_request *smb2req;
791 uint64_t in_session_id;
793 uint8_t in_security_mode;
794 uint64_t in_previous_session_id;
795 DATA_BLOB in_security_buffer;
796 struct smbXsrv_session *session;
797 struct smbXsrv_session_auth0 *auth;
798 struct auth_session_info *session_info;
799 uint16_t out_session_flags;
800 DATA_BLOB out_security_buffer;
801 uint64_t out_session_id;
804 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
805 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
806 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
808 static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
809 struct tevent_context *ev,
810 struct smbd_smb2_request *smb2req,
811 uint64_t in_session_id,
813 uint8_t in_security_mode,
814 uint64_t in_previous_session_id,
815 DATA_BLOB in_security_buffer)
817 struct tevent_req *req;
818 struct smbd_smb2_session_setup_state *state;
820 NTTIME now = timeval_to_nttime(&smb2req->request_time);
821 struct tevent_req *subreq;
822 struct smbXsrv_channel_global0 *c = NULL;
823 enum security_user_level seclvl;
825 req = tevent_req_create(mem_ctx, &state,
826 struct smbd_smb2_session_setup_state);
831 state->smb2req = smb2req;
832 state->in_session_id = in_session_id;
833 state->in_flags = in_flags;
834 state->in_security_mode = in_security_mode;
835 state->in_previous_session_id = in_previous_session_id;
836 state->in_security_buffer = in_security_buffer;
838 if (in_flags & SMB2_SESSION_FLAG_BINDING) {
839 if (smb2req->xconn->protocol < PROTOCOL_SMB2_22) {
840 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
841 return tevent_req_post(req, ev);
844 if (!smb2req->xconn->client->server_multi_channel_enabled) {
845 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
846 return tevent_req_post(req, ev);
849 if (in_session_id == 0) {
850 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
851 return tevent_req_post(req, ev);
854 if (smb2req->session == NULL) {
855 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
856 return tevent_req_post(req, ev);
859 if (!smb2req->do_signing) {
860 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
861 return tevent_req_post(req, ev);
864 status = smbXsrv_session_find_channel(smb2req->session,
867 if (NT_STATUS_IS_OK(status)) {
868 if (!smb2_signing_key_valid(c->signing_key)) {
871 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
872 return tevent_req_post(req, ev);
876 * OLD: 3.00 NEW 3.02 => INVALID_PARAMETER
877 * OLD: 3.02 NEW 3.00 => INVALID_PARAMETER
878 * OLD: 2.10 NEW 3.02 => ACCESS_DENIED
879 * OLD: 3.02 NEW 2.10 => ACCESS_DENIED
881 if (smb2req->session->global->connection_dialect
882 < SMB2_DIALECT_REVISION_222)
884 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
885 return tevent_req_post(req, ev);
887 if (smb2req->xconn->smb2.server.dialect
888 < SMB2_DIALECT_REVISION_222)
890 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
891 return tevent_req_post(req, ev);
893 if (smb2req->session->global->connection_dialect
894 != smb2req->xconn->smb2.server.dialect)
896 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
897 return tevent_req_post(req, ev);
900 seclvl = security_session_user_level(
901 smb2req->session->global->auth_session_info,
903 if (seclvl < SECURITY_USER) {
904 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
905 return tevent_req_post(req, ev);
908 status = smbXsrv_session_add_channel(smb2req->session,
911 if (!NT_STATUS_IS_OK(status)) {
912 tevent_req_nterror(req, status);
913 return tevent_req_post(req, ev);
916 status = smbXsrv_session_update(smb2req->session);
917 if (!NT_STATUS_IS_OK(status)) {
918 tevent_req_nterror(req, status);
919 return tevent_req_post(req, ev);
925 if (state->in_session_id == 0) {
926 /* create a new session */
927 status = smbXsrv_session_create(state->smb2req->xconn,
928 now, &state->session);
929 if (tevent_req_nterror(req, status)) {
930 return tevent_req_post(req, ev);
932 smb2req->session = state->session;
934 if (smb2req->session == NULL) {
935 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
936 return tevent_req_post(req, ev);
939 state->session = smb2req->session;
940 status = state->session->status;
941 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
942 status = NT_STATUS_OK;
944 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
945 status = NT_STATUS_OK;
947 if (tevent_req_nterror(req, status)) {
948 return tevent_req_post(req, ev);
950 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
951 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
955 status = smbXsrv_session_find_channel(smb2req->session,
957 if (!NT_STATUS_IS_OK(status)) {
958 tevent_req_nterror(req, status);
959 return tevent_req_post(req, ev);
962 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
964 if (!NT_STATUS_IS_OK(status)) {
965 status = smbXsrv_session_create_auth(state->session,
967 in_flags, in_security_mode,
969 if (tevent_req_nterror(req, status)) {
970 return tevent_req_post(req, ev);
974 if (state->auth->gensec == NULL) {
975 status = auth_generic_prepare(state->auth,
976 state->smb2req->xconn->remote_address,
977 state->smb2req->xconn->local_address,
979 &state->auth->gensec);
980 if (tevent_req_nterror(req, status)) {
981 return tevent_req_post(req, ev);
984 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
985 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
986 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
988 status = gensec_start_mech_by_oid(state->auth->gensec,
990 if (tevent_req_nterror(req, status)) {
991 return tevent_req_post(req, ev);
995 status = smbXsrv_session_update(state->session);
996 if (tevent_req_nterror(req, status)) {
997 return tevent_req_post(req, ev);
1001 subreq = gensec_update_send(state, state->ev,
1002 state->auth->gensec,
1003 state->in_security_buffer);
1005 if (tevent_req_nomem(subreq, req)) {
1006 return tevent_req_post(req, ev);
1008 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
1013 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
1015 struct tevent_req *req =
1016 tevent_req_callback_data(subreq,
1018 struct smbd_smb2_session_setup_state *state =
1019 tevent_req_data(req,
1020 struct smbd_smb2_session_setup_state);
1024 status = gensec_update_recv(subreq, state,
1025 &state->out_security_buffer);
1027 TALLOC_FREE(subreq);
1028 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
1029 !NT_STATUS_IS_OK(status)) {
1030 tevent_req_nterror(req, status);
1034 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1035 state->out_session_id = state->session->global->session_wire_id;
1036 state->smb2req->preauth = state->auth->preauth;
1037 tevent_req_nterror(req, status);
1041 status = gensec_session_info(state->auth->gensec,
1043 &state->session_info);
1044 if (tevent_req_nterror(req, status)) {
1048 if ((state->in_previous_session_id != 0) &&
1049 (state->session->global->session_wire_id !=
1050 state->in_previous_session_id))
1052 subreq = smb2srv_session_close_previous_send(state, state->ev,
1053 state->smb2req->xconn,
1054 state->session_info,
1055 state->in_previous_session_id,
1056 state->session->global->session_wire_id);
1057 if (tevent_req_nomem(subreq, req)) {
1060 tevent_req_set_callback(subreq,
1061 smbd_smb2_session_setup_previous_done,
1066 smbd_smb2_session_setup_auth_return(req);
1069 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
1071 struct tevent_req *req =
1072 tevent_req_callback_data(subreq,
1076 status = smb2srv_session_close_previous_recv(subreq);
1077 TALLOC_FREE(subreq);
1078 if (tevent_req_nterror(req, status)) {
1082 smbd_smb2_session_setup_auth_return(req);
1085 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
1087 struct smbd_smb2_session_setup_state *state =
1088 tevent_req_data(req,
1089 struct smbd_smb2_session_setup_state);
1092 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1093 status = smbd_smb2_bind_auth_return(state->session,
1096 state->session_info,
1097 &state->out_session_flags,
1098 &state->out_session_id);
1099 if (tevent_req_nterror(req, status)) {
1102 tevent_req_done(req);
1106 if (state->session->global->auth_session_info != NULL) {
1107 status = smbd_smb2_reauth_generic_return(state->session,
1110 state->session_info,
1111 &state->out_session_flags,
1112 &state->out_session_id);
1113 if (tevent_req_nterror(req, status)) {
1116 tevent_req_done(req);
1120 status = smbd_smb2_auth_generic_return(state->session,
1123 state->in_security_mode,
1124 state->session_info,
1125 &state->out_session_flags,
1126 &state->out_session_id);
1127 if (tevent_req_nterror(req, status)) {
1131 tevent_req_done(req);
1135 static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1136 uint16_t *out_session_flags,
1137 TALLOC_CTX *mem_ctx,
1138 DATA_BLOB *out_security_buffer,
1139 uint64_t *out_session_id)
1141 struct smbd_smb2_session_setup_state *state =
1142 tevent_req_data(req,
1143 struct smbd_smb2_session_setup_state);
1146 if (tevent_req_is_nterror(req, &status)) {
1147 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1148 tevent_req_received(req);
1149 return nt_status_squash(status);
1152 status = NT_STATUS_OK;
1155 *out_session_flags = state->out_session_flags;
1156 *out_security_buffer = state->out_security_buffer;
1157 *out_session_id = state->out_session_id;
1159 talloc_steal(mem_ctx, out_security_buffer->data);
1160 tevent_req_received(req);
1164 struct smbd_smb2_session_setup_wrap_state {
1165 struct tevent_context *ev;
1166 struct smbd_smb2_request *smb2req;
1167 uint64_t in_session_id;
1169 uint8_t in_security_mode;
1170 uint64_t in_previous_session_id;
1171 DATA_BLOB in_security_buffer;
1172 uint16_t out_session_flags;
1173 DATA_BLOB out_security_buffer;
1174 uint64_t out_session_id;
1178 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1179 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1181 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1182 struct tevent_context *ev,
1183 struct smbd_smb2_request *smb2req,
1184 uint64_t in_session_id,
1186 uint8_t in_security_mode,
1187 uint64_t in_previous_session_id,
1188 DATA_BLOB in_security_buffer)
1190 struct tevent_req *req;
1191 struct smbd_smb2_session_setup_wrap_state *state;
1192 struct tevent_req *subreq;
1194 req = tevent_req_create(mem_ctx, &state,
1195 struct smbd_smb2_session_setup_wrap_state);
1200 state->smb2req = smb2req;
1201 state->in_session_id = in_session_id;
1202 state->in_flags = in_flags;
1203 state->in_security_mode = in_security_mode;
1204 state->in_previous_session_id = in_previous_session_id;
1205 state->in_security_buffer = in_security_buffer;
1207 subreq = smbd_smb2_session_setup_send(state, state->ev,
1209 state->in_session_id,
1211 state->in_security_mode,
1212 state->in_previous_session_id,
1213 state->in_security_buffer);
1214 if (tevent_req_nomem(subreq, req)) {
1215 return tevent_req_post(req, ev);
1217 tevent_req_set_callback(subreq,
1218 smbd_smb2_session_setup_wrap_setup_done, req);
1223 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1225 struct tevent_req *req =
1226 tevent_req_callback_data(subreq,
1228 struct smbd_smb2_session_setup_wrap_state *state =
1229 tevent_req_data(req,
1230 struct smbd_smb2_session_setup_wrap_state);
1233 status = smbd_smb2_session_setup_recv(subreq,
1234 &state->out_session_flags,
1236 &state->out_security_buffer,
1237 &state->out_session_id);
1238 TALLOC_FREE(subreq);
1239 if (NT_STATUS_IS_OK(status)) {
1240 tevent_req_done(req);
1243 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1244 tevent_req_nterror(req, status);
1248 if (state->smb2req->session == NULL) {
1249 tevent_req_nterror(req, status);
1253 state->error = status;
1255 subreq = smb2srv_session_shutdown_send(state, state->ev,
1256 state->smb2req->session,
1258 if (tevent_req_nomem(subreq, req)) {
1261 tevent_req_set_callback(subreq,
1262 smbd_smb2_session_setup_wrap_shutdown_done,
1266 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1268 struct tevent_req *req =
1269 tevent_req_callback_data(subreq,
1271 struct smbd_smb2_session_setup_wrap_state *state =
1272 tevent_req_data(req,
1273 struct smbd_smb2_session_setup_wrap_state);
1276 status = smb2srv_session_shutdown_recv(subreq);
1277 TALLOC_FREE(subreq);
1278 if (tevent_req_nterror(req, status)) {
1283 * we may need to sign the response, so we need to keep
1284 * the session until the response is sent to the wire.
1286 talloc_steal(state->smb2req, state->smb2req->session);
1288 tevent_req_nterror(req, state->error);
1291 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1292 uint16_t *out_session_flags,
1293 TALLOC_CTX *mem_ctx,
1294 DATA_BLOB *out_security_buffer,
1295 uint64_t *out_session_id)
1297 struct smbd_smb2_session_setup_wrap_state *state =
1298 tevent_req_data(req,
1299 struct smbd_smb2_session_setup_wrap_state);
1302 if (tevent_req_is_nterror(req, &status)) {
1303 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1304 tevent_req_received(req);
1305 return nt_status_squash(status);
1308 status = NT_STATUS_OK;
1311 *out_session_flags = state->out_session_flags;
1312 *out_security_buffer = state->out_security_buffer;
1313 *out_session_id = state->out_session_id;
1315 talloc_steal(mem_ctx, out_security_buffer->data);
1316 tevent_req_received(req);
1320 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1321 struct tevent_context *ev,
1322 struct smbd_smb2_request *smb2req);
1323 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1324 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1326 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1329 struct tevent_req *subreq = NULL;
1331 status = smbd_smb2_request_verify_sizes(req, 0x04);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 return smbd_smb2_request_error(req, status);
1336 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1337 if (subreq == NULL) {
1338 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1340 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1343 * Avoid sending a STATUS_PENDING message, it's very likely
1344 * the client won't expect that.
1346 return smbd_smb2_request_pending_queue(req, subreq, 0);
1349 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1351 struct smbd_smb2_request *smb2req =
1352 tevent_req_callback_data(subreq,
1353 struct smbd_smb2_request);
1358 status = smbd_smb2_logoff_recv(subreq);
1359 TALLOC_FREE(subreq);
1360 if (!NT_STATUS_IS_OK(status)) {
1361 error = smbd_smb2_request_error(smb2req, status);
1362 if (!NT_STATUS_IS_OK(error)) {
1363 smbd_server_connection_terminate(smb2req->xconn,
1370 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1371 if (outbody.data == NULL) {
1372 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1373 if (!NT_STATUS_IS_OK(error)) {
1374 smbd_server_connection_terminate(smb2req->xconn,
1381 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1382 SSVAL(outbody.data, 0x02, 0); /* reserved */
1384 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1385 if (!NT_STATUS_IS_OK(error)) {
1386 smbd_server_connection_terminate(smb2req->xconn,
1392 struct smbd_smb2_logoff_state {
1393 struct smbd_smb2_request *smb2req;
1396 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1398 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1399 struct tevent_context *ev,
1400 struct smbd_smb2_request *smb2req)
1402 struct tevent_req *req;
1403 struct smbd_smb2_logoff_state *state;
1404 struct tevent_req *subreq;
1406 req = tevent_req_create(mem_ctx, &state,
1407 struct smbd_smb2_logoff_state);
1411 state->smb2req = smb2req;
1413 subreq = smb2srv_session_shutdown_send(state, ev,
1416 if (tevent_req_nomem(subreq, req)) {
1417 return tevent_req_post(req, ev);
1419 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1424 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1426 struct tevent_req *req = tevent_req_callback_data(
1427 subreq, struct tevent_req);
1428 struct smbd_smb2_logoff_state *state = tevent_req_data(
1429 req, struct smbd_smb2_logoff_state);
1432 const struct GUID *client_guid =
1433 &state->smb2req->session->client->connections->smb2.client.guid;
1435 status = smb2srv_session_shutdown_recv(subreq);
1436 if (tevent_req_nterror(req, status)) {
1439 TALLOC_FREE(subreq);
1441 if (!GUID_all_zero(client_guid)) {
1442 ok = remote_arch_cache_delete(client_guid);
1444 /* Most likely not an error, but not in cache */
1445 DBG_DEBUG("Deletion from remote arch cache failed\n");
1450 * As we've been awoken, we may have changed
1451 * uid in the meantime. Ensure we're still
1452 * root (SMB2_OP_LOGOFF has .as_root = true).
1454 change_to_root_user();
1456 status = smbXsrv_session_logoff(state->smb2req->session);
1457 if (tevent_req_nterror(req, status)) {
1462 * we may need to sign the response, so we need to keep
1463 * the session until the response is sent to the wire.
1465 talloc_steal(state->smb2req, state->smb2req->session);
1467 tevent_req_done(req);
1470 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1472 return tevent_req_simple_recv_ntstatus(req);