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 if (cli->use_oplocks)
186 SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
188 SIVAL(cli->outbuf,smb_ntcreate_Flags, 0);
189 SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0);
190 SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f);
191 SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0);
192 SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03);
193 SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01);
194 SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0);
195 SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02);
196 SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname));
198 p = smb_buf(cli->outbuf);
201 p = skip_string(p,1);
204 if (!cli_receive_smb(cli)) {
208 if (CVAL(cli->inbuf,smb_rcls) != 0) {
212 return SVAL(cli->inbuf,smb_vwv2 + 1);
216 /****************************************************************************
218 WARNING: if you open with O_WRONLY then getattrE won't work!
219 ****************************************************************************/
220 int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
224 unsigned accessmode=0;
228 if (!(flags & O_EXCL)) {
235 accessmode = (share_mode<<4);
237 if ((flags & O_ACCMODE) == O_RDWR) {
239 } else if ((flags & O_ACCMODE) == O_WRONLY) {
244 if ((flags & O_SYNC) == O_SYNC) {
245 accessmode |= (1<<14);
249 if (share_mode == DENY_FCB) {
253 memset(cli->outbuf,'\0',smb_size);
254 memset(cli->inbuf,'\0',smb_size);
256 set_message(cli->outbuf,15,1 + strlen(fname),True);
258 CVAL(cli->outbuf,smb_com) = SMBopenX;
259 SSVAL(cli->outbuf,smb_tid,cli->cnum);
260 cli_setup_packet(cli);
262 SSVAL(cli->outbuf,smb_vwv0,0xFF);
263 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
264 SSVAL(cli->outbuf,smb_vwv3,accessmode);
265 SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
266 SSVAL(cli->outbuf,smb_vwv5,0);
267 SSVAL(cli->outbuf,smb_vwv8,openfn);
269 if (cli->use_oplocks) {
270 /* if using oplocks then ask for a batch oplock via
271 core and extended methods */
272 CVAL(cli->outbuf,smb_flg) |=
273 FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
274 SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
277 p = smb_buf(cli->outbuf);
280 p = skip_string(p,1);
283 if (!cli_receive_smb(cli)) {
287 if (CVAL(cli->inbuf,smb_rcls) != 0) {
291 return SVAL(cli->inbuf,smb_vwv2);
297 /****************************************************************************
299 ****************************************************************************/
300 BOOL cli_close(struct cli_state *cli, int fnum)
302 memset(cli->outbuf,'\0',smb_size);
303 memset(cli->inbuf,'\0',smb_size);
305 set_message(cli->outbuf,3,0,True);
307 CVAL(cli->outbuf,smb_com) = SMBclose;
308 SSVAL(cli->outbuf,smb_tid,cli->cnum);
309 cli_setup_packet(cli);
311 SSVAL(cli->outbuf,smb_vwv0,fnum);
312 SIVALS(cli->outbuf,smb_vwv1,-1);
315 if (!cli_receive_smb(cli)) {
319 if (CVAL(cli->inbuf,smb_rcls) != 0) {
327 /****************************************************************************
329 ****************************************************************************/
330 BOOL cli_lock(struct cli_state *cli, int fnum,
331 uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
334 int saved_timeout = cli->timeout;
336 memset(cli->outbuf,'\0',smb_size);
337 memset(cli->inbuf,'\0', smb_size);
339 set_message(cli->outbuf,8,10,True);
341 CVAL(cli->outbuf,smb_com) = SMBlockingX;
342 SSVAL(cli->outbuf,smb_tid,cli->cnum);
343 cli_setup_packet(cli);
345 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
346 SSVAL(cli->outbuf,smb_vwv2,fnum);
347 CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0);
348 SIVALS(cli->outbuf, smb_vwv4, timeout);
349 SSVAL(cli->outbuf,smb_vwv6,0);
350 SSVAL(cli->outbuf,smb_vwv7,1);
352 p = smb_buf(cli->outbuf);
353 SSVAL(p, 0, cli->pid);
358 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
360 if (!cli_receive_smb(cli)) {
361 cli->timeout = saved_timeout;
365 cli->timeout = saved_timeout;
367 if (CVAL(cli->inbuf,smb_rcls) != 0) {
374 /****************************************************************************
376 ****************************************************************************/
377 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
381 memset(cli->outbuf,'\0',smb_size);
382 memset(cli->inbuf,'\0',smb_size);
384 set_message(cli->outbuf,8,10,True);
386 CVAL(cli->outbuf,smb_com) = SMBlockingX;
387 SSVAL(cli->outbuf,smb_tid,cli->cnum);
388 cli_setup_packet(cli);
390 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
391 SSVAL(cli->outbuf,smb_vwv2,fnum);
392 CVAL(cli->outbuf,smb_vwv3) = 0;
393 SIVALS(cli->outbuf, smb_vwv4, 0);
394 SSVAL(cli->outbuf,smb_vwv6,1);
395 SSVAL(cli->outbuf,smb_vwv7,0);
397 p = smb_buf(cli->outbuf);
398 SSVAL(p, 0, cli->pid);
403 if (!cli_receive_smb(cli)) {
407 if (CVAL(cli->inbuf,smb_rcls) != 0) {
415 /****************************************************************************
416 lock a file with 64 bit offsets
417 ****************************************************************************/
418 BOOL cli_lock64(struct cli_state *cli, int fnum,
419 SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type)
422 int saved_timeout = cli->timeout;
425 ltype = (lock_type == READ_LOCK? 1 : 0);
426 ltype |= LOCKING_ANDX_LARGE_FILES;
428 memset(cli->outbuf,'\0',smb_size);
429 memset(cli->inbuf,'\0', smb_size);
431 set_message(cli->outbuf,8,20,True);
433 CVAL(cli->outbuf,smb_com) = SMBlockingX;
434 SSVAL(cli->outbuf,smb_tid,cli->cnum);
435 cli_setup_packet(cli);
437 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
438 SSVAL(cli->outbuf,smb_vwv2,fnum);
439 CVAL(cli->outbuf,smb_vwv3) = ltype;
440 SIVALS(cli->outbuf, smb_vwv4, timeout);
441 SSVAL(cli->outbuf,smb_vwv6,0);
442 SSVAL(cli->outbuf,smb_vwv7,1);
444 p = smb_buf(cli->outbuf);
445 SIVAL(p, 0, cli->pid);
446 SIVAL(p, 4, (offset>>32));
447 SIVAL(p, 8, (offset&0xffffffff));
448 SIVAL(p, 12, (len>>32));
449 SIVAL(p, 16, (len&0xffffffff));
452 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
454 if (!cli_receive_smb(cli)) {
455 cli->timeout = saved_timeout;
459 cli->timeout = saved_timeout;
461 if (CVAL(cli->inbuf,smb_rcls) != 0) {
468 /****************************************************************************
469 unlock a file with 64 bit offsets
470 ****************************************************************************/
471 BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
475 memset(cli->outbuf,'\0',smb_size);
476 memset(cli->inbuf,'\0',smb_size);
478 set_message(cli->outbuf,8,20,True);
480 CVAL(cli->outbuf,smb_com) = SMBlockingX;
481 SSVAL(cli->outbuf,smb_tid,cli->cnum);
482 cli_setup_packet(cli);
484 CVAL(cli->outbuf,smb_vwv0) = 0xFF;
485 SSVAL(cli->outbuf,smb_vwv2,fnum);
486 CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES;
487 SIVALS(cli->outbuf, smb_vwv4, 0);
488 SSVAL(cli->outbuf,smb_vwv6,1);
489 SSVAL(cli->outbuf,smb_vwv7,0);
491 p = smb_buf(cli->outbuf);
492 SIVAL(p, 0, cli->pid);
493 SIVAL(p, 4, (offset>>32));
494 SIVAL(p, 8, (offset&0xffffffff));
495 SIVAL(p, 12, (len>>32));
496 SIVAL(p, 16, (len&0xffffffff));
499 if (!cli_receive_smb(cli)) {
503 if (CVAL(cli->inbuf,smb_rcls) != 0) {
514 /****************************************************************************
515 do a SMBgetattrE call
516 ****************************************************************************/
517 BOOL cli_getattrE(struct cli_state *cli, int fd,
518 uint16 *attr, size_t *size,
519 time_t *c_time, time_t *a_time, time_t *m_time)
521 memset(cli->outbuf,'\0',smb_size);
522 memset(cli->inbuf,'\0',smb_size);
524 set_message(cli->outbuf,1,0,True);
526 CVAL(cli->outbuf,smb_com) = SMBgetattrE;
527 SSVAL(cli->outbuf,smb_tid,cli->cnum);
528 cli_setup_packet(cli);
530 SSVAL(cli->outbuf,smb_vwv0,fd);
533 if (!cli_receive_smb(cli)) {
537 if (CVAL(cli->inbuf,smb_rcls) != 0) {
542 *size = IVAL(cli->inbuf, smb_vwv6);
546 *attr = SVAL(cli->inbuf,smb_vwv10);
550 *c_time = make_unix_date3(cli->inbuf+smb_vwv0);
554 *a_time = make_unix_date3(cli->inbuf+smb_vwv2);
558 *m_time = make_unix_date3(cli->inbuf+smb_vwv4);
565 /****************************************************************************
567 ****************************************************************************/
568 BOOL cli_getatr(struct cli_state *cli, char *fname,
569 uint16 *attr, size_t *size, time_t *t)
573 memset(cli->outbuf,'\0',smb_size);
574 memset(cli->inbuf,'\0',smb_size);
576 set_message(cli->outbuf,0,strlen(fname)+2,True);
578 CVAL(cli->outbuf,smb_com) = SMBgetatr;
579 SSVAL(cli->outbuf,smb_tid,cli->cnum);
580 cli_setup_packet(cli);
582 p = smb_buf(cli->outbuf);
585 unix_to_dos(p+1,True);
588 if (!cli_receive_smb(cli)) {
592 if (CVAL(cli->inbuf,smb_rcls) != 0) {
597 *size = IVAL(cli->inbuf, smb_vwv3);
601 *t = make_unix_date3(cli->inbuf+smb_vwv1);
605 *attr = SVAL(cli->inbuf,smb_vwv0);
613 /****************************************************************************
615 ****************************************************************************/
616 BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
620 memset(cli->outbuf,'\0',smb_size);
621 memset(cli->inbuf,'\0',smb_size);
623 set_message(cli->outbuf,8,strlen(fname)+4,True);
625 CVAL(cli->outbuf,smb_com) = SMBsetatr;
626 SSVAL(cli->outbuf,smb_tid,cli->cnum);
627 cli_setup_packet(cli);
629 SSVAL(cli->outbuf,smb_vwv0, attr);
630 put_dos_date3(cli->outbuf,smb_vwv1, t);
632 p = smb_buf(cli->outbuf);
635 unix_to_dos(p+1,True);
636 p = skip_string(p,1);
640 if (!cli_receive_smb(cli)) {
644 if (CVAL(cli->inbuf,smb_rcls) != 0) {
652 /****************************************************************************
653 check for existance of a dir
654 ****************************************************************************/
655 BOOL cli_chkpath(struct cli_state *cli, char *path)
660 safe_strcpy(path2,path,sizeof(pstring));
661 trim_string(path2,NULL,"\\");
662 if (!*path2) *path2 = '\\';
664 memset(cli->outbuf,'\0',smb_size);
665 set_message(cli->outbuf,0,4 + strlen(path2),True);
666 SCVAL(cli->outbuf,smb_com,SMBchkpth);
667 SSVAL(cli->outbuf,smb_tid,cli->cnum);
668 cli_setup_packet(cli);
669 p = smb_buf(cli->outbuf);
671 safe_strcpy(p,path2,strlen(path2));
675 if (!cli_receive_smb(cli)) {
679 if (cli_error(cli, NULL, NULL, NULL)) return False;
686 /****************************************************************************
688 ****************************************************************************/
689 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
691 memset(cli->outbuf,'\0',smb_size);
692 set_message(cli->outbuf,0,0,True);
693 CVAL(cli->outbuf,smb_com) = SMBdskattr;
694 SSVAL(cli->outbuf,smb_tid,cli->cnum);
695 cli_setup_packet(cli);
698 if (!cli_receive_smb(cli)) {
702 *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2);
703 *total = SVAL(cli->inbuf,smb_vwv0);
704 *avail = SVAL(cli->inbuf,smb_vwv3);