2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2001-2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /****************************************************************************
27 Hard/Symlink a file (UNIX extensions).
28 ****************************************************************************/
30 static BOOL
cli_link_internal(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
, BOOL hard_link
)
32 unsigned int data_len
= 0;
33 unsigned int param_len
= 0;
34 uint16 setup
= TRANSACT2_SETPATHINFO
;
35 char param
[sizeof(pstring
)+6];
37 char *rparam
=NULL
, *rdata
=NULL
;
40 memset(param
, 0, sizeof(param
));
41 SSVAL(param
,0,hard_link
? SMB_SET_FILE_UNIX_HLINK
: SMB_SET_FILE_UNIX_LINK
);
44 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
45 param_len
= PTR_DIFF(p
, param
);
48 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
49 data_len
= PTR_DIFF(p
, data
);
51 if (!cli_send_trans(cli
, SMBtrans2
,
53 -1, 0, /* fid, flags */
54 &setup
, 1, 0, /* setup, length, max */
55 param
, param_len
, 2, /* param, length, max */
56 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
61 if (!cli_receive_trans(cli
, SMBtrans2
,
73 /****************************************************************************
74 Map standard UNIX permissions onto wire representations.
75 ****************************************************************************/
77 uint32
unix_perms_to_wire(mode_t perms
)
81 ret
|= ((perms
& S_IXOTH
) ? UNIX_X_OTH
: 0);
82 ret
|= ((perms
& S_IWOTH
) ? UNIX_W_OTH
: 0);
83 ret
|= ((perms
& S_IROTH
) ? UNIX_R_OTH
: 0);
84 ret
|= ((perms
& S_IXGRP
) ? UNIX_X_GRP
: 0);
85 ret
|= ((perms
& S_IWGRP
) ? UNIX_W_GRP
: 0);
86 ret
|= ((perms
& S_IRGRP
) ? UNIX_R_GRP
: 0);
87 ret
|= ((perms
& S_IXUSR
) ? UNIX_X_USR
: 0);
88 ret
|= ((perms
& S_IWUSR
) ? UNIX_W_USR
: 0);
89 ret
|= ((perms
& S_IRUSR
) ? UNIX_R_USR
: 0);
91 ret
|= ((perms
& S_ISVTX
) ? UNIX_STICKY
: 0);
94 ret
|= ((perms
& S_ISGID
) ? UNIX_SET_GID
: 0);
97 ret
|= ((perms
& S_ISUID
) ? UNIX_SET_UID
: 0);
102 /****************************************************************************
103 Symlink a file (UNIX extensions).
104 ****************************************************************************/
106 BOOL
cli_unix_symlink(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
108 return cli_link_internal(cli
, fname_src
, fname_dst
, False
);
111 /****************************************************************************
112 Hard a file (UNIX extensions).
113 ****************************************************************************/
115 BOOL
cli_unix_hardlink(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
117 return cli_link_internal(cli
, fname_src
, fname_dst
, True
);
120 /****************************************************************************
121 Chmod or chown a file internal (UNIX extensions).
122 ****************************************************************************/
124 static BOOL
cli_unix_chmod_chown_internal(struct cli_state
*cli
, const char *fname
, uint32 mode
, uint32 uid
, uint32 gid
)
126 unsigned int data_len
= 0;
127 unsigned int param_len
= 0;
128 uint16 setup
= TRANSACT2_SETPATHINFO
;
129 char param
[sizeof(pstring
)+6];
131 char *rparam
=NULL
, *rdata
=NULL
;
134 memset(param
, 0, sizeof(param
));
135 memset(data
, 0, sizeof(data
));
136 SSVAL(param
,0,SMB_SET_FILE_UNIX_BASIC
);
139 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
140 param_len
= PTR_DIFF(p
, param
);
148 if (!cli_send_trans(cli
, SMBtrans2
,
150 -1, 0, /* fid, flags */
151 &setup
, 1, 0, /* setup, length, max */
152 param
, param_len
, 2, /* param, length, max */
153 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
158 if (!cli_receive_trans(cli
, SMBtrans2
,
160 &rdata
, &data_len
)) {
170 /****************************************************************************
171 chmod a file (UNIX extensions).
172 ****************************************************************************/
174 BOOL
cli_unix_chmod(struct cli_state
*cli
, const char *fname
, mode_t mode
)
176 return cli_unix_chmod_chown_internal(cli
, fname
,
177 unix_perms_to_wire(mode
), SMB_UID_NO_CHANGE
, SMB_GID_NO_CHANGE
);
180 /****************************************************************************
181 chown a file (UNIX extensions).
182 ****************************************************************************/
184 BOOL
cli_unix_chown(struct cli_state
*cli
, const char *fname
, uid_t uid
, gid_t gid
)
186 return cli_unix_chmod_chown_internal(cli
, fname
, SMB_MODE_NO_CHANGE
, (uint32
)uid
, (uint32
)gid
);
189 /****************************************************************************
191 ****************************************************************************/
193 BOOL
cli_rename(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
197 memset(cli
->outbuf
,'\0',smb_size
);
198 memset(cli
->inbuf
,'\0',smb_size
);
200 set_message(cli
->outbuf
,1, 0, True
);
202 SCVAL(cli
->outbuf
,smb_com
,SMBmv
);
203 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
204 cli_setup_packet(cli
);
206 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
| aDIR
);
208 p
= smb_buf(cli
->outbuf
);
210 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
212 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
214 cli_setup_bcc(cli
, p
);
217 if (!cli_receive_smb(cli
))
220 if (cli_is_error(cli
))
226 /****************************************************************************
228 ****************************************************************************/
230 BOOL
cli_unlink(struct cli_state
*cli
, const char *fname
)
234 memset(cli
->outbuf
,'\0',smb_size
);
235 memset(cli
->inbuf
,'\0',smb_size
);
237 set_message(cli
->outbuf
,1, 0,True
);
239 SCVAL(cli
->outbuf
,smb_com
,SMBunlink
);
240 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
241 cli_setup_packet(cli
);
243 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
);
245 p
= smb_buf(cli
->outbuf
);
247 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
249 cli_setup_bcc(cli
, p
);
251 if (!cli_receive_smb(cli
)) {
255 if (cli_is_error(cli
)) {
262 /****************************************************************************
264 ****************************************************************************/
266 BOOL
cli_mkdir(struct cli_state
*cli
, const char *dname
)
270 memset(cli
->outbuf
,'\0',smb_size
);
271 memset(cli
->inbuf
,'\0',smb_size
);
273 set_message(cli
->outbuf
,0, 0,True
);
275 SCVAL(cli
->outbuf
,smb_com
,SMBmkdir
);
276 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
277 cli_setup_packet(cli
);
279 p
= smb_buf(cli
->outbuf
);
281 p
+= clistr_push(cli
, p
, dname
, -1, STR_TERMINATE
);
283 cli_setup_bcc(cli
, p
);
286 if (!cli_receive_smb(cli
)) {
290 if (cli_is_error(cli
)) {
297 /****************************************************************************
299 ****************************************************************************/
301 BOOL
cli_rmdir(struct cli_state
*cli
, const char *dname
)
305 memset(cli
->outbuf
,'\0',smb_size
);
306 memset(cli
->inbuf
,'\0',smb_size
);
308 set_message(cli
->outbuf
,0, 0, True
);
310 SCVAL(cli
->outbuf
,smb_com
,SMBrmdir
);
311 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
312 cli_setup_packet(cli
);
314 p
= smb_buf(cli
->outbuf
);
316 p
+= clistr_push(cli
, p
, dname
, -1, STR_TERMINATE
);
318 cli_setup_bcc(cli
, p
);
321 if (!cli_receive_smb(cli
)) {
325 if (cli_is_error(cli
)) {
332 /****************************************************************************
333 Set or clear the delete on close flag.
334 ****************************************************************************/
336 int cli_nt_delete_on_close(struct cli_state
*cli
, int fnum
, BOOL flag
)
338 unsigned int data_len
= 1;
339 unsigned int param_len
= 6;
340 uint16 setup
= TRANSACT2_SETFILEINFO
;
343 char *rparam
=NULL
, *rdata
=NULL
;
345 memset(param
, 0, param_len
);
347 SSVAL(param
,2,SMB_SET_FILE_DISPOSITION_INFO
);
351 if (!cli_send_trans(cli
, SMBtrans2
,
353 -1, 0, /* fid, flags */
354 &setup
, 1, 0, /* setup, length, max */
355 param
, param_len
, 2, /* param, length, max */
356 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
361 if (!cli_receive_trans(cli
, SMBtrans2
,
363 &rdata
, &data_len
)) {
373 /****************************************************************************
374 Open a file - exposing the full horror of the NT API :-).
376 ****************************************************************************/
378 int cli_nt_create_full(struct cli_state
*cli
, const char *fname
,
379 uint32 CreatFlags
, uint32 DesiredAccess
,
380 uint32 FileAttributes
, uint32 ShareAccess
,
381 uint32 CreateDisposition
, uint32 CreateOptions
,
387 memset(cli
->outbuf
,'\0',smb_size
);
388 memset(cli
->inbuf
,'\0',smb_size
);
390 set_message(cli
->outbuf
,24,0,True
);
392 SCVAL(cli
->outbuf
,smb_com
,SMBntcreateX
);
393 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
394 cli_setup_packet(cli
);
396 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
397 if (cli
->use_oplocks
)
398 CreatFlags
|= (REQUEST_OPLOCK
|REQUEST_BATCH_OPLOCK
);
400 SIVAL(cli
->outbuf
,smb_ntcreate_Flags
, CreatFlags
);
401 SIVAL(cli
->outbuf
,smb_ntcreate_RootDirectoryFid
, 0x0);
402 SIVAL(cli
->outbuf
,smb_ntcreate_DesiredAccess
, DesiredAccess
);
403 SIVAL(cli
->outbuf
,smb_ntcreate_FileAttributes
, FileAttributes
);
404 SIVAL(cli
->outbuf
,smb_ntcreate_ShareAccess
, ShareAccess
);
405 SIVAL(cli
->outbuf
,smb_ntcreate_CreateDisposition
, CreateDisposition
);
406 SIVAL(cli
->outbuf
,smb_ntcreate_CreateOptions
, CreateOptions
);
407 SIVAL(cli
->outbuf
,smb_ntcreate_ImpersonationLevel
, 0x02);
408 SCVAL(cli
->outbuf
,smb_ntcreate_SecurityFlags
, SecuityFlags
);
410 p
= smb_buf(cli
->outbuf
);
411 /* this alignment and termination is critical for netapp filers. Don't change */
412 p
+= clistr_align_out(cli
, p
, 0);
413 len
= clistr_push(cli
, p
, fname
, -1, 0);
415 SSVAL(cli
->outbuf
,smb_ntcreate_NameLength
, len
);
416 /* sigh. this copes with broken netapp filer behaviour */
417 p
+= clistr_push(cli
, p
, "", -1, STR_TERMINATE
);
419 cli_setup_bcc(cli
, p
);
422 if (!cli_receive_smb(cli
)) {
426 if (cli_is_error(cli
)) {
430 return SVAL(cli
->inbuf
,smb_vwv2
+ 1);
433 /****************************************************************************
435 ****************************************************************************/
437 int cli_nt_create(struct cli_state
*cli
, const char *fname
, uint32 DesiredAccess
)
439 return cli_nt_create_full(cli
, fname
, 0, DesiredAccess
, 0,
440 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_EXISTS_OPEN
, 0x0, 0x0);
443 /****************************************************************************
445 WARNING: if you open with O_WRONLY then getattrE won't work!
446 ****************************************************************************/
448 int cli_open(struct cli_state
*cli
, const char *fname
, int flags
, int share_mode
)
452 unsigned accessmode
=0;
456 if (!(flags
& O_EXCL
)) {
463 accessmode
= (share_mode
<<4);
465 if ((flags
& O_ACCMODE
) == O_RDWR
) {
467 } else if ((flags
& O_ACCMODE
) == O_WRONLY
) {
472 if ((flags
& O_SYNC
) == O_SYNC
) {
473 accessmode
|= (1<<14);
477 if (share_mode
== DENY_FCB
) {
481 memset(cli
->outbuf
,'\0',smb_size
);
482 memset(cli
->inbuf
,'\0',smb_size
);
484 set_message(cli
->outbuf
,15,0,True
);
486 SCVAL(cli
->outbuf
,smb_com
,SMBopenX
);
487 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
488 cli_setup_packet(cli
);
490 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
491 SSVAL(cli
->outbuf
,smb_vwv2
,0); /* no additional info */
492 SSVAL(cli
->outbuf
,smb_vwv3
,accessmode
);
493 SSVAL(cli
->outbuf
,smb_vwv4
,aSYSTEM
| aHIDDEN
);
494 SSVAL(cli
->outbuf
,smb_vwv5
,0);
495 SSVAL(cli
->outbuf
,smb_vwv8
,openfn
);
497 if (cli
->use_oplocks
) {
498 /* if using oplocks then ask for a batch oplock via
499 core and extended methods */
500 SCVAL(cli
->outbuf
,smb_flg
, CVAL(cli
->outbuf
,smb_flg
)|
501 FLAG_REQUEST_OPLOCK
|FLAG_REQUEST_BATCH_OPLOCK
);
502 SSVAL(cli
->outbuf
,smb_vwv2
,SVAL(cli
->outbuf
,smb_vwv2
) | 6);
505 p
= smb_buf(cli
->outbuf
);
506 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
508 cli_setup_bcc(cli
, p
);
511 if (!cli_receive_smb(cli
)) {
515 if (cli_is_error(cli
)) {
519 return SVAL(cli
->inbuf
,smb_vwv2
);
522 /****************************************************************************
524 ****************************************************************************/
526 BOOL
cli_close(struct cli_state
*cli
, int fnum
)
528 memset(cli
->outbuf
,'\0',smb_size
);
529 memset(cli
->inbuf
,'\0',smb_size
);
531 set_message(cli
->outbuf
,3,0,True
);
533 SCVAL(cli
->outbuf
,smb_com
,SMBclose
);
534 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
535 cli_setup_packet(cli
);
537 SSVAL(cli
->outbuf
,smb_vwv0
,fnum
);
538 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
541 if (!cli_receive_smb(cli
)) {
545 return !cli_is_error(cli
);
549 /****************************************************************************
550 send a lock with a specified locktype
551 this is used for testing LOCKING_ANDX_CANCEL_LOCK
552 ****************************************************************************/
553 NTSTATUS
cli_locktype(struct cli_state
*cli
, int fnum
,
554 uint32 offset
, uint32 len
, int timeout
, unsigned char locktype
)
557 int saved_timeout
= cli
->timeout
;
559 memset(cli
->outbuf
,'\0',smb_size
);
560 memset(cli
->inbuf
,'\0', smb_size
);
562 set_message(cli
->outbuf
,8,0,True
);
564 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
565 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
566 cli_setup_packet(cli
);
568 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
569 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
570 SCVAL(cli
->outbuf
,smb_vwv3
,locktype
);
571 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
572 SSVAL(cli
->outbuf
,smb_vwv6
,0);
573 SSVAL(cli
->outbuf
,smb_vwv7
,1);
575 p
= smb_buf(cli
->outbuf
);
576 SSVAL(p
, 0, cli
->pid
);
582 cli_setup_bcc(cli
, p
);
587 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
590 if (!cli_receive_smb(cli
)) {
591 cli
->timeout
= saved_timeout
;
592 return NT_STATUS_UNSUCCESSFUL
;
595 cli
->timeout
= saved_timeout
;
597 return cli_nt_error(cli
);
601 /****************************************************************************
603 ****************************************************************************/
605 BOOL
cli_lock(struct cli_state
*cli
, int fnum
,
606 uint32 offset
, uint32 len
, int timeout
, enum brl_type lock_type
)
609 int saved_timeout
= cli
->timeout
;
611 memset(cli
->outbuf
,'\0',smb_size
);
612 memset(cli
->inbuf
,'\0', smb_size
);
614 set_message(cli
->outbuf
,8,0,True
);
616 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
617 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
618 cli_setup_packet(cli
);
620 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
621 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
622 SCVAL(cli
->outbuf
,smb_vwv3
,(lock_type
== READ_LOCK
? 1 : 0));
623 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
624 SSVAL(cli
->outbuf
,smb_vwv6
,0);
625 SSVAL(cli
->outbuf
,smb_vwv7
,1);
627 p
= smb_buf(cli
->outbuf
);
628 SSVAL(p
, 0, cli
->pid
);
634 cli_setup_bcc(cli
, p
);
639 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 10*1000);
642 if (!cli_receive_smb(cli
)) {
643 cli
->timeout
= saved_timeout
;
647 cli
->timeout
= saved_timeout
;
649 if (cli_is_error(cli
)) {
656 /****************************************************************************
658 ****************************************************************************/
660 BOOL
cli_unlock(struct cli_state
*cli
, int fnum
, uint32 offset
, uint32 len
)
664 memset(cli
->outbuf
,'\0',smb_size
);
665 memset(cli
->inbuf
,'\0',smb_size
);
667 set_message(cli
->outbuf
,8,0,True
);
669 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
670 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
671 cli_setup_packet(cli
);
673 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
674 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
675 SCVAL(cli
->outbuf
,smb_vwv3
,0);
676 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
677 SSVAL(cli
->outbuf
,smb_vwv6
,1);
678 SSVAL(cli
->outbuf
,smb_vwv7
,0);
680 p
= smb_buf(cli
->outbuf
);
681 SSVAL(p
, 0, cli
->pid
);
685 cli_setup_bcc(cli
, p
);
687 if (!cli_receive_smb(cli
)) {
691 if (cli_is_error(cli
)) {
698 /****************************************************************************
699 Lock a file with 64 bit offsets.
700 ****************************************************************************/
702 BOOL
cli_lock64(struct cli_state
*cli
, int fnum
,
703 SMB_BIG_UINT offset
, SMB_BIG_UINT len
, int timeout
, enum brl_type lock_type
)
706 int saved_timeout
= cli
->timeout
;
709 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
710 return cli_lock(cli
, fnum
, offset
, len
, timeout
, lock_type
);
713 ltype
= (lock_type
== READ_LOCK
? 1 : 0);
714 ltype
|= LOCKING_ANDX_LARGE_FILES
;
716 memset(cli
->outbuf
,'\0',smb_size
);
717 memset(cli
->inbuf
,'\0', smb_size
);
719 set_message(cli
->outbuf
,8,0,True
);
721 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
722 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
723 cli_setup_packet(cli
);
725 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
726 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
727 SCVAL(cli
->outbuf
,smb_vwv3
,ltype
);
728 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
729 SSVAL(cli
->outbuf
,smb_vwv6
,0);
730 SSVAL(cli
->outbuf
,smb_vwv7
,1);
732 p
= smb_buf(cli
->outbuf
);
733 SIVAL(p
, 0, cli
->pid
);
734 SOFF_T_R(p
, 4, offset
);
735 SOFF_T_R(p
, 12, len
);
738 cli_setup_bcc(cli
, p
);
742 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 5*1000);
745 if (!cli_receive_smb(cli
)) {
746 cli
->timeout
= saved_timeout
;
750 cli
->timeout
= saved_timeout
;
752 if (cli_is_error(cli
)) {
759 /****************************************************************************
760 Unlock a file with 64 bit offsets.
761 ****************************************************************************/
763 BOOL
cli_unlock64(struct cli_state
*cli
, int fnum
, SMB_BIG_UINT offset
, SMB_BIG_UINT len
)
767 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
768 return cli_unlock(cli
, fnum
, offset
, len
);
771 memset(cli
->outbuf
,'\0',smb_size
);
772 memset(cli
->inbuf
,'\0',smb_size
);
774 set_message(cli
->outbuf
,8,0,True
);
776 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
777 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
778 cli_setup_packet(cli
);
780 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
781 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
782 SCVAL(cli
->outbuf
,smb_vwv3
,LOCKING_ANDX_LARGE_FILES
);
783 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
784 SSVAL(cli
->outbuf
,smb_vwv6
,1);
785 SSVAL(cli
->outbuf
,smb_vwv7
,0);
787 p
= smb_buf(cli
->outbuf
);
788 SIVAL(p
, 0, cli
->pid
);
789 SOFF_T_R(p
, 4, offset
);
790 SOFF_T_R(p
, 12, len
);
792 cli_setup_bcc(cli
, p
);
794 if (!cli_receive_smb(cli
)) {
798 if (cli_is_error(cli
)) {
806 /****************************************************************************
807 Do a SMBgetattrE call.
808 ****************************************************************************/
810 BOOL
cli_getattrE(struct cli_state
*cli
, int fd
,
811 uint16
*attr
, SMB_BIG_UINT
*size
,
812 time_t *c_time
, time_t *a_time
, time_t *m_time
)
814 memset(cli
->outbuf
,'\0',smb_size
);
815 memset(cli
->inbuf
,'\0',smb_size
);
817 set_message(cli
->outbuf
,1,0,True
);
819 SCVAL(cli
->outbuf
,smb_com
,SMBgetattrE
);
820 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
821 cli_setup_packet(cli
);
823 SSVAL(cli
->outbuf
,smb_vwv0
,fd
);
826 if (!cli_receive_smb(cli
)) {
830 if (cli_is_error(cli
)) {
835 *size
= IVAL(cli
->inbuf
, smb_vwv6
);
839 *attr
= SVAL(cli
->inbuf
,smb_vwv10
);
843 *c_time
= make_unix_date3(cli
->inbuf
+smb_vwv0
);
847 *a_time
= make_unix_date3(cli
->inbuf
+smb_vwv2
);
851 *m_time
= make_unix_date3(cli
->inbuf
+smb_vwv4
);
857 /****************************************************************************
859 ****************************************************************************/
861 BOOL
cli_getatr(struct cli_state
*cli
, const char *fname
,
862 uint16
*attr
, size_t *size
, time_t *t
)
866 memset(cli
->outbuf
,'\0',smb_size
);
867 memset(cli
->inbuf
,'\0',smb_size
);
869 set_message(cli
->outbuf
,0,0,True
);
871 SCVAL(cli
->outbuf
,smb_com
,SMBgetatr
);
872 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
873 cli_setup_packet(cli
);
875 p
= smb_buf(cli
->outbuf
);
877 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
879 cli_setup_bcc(cli
, p
);
882 if (!cli_receive_smb(cli
)) {
886 if (cli_is_error(cli
)) {
891 *size
= IVAL(cli
->inbuf
, smb_vwv3
);
895 *t
= make_unix_date3(cli
->inbuf
+smb_vwv1
);
899 *attr
= SVAL(cli
->inbuf
,smb_vwv0
);
906 /****************************************************************************
908 ****************************************************************************/
910 BOOL
cli_setatr(struct cli_state
*cli
, const char *fname
, uint16 attr
, time_t t
)
914 memset(cli
->outbuf
,'\0',smb_size
);
915 memset(cli
->inbuf
,'\0',smb_size
);
917 set_message(cli
->outbuf
,8,0,True
);
919 SCVAL(cli
->outbuf
,smb_com
,SMBsetatr
);
920 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
921 cli_setup_packet(cli
);
923 SSVAL(cli
->outbuf
,smb_vwv0
, attr
);
924 put_dos_date3(cli
->outbuf
,smb_vwv1
, t
);
926 p
= smb_buf(cli
->outbuf
);
928 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
931 cli_setup_bcc(cli
, p
);
934 if (!cli_receive_smb(cli
)) {
938 if (cli_is_error(cli
)) {
945 /****************************************************************************
946 Check for existance of a dir.
947 ****************************************************************************/
948 BOOL
cli_chkpath(struct cli_state
*cli
, const char *path
)
954 trim_string(path2
,NULL
,"\\");
955 if (!*path2
) *path2
= '\\';
957 memset(cli
->outbuf
,'\0',smb_size
);
958 set_message(cli
->outbuf
,0,0,True
);
959 SCVAL(cli
->outbuf
,smb_com
,SMBchkpth
);
960 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
961 cli_setup_packet(cli
);
962 p
= smb_buf(cli
->outbuf
);
964 p
+= clistr_push(cli
, p
, path2
, -1, STR_TERMINATE
);
966 cli_setup_bcc(cli
, p
);
969 if (!cli_receive_smb(cli
)) {
973 if (cli_is_error(cli
)) return False
;
978 /****************************************************************************
980 ****************************************************************************/
982 BOOL
cli_dskattr(struct cli_state
*cli
, int *bsize
, int *total
, int *avail
)
984 memset(cli
->outbuf
,'\0',smb_size
);
985 set_message(cli
->outbuf
,0,0,True
);
986 SCVAL(cli
->outbuf
,smb_com
,SMBdskattr
);
987 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
988 cli_setup_packet(cli
);
991 if (!cli_receive_smb(cli
)) {
995 *bsize
= SVAL(cli
->inbuf
,smb_vwv1
)*SVAL(cli
->inbuf
,smb_vwv2
);
996 *total
= SVAL(cli
->inbuf
,smb_vwv0
);
997 *avail
= SVAL(cli
->inbuf
,smb_vwv3
);
1002 /****************************************************************************
1003 Create and open a temporary file.
1004 ****************************************************************************/
1006 int cli_ctemp(struct cli_state
*cli
, const char *path
, char **tmp_path
)
1011 memset(cli
->outbuf
,'\0',smb_size
);
1012 memset(cli
->inbuf
,'\0',smb_size
);
1014 set_message(cli
->outbuf
,3,0,True
);
1016 SCVAL(cli
->outbuf
,smb_com
,SMBctemp
);
1017 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1018 cli_setup_packet(cli
);
1020 SSVAL(cli
->outbuf
,smb_vwv0
,0);
1021 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
1023 p
= smb_buf(cli
->outbuf
);
1025 p
+= clistr_push(cli
, p
, path
, -1, STR_TERMINATE
);
1027 cli_setup_bcc(cli
, p
);
1030 if (!cli_receive_smb(cli
)) {
1034 if (cli_is_error(cli
)) {
1038 /* despite the spec, the result has a -1, followed by
1039 length, followed by name */
1040 p
= smb_buf(cli
->inbuf
);
1042 len
= smb_buflen(cli
->inbuf
) - 4;
1043 if (len
<= 0) return -1;
1047 clistr_pull(cli
, path2
, p
,
1048 sizeof(path2
), len
, STR_ASCII
);
1049 *tmp_path
= strdup(path2
);
1052 return SVAL(cli
->inbuf
,smb_vwv0
);
1057 send a raw ioctl - used by the torture code
1059 NTSTATUS
cli_raw_ioctl(struct cli_state
*cli
, int fnum
, uint32 code
, DATA_BLOB
*blob
)
1061 memset(cli
->outbuf
,'\0',smb_size
);
1062 memset(cli
->inbuf
,'\0',smb_size
);
1064 set_message(cli
->outbuf
, 3, 0, True
);
1065 SCVAL(cli
->outbuf
,smb_com
,SMBioctl
);
1066 cli_setup_packet(cli
);
1068 SSVAL(cli
->outbuf
, smb_vwv0
, fnum
);
1069 SSVAL(cli
->outbuf
, smb_vwv1
, code
>>16);
1070 SSVAL(cli
->outbuf
, smb_vwv2
, (code
&0xFFFF));
1073 if (!cli_receive_smb(cli
)) {
1074 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
1077 if (cli_is_error(cli
)) {
1078 return cli_nt_error(cli
);
1081 *blob
= data_blob(NULL
, 0);
1083 return NT_STATUS_OK
;