2 Unix SMB/CIFS implementation.
4 Copyright (C) Gregor Beck 2013
5 Copyright (C) Stefan Metzmacher 2013
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.
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.
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/>.
22 #include "system/network.h"
23 #include "lib/util/tevent_ntstatus.h"
24 #include "smb_common.h"
25 #include "smbXcli_base.h"
27 struct smb1cli_ntcreatex_state
{
32 static void smb1cli_ntcreatex_done(struct tevent_req
*subreq
);
35 * Send an asynchronous SMB_COM_NT_CREATE_ANDX request.
36 * <a href="http://msdn.microsoft.com/en-us/library/ee442175.aspx">MS-CIFS 2.2.4.64.1</a>
37 * @see smb1cli_ntcreatex_recv(), smb1cli_ntcreatex()
39 * @param[in] mem_ctx The memory context for the result.
40 * @param[in] ev The event context to work on.
41 * @param[in] conn The smb connection.
42 * @param[in] timeout_msec If positiv a timeout for the request.
43 * @param[in] pid The process identifier
44 * @param[in] tcon The smb tree connect.
45 * @param[in] session The smb session.
46 * @param[in] fname The name of the file or directory to be opened or created.
47 * @param[in] CreatFlags
48 * @param[in] RootDirectoryFid The file id of an opened root directory fname is based on. 0 means root of the share.
49 * @param[in] DesiredAccess A field of flags that indicate standard, specific, and generic access rights to be requested.
50 * @param[in] AllocationSize Number of Bytes to allocate if the file is to be created or overwritten.
51 * @param[in] FileAttributes <a href="http://msdn.microsoft.com/en-us/library/ee878573.aspx">Extended file attributes</a>
52 * @param[in] ShareAccess A field that specifies how the file should be shared with other processes.
53 * @param[in] CreateDisposition A value that represents the action to take if the file already exists or if the file is a new file and does not already exist.
54 * @param[in] CreateOptions A field of flag options to use if creating a file or directory.
55 * @param[in] ImpersonationLevel
56 * @param[in] SecurityFlags
58 * @return a tevent_req or NULL
60 struct tevent_req
*smb1cli_ntcreatex_send(TALLOC_CTX
*mem_ctx
,
61 struct tevent_context
*ev
,
62 struct smbXcli_conn
*conn
,
63 uint32_t timeout_msec
,
65 struct smbXcli_tcon
*tcon
,
66 struct smbXcli_session
*session
,
69 uint32_t RootDirectoryFid
,
70 uint32_t DesiredAccess
,
71 uint64_t AllocationSize
,
72 uint32_t FileAttributes
,
74 uint32_t CreateDisposition
,
75 uint32_t CreateOptions
,
76 uint32_t ImpersonationLevel
,
77 uint8_t SecurityFlags
)
79 struct tevent_req
*req
, *subreq
;
80 struct smb1cli_ntcreatex_state
*state
;
84 req
= tevent_req_create(mem_ctx
, &state
, struct smb1cli_ntcreatex_state
);
89 SCVAL(state
->vwv
+0, 0, 0xFF);
90 SCVAL(state
->vwv
+0, 1, 0);
91 SSVAL(state
->vwv
+1, 0, 0);
92 SCVAL(state
->vwv
+2, 0, 0);
93 SIVAL(state
->vwv
+3, 1, CreatFlags
);
94 SIVAL(state
->vwv
+5, 1, RootDirectoryFid
);
95 SIVAL(state
->vwv
+7, 1, DesiredAccess
);
96 SBVAL(state
->vwv
+9, 1, AllocationSize
);
97 SIVAL(state
->vwv
+13, 1, FileAttributes
);
98 SIVAL(state
->vwv
+15, 1, ShareAccess
);
99 SIVAL(state
->vwv
+17, 1, CreateDisposition
);
100 SIVAL(state
->vwv
+19, 1, CreateOptions
);
101 SIVAL(state
->vwv
+21, 1, ImpersonationLevel
);
102 SCVAL(state
->vwv
+23, 1, SecurityFlags
);
104 bytes
= talloc_array(state
, uint8_t, 0);
105 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(conn
),
106 fname
, strlen(fname
)+1,
109 /* sigh. this copes with broken netapp filer behaviour */
110 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(conn
), "", 1, NULL
);
112 if (tevent_req_nomem(bytes
, req
)) {
113 return tevent_req_post(req
, ev
);
116 SSVAL(state
->vwv
+2, 1, converted_len
);
118 subreq
= smb1cli_req_send(state
, ev
, conn
, SMBntcreateX
,
121 timeout_msec
, pid
, tcon
, session
,
122 ARRAY_SIZE(state
->vwv
), state
->vwv
,
123 talloc_get_size(bytes
), bytes
);
124 if (tevent_req_nomem(subreq
, req
)) {
125 return tevent_req_post(req
, ev
);
127 tevent_req_set_callback(subreq
, smb1cli_ntcreatex_done
, req
);
132 static void smb1cli_ntcreatex_done(struct tevent_req
*subreq
)
134 struct tevent_req
*req
= tevent_req_callback_data(
135 subreq
, struct tevent_req
);
136 struct smb1cli_ntcreatex_state
*state
= tevent_req_data(
137 req
, struct smb1cli_ntcreatex_state
);
138 struct iovec
*recv_iov
= NULL
;
142 static const struct smb1cli_req_expected_response expected
[] = {
144 .status
= NT_STATUS_OK
,
149 * This is the broken version see from
151 * Windows-based SMB servers send 50 (0x32) words in the extended
152 * response although they set the WordCount field to 0x2A.
154 * And Samba does the same...
156 .status
= NT_STATUS_OK
,
160 .status
= NT_STATUS_OK
,
165 status
= smb1cli_req_recv(subreq
, state
,
170 NULL
, /* pvwv_offset */
171 NULL
, /* num_bytes */
173 NULL
, /* pbytes_offset */
175 expected
, ARRAY_SIZE(expected
));
177 if (tevent_req_nterror(req
, status
)) {
181 state
->fnum
= SVAL(vwv
+2, 1);
182 tevent_req_done(req
);
186 * Receive the response to an asynchronous SMB_COM_NT_CREATE_ANDX request.
187 * <a href="http://msdn.microsoft.com/en-us/library/ee441612.aspx">MS-CIFS 2.2.4.64.2</a>
189 * @param[in] req A tevent request created with smb1cli_ntcreatex_send()
190 * @param[out] pfnum The file id of the opened file or directory.
192 * @return NT_STATUS_OK on succsess
194 NTSTATUS
smb1cli_ntcreatex_recv(struct tevent_req
*req
, uint16_t *pfnum
)
196 struct smb1cli_ntcreatex_state
*state
= tevent_req_data(
197 req
, struct smb1cli_ntcreatex_state
);
200 if (tevent_req_is_nterror(req
, &status
)) {
201 tevent_req_received(req
);
205 *pfnum
= state
->fnum
;
206 tevent_req_received(req
);
212 * Send a synchronous SMB_COM_NT_CREATE_ANDX request.
213 * <a href="http://msdn.microsoft.com/en-us/library/ee442091.aspx">MS-CIFS 2.2.4.64</a>
214 * @see smb1cli_ntcreatex_send() smb1cli_ntcreatex_recv()
216 * @param[in] conn The smb connection.
217 * @param[in] timeout_msec If positiv a timeout for the request.
218 * @param[in] pid The process identifier
219 * @param[in] tcon The smb tree connect.
220 * @param[in] session The smb session.
221 * @param[in] fname The name of the file or directory to be opened or created.
222 * @param[in] CreatFlags
223 * @param[in] RootDirectoryFid The file id of an opened root directory fname is based on. 0 means root of the share.
224 * @param[in] DesiredAccess A field of flags that indicate standard, specific, and generic access rights to be requested.
225 * @param[in] AllocationSize Number of Bytes to allocate if the file is to be created or overwritten.
226 * @param[in] FileAttributes <a href="http://msdn.microsoft.com/en-us/library/ee878573.aspx">Extended file attributes</a>
227 * @param[in] ShareAccess A field that specifies how the file should be shared with other processes.
228 * @param[in] CreateDisposition A value that represents the action to take if the file already exists or if the file is a new file and does not already exist.
229 * @param[in] CreateOptions A field of flag options to use if creating a file or directory.
230 * @param[in] ImpersonationLevel
231 * @param[in] SecurityFlags
232 * @param[out] pfnum The file id representing the file or directory created or opened.
234 * @return NT_STATUS_OK on succsess
236 NTSTATUS
smb1cli_ntcreatex(struct smbXcli_conn
*conn
,
237 uint32_t timeout_msec
,
239 struct smbXcli_tcon
*tcon
,
240 struct smbXcli_session
*session
,
243 uint32_t RootDirectoryFid
,
244 uint32_t DesiredAccess
,
245 uint64_t AllocationSize
,
246 uint32_t FileAttributes
,
247 uint32_t ShareAccess
,
248 uint32_t CreateDisposition
,
249 uint32_t CreateOptions
,
250 uint32_t ImpersonationLevel
,
251 uint8_t SecurityFlags
,
254 TALLOC_CTX
*frame
= NULL
;
255 struct tevent_context
*ev
;
256 struct tevent_req
*req
;
257 NTSTATUS status
= NT_STATUS_OK
;
259 frame
= talloc_stackframe();
261 if (smbXcli_conn_has_async_calls(conn
)) {
263 * Can't use sync call while an async call is in flight
265 status
= NT_STATUS_INVALID_PARAMETER
;
269 ev
= samba_tevent_context_init(frame
);
271 status
= NT_STATUS_NO_MEMORY
;
275 req
= smb1cli_ntcreatex_send(frame
, ev
, conn
,
278 fname
, CreatFlags
, RootDirectoryFid
,
279 DesiredAccess
, AllocationSize
,
280 FileAttributes
, ShareAccess
,
281 CreateDisposition
, CreateOptions
,
282 ImpersonationLevel
, SecurityFlags
);
284 status
= NT_STATUS_NO_MEMORY
;
288 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
292 status
= smb1cli_ntcreatex_recv(req
, pfnum
);