/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 | } |