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