LCOV - code coverage report
Current view: top level - source3/libsmb - clioplock.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 36 57 63.2 %
Date: 2024-04-21 15:09:00 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          16 : 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           0 :         struct tevent_req *req, *subreq;
      38           0 :         struct cli_smb_oplock_break_waiter_state *state;
      39             : 
      40          16 :         req = tevent_req_create(mem_ctx, &state,
      41             :                                 struct cli_smb_oplock_break_waiter_state);
      42          16 :         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          16 :         subreq = smb1cli_req_create(mem_ctx, ev, cli->conn, 0, 0, 0, 0, 0, 0,
      51             :                                     0, NULL, NULL, 0, NULL, 0, NULL);
      52          16 :         if (tevent_req_nomem(subreq, req)) {
      53           0 :                 return tevent_req_post(req, ev);
      54             :         }
      55          16 :         smb1cli_req_set_mid(subreq, 0xffff);
      56             : 
      57          16 :         if (!smbXcli_req_set_pending(subreq)) {
      58           0 :                 tevent_req_oom(req);
      59           0 :                 return tevent_req_post(req, ev);
      60             :         }
      61          16 :         tevent_req_set_callback(subreq, cli_smb_oplock_break_waiter_done, req);
      62          16 :         return req;
      63             : }
      64             : 
      65          14 : static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq)
      66             : {
      67          14 :         struct tevent_req *req = tevent_req_callback_data(
      68             :                 subreq, struct tevent_req);
      69          14 :         struct cli_smb_oplock_break_waiter_state *state = tevent_req_data(
      70             :                 req, struct cli_smb_oplock_break_waiter_state);
      71           0 :         struct iovec *iov;
      72           0 :         uint8_t wct;
      73           0 :         uint16_t *vwv;
      74           0 :         NTSTATUS status;
      75             : 
      76          14 :         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          14 :         TALLOC_FREE(subreq);
      88          14 :         if (tevent_req_nterror(req, status)) {
      89           0 :                 return;
      90             :         }
      91          14 :         if (wct < 8) {
      92           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
      93           0 :                 return;
      94             :         }
      95          14 :         state->fnum = SVAL(vwv+2, 0);
      96          14 :         state->level = CVAL(vwv+3, 1);
      97          14 :         tevent_req_done(req);
      98             : }
      99             : 
     100          14 : NTSTATUS cli_smb_oplock_break_waiter_recv(struct tevent_req *req,
     101             :                                           uint16_t *pfnum,
     102             :                                           uint8_t *plevel)
     103             : {
     104          14 :         struct cli_smb_oplock_break_waiter_state *state = tevent_req_data(
     105             :                 req, struct cli_smb_oplock_break_waiter_state);
     106           0 :         NTSTATUS status;
     107             : 
     108          14 :         if (tevent_req_is_nterror(req, &status)) {
     109           0 :                 return status;
     110             :         }
     111          14 :         *pfnum = state->fnum;
     112          14 :         *plevel = state->level;
     113          14 :         return NT_STATUS_OK;
     114             : }
     115             : 
     116             : /****************************************************************************
     117             : send an ack for an oplock break request
     118             : ****************************************************************************/
     119             : 
     120             : struct cli_oplock_ack_state {
     121             :         uint8_t dummy;
     122             : };
     123             : 
     124             : static void cli_oplock_ack_done(struct tevent_req *subreq);
     125             : 
     126           9 : struct tevent_req *cli_oplock_ack_send(TALLOC_CTX *mem_ctx,
     127             :                                        struct tevent_context *ev,
     128             :                                        struct cli_state *cli,
     129             :                                        uint16_t fnum, uint8_t level)
     130             : {
     131           0 :         struct tevent_req *req, *subreq;
     132           0 :         struct cli_oplock_ack_state *state;
     133             : 
     134           9 :         req = tevent_req_create(mem_ctx, &state, struct cli_oplock_ack_state);
     135           9 :         if (req == NULL) {
     136           0 :                 return NULL;
     137             :         }
     138             : 
     139           9 :         subreq = cli_lockingx_send(
     140             :                 state,                          /* mem_ctx */
     141             :                 ev,                             /* tevent_context */
     142             :                 cli,                            /* cli */
     143             :                 fnum,                           /* fnum */
     144             :                 LOCKING_ANDX_OPLOCK_RELEASE,    /* typeoflock */
     145             :                 level,                          /* newoplocklevel */
     146             :                 0,                              /* timeout */
     147             :                 0,                              /* num_unlocks */
     148             :                 NULL,                           /* unlocks */
     149             :                 0,                              /* num_locks */
     150             :                 NULL);                          /* locks */
     151             : 
     152           9 :         if (tevent_req_nomem(subreq, req)) {
     153           0 :                 return tevent_req_post(req, ev);
     154             :         }
     155           9 :         tevent_req_set_callback(subreq, cli_oplock_ack_done, req);
     156           9 :         return req;
     157             : }
     158             : 
     159           9 : static void cli_oplock_ack_done(struct tevent_req *subreq)
     160             : {
     161           9 :         NTSTATUS status = cli_lockingx_recv(subreq);
     162           9 :         tevent_req_simple_finish_ntstatus(subreq, status);
     163           9 : }
     164             : 
     165           0 : NTSTATUS cli_oplock_ack_recv(struct tevent_req *req)
     166             : {
     167           0 :         return tevent_req_simple_recv_ntstatus(req);
     168             : }
     169             : 

Generated by: LCOV version 1.14