Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/clioplock.c

    r746 r988  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   SMB client oplock functions
    44   Copyright (C) Andrew Tridgell 2001
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2222#include "async_smb.h"
    2323#include "libsmb/libsmb.h"
     24#include "../libcli/smb/smbXcli_base.h"
     25
     26struct cli_smb_oplock_break_waiter_state {
     27        uint16_t fnum;
     28        uint8_t level;
     29};
     30
     31static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq);
     32
     33struct 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        req = tevent_req_create(mem_ctx, &state,
     41                                struct cli_smb_oplock_break_waiter_state);
     42        if (req == NULL) {
     43                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        subreq = smb1cli_req_create(mem_ctx, ev, cli->conn, 0, 0, 0, 0, 0, 0,
     51                                    0, NULL, NULL, 0, NULL, 0, NULL);
     52        if (tevent_req_nomem(subreq, req)) {
     53                return tevent_req_post(req, ev);
     54        }
     55        smb1cli_req_set_mid(subreq, 0xffff);
     56
     57        if (!smbXcli_req_set_pending(subreq)) {
     58                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     59                return tevent_req_post(req, ev);
     60        }
     61        tevent_req_set_callback(subreq, cli_smb_oplock_break_waiter_done, req);
     62        return req;
     63}
     64
     65static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq)
     66{
     67        struct tevent_req *req = tevent_req_callback_data(
     68                subreq, struct tevent_req);
     69        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        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        TALLOC_FREE(subreq);
     88        if (!NT_STATUS_IS_OK(status)) {
     89                tevent_req_nterror(req, status);
     90                return;
     91        }
     92        if (wct < 8) {
     93                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     94                return;
     95        }
     96        state->fnum = SVAL(vwv+2, 0);
     97        state->level = CVAL(vwv+3, 1);
     98        tevent_req_done(req);
     99}
     100
     101NTSTATUS cli_smb_oplock_break_waiter_recv(struct tevent_req *req,
     102                                          uint16_t *pfnum,
     103                                          uint8_t *plevel)
     104{
     105        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        if (tevent_req_is_nterror(req, &status)) {
     110                return status;
     111        }
     112        *pfnum = state->fnum;
     113        *plevel = state->level;
     114        return NT_STATUS_OK;
     115}
    24116
    25117/****************************************************************************
     
    84176}
    85177
    86 NTSTATUS cli_oplock_ack(struct cli_state *cli, uint16_t fnum, unsigned char level)
    87 {
    88         TALLOC_CTX *frame = talloc_stackframe();
    89         struct event_context *ev;
    90         struct tevent_req *req;
    91         NTSTATUS status = NT_STATUS_OK;
    92 
    93         if (cli_has_async_calls(cli)) {
    94                 /*
    95                  * Can't use sync call while an async call is in flight
    96                  */
    97                 status = NT_STATUS_INVALID_PARAMETER;
    98                 goto fail;
    99         }
    100 
    101         ev = event_context_init(frame);
    102         if (ev == NULL) {
    103                 status = NT_STATUS_NO_MEMORY;
    104                 goto fail;
    105         }
    106 
    107         req = cli_oplock_ack_send(frame, ev, cli, fnum, level);
    108         if (req == NULL) {
    109                 status = NT_STATUS_NO_MEMORY;
    110                 goto fail;
    111         }
    112 
    113         if (!tevent_req_poll(req, ev)) {
    114                 status = map_nt_error_from_unix(errno);
    115                 goto fail;
    116         }
    117 
    118         status = cli_oplock_ack_recv(req);
    119  fail:
    120         TALLOC_FREE(frame);
    121         return status;
    122 }
    123 
    124 /****************************************************************************
    125 set the oplock handler for a connection
    126 ****************************************************************************/
    127 
    128 void cli_oplock_handler(struct cli_state *cli,
    129                         NTSTATUS (*handler)(struct cli_state *, uint16_t, unsigned char))
    130 {
    131         cli->oplock_handler = handler;
    132 }
Note: See TracChangeset for help on using the changeset viewer.