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.
24 /****************************************************************************
25 Hard/Symlink a file (UNIX extensions).
26 Creates new name (sym)linked to oldname.
27 ****************************************************************************/
29 static BOOL
cli_link_internal(struct cli_state
*cli
, const char *oldname
, const char *newname
, BOOL hard_link
)
31 unsigned int data_len
= 0;
32 unsigned int param_len
= 0;
33 uint16 setup
= TRANSACT2_SETPATHINFO
;
34 char param
[sizeof(pstring
)+6];
36 char *rparam
=NULL
, *rdata
=NULL
;
38 size_t oldlen
= 2*(strlen(oldname
)+1);
39 size_t newlen
= 2*(strlen(newname
)+1);
41 memset(param
, 0, sizeof(param
));
42 SSVAL(param
,0,hard_link
? SMB_SET_FILE_UNIX_HLINK
: SMB_SET_FILE_UNIX_LINK
);
45 p
+= clistr_push(cli
, p
, newname
, MIN(newlen
, sizeof(param
)-6), STR_TERMINATE
);
46 param_len
= PTR_DIFF(p
, param
);
49 p
+= clistr_push(cli
, p
, oldname
, MIN(oldlen
,sizeof(data
)), STR_TERMINATE
);
50 data_len
= PTR_DIFF(p
, data
);
52 if (!cli_send_trans(cli
, SMBtrans2
,
54 -1, 0, /* fid, flags */
55 &setup
, 1, 0, /* setup, length, max */
56 param
, param_len
, 2, /* param, length, max */
57 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
62 if (!cli_receive_trans(cli
, SMBtrans2
,
74 /****************************************************************************
75 Map standard UNIX permissions onto wire representations.
76 ****************************************************************************/
78 uint32
unix_perms_to_wire(mode_t perms
)
82 ret
|= ((perms
& S_IXOTH
) ? UNIX_X_OTH
: 0);
83 ret
|= ((perms
& S_IWOTH
) ? UNIX_W_OTH
: 0);
84 ret
|= ((perms
& S_IROTH
) ? UNIX_R_OTH
: 0);
85 ret
|= ((perms
& S_IXGRP
) ? UNIX_X_GRP
: 0);
86 ret
|= ((perms
& S_IWGRP
) ? UNIX_W_GRP
: 0);
87 ret
|= ((perms
& S_IRGRP
) ? UNIX_R_GRP
: 0);
88 ret
|= ((perms
& S_IXUSR
) ? UNIX_X_USR
: 0);
89 ret
|= ((perms
& S_IWUSR
) ? UNIX_W_USR
: 0);
90 ret
|= ((perms
& S_IRUSR
) ? UNIX_R_USR
: 0);
92 ret
|= ((perms
& S_ISVTX
) ? UNIX_STICKY
: 0);
95 ret
|= ((perms
& S_ISGID
) ? UNIX_SET_GID
: 0);
98 ret
|= ((perms
& S_ISUID
) ? UNIX_SET_UID
: 0);
103 /****************************************************************************
104 Map wire permissions to standard UNIX.
105 ****************************************************************************/
107 mode_t
wire_perms_to_unix(uint32 perms
)
109 mode_t ret
= (mode_t
)0;
111 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
112 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
113 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
114 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
115 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
116 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
117 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
118 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
119 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
121 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
124 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
127 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
132 /****************************************************************************
133 Return the file type from the wire filetype for UNIX extensions.
134 ****************************************************************************/
136 static mode_t
unix_filetype_from_wire(uint32 wire_type
)
144 case UNIX_TYPE_SYMLINK
:
148 case UNIX_TYPE_CHARDEV
:
152 case UNIX_TYPE_BLKDEV
:
160 case UNIX_TYPE_SOCKET
:
168 /****************************************************************************
169 Do a POSIX getfacl (UNIX extensions).
170 ****************************************************************************/
172 BOOL
cli_unix_getfacl(struct cli_state
*cli
, const char *name
, size_t *prb_size
, char **retbuf
)
174 unsigned int param_len
= 0;
175 unsigned int data_len
= 0;
176 uint16 setup
= TRANSACT2_QPATHINFO
;
177 char param
[sizeof(pstring
)+6];
178 char *rparam
=NULL
, *rdata
=NULL
;
183 SSVAL(p
, 0, SMB_QUERY_POSIX_ACL
);
185 p
+= clistr_push(cli
, p
, name
, sizeof(pstring
)-6, STR_TERMINATE
);
186 param_len
= PTR_DIFF(p
, param
);
188 if (!cli_send_trans(cli
, SMBtrans2
,
190 -1, 0, /* fid, flags */
191 &setup
, 1, 0, /* setup, length, max */
192 param
, param_len
, 2, /* param, length, max */
193 NULL
, 0, cli
->max_xmit
/* data, length, max */
198 if (!cli_receive_trans(cli
, SMBtrans2
,
200 &rdata
, &data_len
)) {
212 *prb_size
= (size_t)data_len
;
217 /****************************************************************************
218 Stat a file (UNIX extensions).
219 ****************************************************************************/
221 BOOL
cli_unix_stat(struct cli_state
*cli
, const char *name
, SMB_STRUCT_STAT
*sbuf
)
223 unsigned int param_len
= 0;
224 unsigned int data_len
= 0;
225 uint16 setup
= TRANSACT2_QPATHINFO
;
226 char param
[sizeof(pstring
)+6];
227 char *rparam
=NULL
, *rdata
=NULL
;
234 SSVAL(p
, 0, SMB_QUERY_FILE_UNIX_BASIC
);
236 p
+= clistr_push(cli
, p
, name
, sizeof(pstring
)-6, STR_TERMINATE
);
237 param_len
= PTR_DIFF(p
, param
);
239 if (!cli_send_trans(cli
, SMBtrans2
,
241 -1, 0, /* fid, flags */
242 &setup
, 1, 0, /* setup, length, max */
243 param
, param_len
, 2, /* param, length, max */
244 NULL
, 0, cli
->max_xmit
/* data, length, max */
249 if (!cli_receive_trans(cli
, SMBtrans2
,
251 &rdata
, &data_len
)) {
261 sbuf
->st_size
= IVAL2_TO_SMB_BIG_UINT(rdata
,0); /* total size, in bytes */
262 sbuf
->st_blocks
= IVAL2_TO_SMB_BIG_UINT(rdata
,8); /* number of blocks allocated */
263 #if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
264 sbuf
->st_blocks
/= STAT_ST_BLOCKSIZE
;
266 /* assume 512 byte blocks */
267 sbuf
->st_blocks
/= 512;
269 set_ctimespec(sbuf
, interpret_long_date(rdata
+ 16)); /* time of last change */
270 set_atimespec(sbuf
, interpret_long_date(rdata
+ 24)); /* time of last access */
271 set_mtimespec(sbuf
, interpret_long_date(rdata
+ 32)); /* time of last modification */
273 sbuf
->st_uid
= (uid_t
) IVAL(rdata
,40); /* user ID of owner */
274 sbuf
->st_gid
= (gid_t
) IVAL(rdata
,48); /* group ID of owner */
275 sbuf
->st_mode
|= unix_filetype_from_wire(IVAL(rdata
, 56));
276 #if defined(HAVE_MAKEDEV)
278 uint32 dev_major
= IVAL(rdata
,60);
279 uint32 dev_minor
= IVAL(rdata
,68);
280 sbuf
->st_rdev
= makedev(dev_major
, dev_minor
);
283 sbuf
->st_ino
= (SMB_INO_T
)IVAL2_TO_SMB_BIG_UINT(rdata
,76); /* inode */
284 sbuf
->st_mode
|= wire_perms_to_unix(IVAL(rdata
,84)); /* protection */
285 sbuf
->st_nlink
= IVAL(rdata
,92); /* number of hard links */
293 /****************************************************************************
294 Symlink a file (UNIX extensions).
295 ****************************************************************************/
297 BOOL
cli_unix_symlink(struct cli_state
*cli
, const char *oldname
, const char *newname
)
299 return cli_link_internal(cli
, oldname
, newname
, False
);
302 /****************************************************************************
303 Hard a file (UNIX extensions).
304 ****************************************************************************/
306 BOOL
cli_unix_hardlink(struct cli_state
*cli
, const char *oldname
, const char *newname
)
308 return cli_link_internal(cli
, oldname
, newname
, True
);
311 /****************************************************************************
312 Chmod or chown a file internal (UNIX extensions).
313 ****************************************************************************/
315 static BOOL
cli_unix_chmod_chown_internal(struct cli_state
*cli
, const char *fname
, uint32 mode
, uint32 uid
, uint32 gid
)
317 unsigned int data_len
= 0;
318 unsigned int param_len
= 0;
319 uint16 setup
= TRANSACT2_SETPATHINFO
;
320 char param
[sizeof(pstring
)+6];
322 char *rparam
=NULL
, *rdata
=NULL
;
325 memset(param
, 0, sizeof(param
));
326 memset(data
, 0, sizeof(data
));
327 SSVAL(param
,0,SMB_SET_FILE_UNIX_BASIC
);
330 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
331 param_len
= PTR_DIFF(p
, param
);
339 if (!cli_send_trans(cli
, SMBtrans2
,
341 -1, 0, /* fid, flags */
342 &setup
, 1, 0, /* setup, length, max */
343 param
, param_len
, 2, /* param, length, max */
344 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
349 if (!cli_receive_trans(cli
, SMBtrans2
,
351 &rdata
, &data_len
)) {
361 /****************************************************************************
362 chmod a file (UNIX extensions).
363 ****************************************************************************/
365 BOOL
cli_unix_chmod(struct cli_state
*cli
, const char *fname
, mode_t mode
)
367 return cli_unix_chmod_chown_internal(cli
, fname
,
368 unix_perms_to_wire(mode
), SMB_UID_NO_CHANGE
, SMB_GID_NO_CHANGE
);
371 /****************************************************************************
372 chown a file (UNIX extensions).
373 ****************************************************************************/
375 BOOL
cli_unix_chown(struct cli_state
*cli
, const char *fname
, uid_t uid
, gid_t gid
)
377 return cli_unix_chmod_chown_internal(cli
, fname
, SMB_MODE_NO_CHANGE
, (uint32
)uid
, (uint32
)gid
);
380 /****************************************************************************
382 ****************************************************************************/
384 BOOL
cli_rename(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
388 memset(cli
->outbuf
,'\0',smb_size
);
389 memset(cli
->inbuf
,'\0',smb_size
);
391 set_message(cli
->outbuf
,1, 0, True
);
393 SCVAL(cli
->outbuf
,smb_com
,SMBmv
);
394 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
395 cli_setup_packet(cli
);
397 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
| aDIR
);
399 p
= smb_buf(cli
->outbuf
);
401 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
403 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
405 cli_setup_bcc(cli
, p
);
408 if (!cli_receive_smb(cli
))
411 if (cli_is_error(cli
))
417 /****************************************************************************
419 ****************************************************************************/
421 BOOL
cli_ntrename(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
425 memset(cli
->outbuf
,'\0',smb_size
);
426 memset(cli
->inbuf
,'\0',smb_size
);
428 set_message(cli
->outbuf
, 4, 0, True
);
430 SCVAL(cli
->outbuf
,smb_com
,SMBntrename
);
431 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
432 cli_setup_packet(cli
);
434 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
| aDIR
);
435 SSVAL(cli
->outbuf
,smb_vwv1
, RENAME_FLAG_RENAME
);
437 p
= smb_buf(cli
->outbuf
);
439 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
441 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
443 cli_setup_bcc(cli
, p
);
446 if (!cli_receive_smb(cli
))
449 if (cli_is_error(cli
))
455 /****************************************************************************
457 ****************************************************************************/
459 BOOL
cli_nt_hardlink(struct cli_state
*cli
, const char *fname_src
, const char *fname_dst
)
463 memset(cli
->outbuf
,'\0',smb_size
);
464 memset(cli
->inbuf
,'\0',smb_size
);
466 set_message(cli
->outbuf
, 4, 0, True
);
468 SCVAL(cli
->outbuf
,smb_com
,SMBntrename
);
469 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
470 cli_setup_packet(cli
);
472 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
| aDIR
);
473 SSVAL(cli
->outbuf
,smb_vwv1
, RENAME_FLAG_HARD_LINK
);
475 p
= smb_buf(cli
->outbuf
);
477 p
+= clistr_push(cli
, p
, fname_src
, -1, STR_TERMINATE
);
479 p
+= clistr_push(cli
, p
, fname_dst
, -1, STR_TERMINATE
);
481 cli_setup_bcc(cli
, p
);
484 if (!cli_receive_smb(cli
))
487 if (cli_is_error(cli
))
493 /****************************************************************************
495 ****************************************************************************/
497 BOOL
cli_unlink(struct cli_state
*cli
, const char *fname
)
501 memset(cli
->outbuf
,'\0',smb_size
);
502 memset(cli
->inbuf
,'\0',smb_size
);
504 set_message(cli
->outbuf
,1, 0,True
);
506 SCVAL(cli
->outbuf
,smb_com
,SMBunlink
);
507 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
508 cli_setup_packet(cli
);
510 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
);
512 p
= smb_buf(cli
->outbuf
);
514 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
516 cli_setup_bcc(cli
, p
);
518 if (!cli_receive_smb(cli
)) {
522 if (cli_is_error(cli
)) {
529 /****************************************************************************
531 ****************************************************************************/
533 BOOL
cli_mkdir(struct cli_state
*cli
, const char *dname
)
537 memset(cli
->outbuf
,'\0',smb_size
);
538 memset(cli
->inbuf
,'\0',smb_size
);
540 set_message(cli
->outbuf
,0, 0,True
);
542 SCVAL(cli
->outbuf
,smb_com
,SMBmkdir
);
543 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
544 cli_setup_packet(cli
);
546 p
= smb_buf(cli
->outbuf
);
548 p
+= clistr_push(cli
, p
, dname
, -1, STR_TERMINATE
);
550 cli_setup_bcc(cli
, p
);
553 if (!cli_receive_smb(cli
)) {
557 if (cli_is_error(cli
)) {
564 /****************************************************************************
566 ****************************************************************************/
568 BOOL
cli_rmdir(struct cli_state
*cli
, const char *dname
)
572 memset(cli
->outbuf
,'\0',smb_size
);
573 memset(cli
->inbuf
,'\0',smb_size
);
575 set_message(cli
->outbuf
,0, 0, True
);
577 SCVAL(cli
->outbuf
,smb_com
,SMBrmdir
);
578 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
579 cli_setup_packet(cli
);
581 p
= smb_buf(cli
->outbuf
);
583 p
+= clistr_push(cli
, p
, dname
, -1, STR_TERMINATE
);
585 cli_setup_bcc(cli
, p
);
588 if (!cli_receive_smb(cli
)) {
592 if (cli_is_error(cli
)) {
599 /****************************************************************************
600 Set or clear the delete on close flag.
601 ****************************************************************************/
603 int cli_nt_delete_on_close(struct cli_state
*cli
, int fnum
, BOOL flag
)
605 unsigned int data_len
= 1;
606 unsigned int param_len
= 6;
607 uint16 setup
= TRANSACT2_SETFILEINFO
;
610 char *rparam
=NULL
, *rdata
=NULL
;
612 memset(param
, 0, param_len
);
614 SSVAL(param
,2,SMB_SET_FILE_DISPOSITION_INFO
);
618 if (!cli_send_trans(cli
, SMBtrans2
,
620 -1, 0, /* fid, flags */
621 &setup
, 1, 0, /* setup, length, max */
622 param
, param_len
, 2, /* param, length, max */
623 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
628 if (!cli_receive_trans(cli
, SMBtrans2
,
630 &rdata
, &data_len
)) {
640 /****************************************************************************
641 Open a file - exposing the full horror of the NT API :-).
643 ****************************************************************************/
645 int cli_nt_create_full(struct cli_state
*cli
, const char *fname
,
646 uint32 CreatFlags
, uint32 DesiredAccess
,
647 uint32 FileAttributes
, uint32 ShareAccess
,
648 uint32 CreateDisposition
, uint32 CreateOptions
,
654 memset(cli
->outbuf
,'\0',smb_size
);
655 memset(cli
->inbuf
,'\0',smb_size
);
657 set_message(cli
->outbuf
,24,0,True
);
659 SCVAL(cli
->outbuf
,smb_com
,SMBntcreateX
);
660 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
661 cli_setup_packet(cli
);
663 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
664 if (cli
->use_oplocks
)
665 CreatFlags
|= (REQUEST_OPLOCK
|REQUEST_BATCH_OPLOCK
);
667 SIVAL(cli
->outbuf
,smb_ntcreate_Flags
, CreatFlags
);
668 SIVAL(cli
->outbuf
,smb_ntcreate_RootDirectoryFid
, 0x0);
669 SIVAL(cli
->outbuf
,smb_ntcreate_DesiredAccess
, DesiredAccess
);
670 SIVAL(cli
->outbuf
,smb_ntcreate_FileAttributes
, FileAttributes
);
671 SIVAL(cli
->outbuf
,smb_ntcreate_ShareAccess
, ShareAccess
);
672 SIVAL(cli
->outbuf
,smb_ntcreate_CreateDisposition
, CreateDisposition
);
673 SIVAL(cli
->outbuf
,smb_ntcreate_CreateOptions
, CreateOptions
);
674 SIVAL(cli
->outbuf
,smb_ntcreate_ImpersonationLevel
, 0x02);
675 SCVAL(cli
->outbuf
,smb_ntcreate_SecurityFlags
, SecuityFlags
);
677 p
= smb_buf(cli
->outbuf
);
678 /* this alignment and termination is critical for netapp filers. Don't change */
679 p
+= clistr_align_out(cli
, p
, 0);
680 len
= clistr_push(cli
, p
, fname
, -1, 0);
682 SSVAL(cli
->outbuf
,smb_ntcreate_NameLength
, len
);
683 /* sigh. this copes with broken netapp filer behaviour */
684 p
+= clistr_push(cli
, p
, "", -1, STR_TERMINATE
);
686 cli_setup_bcc(cli
, p
);
689 if (!cli_receive_smb(cli
)) {
693 if (cli_is_error(cli
)) {
697 return SVAL(cli
->inbuf
,smb_vwv2
+ 1);
700 /****************************************************************************
702 ****************************************************************************/
704 int cli_nt_create(struct cli_state
*cli
, const char *fname
, uint32 DesiredAccess
)
706 return cli_nt_create_full(cli
, fname
, 0, DesiredAccess
, 0,
707 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0x0, 0x0);
710 /****************************************************************************
712 WARNING: if you open with O_WRONLY then getattrE won't work!
713 ****************************************************************************/
715 int cli_open(struct cli_state
*cli
, const char *fname
, int flags
, int share_mode
)
719 unsigned accessmode
=0;
723 if (!(flags
& O_EXCL
)) {
730 accessmode
= (share_mode
<<4);
732 if ((flags
& O_ACCMODE
) == O_RDWR
) {
734 } else if ((flags
& O_ACCMODE
) == O_WRONLY
) {
739 if ((flags
& O_SYNC
) == O_SYNC
) {
740 accessmode
|= (1<<14);
744 if (share_mode
== DENY_FCB
) {
748 memset(cli
->outbuf
,'\0',smb_size
);
749 memset(cli
->inbuf
,'\0',smb_size
);
751 set_message(cli
->outbuf
,15,0,True
);
753 SCVAL(cli
->outbuf
,smb_com
,SMBopenX
);
754 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
755 cli_setup_packet(cli
);
757 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
758 SSVAL(cli
->outbuf
,smb_vwv2
,0); /* no additional info */
759 SSVAL(cli
->outbuf
,smb_vwv3
,accessmode
);
760 SSVAL(cli
->outbuf
,smb_vwv4
,aSYSTEM
| aHIDDEN
);
761 SSVAL(cli
->outbuf
,smb_vwv5
,0);
762 SSVAL(cli
->outbuf
,smb_vwv8
,openfn
);
764 if (cli
->use_oplocks
) {
765 /* if using oplocks then ask for a batch oplock via
766 core and extended methods */
767 SCVAL(cli
->outbuf
,smb_flg
, CVAL(cli
->outbuf
,smb_flg
)|
768 FLAG_REQUEST_OPLOCK
|FLAG_REQUEST_BATCH_OPLOCK
);
769 SSVAL(cli
->outbuf
,smb_vwv2
,SVAL(cli
->outbuf
,smb_vwv2
) | 6);
772 p
= smb_buf(cli
->outbuf
);
773 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
775 cli_setup_bcc(cli
, p
);
778 if (!cli_receive_smb(cli
)) {
782 if (cli_is_error(cli
)) {
786 return SVAL(cli
->inbuf
,smb_vwv2
);
789 /****************************************************************************
791 ****************************************************************************/
793 BOOL
cli_close(struct cli_state
*cli
, int fnum
)
795 memset(cli
->outbuf
,'\0',smb_size
);
796 memset(cli
->inbuf
,'\0',smb_size
);
798 set_message(cli
->outbuf
,3,0,True
);
800 SCVAL(cli
->outbuf
,smb_com
,SMBclose
);
801 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
802 cli_setup_packet(cli
);
804 SSVAL(cli
->outbuf
,smb_vwv0
,fnum
);
805 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
808 if (!cli_receive_smb(cli
)) {
812 return !cli_is_error(cli
);
816 /****************************************************************************
817 send a lock with a specified locktype
818 this is used for testing LOCKING_ANDX_CANCEL_LOCK
819 ****************************************************************************/
821 NTSTATUS
cli_locktype(struct cli_state
*cli
, int fnum
,
822 uint32 offset
, uint32 len
, int timeout
, unsigned char locktype
)
825 int saved_timeout
= cli
->timeout
;
827 memset(cli
->outbuf
,'\0',smb_size
);
828 memset(cli
->inbuf
,'\0', smb_size
);
830 set_message(cli
->outbuf
,8,0,True
);
832 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
833 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
834 cli_setup_packet(cli
);
836 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
837 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
838 SCVAL(cli
->outbuf
,smb_vwv3
,locktype
);
839 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
840 SSVAL(cli
->outbuf
,smb_vwv6
,0);
841 SSVAL(cli
->outbuf
,smb_vwv7
,1);
843 p
= smb_buf(cli
->outbuf
);
844 SSVAL(p
, 0, cli
->pid
);
850 cli_setup_bcc(cli
, p
);
855 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
858 if (!cli_receive_smb(cli
)) {
859 cli
->timeout
= saved_timeout
;
860 return NT_STATUS_UNSUCCESSFUL
;
863 cli
->timeout
= saved_timeout
;
865 return cli_nt_error(cli
);
868 /****************************************************************************
870 note that timeout is in units of 2 milliseconds
871 ****************************************************************************/
873 BOOL
cli_lock(struct cli_state
*cli
, int fnum
,
874 uint32 offset
, uint32 len
, int timeout
, enum brl_type lock_type
)
877 int saved_timeout
= cli
->timeout
;
879 memset(cli
->outbuf
,'\0',smb_size
);
880 memset(cli
->inbuf
,'\0', smb_size
);
882 set_message(cli
->outbuf
,8,0,True
);
884 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
885 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
886 cli_setup_packet(cli
);
888 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
889 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
890 SCVAL(cli
->outbuf
,smb_vwv3
,(lock_type
== READ_LOCK
? 1 : 0));
891 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
892 SSVAL(cli
->outbuf
,smb_vwv6
,0);
893 SSVAL(cli
->outbuf
,smb_vwv7
,1);
895 p
= smb_buf(cli
->outbuf
);
896 SSVAL(p
, 0, cli
->pid
);
902 cli_setup_bcc(cli
, p
);
907 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
*2 + 5*1000);
910 if (!cli_receive_smb(cli
)) {
911 cli
->timeout
= saved_timeout
;
915 cli
->timeout
= saved_timeout
;
917 if (cli_is_error(cli
)) {
924 /****************************************************************************
926 ****************************************************************************/
928 BOOL
cli_unlock(struct cli_state
*cli
, int fnum
, uint32 offset
, uint32 len
)
932 memset(cli
->outbuf
,'\0',smb_size
);
933 memset(cli
->inbuf
,'\0',smb_size
);
935 set_message(cli
->outbuf
,8,0,True
);
937 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
938 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
939 cli_setup_packet(cli
);
941 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
942 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
943 SCVAL(cli
->outbuf
,smb_vwv3
,0);
944 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
945 SSVAL(cli
->outbuf
,smb_vwv6
,1);
946 SSVAL(cli
->outbuf
,smb_vwv7
,0);
948 p
= smb_buf(cli
->outbuf
);
949 SSVAL(p
, 0, cli
->pid
);
953 cli_setup_bcc(cli
, p
);
955 if (!cli_receive_smb(cli
)) {
959 if (cli_is_error(cli
)) {
966 /****************************************************************************
967 Lock a file with 64 bit offsets.
968 ****************************************************************************/
970 BOOL
cli_lock64(struct cli_state
*cli
, int fnum
,
971 SMB_BIG_UINT offset
, SMB_BIG_UINT len
, int timeout
, enum brl_type lock_type
)
974 int saved_timeout
= cli
->timeout
;
977 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
978 return cli_lock(cli
, fnum
, offset
, len
, timeout
, lock_type
);
981 ltype
= (lock_type
== READ_LOCK
? 1 : 0);
982 ltype
|= LOCKING_ANDX_LARGE_FILES
;
984 memset(cli
->outbuf
,'\0',smb_size
);
985 memset(cli
->inbuf
,'\0', smb_size
);
987 set_message(cli
->outbuf
,8,0,True
);
989 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
990 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
991 cli_setup_packet(cli
);
993 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
994 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
995 SCVAL(cli
->outbuf
,smb_vwv3
,ltype
);
996 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
997 SSVAL(cli
->outbuf
,smb_vwv6
,0);
998 SSVAL(cli
->outbuf
,smb_vwv7
,1);
1000 p
= smb_buf(cli
->outbuf
);
1001 SIVAL(p
, 0, cli
->pid
);
1002 SOFF_T_R(p
, 4, offset
);
1003 SOFF_T_R(p
, 12, len
);
1006 cli_setup_bcc(cli
, p
);
1010 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 5*1000);
1013 if (!cli_receive_smb(cli
)) {
1014 cli
->timeout
= saved_timeout
;
1018 cli
->timeout
= saved_timeout
;
1020 if (cli_is_error(cli
)) {
1027 /****************************************************************************
1028 Unlock a file with 64 bit offsets.
1029 ****************************************************************************/
1031 BOOL
cli_unlock64(struct cli_state
*cli
, int fnum
, SMB_BIG_UINT offset
, SMB_BIG_UINT len
)
1035 if (! (cli
->capabilities
& CAP_LARGE_FILES
)) {
1036 return cli_unlock(cli
, fnum
, offset
, len
);
1039 memset(cli
->outbuf
,'\0',smb_size
);
1040 memset(cli
->inbuf
,'\0',smb_size
);
1042 set_message(cli
->outbuf
,8,0,True
);
1044 SCVAL(cli
->outbuf
,smb_com
,SMBlockingX
);
1045 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1046 cli_setup_packet(cli
);
1048 SCVAL(cli
->outbuf
,smb_vwv0
,0xFF);
1049 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
1050 SCVAL(cli
->outbuf
,smb_vwv3
,LOCKING_ANDX_LARGE_FILES
);
1051 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
1052 SSVAL(cli
->outbuf
,smb_vwv6
,1);
1053 SSVAL(cli
->outbuf
,smb_vwv7
,0);
1055 p
= smb_buf(cli
->outbuf
);
1056 SIVAL(p
, 0, cli
->pid
);
1057 SOFF_T_R(p
, 4, offset
);
1058 SOFF_T_R(p
, 12, len
);
1060 cli_setup_bcc(cli
, p
);
1062 if (!cli_receive_smb(cli
)) {
1066 if (cli_is_error(cli
)) {
1073 /****************************************************************************
1074 Get/unlock a POSIX lock on a file - internal function.
1075 ****************************************************************************/
1077 static BOOL
cli_posix_lock_internal(struct cli_state
*cli
, int fnum
,
1078 SMB_BIG_UINT offset
, SMB_BIG_UINT len
, BOOL wait_lock
, enum brl_type lock_type
)
1080 unsigned int param_len
= 4;
1081 unsigned int data_len
= POSIX_LOCK_DATA_SIZE
;
1082 uint16 setup
= TRANSACT2_SETFILEINFO
;
1084 unsigned char data
[POSIX_LOCK_DATA_SIZE
];
1085 char *rparam
=NULL
, *rdata
=NULL
;
1086 int saved_timeout
= cli
->timeout
;
1088 SSVAL(param
,0,fnum
);
1089 SSVAL(param
,2,SMB_SET_POSIX_LOCK
);
1091 switch (lock_type
) {
1093 SSVAL(data
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_READ
);
1096 SSVAL(data
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_WRITE
);
1099 SSVAL(data
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
1106 SSVAL(data
, POSIX_LOCK_FLAGS_OFFSET
, POSIX_LOCK_FLAG_WAIT
);
1107 cli
->timeout
= 0x7FFFFFFF;
1109 SSVAL(data
, POSIX_LOCK_FLAGS_OFFSET
, POSIX_LOCK_FLAG_NOWAIT
);
1112 SIVAL(data
, POSIX_LOCK_PID_OFFSET
, cli
->pid
);
1113 SOFF_T(data
, POSIX_LOCK_START_OFFSET
, offset
);
1114 SOFF_T(data
, POSIX_LOCK_LEN_OFFSET
, len
);
1116 if (!cli_send_trans(cli
, SMBtrans2
,
1118 -1, 0, /* fid, flags */
1119 &setup
, 1, 0, /* setup, length, max */
1120 param
, param_len
, 2, /* param, length, max */
1121 (char *)&data
, data_len
, cli
->max_xmit
/* data, length, max */
1123 cli
->timeout
= saved_timeout
;
1127 if (!cli_receive_trans(cli
, SMBtrans2
,
1128 &rparam
, ¶m_len
,
1129 &rdata
, &data_len
)) {
1130 cli
->timeout
= saved_timeout
;
1136 cli
->timeout
= saved_timeout
;
1144 /****************************************************************************
1146 ****************************************************************************/
1148 BOOL
cli_posix_lock(struct cli_state
*cli
, int fnum
,
1149 SMB_BIG_UINT offset
, SMB_BIG_UINT len
,
1150 BOOL wait_lock
, enum brl_type lock_type
)
1152 if (lock_type
!= READ_LOCK
&& lock_type
!= WRITE_LOCK
) {
1155 return cli_posix_lock_internal(cli
, fnum
, offset
, len
, wait_lock
, lock_type
);
1158 /****************************************************************************
1159 POSIX Unlock a file.
1160 ****************************************************************************/
1162 BOOL
cli_posix_unlock(struct cli_state
*cli
, int fnum
, SMB_BIG_UINT offset
, SMB_BIG_UINT len
)
1164 return cli_posix_lock_internal(cli
, fnum
, offset
, len
, False
, UNLOCK_LOCK
);
1167 /****************************************************************************
1168 POSIX Get any lock covering a file.
1169 ****************************************************************************/
1171 BOOL
cli_posix_getlock(struct cli_state
*cli
, int fnum
, SMB_BIG_UINT
*poffset
, SMB_BIG_UINT
*plen
)
1176 /****************************************************************************
1177 Do a SMBgetattrE call.
1178 ****************************************************************************/
1180 BOOL
cli_getattrE(struct cli_state
*cli
, int fd
,
1181 uint16
*attr
, SMB_OFF_T
*size
,
1182 time_t *change_time
,
1183 time_t *access_time
,
1186 memset(cli
->outbuf
,'\0',smb_size
);
1187 memset(cli
->inbuf
,'\0',smb_size
);
1189 set_message(cli
->outbuf
,1,0,True
);
1191 SCVAL(cli
->outbuf
,smb_com
,SMBgetattrE
);
1192 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1193 cli_setup_packet(cli
);
1195 SSVAL(cli
->outbuf
,smb_vwv0
,fd
);
1198 if (!cli_receive_smb(cli
)) {
1202 if (cli_is_error(cli
)) {
1207 *size
= IVAL(cli
->inbuf
, smb_vwv6
);
1211 *attr
= SVAL(cli
->inbuf
,smb_vwv10
);
1215 *change_time
= cli_make_unix_date2(cli
, cli
->inbuf
+smb_vwv0
);
1219 *access_time
= cli_make_unix_date2(cli
, cli
->inbuf
+smb_vwv2
);
1223 *write_time
= cli_make_unix_date2(cli
, cli
->inbuf
+smb_vwv4
);
1229 /****************************************************************************
1231 ****************************************************************************/
1233 BOOL
cli_getatr(struct cli_state
*cli
, const char *fname
,
1234 uint16
*attr
, SMB_OFF_T
*size
, time_t *write_time
)
1238 memset(cli
->outbuf
,'\0',smb_size
);
1239 memset(cli
->inbuf
,'\0',smb_size
);
1241 set_message(cli
->outbuf
,0,0,True
);
1243 SCVAL(cli
->outbuf
,smb_com
,SMBgetatr
);
1244 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1245 cli_setup_packet(cli
);
1247 p
= smb_buf(cli
->outbuf
);
1249 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
1251 cli_setup_bcc(cli
, p
);
1254 if (!cli_receive_smb(cli
)) {
1258 if (cli_is_error(cli
)) {
1263 *size
= IVAL(cli
->inbuf
, smb_vwv3
);
1267 *write_time
= cli_make_unix_date3(cli
, cli
->inbuf
+smb_vwv1
);
1271 *attr
= SVAL(cli
->inbuf
,smb_vwv0
);
1278 /****************************************************************************
1279 Do a SMBsetattrE call.
1280 ****************************************************************************/
1282 BOOL
cli_setattrE(struct cli_state
*cli
, int fd
,
1290 memset(cli
->outbuf
,'\0',smb_size
);
1291 memset(cli
->inbuf
,'\0',smb_size
);
1293 set_message(cli
->outbuf
,7,0,True
);
1295 SCVAL(cli
->outbuf
,smb_com
,SMBsetattrE
);
1296 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1297 cli_setup_packet(cli
);
1299 SSVAL(cli
->outbuf
,smb_vwv0
, fd
);
1300 cli_put_dos_date2(cli
, cli
->outbuf
,smb_vwv1
, change_time
);
1301 cli_put_dos_date2(cli
, cli
->outbuf
,smb_vwv3
, access_time
);
1302 cli_put_dos_date2(cli
, cli
->outbuf
,smb_vwv5
, write_time
);
1304 p
= smb_buf(cli
->outbuf
);
1307 cli_setup_bcc(cli
, p
);
1310 if (!cli_receive_smb(cli
)) {
1314 if (cli_is_error(cli
)) {
1321 /****************************************************************************
1322 Do a SMBsetatr call.
1323 ****************************************************************************/
1325 BOOL
cli_setatr(struct cli_state
*cli
, const char *fname
, uint16 attr
, time_t t
)
1329 memset(cli
->outbuf
,'\0',smb_size
);
1330 memset(cli
->inbuf
,'\0',smb_size
);
1332 set_message(cli
->outbuf
,8,0,True
);
1334 SCVAL(cli
->outbuf
,smb_com
,SMBsetatr
);
1335 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1336 cli_setup_packet(cli
);
1338 SSVAL(cli
->outbuf
,smb_vwv0
, attr
);
1339 cli_put_dos_date3(cli
, cli
->outbuf
,smb_vwv1
, t
);
1341 p
= smb_buf(cli
->outbuf
);
1343 p
+= clistr_push(cli
, p
, fname
, -1, STR_TERMINATE
);
1346 cli_setup_bcc(cli
, p
);
1349 if (!cli_receive_smb(cli
)) {
1353 if (cli_is_error(cli
)) {
1360 /****************************************************************************
1361 Check for existance of a dir.
1362 ****************************************************************************/
1363 BOOL
cli_chkpath(struct cli_state
*cli
, const char *path
)
1368 pstrcpy(path2
,path
);
1369 trim_char(path2
,'\0','\\');
1373 memset(cli
->outbuf
,'\0',smb_size
);
1374 set_message(cli
->outbuf
,0,0,True
);
1375 SCVAL(cli
->outbuf
,smb_com
,SMBchkpth
);
1376 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1377 cli_setup_packet(cli
);
1378 p
= smb_buf(cli
->outbuf
);
1380 p
+= clistr_push(cli
, p
, path2
, -1, STR_TERMINATE
);
1382 cli_setup_bcc(cli
, p
);
1385 if (!cli_receive_smb(cli
)) {
1389 if (cli_is_error(cli
)) return False
;
1394 /****************************************************************************
1396 ****************************************************************************/
1398 BOOL
cli_dskattr(struct cli_state
*cli
, int *bsize
, int *total
, int *avail
)
1400 memset(cli
->outbuf
,'\0',smb_size
);
1401 set_message(cli
->outbuf
,0,0,True
);
1402 SCVAL(cli
->outbuf
,smb_com
,SMBdskattr
);
1403 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1404 cli_setup_packet(cli
);
1407 if (!cli_receive_smb(cli
)) {
1411 *bsize
= SVAL(cli
->inbuf
,smb_vwv1
)*SVAL(cli
->inbuf
,smb_vwv2
);
1412 *total
= SVAL(cli
->inbuf
,smb_vwv0
);
1413 *avail
= SVAL(cli
->inbuf
,smb_vwv3
);
1418 /****************************************************************************
1419 Create and open a temporary file.
1420 ****************************************************************************/
1422 int cli_ctemp(struct cli_state
*cli
, const char *path
, char **tmp_path
)
1427 memset(cli
->outbuf
,'\0',smb_size
);
1428 memset(cli
->inbuf
,'\0',smb_size
);
1430 set_message(cli
->outbuf
,3,0,True
);
1432 SCVAL(cli
->outbuf
,smb_com
,SMBctemp
);
1433 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
1434 cli_setup_packet(cli
);
1436 SSVAL(cli
->outbuf
,smb_vwv0
,0);
1437 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
1439 p
= smb_buf(cli
->outbuf
);
1441 p
+= clistr_push(cli
, p
, path
, -1, STR_TERMINATE
);
1443 cli_setup_bcc(cli
, p
);
1446 if (!cli_receive_smb(cli
)) {
1450 if (cli_is_error(cli
)) {
1454 /* despite the spec, the result has a -1, followed by
1455 length, followed by name */
1456 p
= smb_buf(cli
->inbuf
);
1458 len
= smb_buflen(cli
->inbuf
) - 4;
1459 if (len
<= 0) return -1;
1463 clistr_pull(cli
, path2
, p
,
1464 sizeof(path2
), len
, STR_ASCII
);
1465 *tmp_path
= SMB_STRDUP(path2
);
1468 return SVAL(cli
->inbuf
,smb_vwv0
);
1473 send a raw ioctl - used by the torture code
1475 NTSTATUS
cli_raw_ioctl(struct cli_state
*cli
, int fnum
, uint32 code
, DATA_BLOB
*blob
)
1477 memset(cli
->outbuf
,'\0',smb_size
);
1478 memset(cli
->inbuf
,'\0',smb_size
);
1480 set_message(cli
->outbuf
, 3, 0, True
);
1481 SCVAL(cli
->outbuf
,smb_com
,SMBioctl
);
1482 cli_setup_packet(cli
);
1484 SSVAL(cli
->outbuf
, smb_vwv0
, fnum
);
1485 SSVAL(cli
->outbuf
, smb_vwv1
, code
>>16);
1486 SSVAL(cli
->outbuf
, smb_vwv2
, (code
&0xFFFF));
1489 if (!cli_receive_smb(cli
)) {
1490 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
1493 if (cli_is_error(cli
)) {
1494 return cli_nt_error(cli
);
1497 *blob
= data_blob(NULL
, 0);
1499 return NT_STATUS_OK
;
1502 /*********************************************************
1503 Set an extended attribute utility fn.
1504 *********************************************************/
1506 static BOOL
cli_set_ea(struct cli_state
*cli
, uint16 setup
, char *param
, unsigned int param_len
,
1507 const char *ea_name
, const char *ea_val
, size_t ea_len
)
1509 unsigned int data_len
= 0;
1511 char *rparam
=NULL
, *rdata
=NULL
;
1513 size_t ea_namelen
= strlen(ea_name
);
1515 if (ea_namelen
== 0 && ea_len
== 0) {
1517 data
= (char *)SMB_MALLOC(data_len
);
1522 SIVAL(p
,0,data_len
);
1524 data_len
= 4 + 4 + ea_namelen
+ 1 + ea_len
;
1525 data
= (char *)SMB_MALLOC(data_len
);
1530 SIVAL(p
,0,data_len
);
1532 SCVAL(p
, 0, 0); /* EA flags. */
1533 SCVAL(p
, 1, ea_namelen
);
1534 SSVAL(p
, 2, ea_len
);
1535 memcpy(p
+4, ea_name
, ea_namelen
+1); /* Copy in the name. */
1536 memcpy(p
+4+ea_namelen
+1, ea_val
, ea_len
);
1539 if (!cli_send_trans(cli
, SMBtrans2
,
1541 -1, 0, /* fid, flags */
1542 &setup
, 1, 0, /* setup, length, max */
1543 param
, param_len
, 2, /* param, length, max */
1544 data
, data_len
, cli
->max_xmit
/* data, length, max */
1549 if (!cli_receive_trans(cli
, SMBtrans2
,
1550 &rparam
, ¶m_len
,
1551 &rdata
, &data_len
)) {
1562 /*********************************************************
1563 Set an extended attribute on a pathname.
1564 *********************************************************/
1566 BOOL
cli_set_ea_path(struct cli_state
*cli
, const char *path
, const char *ea_name
, const char *ea_val
, size_t ea_len
)
1568 uint16 setup
= TRANSACT2_SETPATHINFO
;
1569 unsigned int param_len
= 0;
1570 char param
[sizeof(pstring
)+6];
1571 size_t srclen
= 2*(strlen(path
)+1);
1574 memset(param
, 0, sizeof(param
));
1575 SSVAL(param
,0,SMB_INFO_SET_EA
);
1578 p
+= clistr_push(cli
, p
, path
, MIN(srclen
, sizeof(param
)-6), STR_TERMINATE
);
1579 param_len
= PTR_DIFF(p
, param
);
1581 return cli_set_ea(cli
, setup
, param
, param_len
, ea_name
, ea_val
, ea_len
);
1584 /*********************************************************
1585 Set an extended attribute on an fnum.
1586 *********************************************************/
1588 BOOL
cli_set_ea_fnum(struct cli_state
*cli
, int fnum
, const char *ea_name
, const char *ea_val
, size_t ea_len
)
1591 uint16 setup
= TRANSACT2_SETFILEINFO
;
1593 memset(param
, 0, 6);
1594 SSVAL(param
,0,fnum
);
1595 SSVAL(param
,2,SMB_INFO_SET_EA
);
1597 return cli_set_ea(cli
, setup
, param
, 6, ea_name
, ea_val
, ea_len
);
1600 /*********************************************************
1601 Get an extended attribute list tility fn.
1602 *********************************************************/
1604 static BOOL
cli_get_ea_list(struct cli_state
*cli
,
1605 uint16 setup
, char *param
, unsigned int param_len
,
1608 struct ea_struct
**pea_list
)
1610 unsigned int data_len
= 0;
1611 unsigned int rparam_len
, rdata_len
;
1612 char *rparam
=NULL
, *rdata
=NULL
;
1617 struct ea_struct
*ea_list
;
1624 if (!cli_send_trans(cli
, SMBtrans2
,
1626 -1, 0, /* fid, flags */
1627 &setup
, 1, 0, /* setup, length, max */
1628 param
, param_len
, 10, /* param, length, max */
1629 NULL
, data_len
, cli
->max_xmit
/* data, length, max */
1634 if (!cli_receive_trans(cli
, SMBtrans2
,
1635 &rparam
, &rparam_len
,
1636 &rdata
, &rdata_len
)) {
1640 if (!rdata
|| rdata_len
< 4) {
1644 ea_size
= (size_t)IVAL(rdata
,0);
1645 if (ea_size
> rdata_len
) {
1650 /* No EA's present. */
1658 /* Validate the EA list and count it. */
1659 for (num_eas
= 0; ea_size
>= 4; num_eas
++) {
1660 unsigned int ea_namelen
= CVAL(p
,1);
1661 unsigned int ea_valuelen
= SVAL(p
,2);
1662 if (ea_namelen
== 0) {
1665 if (4 + ea_namelen
+ 1 + ea_valuelen
> ea_size
) {
1668 ea_size
-= 4 + ea_namelen
+ 1 + ea_valuelen
;
1669 p
+= 4 + ea_namelen
+ 1 + ea_valuelen
;
1677 *pnum_eas
= num_eas
;
1679 /* Caller only wants number of EA's. */
1684 ea_list
= TALLOC_ARRAY(ctx
, struct ea_struct
, num_eas
);
1689 ea_size
= (size_t)IVAL(rdata
,0);
1692 for (num_eas
= 0; num_eas
< *pnum_eas
; num_eas
++ ) {
1693 struct ea_struct
*ea
= &ea_list
[num_eas
];
1694 fstring unix_ea_name
;
1695 unsigned int ea_namelen
= CVAL(p
,1);
1696 unsigned int ea_valuelen
= SVAL(p
,2);
1698 ea
->flags
= CVAL(p
,0);
1699 unix_ea_name
[0] = '\0';
1700 pull_ascii_fstring(unix_ea_name
, p
+ 4);
1701 ea
->name
= talloc_strdup(ctx
, unix_ea_name
);
1702 /* Ensure the value is null terminated (in case it's a string). */
1703 ea
->value
= data_blob_talloc(ctx
, NULL
, ea_valuelen
+ 1);
1704 if (!ea
->value
.data
) {
1708 memcpy(ea
->value
.data
, p
+4+ea_namelen
+1, ea_valuelen
);
1710 ea
->value
.data
[ea_valuelen
] = 0;
1712 p
+= 4 + ea_namelen
+ 1 + ea_valuelen
;
1715 *pea_list
= ea_list
;
1725 /*********************************************************
1726 Get an extended attribute list from a pathname.
1727 *********************************************************/
1729 BOOL
cli_get_ea_list_path(struct cli_state
*cli
, const char *path
,
1732 struct ea_struct
**pea_list
)
1734 uint16 setup
= TRANSACT2_QPATHINFO
;
1735 unsigned int param_len
= 0;
1736 char param
[sizeof(pstring
)+6];
1741 SSVAL(p
, 0, SMB_INFO_QUERY_ALL_EAS
);
1743 p
+= clistr_push(cli
, p
, path
, sizeof(pstring
)-6, STR_TERMINATE
);
1744 param_len
= PTR_DIFF(p
, param
);
1746 return cli_get_ea_list(cli
, setup
, param
, param_len
, ctx
, pnum_eas
, pea_list
);
1749 /*********************************************************
1750 Get an extended attribute list from an fnum.
1751 *********************************************************/
1753 BOOL
cli_get_ea_list_fnum(struct cli_state
*cli
, int fnum
,
1756 struct ea_struct
**pea_list
)
1758 uint16 setup
= TRANSACT2_QFILEINFO
;
1761 memset(param
, 0, 6);
1762 SSVAL(param
,0,fnum
);
1763 SSVAL(param
,2,SMB_INFO_SET_EA
);
1765 return cli_get_ea_list(cli
, setup
, param
, 6, ctx
, pnum_eas
, pea_list
);