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/sha512.h"
32 #include "lib/crypto/aes.h"
33 #include "lib/crypto/aes_ccm_128.h"
34 #include "lib/crypto/aes_gcm_128.h"
36 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
37 struct tevent_context *ev,
38 struct smbd_smb2_request *smb2req,
39 uint64_t in_session_id,
41 uint8_t in_security_mode,
42 uint64_t in_previous_session_id,
43 DATA_BLOB in_security_buffer);
44 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
45 uint16_t *out_session_flags,
47 DATA_BLOB *out_security_buffer,
48 uint64_t *out_session_id);
50 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
52 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
55 const uint8_t *inbody;
56 uint64_t in_session_id;
58 uint8_t in_security_mode;
59 uint64_t in_previous_session_id;
60 uint16_t in_security_offset;
61 uint16_t in_security_length;
62 DATA_BLOB in_security_buffer;
64 struct tevent_req *subreq;
66 status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
67 if (!NT_STATUS_IS_OK(status)) {
68 return smbd_smb2_request_error(smb2req, status);
70 inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
71 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
73 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
75 in_flags = CVAL(inbody, 0x02);
76 in_security_mode = CVAL(inbody, 0x03);
77 /* Capabilities = IVAL(inbody, 0x04) */
78 /* Channel = IVAL(inbody, 0x08) */
79 in_security_offset = SVAL(inbody, 0x0C);
80 in_security_length = SVAL(inbody, 0x0E);
81 in_previous_session_id = BVAL(inbody, 0x10);
83 if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
84 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
87 if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
88 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
91 in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
92 in_security_buffer.length = in_security_length;
94 subreq = smbd_smb2_session_setup_wrap_send(smb2req,
95 smb2req->sconn->ev_ctx,
100 in_previous_session_id,
102 if (subreq == NULL) {
103 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
105 tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
107 return smbd_smb2_request_pending_queue(smb2req, subreq, 500);
110 static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
112 struct smbd_smb2_request *smb2req =
113 tevent_req_callback_data(subreq,
114 struct smbd_smb2_request);
118 uint16_t out_session_flags = 0;
119 uint64_t out_session_id = 0;
120 uint16_t out_security_offset;
121 DATA_BLOB out_security_buffer = data_blob_null;
123 NTSTATUS error; /* transport error */
125 status = smbd_smb2_session_setup_wrap_recv(subreq,
128 &out_security_buffer,
131 if (!NT_STATUS_IS_OK(status) &&
132 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
133 status = nt_status_squash(status);
134 error = smbd_smb2_request_error(smb2req, status);
135 if (!NT_STATUS_IS_OK(error)) {
136 smbd_server_connection_terminate(smb2req->xconn,
143 out_security_offset = SMB2_HDR_BODY + 0x08;
145 outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
147 outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
148 if (outbody.data == NULL) {
149 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
150 if (!NT_STATUS_IS_OK(error)) {
151 smbd_server_connection_terminate(smb2req->xconn,
158 SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
160 SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
161 SSVAL(outbody.data, 0x02,
162 out_session_flags); /* session flags */
163 SSVAL(outbody.data, 0x04,
164 out_security_offset); /* security buffer offset */
165 SSVAL(outbody.data, 0x06,
166 out_security_buffer.length); /* security buffer length */
168 outdyn = out_security_buffer;
170 error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
172 if (!NT_STATUS_IS_OK(error)) {
173 smbd_server_connection_terminate(smb2req->xconn,
179 static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
180 struct smbXsrv_session_auth0 **_auth,
181 struct smbd_smb2_request *smb2req,
182 uint8_t in_security_mode,
183 struct auth_session_info *session_info,
184 uint16_t *out_session_flags,
185 uint64_t *out_session_id)
189 uint8_t session_key[16];
190 struct smbXsrv_session *x = session;
191 struct smbXsrv_session_auth0 *auth = *_auth;
192 struct smbXsrv_connection *xconn = smb2req->xconn;
199 struct _derivation signing;
200 struct _derivation encryption;
201 struct _derivation decryption;
202 struct _derivation application;
207 if (xconn->protocol >= PROTOCOL_SMB3_10) {
208 struct smbXsrv_preauth *preauth;
209 struct _derivation *d;
211 struct hc_sha512state sctx;
213 preauth = talloc_move(smb2req, &auth->preauth);
215 samba_SHA512_Init(&sctx);
216 samba_SHA512_Update(&sctx, preauth->sha512_value,
217 sizeof(preauth->sha512_value));
218 for (i = 1; i < smb2req->in.vector_count; i++) {
219 samba_SHA512_Update(&sctx,
220 smb2req->in.vector[i].iov_base,
221 smb2req->in.vector[i].iov_len);
223 samba_SHA512_Final(preauth->sha512_value, &sctx);
225 p = data_blob_const(preauth->sha512_value,
226 sizeof(preauth->sha512_value));
228 d = &derivation.signing;
229 d->label = data_blob_string_const_null("SMBSigningKey");
232 d = &derivation.decryption;
233 d->label = data_blob_string_const_null("SMBC2SCipherKey");
236 d = &derivation.encryption;
237 d->label = data_blob_string_const_null("SMBS2CCipherKey");
240 d = &derivation.application;
241 d->label = data_blob_string_const_null("SMBAppKey");
244 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
245 struct _derivation *d;
247 d = &derivation.signing;
248 d->label = data_blob_string_const_null("SMB2AESCMAC");
249 d->context = data_blob_string_const_null("SmbSign");
251 d = &derivation.decryption;
252 d->label = data_blob_string_const_null("SMB2AESCCM");
253 d->context = data_blob_string_const_null("ServerIn ");
255 d = &derivation.encryption;
256 d->label = data_blob_string_const_null("SMB2AESCCM");
257 d->context = data_blob_string_const_null("ServerOut");
259 d = &derivation.application;
260 d->label = data_blob_string_const_null("SMB2APP");
261 d->context = data_blob_string_const_null("SmbRpc");
264 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
265 (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
267 x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
270 if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
271 (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
272 x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
275 if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
276 x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
277 SMBXSRV_ENCRYPTION_DESIRED;
280 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
281 /* we map anonymous to guest internally */
282 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
283 *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL;
284 /* force no signing */
285 x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
289 if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
290 DEBUG(1,("reject guest session as encryption is required\n"));
291 return NT_STATUS_ACCESS_DENIED;
294 if (xconn->smb2.server.cipher == 0) {
295 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
296 DEBUG(1,("reject session with dialect[0x%04X] "
297 "as encryption is required\n",
298 xconn->smb2.server.dialect));
299 return NT_STATUS_ACCESS_DENIED;
302 x->global->channels[0].encryption_cipher = xconn->smb2.server.cipher;
305 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
306 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
309 ZERO_STRUCT(session_key);
310 memcpy(session_key, session_info->session_key.data,
311 MIN(session_info->session_key.length, sizeof(session_key)));
313 x->global->signing_key = data_blob_talloc(x->global,
315 sizeof(session_key));
316 if (x->global->signing_key.data == NULL) {
317 ZERO_STRUCT(session_key);
318 return NT_STATUS_NO_MEMORY;
321 if (xconn->protocol >= PROTOCOL_SMB2_24) {
322 struct _derivation *d = &derivation.signing;
324 smb2_key_derivation(session_key, sizeof(session_key),
325 d->label.data, d->label.length,
326 d->context.data, d->context.length,
327 x->global->signing_key.data);
330 if (xconn->protocol >= PROTOCOL_SMB2_24) {
331 struct _derivation *d = &derivation.decryption;
333 x->global->decryption_key = data_blob_talloc(x->global,
335 sizeof(session_key));
336 if (x->global->decryption_key.data == NULL) {
337 ZERO_STRUCT(session_key);
338 return NT_STATUS_NO_MEMORY;
341 smb2_key_derivation(session_key, sizeof(session_key),
342 d->label.data, d->label.length,
343 d->context.data, d->context.length,
344 x->global->decryption_key.data);
347 if (xconn->protocol >= PROTOCOL_SMB2_24) {
348 struct _derivation *d = &derivation.encryption;
351 x->global->encryption_key = data_blob_talloc(x->global,
353 sizeof(session_key));
354 if (x->global->encryption_key.data == NULL) {
355 ZERO_STRUCT(session_key);
356 return NT_STATUS_NO_MEMORY;
359 smb2_key_derivation(session_key, sizeof(session_key),
360 d->label.data, d->label.length,
361 d->context.data, d->context.length,
362 x->global->encryption_key.data);
365 * CCM and GCM algorithms must never have their
366 * nonce wrap, or the security of the whole
367 * communication and the keys is destroyed.
368 * We must drop the connection once we have
369 * transfered too much data.
371 * NOTE: We assume nonces greater than 8 bytes.
373 generate_random_buffer((uint8_t *)&x->nonce_high_random,
374 sizeof(x->nonce_high_random));
375 switch (xconn->smb2.server.cipher) {
376 case SMB2_ENCRYPTION_AES128_CCM:
377 nonce_size = AES_CCM_128_NONCE_SIZE;
379 case SMB2_ENCRYPTION_AES128_GCM:
380 nonce_size = AES_GCM_128_IV_SIZE;
386 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
391 x->global->application_key = data_blob_dup_talloc(x->global,
392 x->global->signing_key);
393 if (x->global->application_key.data == NULL) {
394 ZERO_STRUCT(session_key);
395 return NT_STATUS_NO_MEMORY;
398 if (xconn->protocol >= PROTOCOL_SMB2_24) {
399 struct _derivation *d = &derivation.application;
401 smb2_key_derivation(session_key, sizeof(session_key),
402 d->label.data, d->label.length,
403 d->context.data, d->context.length,
404 x->global->application_key.data);
406 ZERO_STRUCT(session_key);
408 x->global->channels[0].signing_key = data_blob_dup_talloc(x->global->channels,
409 x->global->signing_key);
410 if (x->global->channels[0].signing_key.data == NULL) {
411 return NT_STATUS_NO_MEMORY;
414 data_blob_clear_free(&session_info->session_key);
415 session_info->session_key = data_blob_dup_talloc(session_info,
416 x->global->application_key);
417 if (session_info->session_key.data == NULL) {
418 return NT_STATUS_NO_MEMORY;
421 session->compat = talloc_zero(session, struct user_struct);
422 if (session->compat == NULL) {
423 return NT_STATUS_NO_MEMORY;
425 session->compat->session = session;
426 session->compat->homes_snum = -1;
427 session->compat->session_info = session_info;
428 session->compat->session_keystr = NULL;
429 session->compat->vuid = session->global->session_wire_id;
430 DLIST_ADD(smb2req->sconn->users, session->compat);
431 smb2req->sconn->num_users++;
433 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
434 session->compat->homes_snum =
435 register_homes_share(session_info->unix_info->unix_name);
438 set_current_user_info(session_info->unix_info->sanitized_username,
439 session_info->unix_info->unix_name,
440 session_info->info->domain_name);
442 reload_services(smb2req->sconn, conn_snum_used, true);
444 session->status = NT_STATUS_OK;
445 session->global->auth_session_info = talloc_move(session->global,
447 session->global->auth_session_info_seqnum += 1;
448 for (i=0; i < session->global->num_channels; i++) {
449 struct smbXsrv_channel_global0 *_c =
450 &session->global->channels[i];
452 _c->auth_session_info_seqnum =
453 session->global->auth_session_info_seqnum;
455 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
456 session->global->expiration_time = gensec_expire_time(auth->gensec);
458 if (!session_claim(session)) {
459 DEBUG(1, ("smb2: Failed to claim session "
461 (unsigned long long)session->compat->vuid));
462 return NT_STATUS_LOGON_FAILURE;
466 status = smbXsrv_session_update(session);
467 if (!NT_STATUS_IS_OK(status)) {
468 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
469 (unsigned long long)session->compat->vuid,
471 return NT_STATUS_LOGON_FAILURE;
475 * we attach the session to the request
476 * so that the response can be signed
479 smb2req->do_signing = true;
482 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
484 *out_session_id = session->global->session_wire_id;
489 static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
490 struct smbXsrv_session_auth0 **_auth,
491 struct smbd_smb2_request *smb2req,
492 struct auth_session_info *session_info,
493 uint16_t *out_session_flags,
494 uint64_t *out_session_id)
497 struct smbXsrv_session *x = session;
498 struct smbXsrv_session_auth0 *auth = *_auth;
499 struct smbXsrv_connection *xconn = smb2req->xconn;
504 data_blob_clear_free(&session_info->session_key);
505 session_info->session_key = data_blob_dup_talloc(session_info,
506 x->global->application_key);
507 if (session_info->session_key.data == NULL) {
508 return NT_STATUS_NO_MEMORY;
511 session->compat->session_info = session_info;
512 session->compat->vuid = session->global->session_wire_id;
514 session->compat->homes_snum =
515 register_homes_share(session_info->unix_info->unix_name);
517 set_current_user_info(session_info->unix_info->sanitized_username,
518 session_info->unix_info->unix_name,
519 session_info->info->domain_name);
521 reload_services(smb2req->sconn, conn_snum_used, true);
523 session->status = NT_STATUS_OK;
524 TALLOC_FREE(session->global->auth_session_info);
525 session->global->auth_session_info = talloc_move(session->global,
527 session->global->auth_session_info_seqnum += 1;
528 for (i=0; i < session->global->num_channels; i++) {
529 struct smbXsrv_channel_global0 *_c =
530 &session->global->channels[i];
532 _c->auth_session_info_seqnum =
533 session->global->auth_session_info_seqnum;
535 session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
536 session->global->expiration_time = gensec_expire_time(auth->gensec);
539 status = smbXsrv_session_update(session);
540 if (!NT_STATUS_IS_OK(status)) {
541 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
542 (unsigned long long)session->compat->vuid,
544 return NT_STATUS_LOGON_FAILURE;
547 conn_clear_vuid_caches(xconn->client->sconn, session->compat->vuid);
549 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
550 smb2req->do_signing = true;
553 *out_session_id = session->global->session_wire_id;
558 static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
559 struct smbXsrv_session_auth0 **_auth,
560 struct smbd_smb2_request *smb2req,
561 struct auth_session_info *session_info,
562 uint16_t *out_session_flags,
563 uint64_t *out_session_id)
566 struct smbXsrv_session *x = session;
567 struct smbXsrv_session_auth0 *auth = *_auth;
568 struct smbXsrv_connection *xconn = smb2req->xconn;
569 struct smbXsrv_channel_global0 *c = NULL;
570 uint8_t session_key[16];
577 struct _derivation signing;
583 if (xconn->protocol >= PROTOCOL_SMB3_10) {
584 struct smbXsrv_preauth *preauth;
585 struct _derivation *d;
587 struct hc_sha512state sctx;
589 preauth = talloc_move(smb2req, &auth->preauth);
591 samba_SHA512_Init(&sctx);
592 samba_SHA512_Update(&sctx, preauth->sha512_value,
593 sizeof(preauth->sha512_value));
594 for (i = 1; i < smb2req->in.vector_count; i++) {
595 samba_SHA512_Update(&sctx,
596 smb2req->in.vector[i].iov_base,
597 smb2req->in.vector[i].iov_len);
599 samba_SHA512_Final(preauth->sha512_value, &sctx);
601 p = data_blob_const(preauth->sha512_value,
602 sizeof(preauth->sha512_value));
604 d = &derivation.signing;
605 d->label = data_blob_string_const_null("SMBSigningKey");
608 } else if (xconn->protocol >= PROTOCOL_SMB2_24) {
609 struct _derivation *d;
611 d = &derivation.signing;
612 d->label = data_blob_string_const_null("SMB2AESCMAC");
613 d->context = data_blob_string_const_null("SmbSign");
616 status = smbXsrv_session_find_channel(session, xconn, &c);
617 if (!NT_STATUS_IS_OK(status)) {
621 ok = security_token_is_sid(session_info->security_token,
622 &x->global->auth_session_info->security_token->sids[0]);
624 return NT_STATUS_NOT_SUPPORTED;
627 if (session_info->session_key.length == 0) {
628 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
629 return NT_STATUS_NOT_SUPPORTED;
632 ZERO_STRUCT(session_key);
633 memcpy(session_key, session_info->session_key.data,
634 MIN(session_info->session_key.length, sizeof(session_key)));
636 c->signing_key = data_blob_talloc(x->global,
638 sizeof(session_key));
639 if (c->signing_key.data == NULL) {
640 ZERO_STRUCT(session_key);
641 return NT_STATUS_NO_MEMORY;
644 if (xconn->protocol >= PROTOCOL_SMB2_24) {
645 struct _derivation *d = &derivation.signing;
647 smb2_key_derivation(session_key, sizeof(session_key),
648 d->label.data, d->label.length,
649 d->context.data, d->context.length,
650 c->signing_key.data);
652 ZERO_STRUCT(session_key);
655 status = smbXsrv_session_update(session);
656 if (!NT_STATUS_IS_OK(status)) {
657 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
658 (unsigned long long)session->compat->vuid,
660 return NT_STATUS_LOGON_FAILURE;
663 *out_session_id = session->global->session_wire_id;
668 struct smbd_smb2_session_setup_state {
669 struct tevent_context *ev;
670 struct smbd_smb2_request *smb2req;
671 uint64_t in_session_id;
673 uint8_t in_security_mode;
674 uint64_t in_previous_session_id;
675 DATA_BLOB in_security_buffer;
676 struct smbXsrv_session *session;
677 struct smbXsrv_session_auth0 *auth;
678 struct auth_session_info *session_info;
679 uint16_t out_session_flags;
680 DATA_BLOB out_security_buffer;
681 uint64_t out_session_id;
684 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
685 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
686 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
688 static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
689 struct tevent_context *ev,
690 struct smbd_smb2_request *smb2req,
691 uint64_t in_session_id,
693 uint8_t in_security_mode,
694 uint64_t in_previous_session_id,
695 DATA_BLOB in_security_buffer)
697 struct tevent_req *req;
698 struct smbd_smb2_session_setup_state *state;
700 NTTIME now = timeval_to_nttime(&smb2req->request_time);
701 struct tevent_req *subreq;
702 struct smbXsrv_channel_global0 *c = NULL;
703 enum security_user_level seclvl;
705 req = tevent_req_create(mem_ctx, &state,
706 struct smbd_smb2_session_setup_state);
711 state->smb2req = smb2req;
712 state->in_session_id = in_session_id;
713 state->in_flags = in_flags;
714 state->in_security_mode = in_security_mode;
715 state->in_previous_session_id = in_previous_session_id;
716 state->in_security_buffer = in_security_buffer;
718 if (in_flags & SMB2_SESSION_FLAG_BINDING) {
719 if (smb2req->xconn->protocol < PROTOCOL_SMB2_22) {
720 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
721 return tevent_req_post(req, ev);
724 if (!smb2req->xconn->client->server_multi_channel_enabled) {
725 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
726 return tevent_req_post(req, ev);
729 if (in_session_id == 0) {
730 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
731 return tevent_req_post(req, ev);
734 if (smb2req->session == NULL) {
735 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
736 return tevent_req_post(req, ev);
739 if (!smb2req->do_signing) {
740 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
741 return tevent_req_post(req, ev);
744 status = smbXsrv_session_find_channel(smb2req->session,
747 if (NT_STATUS_IS_OK(status)) {
748 if (c->signing_key.length == 0) {
751 tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
752 return tevent_req_post(req, ev);
756 * OLD: 3.00 NEW 3.02 => INVALID_PARAMETER
757 * OLD: 3.02 NEW 3.00 => INVALID_PARAMETER
758 * OLD: 2.10 NEW 3.02 => ACCESS_DENIED
759 * OLD: 3.02 NEW 2.10 => ACCESS_DENIED
761 if (smb2req->session->global->connection_dialect
762 < SMB2_DIALECT_REVISION_222)
764 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
765 return tevent_req_post(req, ev);
767 if (smb2req->xconn->smb2.server.dialect
768 < SMB2_DIALECT_REVISION_222)
770 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
771 return tevent_req_post(req, ev);
773 if (smb2req->session->global->connection_dialect
774 != smb2req->xconn->smb2.server.dialect)
776 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
777 return tevent_req_post(req, ev);
780 seclvl = security_session_user_level(
781 smb2req->session->global->auth_session_info,
783 if (seclvl < SECURITY_USER) {
784 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
785 return tevent_req_post(req, ev);
788 status = smbXsrv_session_add_channel(smb2req->session,
791 if (!NT_STATUS_IS_OK(status)) {
792 tevent_req_nterror(req, status);
793 return tevent_req_post(req, ev);
796 status = smbXsrv_session_update(smb2req->session);
797 if (!NT_STATUS_IS_OK(status)) {
798 tevent_req_nterror(req, status);
799 return tevent_req_post(req, ev);
805 if (state->in_session_id == 0) {
806 /* create a new session */
807 status = smbXsrv_session_create(state->smb2req->xconn,
808 now, &state->session);
809 if (tevent_req_nterror(req, status)) {
810 return tevent_req_post(req, ev);
812 smb2req->session = state->session;
814 if (smb2req->session == NULL) {
815 tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
816 return tevent_req_post(req, ev);
819 state->session = smb2req->session;
820 status = state->session->status;
821 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
822 status = NT_STATUS_OK;
824 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
825 status = NT_STATUS_OK;
827 if (tevent_req_nterror(req, status)) {
828 return tevent_req_post(req, ev);
830 if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
831 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
835 status = smbXsrv_session_find_channel(smb2req->session,
837 if (!NT_STATUS_IS_OK(status)) {
838 tevent_req_nterror(req, status);
839 return tevent_req_post(req, ev);
842 status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
844 if (!NT_STATUS_IS_OK(status)) {
845 status = smbXsrv_session_create_auth(state->session,
847 in_flags, in_security_mode,
849 if (tevent_req_nterror(req, status)) {
850 return tevent_req_post(req, ev);
854 if (state->auth->gensec == NULL) {
855 status = auth_generic_prepare(state->auth,
856 state->smb2req->xconn->remote_address,
857 &state->auth->gensec);
858 if (tevent_req_nterror(req, status)) {
859 return tevent_req_post(req, ev);
862 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
863 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
865 status = gensec_start_mech_by_oid(state->auth->gensec,
867 if (tevent_req_nterror(req, status)) {
868 return tevent_req_post(req, ev);
872 status = smbXsrv_session_update(state->session);
873 if (tevent_req_nterror(req, status)) {
874 return tevent_req_post(req, ev);
878 subreq = gensec_update_send(state, state->ev,
880 state->in_security_buffer);
882 if (tevent_req_nomem(subreq, req)) {
883 return tevent_req_post(req, ev);
885 tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
890 static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
892 struct tevent_req *req =
893 tevent_req_callback_data(subreq,
895 struct smbd_smb2_session_setup_state *state =
897 struct smbd_smb2_session_setup_state);
901 status = gensec_update_recv(subreq, state,
902 &state->out_security_buffer);
905 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
906 !NT_STATUS_IS_OK(status)) {
907 tevent_req_nterror(req, status);
911 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
912 state->out_session_id = state->session->global->session_wire_id;
913 state->smb2req->preauth = state->auth->preauth;
914 tevent_req_nterror(req, status);
918 status = gensec_session_info(state->auth->gensec,
920 &state->session_info);
921 if (tevent_req_nterror(req, status)) {
925 if ((state->in_previous_session_id != 0) &&
926 (state->session->global->session_wire_id !=
927 state->in_previous_session_id))
929 subreq = smb2srv_session_close_previous_send(state, state->ev,
930 state->smb2req->xconn,
932 state->in_previous_session_id,
933 state->session->global->session_wire_id);
934 if (tevent_req_nomem(subreq, req)) {
937 tevent_req_set_callback(subreq,
938 smbd_smb2_session_setup_previous_done,
943 smbd_smb2_session_setup_auth_return(req);
946 static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
948 struct tevent_req *req =
949 tevent_req_callback_data(subreq,
953 status = smb2srv_session_close_previous_recv(subreq);
955 if (tevent_req_nterror(req, status)) {
959 smbd_smb2_session_setup_auth_return(req);
962 static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
964 struct smbd_smb2_session_setup_state *state =
966 struct smbd_smb2_session_setup_state);
969 if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
970 status = smbd_smb2_bind_auth_return(state->session,
974 &state->out_session_flags,
975 &state->out_session_id);
976 if (tevent_req_nterror(req, status)) {
979 tevent_req_done(req);
983 if (state->session->global->auth_session_info != NULL) {
984 status = smbd_smb2_reauth_generic_return(state->session,
988 &state->out_session_flags,
989 &state->out_session_id);
990 if (tevent_req_nterror(req, status)) {
993 tevent_req_done(req);
997 status = smbd_smb2_auth_generic_return(state->session,
1000 state->in_security_mode,
1001 state->session_info,
1002 &state->out_session_flags,
1003 &state->out_session_id);
1004 if (tevent_req_nterror(req, status)) {
1008 tevent_req_done(req);
1012 static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
1013 uint16_t *out_session_flags,
1014 TALLOC_CTX *mem_ctx,
1015 DATA_BLOB *out_security_buffer,
1016 uint64_t *out_session_id)
1018 struct smbd_smb2_session_setup_state *state =
1019 tevent_req_data(req,
1020 struct smbd_smb2_session_setup_state);
1023 if (tevent_req_is_nterror(req, &status)) {
1024 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1025 tevent_req_received(req);
1026 return nt_status_squash(status);
1029 status = NT_STATUS_OK;
1032 *out_session_flags = state->out_session_flags;
1033 *out_security_buffer = state->out_security_buffer;
1034 *out_session_id = state->out_session_id;
1036 talloc_steal(mem_ctx, out_security_buffer->data);
1037 tevent_req_received(req);
1041 struct smbd_smb2_session_setup_wrap_state {
1042 struct tevent_context *ev;
1043 struct smbd_smb2_request *smb2req;
1044 uint64_t in_session_id;
1046 uint8_t in_security_mode;
1047 uint64_t in_previous_session_id;
1048 DATA_BLOB in_security_buffer;
1049 uint16_t out_session_flags;
1050 DATA_BLOB out_security_buffer;
1051 uint64_t out_session_id;
1055 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
1056 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
1058 static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
1059 struct tevent_context *ev,
1060 struct smbd_smb2_request *smb2req,
1061 uint64_t in_session_id,
1063 uint8_t in_security_mode,
1064 uint64_t in_previous_session_id,
1065 DATA_BLOB in_security_buffer)
1067 struct tevent_req *req;
1068 struct smbd_smb2_session_setup_wrap_state *state;
1069 struct tevent_req *subreq;
1071 req = tevent_req_create(mem_ctx, &state,
1072 struct smbd_smb2_session_setup_wrap_state);
1077 state->smb2req = smb2req;
1078 state->in_session_id = in_session_id;
1079 state->in_flags = in_flags;
1080 state->in_security_mode = in_security_mode;
1081 state->in_previous_session_id = in_previous_session_id;
1082 state->in_security_buffer = in_security_buffer;
1084 subreq = smbd_smb2_session_setup_send(state, state->ev,
1086 state->in_session_id,
1088 state->in_security_mode,
1089 state->in_previous_session_id,
1090 state->in_security_buffer);
1091 if (tevent_req_nomem(subreq, req)) {
1092 return tevent_req_post(req, ev);
1094 tevent_req_set_callback(subreq,
1095 smbd_smb2_session_setup_wrap_setup_done, req);
1100 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
1102 struct tevent_req *req =
1103 tevent_req_callback_data(subreq,
1105 struct smbd_smb2_session_setup_wrap_state *state =
1106 tevent_req_data(req,
1107 struct smbd_smb2_session_setup_wrap_state);
1110 status = smbd_smb2_session_setup_recv(subreq,
1111 &state->out_session_flags,
1113 &state->out_security_buffer,
1114 &state->out_session_id);
1115 TALLOC_FREE(subreq);
1116 if (NT_STATUS_IS_OK(status)) {
1117 tevent_req_done(req);
1120 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1121 tevent_req_nterror(req, status);
1125 if (state->smb2req->session == NULL) {
1126 tevent_req_nterror(req, status);
1130 state->error = status;
1132 subreq = smb2srv_session_shutdown_send(state, state->ev,
1133 state->smb2req->session,
1135 if (tevent_req_nomem(subreq, req)) {
1138 tevent_req_set_callback(subreq,
1139 smbd_smb2_session_setup_wrap_shutdown_done,
1143 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
1145 struct tevent_req *req =
1146 tevent_req_callback_data(subreq,
1148 struct smbd_smb2_session_setup_wrap_state *state =
1149 tevent_req_data(req,
1150 struct smbd_smb2_session_setup_wrap_state);
1153 status = smb2srv_session_shutdown_recv(subreq);
1154 TALLOC_FREE(subreq);
1155 if (tevent_req_nterror(req, status)) {
1160 * we may need to sign the response, so we need to keep
1161 * the session until the response is sent to the wire.
1163 talloc_steal(state->smb2req, state->smb2req->session);
1165 tevent_req_nterror(req, state->error);
1168 static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
1169 uint16_t *out_session_flags,
1170 TALLOC_CTX *mem_ctx,
1171 DATA_BLOB *out_security_buffer,
1172 uint64_t *out_session_id)
1174 struct smbd_smb2_session_setup_wrap_state *state =
1175 tevent_req_data(req,
1176 struct smbd_smb2_session_setup_wrap_state);
1179 if (tevent_req_is_nterror(req, &status)) {
1180 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1181 tevent_req_received(req);
1182 return nt_status_squash(status);
1185 status = NT_STATUS_OK;
1188 *out_session_flags = state->out_session_flags;
1189 *out_security_buffer = state->out_security_buffer;
1190 *out_session_id = state->out_session_id;
1192 talloc_steal(mem_ctx, out_security_buffer->data);
1193 tevent_req_received(req);
1197 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1198 struct tevent_context *ev,
1199 struct smbd_smb2_request *smb2req);
1200 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
1201 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
1203 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
1206 struct tevent_req *subreq = NULL;
1208 status = smbd_smb2_request_verify_sizes(req, 0x04);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 return smbd_smb2_request_error(req, status);
1213 subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
1214 if (subreq == NULL) {
1215 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
1217 tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
1220 * Wait a long time before going async on this to allow
1221 * requests we're waiting on to finish. Set timeout to 10 secs.
1223 return smbd_smb2_request_pending_queue(req, subreq, 10000000);
1226 static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
1228 struct smbd_smb2_request *smb2req =
1229 tevent_req_callback_data(subreq,
1230 struct smbd_smb2_request);
1235 status = smbd_smb2_logoff_recv(subreq);
1236 TALLOC_FREE(subreq);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 error = smbd_smb2_request_error(smb2req, status);
1239 if (!NT_STATUS_IS_OK(error)) {
1240 smbd_server_connection_terminate(smb2req->xconn,
1247 outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
1248 if (outbody.data == NULL) {
1249 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
1250 if (!NT_STATUS_IS_OK(error)) {
1251 smbd_server_connection_terminate(smb2req->xconn,
1258 SSVAL(outbody.data, 0x00, 0x04); /* struct size */
1259 SSVAL(outbody.data, 0x02, 0); /* reserved */
1261 error = smbd_smb2_request_done(smb2req, outbody, NULL);
1262 if (!NT_STATUS_IS_OK(error)) {
1263 smbd_server_connection_terminate(smb2req->xconn,
1269 struct smbd_smb2_logoff_state {
1270 struct smbd_smb2_request *smb2req;
1273 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
1275 static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
1276 struct tevent_context *ev,
1277 struct smbd_smb2_request *smb2req)
1279 struct tevent_req *req;
1280 struct smbd_smb2_logoff_state *state;
1281 struct tevent_req *subreq;
1283 req = tevent_req_create(mem_ctx, &state,
1284 struct smbd_smb2_logoff_state);
1288 state->smb2req = smb2req;
1290 subreq = smb2srv_session_shutdown_send(state, ev,
1293 if (tevent_req_nomem(subreq, req)) {
1294 return tevent_req_post(req, ev);
1296 tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
1301 static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
1303 struct tevent_req *req = tevent_req_callback_data(
1304 subreq, struct tevent_req);
1305 struct smbd_smb2_logoff_state *state = tevent_req_data(
1306 req, struct smbd_smb2_logoff_state);
1309 status = smb2srv_session_shutdown_recv(subreq);
1310 if (tevent_req_nterror(req, status)) {
1313 TALLOC_FREE(subreq);
1316 * As we've been awoken, we may have changed
1317 * uid in the meantime. Ensure we're still
1318 * root (SMB2_OP_LOGOFF has .as_root = true).
1320 change_to_root_user();
1322 status = smbXsrv_session_logoff(state->smb2req->session);
1323 if (tevent_req_nterror(req, status)) {
1328 * we may need to sign the response, so we need to keep
1329 * the session until the response is sent to the wire.
1331 talloc_steal(state->smb2req, state->smb2req->session);
1333 tevent_req_done(req);
1336 static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
1338 return tevent_req_simple_recv_ntstatus(req);