Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : client file operations
4 : Copyright (C) Andrew Tridgell 1994-1998
5 : Copyright (C) Jeremy Allison 2001-2002
6 : Copyright (C) James Myers 2003
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "libcli/raw/libcliraw.h"
24 : #include "libcli/raw/raw_proto.h"
25 : #include "librpc/gen_ndr/ndr_security.h"
26 :
27 : #define SETUP_REQUEST(cmd, wct, buflen) do { \
28 : req = smbcli_request_setup(tree, cmd, wct, buflen); \
29 : if (!req) return NULL; \
30 : } while (0)
31 :
32 : /****************************************************************************
33 : Rename a file - async interface
34 : ****************************************************************************/
35 4229 : struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree,
36 : union smb_rename *parms)
37 : {
38 4229 : struct smbcli_request *req = NULL;
39 : struct smb_nttrans nt;
40 : TALLOC_CTX *mem_ctx;
41 :
42 4229 : switch (parms->generic.level) {
43 101 : case RAW_RENAME_RENAME:
44 101 : SETUP_REQUEST(SMBmv, 1, 0);
45 101 : SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib);
46 101 : smbcli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE);
47 101 : smbcli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE);
48 101 : break;
49 :
50 4126 : case RAW_RENAME_NTRENAME:
51 4126 : SETUP_REQUEST(SMBntrename, 4, 0);
52 4126 : SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib);
53 4126 : SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags);
54 4126 : SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size);
55 4126 : smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE);
56 4126 : smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE);
57 4126 : break;
58 :
59 2 : case RAW_RENAME_NTTRANS:
60 :
61 2 : mem_ctx = talloc_new(tree);
62 :
63 2 : nt.in.max_setup = 0;
64 2 : nt.in.max_param = 0;
65 2 : nt.in.max_data = 0;
66 2 : nt.in.setup_count = 0;
67 2 : nt.in.setup = NULL;
68 2 : nt.in.function = NT_TRANSACT_RENAME;
69 2 : nt.in.params = data_blob_talloc(mem_ctx, NULL, 4);
70 2 : nt.in.data = data_blob(NULL, 0);
71 :
72 2 : SSVAL(nt.in.params.data, VWV(0), parms->nttrans.in.file.fnum);
73 2 : SSVAL(nt.in.params.data, VWV(1), parms->nttrans.in.flags);
74 :
75 2 : smbcli_blob_append_string(tree->session, mem_ctx,
76 : &nt.in.params, parms->nttrans.in.new_name,
77 : STR_TERMINATE);
78 :
79 2 : req = smb_raw_nttrans_send(tree, &nt);
80 2 : talloc_free(mem_ctx);
81 2 : return req;
82 : }
83 :
84 4227 : if (!smbcli_request_send(req)) {
85 0 : smbcli_request_destroy(req);
86 0 : return NULL;
87 : }
88 :
89 4227 : return req;
90 : }
91 :
92 : /****************************************************************************
93 : Rename a file - sync interface
94 : ****************************************************************************/
95 4225 : _PUBLIC_ NTSTATUS smb_raw_rename(struct smbcli_tree *tree,
96 : union smb_rename *parms)
97 : {
98 4225 : struct smbcli_request *req = smb_raw_rename_send(tree, parms);
99 4225 : return smbcli_request_simple_recv(req);
100 : }
101 :
102 :
103 : /****************************************************************************
104 : Delete a file - async interface
105 : ****************************************************************************/
106 41048 : struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree,
107 : union smb_unlink *parms)
108 : {
109 : struct smbcli_request *req;
110 :
111 41048 : SETUP_REQUEST(SMBunlink, 1, 0);
112 :
113 41048 : SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib);
114 41048 : smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE);
115 :
116 41048 : if (!smbcli_request_send(req)) {
117 0 : smbcli_request_destroy(req);
118 0 : return NULL;
119 : }
120 41048 : return req;
121 : }
122 :
123 : /*
124 : delete a file - sync interface
125 : */
126 34125 : _PUBLIC_ NTSTATUS smb_raw_unlink(struct smbcli_tree *tree,
127 : union smb_unlink *parms)
128 : {
129 34125 : struct smbcli_request *req = smb_raw_unlink_send(tree, parms);
130 34125 : return smbcli_request_simple_recv(req);
131 : }
132 :
133 :
134 : /****************************************************************************
135 : create a directory using TRANSACT2_MKDIR - async interface
136 : ****************************************************************************/
137 3 : static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree,
138 : union smb_mkdir *parms)
139 : {
140 : struct smb_trans2 t2;
141 3 : uint16_t setup = TRANSACT2_MKDIR;
142 : TALLOC_CTX *mem_ctx;
143 : struct smbcli_request *req;
144 : uint16_t data_total;
145 :
146 3 : mem_ctx = talloc_init("t2mkdir");
147 :
148 3 : data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
149 :
150 3 : t2.in.max_param = 2;
151 3 : t2.in.max_data = 0;
152 3 : t2.in.max_setup = 0;
153 3 : t2.in.flags = 0;
154 3 : t2.in.timeout = 0;
155 3 : t2.in.setup_count = 1;
156 3 : t2.in.setup = &setup;
157 3 : t2.in.params = data_blob_talloc(mem_ctx, NULL, 4);
158 3 : t2.in.data = data_blob_talloc(mem_ctx, NULL, data_total);
159 :
160 3 : SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */
161 :
162 3 : smbcli_blob_append_string(tree->session, mem_ctx,
163 : &t2.in.params, parms->t2mkdir.in.path, STR_TERMINATE);
164 :
165 3 : ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
166 :
167 3 : req = smb_raw_trans2_send(tree, &t2);
168 :
169 3 : talloc_free(mem_ctx);
170 :
171 3 : return req;
172 : }
173 :
174 : /****************************************************************************
175 : Create a directory - async interface
176 : ****************************************************************************/
177 3720 : struct smbcli_request *smb_raw_mkdir_send(struct smbcli_tree *tree,
178 : union smb_mkdir *parms)
179 : {
180 : struct smbcli_request *req;
181 :
182 3720 : if (parms->generic.level == RAW_MKDIR_T2MKDIR) {
183 3 : return smb_raw_t2mkdir_send(tree, parms);
184 : }
185 :
186 3717 : if (parms->generic.level != RAW_MKDIR_MKDIR) {
187 0 : return NULL;
188 : }
189 :
190 3717 : SETUP_REQUEST(SMBmkdir, 0, 0);
191 :
192 3717 : smbcli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE);
193 :
194 3717 : if (!smbcli_request_send(req)) {
195 0 : return NULL;
196 : }
197 :
198 3717 : return req;
199 : }
200 :
201 : /****************************************************************************
202 : Create a directory - sync interface
203 : ****************************************************************************/
204 2595 : _PUBLIC_ NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree,
205 : union smb_mkdir *parms)
206 : {
207 2595 : struct smbcli_request *req = smb_raw_mkdir_send(tree, parms);
208 2595 : return smbcli_request_simple_recv(req);
209 : }
210 :
211 : /****************************************************************************
212 : Remove a directory - async interface
213 : ****************************************************************************/
214 8204 : struct smbcli_request *smb_raw_rmdir_send(struct smbcli_tree *tree,
215 : struct smb_rmdir *parms)
216 : {
217 : struct smbcli_request *req;
218 :
219 8204 : SETUP_REQUEST(SMBrmdir, 0, 0);
220 :
221 8204 : smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
222 :
223 8204 : if (!smbcli_request_send(req)) {
224 0 : smbcli_request_destroy(req);
225 0 : return NULL;
226 : }
227 :
228 8204 : return req;
229 : }
230 :
231 : /****************************************************************************
232 : Remove a directory - sync interface
233 : ****************************************************************************/
234 6974 : _PUBLIC_ NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree,
235 : struct smb_rmdir *parms)
236 : {
237 6974 : struct smbcli_request *req = smb_raw_rmdir_send(tree, parms);
238 6974 : return smbcli_request_simple_recv(req);
239 : }
240 :
241 :
242 : /*
243 : Open a file using TRANSACT2_OPEN - async recv
244 : */
245 60 : static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req,
246 : TALLOC_CTX *mem_ctx,
247 : union smb_open *parms)
248 : {
249 : NTSTATUS status;
250 : struct smb_nttrans nt;
251 : uint8_t *params;
252 :
253 60 : status = smb_raw_nttrans_recv(req, mem_ctx, &nt);
254 60 : if (!NT_STATUS_IS_OK(status)) return status;
255 :
256 60 : if (nt.out.params.length < 69) {
257 0 : return NT_STATUS_INVALID_PARAMETER;
258 : }
259 :
260 60 : params = nt.out.params.data;
261 :
262 60 : parms->ntcreatex.out.oplock_level = CVAL(params, 0);
263 60 : parms->ntcreatex.out.file.fnum = SVAL(params, 2);
264 60 : parms->ntcreatex.out.create_action = IVAL(params, 4);
265 60 : parms->ntcreatex.out.create_time = smbcli_pull_nttime(params, 12);
266 60 : parms->ntcreatex.out.access_time = smbcli_pull_nttime(params, 20);
267 60 : parms->ntcreatex.out.write_time = smbcli_pull_nttime(params, 28);
268 60 : parms->ntcreatex.out.change_time = smbcli_pull_nttime(params, 36);
269 60 : parms->ntcreatex.out.attrib = IVAL(params, 44);
270 60 : parms->ntcreatex.out.alloc_size = BVAL(params, 48);
271 60 : parms->ntcreatex.out.size = BVAL(params, 56);
272 60 : parms->ntcreatex.out.file_type = SVAL(params, 64);
273 60 : parms->ntcreatex.out.ipc_state = SVAL(params, 66);
274 60 : parms->ntcreatex.out.is_directory = CVAL(params, 68);
275 :
276 60 : return NT_STATUS_OK;
277 : }
278 :
279 :
280 : /*
281 : Open a file using NTTRANS CREATE - async send
282 : */
283 85 : static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tree,
284 : union smb_open *parms)
285 : {
286 : struct smb_nttrans nt;
287 : uint8_t *params;
288 85 : TALLOC_CTX *mem_ctx = talloc_new(tree);
289 : uint16_t fname_len;
290 : DATA_BLOB sd_blob, ea_blob;
291 : struct smbcli_request *req;
292 :
293 85 : nt.in.max_setup = 0;
294 85 : nt.in.max_param = 101;
295 85 : nt.in.max_data = 0;
296 85 : nt.in.setup_count = 0;
297 85 : nt.in.function = NT_TRANSACT_CREATE;
298 85 : nt.in.setup = NULL;
299 :
300 85 : sd_blob = data_blob(NULL, 0);
301 85 : ea_blob = data_blob(NULL, 0);
302 :
303 85 : if (parms->ntcreatex.in.sec_desc) {
304 : enum ndr_err_code ndr_err;
305 19 : ndr_err = ndr_push_struct_blob(&sd_blob, mem_ctx,
306 19 : parms->ntcreatex.in.sec_desc,
307 : (ndr_push_flags_fn_t)ndr_push_security_descriptor);
308 19 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
309 0 : talloc_free(mem_ctx);
310 0 : return NULL;
311 : }
312 : }
313 :
314 85 : if (parms->ntcreatex.in.ea_list) {
315 0 : uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas,
316 0 : parms->ntcreatex.in.ea_list->eas, 4);
317 0 : ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
318 0 : if (ea_blob.data == NULL) {
319 0 : return NULL;
320 : }
321 0 : ea_put_list_chained(ea_blob.data,
322 0 : parms->ntcreatex.in.ea_list->num_eas,
323 0 : parms->ntcreatex.in.ea_list->eas, 4);
324 : }
325 :
326 85 : nt.in.params = data_blob_talloc(mem_ctx, NULL, 53);
327 85 : if (nt.in.params.data == NULL) {
328 0 : talloc_free(mem_ctx);
329 0 : return NULL;
330 : }
331 :
332 : /* build the parameter section */
333 85 : params = nt.in.params.data;
334 :
335 85 : SIVAL(params, 0, parms->ntcreatex.in.flags);
336 85 : SIVAL(params, 4, parms->ntcreatex.in.root_fid.fnum);
337 85 : SIVAL(params, 8, parms->ntcreatex.in.access_mask);
338 85 : SBVAL(params, 12, parms->ntcreatex.in.alloc_size);
339 85 : SIVAL(params, 20, parms->ntcreatex.in.file_attr);
340 85 : SIVAL(params, 24, parms->ntcreatex.in.share_access);
341 85 : SIVAL(params, 28, parms->ntcreatex.in.open_disposition);
342 85 : SIVAL(params, 32, parms->ntcreatex.in.create_options);
343 85 : SIVAL(params, 36, sd_blob.length);
344 85 : SIVAL(params, 40, ea_blob.length);
345 85 : SIVAL(params, 48, parms->ntcreatex.in.impersonation);
346 85 : SCVAL(params, 52, parms->ntcreatex.in.security_flags);
347 :
348 : /* the empty string first forces the correct alignment */
349 85 : smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,"", 0);
350 85 : fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,
351 : parms->ntcreatex.in.fname, STR_TERMINATE);
352 :
353 85 : SIVAL(nt.in.params.data, 44, fname_len);
354 :
355 : /* build the data section */
356 85 : nt.in.data = data_blob_talloc(mem_ctx, NULL, sd_blob.length + ea_blob.length);
357 85 : if (sd_blob.length > 0) {
358 19 : memcpy(nt.in.data.data, sd_blob.data, sd_blob.length);
359 : }
360 85 : if (ea_blob.length > 0) {
361 0 : memcpy(nt.in.data.data + sd_blob.length,
362 0 : ea_blob.data,
363 : ea_blob.length);
364 : }
365 :
366 : /* send the request on its way */
367 85 : req = smb_raw_nttrans_send(tree, &nt);
368 :
369 85 : talloc_free(mem_ctx);
370 :
371 85 : return req;
372 : }
373 :
374 :
375 : /****************************************************************************
376 : Open a file using TRANSACT2_OPEN - async send
377 : ****************************************************************************/
378 17 : static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree,
379 : union smb_open *parms)
380 : {
381 : struct smb_trans2 t2;
382 17 : uint16_t setup = TRANSACT2_OPEN;
383 17 : TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open");
384 : struct smbcli_request *req;
385 : uint16_t list_size;
386 :
387 17 : list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas);
388 :
389 17 : t2.in.max_param = 30;
390 17 : t2.in.max_data = 0;
391 17 : t2.in.max_setup = 0;
392 17 : t2.in.flags = 0;
393 17 : t2.in.timeout = 0;
394 17 : t2.in.setup_count = 1;
395 17 : t2.in.setup = &setup;
396 17 : t2.in.params = data_blob_talloc(mem_ctx, NULL, 28);
397 17 : t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size);
398 :
399 17 : SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
400 17 : SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
401 17 : SSVAL(t2.in.params.data, VWV(2), parms->t2open.in.search_attrs);
402 17 : SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
403 17 : raw_push_dos_date(tree->session->transport,
404 : t2.in.params.data, VWV(4), parms->t2open.in.write_time);
405 17 : SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
406 17 : SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
407 17 : SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
408 17 : SIVAL(t2.in.params.data, VWV(11), 0);
409 17 : SSVAL(t2.in.params.data, VWV(13), 0);
410 :
411 17 : smbcli_blob_append_string(tree->session, mem_ctx,
412 : &t2.in.params, parms->t2open.in.fname,
413 : STR_TERMINATE);
414 :
415 17 : ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
416 :
417 17 : req = smb_raw_trans2_send(tree, &t2);
418 :
419 17 : talloc_free(mem_ctx);
420 :
421 17 : return req;
422 : }
423 :
424 :
425 : /****************************************************************************
426 : Open a file using TRANSACT2_OPEN - async recv
427 : ****************************************************************************/
428 11 : static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
429 : {
430 11 : struct smbcli_transport *transport = req->transport;
431 : struct smb_trans2 t2;
432 : NTSTATUS status;
433 :
434 11 : status = smb_raw_trans2_recv(req, mem_ctx, &t2);
435 11 : if (!NT_STATUS_IS_OK(status)) return status;
436 :
437 11 : if (t2.out.params.length < 30) {
438 0 : return NT_STATUS_INFO_LENGTH_MISMATCH;
439 : }
440 :
441 11 : parms->t2open.out.file.fnum = SVAL(t2.out.params.data, VWV(0));
442 11 : parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1));
443 11 : parms->t2open.out.write_time = raw_pull_dos_date3(transport, t2.out.params.data + VWV(2));
444 11 : parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4));
445 11 : parms->t2open.out.access = SVAL(t2.out.params.data, VWV(6));
446 11 : parms->t2open.out.ftype = SVAL(t2.out.params.data, VWV(7));
447 11 : parms->t2open.out.devstate = SVAL(t2.out.params.data, VWV(8));
448 11 : parms->t2open.out.action = SVAL(t2.out.params.data, VWV(9));
449 11 : parms->t2open.out.file_id = SVAL(t2.out.params.data, VWV(10));
450 :
451 11 : return NT_STATUS_OK;
452 : }
453 :
454 : /****************************************************************************
455 : Open a file - async send
456 : ****************************************************************************/
457 77866 : _PUBLIC_ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms)
458 : {
459 : int len;
460 77866 : struct smbcli_request *req = NULL;
461 77866 : bool bigoffset = false;
462 :
463 77866 : switch (parms->generic.level) {
464 17 : case RAW_OPEN_T2OPEN:
465 17 : return smb_raw_t2open_send(tree, parms);
466 :
467 26 : case RAW_OPEN_OPEN:
468 26 : SETUP_REQUEST(SMBopen, 2, 0);
469 26 : SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode);
470 26 : SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
471 26 : smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
472 26 : break;
473 :
474 11016 : case RAW_OPEN_OPENX:
475 11016 : SETUP_REQUEST(SMBopenX, 15, 0);
476 11016 : SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
477 11016 : SSVAL(req->out.vwv, VWV(1), 0);
478 11016 : SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
479 11016 : SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
480 11016 : SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
481 11016 : SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
482 11016 : raw_push_dos_date3(tree->session->transport,
483 : req->out.vwv, VWV(6), parms->openx.in.write_time);
484 11016 : SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
485 11016 : SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
486 11016 : SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
487 11016 : SIVAL(req->out.vwv, VWV(13),0); /* reserved */
488 11016 : smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
489 11016 : break;
490 :
491 4 : case RAW_OPEN_MKNEW:
492 4 : SETUP_REQUEST(SMBmknew, 3, 0);
493 4 : SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
494 4 : raw_push_dos_date3(tree->session->transport,
495 : req->out.vwv, VWV(1), parms->mknew.in.write_time);
496 4 : smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
497 4 : break;
498 :
499 4 : case RAW_OPEN_CREATE:
500 4 : SETUP_REQUEST(SMBcreate, 3, 0);
501 4 : SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib);
502 4 : raw_push_dos_date3(tree->session->transport,
503 : req->out.vwv, VWV(1), parms->create.in.write_time);
504 4 : smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE);
505 4 : break;
506 :
507 4 : case RAW_OPEN_CTEMP:
508 4 : SETUP_REQUEST(SMBctemp, 3, 0);
509 4 : SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
510 4 : raw_push_dos_date3(tree->session->transport,
511 : req->out.vwv, VWV(1), parms->ctemp.in.write_time);
512 4 : smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
513 4 : break;
514 :
515 0 : case RAW_OPEN_SPLOPEN:
516 0 : SETUP_REQUEST(SMBsplopen, 2, 0);
517 0 : SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
518 0 : SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
519 0 : break;
520 :
521 66707 : case RAW_OPEN_NTCREATEX:
522 66707 : SETUP_REQUEST(SMBntcreateX, 24, 0);
523 66707 : SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
524 66707 : SSVAL(req->out.vwv, VWV(1),0);
525 66707 : SCVAL(req->out.vwv, VWV(2),0); /* padding */
526 66707 : SIVAL(req->out.vwv, 7, parms->ntcreatex.in.flags);
527 66707 : SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid.fnum);
528 66707 : SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
529 66707 : SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
530 66707 : SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
531 66707 : SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
532 66707 : SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
533 66707 : SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
534 66707 : SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
535 66707 : SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
536 :
537 66707 : smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
538 66707 : SSVAL(req->out.vwv, 5, len);
539 66707 : break;
540 :
541 85 : case RAW_OPEN_NTTRANS_CREATE:
542 85 : return smb_raw_nttrans_create_send(tree, parms);
543 :
544 :
545 1 : case RAW_OPEN_OPENX_READX:
546 1 : SETUP_REQUEST(SMBopenX, 15, 0);
547 1 : SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
548 1 : SSVAL(req->out.vwv, VWV(1), 0);
549 1 : SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags);
550 1 : SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode);
551 1 : SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs);
552 1 : SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs);
553 1 : raw_push_dos_date3(tree->session->transport,
554 : req->out.vwv, VWV(6), parms->openxreadx.in.write_time);
555 1 : SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func);
556 1 : SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size);
557 1 : SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout);
558 1 : SIVAL(req->out.vwv, VWV(13),0);
559 1 : smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE);
560 :
561 1 : if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
562 1 : bigoffset = true;
563 : }
564 :
565 1 : smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);
566 :
567 1 : SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
568 1 : SSVAL(req->out.vwv, VWV(1), 0);
569 1 : SSVAL(req->out.vwv, VWV(2), 0);
570 1 : SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset);
571 1 : SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF);
572 1 : SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt);
573 1 : SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16);
574 1 : SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining);
575 1 : if (bigoffset) {
576 1 : SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32);
577 : }
578 1 : break;
579 :
580 2 : case RAW_OPEN_NTCREATEX_READX:
581 2 : SETUP_REQUEST(SMBntcreateX, 24, 0);
582 2 : SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
583 2 : SSVAL(req->out.vwv, VWV(1),0);
584 2 : SCVAL(req->out.vwv, VWV(2),0); /* padding */
585 2 : SIVAL(req->out.vwv, 7, parms->ntcreatexreadx.in.flags);
586 2 : SIVAL(req->out.vwv, 11, parms->ntcreatexreadx.in.root_fid.fnum);
587 2 : SIVAL(req->out.vwv, 15, parms->ntcreatexreadx.in.access_mask);
588 2 : SBVAL(req->out.vwv, 19, parms->ntcreatexreadx.in.alloc_size);
589 2 : SIVAL(req->out.vwv, 27, parms->ntcreatexreadx.in.file_attr);
590 2 : SIVAL(req->out.vwv, 31, parms->ntcreatexreadx.in.share_access);
591 2 : SIVAL(req->out.vwv, 35, parms->ntcreatexreadx.in.open_disposition);
592 2 : SIVAL(req->out.vwv, 39, parms->ntcreatexreadx.in.create_options);
593 2 : SIVAL(req->out.vwv, 43, parms->ntcreatexreadx.in.impersonation);
594 2 : SCVAL(req->out.vwv, 47, parms->ntcreatexreadx.in.security_flags);
595 :
596 2 : smbcli_req_append_string_len(req, parms->ntcreatexreadx.in.fname, STR_TERMINATE, &len);
597 2 : SSVAL(req->out.vwv, 5, len);
598 :
599 2 : if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
600 2 : bigoffset = true;
601 : }
602 :
603 2 : smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);
604 :
605 2 : SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
606 2 : SSVAL(req->out.vwv, VWV(1), 0);
607 2 : SSVAL(req->out.vwv, VWV(2), 0);
608 2 : SIVAL(req->out.vwv, VWV(3), parms->ntcreatexreadx.in.offset);
609 2 : SSVAL(req->out.vwv, VWV(5), parms->ntcreatexreadx.in.maxcnt & 0xFFFF);
610 2 : SSVAL(req->out.vwv, VWV(6), parms->ntcreatexreadx.in.mincnt);
611 2 : SIVAL(req->out.vwv, VWV(7), parms->ntcreatexreadx.in.maxcnt >> 16);
612 2 : SSVAL(req->out.vwv, VWV(9), parms->ntcreatexreadx.in.remaining);
613 2 : if (bigoffset) {
614 2 : SIVAL(req->out.vwv, VWV(10),parms->ntcreatexreadx.in.offset>>32);
615 : }
616 2 : break;
617 :
618 0 : case RAW_OPEN_SMB2:
619 0 : return NULL;
620 : }
621 :
622 77764 : if (!smbcli_request_send(req)) {
623 0 : smbcli_request_destroy(req);
624 0 : return NULL;
625 : }
626 :
627 77764 : return req;
628 : }
629 :
630 : /****************************************************************************
631 : Open a file - async recv
632 : ****************************************************************************/
633 77805 : _PUBLIC_ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
634 : {
635 : NTSTATUS status;
636 :
637 155579 : if (!smbcli_request_receive(req) ||
638 77774 : smbcli_request_is_error(req)) {
639 0 : goto failed;
640 : }
641 :
642 73089 : switch (parms->openold.level) {
643 11 : case RAW_OPEN_T2OPEN:
644 11 : return smb_raw_t2open_recv(req, mem_ctx, parms);
645 :
646 8 : case RAW_OPEN_OPEN:
647 8 : SMBCLI_CHECK_WCT(req, 7);
648 8 : parms->openold.out.file.fnum = SVAL(req->in.vwv, VWV(0));
649 8 : parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1));
650 8 : parms->openold.out.write_time = raw_pull_dos_date3(req->transport,
651 8 : req->in.vwv + VWV(2));
652 8 : parms->openold.out.size = IVAL(req->in.vwv, VWV(4));
653 8 : parms->openold.out.rmode = SVAL(req->in.vwv, VWV(6));
654 23 : break;
655 :
656 7770 : case RAW_OPEN_OPENX:
657 7770 : SMBCLI_CHECK_MIN_WCT(req, 15);
658 7770 : parms->openx.out.file.fnum = SVAL(req->in.vwv, VWV(2));
659 7770 : parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3));
660 7777 : parms->openx.out.write_time = raw_pull_dos_date3(req->transport,
661 7770 : req->in.vwv + VWV(4));
662 7770 : parms->openx.out.size = IVAL(req->in.vwv, VWV(6));
663 7770 : parms->openx.out.access = SVAL(req->in.vwv, VWV(8));
664 7770 : parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9));
665 7770 : parms->openx.out.devstate = SVAL(req->in.vwv, VWV(10));
666 7770 : parms->openx.out.action = SVAL(req->in.vwv, VWV(11));
667 7770 : parms->openx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
668 7770 : if (req->in.wct >= 19) {
669 1 : parms->openx.out.access_mask = IVAL(req->in.vwv, VWV(15));
670 1 : parms->openx.out.unknown = IVAL(req->in.vwv, VWV(17));
671 : } else {
672 7769 : parms->openx.out.access_mask = 0;
673 7769 : parms->openx.out.unknown = 0;
674 : }
675 7770 : break;
676 :
677 3 : case RAW_OPEN_MKNEW:
678 3 : SMBCLI_CHECK_WCT(req, 1);
679 3 : parms->mknew.out.file.fnum = SVAL(req->in.vwv, VWV(0));
680 3 : break;
681 :
682 4 : case RAW_OPEN_CREATE:
683 4 : SMBCLI_CHECK_WCT(req, 1);
684 4 : parms->create.out.file.fnum = SVAL(req->in.vwv, VWV(0));
685 4 : break;
686 :
687 4 : case RAW_OPEN_CTEMP:
688 4 : SMBCLI_CHECK_WCT(req, 1);
689 4 : parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0));
690 4 : smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
691 4 : break;
692 :
693 0 : case RAW_OPEN_SPLOPEN:
694 0 : SMBCLI_CHECK_WCT(req, 1);
695 0 : parms->splopen.out.file.fnum = SVAL(req->in.vwv, VWV(0));
696 0 : break;
697 :
698 65227 : case RAW_OPEN_NTCREATEX:
699 65227 : SMBCLI_CHECK_MIN_WCT(req, 34);
700 65227 : parms->ntcreatex.out.oplock_level = CVAL(req->in.vwv, 4);
701 65227 : parms->ntcreatex.out.file.fnum = SVAL(req->in.vwv, 5);
702 65227 : parms->ntcreatex.out.create_action = IVAL(req->in.vwv, 7);
703 65227 : parms->ntcreatex.out.create_time = smbcli_pull_nttime(req->in.vwv, 11);
704 65227 : parms->ntcreatex.out.access_time = smbcli_pull_nttime(req->in.vwv, 19);
705 65227 : parms->ntcreatex.out.write_time = smbcli_pull_nttime(req->in.vwv, 27);
706 65227 : parms->ntcreatex.out.change_time = smbcli_pull_nttime(req->in.vwv, 35);
707 65227 : parms->ntcreatex.out.attrib = IVAL(req->in.vwv, 43);
708 65227 : parms->ntcreatex.out.alloc_size = BVAL(req->in.vwv, 47);
709 65227 : parms->ntcreatex.out.size = BVAL(req->in.vwv, 55);
710 65227 : parms->ntcreatex.out.file_type = SVAL(req->in.vwv, 63);
711 65227 : parms->ntcreatex.out.ipc_state = SVAL(req->in.vwv, 65);
712 65227 : parms->ntcreatex.out.is_directory = CVAL(req->in.vwv, 67);
713 65227 : break;
714 :
715 60 : case RAW_OPEN_NTTRANS_CREATE:
716 60 : return smb_raw_nttrans_create_recv(req, mem_ctx, parms);
717 :
718 1 : case RAW_OPEN_OPENX_READX:
719 1 : SMBCLI_CHECK_MIN_WCT(req, 15);
720 1 : parms->openxreadx.out.file.fnum = SVAL(req->in.vwv, VWV(2));
721 1 : parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3));
722 1 : parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport,
723 1 : req->in.vwv + VWV(4));
724 1 : parms->openxreadx.out.size = IVAL(req->in.vwv, VWV(6));
725 1 : parms->openxreadx.out.access = SVAL(req->in.vwv, VWV(8));
726 1 : parms->openxreadx.out.ftype = SVAL(req->in.vwv, VWV(9));
727 1 : parms->openxreadx.out.devstate = SVAL(req->in.vwv, VWV(10));
728 1 : parms->openxreadx.out.action = SVAL(req->in.vwv, VWV(11));
729 1 : parms->openxreadx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
730 1 : if (req->in.wct >= 19) {
731 0 : parms->openxreadx.out.access_mask = IVAL(req->in.vwv, VWV(15));
732 0 : parms->openxreadx.out.unknown = IVAL(req->in.vwv, VWV(17));
733 : } else {
734 1 : parms->openxreadx.out.access_mask = 0;
735 1 : parms->openxreadx.out.unknown = 0;
736 : }
737 :
738 1 : status = smbcli_chained_advance(req);
739 1 : if (!NT_STATUS_IS_OK(status)) {
740 0 : return status;
741 : }
742 :
743 1 : SMBCLI_CHECK_WCT(req, 12);
744 1 : parms->openxreadx.out.remaining = SVAL(req->in.vwv, VWV(2));
745 1 : parms->openxreadx.out.compaction_mode = SVAL(req->in.vwv, VWV(3));
746 1 : parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5));
747 2 : if (parms->openxreadx.out.nread >
748 2 : MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) ||
749 2 : !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
750 1 : parms->openxreadx.out.nread,
751 : parms->openxreadx.out.data)) {
752 0 : req->status = NT_STATUS_BUFFER_TOO_SMALL;
753 : }
754 1 : break;
755 :
756 1 : case RAW_OPEN_NTCREATEX_READX:
757 1 : SMBCLI_CHECK_MIN_WCT(req, 34);
758 1 : parms->ntcreatexreadx.out.oplock_level = CVAL(req->in.vwv, 4);
759 1 : parms->ntcreatexreadx.out.file.fnum = SVAL(req->in.vwv, 5);
760 1 : parms->ntcreatexreadx.out.create_action = IVAL(req->in.vwv, 7);
761 1 : parms->ntcreatexreadx.out.create_time = smbcli_pull_nttime(req->in.vwv, 11);
762 1 : parms->ntcreatexreadx.out.access_time = smbcli_pull_nttime(req->in.vwv, 19);
763 1 : parms->ntcreatexreadx.out.write_time = smbcli_pull_nttime(req->in.vwv, 27);
764 1 : parms->ntcreatexreadx.out.change_time = smbcli_pull_nttime(req->in.vwv, 35);
765 1 : parms->ntcreatexreadx.out.attrib = IVAL(req->in.vwv, 43);
766 1 : parms->ntcreatexreadx.out.alloc_size = BVAL(req->in.vwv, 47);
767 1 : parms->ntcreatexreadx.out.size = BVAL(req->in.vwv, 55);
768 1 : parms->ntcreatexreadx.out.file_type = SVAL(req->in.vwv, 63);
769 1 : parms->ntcreatexreadx.out.ipc_state = SVAL(req->in.vwv, 65);
770 1 : parms->ntcreatexreadx.out.is_directory = CVAL(req->in.vwv, 67);
771 :
772 1 : status = smbcli_chained_advance(req);
773 1 : if (!NT_STATUS_IS_OK(status)) {
774 0 : return status;
775 : }
776 :
777 1 : SMBCLI_CHECK_WCT(req, 12);
778 1 : parms->ntcreatexreadx.out.remaining = SVAL(req->in.vwv, VWV(2));
779 1 : parms->ntcreatexreadx.out.compaction_mode = SVAL(req->in.vwv, VWV(3));
780 1 : parms->ntcreatexreadx.out.nread = SVAL(req->in.vwv, VWV(5));
781 2 : if (parms->ntcreatexreadx.out.nread >
782 2 : MAX(parms->ntcreatexreadx.in.mincnt, parms->ntcreatexreadx.in.maxcnt) ||
783 2 : !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
784 1 : parms->ntcreatexreadx.out.nread,
785 : parms->ntcreatexreadx.out.data)) {
786 0 : req->status = NT_STATUS_BUFFER_TOO_SMALL;
787 : }
788 1 : break;
789 :
790 0 : case RAW_OPEN_SMB2:
791 0 : req->status = NT_STATUS_INTERNAL_ERROR;
792 0 : break;
793 : }
794 :
795 82450 : failed:
796 77734 : return smbcli_request_destroy(req);
797 : }
798 :
799 :
800 : /****************************************************************************
801 : Open a file - sync interface
802 : ****************************************************************************/
803 64208 : _PUBLIC_ NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms)
804 : {
805 64208 : struct smbcli_request *req = smb_raw_open_send(tree, parms);
806 64208 : return smb_raw_open_recv(req, mem_ctx, parms);
807 : }
808 :
809 :
810 : /****************************************************************************
811 : Close a file - async send
812 : ****************************************************************************/
813 75343 : _PUBLIC_ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms)
814 : {
815 75343 : struct smbcli_request *req = NULL;
816 :
817 75343 : switch (parms->generic.level) {
818 75342 : case RAW_CLOSE_CLOSE:
819 75342 : SETUP_REQUEST(SMBclose, 3, 0);
820 75342 : SSVAL(req->out.vwv, VWV(0), parms->close.in.file.fnum);
821 75342 : raw_push_dos_date3(tree->session->transport,
822 : req->out.vwv, VWV(1), parms->close.in.write_time);
823 75342 : break;
824 :
825 1 : case RAW_CLOSE_SPLCLOSE:
826 1 : SETUP_REQUEST(SMBsplclose, 3, 0);
827 1 : SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum);
828 1 : SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
829 1 : break;
830 :
831 0 : case RAW_CLOSE_SMB2:
832 : case RAW_CLOSE_GENERIC:
833 0 : return NULL;
834 : }
835 :
836 75343 : if (!req) return NULL;
837 :
838 75343 : if (!smbcli_request_send(req)) {
839 0 : smbcli_request_destroy(req);
840 0 : return NULL;
841 : }
842 :
843 75343 : return req;
844 : }
845 :
846 :
847 : /****************************************************************************
848 : Close a file - sync interface
849 : ****************************************************************************/
850 63372 : _PUBLIC_ NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms)
851 : {
852 63372 : struct smbcli_request *req = smb_raw_close_send(tree, parms);
853 63372 : return smbcli_request_simple_recv(req);
854 : }
855 :
856 :
857 : /****************************************************************************
858 : Locking calls - async interface
859 : ****************************************************************************/
860 1073 : struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_lock *parms)
861 : {
862 1073 : struct smbcli_request *req = NULL;
863 :
864 1073 : switch (parms->generic.level) {
865 11 : case RAW_LOCK_LOCK:
866 11 : SETUP_REQUEST(SMBlock, 5, 0);
867 11 : SSVAL(req->out.vwv, VWV(0), parms->lock.in.file.fnum);
868 11 : SIVAL(req->out.vwv, VWV(1), parms->lock.in.count);
869 11 : SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset);
870 11 : break;
871 :
872 11 : case RAW_LOCK_UNLOCK:
873 11 : SETUP_REQUEST(SMBunlock, 5, 0);
874 11 : SSVAL(req->out.vwv, VWV(0), parms->unlock.in.file.fnum);
875 11 : SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count);
876 11 : SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset);
877 11 : break;
878 :
879 1051 : case RAW_LOCK_LOCKX: {
880 : struct smb_lock_entry *lockp;
881 1051 : unsigned int lck_size = (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES)? 20 : 10;
882 1051 : unsigned int lock_count = parms->lockx.in.ulock_cnt + parms->lockx.in.lock_cnt;
883 : int i;
884 :
885 1051 : SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count);
886 1051 : SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
887 1051 : SSVAL(req->out.vwv, VWV(1), 0);
888 1051 : SSVAL(req->out.vwv, VWV(2), parms->lockx.in.file.fnum);
889 1051 : SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode);
890 1051 : SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout);
891 1051 : SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt);
892 1051 : SSVAL(req->out.vwv, VWV(7), parms->lockx.in.lock_cnt);
893 :
894 : /* copy in all the locks */
895 1051 : lockp = &parms->lockx.in.locks[0];
896 2144 : for (i = 0; i < lock_count; i++) {
897 1093 : uint8_t *p = req->out.data + lck_size * i;
898 1093 : SSVAL(p, 0, lockp[i].pid);
899 1093 : if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) {
900 367 : SSVAL(p, 2, 0); /* reserved */
901 367 : SIVAL(p, 4, lockp[i].offset>>32);
902 367 : SIVAL(p, 8, lockp[i].offset);
903 367 : SIVAL(p, 12, lockp[i].count>>32);
904 367 : SIVAL(p, 16, lockp[i].count);
905 : } else {
906 726 : SIVAL(p, 2, lockp[i].offset);
907 726 : SIVAL(p, 6, lockp[i].count);
908 : }
909 : }
910 1051 : break;
911 : }
912 0 : case RAW_LOCK_SMB2:
913 : case RAW_LOCK_SMB2_BREAK:
914 0 : return NULL;
915 : }
916 :
917 1073 : if (!smbcli_request_send(req)) {
918 0 : smbcli_request_destroy(req);
919 0 : return NULL;
920 : }
921 :
922 1073 : return req;
923 : }
924 :
925 : /****************************************************************************
926 : Locking calls - sync interface
927 : ****************************************************************************/
928 839 : _PUBLIC_ NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms)
929 : {
930 839 : struct smbcli_request *req = smb_raw_lock_send(tree, parms);
931 839 : return smbcli_request_simple_recv(req);
932 : }
933 :
934 :
935 : /****************************************************************************
936 : Check for existence of a dir - async send
937 : ****************************************************************************/
938 767 : struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, union smb_chkpath *parms)
939 : {
940 : struct smbcli_request *req;
941 :
942 767 : SETUP_REQUEST(SMBcheckpath, 0, 0);
943 :
944 767 : smbcli_req_append_ascii4(req, parms->chkpath.in.path, STR_TERMINATE);
945 :
946 767 : if (!smbcli_request_send(req)) {
947 0 : smbcli_request_destroy(req);
948 0 : return NULL;
949 : }
950 :
951 767 : return req;
952 : }
953 :
954 : /****************************************************************************
955 : Check for existence of a dir - sync interface
956 : ****************************************************************************/
957 742 : NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms)
958 : {
959 742 : struct smbcli_request *req = smb_raw_chkpath_send(tree, parms);
960 742 : return smbcli_request_simple_recv(req);
961 : }
962 :
963 : /****************************************************************************
964 : flush a file - async send
965 : a flush with RAW_FLUSH_ALL will flush all files
966 : ****************************************************************************/
967 4 : struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms)
968 : {
969 : struct smbcli_request *req;
970 4 : uint16_t fnum=0;
971 :
972 4 : switch (parms->generic.level) {
973 3 : case RAW_FLUSH_FLUSH:
974 3 : fnum = parms->flush.in.file.fnum;
975 3 : break;
976 1 : case RAW_FLUSH_ALL:
977 1 : fnum = 0xFFFF;
978 1 : break;
979 0 : case RAW_FLUSH_SMB2:
980 0 : return NULL;
981 : }
982 :
983 4 : SETUP_REQUEST(SMBflush, 1, 0);
984 4 : SSVAL(req->out.vwv, VWV(0), fnum);
985 :
986 4 : if (!smbcli_request_send(req)) {
987 0 : smbcli_request_destroy(req);
988 0 : return NULL;
989 : }
990 :
991 4 : return req;
992 : }
993 :
994 :
995 : /****************************************************************************
996 : flush a file - sync interface
997 : ****************************************************************************/
998 4 : _PUBLIC_ NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms)
999 : {
1000 4 : struct smbcli_request *req = smb_raw_flush_send(tree, parms);
1001 4 : return smbcli_request_simple_recv(req);
1002 : }
1003 :
1004 :
1005 : /****************************************************************************
1006 : seek a file - async send
1007 : ****************************************************************************/
1008 24 : struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree,
1009 : union smb_seek *parms)
1010 : {
1011 : struct smbcli_request *req;
1012 :
1013 24 : SETUP_REQUEST(SMBlseek, 4, 0);
1014 :
1015 24 : SSVAL(req->out.vwv, VWV(0), parms->lseek.in.file.fnum);
1016 24 : SSVAL(req->out.vwv, VWV(1), parms->lseek.in.mode);
1017 24 : SIVALS(req->out.vwv, VWV(2), parms->lseek.in.offset);
1018 :
1019 24 : if (!smbcli_request_send(req)) {
1020 0 : smbcli_request_destroy(req);
1021 0 : return NULL;
1022 : }
1023 24 : return req;
1024 : }
1025 :
1026 : /****************************************************************************
1027 : seek a file - async receive
1028 : ****************************************************************************/
1029 24 : NTSTATUS smb_raw_seek_recv(struct smbcli_request *req,
1030 : union smb_seek *parms)
1031 : {
1032 48 : if (!smbcli_request_receive(req) ||
1033 24 : smbcli_request_is_error(req)) {
1034 11 : return smbcli_request_destroy(req);
1035 : }
1036 :
1037 13 : SMBCLI_CHECK_WCT(req, 2);
1038 13 : parms->lseek.out.offset = IVAL(req->in.vwv, VWV(0));
1039 :
1040 13 : failed:
1041 13 : return smbcli_request_destroy(req);
1042 : }
1043 :
1044 : /*
1045 : seek a file - sync interface
1046 : */
1047 24 : _PUBLIC_ NTSTATUS smb_raw_seek(struct smbcli_tree *tree,
1048 : union smb_seek *parms)
1049 : {
1050 24 : struct smbcli_request *req = smb_raw_seek_send(tree, parms);
1051 24 : return smb_raw_seek_recv(req, parms);
1052 : }
|