Coverage Report

Created: 2026-05-24 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/smb/smb1cli_close.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
4
   Copyright (C) Gregor Beck 2013
5
   Copyright (C) Stefan Metzmacher 2013
6
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20
21
#include "includes.h"
22
#include "system/network.h"
23
#include "lib/util/tevent_ntstatus.h"
24
#include "smb_common.h"
25
#include "smbXcli_base.h"
26
27
struct smb1cli_close_state {
28
  uint16_t vwv[3];
29
};
30
31
static void smb1cli_close_done(struct tevent_req *subreq);
32
33
/**
34
 * Send an asynchronous SMB_COM_CLOSE request.
35
 * <a href="http://msdn.microsoft.com/en-us/library/ee442151.aspx">MS-CIFS 2.2.4.5.1</a>
36
 * @see smb1cli_close_recv(), smb1cli_close()
37
 *
38
 * @param[in] mem_ctx  The memory context for the result.
39
 * @param[in] ev The event context to work on.
40
 * @param[in] conn The smb connection.
41
 * @param[in] timeout_msec If positive a timeout for the request.
42
 * @param[in] pid The process identifier.
43
 * @param[in] tcon The smb tree connect.
44
 * @param[in] session The smb session.
45
 * @param[in] fnum The file id of the file to be closed.
46
 * @param[in] last_modified If not 0 or 0xFFFFFFFF request to set modification time to this number of seconds since January 1, 1970.
47
 *
48
 * @return a tevent_req or NULL.
49
 */
50
struct tevent_req *smb1cli_close_send(TALLOC_CTX *mem_ctx,
51
              struct tevent_context *ev,
52
              struct smbXcli_conn *conn,
53
              uint32_t timeout_msec,
54
              uint32_t pid,
55
              struct smbXcli_tcon *tcon,
56
              struct smbXcli_session *session,
57
              uint16_t fnum,
58
              uint32_t last_modified)
59
0
{
60
0
  struct tevent_req *req, *subreq;
61
0
  struct smb1cli_close_state *state;
62
63
0
  req = tevent_req_create(mem_ctx, &state, struct smb1cli_close_state);
64
0
  if (req == NULL) {
65
0
    return NULL;
66
0
  }
67
68
0
  SSVAL(state->vwv+0, 0, fnum);
69
0
  SIVALS(state->vwv+1, 0, last_modified);
70
71
0
  subreq = smb1cli_req_send(state, ev, conn, SMBclose,
72
0
          0, 0, /* *_flags */
73
0
          0, 0, /* *_flags2 */
74
0
          timeout_msec, pid, tcon, session,
75
0
          ARRAY_SIZE(state->vwv), state->vwv,
76
0
          0, NULL);
77
0
  if (tevent_req_nomem(subreq, req)) {
78
0
    return tevent_req_post(req, ev);
79
0
  }
80
0
  tevent_req_set_callback(subreq, smb1cli_close_done, req);
81
0
  return req;
82
0
}
83
84
static void smb1cli_close_done(struct tevent_req *subreq)
85
0
{
86
0
  struct tevent_req *req = tevent_req_callback_data(
87
0
    subreq, struct tevent_req);
88
0
  struct smb1cli_close_state *state = tevent_req_data(
89
0
    req, struct smb1cli_close_state);
90
0
  NTSTATUS status;
91
0
  static const struct smb1cli_req_expected_response expected[] = {
92
0
  {
93
0
    .status = NT_STATUS_OK,
94
0
    .wct = 0x00
95
0
  },
96
0
  };
97
98
0
  status = smb1cli_req_recv(subreq, state,
99
0
          NULL, /* recv_iov */
100
0
          NULL, /* phdr */
101
0
          NULL, /* wct */
102
0
          NULL, /* vwv */
103
0
          NULL, /* pvwv_offset */
104
0
          NULL, /* num_bytes */
105
0
          NULL, /* bytes */
106
0
          NULL, /* pbytes_offset */
107
0
          NULL, /* inbuf */
108
0
          expected, ARRAY_SIZE(expected));
109
0
  TALLOC_FREE(subreq);
110
0
  if (tevent_req_nterror(req, status)) {
111
0
    return;
112
0
  }
113
114
0
  tevent_req_done(req);
115
0
}
116
117
/**
118
 * Receive the response to an asynchronous SMB_COM_CLOSE request.
119
 * <a href="http://msdn.microsoft.com/en-us/library/ee441667.aspx">MS-CIFS 2.2.4.5.2</a>
120
 *
121
 * @param req A tevent_req created with smb1cli_close_send()
122
 *
123
 * @return NT_STATUS_OK on success
124
 */
125
NTSTATUS smb1cli_close_recv(struct tevent_req *req)
126
0
{
127
0
  return tevent_req_simple_recv_ntstatus(req);
128
0
}
129
130
/**
131
 * Send an synchronous SMB_COM_CLOSE request.
132
 * <a href="http://msdn.microsoft.com/en-us/library/ee441493.aspx">MS-CIFS 2.2.4.5</a>
133
 * @see smb1cli_close_send(), smb1cli_close_recv()
134
 *
135
 * @param[in] conn The smb connection.
136
 * @param[in] timeout_msec If positive a timeout for the request.
137
 * @param[in] pid The process identifier.
138
 * @param[in] tcon The smb tree connect.
139
 * @param[in] session The smb session.
140
 * @param[in] fnum The file id of the file to be closed.
141
 * @param[in] last_modified If not 0 or 0xFFFFFFFF request to set modification time to this number of seconds since J
142
 *
143
 * @return NT_STATUS_OK on success.
144
 */
145
NTSTATUS smb1cli_close(struct smbXcli_conn *conn,
146
           uint32_t timeout_msec,
147
           uint32_t pid,
148
           struct smbXcli_tcon *tcon,
149
           struct smbXcli_session *session,
150
           uint16_t fnum,
151
           uint32_t last_modified)
152
0
{
153
0
  NTSTATUS status = NT_STATUS_OK;
154
0
  struct tevent_req *req;
155
0
  TALLOC_CTX *frame = talloc_stackframe();
156
0
  struct tevent_context *ev;
157
158
0
  if (smbXcli_conn_has_async_calls(conn)) {
159
    /*
160
     * Can't use sync call while an async call is in flight
161
     */
162
0
    status = NT_STATUS_INVALID_PARAMETER;
163
0
    goto done;
164
0
  }
165
166
0
  ev = samba_tevent_context_init(frame);
167
0
  if (ev == NULL) {
168
0
    status = NT_STATUS_NO_MEMORY;
169
0
    goto done;
170
0
  }
171
172
0
  req = smb1cli_close_send(frame, ev, conn,
173
0
         timeout_msec, pid, tcon, session,
174
0
         fnum, last_modified);
175
0
  if (req == NULL) {
176
0
    status = NT_STATUS_NO_MEMORY;
177
0
    goto done;
178
0
  }
179
180
0
  if (!tevent_req_poll_ntstatus(req, ev, &status)) {
181
0
    goto done;
182
0
  }
183
184
0
  status = smb1cli_close_recv(req);
185
0
done:
186
  talloc_free(frame);
187
0
  return status;
188
0
}