LCOV - code coverage report
Current view: top level - source3/smbd - smb2_sesssetup.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 597 720 82.9 %
Date: 2024-04-21 15:09:00 Functions: 19 19 100.0 %

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

Generated by: LCOV version 1.14