LCOV - code coverage report
Current view: top level - source3/libsmb - clioplock.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 36 49 73.5 %
Date: 2024-06-13 04:01:37 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB client oplock functions
       4             :    Copyright (C) Andrew Tridgell 2001
       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 "../lib/util/tevent_ntstatus.h"
      22             : #include "async_smb.h"
      23             : #include "libsmb/libsmb.h"
      24             : #include "../libcli/smb/smbXcli_base.h"
      25             : 
      26             : struct cli_smb_oplock_break_waiter_state {
      27             :         uint16_t fnum;
      28             :         uint8_t level;
      29             : };
      30             : 
      31             : static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq);
      32             : 
      33           2 : struct tevent_req *cli_smb_oplock_break_waiter_send(TALLOC_CTX *mem_ctx,
      34             :                                                     struct tevent_context *ev,
      35             :                                                     struct cli_state *cli)
      36             : {
      37             :         struct tevent_req *req, *subreq;
      38             :         struct cli_smb_oplock_break_waiter_state *state;
      39             : 
      40           2 :         req = tevent_req_create(mem_ctx, &state,
      41             :                                 struct cli_smb_oplock_break_waiter_state);
      42           2 :         if (req == NULL) {
      43           0 :                 return NULL;
      44             :         }
      45             : 
      46             :         /*
      47             :          * Create a fake SMB request that we will never send out. This is only
      48             :          * used to be set into the pending queue with the right mid.
      49             :          */
      50           2 :         subreq = smb1cli_req_create(mem_ctx, ev, cli->conn, 0, 0, 0, 0, 0, 0,
      51             :                                     0, NULL, NULL, 0, NULL, 0, NULL);
      52           2 :         if (tevent_req_nomem(subreq, req)) {
      53           0 :                 return tevent_req_post(req, ev);
      54             :         }
      55           2 :         smb1cli_req_set_mid(subreq, 0xffff);
      56             : 
      57           2 :         if (!smbXcli_req_set_pending(subreq)) {
      58           0 :                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
      59           0 :                 return tevent_req_post(req, ev);
      60             :         }
      61           2 :         tevent_req_set_callback(subreq, cli_smb_oplock_break_waiter_done, req);
      62           2 :         return req;
      63             : }
      64             : 
      65           2 : static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq)
      66             : {
      67           2 :         struct tevent_req *req = tevent_req_callback_data(
      68             :                 subreq, struct tevent_req);
      69           2 :         struct cli_smb_oplock_break_waiter_state *state = tevent_req_data(
      70             :                 req, struct cli_smb_oplock_break_waiter_state);
      71             :         struct iovec *iov;
      72             :         uint8_t wct;
      73             :         uint16_t *vwv;
      74             :         NTSTATUS status;
      75             : 
      76           2 :         status = smb1cli_req_recv(subreq, state,
      77             :                                   &iov, /* piov */
      78             :                                   NULL, /* phdr */
      79             :                                   &wct,
      80             :                                   &vwv,
      81             :                                   NULL, /* pvwv_offset */
      82             :                                   NULL, /* pnum_bytes */
      83             :                                   NULL, /* pbytes */
      84             :                                   NULL, /* pbytes_offset */
      85             :                                   NULL, /* pinbuf */
      86             :                                   NULL, 0); /* expected */
      87           2 :         TALLOC_FREE(subreq);
      88           2 :         if (!NT_STATUS_IS_OK(status)) {
      89           0 :                 tevent_req_nterror(req, status);
      90           0 :                 return;
      91             :         }
      92           2 :         if (wct < 8) {
      93           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
      94           0 :                 return;
      95             :         }
      96           2 :         state->fnum = SVAL(vwv+2, 0);
      97           2 :         state->level = CVAL(vwv+3, 1);
      98           2 :         tevent_req_done(req);
      99             : }
     100             : 
     101           2 : NTSTATUS cli_smb_oplock_break_waiter_recv(struct tevent_req *req,
     102             :                                           uint16_t *pfnum,
     103             :                                           uint8_t *plevel)
     104             : {
     105           2 :         struct cli_smb_oplock_break_waiter_state *state = tevent_req_data(
     106             :                 req, struct cli_smb_oplock_break_waiter_state);
     107             :         NTSTATUS status;
     108             : 
     109           2 :         if (tevent_req_is_nterror(req, &status)) {
     110           0 :                 return status;
     111             :         }
     112           2 :         *pfnum = state->fnum;
     113           2 :         *plevel = state->level;
     114           2 :         return NT_STATUS_OK;
     115             : }
     116             : 
     117             : /****************************************************************************
     118             : send an ack for an oplock break request
     119             : ****************************************************************************/
     120             : 
     121             : struct cli_oplock_ack_state {
     122             :         uint8_t dummy;
     123             : };
     124             : 
     125             : static void cli_oplock_ack_done(struct tevent_req *subreq);
     126             : 
     127           1 : struct tevent_req *cli_oplock_ack_send(TALLOC_CTX *mem_ctx,
     128             :                                        struct tevent_context *ev,
     129             :                                        struct cli_state *cli,
     130             :                                        uint16_t fnum, uint8_t level)
     131             : {
     132             :         struct tevent_req *req, *subreq;
     133             :         struct cli_oplock_ack_state *state;
     134             : 
     135           1 :         req = tevent_req_create(mem_ctx, &state, struct cli_oplock_ack_state);
     136           1 :         if (req == NULL) {
     137           0 :                 return NULL;
     138             :         }
     139             : 
     140           1 :         subreq = cli_lockingx_send(
     141             :                 state,                          /* mem_ctx */
     142             :                 ev,                             /* tevent_context */
     143             :                 cli,                            /* cli */
     144             :                 fnum,                           /* fnum */
     145             :                 LOCKING_ANDX_OPLOCK_RELEASE,    /* typeoflock */
     146             :                 level,                          /* newoplocklevel */
     147             :                 0,                              /* timeout */
     148             :                 0,                              /* num_unlocks */
     149             :                 NULL,                           /* unlocks */
     150             :                 0,                              /* num_locks */
     151             :                 NULL);                          /* locks */
     152             : 
     153           1 :         if (tevent_req_nomem(subreq, req)) {
     154           0 :                 return tevent_req_post(req, ev);
     155             :         }
     156           1 :         tevent_req_set_callback(subreq, cli_oplock_ack_done, req);
     157           1 :         return req;
     158             : }
     159             : 
     160           1 : static void cli_oplock_ack_done(struct tevent_req *subreq)
     161             : {
     162           1 :         NTSTATUS status = cli_lockingx_recv(subreq);
     163           1 :         tevent_req_simple_finish_ntstatus(subreq, status);
     164           1 : }
     165             : 
     166           0 : NTSTATUS cli_oplock_ack_recv(struct tevent_req *req)
     167             : {
     168           0 :         return tevent_req_simple_recv_ntstatus(req);
     169             : }
     170             : 

Generated by: LCOV version 1.13