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

Generated by: LCOV version 1.14