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 <gnutls/gnutls.h>
36 #include <gnutls/crypto.h>
39 #define DBGC_CLASS DBGC_SMB2
41 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
42 struct tevent_context *ev,
43 struct smbd_smb2_request *smb2req,
44 uint64_t in_session_id,
46 uint8_t in_security_mode,
47 uint64_t in_previous_session_id,
48 DATA_BLOB in_security_buffer);
49 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
50 uint16_t *out_session_flags,
52 DATA_BLOB *out_security_buffer,
53 uint64_t *out_session_id);
55 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
57 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
60 const uint8_t *inbody;
61 uint64_t in_session_id;
63 uint8_t in_security_mode;
64 uint64_t in_previous_session_id;
65 uint16_t in_security_offset;
66 uint16_t in_security_length;
67 DATA_BLOB in_security_buffer;
69 struct tevent_req *subreq;
71 status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
72 if (!NT_STATUS_IS_OK(status)) {
73 return smbd_smb2_request_error(smb2req, status);
75 inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
76 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
78 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
80 in_flags = CVAL(inbody, 0x02);
81 in_security_mode = CVAL(inbody, 0x03);
82 /* Capabilities = IVAL(inbody, 0x04) */
83 /* Channel = IVAL(inbody, 0x08) */
84 in_security_offset = SVAL(inbody, 0x0C);
85 in_security_length = SVAL(inbody, 0x0E);
86 in_previous_session_id = BVAL(inbody, 0x10);
88 if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
89 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
92 if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
93 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
96 in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
97 in_security_buffer.length = in_security_length;
99 subreq = smbd_smb2_session_setup_wrap_send(smb2req,
100 smb2req->sconn->ev_ctx,
105 in_previous_session_id,
107 if (subreq == NULL) {
108 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
110 tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
113 * Avoid sending a STATUS_PENDING message, which
114 * matches a Windows Server and avoids problems with
117 * Even after 90 seconds a Windows Server doesn't return
118 * STATUS_PENDING if using NTLMSSP against a non reachable
121 return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
124 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
126 struct smbd_smb2_request *smb2req =
127 tevent_req_callback_data(subreq,
128 struct smbd_smb2_request);
132 uint16_t out_session_flags = 0;
133 uint64_t out_session_id = 0;
134 uint16_t out_security_offset;
135 DATA_BLOB out_security_buffer = data_blob_null;
137 NTSTATUS error; /* transport error */
139 status = smbd_smb2_session_setup_wrap_recv(subreq,
142 &out_security_buffer,
145 if (!NT_STATUS_IS_OK(status) &&
146 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
147 status = nt_status_squash(status);
148 error = smbd_smb2_request_error(smb2req, status);
149 if (!NT_STATUS_IS_OK(error)) {
150 smbd_server_connection_terminate(smb2req->xconn,
157 out_security_offset = SMB2_HDR_BODY + 0x08;
159 outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
161 outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
162 if (outbody.data == NULL) {
163 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
164 if (!NT_STATUS_IS_OK(error)) {
165 smbd_server_connection_terminate(smb2req->xconn,
172 SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
174 SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
175 SSVAL(outbody.data, 0x02,
176 out_session_flags); /* session flags */
177 SSVAL(outbody.data, 0x04,
178 out_security_offset); /* security buffer offset */
179 SSVAL(outbody.data, 0x06,
180 out_security_buffer.length); /* security buffer length */
182 outdyn = out_security_buffer;
184 error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
186 if (!NT_STATUS_IS_OK(error)) {
187 smbd_server_connection_terminate(smb2req->xconn,
193 static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
194 struct smbXsrv_session_auth0 **_auth,
195 struct smbd_smb2_request *smb2req,
196 uint8_t in_security_mode,
197 struct auth_session_info *session_info,
198 uint16_t *out_session_flags,
199 uint64_t *out_session_id)
203 uint8_t session_key[16];
204 struct smbXsrv_session *x = session;
205 struct smbXsrv_session_auth0 *auth = *_auth;
206 struct smbXsrv_connection *xconn = smb2req->xconn;
213 struct _derivation signing;
214 struct _derivation encryption;
215 struct _derivation decryption;
216 struct _derivation application;
221 if (xconn->protocol >= PROTOCOL_SMB3_10) {
222 struct smbXsrv_preauth *preauth;
223 struct _derivation *d;
225 gnutls_hash_hd_t hash_hnd;
228 preauth = talloc_move(smb2req, &auth->preauth);
230 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
232 return NT_STATUS_NO_MEMORY;
234 rc = gnutls_hash(hash_hnd,
235 preauth->sha512_value,
236 sizeof(preauth->sha512_value));
238 gnutls_hash_deinit(hash_hnd, NULL);
239 return NT_STATUS_ACCESS_DENIED;
241 for (i = 1; i < smb2req->in.vector_count; i++) {
242 rc = gnutls_hash(hash_hnd,
243 smb2req->in.vector[i].iov_base,
244 smb2req->in.vector[i].iov_len);
246 gnutls_hash_deinit(hash_hnd, NULL);
247 return NT_STATUS_ACCESS_DENIED;
250 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
252 p = data_blob_const(preauth->sha512_value,
253 sizeof(preauth->sha512_value));
255 d = &derivation.signing;
256 d->label = data_blob_string_const_null("SMBSigningKey");
259 d = &derivation.decryption;
260 d->label = data_blob_string_const_null("SMBC2SCipherKey");
263 d = &derivation.encryption;
264 d->label = data_blob_string_const_null("SMBS2CCipherKey");
267 d = &derivation.application;
268 d->label = data_blob_string_const_null("SMBAppKey");
271 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
272 struct _derivation *d;
274 d = &derivation.signing;
275 d->label = data_blob_string_const_null("SMB2AESCMAC");
276 d->context = data_blob_string_const_null("SmbSign");
278 d = &derivation.decryption;
279 d->label = data_blob_string_const_null("SMB2AESCCM");
280 d->context = data_blob_string_const_null("ServerIn ");
282 d = &derivation.encryption;
283 d->label = data_blob_string_const_null("SMB2AESCCM");
284 d->context = data_blob_string_const_null("ServerOut");
286 d = &derivation.application;
287 d->label = data_blob_string_const_null("SMB2APP");
288 d->context = data_blob_string_const_null("SmbRpc");
291 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
292 (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
294 x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
297 if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
298 (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
299 x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
302 if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
303 x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
304 SMBXSRV_ENCRYPTION_DESIRED;
307 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
308 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
309 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
311 /* force no signing */
312 x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
313 /* we map anonymous to guest internally */
317 if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
318 DEBUG(1,("reject guest session as encryption is required\n"));
319 return NT_STATUS_ACCESS_DENIED;
322 if (xconn->smb2.server.cipher == 0) {
323 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
324 DEBUG(1,("reject session with dialect[0x%04X] "
325 "as encryption is required\n",
326 xconn->smb2.server.dialect));
327 return NT_STATUS_ACCESS_DENIED;
330 x->global->channels[0].encryption_cipher = xconn->smb2.server.cipher;
333 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
334 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
337 ZERO_STRUCT(session_key);
338 memcpy(session_key, session_info->session_key.data,
339 MIN(session_info->session_key.length, sizeof(session_key)));
341 x->global->signing_key = talloc_zero(x->global,
342 struct smb2_signing_key);
343 if (x->global->signing_key == NULL) {
344 ZERO_STRUCT(session_key);
345 return NT_STATUS_NO_MEMORY;
347 talloc_set_destructor(x->global->signing_key,
348 smb2_signing_key_destructor);
350 x->global->signing_key->blob =
351 x->global->signing_key_blob =
352 data_blob_talloc(x->global,
354 sizeof(session_key));
355 if (!smb2_signing_key_valid(x->global->signing_key)) {
356 ZERO_STRUCT(session_key);
357 return NT_STATUS_NO_MEMORY;
360 if (xconn->protocol >= PROTOCOL_SMB2_24) {
361 struct _derivation *d = &derivation.signing;
363 status = smb2_key_derivation(session_key, sizeof(session_key),
364 d->label.data, d->label.length,
365 d->context.data, d->context.length,
366 x->global->signing_key->blob.data);
367 if (!NT_STATUS_IS_OK(status)) {
372 if (xconn->protocol >= PROTOCOL_SMB2_24) {
373 struct _derivation *d = &derivation.decryption;
375 x->global->decryption_key_blob = data_blob_talloc(x->global,
377 sizeof(session_key));
378 if (x->global->decryption_key_blob.data == NULL) {
379 ZERO_STRUCT(session_key);
380 return NT_STATUS_NO_MEMORY;
383 status = smb2_key_derivation(session_key, sizeof(session_key),
384 d->label.data, d->label.length,
385 d->context.data, d->context.length,
386 x->global->decryption_key_blob.data);
387 if (!NT_STATUS_IS_OK(status)) {
392 if (xconn->protocol >= PROTOCOL_SMB2_24) {
393 struct _derivation *d = &derivation.encryption;
396 x->global->encryption_key_blob = data_blob_talloc(x->global,
398 sizeof(session_key));
399 if (x->global->encryption_key_blob.data == NULL) {
400 ZERO_STRUCT(session_key);
401 return NT_STATUS_NO_MEMORY;
404 status = smb2_key_derivation(session_key, sizeof(session_key),
405 d->label.data, d->label.length,
406 d->context.data, d->context.length,
407 x->global->encryption_key_blob.data);
408 if (!NT_STATUS_IS_OK(status)) {
413 * CCM and GCM algorithms must never have their
414 * nonce wrap, or the security of the whole
415 * communication and the keys is destroyed.
416 * We must drop the connection once we have
417 * transfered too much data.
419 * NOTE: We assume nonces greater than 8 bytes.
421 generate_random_buffer((uint8_t *)&x->nonce_high_random,
422 sizeof(x->nonce_high_random));
423 switch (xconn->smb2.server.cipher) {
424 case SMB2_ENCRYPTION_AES128_CCM:
425 nonce_size = AES_CCM_128_NONCE_SIZE;
427 case SMB2_ENCRYPTION_AES128_GCM:
428 nonce_size = AES_GCM_128_IV_SIZE;
434 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
439 x->global->application_key =
440 data_blob_dup_talloc(x->global, x->global->signing_key->blob);
441 if (x->global->application_key.data == NULL) {
442 ZERO_STRUCT(session_key);
443 return NT_STATUS_NO_MEMORY;
445 talloc_keep_secret(x->global->application_key.data);
447 if (xconn->protocol >= PROTOCOL_SMB2_24) {
448 struct _derivation *d = &derivation.application;
450 status = smb2_key_derivation(session_key, sizeof(session_key),
451 d->label.data, d->label.length,
452 d->context.data, d->context.length,
453 x->global->application_key.data);
454 if (!NT_STATUS_IS_OK(status)) {
459 if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
460 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
461 DEBUGADD(0, ("Session Id "));
462 dump_data(0, (uint8_t*)&session->global->session_wire_id,
463 sizeof(session->global->session_wire_id));
464 DEBUGADD(0, ("Session Key "));
465 dump_data(0, session_key, sizeof(session_key));
466 DEBUGADD(0, ("Signing Key "));
467 dump_data(0, x->global->signing_key->blob.data,
468 x->global->signing_key->blob.length);
469 DEBUGADD(0, ("App Key "));
470 dump_data(0, x->global->application_key.data,
471 x->global->application_key.length);
473 /* In server code, ServerIn is the decryption key */
475 DEBUGADD(0, ("ServerIn Key "));
476 dump_data(0, x->global->decryption_key_blob.data,
477 x->global->decryption_key_blob.length);
478 DEBUGADD(0, ("ServerOut Key "));
479 dump_data(0, x->global->encryption_key_blob.data,
480 x->global->encryption_key_blob.length);
483 ZERO_STRUCT(session_key);
485 x->global->channels[0].signing_key =
486 talloc_zero(x->global->channels, struct smb2_signing_key);
487 if (x->global->channels[0].signing_key == NULL) {
488 return NT_STATUS_NO_MEMORY;
490 talloc_set_destructor(x->global->channels[0].signing_key,
491 smb2_signing_key_destructor);
493 x->global->channels[0].signing_key->blob =
494 x->global->channels[0].signing_key_blob =
495 data_blob_dup_talloc(x->global->channels[0].signing_key,
496 x->global->signing_key->blob);
497 if (!smb2_signing_key_valid(x->global->channels[0].signing_key)) {
498 return NT_STATUS_NO_MEMORY;
500 talloc_keep_secret(x->global->channels[0].signing_key->blob.data);
502 data_blob_clear_free(&session_info->session_key);
503 session_info->session_key = data_blob_dup_talloc(session_info,
504 x->global->application_key);
505 if (session_info->session_key.data == NULL) {
506 return NT_STATUS_NO_MEMORY;
508 talloc_keep_secret(session_info->session_key.data);
510 session->compat = talloc_zero(session, struct user_struct);
511 if (session->compat == NULL) {
512 return NT_STATUS_NO_MEMORY;
514 session->compat->session = session;
515 session->compat->homes_snum = -1;
516 session->compat->session_info = session_info;
517 session->compat->session_keystr = NULL;
518 session->compat->vuid = session->global->session_wire_id;
519 DLIST_ADD(smb2req->sconn->users, session->compat);
520 smb2req->sconn->num_users++;
522 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
523 session->compat->homes_snum =
524 register_homes_share(session_info->unix_info->unix_name);
527 set_current_user_info(session_info->unix_info->sanitized_username,
528 session_info->unix_info->unix_name,
529 session_info->info->domain_name);
531 reload_services(smb2req->sconn, conn_snum_used, true);
533 session->status = NT_STATUS_OK;
534 session->global->auth_session_info = talloc_move(session->global,
536 session->global->auth_session_info_seqnum += 1;
537 for (i=0; i < session->global->num_channels; i++) {
538 struct smbXsrv_channel_global0 *_c =
539 &session->global->channels[i];
541 _c->auth_session_info_seqnum =
542 session->global->auth_session_info_seqnum;
544 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
545 session->global->expiration_time = gensec_expire_time(auth->gensec);
547 if (!session_claim(session)) {
548 DEBUG(1, ("smb2: Failed to claim session "
550 (unsigned long long)session->compat->vuid));
551 return NT_STATUS_LOGON_FAILURE;
555 status = smbXsrv_session_update(session);
556 if (!NT_STATUS_IS_OK(status)) {
557 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
558 (unsigned long long)session->compat->vuid,
560 return NT_STATUS_LOGON_FAILURE;
564 * we attach the session to the request
565 * so that the response can be signed
568 smb2req->do_signing = true;
571 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
573 *out_session_id = session->global->session_wire_id;
574 smb2req->last_session_id = session->global->session_wire_id;
579 static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
580 struct smbXsrv_session_auth0 **_auth,
581 struct smbd_smb2_request *smb2req,
582 struct auth_session_info *session_info,
583 uint16_t *out_session_flags,
584 uint64_t *out_session_id)
587 struct smbXsrv_session *x = session;
588 struct smbXsrv_session_auth0 *auth = *_auth;
589 struct smbXsrv_connection *xconn = smb2req->xconn;
594 data_blob_clear_free(&session_info->session_key);
595 session_info->session_key = data_blob_dup_talloc(session_info,
596 x->global->application_key);
597 if (session_info->session_key.data == NULL) {
598 return NT_STATUS_NO_MEMORY;
600 talloc_keep_secret(session_info->session_key.data);
602 session->compat->session_info = session_info;
603 session->compat->vuid = session->global->session_wire_id;
605 session->compat->homes_snum =
606 register_homes_share(session_info->unix_info->unix_name);
608 set_current_user_info(session_info->unix_info->sanitized_username,
609 session_info->unix_info->unix_name,
610 session_info->info->domain_name);
612 reload_services(smb2req->sconn, conn_snum_used, true);
614 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
615 smb2req->do_signing = true;
618 session->status = NT_STATUS_OK;
619 TALLOC_FREE(session->global->auth_session_info);
620 session->global->auth_session_info = talloc_move(session->global,
622 session->global->auth_session_info_seqnum += 1;
623 for (i=0; i < session->global->num_channels; i++) {
624 struct smbXsrv_channel_global0 *_c =
625 &session->global->channels[i];
627 _c->auth_session_info_seqnum =
628 session->global->auth_session_info_seqnum;
630 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
631 session->global->expiration_time = gensec_expire_time(auth->gensec);
634 status = smbXsrv_session_update(session);
635 if (!NT_STATUS_IS_OK(status)) {
636 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
637 (unsigned long long)session->compat->vuid,
639 return NT_STATUS_LOGON_FAILURE;
642 conn_clear_vuid_caches(xconn->client->sconn, session->compat->vuid);
644 *out_session_id = session->global->session_wire_id;
649 static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
650 struct smbXsrv_session_auth0 **_auth,
651 struct smbd_smb2_request *smb2req,
652 struct auth_session_info *session_info,
653 uint16_t *out_session_flags,
654 uint64_t *out_session_id)
657 struct smbXsrv_session *x = session;
658 struct smbXsrv_session_auth0 *auth = *_auth;
659 struct smbXsrv_connection *xconn = smb2req->xconn;
660 struct smbXsrv_channel_global0 *c = NULL;
661 uint8_t session_key[16];
668 struct _derivation signing;
674 if (xconn->protocol >= PROTOCOL_SMB3_10) {
675 struct smbXsrv_preauth *preauth;
676 struct _derivation *d;
678 gnutls_hash_hd_t hash_hnd = NULL;
681 preauth = talloc_move(smb2req, &auth->preauth);
683 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
685 return NT_STATUS_NO_MEMORY;
688 rc = gnutls_hash(hash_hnd,
689 preauth->sha512_value,
690 sizeof(preauth->sha512_value));
692 gnutls_hash_deinit(hash_hnd, NULL);
693 return NT_STATUS_INTERNAL_ERROR;
695 for (i = 1; i < smb2req->in.vector_count; i++) {
696 rc = gnutls_hash(hash_hnd,
697 smb2req->in.vector[i].iov_base,
698 smb2req->in.vector[i].iov_len);
700 gnutls_hash_deinit(hash_hnd, NULL);
701 return NT_STATUS_INTERNAL_ERROR;
704 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
706 p = data_blob_const(preauth->sha512_value,
707 sizeof(preauth->sha512_value));
709 d = &derivation.signing;
710 d->label = data_blob_string_const_null("SMBSigningKey");
713 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
714 struct _derivation *d;
716 d = &derivation.signing;
717 d->label = data_blob_string_const_null("SMB2AESCMAC");
718 d->context = data_blob_string_const_null("SmbSign");
721 status = smbXsrv_session_find_channel(session, xconn, &c);
722 if (!NT_STATUS_IS_OK(status)) {
726 ok = security_token_is_sid(session_info->security_token,
727 &x->global->auth_session_info->security_token->sids[0]);
729 return NT_STATUS_NOT_SUPPORTED;
732 if (session_info->session_key.length == 0) {
733 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
734 return NT_STATUS_NOT_SUPPORTED;
737 ZERO_STRUCT(session_key);
738 memcpy(session_key, session_info->session_key.data,
739 MIN(session_info->session_key.length, sizeof(session_key)));
741 c->signing_key = talloc_zero(x->global, struct smb2_signing_key);
742 if (c->signing_key == NULL) {
743 ZERO_STRUCT(session_key);
744 return NT_STATUS_NO_MEMORY;
746 talloc_set_destructor(c->signing_key,
747 smb2_signing_key_destructor);
749 c->signing_key->blob =
750 c->signing_key_blob =
751 data_blob_talloc(c->signing_key,
753 sizeof(session_key));
754 if (!smb2_signing_key_valid(c->signing_key)) {
755 ZERO_STRUCT(session_key);
756 return NT_STATUS_NO_MEMORY;
758 talloc_keep_secret(c->signing_key->blob.data);
760 if (xconn->protocol >= PROTOCOL_SMB2_24) {
761 struct _derivation *d = &derivation.signing;
763 status = smb2_key_derivation(session_key, sizeof(session_key),
764 d->label.data, d->label.length,
765 d->context.data, d->context.length,
766 c->signing_key->blob.data);
767 if (!NT_STATUS_IS_OK(status)) {
771 ZERO_STRUCT(session_key);
774 status = smbXsrv_session_update(session);
775 if (!NT_STATUS_IS_OK(status)) {
776 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
777 (unsigned long long)session->compat->vuid,
779 return NT_STATUS_LOGON_FAILURE;
782 *out_session_id = session->global->session_wire_id;
787 struct smbd_smb2_session_setup_state {
788 struct tevent_context *ev;
789 struct smbd_smb2_request *smb2req;
790 uint64_t in_session_id;
792 uint8_t in_security_mode;
793 uint64_t in_previous_session_id;
794 DATA_BLOB in_security_buffer;
795 struct smbXsrv_session *session;
796 struct smbXsrv_session_auth0 *auth;
797 struct auth_session_info *session_info;
798 uint16_t out_session_flags;
799 DATA_BLOB out_security_buffer;
800 uint64_t out_session_id;
803 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
804 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
805 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
807 static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
808 struct tevent_context *ev,
809 struct smbd_smb2_request *smb2req,
810 uint64_t in_session_id,
812 uint8_t in_security_mode,
813 uint64_t in_previous_session_id,
814 DATA_BLOB in_security_buffer)
816 struct tevent_req *req;
817 struct smbd_smb2_session_setup_state *state;
819 NTTIME now = timeval_to_nttime(&smb2req->request_time);
820 struct tevent_req *subreq;
821 struct smbXsrv_channel_global0 *c = NULL;
822 enum security_user_level seclvl;
824 req = tevent_req_create(mem_ctx, &state,
825 struct smbd_smb2_session_setup_state);
830 state->smb2req = smb2req;
831 state->in_session_id = in_session_id;
832 state->in_flags = in_flags;
833 state->in_security_mode = in_security_mode;
834 state->in_previous_session_id = in_previous_session_id;
835 state->in_security_buffer = in_security_buffer;
837 if (in_flags & SMB2_SESSION_FLAG_BINDING) {
838 if (smb2req->xconn->protocol < PROTOCOL_SMB2_22) {
839 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
840 return tevent_req_post(req, ev);
843 if (!smb2req->xconn->client->server_multi_channel_enabled) {
844 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
845 return tevent_req_post(req, ev);
848 if (in_session_id == 0) {
849 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
850 return tevent_req_post(req, ev);
853 if (smb2req->session == NULL) {
854 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
855 return tevent_req_post(req, ev);
858 if (!smb2req->do_signing) {
859 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
860 return tevent_req_post(req, ev);
863 status = smbXsrv_session_find_channel(smb2req->session,
866 if (NT_STATUS_IS_OK(status)) {
867 if (!smb2_signing_key_valid(c->signing_key)) {
870 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
871 return tevent_req_post(req, ev);
875 * OLD: 3.00 NEW 3.02 => INVALID_PARAMETER
876 * OLD: 3.02 NEW 3.00 => INVALID_PARAMETER
877 * OLD: 2.10 NEW 3.02 => ACCESS_DENIED
878 * OLD: 3.02 NEW 2.10 => ACCESS_DENIED
880 if (smb2req->session->global->connection_dialect
881 < SMB2_DIALECT_REVISION_222)
883 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
884 return tevent_req_post(req, ev);
886 if (smb2req->xconn->smb2.server.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->session->global->connection_dialect
893 != smb2req->xconn->smb2.server.dialect)
895 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
896 return tevent_req_post(req, ev);
899 seclvl = security_session_user_level(
900 smb2req->session->global->auth_session_info,
902 if (seclvl < SECURITY_USER) {
903 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
904 return tevent_req_post(req, ev);
907 status = smbXsrv_session_add_channel(smb2req->session,
910 if (!NT_STATUS_IS_OK(status)) {
911 tevent_req_nterror(req, status);
912 return tevent_req_post(req, ev);
915 status = smbXsrv_session_update(smb2req->session);
916 if (!NT_STATUS_IS_OK(status)) {
917 tevent_req_nterror(req, status);
918 return tevent_req_post(req, ev);
924 if (state->in_session_id == 0) {
925 /* create a new session */
926 status = smbXsrv_session_create(state->smb2req->xconn,
927 now, &state->session);
928 if (tevent_req_nterror(req, status)) {
929 return tevent_req_post(req, ev);
931 smb2req->session = state->session;
933 if (smb2req->session == NULL) {
934 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
935 return tevent_req_post(req, ev);
938 state->session = smb2req->session;
939 status = state->session->status;
940 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
941 status = NT_STATUS_OK;
943 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
944 status = NT_STATUS_OK;
946 if (tevent_req_nterror(req, status)) {
947 return tevent_req_post(req, ev);
949 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
950 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
954 status = smbXsrv_session_find_channel(smb2req->session,
956 if (!NT_STATUS_IS_OK(status)) {
957 tevent_req_nterror(req, status);
958 return tevent_req_post(req, ev);
961 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
963 if (!NT_STATUS_IS_OK(status)) {
964 status = smbXsrv_session_create_auth(state->session,
966 in_flags, in_security_mode,
968 if (tevent_req_nterror(req, status)) {
969 return tevent_req_post(req, ev);
973 if (state->auth->gensec == NULL) {
974 status = auth_generic_prepare(state->auth,
975 state->smb2req->xconn->remote_address,
976 state->smb2req->xconn->local_address,
978 &state->auth->gensec);
979 if (tevent_req_nterror(req, status)) {
980 return tevent_req_post(req, ev);
983 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
984 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
985 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
987 status = gensec_start_mech_by_oid(state->auth->gensec,
989 if (tevent_req_nterror(req, status)) {
990 return tevent_req_post(req, ev);
994 status = smbXsrv_session_update(state->session);
995 if (tevent_req_nterror(req, status)) {
996 return tevent_req_post(req, ev);
1000 subreq = gensec_update_send(state, state->ev,
1001 state->auth->gensec,
1002 state->in_security_buffer);
1004 if (tevent_req_nomem(subreq, req)) {
1005 return tevent_req_post(req, ev);
1007 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
1012 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
1014 struct tevent_req *req =
1015 tevent_req_callback_data(subreq,
1017 struct smbd_smb2_session_setup_state *state =
1018 tevent_req_data(req,
1019 struct smbd_smb2_session_setup_state);
1023 status = gensec_update_recv(subreq, state,
1024 &state->out_security_buffer);
1026 TALLOC_FREE(subreq);
1027 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
1028 !NT_STATUS_IS_OK(status)) {
1029 tevent_req_nterror(req, status);
1033 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1034 state->out_session_id = state->session->global->session_wire_id;
1035 state->smb2req->preauth = state->auth->preauth;
1036 tevent_req_nterror(req, status);
1040 status = gensec_session_info(state->auth->gensec,
1042 &state->session_info);
1043 if (tevent_req_nterror(req, status)) {
1047 if ((state->in_previous_session_id != 0) &&
1048 (state->session->global->session_wire_id !=
1049 state->in_previous_session_id))
1051 subreq = smb2srv_session_close_previous_send(state, state->ev,
1052 state->smb2req->xconn,
1053 state->session_info,
1054 state->in_previous_session_id,
1055 state->session->global->session_wire_id);
1056 if (tevent_req_nomem(subreq, req)) {
1059 tevent_req_set_callback(subreq,
1060 smbd_smb2_session_setup_previous_done,
1065 smbd_smb2_session_setup_auth_return(req);
1068 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
1070 struct tevent_req *req =
1071 tevent_req_callback_data(subreq,
1075 status = smb2srv_session_close_previous_recv(subreq);
1076 TALLOC_FREE(subreq);
1077 if (tevent_req_nterror(req, status)) {
1081 smbd_smb2_session_setup_auth_return(req);
1084 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
1086 struct smbd_smb2_session_setup_state *state =
1087 tevent_req_data(req,
1088 struct smbd_smb2_session_setup_state);
1091 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
1092 status = smbd_smb2_bind_auth_return(state->session,
1095 state->session_info,
1096 &state->out_session_flags,
1097 &state->out_session_id);
1098 if (tevent_req_nterror(req, status)) {
1101 tevent_req_done(req);
1105 if (state->session->global->auth_session_info != NULL) {
1106 status = smbd_smb2_reauth_generic_return(state->session,
1109 state->session_info,
1110 &state->out_session_flags,
1111 &state->out_session_id);
1112 if (tevent_req_nterror(req, status)) {
1115 tevent_req_done(req);
1119 status = smbd_smb2_auth_generic_return(state->session,
1122 state->in_security_mode,
1123 state->session_info,
1124 &state->out_session_flags,
1125 &state->out_session_id);
1126 if (tevent_req_nterror(req, status)) {
1130 tevent_req_done(req);
1134 static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1135 uint16_t *out_session_flags,
1136 TALLOC_CTX *mem_ctx,
1137 DATA_BLOB *out_security_buffer,
1138 uint64_t *out_session_id)
1140 struct smbd_smb2_session_setup_state *state =
1141 tevent_req_data(req,
1142 struct smbd_smb2_session_setup_state);
1145 if (tevent_req_is_nterror(req, &status)) {
1146 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1147 tevent_req_received(req);
1148 return nt_status_squash(status);
1151 status = NT_STATUS_OK;
1154 *out_session_flags = state->out_session_flags;
1155 *out_security_buffer = state->out_security_buffer;
1156 *out_session_id = state->out_session_id;
1158 talloc_steal(mem_ctx, out_security_buffer->data);
1159 tevent_req_received(req);
1163 struct smbd_smb2_session_setup_wrap_state {
1164 struct tevent_context *ev;
1165 struct smbd_smb2_request *smb2req;
1166 uint64_t in_session_id;
1168 uint8_t in_security_mode;
1169 uint64_t in_previous_session_id;
1170 DATA_BLOB in_security_buffer;
1171 uint16_t out_session_flags;
1172 DATA_BLOB out_security_buffer;
1173 uint64_t out_session_id;
1177 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1178 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1180 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1181 struct tevent_context *ev,
1182 struct smbd_smb2_request *smb2req,
1183 uint64_t in_session_id,
1185 uint8_t in_security_mode,
1186 uint64_t in_previous_session_id,
1187 DATA_BLOB in_security_buffer)
1189 struct tevent_req *req;
1190 struct smbd_smb2_session_setup_wrap_state *state;
1191 struct tevent_req *subreq;
1193 req = tevent_req_create(mem_ctx, &state,
1194 struct smbd_smb2_session_setup_wrap_state);
1199 state->smb2req = smb2req;
1200 state->in_session_id = in_session_id;
1201 state->in_flags = in_flags;
1202 state->in_security_mode = in_security_mode;
1203 state->in_previous_session_id = in_previous_session_id;
1204 state->in_security_buffer = in_security_buffer;
1206 subreq = smbd_smb2_session_setup_send(state, state->ev,
1208 state->in_session_id,
1210 state->in_security_mode,
1211 state->in_previous_session_id,
1212 state->in_security_buffer);
1213 if (tevent_req_nomem(subreq, req)) {
1214 return tevent_req_post(req, ev);
1216 tevent_req_set_callback(subreq,
1217 smbd_smb2_session_setup_wrap_setup_done, req);
1222 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1224 struct tevent_req *req =
1225 tevent_req_callback_data(subreq,
1227 struct smbd_smb2_session_setup_wrap_state *state =
1228 tevent_req_data(req,
1229 struct smbd_smb2_session_setup_wrap_state);
1232 status = smbd_smb2_session_setup_recv(subreq,
1233 &state->out_session_flags,
1235 &state->out_security_buffer,
1236 &state->out_session_id);
1237 TALLOC_FREE(subreq);
1238 if (NT_STATUS_IS_OK(status)) {
1239 tevent_req_done(req);
1242 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1243 tevent_req_nterror(req, status);
1247 if (state->smb2req->session == NULL) {
1248 tevent_req_nterror(req, status);
1252 state->error = status;
1254 subreq = smb2srv_session_shutdown_send(state, state->ev,
1255 state->smb2req->session,
1257 if (tevent_req_nomem(subreq, req)) {
1260 tevent_req_set_callback(subreq,
1261 smbd_smb2_session_setup_wrap_shutdown_done,
1265 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1267 struct tevent_req *req =
1268 tevent_req_callback_data(subreq,
1270 struct smbd_smb2_session_setup_wrap_state *state =
1271 tevent_req_data(req,
1272 struct smbd_smb2_session_setup_wrap_state);
1275 status = smb2srv_session_shutdown_recv(subreq);
1276 TALLOC_FREE(subreq);
1277 if (tevent_req_nterror(req, status)) {
1282 * we may need to sign the response, so we need to keep
1283 * the session until the response is sent to the wire.
1285 talloc_steal(state->smb2req, state->smb2req->session);
1287 tevent_req_nterror(req, state->error);
1290 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1291 uint16_t *out_session_flags,
1292 TALLOC_CTX *mem_ctx,
1293 DATA_BLOB *out_security_buffer,
1294 uint64_t *out_session_id)
1296 struct smbd_smb2_session_setup_wrap_state *state =
1297 tevent_req_data(req,
1298 struct smbd_smb2_session_setup_wrap_state);
1301 if (tevent_req_is_nterror(req, &status)) {
1302 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1303 tevent_req_received(req);
1304 return nt_status_squash(status);
1307 status = NT_STATUS_OK;
1310 *out_session_flags = state->out_session_flags;
1311 *out_security_buffer = state->out_security_buffer;
1312 *out_session_id = state->out_session_id;
1314 talloc_steal(mem_ctx, out_security_buffer->data);
1315 tevent_req_received(req);
1319 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1320 struct tevent_context *ev,
1321 struct smbd_smb2_request *smb2req);
1322 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1323 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1325 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1328 struct tevent_req *subreq = NULL;
1330 status = smbd_smb2_request_verify_sizes(req, 0x04);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 return smbd_smb2_request_error(req, status);
1335 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1336 if (subreq == NULL) {
1337 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1339 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1342 * Avoid sending a STATUS_PENDING message, it's very likely
1343 * the client won't expect that.
1345 return smbd_smb2_request_pending_queue(req, subreq, 0);
1348 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1350 struct smbd_smb2_request *smb2req =
1351 tevent_req_callback_data(subreq,
1352 struct smbd_smb2_request);
1357 status = smbd_smb2_logoff_recv(subreq);
1358 TALLOC_FREE(subreq);
1359 if (!NT_STATUS_IS_OK(status)) {
1360 error = smbd_smb2_request_error(smb2req, status);
1361 if (!NT_STATUS_IS_OK(error)) {
1362 smbd_server_connection_terminate(smb2req->xconn,
1369 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1370 if (outbody.data == NULL) {
1371 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1372 if (!NT_STATUS_IS_OK(error)) {
1373 smbd_server_connection_terminate(smb2req->xconn,
1380 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1381 SSVAL(outbody.data, 0x02, 0); /* reserved */
1383 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1384 if (!NT_STATUS_IS_OK(error)) {
1385 smbd_server_connection_terminate(smb2req->xconn,
1391 struct smbd_smb2_logoff_state {
1392 struct smbd_smb2_request *smb2req;
1395 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1397 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1398 struct tevent_context *ev,
1399 struct smbd_smb2_request *smb2req)
1401 struct tevent_req *req;
1402 struct smbd_smb2_logoff_state *state;
1403 struct tevent_req *subreq;
1405 req = tevent_req_create(mem_ctx, &state,
1406 struct smbd_smb2_logoff_state);
1410 state->smb2req = smb2req;
1412 subreq = smb2srv_session_shutdown_send(state, ev,
1415 if (tevent_req_nomem(subreq, req)) {
1416 return tevent_req_post(req, ev);
1418 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1423 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1425 struct tevent_req *req = tevent_req_callback_data(
1426 subreq, struct tevent_req);
1427 struct smbd_smb2_logoff_state *state = tevent_req_data(
1428 req, struct smbd_smb2_logoff_state);
1431 const struct GUID *client_guid =
1432 &state->smb2req->session->client->connections->smb2.client.guid;
1434 status = smb2srv_session_shutdown_recv(subreq);
1435 if (tevent_req_nterror(req, status)) {
1438 TALLOC_FREE(subreq);
1440 if (!GUID_all_zero(client_guid)) {
1441 ok = remote_arch_cache_delete(client_guid);
1443 /* Most likely not an error, but not in cache */
1444 DBG_DEBUG("Deletion from remote arch cache failed\n");
1449 * As we've been awoken, we may have changed
1450 * uid in the meantime. Ensure we're still
1451 * root (SMB2_OP_LOGOFF has .as_root = true).
1453 change_to_root_user();
1455 status = smbXsrv_session_logoff(state->smb2req->session);
1456 if (tevent_req_nterror(req, status)) {
1461 * we may need to sign the response, so we need to keep
1462 * the session until the response is sent to the wire.
1464 talloc_steal(state->smb2req, state->smb2req->session);
1466 tevent_req_done(req);
1469 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1471 return tevent_req_simple_recv_ntstatus(req);