2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1998
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 /****************************************************************************
28 ****************************************************************************/
29 BOOL
cli_rename(struct cli_state
*cli
, char *fname_src
, char *fname_dst
)
33 memset(cli
->outbuf
,'\0',smb_size
);
34 memset(cli
->inbuf
,'\0',smb_size
);
36 set_message(cli
->outbuf
,1, 4 + strlen(fname_src
) + strlen(fname_dst
), True
);
38 CVAL(cli
->outbuf
,smb_com
) = SMBmv
;
39 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
40 cli_setup_packet(cli
);
42 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
| aDIR
);
44 p
= smb_buf(cli
->outbuf
);
54 if (!cli_receive_smb(cli
)) {
58 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
65 /****************************************************************************
67 ****************************************************************************/
68 BOOL
cli_unlink(struct cli_state
*cli
, char *fname
)
72 memset(cli
->outbuf
,'\0',smb_size
);
73 memset(cli
->inbuf
,'\0',smb_size
);
75 set_message(cli
->outbuf
,1, 2 + strlen(fname
),True
);
77 CVAL(cli
->outbuf
,smb_com
) = SMBunlink
;
78 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
79 cli_setup_packet(cli
);
81 SSVAL(cli
->outbuf
,smb_vwv0
,aSYSTEM
| aHIDDEN
);
83 p
= smb_buf(cli
->outbuf
);
89 if (!cli_receive_smb(cli
)) {
93 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
100 /****************************************************************************
102 ****************************************************************************/
103 BOOL
cli_mkdir(struct cli_state
*cli
, char *dname
)
107 memset(cli
->outbuf
,'\0',smb_size
);
108 memset(cli
->inbuf
,'\0',smb_size
);
110 set_message(cli
->outbuf
,0, 2 + strlen(dname
),True
);
112 CVAL(cli
->outbuf
,smb_com
) = SMBmkdir
;
113 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
114 cli_setup_packet(cli
);
116 p
= smb_buf(cli
->outbuf
);
122 if (!cli_receive_smb(cli
)) {
126 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
133 /****************************************************************************
135 ****************************************************************************/
136 BOOL
cli_rmdir(struct cli_state
*cli
, char *dname
)
140 memset(cli
->outbuf
,'\0',smb_size
);
141 memset(cli
->inbuf
,'\0',smb_size
);
143 set_message(cli
->outbuf
,0, 2 + strlen(dname
),True
);
145 CVAL(cli
->outbuf
,smb_com
) = SMBrmdir
;
146 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
147 cli_setup_packet(cli
);
149 p
= smb_buf(cli
->outbuf
);
155 if (!cli_receive_smb(cli
)) {
159 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
168 /****************************************************************************
170 ****************************************************************************/
171 int cli_nt_create(struct cli_state
*cli
, char *fname
)
175 memset(cli
->outbuf
,'\0',smb_size
);
176 memset(cli
->inbuf
,'\0',smb_size
);
178 set_message(cli
->outbuf
,24,1 + strlen(fname
),True
);
180 CVAL(cli
->outbuf
,smb_com
) = SMBntcreateX
;
181 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
182 cli_setup_packet(cli
);
184 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
185 SIVAL(cli
->outbuf
,smb_ntcreate_Flags
, 0x06);
186 SIVAL(cli
->outbuf
,smb_ntcreate_RootDirectoryFid
, 0x0);
187 SIVAL(cli
->outbuf
,smb_ntcreate_DesiredAccess
, 0x2019f);
188 SIVAL(cli
->outbuf
,smb_ntcreate_FileAttributes
, 0x0);
189 SIVAL(cli
->outbuf
,smb_ntcreate_ShareAccess
, 0x03);
190 SIVAL(cli
->outbuf
,smb_ntcreate_CreateDisposition
, 0x01);
191 SIVAL(cli
->outbuf
,smb_ntcreate_CreateOptions
, 0x0);
192 SIVAL(cli
->outbuf
,smb_ntcreate_ImpersonationLevel
, 0x02);
193 SSVAL(cli
->outbuf
,smb_ntcreate_NameLength
, strlen(fname
));
195 p
= smb_buf(cli
->outbuf
);
198 p
= skip_string(p
,1);
201 if (!cli_receive_smb(cli
)) {
205 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
209 return SVAL(cli
->inbuf
,smb_vwv2
+ 1);
213 /****************************************************************************
215 WARNING: if you open with O_WRONLY then getattrE won't work!
216 ****************************************************************************/
217 int cli_open(struct cli_state
*cli
, char *fname
, int flags
, int share_mode
)
221 unsigned accessmode
=0;
225 if (!(flags
& O_EXCL
)) {
232 accessmode
= (share_mode
<<4);
234 if ((flags
& O_ACCMODE
) == O_RDWR
) {
236 } else if ((flags
& O_ACCMODE
) == O_WRONLY
) {
241 if ((flags
& O_SYNC
) == O_SYNC
) {
242 accessmode
|= (1<<14);
246 if (share_mode
== DENY_FCB
) {
250 memset(cli
->outbuf
,'\0',smb_size
);
251 memset(cli
->inbuf
,'\0',smb_size
);
253 set_message(cli
->outbuf
,15,1 + strlen(fname
),True
);
255 CVAL(cli
->outbuf
,smb_com
) = SMBopenX
;
256 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
257 cli_setup_packet(cli
);
259 SSVAL(cli
->outbuf
,smb_vwv0
,0xFF);
260 SSVAL(cli
->outbuf
,smb_vwv2
,0); /* no additional info */
261 SSVAL(cli
->outbuf
,smb_vwv3
,accessmode
);
262 SSVAL(cli
->outbuf
,smb_vwv4
,aSYSTEM
| aHIDDEN
);
263 SSVAL(cli
->outbuf
,smb_vwv5
,0);
264 SSVAL(cli
->outbuf
,smb_vwv8
,openfn
);
266 if (cli
->use_oplocks
) {
267 /* if using oplocks then ask for a batch oplock via
268 core and extended methods */
269 CVAL(cli
->outbuf
,smb_flg
) |=
270 FLAG_REQUEST_OPLOCK
|FLAG_REQUEST_BATCH_OPLOCK
;
271 SSVAL(cli
->outbuf
,smb_vwv2
,SVAL(cli
->outbuf
,smb_vwv2
) | 6);
274 p
= smb_buf(cli
->outbuf
);
277 p
= skip_string(p
,1);
280 if (!cli_receive_smb(cli
)) {
284 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
288 return SVAL(cli
->inbuf
,smb_vwv2
);
294 /****************************************************************************
296 ****************************************************************************/
297 BOOL
cli_close(struct cli_state
*cli
, int fnum
)
299 memset(cli
->outbuf
,'\0',smb_size
);
300 memset(cli
->inbuf
,'\0',smb_size
);
302 set_message(cli
->outbuf
,3,0,True
);
304 CVAL(cli
->outbuf
,smb_com
) = SMBclose
;
305 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
306 cli_setup_packet(cli
);
308 SSVAL(cli
->outbuf
,smb_vwv0
,fnum
);
309 SIVALS(cli
->outbuf
,smb_vwv1
,-1);
312 if (!cli_receive_smb(cli
)) {
316 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
324 /****************************************************************************
326 ****************************************************************************/
327 BOOL
cli_lock(struct cli_state
*cli
, int fnum
,
328 uint32 offset
, uint32 len
, int timeout
, enum brl_type lock_type
)
331 int saved_timeout
= cli
->timeout
;
333 memset(cli
->outbuf
,'\0',smb_size
);
334 memset(cli
->inbuf
,'\0', smb_size
);
336 set_message(cli
->outbuf
,8,10,True
);
338 CVAL(cli
->outbuf
,smb_com
) = SMBlockingX
;
339 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
340 cli_setup_packet(cli
);
342 CVAL(cli
->outbuf
,smb_vwv0
) = 0xFF;
343 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
344 CVAL(cli
->outbuf
,smb_vwv3
) = (lock_type
== READ_LOCK
? 1 : 0);
345 SIVALS(cli
->outbuf
, smb_vwv4
, timeout
);
346 SSVAL(cli
->outbuf
,smb_vwv6
,0);
347 SSVAL(cli
->outbuf
,smb_vwv7
,1);
349 p
= smb_buf(cli
->outbuf
);
350 SSVAL(p
, 0, cli
->pid
);
355 cli
->timeout
= (timeout
== -1) ? 0x7FFFFFFF : (timeout
+ 2*1000);
357 if (!cli_receive_smb(cli
)) {
358 cli
->timeout
= saved_timeout
;
362 cli
->timeout
= saved_timeout
;
364 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
371 /****************************************************************************
373 ****************************************************************************/
374 BOOL
cli_unlock(struct cli_state
*cli
, int fnum
, uint32 offset
, uint32 len
)
378 memset(cli
->outbuf
,'\0',smb_size
);
379 memset(cli
->inbuf
,'\0',smb_size
);
381 set_message(cli
->outbuf
,8,10,True
);
383 CVAL(cli
->outbuf
,smb_com
) = SMBlockingX
;
384 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
385 cli_setup_packet(cli
);
387 CVAL(cli
->outbuf
,smb_vwv0
) = 0xFF;
388 SSVAL(cli
->outbuf
,smb_vwv2
,fnum
);
389 CVAL(cli
->outbuf
,smb_vwv3
) = 0;
390 SIVALS(cli
->outbuf
, smb_vwv4
, 0);
391 SSVAL(cli
->outbuf
,smb_vwv6
,1);
392 SSVAL(cli
->outbuf
,smb_vwv7
,0);
394 p
= smb_buf(cli
->outbuf
);
395 SSVAL(p
, 0, cli
->pid
);
400 if (!cli_receive_smb(cli
)) {
404 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
415 /****************************************************************************
416 do a SMBgetattrE call
417 ****************************************************************************/
418 BOOL
cli_getattrE(struct cli_state
*cli
, int fd
,
419 uint16
*attr
, size_t *size
,
420 time_t *c_time
, time_t *a_time
, time_t *m_time
)
422 memset(cli
->outbuf
,'\0',smb_size
);
423 memset(cli
->inbuf
,'\0',smb_size
);
425 set_message(cli
->outbuf
,1,0,True
);
427 CVAL(cli
->outbuf
,smb_com
) = SMBgetattrE
;
428 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
429 cli_setup_packet(cli
);
431 SSVAL(cli
->outbuf
,smb_vwv0
,fd
);
434 if (!cli_receive_smb(cli
)) {
438 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
443 *size
= IVAL(cli
->inbuf
, smb_vwv6
);
447 *attr
= SVAL(cli
->inbuf
,smb_vwv10
);
451 *c_time
= make_unix_date3(cli
->inbuf
+smb_vwv0
);
455 *a_time
= make_unix_date3(cli
->inbuf
+smb_vwv2
);
459 *m_time
= make_unix_date3(cli
->inbuf
+smb_vwv4
);
466 /****************************************************************************
468 ****************************************************************************/
469 BOOL
cli_getatr(struct cli_state
*cli
, char *fname
,
470 uint16
*attr
, size_t *size
, time_t *t
)
474 memset(cli
->outbuf
,'\0',smb_size
);
475 memset(cli
->inbuf
,'\0',smb_size
);
477 set_message(cli
->outbuf
,0,strlen(fname
)+2,True
);
479 CVAL(cli
->outbuf
,smb_com
) = SMBgetatr
;
480 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
481 cli_setup_packet(cli
);
483 p
= smb_buf(cli
->outbuf
);
486 unix_to_dos(p
+1,True
);
489 if (!cli_receive_smb(cli
)) {
493 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
498 *size
= IVAL(cli
->inbuf
, smb_vwv3
);
502 *t
= make_unix_date3(cli
->inbuf
+smb_vwv1
);
506 *attr
= SVAL(cli
->inbuf
,smb_vwv0
);
514 /****************************************************************************
516 ****************************************************************************/
517 BOOL
cli_setatr(struct cli_state
*cli
, char *fname
, uint16 attr
, time_t t
)
521 memset(cli
->outbuf
,'\0',smb_size
);
522 memset(cli
->inbuf
,'\0',smb_size
);
524 set_message(cli
->outbuf
,8,strlen(fname
)+4,True
);
526 CVAL(cli
->outbuf
,smb_com
) = SMBsetatr
;
527 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
528 cli_setup_packet(cli
);
530 SSVAL(cli
->outbuf
,smb_vwv0
, attr
);
531 put_dos_date3(cli
->outbuf
,smb_vwv1
, t
);
533 p
= smb_buf(cli
->outbuf
);
536 unix_to_dos(p
+1,True
);
537 p
= skip_string(p
,1);
541 if (!cli_receive_smb(cli
)) {
545 if (CVAL(cli
->inbuf
,smb_rcls
) != 0) {
553 /****************************************************************************
554 check for existance of a dir
555 ****************************************************************************/
556 BOOL
cli_chkpath(struct cli_state
*cli
, char *path
)
561 safe_strcpy(path2
,path
,sizeof(pstring
));
562 trim_string(path2
,NULL
,"\\");
563 if (!*path2
) *path2
= '\\';
565 memset(cli
->outbuf
,'\0',smb_size
);
566 set_message(cli
->outbuf
,0,4 + strlen(path2
),True
);
567 SCVAL(cli
->outbuf
,smb_com
,SMBchkpth
);
568 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
569 cli_setup_packet(cli
);
570 p
= smb_buf(cli
->outbuf
);
572 safe_strcpy(p
,path2
,strlen(path2
));
576 if (!cli_receive_smb(cli
)) {
580 if (cli_error(cli
, NULL
, NULL
, NULL
)) return False
;
587 /****************************************************************************
589 ****************************************************************************/
590 BOOL
cli_dskattr(struct cli_state
*cli
, int *bsize
, int *total
, int *avail
)
592 memset(cli
->outbuf
,'\0',smb_size
);
593 set_message(cli
->outbuf
,0,0,True
);
594 CVAL(cli
->outbuf
,smb_com
) = SMBdskattr
;
595 SSVAL(cli
->outbuf
,smb_tid
,cli
->cnum
);
596 cli_setup_packet(cli
);
599 if (!cli_receive_smb(cli
)) {
603 *bsize
= SVAL(cli
->inbuf
,smb_vwv1
)*SVAL(cli
->inbuf
,smb_vwv2
);
604 *total
= SVAL(cli
->inbuf
,smb_vwv0
);
605 *avail
= SVAL(cli
->inbuf
,smb_vwv3
);