LCOV - code coverage report
Current view: top level - libcli/smb - smb2cli_tcon.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 96 133 72.2 %
Date: 2021-09-23 10:06:22 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    smb2 lib
       4             :    Copyright (C) Volker Lendecke 2011
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "system/network.h"
      22             : #include "../lib/util/tevent_ntstatus.h"
      23             : #include "../libcli/smb/smb_common.h"
      24             : #include "../libcli/smb/smbXcli_base.h"
      25             : 
      26             : struct smb2cli_tcon_state {
      27             :         struct tevent_context *ev;
      28             :         struct smbXcli_conn *conn;
      29             :         uint32_t timeout_msec;
      30             :         struct smbXcli_session *session;
      31             :         struct smbXcli_tcon *tcon;
      32             :         uint8_t fixed[8];
      33             :         uint8_t dyn_pad[1];
      34             : };
      35             : 
      36             : static void smb2cli_tcon_done(struct tevent_req *subreq);
      37             : 
      38       36323 : struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
      39             :                                      struct tevent_context *ev,
      40             :                                      struct smbXcli_conn *conn,
      41             :                                      uint32_t timeout_msec,
      42             :                                      struct smbXcli_session *session,
      43             :                                      struct smbXcli_tcon *tcon,
      44             :                                      uint16_t flags,
      45             :                                      const char *unc)
      46             : {
      47             :         struct tevent_req *req, *subreq;
      48             :         struct smb2cli_tcon_state *state;
      49             :         uint8_t *fixed;
      50             :         uint8_t *dyn;
      51             :         size_t dyn_len;
      52       36323 :         uint32_t additional_flags = 0;
      53       36323 :         uint32_t clear_flags = 0;
      54             : 
      55       36323 :         req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
      56       36323 :         if (req == NULL) {
      57           0 :                 return NULL;
      58             :         }
      59       36323 :         state->ev = ev;
      60       36323 :         state->conn = conn;
      61       36323 :         state->timeout_msec = timeout_msec;
      62       36323 :         state->session = session;
      63       36323 :         state->tcon = tcon;
      64             : 
      65       36323 :         if (!convert_string_talloc(state, CH_UNIX, CH_UTF16,
      66             :                                    unc, strlen(unc),
      67             :                                    &dyn, &dyn_len)) {
      68           0 :                 tevent_req_oom(req);
      69           0 :                 return tevent_req_post(req, ev);
      70             :         }
      71             : 
      72       36323 :         if (strlen(unc) == 0) {
      73           0 :                 TALLOC_FREE(dyn);
      74           0 :                 dyn_len = 0;
      75             :         }
      76             : 
      77       36323 :         fixed = state->fixed;
      78       36323 :         SSVAL(fixed, 0, 9);
      79       36323 :         if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
      80       32095 :                 SSVAL(fixed, 2, flags);
      81             :         } else {
      82        4228 :                 SSVAL(fixed, 2, 0); /* Reserved */
      83             :         }
      84       36323 :         SSVAL(fixed, 4, SMB2_HDR_BODY + 8);
      85       36323 :         SSVAL(fixed, 6, dyn_len);
      86             : 
      87       36323 :         if (dyn_len == 0) {
      88           0 :                 dyn = state->dyn_pad;
      89           0 :                 dyn_len = sizeof(state->dyn_pad);
      90             :         }
      91             : 
      92       36323 :         if (smbXcli_session_is_authenticated(state->session)) {
      93       35379 :                 additional_flags |= SMB2_HDR_FLAG_SIGNED;
      94             :         }
      95             : 
      96       69116 :         subreq = smb2cli_req_send(state, ev, conn, SMB2_OP_TCON,
      97             :                                   additional_flags, clear_flags,
      98             :                                   timeout_msec,
      99             :                                   NULL, /* tcon */
     100             :                                   session,
     101       36323 :                                   state->fixed, sizeof(state->fixed),
     102             :                                   dyn, dyn_len,
     103             :                                   0); /* max_dyn_len */
     104       36323 :         if (tevent_req_nomem(subreq, req)) {
     105           0 :                 return tevent_req_post(req, ev);
     106             :         }
     107       36323 :         tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
     108             : 
     109       36323 :         return req;
     110             : }
     111             : 
     112             : static void smb2cli_tcon_validate(struct tevent_req *subreq);
     113             : 
     114       36323 : static void smb2cli_tcon_done(struct tevent_req *subreq)
     115             : {
     116       36323 :         struct tevent_req *req = tevent_req_callback_data(
     117             :                 subreq, struct tevent_req);
     118       36323 :         struct smb2cli_tcon_state *state = tevent_req_data(
     119             :                 req, struct smb2cli_tcon_state);
     120             :         NTSTATUS status;
     121             :         struct iovec *iov;
     122             :         uint8_t *body;
     123             :         uint32_t tcon_id;
     124             :         uint8_t share_type;
     125             :         uint32_t share_flags;
     126             :         uint32_t share_capabilities;
     127             :         uint32_t maximal_access;
     128             :         static const struct smb2cli_req_expected_response expected[] = {
     129             :         {
     130             :                 .status = NT_STATUS_OK,
     131             :                 .body_size = 0x10
     132             :         }
     133             :         };
     134             : 
     135       36323 :         status = smb2cli_req_recv(subreq, state, &iov,
     136             :                                   expected, ARRAY_SIZE(expected));
     137       36323 :         TALLOC_FREE(subreq);
     138       36323 :         if (!NT_STATUS_IS_OK(status)) {
     139          78 :                 tevent_req_nterror(req, status);
     140        2407 :                 return;
     141             :         }
     142             : 
     143       36245 :         tcon_id = IVAL(iov[0].iov_base, SMB2_HDR_TID);
     144             : 
     145       36245 :         body = (uint8_t *)iov[1].iov_base;
     146       36245 :         share_type              = CVAL(body, 0x02);
     147       36245 :         share_flags             = IVAL(body, 0x04);
     148       36245 :         share_capabilities      = IVAL(body, 0x08);
     149       36245 :         maximal_access          = IVAL(body, 0x0C);
     150             : 
     151       36245 :         smb2cli_tcon_set_values(state->tcon,
     152             :                                 state->session,
     153             :                                 tcon_id,
     154             :                                 share_type,
     155             :                                 share_flags,
     156             :                                 share_capabilities,
     157             :                                 maximal_access);
     158             : 
     159       36245 :         if (!smbXcli_session_is_authenticated(state->session)) {
     160         940 :                 tevent_req_done(req);
     161         940 :                 return;
     162             :         }
     163             : 
     164       35305 :         if (smbXcli_conn_protocol(state->conn) >= PROTOCOL_SMB3_11) {
     165       31163 :                 tevent_req_done(req);
     166       31163 :                 return;
     167             :         }
     168             : 
     169        4142 :         subreq = smb2cli_validate_negotiate_info_send(state, state->ev,
     170             :                                                       state->conn,
     171             :                                                       state->timeout_msec,
     172             :                                                       state->session,
     173             :                                                       state->tcon);
     174        4142 :         if (tevent_req_nomem(subreq, req)) {
     175           0 :                 return;
     176             :         }
     177        4142 :         tevent_req_set_callback(subreq, smb2cli_tcon_validate, req);
     178             : }
     179             : 
     180        4142 : static void smb2cli_tcon_validate(struct tevent_req *subreq)
     181             : {
     182        4142 :         struct tevent_req *req = tevent_req_callback_data(
     183             :                 subreq, struct tevent_req);
     184        4142 :         struct smb2cli_tcon_state *state = tevent_req_data(
     185             :                 req, struct smb2cli_tcon_state);
     186             :         NTSTATUS status;
     187             : 
     188        4142 :         status = smb2cli_validate_negotiate_info_recv(subreq);
     189        4142 :         TALLOC_FREE(subreq);
     190        4142 :         if (!NT_STATUS_IS_OK(status)) {
     191           0 :                 smb2cli_tcon_set_values(state->tcon, NULL,
     192             :                                         UINT32_MAX, 0, 0, 0, 0);
     193           0 :                 tevent_req_nterror(req, status);
     194           0 :                 return;
     195             :         }
     196             : 
     197        4142 :         tevent_req_done(req);
     198             : }
     199             : 
     200       36323 : NTSTATUS smb2cli_tcon_recv(struct tevent_req *req)
     201             : {
     202       36323 :         return tevent_req_simple_recv_ntstatus(req);
     203             : }
     204             : 
     205           0 : NTSTATUS smb2cli_tcon(struct smbXcli_conn *conn,
     206             :                       uint32_t timeout_msec,
     207             :                       struct smbXcli_session *session,
     208             :                       struct smbXcli_tcon *tcon,
     209             :                       uint16_t flags,
     210             :                       const char *unc)
     211             : {
     212           0 :         TALLOC_CTX *frame = talloc_stackframe();
     213             :         struct tevent_context *ev;
     214             :         struct tevent_req *req;
     215           0 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     216             : 
     217           0 :         if (smbXcli_conn_has_async_calls(conn)) {
     218             :                 /*
     219             :                  * Can't use sync call while an async call is in flight
     220             :                  */
     221           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     222           0 :                 goto fail;
     223             :         }
     224           0 :         ev = samba_tevent_context_init(frame);
     225           0 :         if (ev == NULL) {
     226           0 :                 goto fail;
     227             :         }
     228           0 :         req = smb2cli_tcon_send(frame, ev, conn,
     229             :                                 timeout_msec, session, tcon,
     230             :                                 flags, unc);
     231           0 :         if (req == NULL) {
     232           0 :                 goto fail;
     233             :         }
     234           0 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     235           0 :                 goto fail;
     236             :         }
     237           0 :         status = smb2cli_tcon_recv(req);
     238           0 :  fail:
     239           0 :         TALLOC_FREE(frame);
     240           0 :         return status;
     241             : }
     242             : 
     243             : struct smb2cli_tdis_state {
     244             :         struct smbXcli_tcon *tcon;
     245             :         uint8_t fixed[4];
     246             : };
     247             : 
     248             : static void smb2cli_tdis_done(struct tevent_req *subreq);
     249             : 
     250       22675 : struct tevent_req *smb2cli_tdis_send(TALLOC_CTX *mem_ctx,
     251             :                                      struct tevent_context *ev,
     252             :                                      struct smbXcli_conn *conn,
     253             :                                      uint32_t timeout_msec,
     254             :                                      struct smbXcli_session *session,
     255             :                                      struct smbXcli_tcon *tcon)
     256             : {
     257             :         struct tevent_req *req, *subreq;
     258             :         struct smb2cli_tdis_state *state;
     259             : 
     260       22675 :         req = tevent_req_create(mem_ctx, &state,
     261             :                                 struct smb2cli_tdis_state);
     262       22675 :         if (req == NULL) {
     263           0 :                 return NULL;
     264             :         }
     265       22675 :         state->tcon = tcon;
     266             : 
     267       22675 :         SSVAL(state->fixed, 0, 4);
     268             : 
     269       22675 :         subreq = smb2cli_req_send(state, ev, conn, SMB2_OP_TDIS,
     270             :                                   0, 0, /* flags */
     271             :                                   timeout_msec,
     272             :                                   tcon, session,
     273       22675 :                                   state->fixed, sizeof(state->fixed),
     274             :                                   NULL, 0, /* dyn* */
     275             :                                   0); /* max_dyn_len */
     276       22675 :         if (tevent_req_nomem(subreq, req)) {
     277           0 :                 return tevent_req_post(req, ev);
     278             :         }
     279       22675 :         tevent_req_set_callback(subreq, smb2cli_tdis_done, req);
     280       22675 :         return req;
     281             : }
     282             : 
     283       22675 : static void smb2cli_tdis_done(struct tevent_req *subreq)
     284             : {
     285       21493 :         struct tevent_req *req =
     286       22675 :                 tevent_req_callback_data(subreq,
     287             :                 struct tevent_req);
     288       21493 :         struct smb2cli_tdis_state *state =
     289       22675 :                 tevent_req_data(req,
     290             :                 struct smb2cli_tdis_state);
     291             :         NTSTATUS status;
     292             :         static const struct smb2cli_req_expected_response expected[] = {
     293             :         {
     294             :                 .status = NT_STATUS_OK,
     295             :                 .body_size = 0x04
     296             :         }
     297             :         };
     298             : 
     299       22675 :         status = smb2cli_req_recv(subreq, NULL, NULL,
     300             :                                   expected, ARRAY_SIZE(expected));
     301       22675 :         TALLOC_FREE(subreq);
     302       22675 :         if (tevent_req_nterror(req, status)) {
     303          95 :                 return;
     304             :         }
     305       22580 :         smb2cli_tcon_set_values(state->tcon, NULL,
     306             :                                 UINT32_MAX, 0, 0, 0, 0);
     307       22580 :         tevent_req_done(req);
     308             : }
     309             : 
     310       22675 : NTSTATUS smb2cli_tdis_recv(struct tevent_req *req)
     311             : {
     312       22675 :         return tevent_req_simple_recv_ntstatus(req);
     313             : }
     314             : 
     315       22675 : NTSTATUS smb2cli_tdis(struct smbXcli_conn *conn,
     316             :                       uint32_t timeout_msec,
     317             :                       struct smbXcli_session *session,
     318             :                       struct smbXcli_tcon *tcon)
     319             : {
     320       22675 :         TALLOC_CTX *frame = talloc_stackframe();
     321             :         struct tevent_context *ev;
     322             :         struct tevent_req *req;
     323       22675 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     324             : 
     325       22675 :         if (smbXcli_conn_has_async_calls(conn)) {
     326             :                 /*
     327             :                  * Can't use sync call while an async call is in flight
     328             :                  */
     329           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     330           0 :                 goto fail;
     331             :         }
     332       22675 :         ev = samba_tevent_context_init(frame);
     333       22675 :         if (ev == NULL) {
     334           0 :                 goto fail;
     335             :         }
     336       22675 :         req = smb2cli_tdis_send(frame, ev, conn,
     337             :                                 timeout_msec, session, tcon);
     338       22675 :         if (req == NULL) {
     339           0 :                 goto fail;
     340             :         }
     341       22675 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     342           0 :                 goto fail;
     343             :         }
     344       22675 :         status = smb2cli_tdis_recv(req);
     345       22675 :  fail:
     346       22675 :         TALLOC_FREE(frame);
     347       22675 :         return status;
     348             : }

Generated by: LCOV version 1.13