LCOV - code coverage report
Current view: top level - source3/smbd - smb2_sesssetup.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 544 669 81.3 %
Date: 2021-08-25 13:27:56 Functions: 19 21 90.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Core SMB2 server
       4             : 
       5             :    Copyright (C) Stefan Metzmacher 2009
       6             :    Copyright (C) Jeremy Allison 2010
       7             : 
       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.
      12             : 
      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.
      17             : 
      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/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "smbd/smbd.h"
      24             : #include "smbd/globals.h"
      25             : #include "../libcli/smb/smb_common.h"
      26             : #include "../auth/gensec/gensec.h"
      27             : #include "auth.h"
      28             : #include "../lib/tsocket/tsocket.h"
      29             : #include "../libcli/security/security.h"
      30             : #include "../lib/util/tevent_ntstatus.h"
      31             : 
      32             : #include "lib/crypto/gnutls_helpers.h"
      33             : #include <gnutls/gnutls.h>
      34             : #include <gnutls/crypto.h>
      35             : 
      36             : #undef DBGC_CLASS
      37             : #define DBGC_CLASS DBGC_SMB2
      38             : 
      39             : static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
      40             :                                         struct tevent_context *ev,
      41             :                                         struct smbd_smb2_request *smb2req,
      42             :                                         uint64_t in_session_id,
      43             :                                         uint8_t in_flags,
      44             :                                         uint8_t in_security_mode,
      45             :                                         uint64_t in_previous_session_id,
      46             :                                         DATA_BLOB in_security_buffer);
      47             : static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
      48             :                                         uint16_t *out_session_flags,
      49             :                                         TALLOC_CTX *mem_ctx,
      50             :                                         DATA_BLOB *out_security_buffer,
      51             :                                         uint64_t *out_session_id);
      52             : 
      53             : static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq);
      54             : 
      55       39735 : NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req)
      56             : {
      57             :         const uint8_t *inhdr;
      58             :         const uint8_t *inbody;
      59             :         uint64_t in_session_id;
      60             :         uint8_t in_flags;
      61             :         uint8_t in_security_mode;
      62             :         uint64_t in_previous_session_id;
      63             :         uint16_t in_security_offset;
      64             :         uint16_t in_security_length;
      65             :         DATA_BLOB in_security_buffer;
      66             :         NTSTATUS status;
      67             :         struct tevent_req *subreq;
      68             : 
      69       39735 :         status = smbd_smb2_request_verify_sizes(smb2req, 0x19);
      70       39735 :         if (!NT_STATUS_IS_OK(status)) {
      71           0 :                 return smbd_smb2_request_error(smb2req, status);
      72             :         }
      73       39735 :         inhdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
      74       39735 :         inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
      75             : 
      76       39735 :         in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
      77             : 
      78       39735 :         in_flags = CVAL(inbody, 0x02);
      79       39735 :         in_security_mode = CVAL(inbody, 0x03);
      80             :         /* Capabilities = IVAL(inbody, 0x04) */
      81             :         /* Channel = IVAL(inbody, 0x08) */
      82       39735 :         in_security_offset = SVAL(inbody, 0x0C);
      83       39735 :         in_security_length = SVAL(inbody, 0x0E);
      84       39735 :         in_previous_session_id = BVAL(inbody, 0x10);
      85             : 
      86       39735 :         if (in_security_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req))) {
      87           0 :                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
      88             :         }
      89             : 
      90       39735 :         if (in_security_length > SMBD_SMB2_IN_DYN_LEN(smb2req)) {
      91           0 :                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
      92             :         }
      93             : 
      94       39735 :         in_security_buffer.data = SMBD_SMB2_IN_DYN_PTR(smb2req);
      95       39735 :         in_security_buffer.length = in_security_length;
      96             : 
      97       79470 :         subreq = smbd_smb2_session_setup_wrap_send(smb2req,
      98       39735 :                                                    smb2req->sconn->ev_ctx,
      99             :                                                    smb2req,
     100             :                                                    in_session_id,
     101             :                                                    in_flags,
     102             :                                                    in_security_mode,
     103             :                                                    in_previous_session_id,
     104             :                                                    in_security_buffer);
     105       39735 :         if (subreq == NULL) {
     106           0 :                 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
     107             :         }
     108       39735 :         tevent_req_set_callback(subreq, smbd_smb2_request_sesssetup_done, smb2req);
     109             : 
     110             :         /*
     111             :          * Avoid sending a STATUS_PENDING message, which
     112             :          * matches a Windows Server and avoids problems with
     113             :          * MacOS clients.
     114             :          *
     115             :          * Even after 90 seconds a Windows Server doesn't return
     116             :          * STATUS_PENDING if using NTLMSSP against a non reachable
     117             :          * trusted domain.
     118             :          */
     119       39735 :         return smbd_smb2_request_pending_queue(smb2req, subreq, 0);
     120             : }
     121             : 
     122       39735 : static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
     123             : {
     124       39735 :         struct smbd_smb2_request *smb2req =
     125       39735 :                 tevent_req_callback_data(subreq,
     126             :                 struct smbd_smb2_request);
     127             :         uint8_t *outhdr;
     128             :         DATA_BLOB outbody;
     129             :         DATA_BLOB outdyn;
     130       39735 :         uint16_t out_session_flags = 0;
     131       39735 :         uint64_t out_session_id = 0;
     132             :         uint16_t out_security_offset;
     133       39735 :         DATA_BLOB out_security_buffer = data_blob_null;
     134             :         NTSTATUS status;
     135             :         NTSTATUS error; /* transport error */
     136             : 
     137       39735 :         status = smbd_smb2_session_setup_wrap_recv(subreq,
     138             :                                                    &out_session_flags,
     139             :                                                    smb2req,
     140             :                                                    &out_security_buffer,
     141             :                                                    &out_session_id);
     142       39735 :         TALLOC_FREE(subreq);
     143       57942 :         if (!NT_STATUS_IS_OK(status) &&
     144       18207 :             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     145        2351 :                 status = nt_status_squash(status);
     146        2351 :                 error = smbd_smb2_request_error(smb2req, status);
     147        2351 :                 if (!NT_STATUS_IS_OK(error)) {
     148           0 :                         smbd_server_connection_terminate(smb2req->xconn,
     149             :                                                          nt_errstr(error));
     150           0 :                         return;
     151             :                 }
     152        2351 :                 return;
     153             :         }
     154             : 
     155       37384 :         out_security_offset = SMB2_HDR_BODY + 0x08;
     156             : 
     157       37384 :         outhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
     158             : 
     159       37384 :         outbody = smbd_smb2_generate_outbody(smb2req, 0x08);
     160       37384 :         if (outbody.data == NULL) {
     161           0 :                 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
     162           0 :                 if (!NT_STATUS_IS_OK(error)) {
     163           0 :                         smbd_server_connection_terminate(smb2req->xconn,
     164             :                                                          nt_errstr(error));
     165           0 :                         return;
     166             :                 }
     167           0 :                 return;
     168             :         }
     169             : 
     170       37384 :         SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
     171             : 
     172       37384 :         SSVAL(outbody.data, 0x00, 0x08 + 1);    /* struct size */
     173       37384 :         SSVAL(outbody.data, 0x02,
     174             :               out_session_flags);               /* session flags */
     175       37384 :         SSVAL(outbody.data, 0x04,
     176             :               out_security_offset);             /* security buffer offset */
     177       37384 :         SSVAL(outbody.data, 0x06,
     178             :               out_security_buffer.length);      /* security buffer length */
     179             : 
     180       37384 :         outdyn = out_security_buffer;
     181             : 
     182       37384 :         error = smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn,
     183             :                                            __location__);
     184       37384 :         if (!NT_STATUS_IS_OK(error)) {
     185           0 :                 smbd_server_connection_terminate(smb2req->xconn,
     186             :                                                  nt_errstr(error));
     187           0 :                 return;
     188             :         }
     189             : }
     190             : 
     191       20662 : static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
     192             :                                         struct smbXsrv_session_auth0 **_auth,
     193             :                                         struct smbd_smb2_request *smb2req,
     194             :                                         uint8_t in_security_mode,
     195             :                                         struct auth_session_info *session_info,
     196             :                                         uint16_t *out_session_flags,
     197             :                                         uint64_t *out_session_id)
     198             : {
     199             :         NTSTATUS status;
     200       20662 :         bool guest = false;
     201       20662 :         struct smbXsrv_session *x = session;
     202       20662 :         struct smbXsrv_session_auth0 *auth = *_auth;
     203       20662 :         struct smbXsrv_connection *xconn = smb2req->xconn;
     204             :         size_t i;
     205       20662 :         struct smb2_signing_derivations derivations = {
     206             :                 .signing = NULL,
     207             :         };
     208       20662 :         DATA_BLOB preauth_hash = data_blob_null;
     209             : 
     210       20662 :         *_auth = NULL;
     211             : 
     212       20662 :         if (xconn->protocol >= PROTOCOL_SMB3_11) {
     213             :                 struct smbXsrv_preauth *preauth;
     214             :                 gnutls_hash_hd_t hash_hnd;
     215             :                 int rc;
     216             : 
     217       18081 :                 preauth = talloc_move(smb2req, &auth->preauth);
     218             : 
     219       18081 :                 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
     220       18081 :                 if (rc < 0) {
     221           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
     222             :                 }
     223       18081 :                 rc = gnutls_hash(hash_hnd,
     224       18081 :                                  preauth->sha512_value,
     225             :                                  sizeof(preauth->sha512_value));
     226       18081 :                 if (rc < 0) {
     227           0 :                         gnutls_hash_deinit(hash_hnd, NULL);
     228           0 :                         return NT_STATUS_ACCESS_DENIED;
     229             :                 }
     230       90015 :                 for (i = 1; i < smb2req->in.vector_count; i++) {
     231      144648 :                         rc = gnutls_hash(hash_hnd,
     232       72324 :                                          smb2req->in.vector[i].iov_base,
     233       72324 :                                          smb2req->in.vector[i].iov_len);
     234       72324 :                         if (rc < 0) {
     235           0 :                                 gnutls_hash_deinit(hash_hnd, NULL);
     236           0 :                                 return NT_STATUS_ACCESS_DENIED;
     237             :                         }
     238             :                 }
     239       18081 :                 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
     240             : 
     241       18081 :                 preauth_hash = data_blob_const(preauth->sha512_value,
     242             :                                     sizeof(preauth->sha512_value));
     243             :         }
     244             : 
     245       20662 :         smb2_signing_derivations_fill_const_stack(&derivations,
     246             :                                                   xconn->protocol,
     247             :                                                   preauth_hash);
     248             : 
     249       32614 :         if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
     250       11952 :             (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
     251             :         {
     252       10347 :                 x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
     253             :         }
     254             : 
     255       20662 :         if ((lp_server_smb_encrypt(-1) >= SMB_ENCRYPTION_DESIRED) &&
     256           0 :             (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
     257           0 :                 x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
     258             :         }
     259             : 
     260       20662 :         if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_REQUIRED) {
     261           0 :                 x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
     262             :                         SMBXSRV_ENCRYPTION_DESIRED;
     263             :         }
     264             : 
     265       20662 :         if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
     266         695 :                 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
     267          19 :                         *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
     268             :                 }
     269             :                 /* force no signing */
     270         695 :                 x->global->signing_flags &= ~SMBXSRV_SIGNING_REQUIRED;
     271             :                 /* we map anonymous to guest internally */
     272         695 :                 guest = true;
     273             :         }
     274             : 
     275       20274 :         if (guest && (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED)) {
     276           0 :                 DEBUG(1,("reject guest session as encryption is required\n"));
     277           0 :                 return NT_STATUS_ACCESS_DENIED;
     278             :         }
     279             : 
     280       20662 :         if (xconn->smb2.server.cipher == 0) {
     281        2743 :                 if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
     282           0 :                         DEBUG(1,("reject session with dialect[0x%04X] "
     283             :                                  "as encryption is required\n",
     284             :                                  xconn->smb2.server.dialect));
     285           0 :                         return NT_STATUS_ACCESS_DENIED;
     286             :                 }
     287             :         }
     288       20662 :         x->global->signing_algo = xconn->smb2.server.sign_algo;
     289       20662 :         x->global->encryption_cipher = xconn->smb2.server.cipher;
     290       20662 :         if (guest) {
     291         695 :                 x->global->encryption_cipher = SMB2_ENCRYPTION_NONE;
     292             :         }
     293             : 
     294       20662 :         if (x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
     295           0 :                 *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
     296             :         }
     297             : 
     298       41324 :         status = smb2_signing_key_sign_create(x->global,
     299       20662 :                                               x->global->signing_algo,
     300       20662 :                                               &session_info->session_key,
     301             :                                               derivations.signing,
     302       20272 :                                               &x->global->signing_key);
     303       20662 :         if (!NT_STATUS_IS_OK(status)) {
     304           0 :                 return status;
     305             :         }
     306       20662 :         x->global->signing_key_blob = x->global->signing_key->blob;
     307             : 
     308       20662 :         if (x->global->encryption_cipher != SMB2_ENCRYPTION_NONE) {
     309             :                 size_t nonce_size;
     310             : 
     311       34578 :                 status = smb2_signing_key_cipher_create(x->global,
     312       16901 :                                                         x->global->encryption_cipher,
     313       17289 :                                                         &session_info->session_key,
     314             :                                                         derivations.cipher_s2c,
     315       16901 :                                                         &x->global->encryption_key);
     316       17289 :                 if (!NT_STATUS_IS_OK(status)) {
     317           0 :                         return status;
     318             :                 }
     319       17289 :                 x->global->encryption_key_blob = x->global->encryption_key->blob;
     320             : 
     321       34578 :                 status = smb2_signing_key_cipher_create(x->global,
     322       17289 :                                                         x->global->encryption_cipher,
     323       17289 :                                                         &session_info->session_key,
     324             :                                                         derivations.cipher_c2s,
     325       16901 :                                                         &x->global->decryption_key);
     326       17289 :                 if (!NT_STATUS_IS_OK(status)) {
     327           0 :                         return status;
     328             :                 }
     329       17289 :                 x->global->decryption_key_blob = x->global->decryption_key->blob;
     330             : 
     331             :                 /*
     332             :                  * CCM and GCM algorithms must never have their
     333             :                  * nonce wrap, or the security of the whole
     334             :                  * communication and the keys is destroyed.
     335             :                  * We must drop the connection once we have
     336             :                  * transfered too much data.
     337             :                  *
     338             :                  * NOTE: We assume nonces greater than 8 bytes.
     339             :                  */
     340       17289 :                 generate_nonce_buffer((uint8_t *)&x->nonce_high_random,
     341             :                                       sizeof(x->nonce_high_random));
     342       17289 :                 switch (xconn->smb2.server.cipher) {
     343          94 :                 case SMB2_ENCRYPTION_AES128_CCM:
     344          94 :                         nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
     345          94 :                         break;
     346       17175 :                 case SMB2_ENCRYPTION_AES128_GCM:
     347       17175 :                         nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
     348       17175 :                         break;
     349          10 :                 case SMB2_ENCRYPTION_AES256_CCM:
     350          10 :                         nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
     351          10 :                         break;
     352          10 :                 case SMB2_ENCRYPTION_AES256_GCM:
     353          10 :                         nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
     354          10 :                         break;
     355           0 :                 default:
     356           0 :                         nonce_size = 0;
     357           0 :                         break;
     358             :                 }
     359       17289 :                 x->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
     360       17289 :                 x->nonce_high = 0;
     361       17289 :                 x->nonce_low = 0;
     362             :         }
     363             : 
     364       41324 :         status = smb2_signing_key_sign_create(x->global,
     365       20662 :                                               x->global->signing_algo,
     366       20662 :                                               &session_info->session_key,
     367             :                                               derivations.application,
     368       20662 :                                               &x->global->application_key);
     369       20662 :         if (!NT_STATUS_IS_OK(status)) {
     370           0 :                 return status;
     371             :         }
     372       20662 :         x->global->application_key_blob = x->global->application_key->blob;
     373             : 
     374       20662 :         if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
     375           0 :                 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
     376           0 :                 DEBUGADD(0, ("Session Id    "));
     377           0 :                 dump_data(0, (uint8_t*)&session->global->session_wire_id,
     378             :                           sizeof(session->global->session_wire_id));
     379           0 :                 DEBUGADD(0, ("Session Key   "));
     380           0 :                 dump_data(0, session_info->session_key.data,
     381           0 :                           session_info->session_key.length);
     382           0 :                 DEBUGADD(0, ("Signing Algo: %u\n", x->global->signing_algo));
     383           0 :                 DEBUGADD(0, ("Signing Key   "));
     384           0 :                 dump_data(0, x->global->signing_key_blob.data,
     385           0 :                           x->global->signing_key_blob.length);
     386           0 :                 DEBUGADD(0, ("App Key       "));
     387           0 :                 dump_data(0, x->global->application_key_blob.data,
     388           0 :                           x->global->application_key_blob.length);
     389             : 
     390             :                 /* In server code, ServerIn is the decryption key */
     391             : 
     392           0 :                 DEBUGADD(0, ("Cipher Algo: %u\n", x->global->encryption_cipher));
     393           0 :                 DEBUGADD(0, ("ServerIn Key  "));
     394           0 :                 dump_data(0, x->global->decryption_key_blob.data,
     395           0 :                           x->global->decryption_key_blob.length);
     396           0 :                 DEBUGADD(0, ("ServerOut Key "));
     397           0 :                 dump_data(0, x->global->encryption_key_blob.data,
     398           0 :                           x->global->encryption_key_blob.length);
     399             :         }
     400             : 
     401       41324 :         status = smb2_signing_key_copy(x->global->channels,
     402       20662 :                                        x->global->signing_key,
     403       20662 :                                        &x->global->channels[0].signing_key);
     404       20662 :         if (!NT_STATUS_IS_OK(status)) {
     405           0 :                 return status;
     406             :         }
     407       20662 :         x->global->channels[0].signing_key_blob =
     408       20662 :                 x->global->channels[0].signing_key->blob;
     409       20662 :         x->global->channels[0].signing_algo = x->global->signing_algo;
     410       20662 :         x->global->channels[0].encryption_cipher = x->global->encryption_cipher;
     411             : 
     412       20662 :         data_blob_clear_free(&session_info->session_key);
     413       20662 :         session_info->session_key = data_blob_dup_talloc(session_info,
     414             :                                                 x->global->application_key_blob);
     415       20662 :         if (session_info->session_key.data == NULL) {
     416           0 :                 return NT_STATUS_NO_MEMORY;
     417             :         }
     418       20662 :         talloc_keep_secret(session_info->session_key.data);
     419             : 
     420       20662 :         smb2req->sconn->num_users++;
     421             : 
     422       20662 :         if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
     423       19967 :                 session->homes_snum =
     424       19967 :                         register_homes_share(session_info->unix_info->unix_name);
     425             :         }
     426             : 
     427       41324 :         set_current_user_info(session_info->unix_info->sanitized_username,
     428       20662 :                               session_info->unix_info->unix_name,
     429       20662 :                               session_info->info->domain_name);
     430             : 
     431       20662 :         reload_services(smb2req->sconn, conn_snum_used, true);
     432             : 
     433       20662 :         session->status = NT_STATUS_OK;
     434       20662 :         session->global->auth_session_info = talloc_move(session->global,
     435             :                                                          &session_info);
     436       20662 :         session->global->auth_session_info_seqnum += 1;
     437       41324 :         for (i=0; i < session->global->num_channels; i++) {
     438       20662 :                 struct smbXsrv_channel_global0 *_c =
     439       20662 :                         &session->global->channels[i];
     440             : 
     441       20662 :                 _c->auth_session_info_seqnum =
     442       20272 :                         session->global->auth_session_info_seqnum;
     443             :         }
     444       20662 :         session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
     445       20662 :         session->global->expiration_time = gensec_expire_time(auth->gensec);
     446             : 
     447       20662 :         if (!session_claim(session)) {
     448           0 :                 DEBUG(1, ("smb2: Failed to claim session "
     449             :                         "for vuid=%llu\n",
     450             :                         (unsigned long long)session->global->session_wire_id));
     451           0 :                 return NT_STATUS_LOGON_FAILURE;
     452             :         }
     453             : 
     454       20662 :         TALLOC_FREE(auth);
     455       20662 :         status = smbXsrv_session_update(session);
     456       20662 :         if (!NT_STATUS_IS_OK(status)) {
     457           0 :                 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
     458             :                           (unsigned long long)session->global->session_wire_id,
     459             :                           nt_errstr(status)));
     460           0 :                 return NT_STATUS_LOGON_FAILURE;
     461             :         }
     462             : 
     463             :         /*
     464             :          * we attach the session to the request
     465             :          * so that the response can be signed
     466             :          */
     467       20662 :         if (!guest) {
     468       19967 :                 smb2req->do_signing = true;
     469             :         }
     470             : 
     471       20662 :         global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
     472             : 
     473       20662 :         *out_session_id = session->global->session_wire_id;
     474       20662 :         smb2req->last_session_id = session->global->session_wire_id;
     475             : 
     476       20662 :         return NT_STATUS_OK;
     477             : }
     478             : 
     479         118 : static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
     480             :                                         struct smbXsrv_session_auth0 **_auth,
     481             :                                         struct smbd_smb2_request *smb2req,
     482             :                                         struct auth_session_info *session_info,
     483             :                                         uint16_t *out_session_flags,
     484             :                                         uint64_t *out_session_id)
     485             : {
     486             :         NTSTATUS status;
     487         118 :         struct smbXsrv_session *x = session;
     488         118 :         struct smbXsrv_session_auth0 *auth = *_auth;
     489         118 :         struct smbXsrv_connection *xconn = smb2req->xconn;
     490             :         size_t i;
     491             : 
     492         118 :         *_auth = NULL;
     493             : 
     494         118 :         data_blob_clear_free(&session_info->session_key);
     495         118 :         session_info->session_key = data_blob_dup_talloc(session_info,
     496             :                                                 x->global->application_key_blob);
     497         118 :         if (session_info->session_key.data == NULL) {
     498           0 :                 return NT_STATUS_NO_MEMORY;
     499             :         }
     500         118 :         talloc_keep_secret(session_info->session_key.data);
     501             : 
     502         118 :         session->homes_snum =
     503         118 :                         register_homes_share(session_info->unix_info->unix_name);
     504             : 
     505         236 :         set_current_user_info(session_info->unix_info->sanitized_username,
     506         118 :                               session_info->unix_info->unix_name,
     507         118 :                               session_info->info->domain_name);
     508             : 
     509         118 :         reload_services(smb2req->sconn, conn_snum_used, true);
     510             : 
     511         118 :         if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
     512          78 :                 smb2req->do_signing = true;
     513             :         }
     514             : 
     515         118 :         session->status = NT_STATUS_OK;
     516         118 :         TALLOC_FREE(session->global->auth_session_info);
     517         118 :         session->global->auth_session_info = talloc_move(session->global,
     518             :                                                          &session_info);
     519         118 :         session->global->auth_session_info_seqnum += 1;
     520         236 :         for (i=0; i < session->global->num_channels; i++) {
     521         118 :                 struct smbXsrv_channel_global0 *_c =
     522         118 :                         &session->global->channels[i];
     523             : 
     524         118 :                 _c->auth_session_info_seqnum =
     525         118 :                         session->global->auth_session_info_seqnum;
     526             :         }
     527         118 :         session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
     528         118 :         session->global->expiration_time = gensec_expire_time(auth->gensec);
     529             : 
     530         118 :         TALLOC_FREE(auth);
     531         118 :         status = smbXsrv_session_update(session);
     532         118 :         if (!NT_STATUS_IS_OK(status)) {
     533           0 :                 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
     534             :                           (unsigned long long)session->global->session_wire_id,
     535             :                           nt_errstr(status)));
     536           0 :                 return NT_STATUS_LOGON_FAILURE;
     537             :         }
     538             : 
     539         118 :         conn_clear_vuid_caches(xconn->client->sconn,
     540         118 :                                session->global->session_wire_id);
     541             : 
     542         118 :         *out_session_id = session->global->session_wire_id;
     543             : 
     544         118 :         return NT_STATUS_OK;
     545             : }
     546             : 
     547         752 : static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
     548             :                                            struct smbXsrv_session_auth0 **_auth,
     549             :                                            struct smbd_smb2_request *smb2req,
     550             :                                            struct auth_session_info *session_info,
     551             :                                            uint16_t *out_session_flags,
     552             :                                            uint64_t *out_session_id)
     553             : {
     554             :         NTSTATUS status;
     555         752 :         struct smbXsrv_session *x = session;
     556         752 :         struct smbXsrv_session_auth0 *auth = *_auth;
     557         752 :         struct smbXsrv_connection *xconn = smb2req->xconn;
     558         752 :         struct smbXsrv_channel_global0 *c = NULL;
     559             :         size_t i;
     560         752 :         struct smb2_signing_derivations derivations = {
     561             :                 .signing = NULL,
     562             :         };
     563         752 :         DATA_BLOB preauth_hash = data_blob_null;
     564             :         bool ok;
     565             : 
     566         752 :         *_auth = NULL;
     567             : 
     568         752 :         if (xconn->protocol >= PROTOCOL_SMB3_11) {
     569             :                 struct smbXsrv_preauth *preauth;
     570         752 :                 gnutls_hash_hd_t hash_hnd = NULL;
     571             :                 int rc;
     572             : 
     573         752 :                 preauth = talloc_move(smb2req, &auth->preauth);
     574             : 
     575         752 :                 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
     576         752 :                 if (rc < 0) {
     577           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
     578             :                 }
     579             : 
     580         752 :                 rc = gnutls_hash(hash_hnd,
     581         752 :                                  preauth->sha512_value,
     582             :                                  sizeof(preauth->sha512_value));
     583         752 :                 if (rc < 0) {
     584           0 :                         gnutls_hash_deinit(hash_hnd, NULL);
     585           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
     586             :                 }
     587        3760 :                 for (i = 1; i < smb2req->in.vector_count; i++) {
     588        6016 :                         rc = gnutls_hash(hash_hnd,
     589        3008 :                                          smb2req->in.vector[i].iov_base,
     590        3008 :                                          smb2req->in.vector[i].iov_len);
     591        3008 :                         if (rc < 0) {
     592           0 :                                 gnutls_hash_deinit(hash_hnd, NULL);
     593           0 :                                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
     594             :                         }
     595             :                 }
     596         752 :                 gnutls_hash_deinit(hash_hnd, preauth->sha512_value);
     597             : 
     598         752 :                 preauth_hash = data_blob_const(preauth->sha512_value,
     599             :                                     sizeof(preauth->sha512_value));
     600             :         }
     601             : 
     602         752 :         smb2_signing_derivations_fill_const_stack(&derivations,
     603             :                                                   xconn->protocol,
     604             :                                                   preauth_hash);
     605             : 
     606         752 :         status = smbXsrv_session_find_channel(session, xconn, &c);
     607         752 :         if (!NT_STATUS_IS_OK(status)) {
     608           0 :                 return status;
     609             :         }
     610             : 
     611         752 :         ok = security_token_is_sid(session_info->security_token,
     612         752 :                         &x->global->auth_session_info->security_token->sids[0]);
     613         752 :         if (!ok) {
     614           6 :                 return NT_STATUS_ACCESS_DENIED;
     615             :         }
     616             : 
     617         746 :         if (session_info->session_key.length == 0) {
     618             :                 /* See [MS-SMB2] 3.3.5.2.4 for the return code. */
     619           0 :                 return NT_STATUS_NOT_SUPPORTED;
     620             :         }
     621             : 
     622         746 :         c->signing_algo = xconn->smb2.server.sign_algo;
     623         746 :         c->encryption_cipher = xconn->smb2.server.cipher;
     624             : 
     625        1492 :         status = smb2_signing_key_sign_create(x->global->channels,
     626         746 :                                               c->signing_algo,
     627         746 :                                               &session_info->session_key,
     628             :                                               derivations.signing,
     629         746 :                                               &c->signing_key);
     630         746 :         if (!NT_STATUS_IS_OK(status)) {
     631           0 :                 return status;
     632             :         }
     633         746 :         c->signing_key_blob = c->signing_key->blob;
     634             : 
     635         746 :         TALLOC_FREE(auth);
     636         746 :         status = smbXsrv_session_update(session);
     637         746 :         if (!NT_STATUS_IS_OK(status)) {
     638           0 :                 DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
     639             :                           (unsigned long long)session->global->session_wire_id,
     640             :                           nt_errstr(status)));
     641           0 :                 return NT_STATUS_LOGON_FAILURE;
     642             :         }
     643             : 
     644         746 :         *out_session_id = session->global->session_wire_id;
     645             : 
     646         746 :         return NT_STATUS_OK;
     647             : }
     648             : 
     649             : struct smbd_smb2_session_setup_state {
     650             :         struct tevent_context *ev;
     651             :         struct smbd_smb2_request *smb2req;
     652             :         uint64_t in_session_id;
     653             :         uint8_t in_flags;
     654             :         uint8_t in_security_mode;
     655             :         uint64_t in_previous_session_id;
     656             :         DATA_BLOB in_security_buffer;
     657             :         struct smbXsrv_session *session;
     658             :         struct smbXsrv_session_auth0 *auth;
     659             :         struct auth_session_info *session_info;
     660             :         uint16_t out_session_flags;
     661             :         DATA_BLOB out_security_buffer;
     662             :         uint64_t out_session_id;
     663             : };
     664             : 
     665             : static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq);
     666             : static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq);
     667             : static void smbd_smb2_session_setup_auth_return(struct tevent_req *req);
     668             : 
     669       39735 : static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx,
     670             :                                         struct tevent_context *ev,
     671             :                                         struct smbd_smb2_request *smb2req,
     672             :                                         uint64_t in_session_id,
     673             :                                         uint8_t in_flags,
     674             :                                         uint8_t in_security_mode,
     675             :                                         uint64_t in_previous_session_id,
     676             :                                         DATA_BLOB in_security_buffer)
     677             : {
     678             :         struct tevent_req *req;
     679             :         struct smbd_smb2_session_setup_state *state;
     680             :         NTSTATUS status;
     681       39735 :         NTTIME now = timeval_to_nttime(&smb2req->request_time);
     682             :         struct tevent_req *subreq;
     683       39735 :         struct smbXsrv_channel_global0 *c = NULL;
     684             :         enum security_user_level seclvl;
     685             : 
     686       39735 :         req = tevent_req_create(mem_ctx, &state,
     687             :                                 struct smbd_smb2_session_setup_state);
     688       39735 :         if (req == NULL) {
     689           0 :                 return NULL;
     690             :         }
     691       39735 :         state->ev = ev;
     692       39735 :         state->smb2req = smb2req;
     693       39735 :         state->in_session_id = in_session_id;
     694       39735 :         state->in_flags = in_flags;
     695       39735 :         state->in_security_mode = in_security_mode;
     696       39735 :         state->in_previous_session_id = in_previous_session_id;
     697       39735 :         state->in_security_buffer = in_security_buffer;
     698             : 
     699       39735 :         if (in_flags & SMB2_SESSION_FLAG_BINDING) {
     700        1900 :                 if (in_session_id == 0) {
     701           0 :                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     702           0 :                         return tevent_req_post(req, ev);
     703             :                 }
     704             : 
     705        1900 :                 if (smb2req->session == NULL) {
     706           0 :                         tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
     707           0 :                         return tevent_req_post(req, ev);
     708             :                 }
     709             : 
     710        3364 :                 if ((smb2req->session->global->signing_algo >= SMB2_SIGNING_AES128_GMAC) &&
     711        1464 :                     (smb2req->xconn->smb2.server.sign_algo != smb2req->session->global->signing_algo))
     712             :                 {
     713         232 :                         tevent_req_nterror(req, NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
     714         232 :                         return tevent_req_post(req, ev);
     715             :                 }
     716        3132 :                 if ((smb2req->xconn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) &&
     717        1464 :                     (smb2req->session->global->signing_algo != smb2req->xconn->smb2.server.sign_algo))
     718             :                 {
     719         232 :                         tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
     720         232 :                         return tevent_req_post(req, ev);
     721             :                 }
     722             : 
     723        1436 :                 if (smb2req->xconn->protocol < PROTOCOL_SMB3_00) {
     724          80 :                         tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
     725          80 :                         return tevent_req_post(req, ev);
     726             :                 }
     727             : 
     728        1356 :                 if (!smb2req->xconn->client->server_multi_channel_enabled) {
     729           0 :                         tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
     730           0 :                         return tevent_req_post(req, ev);
     731             :                 }
     732             : 
     733        1356 :                 if (!smb2req->do_signing) {
     734           0 :                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     735           0 :                         return tevent_req_post(req, ev);
     736             :                 }
     737             : 
     738        2712 :                 if (smb2req->session->global->connection_dialect
     739        1356 :                     != smb2req->xconn->smb2.server.dialect)
     740             :                 {
     741          72 :                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     742          72 :                         return tevent_req_post(req, ev);
     743             :                 }
     744             : 
     745        2568 :                 if (smb2req->session->global->encryption_cipher
     746        1284 :                     != smb2req->xconn->smb2.server.cipher)
     747             :                 {
     748          40 :                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     749          40 :                         return tevent_req_post(req, ev);
     750             :                 }
     751             : 
     752        1244 :                 status = smb2req->session->status;
     753        1244 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
     754             :                         /*
     755             :                          * This comes from smb2srv_session_lookup_global().
     756             :                          */
     757          20 :                         tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
     758          20 :                         return tevent_req_post(req, ev);
     759             :                 }
     760             : 
     761        1224 :                 status = smbXsrv_session_find_channel(smb2req->session,
     762        1224 :                                                       smb2req->xconn,
     763             :                                                       &c);
     764        1224 :                 if (NT_STATUS_IS_OK(status)) {
     765         460 :                         if (!smb2_signing_key_valid(c->signing_key)) {
     766         460 :                                 goto auth;
     767             :                         }
     768           0 :                         tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
     769           0 :                         return tevent_req_post(req, ev);
     770             :                 }
     771             : 
     772         764 :                 seclvl = security_session_user_level(
     773         764 :                                 smb2req->session->global->auth_session_info,
     774             :                                 NULL);
     775         764 :                 if (seclvl < SECURITY_USER) {
     776           0 :                         tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
     777           0 :                         return tevent_req_post(req, ev);
     778             :                 }
     779             : 
     780         764 :                 status = smbXsrv_session_add_channel(smb2req->session,
     781             :                                                      smb2req->xconn,
     782             :                                                      now,
     783             :                                                      &c);
     784         764 :                 if (!NT_STATUS_IS_OK(status)) {
     785           4 :                         tevent_req_nterror(req, status);
     786           4 :                         return tevent_req_post(req, ev);
     787             :                 }
     788             : 
     789         760 :                 status = smbXsrv_session_update(smb2req->session);
     790         760 :                 if (!NT_STATUS_IS_OK(status)) {
     791           0 :                         tevent_req_nterror(req, status);
     792           0 :                         return tevent_req_post(req, ev);
     793             :                 }
     794             :         }
     795             : 
     796       38595 : auth:
     797             : 
     798       39055 :         if (state->in_session_id == 0) {
     799             :                 /* create a new session */
     800       21647 :                 status = smbXsrv_session_create(state->smb2req->xconn,
     801       21257 :                                                 now, &state->session);
     802       21647 :                 if (tevent_req_nterror(req, status)) {
     803           0 :                         return tevent_req_post(req, ev);
     804             :                 }
     805       21647 :                 smb2req->session = state->session;
     806             :         } else {
     807       17408 :                 if (smb2req->session == NULL) {
     808           0 :                         tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
     809           0 :                         return tevent_req_post(req, ev);
     810             :                 }
     811             : 
     812       17408 :                 state->session = smb2req->session;
     813       17408 :                 status = state->session->status;
     814       17408 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
     815             :                         /*
     816             :                          * This comes from smb2srv_session_lookup_global().
     817             :                          */
     818         478 :                         tevent_req_nterror(req, NT_STATUS_USER_SESSION_DELETED);
     819         478 :                         return tevent_req_post(req, ev);
     820             :                 }
     821       16930 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
     822          24 :                         status = NT_STATUS_OK;
     823             :                 }
     824       16930 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     825       15398 :                         status = NT_STATUS_OK;
     826             :                 }
     827       16930 :                 if (tevent_req_nterror(req, status)) {
     828           0 :                         return tevent_req_post(req, ev);
     829             :                 }
     830             :         }
     831             : 
     832       38577 :         status = smbXsrv_session_find_channel(smb2req->session,
     833       38577 :                                               smb2req->xconn, &c);
     834       38577 :         if (!NT_STATUS_IS_OK(status)) {
     835         178 :                 tevent_req_nterror(req, status);
     836         178 :                 return tevent_req_post(req, ev);
     837             :         }
     838             : 
     839       38399 :         if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
     840       37179 :                 state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
     841             :         }
     842             : 
     843       38399 :         status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
     844       38399 :                                            now, &state->auth);
     845       38399 :         if (!NT_STATUS_IS_OK(status)) {
     846       22541 :                 status = smbXsrv_session_create_auth(state->session,
     847             :                                                      smb2req->xconn, now,
     848             :                                                      in_flags, in_security_mode,
     849       22541 :                                                      &state->auth);
     850       22541 :                 if (tevent_req_nterror(req, status)) {
     851           0 :                         return tevent_req_post(req, ev);
     852             :                 }
     853             :         }
     854             : 
     855       38399 :         if (state->auth->gensec == NULL) {
     856       67233 :                 status = auth_generic_prepare(state->auth,
     857       22151 :                                               state->smb2req->xconn->remote_address,
     858       22541 :                                               state->smb2req->xconn->local_address,
     859             :                                               "SMB2",
     860       22151 :                                               &state->auth->gensec);
     861       22541 :                 if (tevent_req_nterror(req, status)) {
     862           0 :                         return tevent_req_post(req, ev);
     863             :                 }
     864             : 
     865       22541 :                 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
     866       22541 :                 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
     867       22541 :                 gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
     868             : 
     869       22541 :                 status = gensec_start_mech_by_oid(state->auth->gensec,
     870             :                                                   GENSEC_OID_SPNEGO);
     871       22541 :                 if (tevent_req_nterror(req, status)) {
     872           0 :                         return tevent_req_post(req, ev);
     873             :                 }
     874             :         }
     875             : 
     876       38399 :         status = smbXsrv_session_update(state->session);
     877       38399 :         if (tevent_req_nterror(req, status)) {
     878           0 :                 return tevent_req_post(req, ev);
     879             :         }
     880             : 
     881       38399 :         become_root();
     882       38399 :         subreq = gensec_update_send(state, state->ev,
     883       38399 :                                     state->auth->gensec,
     884       38399 :                                     state->in_security_buffer);
     885       38399 :         unbecome_root();
     886       38399 :         if (tevent_req_nomem(subreq, req)) {
     887           0 :                 return tevent_req_post(req, ev);
     888             :         }
     889       38399 :         tevent_req_set_callback(subreq, smbd_smb2_session_setup_gensec_done, req);
     890             : 
     891       38399 :         return req;
     892             : }
     893             : 
     894       38399 : static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
     895             : {
     896       38399 :         struct tevent_req *req =
     897       38399 :                 tevent_req_callback_data(subreq,
     898             :                 struct tevent_req);
     899       38399 :         struct smbd_smb2_session_setup_state *state =
     900       38399 :                 tevent_req_data(req,
     901             :                 struct smbd_smb2_session_setup_state);
     902             :         NTSTATUS status;
     903             : 
     904       38399 :         become_root();
     905       38399 :         status = gensec_update_recv(subreq, state,
     906             :                                     &state->out_security_buffer);
     907       38399 :         unbecome_root();
     908       38399 :         TALLOC_FREE(subreq);
     909       60940 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
     910       22541 :             !NT_STATUS_IS_OK(status)) {
     911        1007 :                 tevent_req_nterror(req, status);
     912        1007 :                 return;
     913             :         }
     914             : 
     915       37392 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     916       15858 :                 state->out_session_id = state->session->global->session_wire_id;
     917       15858 :                 state->smb2req->preauth = state->auth->preauth;
     918       15858 :                 tevent_req_nterror(req, status);
     919       15858 :                 return;
     920             :         }
     921             : 
     922       21534 :         status = gensec_session_info(state->auth->gensec,
     923             :                                      state,
     924             :                                      &state->session_info);
     925       21534 :         if (tevent_req_nterror(req, status)) {
     926           2 :                 return;
     927             :         }
     928             : 
     929       21630 :         if ((state->in_previous_session_id != 0) &&
     930          98 :              (state->session->global->session_wire_id !=
     931          98 :               state->in_previous_session_id))
     932             :         {
     933         196 :                 subreq = smb2srv_session_close_previous_send(state, state->ev,
     934          98 :                                                 state->smb2req->xconn,
     935             :                                                 state->session_info,
     936             :                                                 state->in_previous_session_id,
     937          98 :                                                 state->session->global->session_wire_id);
     938          98 :                 if (tevent_req_nomem(subreq, req)) {
     939           0 :                         return;
     940             :                 }
     941          98 :                 tevent_req_set_callback(subreq,
     942             :                                         smbd_smb2_session_setup_previous_done,
     943             :                                         req);
     944          98 :                 return;
     945             :         }
     946             : 
     947       21434 :         smbd_smb2_session_setup_auth_return(req);
     948             : }
     949             : 
     950          98 : static void smbd_smb2_session_setup_previous_done(struct tevent_req *subreq)
     951             : {
     952          98 :         struct tevent_req *req =
     953          98 :                 tevent_req_callback_data(subreq,
     954             :                 struct tevent_req);
     955             :         NTSTATUS status;
     956             : 
     957          98 :         status = smb2srv_session_close_previous_recv(subreq);
     958          98 :         TALLOC_FREE(subreq);
     959          98 :         if (tevent_req_nterror(req, status)) {
     960           0 :                 return;
     961             :         }
     962             : 
     963          98 :         smbd_smb2_session_setup_auth_return(req);
     964             : }
     965             : 
     966       21532 : static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
     967             : {
     968       21532 :         struct smbd_smb2_session_setup_state *state =
     969       21532 :                 tevent_req_data(req,
     970             :                 struct smbd_smb2_session_setup_state);
     971             :         NTSTATUS status;
     972             : 
     973       21532 :         if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
     974         752 :                 status = smbd_smb2_bind_auth_return(state->session,
     975             :                                                     &state->auth,
     976             :                                                     state->smb2req,
     977             :                                                     state->session_info,
     978             :                                                     &state->out_session_flags,
     979             :                                                     &state->out_session_id);
     980         752 :                 if (tevent_req_nterror(req, status)) {
     981           6 :                         return;
     982             :                 }
     983         746 :                 tevent_req_done(req);
     984         746 :                 return;
     985             :         }
     986             : 
     987       20780 :         if (state->session->global->auth_session_info != NULL) {
     988         118 :                 status = smbd_smb2_reauth_generic_return(state->session,
     989             :                                                          &state->auth,
     990             :                                                          state->smb2req,
     991             :                                                          state->session_info,
     992             :                                                          &state->out_session_flags,
     993             :                                                          &state->out_session_id);
     994         118 :                 if (tevent_req_nterror(req, status)) {
     995           0 :                         return;
     996             :                 }
     997         118 :                 tevent_req_done(req);
     998         118 :                 return;
     999             :         }
    1000             : 
    1001       41324 :         status = smbd_smb2_auth_generic_return(state->session,
    1002             :                                                &state->auth,
    1003             :                                                state->smb2req,
    1004       20662 :                                                state->in_security_mode,
    1005             :                                                state->session_info,
    1006             :                                                &state->out_session_flags,
    1007             :                                                &state->out_session_id);
    1008       20662 :         if (tevent_req_nterror(req, status)) {
    1009           0 :                 return;
    1010             :         }
    1011             : 
    1012       20662 :         tevent_req_done(req);
    1013       20662 :         return;
    1014             : }
    1015             : 
    1016       39735 : static NTSTATUS smbd_smb2_session_setup_recv(struct tevent_req *req,
    1017             :                                         uint16_t *out_session_flags,
    1018             :                                         TALLOC_CTX *mem_ctx,
    1019             :                                         DATA_BLOB *out_security_buffer,
    1020             :                                         uint64_t *out_session_id)
    1021             : {
    1022       39735 :         struct smbd_smb2_session_setup_state *state =
    1023       39735 :                 tevent_req_data(req,
    1024             :                 struct smbd_smb2_session_setup_state);
    1025             :         NTSTATUS status;
    1026             : 
    1027       39735 :         if (tevent_req_is_nterror(req, &status)) {
    1028       18209 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1029        2351 :                         tevent_req_received(req);
    1030        2351 :                         return nt_status_squash(status);
    1031             :                 }
    1032             :         } else {
    1033       21526 :                 status = NT_STATUS_OK;
    1034             :         }
    1035             : 
    1036       37384 :         *out_session_flags = state->out_session_flags;
    1037       37384 :         *out_security_buffer = state->out_security_buffer;
    1038       37384 :         *out_session_id = state->out_session_id;
    1039             : 
    1040       37384 :         talloc_steal(mem_ctx, out_security_buffer->data);
    1041       37384 :         tevent_req_received(req);
    1042       37384 :         return status;
    1043             : }
    1044             : 
    1045             : struct smbd_smb2_session_setup_wrap_state {
    1046             :         struct tevent_context *ev;
    1047             :         struct smbd_smb2_request *smb2req;
    1048             :         uint64_t in_session_id;
    1049             :         uint8_t in_flags;
    1050             :         uint8_t in_security_mode;
    1051             :         uint64_t in_previous_session_id;
    1052             :         DATA_BLOB in_security_buffer;
    1053             :         uint16_t out_session_flags;
    1054             :         DATA_BLOB out_security_buffer;
    1055             :         uint64_t out_session_id;
    1056             :         NTSTATUS error;
    1057             : };
    1058             : 
    1059             : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq);
    1060             : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq);
    1061             : 
    1062       39735 : static struct tevent_req *smbd_smb2_session_setup_wrap_send(TALLOC_CTX *mem_ctx,
    1063             :                                         struct tevent_context *ev,
    1064             :                                         struct smbd_smb2_request *smb2req,
    1065             :                                         uint64_t in_session_id,
    1066             :                                         uint8_t in_flags,
    1067             :                                         uint8_t in_security_mode,
    1068             :                                         uint64_t in_previous_session_id,
    1069             :                                         DATA_BLOB in_security_buffer)
    1070             : {
    1071             :         struct tevent_req *req;
    1072             :         struct smbd_smb2_session_setup_wrap_state *state;
    1073             :         struct tevent_req *subreq;
    1074             : 
    1075       39735 :         req = tevent_req_create(mem_ctx, &state,
    1076             :                                 struct smbd_smb2_session_setup_wrap_state);
    1077       39735 :         if (req == NULL) {
    1078           0 :                 return NULL;
    1079             :         }
    1080       39735 :         state->ev = ev;
    1081       39735 :         state->smb2req = smb2req;
    1082       39735 :         state->in_session_id = in_session_id;
    1083       39735 :         state->in_flags = in_flags;
    1084       39735 :         state->in_security_mode = in_security_mode;
    1085       39735 :         state->in_previous_session_id = in_previous_session_id;
    1086       39735 :         state->in_security_buffer = in_security_buffer;
    1087             : 
    1088      197107 :         subreq = smbd_smb2_session_setup_send(state, state->ev,
    1089       39343 :                                               state->smb2req,
    1090       39343 :                                               state->in_session_id,
    1091       39343 :                                               state->in_flags,
    1092       39343 :                                               state->in_security_mode,
    1093       39343 :                                               state->in_previous_session_id,
    1094       39343 :                                               state->in_security_buffer);
    1095       39735 :         if (tevent_req_nomem(subreq, req)) {
    1096           0 :                 return tevent_req_post(req, ev);
    1097             :         }
    1098       39735 :         tevent_req_set_callback(subreq,
    1099             :                                 smbd_smb2_session_setup_wrap_setup_done, req);
    1100             : 
    1101       39735 :         return req;
    1102             : }
    1103             : 
    1104       39735 : static void smbd_smb2_session_setup_wrap_setup_done(struct tevent_req *subreq)
    1105             : {
    1106       39735 :         struct tevent_req *req =
    1107       39735 :                 tevent_req_callback_data(subreq,
    1108             :                 struct tevent_req);
    1109       39735 :         struct smbd_smb2_session_setup_wrap_state *state =
    1110       39735 :                 tevent_req_data(req,
    1111             :                 struct smbd_smb2_session_setup_wrap_state);
    1112             :         NTSTATUS status;
    1113             : 
    1114       39735 :         status = smbd_smb2_session_setup_recv(subreq,
    1115             :                                               &state->out_session_flags,
    1116             :                                               state,
    1117             :                                               &state->out_security_buffer,
    1118             :                                               &state->out_session_id);
    1119       39735 :         TALLOC_FREE(subreq);
    1120       39735 :         if (NT_STATUS_IS_OK(status)) {
    1121       21526 :                 tevent_req_done(req);
    1122       21526 :                 return;
    1123             :         }
    1124       18209 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1125       15858 :                 tevent_req_nterror(req, status);
    1126       15858 :                 return;
    1127             :         }
    1128             : 
    1129        2351 :         if (state->smb2req->session == NULL) {
    1130           0 :                 tevent_req_nterror(req, status);
    1131           0 :                 return;
    1132             :         }
    1133             : 
    1134        2351 :         state->error = status;
    1135             : 
    1136        2351 :         if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
    1137         694 :                 status = smbXsrv_session_remove_channel(state->smb2req->session,
    1138         694 :                                                         state->smb2req->xconn);
    1139         694 :                 if (tevent_req_nterror(req, status)) {
    1140           0 :                         return;
    1141             :                 }
    1142         694 :                 tevent_req_nterror(req, state->error);
    1143         694 :                 return;
    1144             :         }
    1145             : 
    1146        1657 :         if (NT_STATUS_EQUAL(state->error, NT_STATUS_USER_SESSION_DELETED)) {
    1147         656 :                 tevent_req_nterror(req, state->error);
    1148         656 :                 return;
    1149             :         }
    1150             : 
    1151        2002 :         subreq = smb2srv_session_shutdown_send(state, state->ev,
    1152        1001 :                                                state->smb2req->session,
    1153             :                                                state->smb2req);
    1154        1001 :         if (tevent_req_nomem(subreq, req)) {
    1155           0 :                 return;
    1156             :         }
    1157        1001 :         tevent_req_set_callback(subreq,
    1158             :                                 smbd_smb2_session_setup_wrap_shutdown_done,
    1159             :                                 req);
    1160             : }
    1161             : 
    1162        1001 : static void smbd_smb2_session_setup_wrap_shutdown_done(struct tevent_req *subreq)
    1163             : {
    1164        1001 :         struct tevent_req *req =
    1165        1001 :                 tevent_req_callback_data(subreq,
    1166             :                 struct tevent_req);
    1167        1001 :         struct smbd_smb2_session_setup_wrap_state *state =
    1168        1001 :                 tevent_req_data(req,
    1169             :                 struct smbd_smb2_session_setup_wrap_state);
    1170             :         NTSTATUS status;
    1171             : 
    1172        1001 :         status = smb2srv_session_shutdown_recv(subreq);
    1173        1001 :         TALLOC_FREE(subreq);
    1174        1001 :         if (tevent_req_nterror(req, status)) {
    1175           0 :                 return;
    1176             :         }
    1177             : 
    1178             :         /*
    1179             :          * we may need to sign the response, so we need to keep
    1180             :          * the session until the response is sent to the wire.
    1181             :          */
    1182        1001 :         talloc_steal(state->smb2req, state->smb2req->session);
    1183             : 
    1184        1001 :         tevent_req_nterror(req, state->error);
    1185             : }
    1186             : 
    1187       39735 : static NTSTATUS smbd_smb2_session_setup_wrap_recv(struct tevent_req *req,
    1188             :                                         uint16_t *out_session_flags,
    1189             :                                         TALLOC_CTX *mem_ctx,
    1190             :                                         DATA_BLOB *out_security_buffer,
    1191             :                                         uint64_t *out_session_id)
    1192             : {
    1193       39735 :         struct smbd_smb2_session_setup_wrap_state *state =
    1194       39735 :                 tevent_req_data(req,
    1195             :                 struct smbd_smb2_session_setup_wrap_state);
    1196             :         NTSTATUS status;
    1197             : 
    1198       39735 :         if (tevent_req_is_nterror(req, &status)) {
    1199       18209 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1200        2351 :                         tevent_req_received(req);
    1201        2351 :                         return nt_status_squash(status);
    1202             :                 }
    1203             :         } else {
    1204       21526 :                 status = NT_STATUS_OK;
    1205             :         }
    1206             : 
    1207       37384 :         *out_session_flags = state->out_session_flags;
    1208       37384 :         *out_security_buffer = state->out_security_buffer;
    1209       37384 :         *out_session_id = state->out_session_id;
    1210             : 
    1211       37384 :         talloc_steal(mem_ctx, out_security_buffer->data);
    1212       37384 :         tevent_req_received(req);
    1213       37384 :         return status;
    1214             : }
    1215             : 
    1216             : static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
    1217             :                                         struct tevent_context *ev,
    1218             :                                         struct smbd_smb2_request *smb2req);
    1219             : static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req);
    1220             : static void smbd_smb2_request_logoff_done(struct tevent_req *subreq);
    1221             : 
    1222         149 : NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
    1223             : {
    1224             :         NTSTATUS status;
    1225         149 :         struct tevent_req *subreq = NULL;
    1226             : 
    1227         149 :         status = smbd_smb2_request_verify_sizes(req, 0x04);
    1228         149 :         if (!NT_STATUS_IS_OK(status)) {
    1229           0 :                 return smbd_smb2_request_error(req, status);
    1230             :         }
    1231             : 
    1232         149 :         subreq = smbd_smb2_logoff_send(req, req->sconn->ev_ctx, req);
    1233         149 :         if (subreq == NULL) {
    1234           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
    1235             :         }
    1236         149 :         tevent_req_set_callback(subreq, smbd_smb2_request_logoff_done, req);
    1237             : 
    1238             :         /*
    1239             :          * Avoid sending a STATUS_PENDING message, it's very likely
    1240             :          * the client won't expect that.
    1241             :          */
    1242         149 :         return smbd_smb2_request_pending_queue(req, subreq, 0);
    1243             : }
    1244             : 
    1245         149 : static void smbd_smb2_request_logoff_done(struct tevent_req *subreq)
    1246             : {
    1247         149 :         struct smbd_smb2_request *smb2req =
    1248         149 :                 tevent_req_callback_data(subreq,
    1249             :                 struct smbd_smb2_request);
    1250             :         DATA_BLOB outbody;
    1251             :         NTSTATUS status;
    1252             :         NTSTATUS error;
    1253             : 
    1254         149 :         status = smbd_smb2_logoff_recv(subreq);
    1255         149 :         TALLOC_FREE(subreq);
    1256         149 :         if (!NT_STATUS_IS_OK(status)) {
    1257           0 :                 error = smbd_smb2_request_error(smb2req, status);
    1258           0 :                 if (!NT_STATUS_IS_OK(error)) {
    1259           0 :                         smbd_server_connection_terminate(smb2req->xconn,
    1260             :                                                         nt_errstr(error));
    1261           0 :                         return;
    1262             :                 }
    1263           0 :                 return;
    1264             :         }
    1265             : 
    1266         149 :         outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
    1267         149 :         if (outbody.data == NULL) {
    1268           0 :                 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
    1269           0 :                 if (!NT_STATUS_IS_OK(error)) {
    1270           0 :                         smbd_server_connection_terminate(smb2req->xconn,
    1271             :                                                         nt_errstr(error));
    1272           0 :                         return;
    1273             :                 }
    1274           0 :                 return;
    1275             :         }
    1276             : 
    1277         149 :         SSVAL(outbody.data, 0x00, 0x04);        /* struct size */
    1278         149 :         SSVAL(outbody.data, 0x02, 0);           /* reserved */
    1279             : 
    1280         149 :         error = smbd_smb2_request_done(smb2req, outbody, NULL);
    1281         149 :         if (!NT_STATUS_IS_OK(error)) {
    1282           0 :                 smbd_server_connection_terminate(smb2req->xconn,
    1283             :                                                 nt_errstr(error));
    1284           0 :                 return;
    1285             :         }
    1286             : }
    1287             : 
    1288             : struct smbd_smb2_logoff_state {
    1289             :         struct smbd_smb2_request *smb2req;
    1290             : };
    1291             : 
    1292             : static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq);
    1293             : 
    1294         149 : static struct tevent_req *smbd_smb2_logoff_send(TALLOC_CTX *mem_ctx,
    1295             :                                         struct tevent_context *ev,
    1296             :                                         struct smbd_smb2_request *smb2req)
    1297             : {
    1298             :         struct tevent_req *req;
    1299             :         struct smbd_smb2_logoff_state *state;
    1300             :         struct tevent_req *subreq;
    1301             : 
    1302         149 :         req = tevent_req_create(mem_ctx, &state,
    1303             :                         struct smbd_smb2_logoff_state);
    1304         149 :         if (req == NULL) {
    1305           0 :                 return NULL;
    1306             :         }
    1307         149 :         state->smb2req = smb2req;
    1308             : 
    1309         149 :         subreq = smb2srv_session_shutdown_send(state, ev,
    1310             :                                                smb2req->session,
    1311             :                                                smb2req);
    1312         149 :         if (tevent_req_nomem(subreq, req)) {
    1313           0 :                 return tevent_req_post(req, ev);
    1314             :         }
    1315         149 :         tevent_req_set_callback(subreq, smbd_smb2_logoff_shutdown_done, req);
    1316             : 
    1317         149 :         return req;
    1318             : }
    1319             : 
    1320         149 : static void smbd_smb2_logoff_shutdown_done(struct tevent_req *subreq)
    1321             : {
    1322         149 :         struct tevent_req *req = tevent_req_callback_data(
    1323             :                 subreq, struct tevent_req);
    1324         149 :         struct smbd_smb2_logoff_state *state = tevent_req_data(
    1325             :                 req, struct smbd_smb2_logoff_state);
    1326             :         NTSTATUS status;
    1327             :         bool ok;
    1328         149 :         const struct GUID *client_guid =
    1329         149 :                 &state->smb2req->session->client->global->client_guid;
    1330             : 
    1331         149 :         status = smb2srv_session_shutdown_recv(subreq);
    1332         149 :         if (tevent_req_nterror(req, status)) {
    1333           0 :                 return;
    1334             :         }
    1335         149 :         TALLOC_FREE(subreq);
    1336             : 
    1337         149 :         if (!GUID_all_zero(client_guid)) {
    1338         133 :                 ok = remote_arch_cache_delete(client_guid);
    1339         133 :                 if (!ok) {
    1340             :                         /* Most likely not an error, but not in cache */
    1341         123 :                         DBG_DEBUG("Deletion from remote arch cache failed\n");
    1342             :                 }
    1343             :         }
    1344             : 
    1345             :         /*
    1346             :          * As we've been awoken, we may have changed
    1347             :          * uid in the meantime. Ensure we're still
    1348             :          * root (SMB2_OP_LOGOFF has .as_root = true).
    1349             :          */
    1350         149 :         change_to_root_user();
    1351             : 
    1352         149 :         status = smbXsrv_session_logoff(state->smb2req->session);
    1353         149 :         if (tevent_req_nterror(req, status)) {
    1354           0 :                 return;
    1355             :         }
    1356             : 
    1357             :         /*
    1358             :          * we may need to sign the response, so we need to keep
    1359             :          * the session until the response is sent to the wire.
    1360             :          */
    1361         149 :         talloc_steal(state->smb2req, state->smb2req->session);
    1362             : 
    1363         149 :         tevent_req_done(req);
    1364             : }
    1365             : 
    1366         149 : static NTSTATUS smbd_smb2_logoff_recv(struct tevent_req *req)
    1367             : {
    1368         149 :         return tevent_req_simple_recv_ntstatus(req);
    1369             : }

Generated by: LCOV version 1.13