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 "source3/smbd/smbXsrv_session.h"
26 #include "../libcli/smb/smb_common.h"
27 #include "../auth/gensec/gensec.h"
29 #include "../lib/tsocket/tsocket.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/tevent_ntstatus.h"
32 #include "source3/lib/substitute.h"
34 #include "lib/crypto/gnutls_helpers.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 struct smbXsrv_session
*x
= session
;
204 struct smbXsrv_session_auth0
*auth
= *_auth
;
205 struct smbXsrv_connection
*xconn
= smb2req
->xconn
;
207 struct smb2_signing_derivations derivations
= {
210 DATA_BLOB preauth_hash
= data_blob_null
;
214 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
215 struct smbXsrv_preauth
*preauth
;
216 gnutls_hash_hd_t hash_hnd
;
219 preauth
= talloc_move(smb2req
, &auth
->preauth
);
221 rc
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_SHA512
);
223 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
225 rc
= gnutls_hash(hash_hnd
,
226 preauth
->sha512_value
,
227 sizeof(preauth
->sha512_value
));
229 gnutls_hash_deinit(hash_hnd
, NULL
);
230 return NT_STATUS_ACCESS_DENIED
;
232 for (i
= 1; i
< smb2req
->in
.vector_count
; i
++) {
233 rc
= gnutls_hash(hash_hnd
,
234 smb2req
->in
.vector
[i
].iov_base
,
235 smb2req
->in
.vector
[i
].iov_len
);
237 gnutls_hash_deinit(hash_hnd
, NULL
);
238 return NT_STATUS_ACCESS_DENIED
;
241 gnutls_hash_deinit(hash_hnd
, preauth
->sha512_value
);
243 preauth_hash
= data_blob_const(preauth
->sha512_value
,
244 sizeof(preauth
->sha512_value
));
247 smb2_signing_derivations_fill_const_stack(&derivations
,
251 if ((in_security_mode
& SMB2_NEGOTIATE_SIGNING_REQUIRED
) ||
252 (xconn
->smb2
.server
.security_mode
& SMB2_NEGOTIATE_SIGNING_REQUIRED
))
254 x
->global
->signing_flags
= SMBXSRV_SIGNING_REQUIRED
;
257 if ((lp_server_smb_encrypt(-1) >= SMB_ENCRYPTION_DESIRED
) &&
258 (xconn
->smb2
.client
.capabilities
& SMB2_CAP_ENCRYPTION
)) {
259 x
->global
->encryption_flags
= SMBXSRV_ENCRYPTION_DESIRED
;
262 if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_REQUIRED
) {
263 x
->global
->encryption_flags
= SMBXSRV_ENCRYPTION_REQUIRED
|
264 SMBXSRV_ENCRYPTION_DESIRED
;
267 if (security_session_user_level(session_info
, NULL
) < SECURITY_USER
) {
268 if (security_session_user_level(session_info
, NULL
) == SECURITY_GUEST
) {
269 *out_session_flags
|= SMB2_SESSION_FLAG_IS_GUEST
;
271 /* force no signing */
272 x
->global
->signing_flags
&= ~SMBXSRV_SIGNING_REQUIRED
;
273 /* we map anonymous to guest internally */
277 if (guest
&& (x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
)) {
278 DEBUG(1,("reject guest session as encryption is required\n"));
279 return NT_STATUS_ACCESS_DENIED
;
282 if (xconn
->smb2
.server
.cipher
== 0) {
283 if (x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
) {
284 DEBUG(1,("reject session with dialect[0x%04X] "
285 "as encryption is required\n",
286 xconn
->smb2
.server
.dialect
));
287 return NT_STATUS_ACCESS_DENIED
;
290 x
->global
->signing_algo
= xconn
->smb2
.server
.sign_algo
;
291 x
->global
->encryption_cipher
= xconn
->smb2
.server
.cipher
;
293 x
->global
->encryption_cipher
= SMB2_ENCRYPTION_NONE
;
296 if (x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
297 *out_session_flags
|= SMB2_SESSION_FLAG_ENCRYPT_DATA
;
300 status
= smb2_signing_key_sign_create(x
->global
,
301 x
->global
->signing_algo
,
302 &session_info
->session_key
,
304 &x
->global
->signing_key
);
305 if (!NT_STATUS_IS_OK(status
)) {
308 x
->global
->signing_key_blob
= x
->global
->signing_key
->blob
;
310 if (x
->global
->encryption_cipher
!= SMB2_ENCRYPTION_NONE
) {
313 status
= smb2_signing_key_cipher_create(x
->global
,
314 x
->global
->encryption_cipher
,
315 &session_info
->session_key
,
316 derivations
.cipher_s2c
,
317 &x
->global
->encryption_key
);
318 if (!NT_STATUS_IS_OK(status
)) {
321 x
->global
->encryption_key_blob
= x
->global
->encryption_key
->blob
;
323 status
= smb2_signing_key_cipher_create(x
->global
,
324 x
->global
->encryption_cipher
,
325 &session_info
->session_key
,
326 derivations
.cipher_c2s
,
327 &x
->global
->decryption_key
);
328 if (!NT_STATUS_IS_OK(status
)) {
331 x
->global
->decryption_key_blob
= x
->global
->decryption_key
->blob
;
334 * CCM and GCM algorithms must never have their
335 * nonce wrap, or the security of the whole
336 * communication and the keys is destroyed.
337 * We must drop the connection once we have
338 * transferred too much data.
340 * NOTE: We assume nonces greater than 8 bytes.
342 generate_nonce_buffer((uint8_t *)&x
->nonce_high_random
,
343 sizeof(x
->nonce_high_random
));
344 switch (xconn
->smb2
.server
.cipher
) {
345 case SMB2_ENCRYPTION_AES128_CCM
:
346 nonce_size
= SMB2_AES_128_CCM_NONCE_SIZE
;
348 case SMB2_ENCRYPTION_AES128_GCM
:
349 nonce_size
= gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM
);
351 case SMB2_ENCRYPTION_AES256_CCM
:
352 nonce_size
= SMB2_AES_128_CCM_NONCE_SIZE
;
354 case SMB2_ENCRYPTION_AES256_GCM
:
355 nonce_size
= gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM
);
361 x
->nonce_high_max
= SMB2_NONCE_HIGH_MAX(nonce_size
);
366 status
= smb2_signing_key_sign_create(x
->global
,
367 x
->global
->signing_algo
,
368 &session_info
->session_key
,
369 derivations
.application
,
370 &x
->global
->application_key
);
371 if (!NT_STATUS_IS_OK(status
)) {
374 x
->global
->application_key_blob
= x
->global
->application_key
->blob
;
376 if (xconn
->protocol
>= PROTOCOL_SMB3_00
&& lp_debug_encryption()) {
377 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
378 DEBUGADD(0, ("Session Id "));
379 dump_data(0, (uint8_t*)&session
->global
->session_wire_id
,
380 sizeof(session
->global
->session_wire_id
));
381 DEBUGADD(0, ("Session Key "));
382 dump_data(0, session_info
->session_key
.data
,
383 session_info
->session_key
.length
);
384 DEBUGADD(0, ("Signing Algo: %u\n", x
->global
->signing_algo
));
385 DEBUGADD(0, ("Signing Key "));
386 dump_data(0, x
->global
->signing_key_blob
.data
,
387 x
->global
->signing_key_blob
.length
);
388 DEBUGADD(0, ("App Key "));
389 dump_data(0, x
->global
->application_key_blob
.data
,
390 x
->global
->application_key_blob
.length
);
392 /* In server code, ServerIn is the decryption key */
394 DEBUGADD(0, ("Cipher Algo: %u\n", x
->global
->encryption_cipher
));
395 DEBUGADD(0, ("ServerIn Key "));
396 dump_data(0, x
->global
->decryption_key_blob
.data
,
397 x
->global
->decryption_key_blob
.length
);
398 DEBUGADD(0, ("ServerOut Key "));
399 dump_data(0, x
->global
->encryption_key_blob
.data
,
400 x
->global
->encryption_key_blob
.length
);
403 status
= smb2_signing_key_copy(x
->global
->channels
,
404 x
->global
->signing_key
,
405 &x
->global
->channels
[0].signing_key
);
406 if (!NT_STATUS_IS_OK(status
)) {
409 x
->global
->channels
[0].signing_key_blob
=
410 x
->global
->channels
[0].signing_key
->blob
;
411 x
->global
->channels
[0].signing_algo
= x
->global
->signing_algo
;
412 x
->global
->channels
[0].encryption_cipher
= x
->global
->encryption_cipher
;
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_blob
);
417 if (session_info
->session_key
.data
== NULL
) {
418 return NT_STATUS_NO_MEMORY
;
420 talloc_keep_secret(session_info
->session_key
.data
);
422 smb2req
->sconn
->num_users
++;
424 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
425 session
->homes_snum
=
426 register_homes_share(session_info
->unix_info
->unix_name
);
429 set_current_user_info(session_info
->unix_info
->sanitized_username
,
430 session_info
->unix_info
->unix_name
,
431 session_info
->info
->domain_name
);
433 reload_services(smb2req
->sconn
, conn_snum_used
, true);
435 session
->status
= NT_STATUS_OK
;
436 session
->global
->auth_session_info
= talloc_move(session
->global
,
438 session
->global
->auth_session_info_seqnum
+= 1;
439 for (i
=0; i
< session
->global
->num_channels
; i
++) {
440 struct smbXsrv_channel_global0
*_c
=
441 &session
->global
->channels
[i
];
443 _c
->auth_session_info_seqnum
=
444 session
->global
->auth_session_info_seqnum
;
446 session
->global
->auth_time
= timeval_to_nttime(&smb2req
->request_time
);
447 session
->global
->expiration_time
= gensec_expire_time(auth
->gensec
);
449 if (!session_claim(session
)) {
450 DEBUG(1, ("smb2: Failed to claim session "
452 (unsigned long long)session
->global
->session_wire_id
));
453 return NT_STATUS_LOGON_FAILURE
;
457 status
= smbXsrv_session_update(session
);
458 if (!NT_STATUS_IS_OK(status
)) {
459 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
460 (unsigned long long)session
->global
->session_wire_id
,
462 return NT_STATUS_LOGON_FAILURE
;
466 * we attach the session to the request
467 * so that the response can be signed
470 smb2req
->do_signing
= true;
473 global_client_caps
|= (CAP_LEVEL_II_OPLOCKS
|CAP_STATUS32
);
475 *out_session_id
= session
->global
->session_wire_id
;
476 smb2req
->last_session_id
= session
->global
->session_wire_id
;
481 static NTSTATUS
smbd_smb2_reauth_generic_return(struct smbXsrv_session
*session
,
482 struct smbXsrv_session_auth0
**_auth
,
483 struct smbd_smb2_request
*smb2req
,
484 struct auth_session_info
*session_info
,
485 uint16_t *out_session_flags
,
486 uint64_t *out_session_id
)
489 struct smbXsrv_session
*x
= session
;
490 struct smbXsrv_session_auth0
*auth
= *_auth
;
491 struct smbXsrv_connection
*xconn
= smb2req
->xconn
;
496 data_blob_clear_free(&session_info
->session_key
);
497 session_info
->session_key
= data_blob_dup_talloc(session_info
,
498 x
->global
->application_key_blob
);
499 if (session_info
->session_key
.data
== NULL
) {
500 return NT_STATUS_NO_MEMORY
;
502 talloc_keep_secret(session_info
->session_key
.data
);
504 session
->homes_snum
=
505 register_homes_share(session_info
->unix_info
->unix_name
);
507 set_current_user_info(session_info
->unix_info
->sanitized_username
,
508 session_info
->unix_info
->unix_name
,
509 session_info
->info
->domain_name
);
511 reload_services(smb2req
->sconn
, conn_snum_used
, true);
513 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
514 smb2req
->do_signing
= true;
517 session
->status
= NT_STATUS_OK
;
518 TALLOC_FREE(session
->global
->auth_session_info
);
519 session
->global
->auth_session_info
= talloc_move(session
->global
,
521 session
->global
->auth_session_info_seqnum
+= 1;
522 for (i
=0; i
< session
->global
->num_channels
; i
++) {
523 struct smbXsrv_channel_global0
*_c
=
524 &session
->global
->channels
[i
];
526 _c
->auth_session_info_seqnum
=
527 session
->global
->auth_session_info_seqnum
;
529 session
->global
->auth_time
= timeval_to_nttime(&smb2req
->request_time
);
530 session
->global
->expiration_time
= gensec_expire_time(auth
->gensec
);
533 status
= smbXsrv_session_update(session
);
534 if (!NT_STATUS_IS_OK(status
)) {
535 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
536 (unsigned long long)session
->global
->session_wire_id
,
538 return NT_STATUS_LOGON_FAILURE
;
541 conn_clear_vuid_caches(xconn
->client
->sconn
,
542 session
->global
->session_wire_id
);
544 *out_session_id
= session
->global
->session_wire_id
;
549 static NTSTATUS
smbd_smb2_bind_auth_return(struct smbXsrv_session
*session
,
550 struct smbXsrv_session_auth0
**_auth
,
551 struct smbd_smb2_request
*smb2req
,
552 struct auth_session_info
*session_info
,
553 uint16_t *out_session_flags
,
554 uint64_t *out_session_id
)
557 struct smbXsrv_session
*x
= session
;
558 struct smbXsrv_session_auth0
*auth
= *_auth
;
559 struct smbXsrv_connection
*xconn
= smb2req
->xconn
;
560 struct smbXsrv_channel_global0
*c
= NULL
;
562 struct smb2_signing_derivations derivations
= {
565 DATA_BLOB preauth_hash
= data_blob_null
;
570 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
571 struct smbXsrv_preauth
*preauth
;
572 gnutls_hash_hd_t hash_hnd
= NULL
;
575 preauth
= talloc_move(smb2req
, &auth
->preauth
);
577 rc
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_SHA512
);
579 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
582 rc
= gnutls_hash(hash_hnd
,
583 preauth
->sha512_value
,
584 sizeof(preauth
->sha512_value
));
586 gnutls_hash_deinit(hash_hnd
, NULL
);
587 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
589 for (i
= 1; i
< smb2req
->in
.vector_count
; i
++) {
590 rc
= gnutls_hash(hash_hnd
,
591 smb2req
->in
.vector
[i
].iov_base
,
592 smb2req
->in
.vector
[i
].iov_len
);
594 gnutls_hash_deinit(hash_hnd
, NULL
);
595 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
598 gnutls_hash_deinit(hash_hnd
, preauth
->sha512_value
);
600 preauth_hash
= data_blob_const(preauth
->sha512_value
,
601 sizeof(preauth
->sha512_value
));
604 smb2_signing_derivations_fill_const_stack(&derivations
,
608 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
609 if (!NT_STATUS_IS_OK(status
)) {
613 ok
= security_token_is_sid(session_info
->security_token
,
614 &x
->global
->auth_session_info
->security_token
->sids
[0]);
616 return NT_STATUS_ACCESS_DENIED
;
619 if (session_info
->session_key
.length
== 0) {
620 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
621 return NT_STATUS_NOT_SUPPORTED
;
624 c
->signing_algo
= xconn
->smb2
.server
.sign_algo
;
625 c
->encryption_cipher
= xconn
->smb2
.server
.cipher
;
627 status
= smb2_signing_key_sign_create(x
->global
->channels
,
629 &session_info
->session_key
,
632 if (!NT_STATUS_IS_OK(status
)) {
635 c
->signing_key_blob
= c
->signing_key
->blob
;
638 status
= smbXsrv_session_update(session
);
639 if (!NT_STATUS_IS_OK(status
)) {
640 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
641 (unsigned long long)session
->global
->session_wire_id
,
643 return NT_STATUS_LOGON_FAILURE
;
646 *out_session_id
= session
->global
->session_wire_id
;
651 struct smbd_smb2_session_setup_state
{
652 struct tevent_context
*ev
;
653 struct smbd_smb2_request
*smb2req
;
654 uint64_t in_session_id
;
656 uint8_t in_security_mode
;
657 uint64_t in_previous_session_id
;
658 DATA_BLOB in_security_buffer
;
659 struct smbXsrv_session
*session
;
660 struct smbXsrv_session_auth0
*auth
;
661 struct auth_session_info
*session_info
;
662 uint16_t out_session_flags
;
663 DATA_BLOB out_security_buffer
;
664 uint64_t out_session_id
;
667 static void smbd_smb2_session_setup_gensec_done(struct tevent_req
*subreq
);
668 static void smbd_smb2_session_setup_previous_done(struct tevent_req
*subreq
);
669 static void smbd_smb2_session_setup_auth_return(struct tevent_req
*req
);
671 static struct tevent_req
*smbd_smb2_session_setup_send(TALLOC_CTX
*mem_ctx
,
672 struct tevent_context
*ev
,
673 struct smbd_smb2_request
*smb2req
,
674 uint64_t in_session_id
,
676 uint8_t in_security_mode
,
677 uint64_t in_previous_session_id
,
678 DATA_BLOB in_security_buffer
)
680 struct tevent_req
*req
;
681 struct smbd_smb2_session_setup_state
*state
;
683 NTTIME now
= timeval_to_nttime(&smb2req
->request_time
);
684 struct tevent_req
*subreq
;
685 struct smbXsrv_channel_global0
*c
= NULL
;
686 enum security_user_level seclvl
;
688 req
= tevent_req_create(mem_ctx
, &state
,
689 struct smbd_smb2_session_setup_state
);
694 state
->smb2req
= smb2req
;
695 state
->in_session_id
= in_session_id
;
696 state
->in_flags
= in_flags
;
697 state
->in_security_mode
= in_security_mode
;
698 state
->in_previous_session_id
= in_previous_session_id
;
699 state
->in_security_buffer
= in_security_buffer
;
701 if (in_flags
& SMB2_SESSION_FLAG_BINDING
) {
702 if (in_session_id
== 0) {
703 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
704 return tevent_req_post(req
, ev
);
707 if (smb2req
->session
== NULL
) {
708 tevent_req_nterror(req
, NT_STATUS_USER_SESSION_DELETED
);
709 return tevent_req_post(req
, ev
);
712 if ((smb2req
->session
->global
->signing_algo
>= SMB2_SIGNING_AES128_GMAC
) &&
713 (smb2req
->xconn
->smb2
.server
.sign_algo
!= smb2req
->session
->global
->signing_algo
))
715 tevent_req_nterror(req
, NT_STATUS_REQUEST_OUT_OF_SEQUENCE
);
716 return tevent_req_post(req
, ev
);
718 if ((smb2req
->xconn
->smb2
.server
.sign_algo
>= SMB2_SIGNING_AES128_GMAC
) &&
719 (smb2req
->session
->global
->signing_algo
!= smb2req
->xconn
->smb2
.server
.sign_algo
))
721 tevent_req_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
722 return tevent_req_post(req
, ev
);
725 if (smb2req
->xconn
->protocol
< PROTOCOL_SMB3_00
) {
726 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
727 return tevent_req_post(req
, ev
);
730 if (!smb2req
->xconn
->client
->server_multi_channel_enabled
) {
731 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
732 return tevent_req_post(req
, ev
);
735 if (!smb2req
->do_signing
) {
736 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
737 return tevent_req_post(req
, ev
);
740 if (smb2req
->session
->global
->connection_dialect
741 != smb2req
->xconn
->smb2
.server
.dialect
)
743 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
744 return tevent_req_post(req
, ev
);
747 if (smb2req
->session
->global
->encryption_cipher
748 != smb2req
->xconn
->smb2
.server
.cipher
)
750 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
751 return tevent_req_post(req
, ev
);
754 status
= smb2req
->session
->status
;
755 if (NT_STATUS_EQUAL(status
, NT_STATUS_BAD_LOGON_SESSION_STATE
)) {
757 * This comes from smb2srv_session_lookup_global().
758 * And it's a cross node/cross smbd session bind,
759 * which can't work in our architecture.
761 * Returning NT_STATUS_REQUEST_NOT_ACCEPTED is better
762 * than NT_STATUS_USER_SESSION_DELETED in order to
763 * avoid a completely new session.
765 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
766 return tevent_req_post(req
, ev
);
769 status
= smbXsrv_session_find_channel(smb2req
->session
,
772 if (NT_STATUS_IS_OK(status
)) {
773 if (!smb2_signing_key_valid(c
->signing_key
)) {
776 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
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
,
792 if (tevent_req_nterror(req
, status
)) {
793 return tevent_req_post(req
, ev
);
796 status
= smbXsrv_session_update(smb2req
->session
);
797 if (tevent_req_nterror(req
, status
)) {
798 return tevent_req_post(req
, ev
);
804 if (state
->in_session_id
== 0) {
805 /* create a new session */
806 status
= smbXsrv_session_create(state
->smb2req
->xconn
,
807 now
, &state
->session
);
808 if (tevent_req_nterror(req
, status
)) {
809 return tevent_req_post(req
, ev
);
811 smb2req
->session
= state
->session
;
813 if (smb2req
->session
== NULL
) {
814 tevent_req_nterror(req
, NT_STATUS_USER_SESSION_DELETED
);
815 return tevent_req_post(req
, ev
);
818 state
->session
= smb2req
->session
;
819 status
= state
->session
->status
;
820 if (NT_STATUS_EQUAL(status
, NT_STATUS_BAD_LOGON_SESSION_STATE
)) {
822 * This comes from smb2srv_session_lookup_global().
824 tevent_req_nterror(req
, NT_STATUS_USER_SESSION_DELETED
);
825 return tevent_req_post(req
, ev
);
827 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
828 status
= NT_STATUS_OK
;
830 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
831 status
= NT_STATUS_OK
;
833 if (tevent_req_nterror(req
, status
)) {
834 return tevent_req_post(req
, ev
);
838 status
= smbXsrv_session_find_channel(smb2req
->session
,
840 if (tevent_req_nterror(req
, status
)) {
841 return tevent_req_post(req
, ev
);
844 if (!(in_flags
& SMB2_SESSION_FLAG_BINDING
)) {
845 state
->session
->status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
848 status
= smbXsrv_session_find_auth(state
->session
, smb2req
->xconn
,
850 if (!NT_STATUS_IS_OK(status
)) {
851 status
= smbXsrv_session_create_auth(state
->session
,
853 in_flags
, in_security_mode
,
855 if (tevent_req_nterror(req
, status
)) {
856 return tevent_req_post(req
, ev
);
860 if (state
->auth
->gensec
== NULL
) {
861 status
= auth_generic_prepare(state
->auth
,
862 state
->smb2req
->xconn
->remote_address
,
863 state
->smb2req
->xconn
->local_address
,
865 &state
->auth
->gensec
);
866 if (tevent_req_nterror(req
, status
)) {
867 return tevent_req_post(req
, ev
);
870 gensec_want_feature(state
->auth
->gensec
, GENSEC_FEATURE_SESSION_KEY
);
871 gensec_want_feature(state
->auth
->gensec
, GENSEC_FEATURE_UNIX_TOKEN
);
872 gensec_want_feature(state
->auth
->gensec
, GENSEC_FEATURE_SMB_TRANSPORT
);
874 status
= gensec_start_mech_by_oid(state
->auth
->gensec
,
876 if (tevent_req_nterror(req
, status
)) {
877 return tevent_req_post(req
, ev
);
881 status
= smbXsrv_session_update(state
->session
);
882 if (tevent_req_nterror(req
, status
)) {
883 return tevent_req_post(req
, ev
);
887 subreq
= gensec_update_send(state
, state
->ev
,
889 state
->in_security_buffer
);
891 if (tevent_req_nomem(subreq
, req
)) {
892 return tevent_req_post(req
, ev
);
894 tevent_req_set_callback(subreq
, smbd_smb2_session_setup_gensec_done
, req
);
899 static void smbd_smb2_session_setup_gensec_done(struct tevent_req
*subreq
)
901 struct tevent_req
*req
=
902 tevent_req_callback_data(subreq
,
904 struct smbd_smb2_session_setup_state
*state
=
906 struct smbd_smb2_session_setup_state
);
910 status
= gensec_update_recv(subreq
, state
,
911 &state
->out_security_buffer
);
914 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
915 !NT_STATUS_IS_OK(status
)) {
916 tevent_req_nterror(req
, status
);
920 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
921 state
->out_session_id
= state
->session
->global
->session_wire_id
;
922 state
->smb2req
->preauth
= state
->auth
->preauth
;
923 tevent_req_nterror(req
, status
);
927 status
= gensec_session_info(state
->auth
->gensec
,
929 &state
->session_info
);
930 if (tevent_req_nterror(req
, status
)) {
934 if ((state
->in_previous_session_id
!= 0) &&
935 (state
->session
->global
->session_wire_id
!=
936 state
->in_previous_session_id
))
938 subreq
= smb2srv_session_close_previous_send(state
, state
->ev
,
939 state
->smb2req
->xconn
,
941 state
->in_previous_session_id
,
942 state
->session
->global
->session_wire_id
);
943 if (tevent_req_nomem(subreq
, req
)) {
946 tevent_req_set_callback(subreq
,
947 smbd_smb2_session_setup_previous_done
,
952 smbd_smb2_session_setup_auth_return(req
);
955 static void smbd_smb2_session_setup_previous_done(struct tevent_req
*subreq
)
957 struct tevent_req
*req
=
958 tevent_req_callback_data(subreq
,
962 status
= smb2srv_session_close_previous_recv(subreq
);
964 if (tevent_req_nterror(req
, status
)) {
968 smbd_smb2_session_setup_auth_return(req
);
971 static void smbd_smb2_session_setup_auth_return(struct tevent_req
*req
)
973 struct smbd_smb2_session_setup_state
*state
=
975 struct smbd_smb2_session_setup_state
);
978 if (state
->in_flags
& SMB2_SESSION_FLAG_BINDING
) {
979 status
= smbd_smb2_bind_auth_return(state
->session
,
983 &state
->out_session_flags
,
984 &state
->out_session_id
);
985 if (tevent_req_nterror(req
, status
)) {
988 tevent_req_done(req
);
992 if (state
->session
->global
->auth_session_info
!= NULL
) {
993 status
= smbd_smb2_reauth_generic_return(state
->session
,
997 &state
->out_session_flags
,
998 &state
->out_session_id
);
999 if (tevent_req_nterror(req
, status
)) {
1002 tevent_req_done(req
);
1006 status
= smbd_smb2_auth_generic_return(state
->session
,
1009 state
->in_security_mode
,
1010 state
->session_info
,
1011 &state
->out_session_flags
,
1012 &state
->out_session_id
);
1013 if (tevent_req_nterror(req
, status
)) {
1017 tevent_req_done(req
);
1021 static NTSTATUS
smbd_smb2_session_setup_recv(struct tevent_req
*req
,
1022 uint16_t *out_session_flags
,
1023 TALLOC_CTX
*mem_ctx
,
1024 DATA_BLOB
*out_security_buffer
,
1025 uint64_t *out_session_id
)
1027 struct smbd_smb2_session_setup_state
*state
=
1028 tevent_req_data(req
,
1029 struct smbd_smb2_session_setup_state
);
1032 if (tevent_req_is_nterror(req
, &status
)) {
1033 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1034 tevent_req_received(req
);
1035 return nt_status_squash(status
);
1038 status
= NT_STATUS_OK
;
1041 *out_session_flags
= state
->out_session_flags
;
1042 *out_security_buffer
= state
->out_security_buffer
;
1043 *out_session_id
= state
->out_session_id
;
1045 talloc_steal(mem_ctx
, out_security_buffer
->data
);
1046 tevent_req_received(req
);
1050 struct smbd_smb2_session_setup_wrap_state
{
1051 struct tevent_context
*ev
;
1052 struct smbd_smb2_request
*smb2req
;
1053 uint64_t in_session_id
;
1055 uint8_t in_security_mode
;
1056 uint64_t in_previous_session_id
;
1057 DATA_BLOB in_security_buffer
;
1058 uint16_t out_session_flags
;
1059 DATA_BLOB out_security_buffer
;
1060 uint64_t out_session_id
;
1064 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req
*subreq
);
1065 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req
*subreq
);
1067 static struct tevent_req
*smbd_smb2_session_setup_wrap_send(TALLOC_CTX
*mem_ctx
,
1068 struct tevent_context
*ev
,
1069 struct smbd_smb2_request
*smb2req
,
1070 uint64_t in_session_id
,
1072 uint8_t in_security_mode
,
1073 uint64_t in_previous_session_id
,
1074 DATA_BLOB in_security_buffer
)
1076 struct tevent_req
*req
;
1077 struct smbd_smb2_session_setup_wrap_state
*state
;
1078 struct tevent_req
*subreq
;
1080 req
= tevent_req_create(mem_ctx
, &state
,
1081 struct smbd_smb2_session_setup_wrap_state
);
1086 state
->smb2req
= smb2req
;
1087 state
->in_session_id
= in_session_id
;
1088 state
->in_flags
= in_flags
;
1089 state
->in_security_mode
= in_security_mode
;
1090 state
->in_previous_session_id
= in_previous_session_id
;
1091 state
->in_security_buffer
= in_security_buffer
;
1093 subreq
= smbd_smb2_session_setup_send(state
, state
->ev
,
1095 state
->in_session_id
,
1097 state
->in_security_mode
,
1098 state
->in_previous_session_id
,
1099 state
->in_security_buffer
);
1100 if (tevent_req_nomem(subreq
, req
)) {
1101 return tevent_req_post(req
, ev
);
1103 tevent_req_set_callback(subreq
,
1104 smbd_smb2_session_setup_wrap_setup_done
, req
);
1109 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req
*subreq
)
1111 struct tevent_req
*req
=
1112 tevent_req_callback_data(subreq
,
1114 struct smbd_smb2_session_setup_wrap_state
*state
=
1115 tevent_req_data(req
,
1116 struct smbd_smb2_session_setup_wrap_state
);
1119 status
= smbd_smb2_session_setup_recv(subreq
,
1120 &state
->out_session_flags
,
1122 &state
->out_security_buffer
,
1123 &state
->out_session_id
);
1124 TALLOC_FREE(subreq
);
1125 if (NT_STATUS_IS_OK(status
)) {
1126 tevent_req_done(req
);
1129 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1130 tevent_req_nterror(req
, status
);
1134 if (state
->smb2req
->session
== NULL
) {
1135 tevent_req_nterror(req
, status
);
1139 state
->error
= status
;
1141 if (state
->in_flags
& SMB2_SESSION_FLAG_BINDING
) {
1142 status
= smbXsrv_session_remove_channel(state
->smb2req
->session
,
1143 state
->smb2req
->xconn
);
1144 if (tevent_req_nterror(req
, status
)) {
1147 tevent_req_nterror(req
, state
->error
);
1151 if (NT_STATUS_EQUAL(state
->error
, NT_STATUS_USER_SESSION_DELETED
)) {
1152 tevent_req_nterror(req
, state
->error
);
1156 subreq
= smb2srv_session_shutdown_send(state
, state
->ev
,
1157 state
->smb2req
->session
,
1159 if (tevent_req_nomem(subreq
, req
)) {
1162 tevent_req_set_callback(subreq
,
1163 smbd_smb2_session_setup_wrap_shutdown_done
,
1167 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req
*subreq
)
1169 struct tevent_req
*req
=
1170 tevent_req_callback_data(subreq
,
1172 struct smbd_smb2_session_setup_wrap_state
*state
=
1173 tevent_req_data(req
,
1174 struct smbd_smb2_session_setup_wrap_state
);
1177 status
= smb2srv_session_shutdown_recv(subreq
);
1178 TALLOC_FREE(subreq
);
1179 if (tevent_req_nterror(req
, status
)) {
1184 * we may need to sign the response, so we need to keep
1185 * the session until the response is sent to the wire.
1187 talloc_steal(state
->smb2req
, state
->smb2req
->session
);
1189 tevent_req_nterror(req
, state
->error
);
1192 static NTSTATUS
smbd_smb2_session_setup_wrap_recv(struct tevent_req
*req
,
1193 uint16_t *out_session_flags
,
1194 TALLOC_CTX
*mem_ctx
,
1195 DATA_BLOB
*out_security_buffer
,
1196 uint64_t *out_session_id
)
1198 struct smbd_smb2_session_setup_wrap_state
*state
=
1199 tevent_req_data(req
,
1200 struct smbd_smb2_session_setup_wrap_state
);
1203 if (tevent_req_is_nterror(req
, &status
)) {
1204 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1205 tevent_req_received(req
);
1206 return nt_status_squash(status
);
1209 status
= NT_STATUS_OK
;
1212 *out_session_flags
= state
->out_session_flags
;
1213 *out_security_buffer
= state
->out_security_buffer
;
1214 *out_session_id
= state
->out_session_id
;
1216 talloc_steal(mem_ctx
, out_security_buffer
->data
);
1217 tevent_req_received(req
);
1221 static struct tevent_req
*smbd_smb2_logoff_send(TALLOC_CTX
*mem_ctx
,
1222 struct tevent_context
*ev
,
1223 struct smbd_smb2_request
*smb2req
);
1224 static NTSTATUS
smbd_smb2_logoff_recv(struct tevent_req
*req
);
1225 static void smbd_smb2_request_logoff_done(struct tevent_req
*subreq
);
1227 NTSTATUS
smbd_smb2_request_process_logoff(struct smbd_smb2_request
*req
)
1230 struct tevent_req
*subreq
= NULL
;
1232 status
= smbd_smb2_request_verify_sizes(req
, 0x04);
1233 if (!NT_STATUS_IS_OK(status
)) {
1234 return smbd_smb2_request_error(req
, status
);
1237 subreq
= smbd_smb2_logoff_send(req
, req
->sconn
->ev_ctx
, req
);
1238 if (subreq
== NULL
) {
1239 return smbd_smb2_request_error(req
, NT_STATUS_NO_MEMORY
);
1241 tevent_req_set_callback(subreq
, smbd_smb2_request_logoff_done
, req
);
1244 * Avoid sending a STATUS_PENDING message, it's very likely
1245 * the client won't expect that.
1247 return smbd_smb2_request_pending_queue(req
, subreq
, 0);
1250 static void smbd_smb2_request_logoff_done(struct tevent_req
*subreq
)
1252 struct smbd_smb2_request
*smb2req
=
1253 tevent_req_callback_data(subreq
,
1254 struct smbd_smb2_request
);
1259 status
= smbd_smb2_logoff_recv(subreq
);
1260 TALLOC_FREE(subreq
);
1261 if (!NT_STATUS_IS_OK(status
)) {
1262 error
= smbd_smb2_request_error(smb2req
, status
);
1263 if (!NT_STATUS_IS_OK(error
)) {
1264 smbd_server_connection_terminate(smb2req
->xconn
,
1271 outbody
= smbd_smb2_generate_outbody(smb2req
, 0x04);
1272 if (outbody
.data
== NULL
) {
1273 error
= smbd_smb2_request_error(smb2req
, NT_STATUS_NO_MEMORY
);
1274 if (!NT_STATUS_IS_OK(error
)) {
1275 smbd_server_connection_terminate(smb2req
->xconn
,
1282 SSVAL(outbody
.data
, 0x00, 0x04); /* struct size */
1283 SSVAL(outbody
.data
, 0x02, 0); /* reserved */
1285 error
= smbd_smb2_request_done(smb2req
, outbody
, NULL
);
1286 if (!NT_STATUS_IS_OK(error
)) {
1287 smbd_server_connection_terminate(smb2req
->xconn
,
1293 struct smbd_smb2_logoff_state
{
1294 struct smbd_smb2_request
*smb2req
;
1297 static void smbd_smb2_logoff_shutdown_done(struct tevent_req
*subreq
);
1299 static struct tevent_req
*smbd_smb2_logoff_send(TALLOC_CTX
*mem_ctx
,
1300 struct tevent_context
*ev
,
1301 struct smbd_smb2_request
*smb2req
)
1303 struct tevent_req
*req
;
1304 struct smbd_smb2_logoff_state
*state
;
1305 struct tevent_req
*subreq
;
1307 req
= tevent_req_create(mem_ctx
, &state
,
1308 struct smbd_smb2_logoff_state
);
1312 state
->smb2req
= smb2req
;
1314 subreq
= smb2srv_session_shutdown_send(state
, ev
,
1317 if (tevent_req_nomem(subreq
, req
)) {
1318 return tevent_req_post(req
, ev
);
1320 tevent_req_set_callback(subreq
, smbd_smb2_logoff_shutdown_done
, req
);
1325 static void smbd_smb2_logoff_shutdown_done(struct tevent_req
*subreq
)
1327 struct tevent_req
*req
= tevent_req_callback_data(
1328 subreq
, struct tevent_req
);
1329 struct smbd_smb2_logoff_state
*state
= tevent_req_data(
1330 req
, struct smbd_smb2_logoff_state
);
1333 const struct GUID
*client_guid
=
1334 &state
->smb2req
->session
->client
->global
->client_guid
;
1336 status
= smb2srv_session_shutdown_recv(subreq
);
1337 if (tevent_req_nterror(req
, status
)) {
1340 TALLOC_FREE(subreq
);
1342 if (!GUID_all_zero(client_guid
)) {
1343 ok
= remote_arch_cache_delete(client_guid
);
1345 /* Most likely not an error, but not in cache */
1346 DBG_DEBUG("Deletion from remote arch cache failed\n");
1351 * As we've been awoken, we may have changed
1352 * uid in the meantime. Ensure we're still
1353 * root (SMB2_OP_LOGOFF has .as_root = true).
1355 change_to_root_user();
1357 status
= smbXsrv_session_logoff(state
->smb2req
->session
);
1358 if (tevent_req_nterror(req
, status
)) {
1363 * we may need to sign the response, so we need to keep
1364 * the session until the response is sent to the wire.
1366 talloc_steal(state
->smb2req
, state
->smb2req
->session
);
1368 tevent_req_done(req
);
1371 static NTSTATUS
smbd_smb2_logoff_recv(struct tevent_req
*req
)
1373 return tevent_req_simple_recv_ntstatus(req
);