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 * Remember we got one authenticated session on the connection
278 * in order to allow SMB3 decryption to happen
279 * (sadly even for future anonymous connections).
281 xconn
->smb2
.got_authenticated_session
= true;
284 if (guest
&& (x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
)) {
285 DEBUG(1,("reject guest session as encryption is required\n"));
286 return NT_STATUS_ACCESS_DENIED
;
289 if (xconn
->smb2
.server
.cipher
== 0) {
290 if (x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
) {
291 DEBUG(1,("reject session with dialect[0x%04X] "
292 "as encryption is required\n",
293 xconn
->smb2
.server
.dialect
));
294 return NT_STATUS_ACCESS_DENIED
;
297 x
->global
->signing_algo
= xconn
->smb2
.server
.sign_algo
;
298 x
->global
->encryption_cipher
= xconn
->smb2
.server
.cipher
;
299 if (*out_session_flags
& SMB2_SESSION_FLAG_IS_GUEST
) {
301 * A fallback to guest can't do any encryption
303 x
->global
->encryption_cipher
= SMB2_ENCRYPTION_NONE
;
306 if (x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
307 *out_session_flags
|= SMB2_SESSION_FLAG_ENCRYPT_DATA
;
310 status
= smb2_signing_key_sign_create(x
->global
,
311 x
->global
->signing_algo
,
312 &session_info
->session_key
,
314 &x
->global
->signing_key
);
315 if (!NT_STATUS_IS_OK(status
)) {
318 x
->global
->signing_key_blob
= x
->global
->signing_key
->blob
;
320 if (x
->global
->encryption_cipher
!= SMB2_ENCRYPTION_NONE
) {
323 status
= smb2_signing_key_cipher_create(x
->global
,
324 x
->global
->encryption_cipher
,
325 &session_info
->session_key
,
326 derivations
.cipher_s2c
,
327 &x
->global
->encryption_key
);
328 if (!NT_STATUS_IS_OK(status
)) {
331 x
->global
->encryption_key_blob
= x
->global
->encryption_key
->blob
;
333 status
= smb2_signing_key_cipher_create(x
->global
,
334 x
->global
->encryption_cipher
,
335 &session_info
->session_key
,
336 derivations
.cipher_c2s
,
337 &x
->global
->decryption_key
);
338 if (!NT_STATUS_IS_OK(status
)) {
341 x
->global
->decryption_key_blob
= x
->global
->decryption_key
->blob
;
344 * CCM and GCM algorithms must never have their
345 * nonce wrap, or the security of the whole
346 * communication and the keys is destroyed.
347 * We must drop the connection once we have
348 * transferred too much data.
350 * NOTE: We assume nonces greater than 8 bytes.
352 generate_nonce_buffer((uint8_t *)&x
->nonce_high_random
,
353 sizeof(x
->nonce_high_random
));
354 switch (xconn
->smb2
.server
.cipher
) {
355 case SMB2_ENCRYPTION_AES128_CCM
:
356 nonce_size
= SMB2_AES_128_CCM_NONCE_SIZE
;
358 case SMB2_ENCRYPTION_AES128_GCM
:
359 nonce_size
= gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM
);
361 case SMB2_ENCRYPTION_AES256_CCM
:
362 nonce_size
= SMB2_AES_128_CCM_NONCE_SIZE
;
364 case SMB2_ENCRYPTION_AES256_GCM
:
365 nonce_size
= gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM
);
371 x
->nonce_high_max
= SMB2_NONCE_HIGH_MAX(nonce_size
);
376 status
= smb2_signing_key_sign_create(x
->global
,
377 x
->global
->signing_algo
,
378 &session_info
->session_key
,
379 derivations
.application
,
380 &x
->global
->application_key
);
381 if (!NT_STATUS_IS_OK(status
)) {
384 x
->global
->application_key_blob
= x
->global
->application_key
->blob
;
386 if (xconn
->protocol
>= PROTOCOL_SMB3_00
&& lp_debug_encryption()) {
387 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
388 DEBUGADD(0, ("Session Id "));
389 dump_data(0, (uint8_t*)&session
->global
->session_wire_id
,
390 sizeof(session
->global
->session_wire_id
));
391 DEBUGADD(0, ("Session Key "));
392 dump_data(0, session_info
->session_key
.data
,
393 session_info
->session_key
.length
);
394 DEBUGADD(0, ("Signing Algo: %u\n", x
->global
->signing_algo
));
395 DEBUGADD(0, ("Signing Key "));
396 dump_data(0, x
->global
->signing_key_blob
.data
,
397 x
->global
->signing_key_blob
.length
);
398 DEBUGADD(0, ("App Key "));
399 dump_data(0, x
->global
->application_key_blob
.data
,
400 x
->global
->application_key_blob
.length
);
402 /* In server code, ServerIn is the decryption key */
404 DEBUGADD(0, ("Cipher Algo: %u\n", x
->global
->encryption_cipher
));
405 DEBUGADD(0, ("ServerIn Key "));
406 dump_data(0, x
->global
->decryption_key_blob
.data
,
407 x
->global
->decryption_key_blob
.length
);
408 DEBUGADD(0, ("ServerOut Key "));
409 dump_data(0, x
->global
->encryption_key_blob
.data
,
410 x
->global
->encryption_key_blob
.length
);
413 status
= smb2_signing_key_copy(x
->global
->channels
,
414 x
->global
->signing_key
,
415 &x
->global
->channels
[0].signing_key
);
416 if (!NT_STATUS_IS_OK(status
)) {
419 x
->global
->channels
[0].signing_key_blob
=
420 x
->global
->channels
[0].signing_key
->blob
;
421 x
->global
->channels
[0].signing_algo
= x
->global
->signing_algo
;
422 x
->global
->channels
[0].encryption_cipher
= x
->global
->encryption_cipher
;
424 data_blob_clear_free(&session_info
->session_key
);
425 session_info
->session_key
= data_blob_dup_talloc(session_info
,
426 x
->global
->application_key_blob
);
427 if (session_info
->session_key
.data
== NULL
) {
428 return NT_STATUS_NO_MEMORY
;
430 talloc_keep_secret(session_info
->session_key
.data
);
432 smb2req
->sconn
->num_users
++;
434 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
435 session
->homes_snum
=
436 register_homes_share(session_info
->unix_info
->unix_name
);
439 set_current_user_info(session_info
->unix_info
->sanitized_username
,
440 session_info
->unix_info
->unix_name
,
441 session_info
->info
->domain_name
);
443 reload_services(smb2req
->sconn
, conn_snum_used
, true);
445 session
->status
= NT_STATUS_OK
;
446 session
->global
->auth_session_info
= talloc_move(session
->global
,
448 session
->global
->auth_session_info_seqnum
+= 1;
449 for (i
=0; i
< session
->global
->num_channels
; i
++) {
450 struct smbXsrv_channel_global0
*_c
=
451 &session
->global
->channels
[i
];
453 _c
->auth_session_info_seqnum
=
454 session
->global
->auth_session_info_seqnum
;
456 session
->global
->auth_time
= timeval_to_nttime(&smb2req
->request_time
);
457 session
->global
->expiration_time
= gensec_expire_time(auth
->gensec
);
459 if (!session_claim(session
)) {
460 DEBUG(1, ("smb2: Failed to claim session "
462 (unsigned long long)session
->global
->session_wire_id
));
463 return NT_STATUS_LOGON_FAILURE
;
467 status
= smbXsrv_session_update(session
);
468 if (!NT_STATUS_IS_OK(status
)) {
469 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
470 (unsigned long long)session
->global
->session_wire_id
,
472 return NT_STATUS_LOGON_FAILURE
;
476 * we attach the session to the request
477 * so that the response can be signed
480 smb2req
->do_signing
= true;
483 global_client_caps
|= (CAP_LEVEL_II_OPLOCKS
|CAP_STATUS32
);
485 *out_session_id
= session
->global
->session_wire_id
;
486 smb2req
->last_session_id
= session
->global
->session_wire_id
;
491 static NTSTATUS
smbd_smb2_reauth_generic_return(struct smbXsrv_session
*session
,
492 struct smbXsrv_session_auth0
**_auth
,
493 struct smbd_smb2_request
*smb2req
,
494 struct auth_session_info
*session_info
,
495 uint16_t *out_session_flags
,
496 uint64_t *out_session_id
)
499 struct smbXsrv_session
*x
= session
;
500 struct smbXsrv_session_auth0
*auth
= *_auth
;
501 struct smbXsrv_connection
*xconn
= smb2req
->xconn
;
506 data_blob_clear_free(&session_info
->session_key
);
507 session_info
->session_key
= data_blob_dup_talloc(session_info
,
508 x
->global
->application_key_blob
);
509 if (session_info
->session_key
.data
== NULL
) {
510 return NT_STATUS_NO_MEMORY
;
512 talloc_keep_secret(session_info
->session_key
.data
);
514 session
->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 if (security_session_user_level(session_info
, NULL
) >= SECURITY_USER
) {
524 smb2req
->do_signing
= true;
527 session
->status
= NT_STATUS_OK
;
528 TALLOC_FREE(session
->global
->auth_session_info
);
529 session
->global
->auth_session_info
= talloc_move(session
->global
,
531 session
->global
->auth_session_info_seqnum
+= 1;
532 for (i
=0; i
< session
->global
->num_channels
; i
++) {
533 struct smbXsrv_channel_global0
*_c
=
534 &session
->global
->channels
[i
];
536 _c
->auth_session_info_seqnum
=
537 session
->global
->auth_session_info_seqnum
;
539 session
->global
->auth_time
= timeval_to_nttime(&smb2req
->request_time
);
540 session
->global
->expiration_time
= gensec_expire_time(auth
->gensec
);
543 status
= smbXsrv_session_update(session
);
544 if (!NT_STATUS_IS_OK(status
)) {
545 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
546 (unsigned long long)session
->global
->session_wire_id
,
548 return NT_STATUS_LOGON_FAILURE
;
551 conn_clear_vuid_caches(xconn
->client
->sconn
,
552 session
->global
->session_wire_id
);
554 *out_session_id
= session
->global
->session_wire_id
;
559 static NTSTATUS
smbd_smb2_bind_auth_return(struct smbXsrv_session
*session
,
560 struct smbXsrv_session_auth0
**_auth
,
561 struct smbd_smb2_request
*smb2req
,
562 struct auth_session_info
*session_info
,
563 uint16_t *out_session_flags
,
564 uint64_t *out_session_id
)
567 struct smbXsrv_session
*x
= session
;
568 struct smbXsrv_session_auth0
*auth
= *_auth
;
569 struct smbXsrv_connection
*xconn
= smb2req
->xconn
;
570 struct smbXsrv_channel_global0
*c
= NULL
;
572 struct smb2_signing_derivations derivations
= {
575 DATA_BLOB preauth_hash
= data_blob_null
;
580 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
581 struct smbXsrv_preauth
*preauth
;
582 gnutls_hash_hd_t hash_hnd
= NULL
;
585 preauth
= talloc_move(smb2req
, &auth
->preauth
);
587 rc
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_SHA512
);
589 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
592 rc
= gnutls_hash(hash_hnd
,
593 preauth
->sha512_value
,
594 sizeof(preauth
->sha512_value
));
596 gnutls_hash_deinit(hash_hnd
, NULL
);
597 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
599 for (i
= 1; i
< smb2req
->in
.vector_count
; i
++) {
600 rc
= gnutls_hash(hash_hnd
,
601 smb2req
->in
.vector
[i
].iov_base
,
602 smb2req
->in
.vector
[i
].iov_len
);
604 gnutls_hash_deinit(hash_hnd
, NULL
);
605 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
608 gnutls_hash_deinit(hash_hnd
, preauth
->sha512_value
);
610 preauth_hash
= data_blob_const(preauth
->sha512_value
,
611 sizeof(preauth
->sha512_value
));
614 smb2_signing_derivations_fill_const_stack(&derivations
,
618 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
619 if (!NT_STATUS_IS_OK(status
)) {
623 ok
= security_token_is_sid(session_info
->security_token
,
624 &x
->global
->auth_session_info
->security_token
->sids
[0]);
626 return NT_STATUS_ACCESS_DENIED
;
629 if (session_info
->session_key
.length
== 0) {
630 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
631 return NT_STATUS_NOT_SUPPORTED
;
634 c
->signing_algo
= xconn
->smb2
.server
.sign_algo
;
635 c
->encryption_cipher
= xconn
->smb2
.server
.cipher
;
637 status
= smb2_signing_key_sign_create(x
->global
->channels
,
639 &session_info
->session_key
,
642 if (!NT_STATUS_IS_OK(status
)) {
645 c
->signing_key_blob
= c
->signing_key
->blob
;
648 status
= smbXsrv_session_update(session
);
649 if (!NT_STATUS_IS_OK(status
)) {
650 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
651 (unsigned long long)session
->global
->session_wire_id
,
653 return NT_STATUS_LOGON_FAILURE
;
657 * Remember we got one authenticated session on the connection
658 * in order to allow SMB3 decryption to happen
660 xconn
->smb2
.got_authenticated_session
= true;
662 *out_session_id
= session
->global
->session_wire_id
;
667 struct smbd_smb2_session_setup_state
{
668 struct tevent_context
*ev
;
669 struct smbd_smb2_request
*smb2req
;
670 uint64_t in_session_id
;
672 uint8_t in_security_mode
;
673 uint64_t in_previous_session_id
;
674 DATA_BLOB in_security_buffer
;
675 struct smbXsrv_session
*session
;
676 struct smbXsrv_session_auth0
*auth
;
677 struct auth_session_info
*session_info
;
678 uint16_t out_session_flags
;
679 DATA_BLOB out_security_buffer
;
680 uint64_t out_session_id
;
683 static void smbd_smb2_session_setup_gensec_done(struct tevent_req
*subreq
);
684 static void smbd_smb2_session_setup_previous_done(struct tevent_req
*subreq
);
685 static void smbd_smb2_session_setup_auth_return(struct tevent_req
*req
);
687 static struct tevent_req
*smbd_smb2_session_setup_send(TALLOC_CTX
*mem_ctx
,
688 struct tevent_context
*ev
,
689 struct smbd_smb2_request
*smb2req
,
690 uint64_t in_session_id
,
692 uint8_t in_security_mode
,
693 uint64_t in_previous_session_id
,
694 DATA_BLOB in_security_buffer
)
696 struct tevent_req
*req
;
697 struct smbd_smb2_session_setup_state
*state
;
699 NTTIME now
= timeval_to_nttime(&smb2req
->request_time
);
700 struct tevent_req
*subreq
;
701 struct smbXsrv_channel_global0
*c
= NULL
;
702 enum security_user_level seclvl
;
704 req
= tevent_req_create(mem_ctx
, &state
,
705 struct smbd_smb2_session_setup_state
);
710 state
->smb2req
= smb2req
;
711 state
->in_session_id
= in_session_id
;
712 state
->in_flags
= in_flags
;
713 state
->in_security_mode
= in_security_mode
;
714 state
->in_previous_session_id
= in_previous_session_id
;
715 state
->in_security_buffer
= in_security_buffer
;
717 if (in_flags
& SMB2_SESSION_FLAG_BINDING
) {
718 if (in_session_id
== 0) {
719 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
720 return tevent_req_post(req
, ev
);
723 if (smb2req
->session
== NULL
) {
724 tevent_req_nterror(req
, NT_STATUS_USER_SESSION_DELETED
);
725 return tevent_req_post(req
, ev
);
728 if ((smb2req
->session
->global
->signing_algo
>= SMB2_SIGNING_AES128_GMAC
) &&
729 (smb2req
->xconn
->smb2
.server
.sign_algo
!= smb2req
->session
->global
->signing_algo
))
731 tevent_req_nterror(req
, NT_STATUS_REQUEST_OUT_OF_SEQUENCE
);
732 return tevent_req_post(req
, ev
);
734 if ((smb2req
->xconn
->smb2
.server
.sign_algo
>= SMB2_SIGNING_AES128_GMAC
) &&
735 (smb2req
->session
->global
->signing_algo
!= smb2req
->xconn
->smb2
.server
.sign_algo
))
737 tevent_req_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
738 return tevent_req_post(req
, ev
);
741 if (smb2req
->xconn
->protocol
< PROTOCOL_SMB3_00
) {
742 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
743 return tevent_req_post(req
, ev
);
746 if (!smb2req
->xconn
->client
->server_multi_channel_enabled
) {
747 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
748 return tevent_req_post(req
, ev
);
751 if (!smb2req
->do_signing
) {
752 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
753 return tevent_req_post(req
, ev
);
756 if (smb2req
->session
->global
->connection_dialect
757 != smb2req
->xconn
->smb2
.server
.dialect
)
759 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
760 return tevent_req_post(req
, ev
);
763 if (smb2req
->session
->global
->encryption_cipher
764 != smb2req
->xconn
->smb2
.server
.cipher
)
766 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
767 return tevent_req_post(req
, ev
);
770 status
= smb2req
->session
->status
;
771 if (NT_STATUS_EQUAL(status
, NT_STATUS_BAD_LOGON_SESSION_STATE
)) {
773 * This comes from smb2srv_session_lookup_global().
774 * And it's a cross node/cross smbd session bind,
775 * which can't work in our architecture.
777 * Returning NT_STATUS_REQUEST_NOT_ACCEPTED is better
778 * than NT_STATUS_USER_SESSION_DELETED in order to
779 * avoid a completely new session.
781 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
782 return tevent_req_post(req
, ev
);
785 status
= smbXsrv_session_find_channel(smb2req
->session
,
788 if (NT_STATUS_IS_OK(status
)) {
789 if (!smb2_signing_key_valid(c
->signing_key
)) {
792 tevent_req_nterror(req
, NT_STATUS_REQUEST_NOT_ACCEPTED
);
793 return tevent_req_post(req
, ev
);
796 seclvl
= security_session_user_level(
797 smb2req
->session
->global
->auth_session_info
,
799 if (seclvl
< SECURITY_USER
) {
800 tevent_req_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
801 return tevent_req_post(req
, ev
);
804 status
= smbXsrv_session_add_channel(smb2req
->session
,
808 if (tevent_req_nterror(req
, status
)) {
809 return tevent_req_post(req
, ev
);
812 status
= smbXsrv_session_update(smb2req
->session
);
813 if (tevent_req_nterror(req
, status
)) {
814 return tevent_req_post(req
, ev
);
820 if (state
->in_session_id
== 0) {
821 /* create a new session */
822 status
= smbXsrv_session_create(state
->smb2req
->xconn
,
823 now
, &state
->session
);
824 if (tevent_req_nterror(req
, status
)) {
825 return tevent_req_post(req
, ev
);
827 smb2req
->session
= state
->session
;
829 if (smb2req
->session
== NULL
) {
830 tevent_req_nterror(req
, NT_STATUS_USER_SESSION_DELETED
);
831 return tevent_req_post(req
, ev
);
834 state
->session
= smb2req
->session
;
835 status
= state
->session
->status
;
836 if (NT_STATUS_EQUAL(status
, NT_STATUS_BAD_LOGON_SESSION_STATE
)) {
838 * This comes from smb2srv_session_lookup_global().
840 tevent_req_nterror(req
, NT_STATUS_USER_SESSION_DELETED
);
841 return tevent_req_post(req
, ev
);
843 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
844 status
= NT_STATUS_OK
;
846 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
847 status
= NT_STATUS_OK
;
849 if (tevent_req_nterror(req
, status
)) {
850 return tevent_req_post(req
, ev
);
854 status
= smbXsrv_session_find_channel(smb2req
->session
,
856 if (tevent_req_nterror(req
, status
)) {
857 return tevent_req_post(req
, ev
);
860 if (!(in_flags
& SMB2_SESSION_FLAG_BINDING
)) {
861 state
->session
->status
= NT_STATUS_MORE_PROCESSING_REQUIRED
;
864 status
= smbXsrv_session_find_auth(state
->session
, smb2req
->xconn
,
866 if (!NT_STATUS_IS_OK(status
)) {
867 status
= smbXsrv_session_create_auth(state
->session
,
869 in_flags
, in_security_mode
,
871 if (tevent_req_nterror(req
, status
)) {
872 return tevent_req_post(req
, ev
);
876 if (state
->auth
->gensec
== NULL
) {
877 status
= auth_generic_prepare(state
->auth
,
878 state
->smb2req
->xconn
->remote_address
,
879 state
->smb2req
->xconn
->local_address
,
881 &state
->auth
->gensec
);
882 if (tevent_req_nterror(req
, status
)) {
883 return tevent_req_post(req
, ev
);
886 gensec_want_feature(state
->auth
->gensec
, GENSEC_FEATURE_SESSION_KEY
);
887 gensec_want_feature(state
->auth
->gensec
, GENSEC_FEATURE_UNIX_TOKEN
);
888 gensec_want_feature(state
->auth
->gensec
, GENSEC_FEATURE_SMB_TRANSPORT
);
890 status
= gensec_start_mech_by_oid(state
->auth
->gensec
,
892 if (tevent_req_nterror(req
, status
)) {
893 return tevent_req_post(req
, ev
);
897 status
= smbXsrv_session_update(state
->session
);
898 if (tevent_req_nterror(req
, status
)) {
899 return tevent_req_post(req
, ev
);
903 subreq
= gensec_update_send(state
, state
->ev
,
905 state
->in_security_buffer
);
907 if (tevent_req_nomem(subreq
, req
)) {
908 return tevent_req_post(req
, ev
);
910 tevent_req_set_callback(subreq
, smbd_smb2_session_setup_gensec_done
, req
);
915 static void smbd_smb2_session_setup_gensec_done(struct tevent_req
*subreq
)
917 struct tevent_req
*req
=
918 tevent_req_callback_data(subreq
,
920 struct smbd_smb2_session_setup_state
*state
=
922 struct smbd_smb2_session_setup_state
);
926 status
= gensec_update_recv(subreq
, state
,
927 &state
->out_security_buffer
);
930 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
931 !NT_STATUS_IS_OK(status
)) {
932 tevent_req_nterror(req
, status
);
936 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
937 state
->out_session_id
= state
->session
->global
->session_wire_id
;
938 state
->smb2req
->preauth
= state
->auth
->preauth
;
939 tevent_req_nterror(req
, status
);
943 status
= gensec_session_info(state
->auth
->gensec
,
945 &state
->session_info
);
946 if (tevent_req_nterror(req
, status
)) {
950 if ((state
->in_previous_session_id
!= 0) &&
951 (state
->session
->global
->session_wire_id
!=
952 state
->in_previous_session_id
))
954 subreq
= smb2srv_session_close_previous_send(state
, state
->ev
,
955 state
->smb2req
->xconn
,
957 state
->in_previous_session_id
,
958 state
->session
->global
->session_wire_id
);
959 if (tevent_req_nomem(subreq
, req
)) {
962 tevent_req_set_callback(subreq
,
963 smbd_smb2_session_setup_previous_done
,
968 smbd_smb2_session_setup_auth_return(req
);
971 static void smbd_smb2_session_setup_previous_done(struct tevent_req
*subreq
)
973 struct tevent_req
*req
=
974 tevent_req_callback_data(subreq
,
978 status
= smb2srv_session_close_previous_recv(subreq
);
980 if (tevent_req_nterror(req
, status
)) {
984 smbd_smb2_session_setup_auth_return(req
);
987 static void smbd_smb2_session_setup_auth_return(struct tevent_req
*req
)
989 struct smbd_smb2_session_setup_state
*state
=
991 struct smbd_smb2_session_setup_state
);
994 if (state
->in_flags
& SMB2_SESSION_FLAG_BINDING
) {
995 status
= smbd_smb2_bind_auth_return(state
->session
,
999 &state
->out_session_flags
,
1000 &state
->out_session_id
);
1001 if (tevent_req_nterror(req
, status
)) {
1004 tevent_req_done(req
);
1008 if (state
->session
->global
->auth_session_info
!= NULL
) {
1009 status
= smbd_smb2_reauth_generic_return(state
->session
,
1012 state
->session_info
,
1013 &state
->out_session_flags
,
1014 &state
->out_session_id
);
1015 if (tevent_req_nterror(req
, status
)) {
1018 tevent_req_done(req
);
1022 status
= smbd_smb2_auth_generic_return(state
->session
,
1025 state
->in_security_mode
,
1026 state
->session_info
,
1027 &state
->out_session_flags
,
1028 &state
->out_session_id
);
1029 if (tevent_req_nterror(req
, status
)) {
1033 tevent_req_done(req
);
1037 static NTSTATUS
smbd_smb2_session_setup_recv(struct tevent_req
*req
,
1038 uint16_t *out_session_flags
,
1039 TALLOC_CTX
*mem_ctx
,
1040 DATA_BLOB
*out_security_buffer
,
1041 uint64_t *out_session_id
)
1043 struct smbd_smb2_session_setup_state
*state
=
1044 tevent_req_data(req
,
1045 struct smbd_smb2_session_setup_state
);
1048 if (tevent_req_is_nterror(req
, &status
)) {
1049 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1050 tevent_req_received(req
);
1051 return nt_status_squash(status
);
1054 status
= NT_STATUS_OK
;
1057 *out_session_flags
= state
->out_session_flags
;
1058 *out_security_buffer
= state
->out_security_buffer
;
1059 *out_session_id
= state
->out_session_id
;
1061 talloc_steal(mem_ctx
, out_security_buffer
->data
);
1062 tevent_req_received(req
);
1066 struct smbd_smb2_session_setup_wrap_state
{
1067 struct tevent_context
*ev
;
1068 struct smbd_smb2_request
*smb2req
;
1069 uint64_t in_session_id
;
1071 uint8_t in_security_mode
;
1072 uint64_t in_previous_session_id
;
1073 DATA_BLOB in_security_buffer
;
1074 uint16_t out_session_flags
;
1075 DATA_BLOB out_security_buffer
;
1076 uint64_t out_session_id
;
1080 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req
*subreq
);
1081 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req
*subreq
);
1083 static struct tevent_req
*smbd_smb2_session_setup_wrap_send(TALLOC_CTX
*mem_ctx
,
1084 struct tevent_context
*ev
,
1085 struct smbd_smb2_request
*smb2req
,
1086 uint64_t in_session_id
,
1088 uint8_t in_security_mode
,
1089 uint64_t in_previous_session_id
,
1090 DATA_BLOB in_security_buffer
)
1092 struct tevent_req
*req
;
1093 struct smbd_smb2_session_setup_wrap_state
*state
;
1094 struct tevent_req
*subreq
;
1096 req
= tevent_req_create(mem_ctx
, &state
,
1097 struct smbd_smb2_session_setup_wrap_state
);
1102 state
->smb2req
= smb2req
;
1103 state
->in_session_id
= in_session_id
;
1104 state
->in_flags
= in_flags
;
1105 state
->in_security_mode
= in_security_mode
;
1106 state
->in_previous_session_id
= in_previous_session_id
;
1107 state
->in_security_buffer
= in_security_buffer
;
1109 subreq
= smbd_smb2_session_setup_send(state
, state
->ev
,
1111 state
->in_session_id
,
1113 state
->in_security_mode
,
1114 state
->in_previous_session_id
,
1115 state
->in_security_buffer
);
1116 if (tevent_req_nomem(subreq
, req
)) {
1117 return tevent_req_post(req
, ev
);
1119 tevent_req_set_callback(subreq
,
1120 smbd_smb2_session_setup_wrap_setup_done
, req
);
1125 static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req
*subreq
)
1127 struct tevent_req
*req
=
1128 tevent_req_callback_data(subreq
,
1130 struct smbd_smb2_session_setup_wrap_state
*state
=
1131 tevent_req_data(req
,
1132 struct smbd_smb2_session_setup_wrap_state
);
1135 status
= smbd_smb2_session_setup_recv(subreq
,
1136 &state
->out_session_flags
,
1138 &state
->out_security_buffer
,
1139 &state
->out_session_id
);
1140 TALLOC_FREE(subreq
);
1141 if (NT_STATUS_IS_OK(status
)) {
1142 tevent_req_done(req
);
1145 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1146 tevent_req_nterror(req
, status
);
1150 if (state
->smb2req
->session
== NULL
) {
1151 tevent_req_nterror(req
, status
);
1155 state
->error
= status
;
1157 if (state
->in_flags
& SMB2_SESSION_FLAG_BINDING
) {
1158 status
= smbXsrv_session_remove_channel(state
->smb2req
->session
,
1159 state
->smb2req
->xconn
);
1160 if (tevent_req_nterror(req
, status
)) {
1163 tevent_req_nterror(req
, state
->error
);
1167 if (NT_STATUS_EQUAL(state
->error
, NT_STATUS_USER_SESSION_DELETED
)) {
1168 tevent_req_nterror(req
, state
->error
);
1172 subreq
= smb2srv_session_shutdown_send(state
, state
->ev
,
1173 state
->smb2req
->session
,
1175 if (tevent_req_nomem(subreq
, req
)) {
1178 tevent_req_set_callback(subreq
,
1179 smbd_smb2_session_setup_wrap_shutdown_done
,
1183 static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req
*subreq
)
1185 struct tevent_req
*req
=
1186 tevent_req_callback_data(subreq
,
1188 struct smbd_smb2_session_setup_wrap_state
*state
=
1189 tevent_req_data(req
,
1190 struct smbd_smb2_session_setup_wrap_state
);
1193 status
= smb2srv_session_shutdown_recv(subreq
);
1194 TALLOC_FREE(subreq
);
1195 if (tevent_req_nterror(req
, status
)) {
1200 * we may need to sign the response, so we need to keep
1201 * the session until the response is sent to the wire.
1203 talloc_steal(state
->smb2req
, state
->smb2req
->session
);
1205 tevent_req_nterror(req
, state
->error
);
1208 static NTSTATUS
smbd_smb2_session_setup_wrap_recv(struct tevent_req
*req
,
1209 uint16_t *out_session_flags
,
1210 TALLOC_CTX
*mem_ctx
,
1211 DATA_BLOB
*out_security_buffer
,
1212 uint64_t *out_session_id
)
1214 struct smbd_smb2_session_setup_wrap_state
*state
=
1215 tevent_req_data(req
,
1216 struct smbd_smb2_session_setup_wrap_state
);
1219 if (tevent_req_is_nterror(req
, &status
)) {
1220 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1221 tevent_req_received(req
);
1222 return nt_status_squash(status
);
1225 status
= NT_STATUS_OK
;
1228 *out_session_flags
= state
->out_session_flags
;
1229 *out_security_buffer
= state
->out_security_buffer
;
1230 *out_session_id
= state
->out_session_id
;
1232 talloc_steal(mem_ctx
, out_security_buffer
->data
);
1233 tevent_req_received(req
);
1237 static struct tevent_req
*smbd_smb2_logoff_send(TALLOC_CTX
*mem_ctx
,
1238 struct tevent_context
*ev
,
1239 struct smbd_smb2_request
*smb2req
);
1240 static NTSTATUS
smbd_smb2_logoff_recv(struct tevent_req
*req
);
1241 static void smbd_smb2_request_logoff_done(struct tevent_req
*subreq
);
1243 NTSTATUS
smbd_smb2_request_process_logoff(struct smbd_smb2_request
*req
)
1246 struct tevent_req
*subreq
= NULL
;
1248 status
= smbd_smb2_request_verify_sizes(req
, 0x04);
1249 if (!NT_STATUS_IS_OK(status
)) {
1250 return smbd_smb2_request_error(req
, status
);
1253 subreq
= smbd_smb2_logoff_send(req
, req
->sconn
->ev_ctx
, req
);
1254 if (subreq
== NULL
) {
1255 return smbd_smb2_request_error(req
, NT_STATUS_NO_MEMORY
);
1257 tevent_req_set_callback(subreq
, smbd_smb2_request_logoff_done
, req
);
1260 * Avoid sending a STATUS_PENDING message, it's very likely
1261 * the client won't expect that.
1263 return smbd_smb2_request_pending_queue(req
, subreq
, 0);
1266 static void smbd_smb2_request_logoff_done(struct tevent_req
*subreq
)
1268 struct smbd_smb2_request
*smb2req
=
1269 tevent_req_callback_data(subreq
,
1270 struct smbd_smb2_request
);
1275 status
= smbd_smb2_logoff_recv(subreq
);
1276 TALLOC_FREE(subreq
);
1277 if (!NT_STATUS_IS_OK(status
)) {
1278 error
= smbd_smb2_request_error(smb2req
, status
);
1279 if (!NT_STATUS_IS_OK(error
)) {
1280 smbd_server_connection_terminate(smb2req
->xconn
,
1287 outbody
= smbd_smb2_generate_outbody(smb2req
, 0x04);
1288 if (outbody
.data
== NULL
) {
1289 error
= smbd_smb2_request_error(smb2req
, NT_STATUS_NO_MEMORY
);
1290 if (!NT_STATUS_IS_OK(error
)) {
1291 smbd_server_connection_terminate(smb2req
->xconn
,
1298 SSVAL(outbody
.data
, 0x00, 0x04); /* struct size */
1299 SSVAL(outbody
.data
, 0x02, 0); /* reserved */
1301 error
= smbd_smb2_request_done(smb2req
, outbody
, NULL
);
1302 if (!NT_STATUS_IS_OK(error
)) {
1303 smbd_server_connection_terminate(smb2req
->xconn
,
1309 struct smbd_smb2_logoff_state
{
1310 struct smbd_smb2_request
*smb2req
;
1313 static void smbd_smb2_logoff_shutdown_done(struct tevent_req
*subreq
);
1315 static struct tevent_req
*smbd_smb2_logoff_send(TALLOC_CTX
*mem_ctx
,
1316 struct tevent_context
*ev
,
1317 struct smbd_smb2_request
*smb2req
)
1319 struct tevent_req
*req
;
1320 struct smbd_smb2_logoff_state
*state
;
1321 struct tevent_req
*subreq
;
1323 req
= tevent_req_create(mem_ctx
, &state
,
1324 struct smbd_smb2_logoff_state
);
1328 state
->smb2req
= smb2req
;
1330 subreq
= smb2srv_session_shutdown_send(state
, ev
,
1333 if (tevent_req_nomem(subreq
, req
)) {
1334 return tevent_req_post(req
, ev
);
1336 tevent_req_set_callback(subreq
, smbd_smb2_logoff_shutdown_done
, req
);
1341 static void smbd_smb2_logoff_shutdown_done(struct tevent_req
*subreq
)
1343 struct tevent_req
*req
= tevent_req_callback_data(
1344 subreq
, struct tevent_req
);
1345 struct smbd_smb2_logoff_state
*state
= tevent_req_data(
1346 req
, struct smbd_smb2_logoff_state
);
1349 const struct GUID
*client_guid
=
1350 &state
->smb2req
->session
->client
->global
->client_guid
;
1352 status
= smb2srv_session_shutdown_recv(subreq
);
1353 if (tevent_req_nterror(req
, status
)) {
1356 TALLOC_FREE(subreq
);
1358 if (!GUID_all_zero(client_guid
)) {
1359 ok
= remote_arch_cache_delete(client_guid
);
1361 /* Most likely not an error, but not in cache */
1362 DBG_DEBUG("Deletion from remote arch cache failed\n");
1367 * As we've been awoken, we may have changed
1368 * uid in the meantime. Ensure we're still
1369 * root (SMB2_OP_LOGOFF has .as_root = true).
1371 change_to_root_user();
1373 status
= smbXsrv_session_logoff(state
->smb2req
->session
);
1374 if (tevent_req_nterror(req
, status
)) {
1379 * we may need to sign the response, so we need to keep
1380 * the session until the response is sent to the wire.
1382 talloc_steal(state
->smb2req
, state
->smb2req
->session
);
1384 tevent_req_done(req
);
1387 static NTSTATUS
smbd_smb2_logoff_recv(struct tevent_req
*req
)
1389 return tevent_req_simple_recv_ntstatus(req
);