2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2001-2002
6 Copyright (C) James Myers 2003
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/raw/libcliraw.h"
25 #include "librpc/gen_ndr/ndr_security.h"
27 #define SETUP_REQUEST(cmd, wct, buflen) do { \
28 req = smbcli_request_setup(tree, cmd, wct, buflen); \
29 if (!req) return NULL; \
33 /****************************************************************************
34 Rename a file - async interface
35 ****************************************************************************/
36 struct smbcli_request
*smb_raw_rename_send(struct smbcli_tree
*tree
,
37 union smb_rename
*parms
)
39 struct smbcli_request
*req
= NULL
;
41 switch (parms
->generic
.level
) {
42 case RAW_RENAME_RENAME
:
43 SETUP_REQUEST(SMBmv
, 1, 0);
44 SSVAL(req
->out
.vwv
, VWV(0), parms
->rename
.in
.attrib
);
45 smbcli_req_append_ascii4(req
, parms
->rename
.in
.pattern1
, STR_TERMINATE
);
46 smbcli_req_append_ascii4(req
, parms
->rename
.in
.pattern2
, STR_TERMINATE
);
49 case RAW_RENAME_NTRENAME
:
50 SETUP_REQUEST(SMBntrename
, 4, 0);
51 SSVAL(req
->out
.vwv
, VWV(0), parms
->ntrename
.in
.attrib
);
52 SSVAL(req
->out
.vwv
, VWV(1), parms
->ntrename
.in
.flags
);
53 SIVAL(req
->out
.vwv
, VWV(2), parms
->ntrename
.in
.cluster_size
);
54 smbcli_req_append_ascii4(req
, parms
->ntrename
.in
.old_name
, STR_TERMINATE
);
55 smbcli_req_append_ascii4(req
, parms
->ntrename
.in
.new_name
, STR_TERMINATE
);
59 if (!smbcli_request_send(req
)) {
60 smbcli_request_destroy(req
);
67 /****************************************************************************
68 Rename a file - sync interface
69 ****************************************************************************/
70 NTSTATUS
smb_raw_rename(struct smbcli_tree
*tree
,
71 union smb_rename
*parms
)
73 struct smbcli_request
*req
= smb_raw_rename_send(tree
, parms
);
74 return smbcli_request_simple_recv(req
);
78 /****************************************************************************
79 Delete a file - async interface
80 ****************************************************************************/
81 struct smbcli_request
*smb_raw_unlink_send(struct smbcli_tree
*tree
,
82 struct smb_unlink
*parms
)
84 struct smbcli_request
*req
;
86 SETUP_REQUEST(SMBunlink
, 1, 0);
88 SSVAL(req
->out
.vwv
, VWV(0), parms
->in
.attrib
);
89 smbcli_req_append_ascii4(req
, parms
->in
.pattern
, STR_TERMINATE
);
91 if (!smbcli_request_send(req
)) {
92 smbcli_request_destroy(req
);
99 delete a file - sync interface
101 NTSTATUS
smb_raw_unlink(struct smbcli_tree
*tree
,
102 struct smb_unlink
*parms
)
104 struct smbcli_request
*req
= smb_raw_unlink_send(tree
, parms
);
105 return smbcli_request_simple_recv(req
);
109 /****************************************************************************
110 create a directory using TRANSACT2_MKDIR - async interface
111 ****************************************************************************/
112 static struct smbcli_request
*smb_raw_t2mkdir_send(struct smbcli_tree
*tree
,
113 union smb_mkdir
*parms
)
115 struct smb_trans2 t2
;
116 uint16_t setup
= TRANSACT2_MKDIR
;
118 struct smbcli_request
*req
;
121 mem_ctx
= talloc_init("t2mkdir");
123 data_total
= ea_list_size(parms
->t2mkdir
.in
.num_eas
, parms
->t2mkdir
.in
.eas
);
130 t2
.in
.setup_count
= 1;
131 t2
.in
.setup
= &setup
;
132 t2
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 4);
133 t2
.in
.data
= data_blob_talloc(mem_ctx
, NULL
, data_total
);
135 SIVAL(t2
.in
.params
.data
, VWV(0), 0); /* reserved */
137 smbcli_blob_append_string(tree
->session
, mem_ctx
,
138 &t2
.in
.params
, parms
->t2mkdir
.in
.path
, 0);
140 ea_put_list(t2
.in
.data
.data
, parms
->t2mkdir
.in
.num_eas
, parms
->t2mkdir
.in
.eas
);
142 req
= smb_raw_trans2_send(tree
, &t2
);
144 talloc_destroy(mem_ctx
);
149 /****************************************************************************
150 Create a directory - async interface
151 ****************************************************************************/
152 struct smbcli_request
*smb_raw_mkdir_send(struct smbcli_tree
*tree
,
153 union smb_mkdir
*parms
)
155 struct smbcli_request
*req
;
157 if (parms
->generic
.level
== RAW_MKDIR_T2MKDIR
) {
158 return smb_raw_t2mkdir_send(tree
, parms
);
161 if (parms
->generic
.level
!= RAW_MKDIR_MKDIR
) {
165 SETUP_REQUEST(SMBmkdir
, 0, 0);
167 smbcli_req_append_ascii4(req
, parms
->mkdir
.in
.path
, STR_TERMINATE
);
169 if (!smbcli_request_send(req
)) {
176 /****************************************************************************
177 Create a directory - sync interface
178 ****************************************************************************/
179 NTSTATUS
smb_raw_mkdir(struct smbcli_tree
*tree
,
180 union smb_mkdir
*parms
)
182 struct smbcli_request
*req
= smb_raw_mkdir_send(tree
, parms
);
183 return smbcli_request_simple_recv(req
);
186 /****************************************************************************
187 Remove a directory - async interface
188 ****************************************************************************/
189 struct smbcli_request
*smb_raw_rmdir_send(struct smbcli_tree
*tree
,
190 struct smb_rmdir
*parms
)
192 struct smbcli_request
*req
;
194 SETUP_REQUEST(SMBrmdir
, 0, 0);
196 smbcli_req_append_ascii4(req
, parms
->in
.path
, STR_TERMINATE
);
198 if (!smbcli_request_send(req
)) {
199 smbcli_request_destroy(req
);
206 /****************************************************************************
207 Remove a directory - sync interface
208 ****************************************************************************/
209 NTSTATUS
smb_raw_rmdir(struct smbcli_tree
*tree
,
210 struct smb_rmdir
*parms
)
212 struct smbcli_request
*req
= smb_raw_rmdir_send(tree
, parms
);
213 return smbcli_request_simple_recv(req
);
218 Open a file using TRANSACT2_OPEN - async recv
220 static NTSTATUS
smb_raw_nttrans_create_recv(struct smbcli_request
*req
,
222 union smb_open
*parms
)
225 struct smb_nttrans nt
;
228 status
= smb_raw_nttrans_recv(req
, mem_ctx
, &nt
);
229 if (!NT_STATUS_IS_OK(status
)) return status
;
231 if (nt
.out
.params
.length
< 69) {
232 return NT_STATUS_INVALID_PARAMETER
;
235 params
= nt
.out
.params
.data
;
237 parms
->ntcreatex
.out
.oplock_level
= CVAL(params
, 0);
238 parms
->ntcreatex
.out
.fnum
= SVAL(params
, 2);
239 parms
->ntcreatex
.out
.create_action
= IVAL(params
, 4);
240 parms
->ntcreatex
.out
.create_time
= smbcli_pull_nttime(params
, 12);
241 parms
->ntcreatex
.out
.access_time
= smbcli_pull_nttime(params
, 20);
242 parms
->ntcreatex
.out
.write_time
= smbcli_pull_nttime(params
, 28);
243 parms
->ntcreatex
.out
.change_time
= smbcli_pull_nttime(params
, 36);
244 parms
->ntcreatex
.out
.attrib
= IVAL(params
, 44);
245 parms
->ntcreatex
.out
.alloc_size
= BVAL(params
, 48);
246 parms
->ntcreatex
.out
.size
= BVAL(params
, 56);
247 parms
->ntcreatex
.out
.file_type
= SVAL(params
, 64);
248 parms
->ntcreatex
.out
.ipc_state
= SVAL(params
, 66);
249 parms
->ntcreatex
.out
.is_directory
= CVAL(params
, 68);
256 Open a file using NTTRANS CREATE - async send
258 static struct smbcli_request
*smb_raw_nttrans_create_send(struct smbcli_tree
*tree
,
259 union smb_open
*parms
)
261 struct smb_nttrans nt
;
263 TALLOC_CTX
*mem_ctx
= talloc(tree
, 0);
265 DATA_BLOB sd_blob
, ea_blob
;
266 struct smbcli_request
*req
;
270 nt
.in
.max_param
= 101;
272 nt
.in
.setup_count
= 0;
273 nt
.in
.function
= NT_TRANSACT_CREATE
;
276 sd_blob
= data_blob(NULL
, 0);
277 ea_blob
= data_blob(NULL
, 0);
279 if (parms
->ntcreatex
.in
.sec_desc
) {
280 status
= ndr_push_struct_blob(&sd_blob
, mem_ctx
,
281 parms
->ntcreatex
.in
.sec_desc
,
282 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
283 if (!NT_STATUS_IS_OK(status
)) {
284 talloc_free(mem_ctx
);
289 if (parms
->ntcreatex
.in
.ea_list
) {
290 uint32_t ea_size
= ea_list_size(parms
->ntcreatex
.in
.ea_list
->num_eas
,
291 parms
->ntcreatex
.in
.ea_list
->eas
);
292 ea_blob
= data_blob_talloc(mem_ctx
, NULL
, ea_size
);
293 if (ea_blob
.data
== NULL
) {
296 ea_put_list(ea_blob
.data
,
297 parms
->ntcreatex
.in
.ea_list
->num_eas
,
298 parms
->ntcreatex
.in
.ea_list
->eas
);
301 nt
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 54);
302 if (nt
.in
.params
.data
== NULL
) {
303 talloc_free(mem_ctx
);
307 /* build the parameter section */
308 params
= nt
.in
.params
.data
;
310 SIVAL(params
, 0, parms
->ntcreatex
.in
.flags
);
311 SIVAL(params
, 4, parms
->ntcreatex
.in
.root_fid
);
312 SIVAL(params
, 8, parms
->ntcreatex
.in
.access_mask
);
313 SBVAL(params
, 12, parms
->ntcreatex
.in
.alloc_size
);
314 SIVAL(params
, 20, parms
->ntcreatex
.in
.file_attr
);
315 SIVAL(params
, 24, parms
->ntcreatex
.in
.share_access
);
316 SIVAL(params
, 28, parms
->ntcreatex
.in
.open_disposition
);
317 SIVAL(params
, 32, parms
->ntcreatex
.in
.create_options
);
318 SIVAL(params
, 36, sd_blob
.length
);
319 SIVAL(params
, 40, ea_blob
.length
);
320 SIVAL(params
, 48, parms
->ntcreatex
.in
.impersonation
);
321 SCVAL(params
, 52, parms
->ntcreatex
.in
.security_flags
);
322 SCVAL(params
, 53, 0);
324 fname_len
= smbcli_blob_append_string(tree
->session
, mem_ctx
, &nt
.in
.params
,
325 parms
->ntcreatex
.in
.fname
, STR_TERMINATE
);
327 SIVAL(nt
.in
.params
.data
, 44, fname_len
);
329 /* build the data section */
330 nt
.in
.data
= data_blob_talloc(mem_ctx
, NULL
, sd_blob
.length
+ ea_blob
.length
);
331 memcpy(nt
.in
.data
.data
, sd_blob
.data
, sd_blob
.length
);
332 memcpy(nt
.in
.data
.data
+sd_blob
.length
, ea_blob
.data
, ea_blob
.length
);
334 /* send the request on its way */
335 req
= smb_raw_nttrans_send(tree
, &nt
);
337 talloc_free(mem_ctx
);
343 /****************************************************************************
344 Open a file using TRANSACT2_OPEN - async send
345 ****************************************************************************/
346 static struct smbcli_request
*smb_raw_t2open_send(struct smbcli_tree
*tree
,
347 union smb_open
*parms
)
349 struct smb_trans2 t2
;
350 uint16_t setup
= TRANSACT2_OPEN
;
351 TALLOC_CTX
*mem_ctx
= talloc_init("smb_raw_t2open");
352 struct smbcli_request
*req
;
355 list_size
= ea_list_size(parms
->t2open
.in
.num_eas
, parms
->t2open
.in
.eas
);
357 t2
.in
.max_param
= 30;
362 t2
.in
.setup_count
= 1;
363 t2
.in
.setup
= &setup
;
364 t2
.in
.params
= data_blob_talloc(mem_ctx
, NULL
, 28);
365 t2
.in
.data
= data_blob_talloc(mem_ctx
, NULL
, list_size
);
367 SSVAL(t2
.in
.params
.data
, VWV(0), parms
->t2open
.in
.flags
);
368 SSVAL(t2
.in
.params
.data
, VWV(1), parms
->t2open
.in
.open_mode
);
369 SSVAL(t2
.in
.params
.data
, VWV(2), 0); /* reserved */
370 SSVAL(t2
.in
.params
.data
, VWV(3), parms
->t2open
.in
.file_attrs
);
371 raw_push_dos_date(tree
->session
->transport
,
372 t2
.in
.params
.data
, VWV(4), parms
->t2open
.in
.write_time
);
373 SSVAL(t2
.in
.params
.data
, VWV(6), parms
->t2open
.in
.open_func
);
374 SIVAL(t2
.in
.params
.data
, VWV(7), parms
->t2open
.in
.size
);
375 SIVAL(t2
.in
.params
.data
, VWV(9), parms
->t2open
.in
.timeout
);
376 SIVAL(t2
.in
.params
.data
, VWV(11), 0);
377 SSVAL(t2
.in
.params
.data
, VWV(13), 0);
379 smbcli_blob_append_string(tree
->session
, mem_ctx
,
380 &t2
.in
.params
, parms
->t2open
.in
.fname
,
383 ea_put_list(t2
.in
.data
.data
, parms
->t2open
.in
.num_eas
, parms
->t2open
.in
.eas
);
385 req
= smb_raw_trans2_send(tree
, &t2
);
387 talloc_destroy(mem_ctx
);
393 /****************************************************************************
394 Open a file using TRANSACT2_OPEN - async recv
395 ****************************************************************************/
396 static NTSTATUS
smb_raw_t2open_recv(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
, union smb_open
*parms
)
398 struct smbcli_transport
*transport
= req
?req
->transport
:NULL
;
399 struct smb_trans2 t2
;
402 status
= smb_raw_trans2_recv(req
, mem_ctx
, &t2
);
403 if (!NT_STATUS_IS_OK(status
)) return status
;
405 if (t2
.out
.params
.length
< 30) {
406 return NT_STATUS_INFO_LENGTH_MISMATCH
;
409 parms
->t2open
.out
.fnum
= SVAL(t2
.out
.params
.data
, VWV(0));
410 parms
->t2open
.out
.attrib
= SVAL(t2
.out
.params
.data
, VWV(1));
411 parms
->t2open
.out
.write_time
= raw_pull_dos_date3(transport
, t2
.out
.params
.data
+ VWV(2));
412 parms
->t2open
.out
.size
= IVAL(t2
.out
.params
.data
, VWV(4));
413 parms
->t2open
.out
.access
= SVAL(t2
.out
.params
.data
, VWV(6));
414 parms
->t2open
.out
.ftype
= SVAL(t2
.out
.params
.data
, VWV(7));
415 parms
->t2open
.out
.devstate
= SVAL(t2
.out
.params
.data
, VWV(8));
416 parms
->t2open
.out
.action
= SVAL(t2
.out
.params
.data
, VWV(9));
417 parms
->t2open
.out
.unknown
= SVAL(t2
.out
.params
.data
, VWV(10));
422 /****************************************************************************
423 Open a file - async send
424 ****************************************************************************/
425 struct smbcli_request
*smb_raw_open_send(struct smbcli_tree
*tree
, union smb_open
*parms
)
428 struct smbcli_request
*req
= NULL
;
430 switch (parms
->generic
.level
) {
431 case RAW_OPEN_T2OPEN
:
432 return smb_raw_t2open_send(tree
, parms
);
435 SETUP_REQUEST(SMBopen
, 2, 0);
436 SSVAL(req
->out
.vwv
, VWV(0), parms
->openold
.in
.flags
);
437 SSVAL(req
->out
.vwv
, VWV(1), parms
->openold
.in
.search_attrs
);
438 smbcli_req_append_ascii4(req
, parms
->openold
.in
.fname
, STR_TERMINATE
);
442 SETUP_REQUEST(SMBopenX
, 15, 0);
443 SSVAL(req
->out
.vwv
, VWV(0), SMB_CHAIN_NONE
);
444 SSVAL(req
->out
.vwv
, VWV(1), 0);
445 SSVAL(req
->out
.vwv
, VWV(2), parms
->openx
.in
.flags
);
446 SSVAL(req
->out
.vwv
, VWV(3), parms
->openx
.in
.open_mode
);
447 SSVAL(req
->out
.vwv
, VWV(4), parms
->openx
.in
.search_attrs
);
448 SSVAL(req
->out
.vwv
, VWV(5), parms
->openx
.in
.file_attrs
);
449 raw_push_dos_date3(tree
->session
->transport
,
450 req
->out
.vwv
, VWV(6), parms
->openx
.in
.write_time
);
451 SSVAL(req
->out
.vwv
, VWV(8), parms
->openx
.in
.open_func
);
452 SIVAL(req
->out
.vwv
, VWV(9), parms
->openx
.in
.size
);
453 SIVAL(req
->out
.vwv
, VWV(11),parms
->openx
.in
.timeout
);
454 SIVAL(req
->out
.vwv
, VWV(13),0); /* reserved */
455 smbcli_req_append_string(req
, parms
->openx
.in
.fname
, STR_TERMINATE
);
459 SETUP_REQUEST(SMBmknew
, 3, 0);
460 SSVAL(req
->out
.vwv
, VWV(0), parms
->mknew
.in
.attrib
);
461 raw_push_dos_date3(tree
->session
->transport
,
462 req
->out
.vwv
, VWV(1), parms
->mknew
.in
.write_time
);
463 smbcli_req_append_ascii4(req
, parms
->mknew
.in
.fname
, STR_TERMINATE
);
466 case RAW_OPEN_CREATE
:
467 SETUP_REQUEST(SMBcreate
, 3, 0);
468 SSVAL(req
->out
.vwv
, VWV(0), parms
->create
.in
.attrib
);
469 raw_push_dos_date3(tree
->session
->transport
,
470 req
->out
.vwv
, VWV(1), parms
->create
.in
.write_time
);
471 smbcli_req_append_ascii4(req
, parms
->create
.in
.fname
, STR_TERMINATE
);
475 SETUP_REQUEST(SMBctemp
, 3, 0);
476 SSVAL(req
->out
.vwv
, VWV(0), parms
->ctemp
.in
.attrib
);
477 raw_push_dos_date3(tree
->session
->transport
,
478 req
->out
.vwv
, VWV(1), parms
->ctemp
.in
.write_time
);
479 smbcli_req_append_ascii4(req
, parms
->ctemp
.in
.directory
, STR_TERMINATE
);
482 case RAW_OPEN_SPLOPEN
:
483 SETUP_REQUEST(SMBsplopen
, 2, 0);
484 SSVAL(req
->out
.vwv
, VWV(0), parms
->splopen
.in
.setup_length
);
485 SSVAL(req
->out
.vwv
, VWV(1), parms
->splopen
.in
.mode
);
488 case RAW_OPEN_NTCREATEX
:
489 SETUP_REQUEST(SMBntcreateX
, 24, 0);
490 SSVAL(req
->out
.vwv
, VWV(0),SMB_CHAIN_NONE
);
491 SSVAL(req
->out
.vwv
, VWV(1),0);
492 SCVAL(req
->out
.vwv
, VWV(2),0); /* padding */
493 SIVAL(req
->out
.vwv
, 7, parms
->ntcreatex
.in
.flags
);
494 SIVAL(req
->out
.vwv
, 11, parms
->ntcreatex
.in
.root_fid
);
495 SIVAL(req
->out
.vwv
, 15, parms
->ntcreatex
.in
.access_mask
);
496 SBVAL(req
->out
.vwv
, 19, parms
->ntcreatex
.in
.alloc_size
);
497 SIVAL(req
->out
.vwv
, 27, parms
->ntcreatex
.in
.file_attr
);
498 SIVAL(req
->out
.vwv
, 31, parms
->ntcreatex
.in
.share_access
);
499 SIVAL(req
->out
.vwv
, 35, parms
->ntcreatex
.in
.open_disposition
);
500 SIVAL(req
->out
.vwv
, 39, parms
->ntcreatex
.in
.create_options
);
501 SIVAL(req
->out
.vwv
, 43, parms
->ntcreatex
.in
.impersonation
);
502 SCVAL(req
->out
.vwv
, 47, parms
->ntcreatex
.in
.security_flags
);
504 smbcli_req_append_string_len(req
, parms
->ntcreatex
.in
.fname
, STR_TERMINATE
, &len
);
505 SSVAL(req
->out
.vwv
, 5, len
);
508 case RAW_OPEN_NTTRANS_CREATE
:
509 return smb_raw_nttrans_create_send(tree
, parms
);
512 if (!smbcli_request_send(req
)) {
513 smbcli_request_destroy(req
);
520 /****************************************************************************
521 Open a file - async recv
522 ****************************************************************************/
523 NTSTATUS
smb_raw_open_recv(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
, union smb_open
*parms
)
525 if (!smbcli_request_receive(req
) ||
526 smbcli_request_is_error(req
)) {
530 switch (parms
->openold
.level
) {
531 case RAW_OPEN_T2OPEN
:
532 return smb_raw_t2open_recv(req
, mem_ctx
, parms
);
535 SMBCLI_CHECK_WCT(req
, 7);
536 parms
->openold
.out
.fnum
= SVAL(req
->in
.vwv
, VWV(0));
537 parms
->openold
.out
.attrib
= SVAL(req
->in
.vwv
, VWV(1));
538 parms
->openold
.out
.write_time
= raw_pull_dos_date3(req
->transport
,
539 req
->in
.vwv
+ VWV(2));
540 parms
->openold
.out
.size
= IVAL(req
->in
.vwv
, VWV(4));
541 parms
->openold
.out
.rmode
= SVAL(req
->in
.vwv
, VWV(6));
545 SMBCLI_CHECK_MIN_WCT(req
, 15);
546 parms
->openx
.out
.fnum
= SVAL(req
->in
.vwv
, VWV(2));
547 parms
->openx
.out
.attrib
= SVAL(req
->in
.vwv
, VWV(3));
548 parms
->openx
.out
.write_time
= raw_pull_dos_date3(req
->transport
,
549 req
->in
.vwv
+ VWV(4));
550 parms
->openx
.out
.size
= IVAL(req
->in
.vwv
, VWV(6));
551 parms
->openx
.out
.access
= SVAL(req
->in
.vwv
, VWV(8));
552 parms
->openx
.out
.ftype
= SVAL(req
->in
.vwv
, VWV(9));
553 parms
->openx
.out
.devstate
= SVAL(req
->in
.vwv
, VWV(10));
554 parms
->openx
.out
.action
= SVAL(req
->in
.vwv
, VWV(11));
555 parms
->openx
.out
.unique_fid
= IVAL(req
->in
.vwv
, VWV(12));
556 if (req
->in
.wct
>= 19) {
557 parms
->openx
.out
.access_mask
= IVAL(req
->in
.vwv
, VWV(15));
558 parms
->openx
.out
.unknown
= IVAL(req
->in
.vwv
, VWV(17));
560 parms
->openx
.out
.access_mask
= 0;
561 parms
->openx
.out
.unknown
= 0;
566 SMBCLI_CHECK_WCT(req
, 1);
567 parms
->mknew
.out
.fnum
= SVAL(req
->in
.vwv
, VWV(0));
570 case RAW_OPEN_CREATE
:
571 SMBCLI_CHECK_WCT(req
, 1);
572 parms
->create
.out
.fnum
= SVAL(req
->in
.vwv
, VWV(0));
576 SMBCLI_CHECK_WCT(req
, 1);
577 parms
->ctemp
.out
.fnum
= SVAL(req
->in
.vwv
, VWV(0));
578 smbcli_req_pull_string(req
, mem_ctx
, &parms
->ctemp
.out
.name
, req
->in
.data
, -1, STR_TERMINATE
| STR_ASCII
);
581 case RAW_OPEN_SPLOPEN
:
582 SMBCLI_CHECK_WCT(req
, 1);
583 parms
->splopen
.out
.fnum
= SVAL(req
->in
.vwv
, VWV(0));
586 case RAW_OPEN_NTCREATEX
:
587 SMBCLI_CHECK_MIN_WCT(req
, 34);
588 parms
->ntcreatex
.out
.oplock_level
= CVAL(req
->in
.vwv
, 4);
589 parms
->ntcreatex
.out
.fnum
= SVAL(req
->in
.vwv
, 5);
590 parms
->ntcreatex
.out
.create_action
= IVAL(req
->in
.vwv
, 7);
591 parms
->ntcreatex
.out
.create_time
= smbcli_pull_nttime(req
->in
.vwv
, 11);
592 parms
->ntcreatex
.out
.access_time
= smbcli_pull_nttime(req
->in
.vwv
, 19);
593 parms
->ntcreatex
.out
.write_time
= smbcli_pull_nttime(req
->in
.vwv
, 27);
594 parms
->ntcreatex
.out
.change_time
= smbcli_pull_nttime(req
->in
.vwv
, 35);
595 parms
->ntcreatex
.out
.attrib
= IVAL(req
->in
.vwv
, 43);
596 parms
->ntcreatex
.out
.alloc_size
= BVAL(req
->in
.vwv
, 47);
597 parms
->ntcreatex
.out
.size
= BVAL(req
->in
.vwv
, 55);
598 parms
->ntcreatex
.out
.file_type
= SVAL(req
->in
.vwv
, 63);
599 parms
->ntcreatex
.out
.ipc_state
= SVAL(req
->in
.vwv
, 65);
600 parms
->ntcreatex
.out
.is_directory
= CVAL(req
->in
.vwv
, 67);
603 case RAW_OPEN_NTTRANS_CREATE
:
604 return smb_raw_nttrans_create_recv(req
, mem_ctx
, parms
);
608 return smbcli_request_destroy(req
);
612 /****************************************************************************
613 Open a file - sync interface
614 ****************************************************************************/
615 NTSTATUS
smb_raw_open(struct smbcli_tree
*tree
, TALLOC_CTX
*mem_ctx
, union smb_open
*parms
)
617 struct smbcli_request
*req
= smb_raw_open_send(tree
, parms
);
618 return smb_raw_open_recv(req
, mem_ctx
, parms
);
622 /****************************************************************************
623 Close a file - async send
624 ****************************************************************************/
625 struct smbcli_request
*smb_raw_close_send(struct smbcli_tree
*tree
, union smb_close
*parms
)
627 struct smbcli_request
*req
= NULL
;
629 switch (parms
->generic
.level
) {
630 case RAW_CLOSE_CLOSE
:
631 SETUP_REQUEST(SMBclose
, 3, 0);
632 SSVAL(req
->out
.vwv
, VWV(0), parms
->close
.in
.fnum
);
633 raw_push_dos_date3(tree
->session
->transport
,
634 req
->out
.vwv
, VWV(1), parms
->close
.in
.write_time
);
637 case RAW_CLOSE_SPLCLOSE
:
638 SETUP_REQUEST(SMBsplclose
, 3, 0);
639 SSVAL(req
->out
.vwv
, VWV(0), parms
->splclose
.in
.fnum
);
640 SIVAL(req
->out
.vwv
, VWV(1), 0); /* reserved */
644 if (!req
) return NULL
;
646 if (!smbcli_request_send(req
)) {
647 smbcli_request_destroy(req
);
655 /****************************************************************************
656 Close a file - sync interface
657 ****************************************************************************/
658 NTSTATUS
smb_raw_close(struct smbcli_tree
*tree
, union smb_close
*parms
)
660 struct smbcli_request
*req
= smb_raw_close_send(tree
, parms
);
661 return smbcli_request_simple_recv(req
);
665 /****************************************************************************
666 Locking calls - async interface
667 ****************************************************************************/
668 struct smbcli_request
*smb_raw_lock_send(struct smbcli_tree
*tree
, union smb_lock
*parms
)
670 struct smbcli_request
*req
= NULL
;
672 switch (parms
->generic
.level
) {
674 SETUP_REQUEST(SMBlock
, 5, 0);
675 SSVAL(req
->out
.vwv
, VWV(0), parms
->lock
.in
.fnum
);
676 SIVAL(req
->out
.vwv
, VWV(1), parms
->lock
.in
.count
);
677 SIVAL(req
->out
.vwv
, VWV(3), parms
->lock
.in
.offset
);
680 case RAW_LOCK_UNLOCK
:
681 SETUP_REQUEST(SMBunlock
, 5, 0);
682 SSVAL(req
->out
.vwv
, VWV(0), parms
->unlock
.in
.fnum
);
683 SIVAL(req
->out
.vwv
, VWV(1), parms
->unlock
.in
.count
);
684 SIVAL(req
->out
.vwv
, VWV(3), parms
->unlock
.in
.offset
);
687 case RAW_LOCK_LOCKX
: {
688 struct smb_lock_entry
*lockp
;
689 uint_t lck_size
= (parms
->lockx
.in
.mode
& LOCKING_ANDX_LARGE_FILES
)? 20 : 10;
690 uint_t lock_count
= parms
->lockx
.in
.ulock_cnt
+ parms
->lockx
.in
.lock_cnt
;
693 SETUP_REQUEST(SMBlockingX
, 8, lck_size
* lock_count
);
694 SSVAL(req
->out
.vwv
, VWV(0), SMB_CHAIN_NONE
);
695 SSVAL(req
->out
.vwv
, VWV(1), 0);
696 SSVAL(req
->out
.vwv
, VWV(2), parms
->lockx
.in
.fnum
);
697 SSVAL(req
->out
.vwv
, VWV(3), parms
->lockx
.in
.mode
);
698 SIVAL(req
->out
.vwv
, VWV(4), parms
->lockx
.in
.timeout
);
699 SSVAL(req
->out
.vwv
, VWV(6), parms
->lockx
.in
.ulock_cnt
);
700 SSVAL(req
->out
.vwv
, VWV(7), parms
->lockx
.in
.lock_cnt
);
702 /* copy in all the locks */
703 lockp
= &parms
->lockx
.in
.locks
[0];
704 for (i
= 0; i
< lock_count
; i
++) {
705 char *p
= req
->out
.data
+ lck_size
* i
;
706 SSVAL(p
, 0, lockp
[i
].pid
);
707 if (parms
->lockx
.in
.mode
& LOCKING_ANDX_LARGE_FILES
) {
708 SSVAL(p
, 2, 0); /* reserved */
709 SIVAL(p
, 4, lockp
[i
].offset
>>32);
710 SIVAL(p
, 8, lockp
[i
].offset
);
711 SIVAL(p
, 12, lockp
[i
].count
>>32);
712 SIVAL(p
, 16, lockp
[i
].count
);
714 SIVAL(p
, 2, lockp
[i
].offset
);
715 SIVAL(p
, 6, lockp
[i
].count
);
721 if (!smbcli_request_send(req
)) {
722 smbcli_request_destroy(req
);
729 /****************************************************************************
730 Locking calls - sync interface
731 ****************************************************************************/
732 NTSTATUS
smb_raw_lock(struct smbcli_tree
*tree
, union smb_lock
*parms
)
734 struct smbcli_request
*req
= smb_raw_lock_send(tree
, parms
);
735 return smbcli_request_simple_recv(req
);
739 /****************************************************************************
740 Check for existence of a dir - async send
741 ****************************************************************************/
742 struct smbcli_request
*smb_raw_chkpath_send(struct smbcli_tree
*tree
, struct smb_chkpath
*parms
)
744 struct smbcli_request
*req
;
746 SETUP_REQUEST(SMBchkpth
, 0, 0);
748 smbcli_req_append_ascii4(req
, parms
->in
.path
, STR_TERMINATE
);
750 if (!smbcli_request_send(req
)) {
751 smbcli_request_destroy(req
);
758 /****************************************************************************
759 Check for existence of a dir - sync interface
760 ****************************************************************************/
761 NTSTATUS
smb_raw_chkpath(struct smbcli_tree
*tree
, struct smb_chkpath
*parms
)
763 struct smbcli_request
*req
= smb_raw_chkpath_send(tree
, parms
);
764 return smbcli_request_simple_recv(req
);
770 /****************************************************************************
771 flush a file - async send
772 a flush to fnum 0xFFFF will flush all files
773 ****************************************************************************/
774 struct smbcli_request
*smb_raw_flush_send(struct smbcli_tree
*tree
, struct smb_flush
*parms
)
776 struct smbcli_request
*req
;
778 SETUP_REQUEST(SMBflush
, 1, 0);
779 SSVAL(req
->out
.vwv
, VWV(0), parms
->in
.fnum
);
781 if (!smbcli_request_send(req
)) {
782 smbcli_request_destroy(req
);
790 /****************************************************************************
791 flush a file - sync interface
792 ****************************************************************************/
793 NTSTATUS
smb_raw_flush(struct smbcli_tree
*tree
, struct smb_flush
*parms
)
795 struct smbcli_request
*req
= smb_raw_flush_send(tree
, parms
);
796 return smbcli_request_simple_recv(req
);
800 /****************************************************************************
801 seek a file - async send
802 ****************************************************************************/
803 struct smbcli_request
*smb_raw_seek_send(struct smbcli_tree
*tree
,
804 struct smb_seek
*parms
)
806 struct smbcli_request
*req
;
808 SETUP_REQUEST(SMBlseek
, 4, 0);
810 SSVAL(req
->out
.vwv
, VWV(0), parms
->in
.fnum
);
811 SSVAL(req
->out
.vwv
, VWV(1), parms
->in
.mode
);
812 SIVALS(req
->out
.vwv
, VWV(2), parms
->in
.offset
);
814 if (!smbcli_request_send(req
)) {
815 smbcli_request_destroy(req
);
821 /****************************************************************************
822 seek a file - async receive
823 ****************************************************************************/
824 NTSTATUS
smb_raw_seek_recv(struct smbcli_request
*req
,
825 struct smb_seek
*parms
)
827 if (!smbcli_request_receive(req
) ||
828 smbcli_request_is_error(req
)) {
829 return smbcli_request_destroy(req
);
832 SMBCLI_CHECK_WCT(req
, 2);
833 parms
->out
.offset
= IVAL(req
->in
.vwv
, VWV(0));
836 return smbcli_request_destroy(req
);
840 seek a file - sync interface
842 NTSTATUS
smb_raw_seek(struct smbcli_tree
*tree
,
843 struct smb_seek
*parms
)
845 struct smbcli_request
*req
= smb_raw_seek_send(tree
, parms
);
846 return smb_raw_seek_recv(req
, parms
);