ctdb-build: Apply dependency to correct subsystem
[Samba.git] / libcli / smb / smb1cli_create.c
blobd9887a04cda8eaf6c3bfb4830822134002a6eef9
1 /*
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/>.
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"
27 struct smb1cli_ntcreatex_state {
28 uint16_t vwv[24];
29 uint16_t fnum;
32 static void smb1cli_ntcreatex_done(struct tevent_req *subreq);
34 /**
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,
64 uint32_t pid,
65 struct smbXcli_tcon *tcon,
66 struct smbXcli_session *session,
67 const char *fname,
68 uint32_t CreatFlags,
69 uint32_t RootDirectoryFid,
70 uint32_t DesiredAccess,
71 uint64_t AllocationSize,
72 uint32_t FileAttributes,
73 uint32_t ShareAccess,
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;
81 uint8_t *bytes;
82 size_t converted_len;
84 req = tevent_req_create(mem_ctx, &state, struct smb1cli_ntcreatex_state);
85 if (req == NULL) {
86 return NULL;
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,
107 &converted_len);
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,
119 0, 0, /* *_flags */
120 0, 0, /* *_flags2 */
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);
129 return 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;
139 uint8_t wct;
140 uint16_t *vwv;
141 NTSTATUS status;
142 static const struct smb1cli_req_expected_response expected[] = {
144 .status = NT_STATUS_OK,
145 .wct = 0x22
149 * This is the broken version see from
150 * [MS-SMB]:
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,
157 .wct = 0x2a
160 .status = NT_STATUS_OK,
161 .wct = 0x32
165 status = smb1cli_req_recv(subreq, state,
166 &recv_iov,
167 NULL, /* phdr */
168 &wct,
169 &vwv,
170 NULL, /* pvwv_offset */
171 NULL, /* num_bytes */
172 NULL, /* bytes */
173 NULL, /* pbytes_offset */
174 NULL, /* inbuf */
175 expected, ARRAY_SIZE(expected));
176 TALLOC_FREE(subreq);
177 if (tevent_req_nterror(req, status)) {
178 return;
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);
198 NTSTATUS status;
200 if (tevent_req_is_nterror(req, &status)) {
201 tevent_req_received(req);
202 return status;
205 *pfnum = state->fnum;
206 tevent_req_received(req);
207 return NT_STATUS_OK;
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,
238 uint32_t pid,
239 struct smbXcli_tcon *tcon,
240 struct smbXcli_session *session,
241 const char *fname,
242 uint32_t CreatFlags,
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,
252 uint16_t *pfnum)
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;
266 goto fail;
269 ev = samba_tevent_context_init(frame);
270 if (ev == NULL) {
271 status = NT_STATUS_NO_MEMORY;
272 goto fail;
275 req = smb1cli_ntcreatex_send(frame, ev, conn,
276 timeout_msec,
277 pid, tcon, session,
278 fname, CreatFlags, RootDirectoryFid,
279 DesiredAccess, AllocationSize,
280 FileAttributes, ShareAccess,
281 CreateDisposition, CreateOptions,
282 ImpersonationLevel, SecurityFlags);
283 if (req == NULL) {
284 status = NT_STATUS_NO_MEMORY;
285 goto fail;
288 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
289 goto fail;
292 status = smb1cli_ntcreatex_recv(req, pfnum);
293 fail:
294 TALLOC_FREE(frame);
295 return status;