2 Unix SMB/CIFS implementation.
3 Main SMB reply routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 1992-2004.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 This file handles most of the reply_ calls that the server
24 makes to handle specific protocols
29 /* look in server.c for some explanation of these variables */
30 extern enum protocol_types Protocol;
33 extern char magic_char;
34 extern int global_oplock_break;
35 unsigned int smb_echo_count = 0;
36 extern uint32 global_client_caps;
38 extern BOOL global_encrypted_passwords_negotiated;
40 /****************************************************************************
41 Ensure we check the path in *exactly* the same way as W2K.
42 We're assuming here that '/' is not the second byte in any multibyte char
43 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
45 ****************************************************************************/
47 NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_wcard_names)
50 const char *s = srcname;
51 NTSTATUS ret = NT_STATUS_OK;
52 BOOL start_of_name_component = True;
53 unsigned int num_bad_components = 0;
56 if (IS_DIRECTORY_SEP(*s)) {
58 * Safe to assume is not the second part of a mb char as this is handled below.
60 /* Eat multiple '/' or '\\' */
61 while (IS_DIRECTORY_SEP(*s)) {
64 if ((d != destname) && (*s != '\0')) {
65 /* We only care about non-leading or trailing '/' or '\\' */
69 start_of_name_component = True;
73 if (start_of_name_component) {
74 if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
75 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
78 * No mb char starts with '.' so we're safe checking the directory separator here.
81 /* If we just added a '/' - delete it */
82 if ((d > destname) && (*(d-1) == '/')) {
87 /* Are we at the start ? Can't go back further if so. */
89 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
92 /* Go back one level... */
93 /* We know this is safe as '/' cannot be part of a mb sequence. */
94 /* NOTE - if this assumption is invalid we are not in good shape... */
95 /* Decrement d first as d points to the *next* char to write into. */
96 for (d--; d > destname; d--) {
100 s += 2; /* Else go past the .. */
101 /* We're still at the start of a name component, just the previous one. */
103 if (num_bad_components) {
104 /* Hmmm. Should we only decrement the bad_components if
105 we're removing a bad component ? Need to check this. JRA. */
106 num_bad_components--;
111 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
112 /* Component of pathname can't be "." only. */
113 ret = NT_STATUS_OBJECT_NAME_INVALID;
114 num_bad_components++;
121 if (allow_wcard_names) {
130 return NT_STATUS_OBJECT_NAME_INVALID;
137 switch(next_mb_char_size(s)) {
148 DEBUG(0,("check_path_syntax: character length assumptions invalid !\n"));
150 return NT_STATUS_INVALID_PARAMETER;
153 if (start_of_name_component && num_bad_components) {
154 num_bad_components++;
156 start_of_name_component = False;
159 if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
160 /* For some strange reason being called from findfirst changes
161 the num_components number to cause the error return to change. JRA. */
162 if (allow_wcard_names) {
163 if (num_bad_components > 2) {
164 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
167 if (num_bad_components > 1) {
168 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
177 /****************************************************************************
178 Pull a string and check the path - provide for error return.
179 ****************************************************************************/
181 size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err, BOOL allow_wcard_names)
184 char *tmppath_ptr = tmppath;
187 SMB_ASSERT(dest_len == sizeof(pstring));
191 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
193 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
195 *err = check_path_syntax(dest, tmppath, allow_wcard_names);
199 /****************************************************************************
200 Reply to a special message.
201 ****************************************************************************/
203 int reply_special(char *inbuf,char *outbuf)
206 int msg_type = CVAL(inbuf,0);
207 int msg_flags = CVAL(inbuf,1);
211 static BOOL already_got_session = False;
215 memset(outbuf,'\0',smb_size);
217 smb_setlen(outbuf,0);
220 case 0x81: /* session request */
222 if (already_got_session) {
223 exit_server("multiple session request not permitted");
226 SCVAL(outbuf,0,0x82);
228 if (name_len(inbuf+4) > 50 ||
229 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
230 DEBUG(0,("Invalid name length in session request\n"));
233 name_extract(inbuf,4,name1);
234 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
235 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
238 set_local_machine_name(name1, True);
239 set_remote_machine_name(name2, True);
241 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
242 get_local_machine_name(), get_remote_machine_name(),
245 if (name_type == 'R') {
246 /* We are being asked for a pathworks session ---
248 SCVAL(outbuf, 0,0x83);
252 /* only add the client's machine name to the list
253 of possibly valid usernames if we are operating
254 in share mode security */
255 if (lp_security() == SEC_SHARE) {
256 add_session_user(get_remote_machine_name());
259 reload_services(True);
262 already_got_session = True;
265 case 0x89: /* session keepalive request
266 (some old clients produce this?) */
267 SCVAL(outbuf,0,SMBkeepalive);
271 case 0x82: /* positive session response */
272 case 0x83: /* negative session response */
273 case 0x84: /* retarget session response */
274 DEBUG(0,("Unexpected session response\n"));
277 case SMBkeepalive: /* session keepalive */
282 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
283 msg_type, msg_flags));
288 /****************************************************************************
290 ****************************************************************************/
292 int reply_tcon(connection_struct *conn,
293 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
300 uint16 vuid = SVAL(inbuf,smb_uid);
304 DATA_BLOB password_blob;
306 START_PROFILE(SMBtcon);
308 *service_buf = *password = *dev = 0;
310 p = smb_buf(inbuf)+1;
311 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
312 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
314 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
316 p = strrchr_m(service_buf,'\\');
320 service = service_buf;
323 password_blob = data_blob(password, pwlen+1);
325 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
327 data_blob_clear_free(&password_blob);
330 END_PROFILE(SMBtcon);
331 return ERROR_NT(nt_status);
334 outsize = set_message(outbuf,2,0,True);
335 SSVAL(outbuf,smb_vwv0,max_recv);
336 SSVAL(outbuf,smb_vwv1,conn->cnum);
337 SSVAL(outbuf,smb_tid,conn->cnum);
339 DEBUG(3,("tcon service=%s cnum=%d\n",
340 service, conn->cnum));
342 END_PROFILE(SMBtcon);
346 /****************************************************************************
347 Reply to a tcon and X.
348 ****************************************************************************/
350 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
355 /* what the cleint thinks the device is */
356 fstring client_devicetype;
357 /* what the server tells the client the share represents */
358 const char *server_devicetype;
360 uint16 vuid = SVAL(inbuf,smb_uid);
361 int passlen = SVAL(inbuf,smb_vwv3);
364 extern BOOL global_encrypted_passwords_negotiated;
366 START_PROFILE(SMBtconX);
368 *service = *client_devicetype = 0;
370 /* we might have to close an old one */
371 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
372 close_cnum(conn,vuid);
375 if (passlen > MAX_PASS_LEN) {
376 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
379 if (global_encrypted_passwords_negotiated) {
380 password = data_blob(smb_buf(inbuf),passlen);
382 password = data_blob(smb_buf(inbuf),passlen+1);
383 /* Ensure correct termination */
384 password.data[passlen]=0;
387 p = smb_buf(inbuf) + passlen;
388 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
391 * the service name can be either: \\server\share
392 * or share directly like on the DELL PowerVault 705
395 q = strchr_m(path+2,'\\');
397 END_PROFILE(SMBtconX);
398 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
400 fstrcpy(service,q+1);
403 fstrcpy(service,path);
405 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
407 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
409 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
411 data_blob_clear_free(&password);
414 END_PROFILE(SMBtconX);
415 return ERROR_NT(nt_status);
419 server_devicetype = "IPC";
420 else if ( IS_PRINT(conn) )
421 server_devicetype = "LPT1:";
423 server_devicetype = "A:";
425 if (Protocol < PROTOCOL_NT1) {
426 set_message(outbuf,2,0,True);
428 p += srvstr_push(outbuf, p, server_devicetype, -1,
429 STR_TERMINATE|STR_ASCII);
430 set_message_end(outbuf,p);
432 /* NT sets the fstype of IPC$ to the null string */
433 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
435 set_message(outbuf,3,0,True);
438 p += srvstr_push(outbuf, p, server_devicetype, -1,
439 STR_TERMINATE|STR_ASCII);
440 p += srvstr_push(outbuf, p, fstype, -1,
443 set_message_end(outbuf,p);
445 /* what does setting this bit do? It is set by NT4 and
446 may affect the ability to autorun mounted cdroms */
447 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
448 (lp_csc_policy(SNUM(conn)) << 2));
450 init_dfsroot(conn, inbuf, outbuf);
454 DEBUG(3,("tconX service=%s \n",
457 /* set the incoming and outgoing tid to the just created one */
458 SSVAL(inbuf,smb_tid,conn->cnum);
459 SSVAL(outbuf,smb_tid,conn->cnum);
461 END_PROFILE(SMBtconX);
462 return chain_reply(inbuf,outbuf,length,bufsize);
465 /****************************************************************************
466 Reply to an unknown type.
467 ****************************************************************************/
469 int reply_unknown(char *inbuf,char *outbuf)
472 type = CVAL(inbuf,smb_com);
474 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
475 smb_fn_name(type), type, type));
477 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
480 /****************************************************************************
482 ****************************************************************************/
484 int reply_ioctl(connection_struct *conn,
485 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
487 uint16 device = SVAL(inbuf,smb_vwv1);
488 uint16 function = SVAL(inbuf,smb_vwv2);
489 uint32 ioctl_code = (device << 16) + function;
490 int replysize, outsize;
492 START_PROFILE(SMBioctl);
494 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
496 switch (ioctl_code) {
497 case IOCTL_QUERY_JOB_INFO:
501 END_PROFILE(SMBioctl);
502 return(ERROR_DOS(ERRSRV,ERRnosupport));
505 outsize = set_message(outbuf,8,replysize+1,True);
506 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
507 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
508 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
509 p = smb_buf(outbuf) + 1; /* Allow for alignment */
511 switch (ioctl_code) {
512 case IOCTL_QUERY_JOB_INFO:
514 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
516 END_PROFILE(SMBioctl);
517 return(UNIXERROR(ERRDOS,ERRbadfid));
519 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
520 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
522 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
528 END_PROFILE(SMBioctl);
532 /****************************************************************************
534 ****************************************************************************/
536 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
541 BOOL bad_path = False;
542 SMB_STRUCT_STAT sbuf;
545 START_PROFILE(SMBchkpth);
547 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, False);
548 if (!NT_STATUS_IS_OK(status)) {
549 END_PROFILE(SMBchkpth);
550 return ERROR_NT(status);
553 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
555 unix_convert(name,conn,0,&bad_path,&sbuf);
557 END_PROFILE(SMBchkpth);
558 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
561 if (check_name(name,conn)) {
562 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
563 if (!(ok = S_ISDIR(sbuf.st_mode))) {
564 END_PROFILE(SMBchkpth);
565 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
570 /* We special case this - as when a Windows machine
571 is parsing a path is steps through the components
572 one at a time - if a component fails it expects
573 ERRbadpath, not ERRbadfile.
575 if(errno == ENOENT) {
577 * Windows returns different error codes if
578 * the parent directory is valid but not the
579 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
580 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
581 * if the path is invalid. This is different from set_bad_path_error()
582 * in the non-NT error case.
584 END_PROFILE(SMBchkpth);
585 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpath);
588 END_PROFILE(SMBchkpth);
589 return(UNIXERROR(ERRDOS,ERRbadpath));
592 outsize = set_message(outbuf,0,0,True);
593 DEBUG(3,("chkpth %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0)));
595 END_PROFILE(SMBchkpth);
599 /****************************************************************************
601 ****************************************************************************/
603 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
607 SMB_STRUCT_STAT sbuf;
612 BOOL bad_path = False;
616 START_PROFILE(SMBgetatr);
618 p = smb_buf(inbuf) + 1;
619 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status, False);
620 if (!NT_STATUS_IS_OK(status)) {
621 END_PROFILE(SMBgetatr);
622 return ERROR_NT(status);
625 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
627 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
628 under WfWg - weird! */
630 mode = aHIDDEN | aDIR;
631 if (!CAN_WRITE(conn))
637 unix_convert(fname,conn,0,&bad_path,&sbuf);
639 END_PROFILE(SMBgetatr);
640 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
642 if (check_name(fname,conn)) {
643 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
644 mode = dos_mode(conn,fname,&sbuf);
646 mtime = sbuf.st_mtime;
651 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
657 END_PROFILE(SMBgetatr);
658 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
661 outsize = set_message(outbuf,10,0,True);
663 SSVAL(outbuf,smb_vwv0,mode);
664 if(lp_dos_filetime_resolution(SNUM(conn)) )
665 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
667 put_dos_date3(outbuf,smb_vwv1,mtime);
668 SIVAL(outbuf,smb_vwv3,(uint32)size);
670 if (Protocol >= PROTOCOL_NT1)
671 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
673 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
675 END_PROFILE(SMBgetatr);
679 /****************************************************************************
681 ****************************************************************************/
683 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
690 SMB_STRUCT_STAT sbuf;
691 BOOL bad_path = False;
695 START_PROFILE(SMBsetatr);
697 p = smb_buf(inbuf) + 1;
698 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status, False);
699 if (!NT_STATUS_IS_OK(status)) {
700 END_PROFILE(SMBsetatr);
701 return ERROR_NT(status);
704 unix_convert(fname,conn,0,&bad_path,&sbuf);
706 END_PROFILE(SMBsetatr);
707 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
710 mode = SVAL(inbuf,smb_vwv0);
711 mtime = make_unix_date3(inbuf+smb_vwv1);
713 if (mode != FILE_ATTRIBUTE_NORMAL) {
714 if (VALID_STAT_OF_DIR(sbuf))
719 if (check_name(fname,conn)) {
720 ok = (file_set_dosmode(conn,fname,mode,&sbuf,False) == 0);
727 ok = set_filetime(conn,fname,mtime);
730 END_PROFILE(SMBsetatr);
731 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
734 outsize = set_message(outbuf,0,0,True);
736 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
738 END_PROFILE(SMBsetatr);
742 /****************************************************************************
744 ****************************************************************************/
746 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
749 SMB_BIG_UINT dfree,dsize,bsize;
750 START_PROFILE(SMBdskattr);
752 SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
754 outsize = set_message(outbuf,5,0,True);
756 if (Protocol <= PROTOCOL_LANMAN2) {
757 double total_space, free_space;
758 /* we need to scale this to a number that DOS6 can handle. We
759 use floating point so we can handle large drives on systems
760 that don't have 64 bit integers
762 we end up displaying a maximum of 2G to DOS systems
764 total_space = dsize * (double)bsize;
765 free_space = dfree * (double)bsize;
767 dsize = (total_space+63*512) / (64*512);
768 dfree = (free_space+63*512) / (64*512);
770 if (dsize > 0xFFFF) dsize = 0xFFFF;
771 if (dfree > 0xFFFF) dfree = 0xFFFF;
773 SSVAL(outbuf,smb_vwv0,dsize);
774 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
775 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
776 SSVAL(outbuf,smb_vwv3,dfree);
778 SSVAL(outbuf,smb_vwv0,dsize);
779 SSVAL(outbuf,smb_vwv1,bsize/512);
780 SSVAL(outbuf,smb_vwv2,512);
781 SSVAL(outbuf,smb_vwv3,dfree);
784 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
786 END_PROFILE(SMBdskattr);
790 /****************************************************************************
792 Can be called from SMBsearch, SMBffirst or SMBfunique.
793 ****************************************************************************/
795 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
805 unsigned int numentries = 0;
806 unsigned int maxentries = 0;
807 BOOL finished = False;
814 BOOL check_descend = False;
815 BOOL expect_close = False;
816 BOOL can_open = True;
817 BOOL bad_path = False;
819 START_PROFILE(SMBsearch);
821 *mask = *directory = *fname = 0;
823 /* If we were called as SMBffirst then we must expect close. */
824 if(CVAL(inbuf,smb_com) == SMBffirst)
827 outsize = set_message(outbuf,1,3,True);
828 maxentries = SVAL(inbuf,smb_vwv0);
829 dirtype = SVAL(inbuf,smb_vwv1);
830 p = smb_buf(inbuf) + 1;
831 p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status, True);
832 if (!NT_STATUS_IS_OK(nt_status)) {
833 END_PROFILE(SMBsearch);
834 return ERROR_NT(nt_status);
837 status_len = SVAL(p, 0);
840 /* dirtype &= ~aDIR; */
842 if (status_len == 0) {
843 SMB_STRUCT_STAT sbuf;
846 pstrcpy(directory,path);
848 unix_convert(directory,conn,0,&bad_path,&sbuf);
851 if (!check_name(directory,conn))
854 p = strrchr_m(dir2,'/');
863 p = strrchr_m(directory,'/');
869 if (strlen(directory) == 0)
870 pstrcpy(directory,".");
871 memset((char *)status,'\0',21);
872 SCVAL(status,0,(dirtype & 0x1F));
877 status_dirtype = CVAL(status,0) & 0x1F;
878 if (status_dirtype != (dirtype & 0x1F))
879 dirtype = status_dirtype;
881 conn->dirptr = dptr_fetch(status+12,&dptr_num);
884 string_set(&conn->dirpath,dptr_path(dptr_num));
885 pstrcpy(mask, dptr_wcard(dptr_num));
889 p = smb_buf(outbuf) + 3;
892 if (status_len == 0) {
893 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
896 END_PROFILE(SMBsearch);
897 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
899 END_PROFILE(SMBsearch);
900 return ERROR_DOS(ERRDOS,ERRnofids);
902 if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
903 END_PROFILE(SMBsearch);
904 return ERROR_DOS(ERRDOS,ERRnomem);
907 dirtype = dptr_attr(dptr_num);
910 DEBUG(4,("dptr_num is %d\n",dptr_num));
913 if ((dirtype&0x1F) == aVOLID) {
915 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
916 dptr_fill(p+12,dptr_num);
917 if (dptr_zero(p+12) && (status_len==0))
921 p += DIR_STRUCT_SIZE;
924 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
926 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
927 conn->dirpath,lp_dontdescend(SNUM(conn))));
928 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
929 check_descend = True;
931 for (i=numentries;(i<maxentries) && !finished;i++) {
932 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
935 make_dir_struct(p,mask,fname,size,mode,date);
936 dptr_fill(p+12,dptr_num);
938 p += DIR_STRUCT_SIZE;
948 /* If we were called as SMBffirst with smb_search_id == NULL
949 and no entries were found then return error and close dirptr
952 if (numentries == 0 || !ok) {
953 dptr_close(&dptr_num);
954 } else if(ok && expect_close && status_len == 0) {
955 /* Close the dptr - we know it's gone */
956 dptr_close(&dptr_num);
959 /* If we were called as SMBfunique, then we can close the dirptr now ! */
960 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique) {
961 dptr_close(&dptr_num);
964 if ((numentries == 0) && !ms_has_wild(mask)) {
965 return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles);
968 SSVAL(outbuf,smb_vwv0,numentries);
969 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
970 SCVAL(smb_buf(outbuf),0,5);
971 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
973 if (Protocol >= PROTOCOL_NT1)
974 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
976 outsize += DIR_STRUCT_SIZE*numentries;
977 smb_setlen(outbuf,outsize - 4);
979 if ((! *directory) && dptr_path(dptr_num))
980 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
982 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
983 smb_fn_name(CVAL(inbuf,smb_com)),
984 mask, directory, dirtype, numentries, maxentries ) );
986 END_PROFILE(SMBsearch);
990 /****************************************************************************
991 Reply to a fclose (stop directory search).
992 ****************************************************************************/
994 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1004 START_PROFILE(SMBfclose);
1006 outsize = set_message(outbuf,1,0,True);
1007 p = smb_buf(inbuf) + 1;
1008 p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, True);
1009 if (!NT_STATUS_IS_OK(err)) {
1010 END_PROFILE(SMBfclose);
1011 return ERROR_NT(err);
1014 status_len = SVAL(p,0);
1017 if (status_len == 0) {
1018 END_PROFILE(SMBfclose);
1019 return ERROR_DOS(ERRSRV,ERRsrverror);
1022 memcpy(status,p,21);
1024 if(dptr_fetch(status+12,&dptr_num)) {
1025 /* Close the dptr - we know it's gone */
1026 dptr_close(&dptr_num);
1029 SSVAL(outbuf,smb_vwv0,0);
1031 DEBUG(3,("search close\n"));
1033 END_PROFILE(SMBfclose);
1037 /****************************************************************************
1039 ****************************************************************************/
1041 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1050 SMB_STRUCT_STAT sbuf;
1051 BOOL bad_path = False;
1053 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1054 uint16 dos_attr = SVAL(inbuf,smb_vwv1);
1056 START_PROFILE(SMBopen);
1058 share_mode = SVAL(inbuf,smb_vwv0);
1060 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 END_PROFILE(SMBopen);
1063 return ERROR_NT(status);
1066 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1068 unix_convert(fname,conn,0,&bad_path,&sbuf);
1070 END_PROFILE(SMBopen);
1071 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1074 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1075 (uint32)dos_attr, oplock_request,&rmode,NULL);
1078 END_PROFILE(SMBopen);
1079 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1080 /* We have re-scheduled this call. */
1081 clear_cached_errors();
1084 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1087 size = sbuf.st_size;
1088 fmode = dos_mode(conn,fname,&sbuf);
1089 mtime = sbuf.st_mtime;
1092 DEBUG(3,("attempt to open a directory %s\n",fname));
1093 close_file(fsp,False);
1094 END_PROFILE(SMBopen);
1095 return ERROR_DOS(ERRDOS,ERRnoaccess);
1098 outsize = set_message(outbuf,7,0,True);
1099 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1100 SSVAL(outbuf,smb_vwv1,fmode);
1101 if(lp_dos_filetime_resolution(SNUM(conn)) )
1102 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1104 put_dos_date3(outbuf,smb_vwv2,mtime);
1105 SIVAL(outbuf,smb_vwv4,(uint32)size);
1106 SSVAL(outbuf,smb_vwv6,rmode);
1108 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1109 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1111 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1112 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1113 END_PROFILE(SMBopen);
1117 /****************************************************************************
1118 Reply to an open and X.
1119 ****************************************************************************/
1121 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1124 int smb_mode = SVAL(inbuf,smb_vwv3);
1125 int smb_attr = SVAL(inbuf,smb_vwv5);
1126 /* Breakout the oplock request bits so we can set the
1127 reply bits separately. */
1128 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1129 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1130 BOOL oplock_request = ex_oplock_request | core_oplock_request;
1132 int open_flags = SVAL(inbuf,smb_vwv2);
1133 int smb_sattr = SVAL(inbuf,smb_vwv4);
1134 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1136 int smb_ofun = SVAL(inbuf,smb_vwv8);
1138 int fmode=0,mtime=0,rmode=0;
1139 SMB_STRUCT_STAT sbuf;
1141 BOOL bad_path = False;
1144 START_PROFILE(SMBopenX);
1146 /* If it's an IPC, pass off the pipe handler. */
1148 if (lp_nt_pipe_support()) {
1149 END_PROFILE(SMBopenX);
1150 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1152 END_PROFILE(SMBopenX);
1153 return ERROR_DOS(ERRSRV,ERRaccess);
1157 /* XXXX we need to handle passed times, sattr and flags */
1158 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status, False);
1159 if (!NT_STATUS_IS_OK(status)) {
1160 END_PROFILE(SMBopenX);
1161 return ERROR_NT(status);
1164 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1166 unix_convert(fname,conn,0,&bad_path,&sbuf);
1168 END_PROFILE(SMBopenX);
1169 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1172 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
1173 oplock_request, &rmode,&smb_action);
1176 END_PROFILE(SMBopenX);
1177 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1178 /* We have re-scheduled this call. */
1179 clear_cached_errors();
1182 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1185 size = sbuf.st_size;
1186 fmode = dos_mode(conn,fname,&sbuf);
1187 mtime = sbuf.st_mtime;
1189 close_file(fsp,False);
1190 END_PROFILE(SMBopenX);
1191 return ERROR_DOS(ERRDOS,ERRnoaccess);
1194 /* If the caller set the extended oplock request bit
1195 and we granted one (by whatever means) - set the
1196 correct bit for extended oplock reply.
1199 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
1200 smb_action |= EXTENDED_OPLOCK_GRANTED;
1202 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1203 smb_action |= EXTENDED_OPLOCK_GRANTED;
1205 /* If the caller set the core oplock request bit
1206 and we granted one (by whatever means) - set the
1207 correct bit for core oplock reply.
1210 if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
1211 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1213 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1214 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1216 set_message(outbuf,15,0,True);
1217 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1218 SSVAL(outbuf,smb_vwv3,fmode);
1219 if(lp_dos_filetime_resolution(SNUM(conn)) )
1220 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1222 put_dos_date3(outbuf,smb_vwv4,mtime);
1223 SIVAL(outbuf,smb_vwv6,(uint32)size);
1224 SSVAL(outbuf,smb_vwv8,rmode);
1225 SSVAL(outbuf,smb_vwv11,smb_action);
1227 END_PROFILE(SMBopenX);
1228 return chain_reply(inbuf,outbuf,length,bufsize);
1231 /****************************************************************************
1232 Reply to a SMBulogoffX.
1233 ****************************************************************************/
1235 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1237 uint16 vuid = SVAL(inbuf,smb_uid);
1238 user_struct *vuser = get_valid_user_struct(vuid);
1239 START_PROFILE(SMBulogoffX);
1242 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1244 /* in user level security we are supposed to close any files
1245 open by this user */
1246 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1247 file_close_user(vuid);
1249 invalidate_vuid(vuid);
1251 set_message(outbuf,2,0,True);
1253 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1255 END_PROFILE(SMBulogoffX);
1256 return chain_reply(inbuf,outbuf,length,bufsize);
1259 /****************************************************************************
1260 Reply to a mknew or a create.
1261 ****************************************************************************/
1263 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1270 BOOL bad_path = False;
1272 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1273 SMB_STRUCT_STAT sbuf;
1275 START_PROFILE(SMBcreate);
1277 com = SVAL(inbuf,smb_com);
1279 createmode = SVAL(inbuf,smb_vwv0);
1280 srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status, False);
1281 if (!NT_STATUS_IS_OK(status)) {
1282 END_PROFILE(SMBcreate);
1283 return ERROR_NT(status);
1286 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1288 unix_convert(fname,conn,0,&bad_path,&sbuf);
1290 END_PROFILE(SMBcreate);
1291 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1294 if (createmode & aVOLID)
1295 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1297 if(com == SMBmknew) {
1298 /* We should fail if file exists. */
1299 ofun = FILE_CREATE_IF_NOT_EXIST;
1301 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1302 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1305 /* Open file in dos compatibility share mode. */
1306 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1307 ofun, (uint32)createmode, oplock_request, NULL, NULL);
1310 END_PROFILE(SMBcreate);
1311 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1312 /* We have re-scheduled this call. */
1313 clear_cached_errors();
1316 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1319 outsize = set_message(outbuf,1,0,True);
1320 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1322 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1323 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1325 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1326 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1328 DEBUG( 2, ( "new file %s\n", fname ) );
1329 DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) );
1331 END_PROFILE(SMBcreate);
1335 /****************************************************************************
1336 Reply to a create temporary file.
1337 ****************************************************************************/
1339 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1344 BOOL bad_path = False;
1346 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1348 SMB_STRUCT_STAT sbuf;
1351 unsigned int namelen;
1353 START_PROFILE(SMBctemp);
1355 createattr = SVAL(inbuf,smb_vwv0);
1356 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 END_PROFILE(SMBctemp);
1359 return ERROR_NT(status);
1362 pstrcat(fname,"/TMXXXXXX");
1364 pstrcat(fname,"TMXXXXXX");
1367 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1369 unix_convert(fname,conn,0,&bad_path,&sbuf);
1371 END_PROFILE(SMBctemp);
1372 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1375 tmpfd = smb_mkstemp(fname);
1377 END_PROFILE(SMBctemp);
1378 return(UNIXERROR(ERRDOS,ERRnoaccess));
1381 SMB_VFS_STAT(conn,fname,&sbuf);
1383 /* Open file in dos compatibility share mode. */
1384 /* We should fail if file does not exist. */
1385 fsp = open_file_shared(conn,fname,&sbuf,
1386 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1387 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1388 (uint32)createattr, oplock_request, NULL, NULL);
1390 /* close fd from smb_mkstemp() */
1394 END_PROFILE(SMBctemp);
1395 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1396 /* We have re-scheduled this call. */
1397 clear_cached_errors();
1400 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1403 outsize = set_message(outbuf,1,0,True);
1404 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1406 /* the returned filename is relative to the directory */
1407 s = strrchr_m(fname, '/');
1413 p = smb_buf(outbuf);
1415 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
1416 thing in the byte section. JRA */
1417 SSVALS(p, 0, -1); /* what is this? not in spec */
1419 namelen = srvstr_push(outbuf, p, s, -1, STR_ASCII|STR_TERMINATE);
1421 outsize = set_message_end(outbuf, p);
1423 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1424 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1426 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1427 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1429 DEBUG( 2, ( "created temp file %s\n", fname ) );
1430 DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n",
1431 fname, fsp->fd, sbuf.st_mode ) );
1433 END_PROFILE(SMBctemp);
1437 /*******************************************************************
1438 Check if a user is allowed to rename a file.
1439 ********************************************************************/
1441 static NTSTATUS can_rename(char *fname,connection_struct *conn, uint16 dirtype, SMB_STRUCT_STAT *pst)
1448 if (!CAN_WRITE(conn))
1449 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1451 fmode = dos_mode(conn,fname,pst);
1452 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1453 return NT_STATUS_NO_SUCH_FILE;
1455 if (S_ISDIR(pst->st_mode))
1456 return NT_STATUS_OK;
1458 /* We need a better way to return NT status codes from open... */
1462 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1463 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
1466 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1467 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1468 ret = NT_STATUS_SHARING_VIOLATION;
1471 unix_ERR_ntstatus = NT_STATUS_OK;
1474 close_file(fsp,False);
1475 return NT_STATUS_OK;
1478 /*******************************************************************
1479 Check if a user is allowed to delete a file.
1480 ********************************************************************/
1482 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOOL bad_path)
1484 SMB_STRUCT_STAT sbuf;
1490 DEBUG(10,("can_delete: %s, dirtype = %d\n",
1493 if (!CAN_WRITE(conn))
1494 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1496 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
1497 if(errno == ENOENT) {
1499 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1501 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1503 return map_nt_error_from_unix(errno);
1506 fmode = dos_mode(conn,fname,&sbuf);
1508 /* Can't delete a directory. */
1510 return NT_STATUS_FILE_IS_A_DIRECTORY;
1512 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1513 return NT_STATUS_OBJECT_NAME_INVALID;
1514 #endif /* JRATEST */
1516 if (!lp_delete_readonly(SNUM(conn))) {
1518 return NT_STATUS_CANNOT_DELETE;
1520 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1521 return NT_STATUS_NO_SUCH_FILE;
1523 /* We need a better way to return NT status codes from open... */
1527 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1528 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
1531 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1532 if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
1533 ret = unix_ERR_ntstatus;
1534 else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1535 ret = NT_STATUS_SHARING_VIOLATION;
1538 unix_ERR_ntstatus = NT_STATUS_OK;
1541 close_file(fsp,False);
1542 return NT_STATUS_OK;
1545 /****************************************************************************
1546 The guts of the unlink command, split out so it may be called by the NT SMB
1548 ****************************************************************************/
1550 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1556 NTSTATUS error = NT_STATUS_OK;
1558 BOOL bad_path = False;
1560 SMB_STRUCT_STAT sbuf;
1562 *directory = *mask = 0;
1564 /* We must check for wildcards in the name given
1565 * directly by the client - before any unmangling.
1566 * This prevents an unmangling of a UNIX name containing
1567 * a DOS wildcard like '*' or '?' from unmangling into
1568 * a wildcard delete which was not intended.
1569 * FIX for #226. JRA.
1572 has_wild = ms_has_wild(name);
1574 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1576 p = strrchr_m(name,'/');
1578 pstrcpy(directory,".");
1582 pstrcpy(directory,name);
1587 * We should only check the mangled cache
1588 * here if unix_convert failed. This means
1589 * that the path in 'mask' doesn't exist
1590 * on the file system and so we need to look
1591 * for a possible mangle. This patch from
1592 * Tine Smukavec <valentin.smukavec@hermes.si>.
1595 if (!rc && mangle_is_mangled(mask))
1596 mangle_check_cache( mask, sizeof(pstring)-1 );
1599 pstrcat(directory,"/");
1600 pstrcat(directory,mask);
1601 error = can_delete(directory,conn,dirtype,bad_path);
1602 if (!NT_STATUS_IS_OK(error))
1605 if (SMB_VFS_UNLINK(conn,directory) == 0) {
1609 struct smb_Dir *dir_hnd = NULL;
1612 if (check_name(directory,conn))
1613 dir_hnd = OpenDir(conn, directory);
1615 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1616 the pattern matches against the long name, otherwise the short name
1617 We don't implement this yet XXXX
1622 error = NT_STATUS_NO_SUCH_FILE;
1624 if (strequal(mask,"????????.???"))
1627 while ((dname = ReadDirName(dir_hnd, &offset))) {
1630 BOOL sys_direntry = False;
1631 pstrcpy(fname,dname);
1633 if (!is_visible_file(conn, directory, dname, &st, True)) {
1637 /* Quick check for "." and ".." */
1638 if (fname[0] == '.') {
1639 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
1640 if ((dirtype & FILE_ATTRIBUTE_DIRECTORY) && (dirtype & FILE_ATTRIBUTE_SYSTEM)) {
1641 sys_direntry = True;
1648 if(!mask_match(fname, mask, conn->case_sensitive))
1652 error = NT_STATUS_OBJECT_NAME_INVALID;
1653 DEBUG(3,("unlink_internals: system directory delete denied [%s] mask [%s]\n",
1658 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1659 error = can_delete(fname,conn,dirtype,bad_path);
1660 if (!NT_STATUS_IS_OK(error)) {
1663 if (SMB_VFS_UNLINK(conn,fname) == 0)
1665 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1671 if (count == 0 && NT_STATUS_IS_OK(error)) {
1672 error = map_nt_error_from_unix(errno);
1678 /****************************************************************************
1680 ****************************************************************************/
1682 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1689 START_PROFILE(SMBunlink);
1691 dirtype = SVAL(inbuf,smb_vwv0);
1693 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, True);
1694 if (!NT_STATUS_IS_OK(status)) {
1695 END_PROFILE(SMBunlink);
1696 return ERROR_NT(status);
1699 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1701 DEBUG(3,("reply_unlink : %s\n",name));
1703 status = unlink_internals(conn, dirtype, name);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1706 /* We have re-scheduled this call. */
1707 clear_cached_errors();
1710 return ERROR_NT(status);
1714 * Win2k needs a changenotify request response before it will
1715 * update after a rename..
1717 process_pending_change_notify_queue((time_t)0);
1719 outsize = set_message(outbuf,0,0,True);
1721 END_PROFILE(SMBunlink);
1725 /****************************************************************************
1727 ****************************************************************************/
1729 static void fail_readraw(void)
1732 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1734 exit_server(errstr);
1737 #if defined(WITH_SENDFILE)
1738 /****************************************************************************
1739 Fake (read/write) sendfile. Returns -1 on read or write fail.
1740 ****************************************************************************/
1742 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, int bufsize)
1746 /* Paranioa check... */
1747 if (nread > bufsize) {
1752 ret = read_file(fsp,buf,startpos,nread);
1758 /* If we had a short read, fill with zeros. */
1760 memset(buf, '\0', nread - ret);
1763 if (write_data(smbd_server_fd(),buf,nread) != nread) {
1767 return (ssize_t)nread;
1771 /****************************************************************************
1772 Use sendfile in readbraw.
1773 ****************************************************************************/
1775 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
1776 ssize_t mincount, char *outbuf, int out_buffsize)
1780 #if defined(WITH_SENDFILE)
1782 * We can only use sendfile on a non-chained packet
1783 * but we can use on a non-oplocked file. tridge proved this
1784 * on a train in Germany :-). JRA.
1785 * reply_readbraw has already checked the length.
1788 if (chain_size ==0 && (nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) && lp_use_sendfile(SNUM(conn)) ) {
1791 _smb_setlen(outbuf,nread);
1792 header.data = outbuf;
1796 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
1797 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
1798 if (errno == ENOSYS) {
1799 goto normal_readbraw;
1803 * Special hack for broken Linux with no working sendfile. If we
1804 * return EINTR we sent the header but not the rest of the data.
1805 * Fake this up by doing read/write calls.
1807 if (errno == EINTR) {
1808 /* Ensure we don't do this again. */
1809 set_use_sendfile(SNUM(conn), False);
1810 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
1812 if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
1813 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
1814 fsp->fsp_name, strerror(errno) ));
1815 exit_server("send_file_readbraw fake_sendfile failed");
1820 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
1821 fsp->fsp_name, strerror(errno) ));
1822 exit_server("send_file_readbraw sendfile failed");
1832 ret = read_file(fsp,outbuf+4,startpos,nread);
1833 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1842 _smb_setlen(outbuf,ret);
1843 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
1847 /****************************************************************************
1848 Reply to a readbraw (core+ protocol).
1849 ****************************************************************************/
1851 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
1853 extern struct current_user current_user;
1854 ssize_t maxcount,mincount;
1857 char *header = outbuf;
1859 START_PROFILE(SMBreadbraw);
1861 if (srv_is_signing_active()) {
1862 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1866 * Special check if an oplock break has been issued
1867 * and the readraw request croses on the wire, we must
1868 * return a zero length response here.
1871 if(global_oplock_break) {
1872 _smb_setlen(header,0);
1873 if (write_data(smbd_server_fd(),header,4) != 4)
1875 DEBUG(5,("readbraw - oplock break finished\n"));
1876 END_PROFILE(SMBreadbraw);
1880 fsp = file_fsp(inbuf,smb_vwv0);
1882 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1884 * fsp could be NULL here so use the value from the packet. JRA.
1886 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1887 _smb_setlen(header,0);
1888 if (write_data(smbd_server_fd(),header,4) != 4)
1890 END_PROFILE(SMBreadbraw);
1894 CHECK_FSP(fsp,conn);
1896 flush_write_cache(fsp, READRAW_FLUSH);
1898 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
1899 if(CVAL(inbuf,smb_wct) == 10) {
1901 * This is a large offset (64 bit) read.
1903 #ifdef LARGE_SMB_OFF_T
1905 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1907 #else /* !LARGE_SMB_OFF_T */
1910 * Ensure we haven't been sent a >32 bit offset.
1913 if(IVAL(inbuf,smb_vwv8) != 0) {
1914 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1915 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1916 _smb_setlen(header,0);
1917 if (write_data(smbd_server_fd(),header,4) != 4)
1919 END_PROFILE(SMBreadbraw);
1923 #endif /* LARGE_SMB_OFF_T */
1926 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1927 _smb_setlen(header,0);
1928 if (write_data(smbd_server_fd(),header,4) != 4)
1930 END_PROFILE(SMBreadbraw);
1934 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1935 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1937 /* ensure we don't overrun the packet size */
1938 maxcount = MIN(65535,maxcount);
1940 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
1941 SMB_OFF_T size = fsp->size;
1942 SMB_OFF_T sizeneeded = startpos + maxcount;
1944 if (size < sizeneeded) {
1946 if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
1948 if (!fsp->can_write)
1952 if (startpos >= size)
1955 nread = MIN(maxcount,(size - startpos));
1958 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1959 if (nread < mincount)
1963 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1964 (int)maxcount, (int)mincount, (int)nread ) );
1966 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
1968 DEBUG(5,("readbraw finished\n"));
1969 END_PROFILE(SMBreadbraw);
1973 /****************************************************************************
1974 Reply to a lockread (core+ protocol).
1975 ****************************************************************************/
1977 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1985 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1986 BOOL my_lock_ctx = False;
1987 START_PROFILE(SMBlockread);
1989 CHECK_FSP(fsp,conn);
1992 release_level_2_oplocks_on_change(fsp);
1994 numtoread = SVAL(inbuf,smb_vwv1);
1995 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1997 outsize = set_message(outbuf,5,3,True);
1998 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1999 data = smb_buf(outbuf) + 3;
2002 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2003 * protocol request that predates the read/write lock concept.
2004 * Thus instead of asking for a read lock here we need to ask
2005 * for a write lock. JRA.
2006 * Note that the requested lock size is unaffected by max_recv.
2009 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
2010 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &my_lock_ctx);
2012 if (NT_STATUS_V(status)) {
2015 * We used to make lockread a blocking lock. It turns out
2016 * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
2020 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
2022 * A blocking lock was requested. Package up
2023 * this smb into a queued request and push it
2024 * onto the blocking lock queue.
2026 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
2027 (SMB_BIG_UINT)numtoread)) {
2028 END_PROFILE(SMBlockread);
2033 END_PROFILE(SMBlockread);
2034 return ERROR_NT(status);
2038 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2041 if (numtoread > max_recv) {
2042 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2043 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2044 (unsigned int)numtoread, (unsigned int)max_recv ));
2045 numtoread = MIN(numtoread,max_recv);
2047 nread = read_file(fsp,data,startpos,numtoread);
2050 END_PROFILE(SMBlockread);
2051 return(UNIXERROR(ERRDOS,ERRnoaccess));
2055 SSVAL(outbuf,smb_vwv0,nread);
2056 SSVAL(outbuf,smb_vwv5,nread+3);
2057 SSVAL(smb_buf(outbuf),1,nread);
2059 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2060 fsp->fnum, (int)numtoread, (int)nread));
2062 END_PROFILE(SMBlockread);
2066 /****************************************************************************
2068 ****************************************************************************/
2070 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2077 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2078 START_PROFILE(SMBread);
2080 CHECK_FSP(fsp,conn);
2083 numtoread = SVAL(inbuf,smb_vwv1);
2084 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2086 outsize = set_message(outbuf,5,3,True);
2087 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2089 * The requested read size cannot be greater than max_recv. JRA.
2091 if (numtoread > max_recv) {
2092 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
2093 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2094 (unsigned int)numtoread, (unsigned int)max_recv ));
2095 numtoread = MIN(numtoread,max_recv);
2098 data = smb_buf(outbuf) + 3;
2100 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2101 END_PROFILE(SMBread);
2102 return ERROR_DOS(ERRDOS,ERRlock);
2106 nread = read_file(fsp,data,startpos,numtoread);
2109 END_PROFILE(SMBread);
2110 return(UNIXERROR(ERRDOS,ERRnoaccess));
2114 SSVAL(outbuf,smb_vwv0,nread);
2115 SSVAL(outbuf,smb_vwv5,nread+3);
2116 SCVAL(smb_buf(outbuf),0,1);
2117 SSVAL(smb_buf(outbuf),1,nread);
2119 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2120 fsp->fnum, (int)numtoread, (int)nread ) );
2122 END_PROFILE(SMBread);
2126 /****************************************************************************
2127 Reply to a read and X - possibly using sendfile.
2128 ****************************************************************************/
2130 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
2131 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
2135 char *data = smb_buf(outbuf);
2137 #if defined(WITH_SENDFILE)
2139 * We can only use sendfile on a non-chained packet
2140 * but we can use on a non-oplocked file. tridge proved this
2141 * on a train in Germany :-). JRA.
2144 if (chain_size ==0 && (CVAL(inbuf,smb_vwv0) == 0xFF) && lp_use_sendfile(SNUM(conn)) &&
2145 (lp_write_cache_size(SNUM(conn)) == 0) ) {
2146 SMB_STRUCT_STAT sbuf;
2149 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
2150 return(UNIXERROR(ERRDOS,ERRnoaccess));
2152 if (startpos > sbuf.st_size)
2155 if (smb_maxcnt > (sbuf.st_size - startpos))
2156 smb_maxcnt = (sbuf.st_size - startpos);
2158 if (smb_maxcnt == 0)
2162 * Set up the packet header before send. We
2163 * assume here the sendfile will work (get the
2164 * correct amount of data).
2167 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2168 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
2169 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2170 SSVAL(outbuf,smb_vwv7,((smb_maxcnt >> 16) & 1));
2171 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
2172 SCVAL(outbuf,smb_vwv0,0xFF);
2173 set_message(outbuf,12,smb_maxcnt,False);
2174 header.data = outbuf;
2175 header.length = data - outbuf;
2178 if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) {
2179 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2180 if (errno == ENOSYS) {
2185 * Special hack for broken Linux with no working sendfile. If we
2186 * return EINTR we sent the header but not the rest of the data.
2187 * Fake this up by doing read/write calls.
2190 if (errno == EINTR) {
2191 /* Ensure we don't do this again. */
2192 set_use_sendfile(SNUM(conn), False);
2193 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
2195 if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
2196 len_outbuf - (data-outbuf))) == -1) {
2197 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2198 fsp->fsp_name, strerror(errno) ));
2199 exit_server("send_file_readX: fake_sendfile failed");
2201 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
2202 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2203 /* Returning -1 here means successful sendfile. */
2207 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2208 fsp->fsp_name, strerror(errno) ));
2209 exit_server("send_file_readX sendfile failed");
2212 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2213 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2214 /* Returning -1 here means successful sendfile. */
2222 nread = read_file(fsp,data,startpos,smb_maxcnt);
2225 END_PROFILE(SMBreadX);
2226 return(UNIXERROR(ERRDOS,ERRnoaccess));
2229 outsize = set_message(outbuf,12,nread,False);
2230 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2231 SSVAL(outbuf,smb_vwv5,nread);
2232 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2233 SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
2234 SSVAL(smb_buf(outbuf),-2,nread);
2236 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2237 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2239 /* Returning the number of bytes we want to send back - including header. */
2243 /****************************************************************************
2244 Reply to a read and X.
2245 ****************************************************************************/
2247 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2249 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2250 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2252 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2254 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2257 START_PROFILE(SMBreadX);
2259 /* If it's an IPC, pass off the pipe handler. */
2261 END_PROFILE(SMBreadX);
2262 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2265 CHECK_FSP(fsp,conn);
2268 set_message(outbuf,12,0,True);
2270 if (global_client_caps & CAP_LARGE_READX) {
2271 if (SVAL(inbuf,smb_vwv7) == 1) {
2272 smb_maxcnt |= (1<<16);
2274 if (smb_maxcnt > BUFFER_SIZE) {
2275 DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n",
2276 (unsigned int)smb_maxcnt, (unsigned int)BUFFER_SIZE));
2277 END_PROFILE(SMBreadX);
2278 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2282 if(CVAL(inbuf,smb_wct) == 12) {
2283 #ifdef LARGE_SMB_OFF_T
2285 * This is a large offset (64 bit) read.
2287 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2289 #else /* !LARGE_SMB_OFF_T */
2292 * Ensure we haven't been sent a >32 bit offset.
2295 if(IVAL(inbuf,smb_vwv10) != 0) {
2296 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2297 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2298 END_PROFILE(SMBreadX);
2299 return ERROR_DOS(ERRDOS,ERRbadaccess);
2302 #endif /* LARGE_SMB_OFF_T */
2306 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2307 END_PROFILE(SMBreadX);
2308 return ERROR_DOS(ERRDOS,ERRlock);
2311 nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
2313 nread = chain_reply(inbuf,outbuf,length,bufsize);
2315 END_PROFILE(SMBreadX);
2319 /****************************************************************************
2320 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2321 ****************************************************************************/
2323 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2326 ssize_t total_written=0;
2327 size_t numtowrite=0;
2332 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2334 START_PROFILE(SMBwritebraw);
2336 if (srv_is_signing_active()) {
2337 exit_server("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2340 CHECK_FSP(fsp,conn);
2343 tcount = IVAL(inbuf,smb_vwv1);
2344 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2345 write_through = BITSETW(inbuf+smb_vwv7,0);
2347 /* We have to deal with slightly different formats depending
2348 on whether we are using the core+ or lanman1.0 protocol */
2350 if(Protocol <= PROTOCOL_COREPLUS) {
2351 numtowrite = SVAL(smb_buf(inbuf),-2);
2352 data = smb_buf(inbuf);
2354 numtowrite = SVAL(inbuf,smb_vwv10);
2355 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2358 /* force the error type */
2359 SCVAL(inbuf,smb_com,SMBwritec);
2360 SCVAL(outbuf,smb_com,SMBwritec);
2362 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2363 END_PROFILE(SMBwritebraw);
2364 return(ERROR_DOS(ERRDOS,ERRlock));
2368 nwritten = write_file(fsp,data,startpos,numtowrite);
2370 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2371 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2373 if (nwritten < (ssize_t)numtowrite) {
2374 END_PROFILE(SMBwritebraw);
2375 return(UNIXERROR(ERRHRD,ERRdiskfull));
2378 total_written = nwritten;
2380 /* Return a message to the redirector to tell it to send more bytes */
2381 SCVAL(outbuf,smb_com,SMBwritebraw);
2382 SSVALS(outbuf,smb_vwv0,-1);
2383 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2384 if (!send_smb(smbd_server_fd(),outbuf))
2385 exit_server("reply_writebraw: send_smb failed.");
2387 /* Now read the raw data into the buffer and write it */
2388 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
2389 exit_server("secondary writebraw failed");
2392 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2393 numtowrite = smb_len(inbuf);
2395 /* Set up outbuf to return the correct return */
2396 outsize = set_message(outbuf,1,0,True);
2397 SCVAL(outbuf,smb_com,SMBwritec);
2398 SSVAL(outbuf,smb_vwv0,total_written);
2400 if (numtowrite != 0) {
2402 if (numtowrite > BUFFER_SIZE) {
2403 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2404 (unsigned int)numtowrite ));
2405 exit_server("secondary writebraw failed");
2408 if (tcount > nwritten+numtowrite) {
2409 DEBUG(3,("Client overestimated the write %d %d %d\n",
2410 (int)tcount,(int)nwritten,(int)numtowrite));
2413 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2414 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2416 exit_server("secondary writebraw failed");
2419 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2421 if (nwritten < (ssize_t)numtowrite) {
2422 SCVAL(outbuf,smb_rcls,ERRHRD);
2423 SSVAL(outbuf,smb_err,ERRdiskfull);
2427 total_written += nwritten;
2430 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
2431 sync_file(conn,fsp);
2433 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2434 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2436 /* we won't return a status if write through is not selected - this follows what WfWg does */
2437 END_PROFILE(SMBwritebraw);
2438 if (!write_through && total_written==tcount) {
2440 #if RABBIT_PELLET_FIX
2442 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2443 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2445 if (!send_keepalive(smbd_server_fd()))
2446 exit_server("reply_writebraw: send of keepalive failed");
2454 /****************************************************************************
2455 Reply to a writeunlock (core+).
2456 ****************************************************************************/
2458 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2459 int size, int dum_buffsize)
2461 ssize_t nwritten = -1;
2465 NTSTATUS status = NT_STATUS_OK;
2466 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2468 START_PROFILE(SMBwriteunlock);
2470 CHECK_FSP(fsp,conn);
2473 numtowrite = SVAL(inbuf,smb_vwv1);
2474 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2475 data = smb_buf(inbuf) + 3;
2477 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2478 END_PROFILE(SMBwriteunlock);
2479 return ERROR_DOS(ERRDOS,ERRlock);
2482 /* The special X/Open SMB protocol handling of
2483 zero length writes is *NOT* done for
2488 nwritten = write_file(fsp,data,startpos,numtowrite);
2490 if (lp_syncalways(SNUM(conn)))
2491 sync_file(conn,fsp);
2493 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2494 END_PROFILE(SMBwriteunlock);
2495 return(UNIXERROR(ERRHRD,ERRdiskfull));
2499 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
2500 (SMB_BIG_UINT)startpos);
2501 if (NT_STATUS_V(status)) {
2502 END_PROFILE(SMBwriteunlock);
2503 return ERROR_NT(status);
2507 outsize = set_message(outbuf,1,0,True);
2509 SSVAL(outbuf,smb_vwv0,nwritten);
2511 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2512 fsp->fnum, (int)numtowrite, (int)nwritten));
2514 END_PROFILE(SMBwriteunlock);
2518 /****************************************************************************
2520 ****************************************************************************/
2522 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2525 ssize_t nwritten = -1;
2528 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2530 START_PROFILE(SMBwrite);
2532 /* If it's an IPC, pass off the pipe handler. */
2534 END_PROFILE(SMBwrite);
2535 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2538 CHECK_FSP(fsp,conn);
2541 numtowrite = SVAL(inbuf,smb_vwv1);
2542 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2543 data = smb_buf(inbuf) + 3;
2545 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2546 END_PROFILE(SMBwrite);
2547 return ERROR_DOS(ERRDOS,ERRlock);
2551 * X/Open SMB protocol says that if smb_vwv1 is
2552 * zero then the file size should be extended or
2553 * truncated to the size given in smb_vwv[2-3].
2556 if(numtowrite == 0) {
2558 * This is actually an allocate call, and set EOF. JRA.
2560 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
2562 END_PROFILE(SMBwrite);
2563 return ERROR_NT(NT_STATUS_DISK_FULL);
2565 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2567 END_PROFILE(SMBwrite);
2568 return ERROR_NT(NT_STATUS_DISK_FULL);
2571 nwritten = write_file(fsp,data,startpos,numtowrite);
2573 if (lp_syncalways(SNUM(conn)))
2574 sync_file(conn,fsp);
2576 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2577 END_PROFILE(SMBwrite);
2578 return(UNIXERROR(ERRHRD,ERRdiskfull));
2581 outsize = set_message(outbuf,1,0,True);
2583 SSVAL(outbuf,smb_vwv0,nwritten);
2585 if (nwritten < (ssize_t)numtowrite) {
2586 SCVAL(outbuf,smb_rcls,ERRHRD);
2587 SSVAL(outbuf,smb_err,ERRdiskfull);
2590 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2592 END_PROFILE(SMBwrite);
2596 /****************************************************************************
2597 Reply to a write and X.
2598 ****************************************************************************/
2600 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2602 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2603 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2604 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2605 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2606 ssize_t nwritten = -1;
2607 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2608 unsigned int smblen = smb_len(inbuf);
2610 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2611 START_PROFILE(SMBwriteX);
2613 /* If it's an IPC, pass off the pipe handler. */
2615 END_PROFILE(SMBwriteX);
2616 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2619 CHECK_FSP(fsp,conn);
2622 /* Deal with possible LARGE_WRITEX */
2624 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2626 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2627 END_PROFILE(SMBwriteX);
2628 return ERROR_DOS(ERRDOS,ERRbadmem);
2631 data = smb_base(inbuf) + smb_doff;
2633 if(CVAL(inbuf,smb_wct) == 14) {
2634 #ifdef LARGE_SMB_OFF_T
2636 * This is a large offset (64 bit) write.
2638 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2640 #else /* !LARGE_SMB_OFF_T */
2643 * Ensure we haven't been sent a >32 bit offset.
2646 if(IVAL(inbuf,smb_vwv12) != 0) {
2647 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2648 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2649 END_PROFILE(SMBwriteX);
2650 return ERROR_DOS(ERRDOS,ERRbadaccess);
2653 #endif /* LARGE_SMB_OFF_T */
2656 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2657 END_PROFILE(SMBwriteX);
2658 return ERROR_DOS(ERRDOS,ERRlock);
2661 /* X/Open SMB protocol says that, unlike SMBwrite
2662 if the length is zero then NO truncation is
2663 done, just a write of zero. To truncate a file,
2669 nwritten = write_file(fsp,data,startpos,numtowrite);
2671 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2672 END_PROFILE(SMBwriteX);
2673 return(UNIXERROR(ERRHRD,ERRdiskfull));
2676 set_message(outbuf,6,0,True);
2678 SSVAL(outbuf,smb_vwv2,nwritten);
2680 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2682 if (nwritten < (ssize_t)numtowrite) {
2683 SCVAL(outbuf,smb_rcls,ERRHRD);
2684 SSVAL(outbuf,smb_err,ERRdiskfull);
2687 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2688 fsp->fnum, (int)numtowrite, (int)nwritten));
2690 if (lp_syncalways(SNUM(conn)) || write_through)
2691 sync_file(conn,fsp);
2693 END_PROFILE(SMBwriteX);
2694 return chain_reply(inbuf,outbuf,length,bufsize);
2697 /****************************************************************************
2699 ****************************************************************************/
2701 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2707 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2708 START_PROFILE(SMBlseek);
2710 CHECK_FSP(fsp,conn);
2712 flush_write_cache(fsp, SEEK_FLUSH);
2714 mode = SVAL(inbuf,smb_vwv1) & 3;
2715 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
2716 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
2725 res = fsp->pos + startpos;
2736 if (umode == SEEK_END) {
2737 if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
2738 if(errno == EINVAL) {
2739 SMB_OFF_T current_pos = startpos;
2740 SMB_STRUCT_STAT sbuf;
2742 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
2743 END_PROFILE(SMBlseek);
2744 return(UNIXERROR(ERRDOS,ERRnoaccess));
2747 current_pos += sbuf.st_size;
2749 res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
2754 END_PROFILE(SMBlseek);
2755 return(UNIXERROR(ERRDOS,ERRnoaccess));
2761 outsize = set_message(outbuf,2,0,True);
2762 SIVAL(outbuf,smb_vwv0,res);
2764 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2765 fsp->fnum, (double)startpos, (double)res, mode));
2767 END_PROFILE(SMBlseek);
2771 /****************************************************************************
2773 ****************************************************************************/
2775 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2777 int outsize = set_message(outbuf,0,0,True);
2778 uint16 fnum = SVAL(inbuf,smb_vwv0);
2779 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2780 START_PROFILE(SMBflush);
2783 CHECK_FSP(fsp,conn);
2786 file_sync_all(conn);
2788 sync_file(conn,fsp);
2791 DEBUG(3,("flush\n"));
2792 END_PROFILE(SMBflush);
2796 /****************************************************************************
2798 ****************************************************************************/
2800 int reply_exit(connection_struct *conn,
2801 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2804 START_PROFILE(SMBexit);
2806 file_close_pid(SVAL(inbuf,smb_pid));
2808 outsize = set_message(outbuf,0,0,True);
2810 DEBUG(3,("exit\n"));
2812 END_PROFILE(SMBexit);
2816 /****************************************************************************
2817 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2818 ****************************************************************************/
2820 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2823 extern struct current_user current_user;
2826 int32 eclass = 0, err = 0;
2827 files_struct *fsp = NULL;
2828 START_PROFILE(SMBclose);
2830 outsize = set_message(outbuf,0,0,True);
2832 /* If it's an IPC, pass off to the pipe handler. */
2834 END_PROFILE(SMBclose);
2835 return reply_pipe_close(conn, inbuf,outbuf);
2838 fsp = file_fsp(inbuf,smb_vwv0);
2841 * We can only use CHECK_FSP if we know it's not a directory.
2844 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
2845 END_PROFILE(SMBclose);
2846 return ERROR_DOS(ERRDOS,ERRbadfid);
2849 if(fsp->is_directory) {
2851 * Special case - close NT SMB directory handle.
2853 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2854 close_file(fsp,True);
2857 * Close ordinary file.
2862 /* Save the name for time set in close. */
2863 pstrcpy( file_name, fsp->fsp_name);
2865 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2867 conn->num_files_open));
2870 * close_file() returns the unix errno if an error
2871 * was detected on close - normally this is due to
2872 * a disk full error. If not then it was probably an I/O error.
2875 if((close_err = close_file(fsp,True)) != 0) {
2877 END_PROFILE(SMBclose);
2878 return (UNIXERROR(ERRHRD,ERRgeneral));
2882 * Now take care of any time sent in the close.
2885 mtime = make_unix_date3(inbuf+smb_vwv1);
2887 /* try and set the date */
2888 set_filetime(conn, file_name, mtime);
2892 /* We have a cached error */
2894 END_PROFILE(SMBclose);
2895 return ERROR_DOS(eclass,err);
2898 END_PROFILE(SMBclose);
2902 /****************************************************************************
2903 Reply to a writeclose (Core+ protocol).
2904 ****************************************************************************/
2906 int reply_writeclose(connection_struct *conn,
2907 char *inbuf,char *outbuf, int size, int dum_buffsize)
2910 ssize_t nwritten = -1;
2916 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2917 START_PROFILE(SMBwriteclose);
2919 CHECK_FSP(fsp,conn);
2922 numtowrite = SVAL(inbuf,smb_vwv1);
2923 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2924 mtime = make_unix_date3(inbuf+smb_vwv4);
2925 data = smb_buf(inbuf) + 1;
2927 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2928 END_PROFILE(SMBwriteclose);
2929 return ERROR_DOS(ERRDOS,ERRlock);
2932 nwritten = write_file(fsp,data,startpos,numtowrite);
2934 set_filetime(conn, fsp->fsp_name,mtime);
2937 * More insanity. W2K only closes the file if writelen > 0.
2942 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
2944 close_err = close_file(fsp,True);
2947 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2948 fsp->fnum, (int)numtowrite, (int)nwritten,
2949 conn->num_files_open));
2951 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2952 END_PROFILE(SMBwriteclose);
2953 return(UNIXERROR(ERRHRD,ERRdiskfull));
2956 if(close_err != 0) {
2958 END_PROFILE(SMBwriteclose);
2959 return(UNIXERROR(ERRHRD,ERRgeneral));
2962 outsize = set_message(outbuf,1,0,True);
2964 SSVAL(outbuf,smb_vwv0,nwritten);
2965 END_PROFILE(SMBwriteclose);
2969 /****************************************************************************
2971 ****************************************************************************/
2973 int reply_lock(connection_struct *conn,
2974 char *inbuf,char *outbuf, int length, int dum_buffsize)
2976 int outsize = set_message(outbuf,0,0,True);
2977 SMB_BIG_UINT count,offset;
2979 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2980 BOOL my_lock_ctx = False;
2982 START_PROFILE(SMBlock);
2984 CHECK_FSP(fsp,conn);
2986 release_level_2_oplocks_on_change(fsp);
2988 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2989 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2991 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2992 fsp->fd, fsp->fnum, (double)offset, (double)count));
2994 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
2995 if (NT_STATUS_V(status)) {
2997 /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
2998 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
3000 * A blocking lock was requested. Package up
3001 * this smb into a queued request and push it
3002 * onto the blocking lock queue.
3004 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
3005 END_PROFILE(SMBlock);
3010 END_PROFILE(SMBlock);
3011 return ERROR_NT(status);
3014 END_PROFILE(SMBlock);
3018 /****************************************************************************
3020 ****************************************************************************/
3022 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
3025 int outsize = set_message(outbuf,0,0,True);
3026 SMB_BIG_UINT count,offset;
3028 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3029 START_PROFILE(SMBunlock);
3031 CHECK_FSP(fsp,conn);
3033 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
3034 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
3036 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
3037 if (NT_STATUS_V(status)) {
3038 END_PROFILE(SMBunlock);
3039 return ERROR_NT(status);
3042 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3043 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
3045 END_PROFILE(SMBunlock);
3049 /****************************************************************************
3051 ****************************************************************************/
3053 int reply_tdis(connection_struct *conn,
3054 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3056 int outsize = set_message(outbuf,0,0,True);
3058 START_PROFILE(SMBtdis);
3060 vuid = SVAL(inbuf,smb_uid);
3063 DEBUG(4,("Invalid connection in tdis\n"));
3064 END_PROFILE(SMBtdis);
3065 return ERROR_DOS(ERRSRV,ERRinvnid);
3070 close_cnum(conn,vuid);
3072 END_PROFILE(SMBtdis);
3076 /****************************************************************************
3078 ****************************************************************************/
3080 int reply_echo(connection_struct *conn,
3081 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3083 int smb_reverb = SVAL(inbuf,smb_vwv0);
3085 unsigned int data_len = smb_buflen(inbuf);
3086 int outsize = set_message(outbuf,1,data_len,True);
3087 START_PROFILE(SMBecho);
3089 if (data_len > BUFFER_SIZE) {
3090 DEBUG(0,("reply_echo: data_len too large.\n"));
3091 END_PROFILE(SMBecho);
3095 /* copy any incoming data back out */
3097 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
3099 if (smb_reverb > 100) {
3100 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
3104 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
3105 SSVAL(outbuf,smb_vwv0,seq_num);
3107 smb_setlen(outbuf,outsize - 4);
3109 if (!send_smb(smbd_server_fd(),outbuf))
3110 exit_server("reply_echo: send_smb failed.");
3113 DEBUG(3,("echo %d times\n", smb_reverb));
3117 END_PROFILE(SMBecho);
3121 /****************************************************************************
3122 Reply to a printopen.
3123 ****************************************************************************/
3125 int reply_printopen(connection_struct *conn,
3126 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3130 START_PROFILE(SMBsplopen);
3132 if (!CAN_PRINT(conn)) {
3133 END_PROFILE(SMBsplopen);
3134 return ERROR_DOS(ERRDOS,ERRnoaccess);
3137 /* Open for exclusive use, write only. */
3138 fsp = print_fsp_open(conn, NULL);
3141 END_PROFILE(SMBsplopen);
3142 return(UNIXERROR(ERRDOS,ERRnoaccess));
3145 outsize = set_message(outbuf,1,0,True);
3146 SSVAL(outbuf,smb_vwv0,fsp->fnum);
3148 DEBUG(3,("openprint fd=%d fnum=%d\n",
3149 fsp->fd, fsp->fnum));
3151 END_PROFILE(SMBsplopen);
3155 /****************************************************************************
3156 Reply to a printclose.
3157 ****************************************************************************/
3159 int reply_printclose(connection_struct *conn,
3160 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3162 int outsize = set_message(outbuf,0,0,True);
3163 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3165 START_PROFILE(SMBsplclose);
3167 CHECK_FSP(fsp,conn);
3169 if (!CAN_PRINT(conn)) {
3170 END_PROFILE(SMBsplclose);
3171 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
3174 DEBUG(3,("printclose fd=%d fnum=%d\n",
3175 fsp->fd,fsp->fnum));
3177 close_err = close_file(fsp,True);
3179 if(close_err != 0) {
3181 END_PROFILE(SMBsplclose);
3182 return(UNIXERROR(ERRHRD,ERRgeneral));
3185 END_PROFILE(SMBsplclose);
3189 /****************************************************************************
3190 Reply to a printqueue.
3191 ****************************************************************************/
3193 int reply_printqueue(connection_struct *conn,
3194 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3196 int outsize = set_message(outbuf,2,3,True);
3197 int max_count = SVAL(inbuf,smb_vwv0);
3198 int start_index = SVAL(inbuf,smb_vwv1);
3199 START_PROFILE(SMBsplretq);
3201 /* we used to allow the client to get the cnum wrong, but that
3202 is really quite gross and only worked when there was only
3203 one printer - I think we should now only accept it if they
3204 get it right (tridge) */
3205 if (!CAN_PRINT(conn)) {
3206 END_PROFILE(SMBsplretq);
3207 return ERROR_DOS(ERRDOS,ERRnoaccess);
3210 SSVAL(outbuf,smb_vwv0,0);
3211 SSVAL(outbuf,smb_vwv1,0);
3212 SCVAL(smb_buf(outbuf),0,1);
3213 SSVAL(smb_buf(outbuf),1,0);
3215 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3216 start_index, max_count));
3219 print_queue_struct *queue = NULL;
3220 print_status_struct status;
3221 char *p = smb_buf(outbuf) + 3;
3222 int count = print_queue_status(SNUM(conn), &queue, &status);
3223 int num_to_get = ABS(max_count);
3224 int first = (max_count>0?start_index:start_index+max_count+1);
3230 num_to_get = MIN(num_to_get,count-first);
3233 for (i=first;i<first+num_to_get;i++) {
3234 put_dos_date2(p,0,queue[i].time);
3235 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
3236 SSVAL(p,5, queue[i].job);
3237 SIVAL(p,7,queue[i].size);
3239 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
3244 outsize = set_message(outbuf,2,28*count+3,False);
3245 SSVAL(outbuf,smb_vwv0,count);
3246 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
3247 SCVAL(smb_buf(outbuf),0,1);
3248 SSVAL(smb_buf(outbuf),1,28*count);
3253 DEBUG(3,("%d entries returned in queue\n",count));
3256 END_PROFILE(SMBsplretq);
3260 /****************************************************************************
3261 Reply to a printwrite.
3262 ****************************************************************************/
3264 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3267 int outsize = set_message(outbuf,0,0,True);
3269 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3271 START_PROFILE(SMBsplwr);
3273 if (!CAN_PRINT(conn)) {
3274 END_PROFILE(SMBsplwr);
3275 return ERROR_DOS(ERRDOS,ERRnoaccess);
3278 CHECK_FSP(fsp,conn);
3281 numtowrite = SVAL(smb_buf(inbuf),1);
3282 data = smb_buf(inbuf) + 3;
3284 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
3285 END_PROFILE(SMBsplwr);
3286 return(UNIXERROR(ERRHRD,ERRdiskfull));
3289 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3291 END_PROFILE(SMBsplwr);
3295 /****************************************************************************
3296 The guts of the mkdir command, split out so it may be called by the NT SMB
3298 ****************************************************************************/
3300 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
3302 BOOL bad_path = False;
3303 SMB_STRUCT_STAT sbuf;
3306 unix_convert(directory,conn,0,&bad_path,&sbuf);
3308 if( strchr_m(directory, ':')) {
3309 return NT_STATUS_NOT_A_DIRECTORY;
3312 if (ms_has_wild(directory)) {
3313 return NT_STATUS_OBJECT_NAME_INVALID;
3317 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3320 if (check_name(directory, conn))
3321 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
3324 if(errno == ENOENT) {
3325 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3327 return map_nt_error_from_unix(errno);
3330 return NT_STATUS_OK;
3333 /****************************************************************************
3335 ****************************************************************************/
3337 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3342 START_PROFILE(SMBmkdir);
3344 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status, False);
3345 if (!NT_STATUS_IS_OK(status)) {
3346 END_PROFILE(SMBmkdir);
3347 return ERROR_NT(status);
3350 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
3352 status = mkdir_internal(conn, directory);
3353 if (!NT_STATUS_IS_OK(status)) {
3354 END_PROFILE(SMBmkdir);
3355 return ERROR_NT(status);
3358 outsize = set_message(outbuf,0,0,True);
3360 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
3362 END_PROFILE(SMBmkdir);
3366 /****************************************************************************
3367 Static function used by reply_rmdir to delete an entire directory
3368 tree recursively. Return False on ok, True on fail.
3369 ****************************************************************************/
3371 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
3373 const char *dname = NULL;
3376 struct smb_Dir *dir_hnd = OpenDir(conn, directory);
3381 while((dname = ReadDirName(dir_hnd, &offset))) {
3385 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3388 if (!is_visible_file(conn, directory, dname, &st, False))
3391 /* Construct the full name. */
3392 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3398 pstrcpy(fullname, directory);
3399 pstrcat(fullname, "/");
3400 pstrcat(fullname, dname);
3402 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
3407 if(st.st_mode & S_IFDIR) {
3408 if(recursive_rmdir(conn, fullname)!=0) {
3412 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
3416 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
3425 /****************************************************************************
3426 The internals of the rmdir code - called elsewhere.
3427 ****************************************************************************/
3429 BOOL rmdir_internals(connection_struct *conn, char *directory)
3434 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3435 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
3437 * Check to see if the only thing in this directory are
3438 * vetoed files/directories. If so then delete them and
3439 * retry. If we fail to delete any of them (and we *don't*
3440 * do a recursive delete) then fail the rmdir.
3442 BOOL all_veto_files = True;
3444 struct smb_Dir *dir_hnd = OpenDir(conn, directory);
3446 if(dir_hnd != NULL) {
3447 long dirpos = TellDir(dir_hnd);
3448 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
3449 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3451 if (!is_visible_file(conn, directory, dname, &st, False))
3453 if(!IS_VETO_PATH(conn, dname)) {
3454 all_veto_files = False;
3459 if(all_veto_files) {
3460 SeekDir(dir_hnd,dirpos);
3461 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
3464 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3466 if (!is_visible_file(conn, directory, dname, &st, False))
3469 /* Construct the full name. */
3470 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3475 pstrcpy(fullname, directory);
3476 pstrcat(fullname, "/");
3477 pstrcat(fullname, dname);
3479 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
3481 if(st.st_mode & S_IFDIR) {
3482 if(lp_recursive_veto_delete(SNUM(conn))) {
3483 if(recursive_rmdir(conn, fullname) != 0)
3486 if(SMB_VFS_RMDIR(conn,fullname) != 0)
3488 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
3492 /* Retry the rmdir */
3493 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3503 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
3508 /****************************************************************************
3510 ****************************************************************************/
3512 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3517 BOOL bad_path = False;
3518 SMB_STRUCT_STAT sbuf;
3520 START_PROFILE(SMBrmdir);
3522 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status, False);
3523 if (!NT_STATUS_IS_OK(status)) {
3524 END_PROFILE(SMBrmdir);
3525 return ERROR_NT(status);
3528 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
3530 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
3532 END_PROFILE(SMBrmdir);
3533 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3536 if (check_name(directory,conn)) {
3537 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3538 ok = rmdir_internals(conn, directory);
3542 END_PROFILE(SMBrmdir);
3543 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
3546 outsize = set_message(outbuf,0,0,True);
3548 DEBUG( 3, ( "rmdir %s\n", directory ) );
3550 END_PROFILE(SMBrmdir);
3554 /*******************************************************************
3555 Resolve wildcards in a filename rename.
3556 Note that name is in UNIX charset and thus potentially can be more
3557 than fstring buffer (255 bytes) especially in default UTF-8 case.
3558 Therefore, we use pstring inside and all calls should ensure that
3559 name2 is at least pstring-long (they do already)
3560 ********************************************************************/
3562 static BOOL resolve_wildcards(const char *name1, char *name2)
3564 pstring root1,root2;
3566 char *p,*p2, *pname1, *pname2;
3567 int available_space, actual_space;
3570 pname1 = strrchr_m(name1,'/');
3571 pname2 = strrchr_m(name2,'/');
3573 if (!pname1 || !pname2)
3576 pstrcpy(root1,pname1);
3577 pstrcpy(root2,pname2);
3578 p = strrchr_m(root1,'.');
3585 p = strrchr_m(root2,'.');
3599 } else if (*p2 == '*') {
3615 } else if (*p2 == '*') {
3625 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
3628 actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
3629 if (actual_space >= available_space - 1) {
3630 DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
3631 actual_space - available_space));
3634 pstrcpy_base(pname2, root2, name2);
3640 /****************************************************************************
3641 Ensure open files have their names updates.
3642 ****************************************************************************/
3644 static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
3647 BOOL did_rename = False;
3649 for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
3650 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
3651 fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
3652 fsp->fsp_name, newname ));
3653 string_set(&fsp->fsp_name, newname);
3658 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
3659 (unsigned int)dev, (double)inode, newname ));
3662 /****************************************************************************
3663 Rename an open file - given an fsp.
3664 ****************************************************************************/
3666 NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, uint16 attrs, BOOL replace_if_exists)
3668 SMB_STRUCT_STAT sbuf;
3669 BOOL bad_path = False;
3670 pstring newname_last_component;
3671 NTSTATUS error = NT_STATUS_OK;
3676 rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
3678 /* Quick check for "." and ".." */
3679 if (!bad_path && newname_last_component[0] == '.') {
3680 if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) {
3681 return NT_STATUS_ACCESS_DENIED;
3684 if (!rcdest && bad_path) {
3685 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3688 /* Ensure newname contains a '/' */
3689 if(strrchr_m(newname,'/') == 0) {
3692 pstrcpy(tmpstr, "./");
3693 pstrcat(tmpstr, newname);
3694 pstrcpy(newname, tmpstr);
3698 * Check for special case with case preserving and not
3699 * case sensitive. If the old last component differs from the original
3700 * last component only by case, then we should allow
3701 * the rename (user is trying to change the case of the
3705 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
3706 strequal(newname, fsp->fsp_name)) {
3708 pstring newname_modified_last_component;
3711 * Get the last component of the modified name.
3712 * Note that we guarantee that newname contains a '/'
3715 p = strrchr_m(newname,'/');
3716 pstrcpy(newname_modified_last_component,p+1);
3718 if(strcsequal(newname_modified_last_component,
3719 newname_last_component) == False) {
3721 * Replace the modified last component with
3724 pstrcpy(p+1, newname_last_component);
3729 * If the src and dest names are identical - including case,
3730 * don't do the rename, just return success.
3733 if (strcsequal(fsp->fsp_name, newname)) {
3734 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
3736 return NT_STATUS_OK;
3739 dest_exists = vfs_object_exist(conn,newname,NULL);
3741 if(!replace_if_exists && dest_exists) {
3742 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
3743 fsp->fsp_name,newname));
3744 return NT_STATUS_OBJECT_NAME_COLLISION;
3747 error = can_rename(newname,conn,attrs,&sbuf);
3749 if (dest_exists && !NT_STATUS_IS_OK(error)) {
3750 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3751 nt_errstr(error), fsp->fsp_name,newname));
3752 if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
3753 error = NT_STATUS_ACCESS_DENIED;
3757 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
3758 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
3759 fsp->fsp_name,newname));
3760 rename_open_files(conn, fsp->dev, fsp->inode, newname);
3761 return NT_STATUS_OK;
3764 if (errno == ENOTDIR || errno == EISDIR)
3765 error = NT_STATUS_OBJECT_NAME_COLLISION;
3767 error = map_nt_error_from_unix(errno);
3769 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
3770 nt_errstr(error), fsp->fsp_name,newname));
3775 /****************************************************************************
3776 The guts of the rename command, split out so it may be called by the NT SMB
3778 ****************************************************************************/
3780 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint16 attrs, BOOL replace_if_exists)
3784 pstring last_component_src;
3785 pstring last_component_dest;
3788 BOOL bad_path_src = False;
3789 BOOL bad_path_dest = False;
3791 NTSTATUS error = NT_STATUS_OK;
3794 SMB_STRUCT_STAT sbuf1, sbuf2;
3796 *directory = *mask = 0;
3801 rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1);
3802 if (!rc && bad_path_src) {
3803 if (ms_has_wild(last_component_src))
3804 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3805 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3808 /* Quick check for "." and ".." */
3809 if (last_component_src[0] == '.') {
3810 if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) {
3811 return NT_STATUS_OBJECT_NAME_INVALID;
3815 rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2);
3817 /* Quick check for "." and ".." */
3818 if (last_component_dest[0] == '.') {
3819 if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) {
3820 return NT_STATUS_OBJECT_NAME_INVALID;
3825 * Split the old name into directory and last component
3826 * strings. Note that unix_convert may have stripped off a
3827 * leading ./ from both name and newname if the rename is
3828 * at the root of the share. We need to make sure either both
3829 * name and newname contain a / character or neither of them do
3830 * as this is checked in resolve_wildcards().
3833 p = strrchr_m(name,'/');
3835 pstrcpy(directory,".");
3839 pstrcpy(directory,name);
3841 *p = '/'; /* Replace needed for exceptional test below. */
3845 * We should only check the mangled cache
3846 * here if unix_convert failed. This means
3847 * that the path in 'mask' doesn't exist
3848 * on the file system and so we need to look
3849 * for a possible mangle. This patch from
3850 * Tine Smukavec <valentin.smukavec@hermes.si>.
3853 if (!rc && mangle_is_mangled(mask))
3854 mangle_check_cache( mask, sizeof(pstring)-1 );
3856 has_wild = ms_has_wild(mask);
3860 * No wildcards - just process the one file.
3862 BOOL is_short_name = mangle_is_8_3(name, True);
3864 /* Add a terminating '/' to the directory name. */
3865 pstrcat(directory,"/");
3866 pstrcat(directory,mask);
3868 /* Ensure newname contains a '/' also */
3869 if(strrchr_m(newname,'/') == 0) {
3872 pstrcpy(tmpstr, "./");
3873 pstrcat(tmpstr, newname);
3874 pstrcpy(newname, tmpstr);
3877 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
3878 directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
3879 conn->case_sensitive, conn->case_preserve, conn->short_case_preserve, directory,
3880 newname, last_component_dest, is_short_name));
3883 * Check for special case with case preserving and not
3884 * case sensitive, if directory and newname are identical,
3885 * and the old last component differs from the original
3886 * last component only by case, then we should allow
3887 * the rename (user is trying to change the case of the
3890 if((conn->case_sensitive == False) &&
3891 (((conn->case_preserve == True) &&
3892 (is_short_name == False)) ||
3893 ((conn->short_case_preserve == True) &&
3894 (is_short_name == True))) &&
3895 strcsequal(directory, newname)) {
3896 pstring modified_last_component;
3899 * Get the last component of the modified name.
3900 * Note that we guarantee that newname contains a '/'
3903 p = strrchr_m(newname,'/');
3904 pstrcpy(modified_last_component,p+1);
3906 if(strcsequal(modified_last_component,
3907 last_component_dest) == False) {
3909 * Replace the modified last component with
3912 pstrcpy(p+1, last_component_dest);
3916 resolve_wildcards(directory,newname);
3919 * The source object must exist.
3922 if (!vfs_object_exist(conn, directory, &sbuf1)) {
3923 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
3924 directory,newname));
3926 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
3928 * Must return different errors depending on whether the parent
3929 * directory existed or not.
3932 p = strrchr_m(directory, '/');
3934 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3936 if (vfs_object_exist(conn, directory, NULL))
3937 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3938 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3940 error = map_nt_error_from_unix(errno);
3941 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3942 nt_errstr(error), directory,newname));
3947 if (!rcdest && bad_path_dest) {
3948 if (ms_has_wild(last_component_dest))
3949 return NT_STATUS_OBJECT_NAME_INVALID;
3950 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3953 error = can_rename(directory,conn,attrs,&sbuf1);
3955 if (!NT_STATUS_IS_OK(error)) {
3956 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3957 nt_errstr(error), directory,newname));
3962 * If the src and dest names are identical - including case,
3963 * don't do the rename, just return success.
3966 if (strcsequal(directory, newname)) {
3967 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3968 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
3969 return NT_STATUS_OK;
3972 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
3973 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
3974 directory,newname));
3975 return NT_STATUS_OBJECT_NAME_COLLISION;
3978 if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
3979 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
3980 directory,newname));
3981 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3982 return NT_STATUS_OK;
3985 if (errno == ENOTDIR || errno == EISDIR)
3986 error = NT_STATUS_OBJECT_NAME_COLLISION;
3988 error = map_nt_error_from_unix(errno);
3990 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3991 nt_errstr(error), directory,newname));
3996 * Wildcards - process each file that matches.
3998 struct smb_Dir *dir_hnd = NULL;
4002 if (check_name(directory,conn))
4003 dir_hnd = OpenDir(conn, directory);
4007 error = NT_STATUS_NO_SUCH_FILE;
4008 /* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
4010 if (strequal(mask,"????????.???"))
4013 while ((dname = ReadDirName(dir_hnd, &offset))) {
4015 BOOL sysdir_entry = False;
4017 pstrcpy(fname,dname);
4019 /* Quick check for "." and ".." */
4020 if (fname[0] == '.') {
4021 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
4023 sysdir_entry = True;
4030 if (!is_visible_file(conn, directory, dname, &sbuf1, False))
4033 if(!mask_match(fname, mask, conn->case_sensitive))
4037 error = NT_STATUS_OBJECT_NAME_INVALID;
4041 error = NT_STATUS_ACCESS_DENIED;
4042 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
4043 if (!vfs_object_exist(conn, fname, &sbuf1)) {
4044 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
4045 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
4048 error = can_rename(fname,conn,attrs,&sbuf1);
4049 if (!NT_STATUS_IS_OK(error)) {
4050 DEBUG(6,("rename %s refused\n", fname));
4053 pstrcpy(destname,newname);
4055 if (!resolve_wildcards(fname,destname)) {
4056 DEBUG(6,("resolve_wildcards %s %s failed\n",
4061 if (strcsequal(fname,destname)) {
4062 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
4063 DEBUG(3,("rename_internals: identical names in wildcard rename %s - success\n", fname));
4065 error = NT_STATUS_OK;
4069 if (!replace_if_exists &&
4070 vfs_file_exist(conn,destname, NULL)) {
4071 DEBUG(6,("file_exist %s\n", destname));
4072 error = NT_STATUS_OBJECT_NAME_COLLISION;
4076 if (!SMB_VFS_RENAME(conn,fname,destname)) {
4077 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
4079 error = NT_STATUS_OK;
4081 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
4086 if (!NT_STATUS_EQUAL(error,NT_STATUS_NO_SUCH_FILE)) {
4087 if (!rcdest && bad_path_dest) {
4088 if (ms_has_wild(last_component_dest))
4089 return NT_STATUS_OBJECT_NAME_INVALID;
4090 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
4095 if (count == 0 && NT_STATUS_IS_OK(error)) {
4096 error = map_nt_error_from_unix(errno);
4102 /****************************************************************************
4104 ****************************************************************************/
4106 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
4113 uint16 attrs = SVAL(inbuf,smb_vwv0);
4116 START_PROFILE(SMBmv);
4118 p = smb_buf(inbuf) + 1;
4119 p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, True);
4120 if (!NT_STATUS_IS_OK(status)) {
4122 return ERROR_NT(status);
4125 p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, True);
4126 if (!NT_STATUS_IS_OK(status)) {
4128 return ERROR_NT(status);
4131 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
4132 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4134 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
4136 status = rename_internals(conn, name, newname, attrs, False);
4137 if (!NT_STATUS_IS_OK(status)) {
4139 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4140 /* We have re-scheduled this call. */
4141 clear_cached_errors();
4144 return ERROR_NT(status);
4148 * Win2k needs a changenotify request response before it will
4149 * update after a rename..
4151 process_pending_change_notify_queue((time_t)0);
4152 outsize = set_message(outbuf,0,0,True);
4158 /*******************************************************************
4159 Copy a file as part of a reply_copy.
4160 ******************************************************************/
4162 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
4163 int count,BOOL target_is_directory, int *err_ret)
4166 SMB_STRUCT_STAT src_sbuf, sbuf2;
4168 files_struct *fsp1,*fsp2;
4174 pstrcpy(dest,dest1);
4175 if (target_is_directory) {
4176 char *p = strrchr_m(src,'/');
4185 if (!vfs_file_exist(conn,src,&src_sbuf))
4188 fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
4189 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,INTERNAL_OPEN_ONLY,
4195 if (!target_is_directory && count)
4196 ofun = FILE_EXISTS_OPEN;
4198 dosattrs = dos_mode(conn, src, &src_sbuf);
4199 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
4200 ZERO_STRUCTP(&sbuf2);
4202 fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
4203 ofun,dosattrs,INTERNAL_OPEN_ONLY,&Access,&action);
4206 close_file(fsp1,False);
4210 if ((ofun&3) == 1) {
4211 if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
4212 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
4214 * Stop the copy from occurring.
4217 src_sbuf.st_size = 0;
4221 if (src_sbuf.st_size)
4222 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
4224 close_file(fsp1,False);
4226 /* Ensure the modtime is set correctly on the destination file. */
4227 fsp2->pending_modtime = src_sbuf.st_mtime;
4230 * As we are opening fsp1 read-only we only expect
4231 * an error on close on fsp2 if we are out of space.
4232 * Thus we don't look at the error return from the
4235 *err_ret = close_file(fsp2,False);
4237 return(ret == (SMB_OFF_T)src_sbuf.st_size);
4240 /****************************************************************************
4241 Reply to a file copy.
4242 ****************************************************************************/
4244 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4249 pstring mask,newname;
4252 int error = ERRnoaccess;
4256 int tid2 = SVAL(inbuf,smb_vwv0);
4257 int ofun = SVAL(inbuf,smb_vwv1);
4258 int flags = SVAL(inbuf,smb_vwv2);
4259 BOOL target_is_directory=False;
4260 BOOL bad_path1 = False;
4261 BOOL bad_path2 = False;
4263 SMB_STRUCT_STAT sbuf1, sbuf2;
4266 START_PROFILE(SMBcopy);
4268 *directory = *mask = 0;
4271 p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, True);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 END_PROFILE(SMBcopy);
4274 return ERROR_NT(status);
4276 p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, True);
4277 if (!NT_STATUS_IS_OK(status)) {
4278 END_PROFILE(SMBcopy);
4279 return ERROR_NT(status);
4282 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
4284 if (tid2 != conn->cnum) {
4285 /* can't currently handle inter share copies XXXX */
4286 DEBUG(3,("Rejecting inter-share copy\n"));
4287 END_PROFILE(SMBcopy);
4288 return ERROR_DOS(ERRSRV,ERRinvdevice);
4291 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
4292 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4294 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
4295 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
4297 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
4299 if ((flags&1) && target_is_directory) {
4300 END_PROFILE(SMBcopy);
4301 return ERROR_DOS(ERRDOS,ERRbadfile);
4304 if ((flags&2) && !target_is_directory) {
4305 END_PROFILE(SMBcopy);
4306 return ERROR_DOS(ERRDOS,ERRbadpath);
4309 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
4310 /* wants a tree copy! XXXX */
4311 DEBUG(3,("Rejecting tree copy\n"));
4312 END_PROFILE(SMBcopy);
4313 return ERROR_DOS(ERRSRV,ERRerror);
4316 p = strrchr_m(name,'/');
4318 pstrcpy(directory,"./");
4322 pstrcpy(directory,name);
4327 * We should only check the mangled cache
4328 * here if unix_convert failed. This means
4329 * that the path in 'mask' doesn't exist
4330 * on the file system and so we need to look
4331 * for a possible mangle. This patch from
4332 * Tine Smukavec <valentin.smukavec@hermes.si>.
4335 if (!rc && mangle_is_mangled(mask))
4336 mangle_check_cache( mask, sizeof(pstring)-1 );
4338 has_wild = ms_has_wild(mask);
4341 pstrcat(directory,"/");
4342 pstrcat(directory,mask);
4343 if (resolve_wildcards(directory,newname) &&
4344 copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
4348 END_PROFILE(SMBcopy);
4349 return(UNIXERROR(ERRHRD,ERRgeneral));
4352 exists = vfs_file_exist(conn,directory,NULL);
4355 struct smb_Dir *dir_hnd = NULL;
4359 if (check_name(directory,conn))
4360 dir_hnd = OpenDir(conn, directory);
4366 if (strequal(mask,"????????.???"))
4369 while ((dname = ReadDirName(dir_hnd, &offset))) {
4371 pstrcpy(fname,dname);
4373 if (!is_visible_file(conn, directory, dname, &sbuf1, False))
4376 if(!mask_match(fname, mask, conn->case_sensitive))
4379 error = ERRnoaccess;
4380 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
4381 pstrcpy(destname,newname);
4382 if (resolve_wildcards(fname,destname) &&
4383 copy_file(fname,destname,conn,ofun,
4384 count,target_is_directory,&err))
4386 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
4394 /* Error on close... */
4396 END_PROFILE(SMBcopy);
4397 return(UNIXERROR(ERRHRD,ERRgeneral));
4401 END_PROFILE(SMBcopy);
4402 return ERROR_DOS(ERRDOS,error);
4404 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
4405 unix_ERR_class = ERRDOS;
4406 unix_ERR_code = ERRbadpath;
4408 END_PROFILE(SMBcopy);
4409 return(UNIXERROR(ERRDOS,error));
4413 outsize = set_message(outbuf,1,0,True);
4414 SSVAL(outbuf,smb_vwv0,count);
4416 END_PROFILE(SMBcopy);
4420 /****************************************************************************
4422 ****************************************************************************/
4424 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4432 START_PROFILE(pathworks_setdir);
4435 if (!CAN_SETDIR(snum)) {
4436 END_PROFILE(pathworks_setdir);
4437 return ERROR_DOS(ERRDOS,ERRnoaccess);
4440 srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status, False);
4441 if (!NT_STATUS_IS_OK(status)) {
4442 END_PROFILE(pathworks_setdir);
4443 return ERROR_NT(status);
4446 if (strlen(newdir) == 0) {
4449 ok = vfs_directory_exist(conn,newdir,NULL);
4451 string_set(&conn->connectpath,newdir);
4455 END_PROFILE(pathworks_setdir);
4456 return ERROR_DOS(ERRDOS,ERRbadpath);
4459 outsize = set_message(outbuf,0,0,True);
4460 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
4462 DEBUG(3,("setdir %s\n", newdir));
4464 END_PROFILE(pathworks_setdir);
4468 /****************************************************************************
4469 Get a lock pid, dealing with large count requests.
4470 ****************************************************************************/
4472 uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
4474 if(!large_file_format)
4475 return SVAL(data,SMB_LPID_OFFSET(data_offset));
4477 return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
4480 /****************************************************************************
4481 Get a lock count, dealing with large count requests.
4482 ****************************************************************************/
4484 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
4486 SMB_BIG_UINT count = 0;
4488 if(!large_file_format) {
4489 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
4492 #if defined(HAVE_LONGLONG)
4493 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
4494 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
4495 #else /* HAVE_LONGLONG */
4498 * NT4.x seems to be broken in that it sends large file (64 bit)
4499 * lockingX calls even if the CAP_LARGE_FILES was *not*
4500 * negotiated. For boxes without large unsigned ints truncate the
4501 * lock count by dropping the top 32 bits.
4504 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
4505 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
4506 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
4507 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
4508 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
4511 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
4512 #endif /* HAVE_LONGLONG */
4518 #if !defined(HAVE_LONGLONG)
4519 /****************************************************************************
4520 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
4521 ****************************************************************************/
4523 static uint32 map_lock_offset(uint32 high, uint32 low)
4527 uint32 highcopy = high;
4530 * Try and find out how many significant bits there are in high.
4533 for(i = 0; highcopy; i++)
4537 * We use 31 bits not 32 here as POSIX
4538 * lock offsets may not be negative.
4541 mask = (~0) << (31 - i);
4544 return 0; /* Fail. */
4550 #endif /* !defined(HAVE_LONGLONG) */
4552 /****************************************************************************
4553 Get a lock offset, dealing with large offset requests.
4554 ****************************************************************************/
4556 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
4558 SMB_BIG_UINT offset = 0;
4562 if(!large_file_format) {
4563 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
4566 #if defined(HAVE_LONGLONG)
4567 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
4568 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
4569 #else /* HAVE_LONGLONG */
4572 * NT4.x seems to be broken in that it sends large file (64 bit)
4573 * lockingX calls even if the CAP_LARGE_FILES was *not*
4574 * negotiated. For boxes without large unsigned ints mangle the
4575 * lock offset by mapping the top 32 bits onto the lower 32.
4578 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
4579 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4580 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
4583 if((new_low = map_lock_offset(high, low)) == 0) {
4585 return (SMB_BIG_UINT)-1;
4588 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
4589 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
4590 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
4591 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
4594 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4595 #endif /* HAVE_LONGLONG */
4601 /****************************************************************************
4602 Reply to a lockingX request.
4603 ****************************************************************************/
4605 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4607 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
4608 unsigned char locktype = CVAL(inbuf,smb_vwv3);
4609 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
4610 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
4611 uint16 num_locks = SVAL(inbuf,smb_vwv7);
4612 SMB_BIG_UINT count = 0, offset = 0;
4614 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
4617 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
4619 BOOL my_lock_ctx = False;
4622 START_PROFILE(SMBlockingX);
4624 CHECK_FSP(fsp,conn);
4626 data = smb_buf(inbuf);
4628 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
4629 /* we don't support these - and CANCEL_LOCK makes w2k
4630 and XP reboot so I don't really want to be
4631 compatible! (tridge) */
4632 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
4635 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
4636 /* Need to make this like a cancel.... JRA. */
4637 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
4640 /* Check if this is an oplock break on a file
4641 we have granted an oplock on.
4643 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
4644 /* Client can insist on breaking to none. */
4645 BOOL break_to_none = (oplocklevel == 0);
4647 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
4648 (unsigned int)oplocklevel, fsp->fnum ));
4651 * Make sure we have granted an exclusive or batch oplock on this file.
4654 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
4655 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
4656 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
4658 /* if this is a pure oplock break request then don't send a reply */
4659 if (num_locks == 0 && num_ulocks == 0) {
4660 END_PROFILE(SMBlockingX);
4663 END_PROFILE(SMBlockingX);
4664 return ERROR_DOS(ERRDOS,ERRlock);
4668 if (remove_oplock(fsp, break_to_none) == False) {
4669 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
4673 /* if this is a pure oplock break request then don't send a reply */
4674 if (num_locks == 0 && num_ulocks == 0) {
4675 /* Sanity check - ensure a pure oplock break is not a
4677 if(CVAL(inbuf,smb_vwv0) != 0xff)
4678 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
4679 (unsigned int)CVAL(inbuf,smb_vwv0) ));
4680 END_PROFILE(SMBlockingX);
4686 * We do this check *after* we have checked this is not a oplock break
4687 * response message. JRA.
4690 release_level_2_oplocks_on_change(fsp);
4692 /* Data now points at the beginning of the list
4693 of smb_unlkrng structs */
4694 for(i = 0; i < (int)num_ulocks; i++) {
4695 lock_pid = get_lock_pid( data, i, large_file_format);
4696 count = get_lock_count( data, i, large_file_format);
4697 offset = get_lock_offset( data, i, large_file_format, &err);
4700 * There is no error code marked "stupid client bug".... :-).
4703 END_PROFILE(SMBlockingX);
4704 return ERROR_DOS(ERRDOS,ERRnoaccess);
4707 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
4708 (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
4710 status = do_unlock(fsp,conn,lock_pid,count,offset);
4711 if (NT_STATUS_V(status)) {
4712 END_PROFILE(SMBlockingX);
4713 return ERROR_NT(status);
4717 /* Setup the timeout in seconds. */
4719 lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
4721 /* Now do any requested locks */
4722 data += ((large_file_format ? 20 : 10)*num_ulocks);
4724 /* Data now points at the beginning of the list
4725 of smb_lkrng structs */
4727 for(i = 0; i < (int)num_locks; i++) {
4728 lock_pid = get_lock_pid( data, i, large_file_format);
4729 count = get_lock_count( data, i, large_file_format);
4730 offset = get_lock_offset( data, i, large_file_format, &err);
4733 * There is no error code marked "stupid client bug".... :-).
4736 END_PROFILE(SMBlockingX);
4737 return ERROR_DOS(ERRDOS,ERRnoaccess);
4740 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
4741 (double)offset, (double)count, (unsigned int)lock_pid,
4742 fsp->fsp_name, (int)lock_timeout ));
4744 status = do_lock_spin(fsp,conn,lock_pid, count,offset,
4745 ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
4746 if (NT_STATUS_V(status)) {
4748 * Interesting fact found by IFSTEST /t LockOverlappedTest...
4749 * Even if it's our own lock context, we need to wait here as
4750 * there may be an unlock on the way.
4751 * So I removed a "&& !my_lock_ctx" from the following
4752 * if statement. JRA.
4754 if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
4756 * A blocking lock was requested. Package up
4757 * this smb into a queued request and push it
4758 * onto the blocking lock queue.
4760 if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
4761 END_PROFILE(SMBlockingX);
4769 /* If any of the above locks failed, then we must unlock
4770 all of the previous locks (X/Open spec). */
4771 if (i != num_locks && num_locks != 0) {
4773 * Ensure we don't do a remove on the lock that just failed,
4774 * as under POSIX rules, if we have a lock already there, we
4775 * will delete it (and we shouldn't) .....
4777 for(i--; i >= 0; i--) {
4778 lock_pid = get_lock_pid( data, i, large_file_format);
4779 count = get_lock_count( data, i, large_file_format);
4780 offset = get_lock_offset( data, i, large_file_format, &err);
4783 * There is no error code marked "stupid client bug".... :-).
4786 END_PROFILE(SMBlockingX);
4787 return ERROR_DOS(ERRDOS,ERRnoaccess);
4790 do_unlock(fsp,conn,lock_pid,count,offset);
4792 END_PROFILE(SMBlockingX);
4793 return ERROR_NT(status);
4796 set_message(outbuf,2,0,True);
4798 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4799 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
4801 END_PROFILE(SMBlockingX);
4802 return chain_reply(inbuf,outbuf,length,bufsize);
4805 /****************************************************************************
4806 Reply to a SMBreadbmpx (read block multiplex) request.
4807 ****************************************************************************/
4809 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4820 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4821 START_PROFILE(SMBreadBmpx);
4823 /* this function doesn't seem to work - disable by default */
4824 if (!lp_readbmpx()) {
4825 END_PROFILE(SMBreadBmpx);
4826 return ERROR_DOS(ERRSRV,ERRuseSTD);
4829 outsize = set_message(outbuf,8,0,True);
4831 CHECK_FSP(fsp,conn);
4834 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
4835 maxcount = SVAL(inbuf,smb_vwv3);
4837 data = smb_buf(outbuf);
4838 pad = ((long)data)%4;
4843 max_per_packet = bufsize-(outsize+pad);
4847 if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
4848 END_PROFILE(SMBreadBmpx);
4849 return ERROR_DOS(ERRDOS,ERRlock);
4853 size_t N = MIN(max_per_packet,tcount-total_read);
4855 nread = read_file(fsp,data,startpos,N);
4860 if (nread < (ssize_t)N)
4861 tcount = total_read + nread;
4863 set_message(outbuf,8,nread,False);
4864 SIVAL(outbuf,smb_vwv0,startpos);
4865 SSVAL(outbuf,smb_vwv2,tcount);
4866 SSVAL(outbuf,smb_vwv6,nread);
4867 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
4869 if (!send_smb(smbd_server_fd(),outbuf))
4870 exit_server("reply_readbmpx: send_smb failed.");
4872 total_read += nread;
4874 } while (total_read < (ssize_t)tcount);
4876 END_PROFILE(SMBreadBmpx);
4880 /****************************************************************************
4881 Reply to a SMBsetattrE.
4882 ****************************************************************************/
4884 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4886 struct utimbuf unix_times;
4888 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4889 START_PROFILE(SMBsetattrE);
4891 outsize = set_message(outbuf,0,0,True);
4893 if(!fsp || (fsp->conn != conn)) {
4894 END_PROFILE(SMBgetattrE);
4895 return ERROR_DOS(ERRDOS,ERRbadfid);
4899 * Convert the DOS times into unix times. Ignore create
4900 * time as UNIX can't set this.
4903 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4904 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4907 * Patch from Ray Frush <frush@engr.colostate.edu>
4908 * Sometimes times are sent as zero - ignore them.
4911 if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
4912 /* Ignore request */
4913 if( DEBUGLVL( 3 ) ) {
4914 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4915 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4917 END_PROFILE(SMBsetattrE);
4919 } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
4920 /* set modify time = to access time if modify time was 0 */
4921 unix_times.modtime = unix_times.actime;
4924 /* Set the date on this file */
4925 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
4926 END_PROFILE(SMBsetattrE);
4927 return ERROR_DOS(ERRDOS,ERRnoaccess);
4930 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4931 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4933 END_PROFILE(SMBsetattrE);
4938 /* Back from the dead for OS/2..... JRA. */
4940 /****************************************************************************
4941 Reply to a SMBwritebmpx (write block multiplex primary) request.
4942 ****************************************************************************/
4944 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4947 ssize_t nwritten = -1;
4954 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4955 START_PROFILE(SMBwriteBmpx);
4957 CHECK_FSP(fsp,conn);
4961 tcount = SVAL(inbuf,smb_vwv1);
4962 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
4963 write_through = BITSETW(inbuf+smb_vwv7,0);
4964 numtowrite = SVAL(inbuf,smb_vwv10);
4965 smb_doff = SVAL(inbuf,smb_vwv11);
4967 data = smb_base(inbuf) + smb_doff;
4969 /* If this fails we need to send an SMBwriteC response,
4970 not an SMBwritebmpx - set this up now so we don't forget */
4971 SCVAL(outbuf,smb_com,SMBwritec);
4973 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
4974 END_PROFILE(SMBwriteBmpx);
4975 return(ERROR_DOS(ERRDOS,ERRlock));
4978 nwritten = write_file(fsp,data,startpos,numtowrite);
4980 if(lp_syncalways(SNUM(conn)) || write_through)
4981 sync_file(conn,fsp);
4983 if(nwritten < (ssize_t)numtowrite) {
4984 END_PROFILE(SMBwriteBmpx);
4985 return(UNIXERROR(ERRHRD,ERRdiskfull));
4988 /* If the maximum to be written to this file
4989 is greater than what we just wrote then set
4990 up a secondary struct to be attached to this
4991 fd, we will use this to cache error messages etc. */
4993 if((ssize_t)tcount > nwritten) {
4994 write_bmpx_struct *wbms;
4995 if(fsp->wbmpx_ptr != NULL)
4996 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4998 wbms = SMB_MALLOC_P(write_bmpx_struct);
5000 DEBUG(0,("Out of memory in reply_readmpx\n"));
5001 END_PROFILE(SMBwriteBmpx);
5002 return(ERROR_DOS(ERRSRV,ERRnoresource));
5004 wbms->wr_mode = write_through;
5005 wbms->wr_discard = False; /* No errors yet */
5006 wbms->wr_total_written = nwritten;
5007 wbms->wr_errclass = 0;
5009 fsp->wbmpx_ptr = wbms;
5012 /* We are returning successfully, set the message type back to
5014 SCVAL(outbuf,smb_com,SMBwriteBmpx);
5016 outsize = set_message(outbuf,1,0,True);
5018 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
5020 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
5021 fsp->fnum, (int)numtowrite, (int)nwritten ) );
5023 if (write_through && tcount==nwritten) {
5024 /* We need to send both a primary and a secondary response */
5025 smb_setlen(outbuf,outsize - 4);
5026 if (!send_smb(smbd_server_fd(),outbuf))
5027 exit_server("reply_writebmpx: send_smb failed.");
5029 /* Now the secondary */
5030 outsize = set_message(outbuf,1,0,True);
5031 SCVAL(outbuf,smb_com,SMBwritec);
5032 SSVAL(outbuf,smb_vwv0,nwritten);
5035 END_PROFILE(SMBwriteBmpx);
5039 /****************************************************************************
5040 Reply to a SMBwritebs (write block multiplex secondary) request.
5041 ****************************************************************************/
5043 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
5046 ssize_t nwritten = -1;
5053 write_bmpx_struct *wbms;
5054 BOOL send_response = False;
5055 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5056 START_PROFILE(SMBwriteBs);
5058 CHECK_FSP(fsp,conn);
5061 tcount = SVAL(inbuf,smb_vwv1);
5062 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
5063 numtowrite = SVAL(inbuf,smb_vwv6);
5064 smb_doff = SVAL(inbuf,smb_vwv7);
5066 data = smb_base(inbuf) + smb_doff;
5068 /* We need to send an SMBwriteC response, not an SMBwritebs */
5069 SCVAL(outbuf,smb_com,SMBwritec);
5071 /* This fd should have an auxiliary struct attached,
5072 check that it does */
5073 wbms = fsp->wbmpx_ptr;
5075 END_PROFILE(SMBwriteBs);
5079 /* If write through is set we can return errors, else we must cache them */
5080 write_through = wbms->wr_mode;
5082 /* Check for an earlier error */
5083 if(wbms->wr_discard) {
5084 END_PROFILE(SMBwriteBs);
5085 return -1; /* Just discard the packet */
5088 nwritten = write_file(fsp,data,startpos,numtowrite);
5090 if(lp_syncalways(SNUM(conn)) || write_through)
5091 sync_file(conn,fsp);
5093 if (nwritten < (ssize_t)numtowrite) {
5095 /* We are returning an error - we can delete the aux struct */
5098 fsp->wbmpx_ptr = NULL;
5099 END_PROFILE(SMBwriteBs);
5100 return(ERROR_DOS(ERRHRD,ERRdiskfull));
5102 END_PROFILE(SMBwriteBs);
5103 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
5106 /* Increment the total written, if this matches tcount
5107 we can discard the auxiliary struct (hurrah !) and return a writeC */
5108 wbms->wr_total_written += nwritten;
5109 if(wbms->wr_total_written >= tcount) {
5110 if (write_through) {
5111 outsize = set_message(outbuf,1,0,True);
5112 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
5113 send_response = True;
5117 fsp->wbmpx_ptr = NULL;
5121 END_PROFILE(SMBwriteBs);
5125 END_PROFILE(SMBwriteBs);
5129 /****************************************************************************
5130 Reply to a SMBgetattrE.
5131 ****************************************************************************/
5133 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
5135 SMB_STRUCT_STAT sbuf;
5138 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5139 START_PROFILE(SMBgetattrE);
5141 outsize = set_message(outbuf,11,0,True);
5143 if(!fsp || (fsp->conn != conn)) {
5144 END_PROFILE(SMBgetattrE);
5145 return ERROR_DOS(ERRDOS,ERRbadfid);
5148 /* Do an fstat on this file */
5149 if(fsp_stat(fsp, &sbuf)) {
5150 END_PROFILE(SMBgetattrE);
5151 return(UNIXERROR(ERRDOS,ERRnoaccess));
5154 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
5157 * Convert the times into dos times. Set create
5158 * date to be last modify date as UNIX doesn't save
5162 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
5163 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
5164 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
5167 SIVAL(outbuf,smb_vwv6,0);
5168 SIVAL(outbuf,smb_vwv8,0);
5170 uint32 allocation_size = get_allocation_size(fsp, &sbuf);
5171 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
5172 SIVAL(outbuf,smb_vwv8,allocation_size);
5174 SSVAL(outbuf,smb_vwv10, mode);
5176 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
5178 END_PROFILE(SMBgetattrE);