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 unsigned int smb_echo_count = 0;
34 extern uint32 global_client_caps;
36 extern struct current_user current_user;
37 extern BOOL global_encrypted_passwords_negotiated;
39 /****************************************************************************
40 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
41 We're assuming here that '/' is not the second byte in any multibyte char
42 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
44 ****************************************************************************/
46 NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
49 const char *s = srcname;
50 NTSTATUS ret = NT_STATUS_OK;
51 BOOL start_of_name_component = True;
52 unsigned int num_bad_components = 0;
55 if (IS_DIRECTORY_SEP(*s)) {
57 * Safe to assume is not the second part of a mb char as this is handled below.
59 /* Eat multiple '/' or '\\' */
60 while (IS_DIRECTORY_SEP(*s)) {
63 if ((d != destname) && (*s != '\0')) {
64 /* We only care about non-leading or trailing '/' or '\\' */
68 start_of_name_component = True;
72 if (start_of_name_component) {
73 if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
74 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
77 * No mb char starts with '.' so we're safe checking the directory separator here.
80 /* If we just added a '/' - delete it */
81 if ((d > destname) && (*(d-1) == '/')) {
86 /* Are we at the start ? Can't go back further if so. */
88 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
91 /* Go back one level... */
92 /* We know this is safe as '/' cannot be part of a mb sequence. */
93 /* NOTE - if this assumption is invalid we are not in good shape... */
94 /* Decrement d first as d points to the *next* char to write into. */
95 for (d--; d > destname; d--) {
99 s += 2; /* Else go past the .. */
100 /* We're still at the start of a name component, just the previous one. */
102 if (num_bad_components) {
103 /* Hmmm. Should we only decrement the bad_components if
104 we're removing a bad component ? Need to check this. JRA. */
105 num_bad_components--;
110 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
111 /* Component of pathname can't be "." only. */
112 ret = NT_STATUS_OBJECT_NAME_INVALID;
113 num_bad_components++;
121 return NT_STATUS_OBJECT_NAME_INVALID;
129 return NT_STATUS_OBJECT_NAME_INVALID;
136 /* Get the size of the next MB character. */
137 next_codepoint(s,&siz);
155 DEBUG(0,("check_path_syntax: character length assumptions invalid !\n"));
157 return NT_STATUS_INVALID_PARAMETER;
160 if (start_of_name_component && num_bad_components) {
161 num_bad_components++;
163 start_of_name_component = False;
166 if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
167 if (num_bad_components > 1) {
168 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
176 /****************************************************************************
177 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
178 path or anything including wildcards.
179 We're assuming here that '/' is not the second byte in any multibyte char
180 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
182 ****************************************************************************/
184 NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname, BOOL *p_contains_wcard)
187 const char *s = srcname;
188 NTSTATUS ret = NT_STATUS_OK;
189 BOOL start_of_name_component = True;
190 unsigned int num_bad_components = 0;
192 *p_contains_wcard = False;
195 if (IS_DIRECTORY_SEP(*s)) {
197 * Safe to assume is not the second part of a mb char as this is handled below.
199 /* Eat multiple '/' or '\\' */
200 while (IS_DIRECTORY_SEP(*s)) {
203 if ((d != destname) && (*s != '\0')) {
204 /* We only care about non-leading or trailing '/' or '\\' */
208 start_of_name_component = True;
212 if (start_of_name_component) {
213 if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
214 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
217 * No mb char starts with '.' so we're safe checking the directory separator here.
220 /* If we just added a '/' - delete it */
221 if ((d > destname) && (*(d-1) == '/')) {
226 /* Are we at the start ? Can't go back further if so. */
228 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
231 /* Go back one level... */
232 /* We know this is safe as '/' cannot be part of a mb sequence. */
233 /* NOTE - if this assumption is invalid we are not in good shape... */
234 /* Decrement d first as d points to the *next* char to write into. */
235 for (d--; d > destname; d--) {
239 s += 2; /* Else go past the .. */
240 /* We're still at the start of a name component, just the previous one. */
242 if (num_bad_components) {
243 /* Hmmm. Should we only decrement the bad_components if
244 we're removing a bad component ? Need to check this. JRA. */
245 num_bad_components--;
250 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
251 /* Component of pathname can't be "." only. */
252 ret = NT_STATUS_OBJECT_NAME_INVALID;
253 num_bad_components++;
261 return NT_STATUS_OBJECT_NAME_INVALID;
263 if (!*p_contains_wcard) {
270 *p_contains_wcard = True;
279 /* Get the size of the next MB character. */
280 next_codepoint(s,&siz);
298 DEBUG(0,("check_path_syntax_wcard: character length assumptions invalid !\n"));
300 return NT_STATUS_INVALID_PARAMETER;
303 if (start_of_name_component && num_bad_components) {
304 num_bad_components++;
306 start_of_name_component = False;
309 if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
310 /* For some strange reason being called from findfirst changes
311 the num_components number to cause the error return to change. JRA. */
312 if (num_bad_components > 2) {
313 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
321 /****************************************************************************
322 Check the path for a POSIX client.
323 We're assuming here that '/' is not the second byte in any multibyte char
324 set (a safe assumption).
325 ****************************************************************************/
327 NTSTATUS check_path_syntax_posix(pstring destname, const pstring srcname)
330 const char *s = srcname;
331 NTSTATUS ret = NT_STATUS_OK;
332 BOOL start_of_name_component = True;
337 * Safe to assume is not the second part of a mb char as this is handled below.
339 /* Eat multiple '/' or '\\' */
343 if ((d != destname) && (*s != '\0')) {
344 /* We only care about non-leading or trailing '/' */
348 start_of_name_component = True;
352 if (start_of_name_component) {
353 if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
354 /* Uh oh - "/../" or "/..\0" ! */
357 * No mb char starts with '.' so we're safe checking the directory separator here.
360 /* If we just added a '/' - delete it */
361 if ((d > destname) && (*(d-1) == '/')) {
366 /* Are we at the start ? Can't go back further if so. */
368 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
371 /* Go back one level... */
372 /* We know this is safe as '/' cannot be part of a mb sequence. */
373 /* NOTE - if this assumption is invalid we are not in good shape... */
374 /* Decrement d first as d points to the *next* char to write into. */
375 for (d--; d > destname; d--) {
379 s += 2; /* Else go past the .. */
382 } else if ((s[0] == '.') && ((s[1] == '\0') || (s[1] == '/'))) {
393 /* Get the size of the next MB character. */
394 next_codepoint(s,&siz);
412 DEBUG(0,("check_path_syntax_posix: character length assumptions invalid !\n"));
414 return NT_STATUS_INVALID_PARAMETER;
417 start_of_name_component = False;
424 /****************************************************************************
425 Pull a string and check the path allowing a wilcard - provide for error return.
426 ****************************************************************************/
428 size_t srvstr_get_path_wcard(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags,
429 NTSTATUS *err, BOOL *contains_wcard)
432 char *tmppath_ptr = tmppath;
435 SMB_ASSERT(dest_len == sizeof(pstring));
439 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
441 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
444 *contains_wcard = False;
446 if (lp_posix_pathnames()) {
447 *err = check_path_syntax_posix(dest, tmppath);
449 *err = check_path_syntax_wcard(dest, tmppath, contains_wcard);
455 /****************************************************************************
456 Pull a string and check the path - provide for error return.
457 ****************************************************************************/
459 size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err)
462 char *tmppath_ptr = tmppath;
465 SMB_ASSERT(dest_len == sizeof(pstring));
469 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
471 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
473 if (lp_posix_pathnames()) {
474 *err = check_path_syntax_posix(dest, tmppath);
476 *err = check_path_syntax(dest, tmppath);
482 /****************************************************************************
483 Reply to a special message.
484 ****************************************************************************/
486 int reply_special(char *inbuf,char *outbuf)
489 int msg_type = CVAL(inbuf,0);
490 int msg_flags = CVAL(inbuf,1);
494 static BOOL already_got_session = False;
498 memset(outbuf,'\0',smb_size);
500 smb_setlen(outbuf,0);
503 case 0x81: /* session request */
505 if (already_got_session) {
506 exit_server_cleanly("multiple session request not permitted");
509 SCVAL(outbuf,0,0x82);
511 if (name_len(inbuf+4) > 50 ||
512 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
513 DEBUG(0,("Invalid name length in session request\n"));
516 name_extract(inbuf,4,name1);
517 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
518 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
521 set_local_machine_name(name1, True);
522 set_remote_machine_name(name2, True);
524 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
525 get_local_machine_name(), get_remote_machine_name(),
528 if (name_type == 'R') {
529 /* We are being asked for a pathworks session ---
531 SCVAL(outbuf, 0,0x83);
535 /* only add the client's machine name to the list
536 of possibly valid usernames if we are operating
537 in share mode security */
538 if (lp_security() == SEC_SHARE) {
539 add_session_user(get_remote_machine_name());
542 reload_services(True);
545 already_got_session = True;
548 case 0x89: /* session keepalive request
549 (some old clients produce this?) */
550 SCVAL(outbuf,0,SMBkeepalive);
554 case 0x82: /* positive session response */
555 case 0x83: /* negative session response */
556 case 0x84: /* retarget session response */
557 DEBUG(0,("Unexpected session response\n"));
560 case SMBkeepalive: /* session keepalive */
565 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
566 msg_type, msg_flags));
571 /****************************************************************************
573 conn POINTER CAN BE NULL HERE !
574 ****************************************************************************/
576 int reply_tcon(connection_struct *conn,
577 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
584 uint16 vuid = SVAL(inbuf,smb_uid);
588 DATA_BLOB password_blob;
590 START_PROFILE(SMBtcon);
592 *service_buf = *password = *dev = 0;
594 p = smb_buf(inbuf)+1;
595 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
596 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
598 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
600 p = strrchr_m(service_buf,'\\');
604 service = service_buf;
607 password_blob = data_blob(password, pwlen+1);
609 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
611 data_blob_clear_free(&password_blob);
614 END_PROFILE(SMBtcon);
615 return ERROR_NT(nt_status);
618 outsize = set_message(outbuf,2,0,True);
619 SSVAL(outbuf,smb_vwv0,max_recv);
620 SSVAL(outbuf,smb_vwv1,conn->cnum);
621 SSVAL(outbuf,smb_tid,conn->cnum);
623 DEBUG(3,("tcon service=%s cnum=%d\n",
624 service, conn->cnum));
626 END_PROFILE(SMBtcon);
630 /****************************************************************************
631 Reply to a tcon and X.
632 conn POINTER CAN BE NULL HERE !
633 ****************************************************************************/
635 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
640 /* what the cleint thinks the device is */
641 fstring client_devicetype;
642 /* what the server tells the client the share represents */
643 const char *server_devicetype;
645 uint16 vuid = SVAL(inbuf,smb_uid);
646 int passlen = SVAL(inbuf,smb_vwv3);
650 START_PROFILE(SMBtconX);
652 *service = *client_devicetype = 0;
654 /* we might have to close an old one */
655 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
656 close_cnum(conn,vuid);
659 if (passlen > MAX_PASS_LEN) {
660 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
663 if (global_encrypted_passwords_negotiated) {
664 password = data_blob(smb_buf(inbuf),passlen);
666 password = data_blob(smb_buf(inbuf),passlen+1);
667 /* Ensure correct termination */
668 password.data[passlen]=0;
671 p = smb_buf(inbuf) + passlen;
672 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
675 * the service name can be either: \\server\share
676 * or share directly like on the DELL PowerVault 705
679 q = strchr_m(path+2,'\\');
681 END_PROFILE(SMBtconX);
682 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
684 fstrcpy(service,q+1);
687 fstrcpy(service,path);
689 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
691 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
693 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
695 data_blob_clear_free(&password);
698 END_PROFILE(SMBtconX);
699 return ERROR_NT(nt_status);
703 server_devicetype = "IPC";
704 else if ( IS_PRINT(conn) )
705 server_devicetype = "LPT1:";
707 server_devicetype = "A:";
709 if (Protocol < PROTOCOL_NT1) {
710 set_message(outbuf,2,0,True);
712 p += srvstr_push(outbuf, p, server_devicetype, -1,
713 STR_TERMINATE|STR_ASCII);
714 set_message_end(outbuf,p);
716 /* NT sets the fstype of IPC$ to the null string */
717 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
719 set_message(outbuf,3,0,True);
722 p += srvstr_push(outbuf, p, server_devicetype, -1,
723 STR_TERMINATE|STR_ASCII);
724 p += srvstr_push(outbuf, p, fstype, -1,
727 set_message_end(outbuf,p);
729 /* what does setting this bit do? It is set by NT4 and
730 may affect the ability to autorun mounted cdroms */
731 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
732 (lp_csc_policy(SNUM(conn)) << 2));
734 init_dfsroot(conn, inbuf, outbuf);
738 DEBUG(3,("tconX service=%s \n",
741 /* set the incoming and outgoing tid to the just created one */
742 SSVAL(inbuf,smb_tid,conn->cnum);
743 SSVAL(outbuf,smb_tid,conn->cnum);
745 END_PROFILE(SMBtconX);
746 return chain_reply(inbuf,outbuf,length,bufsize);
749 /****************************************************************************
750 Reply to an unknown type.
751 ****************************************************************************/
753 int reply_unknown(char *inbuf,char *outbuf)
756 type = CVAL(inbuf,smb_com);
758 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
759 smb_fn_name(type), type, type));
761 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
764 /****************************************************************************
766 conn POINTER CAN BE NULL HERE !
767 ****************************************************************************/
769 int reply_ioctl(connection_struct *conn,
770 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
772 uint16 device = SVAL(inbuf,smb_vwv1);
773 uint16 function = SVAL(inbuf,smb_vwv2);
774 uint32 ioctl_code = (device << 16) + function;
775 int replysize, outsize;
777 START_PROFILE(SMBioctl);
779 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
781 switch (ioctl_code) {
782 case IOCTL_QUERY_JOB_INFO:
786 END_PROFILE(SMBioctl);
787 return(ERROR_DOS(ERRSRV,ERRnosupport));
790 outsize = set_message(outbuf,8,replysize+1,True);
791 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
792 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
793 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
794 p = smb_buf(outbuf) + 1; /* Allow for alignment */
796 switch (ioctl_code) {
797 case IOCTL_QUERY_JOB_INFO:
799 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
801 END_PROFILE(SMBioctl);
802 return(UNIXERROR(ERRDOS,ERRbadfid));
804 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
805 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
807 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
813 END_PROFILE(SMBioctl);
817 /****************************************************************************
819 ****************************************************************************/
821 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
826 BOOL bad_path = False;
827 SMB_STRUCT_STAT sbuf;
830 START_PROFILE(SMBchkpth);
832 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
833 if (!NT_STATUS_IS_OK(status)) {
834 END_PROFILE(SMBchkpth);
836 /* Strange DOS error code semantics only for chkpth... */
837 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
838 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
839 /* We need to map to ERRbadpath */
840 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
843 return ERROR_NT(status);
846 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
848 unix_convert(name,conn,0,&bad_path,&sbuf);
850 END_PROFILE(SMBchkpth);
851 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
854 if (check_name(name,conn)) {
855 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
856 if (!(ok = S_ISDIR(sbuf.st_mode))) {
857 END_PROFILE(SMBchkpth);
858 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
863 /* We special case this - as when a Windows machine
864 is parsing a path is steps through the components
865 one at a time - if a component fails it expects
866 ERRbadpath, not ERRbadfile.
868 if(errno == ENOENT) {
870 * Windows returns different error codes if
871 * the parent directory is valid but not the
872 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
873 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
874 * if the path is invalid. This is different from set_bad_path_error()
875 * in the non-NT error case.
877 END_PROFILE(SMBchkpth);
878 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpath);
881 END_PROFILE(SMBchkpth);
882 return(UNIXERROR(ERRDOS,ERRbadpath));
885 outsize = set_message(outbuf,0,0,False);
886 DEBUG(3,("chkpth %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0)));
888 END_PROFILE(SMBchkpth);
892 /****************************************************************************
894 ****************************************************************************/
896 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
900 SMB_STRUCT_STAT sbuf;
905 BOOL bad_path = False;
909 START_PROFILE(SMBgetatr);
911 p = smb_buf(inbuf) + 1;
912 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
913 if (!NT_STATUS_IS_OK(status)) {
914 END_PROFILE(SMBgetatr);
915 return ERROR_NT(status);
918 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
920 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
921 under WfWg - weird! */
923 mode = aHIDDEN | aDIR;
924 if (!CAN_WRITE(conn))
930 unix_convert(fname,conn,0,&bad_path,&sbuf);
932 END_PROFILE(SMBgetatr);
933 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
935 if (check_name(fname,conn)) {
936 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
937 mode = dos_mode(conn,fname,&sbuf);
939 mtime = sbuf.st_mtime;
944 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
950 END_PROFILE(SMBgetatr);
951 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
954 outsize = set_message(outbuf,10,0,True);
956 SSVAL(outbuf,smb_vwv0,mode);
957 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
958 srv_put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
960 srv_put_dos_date3(outbuf,smb_vwv1,mtime);
962 SIVAL(outbuf,smb_vwv3,(uint32)size);
964 if (Protocol >= PROTOCOL_NT1) {
965 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
968 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
970 END_PROFILE(SMBgetatr);
974 /****************************************************************************
976 ****************************************************************************/
978 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
985 SMB_STRUCT_STAT sbuf;
986 BOOL bad_path = False;
990 START_PROFILE(SMBsetatr);
992 p = smb_buf(inbuf) + 1;
993 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
994 if (!NT_STATUS_IS_OK(status)) {
995 END_PROFILE(SMBsetatr);
996 return ERROR_NT(status);
999 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1001 unix_convert(fname,conn,0,&bad_path,&sbuf);
1003 END_PROFILE(SMBsetatr);
1004 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1007 mode = SVAL(inbuf,smb_vwv0);
1008 mtime = srv_make_unix_date3(inbuf+smb_vwv1);
1010 if (mode != FILE_ATTRIBUTE_NORMAL) {
1011 if (VALID_STAT_OF_DIR(sbuf))
1016 if (check_name(fname,conn)) {
1017 ok = (file_set_dosmode(conn,fname,mode,&sbuf,False) == 0);
1024 ok = set_filetime(conn,fname,mtime);
1027 END_PROFILE(SMBsetatr);
1028 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1031 outsize = set_message(outbuf,0,0,False);
1033 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1035 END_PROFILE(SMBsetatr);
1039 /****************************************************************************
1041 ****************************************************************************/
1043 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1046 SMB_BIG_UINT dfree,dsize,bsize;
1047 START_PROFILE(SMBdskattr);
1049 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
1050 END_PROFILE(SMBdskattr);
1051 return(UNIXERROR(ERRHRD,ERRgeneral));
1054 outsize = set_message(outbuf,5,0,True);
1056 if (Protocol <= PROTOCOL_LANMAN2) {
1057 double total_space, free_space;
1058 /* we need to scale this to a number that DOS6 can handle. We
1059 use floating point so we can handle large drives on systems
1060 that don't have 64 bit integers
1062 we end up displaying a maximum of 2G to DOS systems
1064 total_space = dsize * (double)bsize;
1065 free_space = dfree * (double)bsize;
1067 dsize = (total_space+63*512) / (64*512);
1068 dfree = (free_space+63*512) / (64*512);
1070 if (dsize > 0xFFFF) dsize = 0xFFFF;
1071 if (dfree > 0xFFFF) dfree = 0xFFFF;
1073 SSVAL(outbuf,smb_vwv0,dsize);
1074 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1075 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
1076 SSVAL(outbuf,smb_vwv3,dfree);
1078 SSVAL(outbuf,smb_vwv0,dsize);
1079 SSVAL(outbuf,smb_vwv1,bsize/512);
1080 SSVAL(outbuf,smb_vwv2,512);
1081 SSVAL(outbuf,smb_vwv3,dfree);
1084 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1086 END_PROFILE(SMBdskattr);
1090 /****************************************************************************
1092 Can be called from SMBsearch, SMBffirst or SMBfunique.
1093 ****************************************************************************/
1095 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1105 unsigned int numentries = 0;
1106 unsigned int maxentries = 0;
1107 BOOL finished = False;
1114 BOOL check_descend = False;
1115 BOOL expect_close = False;
1116 BOOL can_open = True;
1117 BOOL bad_path = False;
1119 BOOL mask_contains_wcard = False;
1120 BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1122 START_PROFILE(SMBsearch);
1124 if (lp_posix_pathnames()) {
1125 END_PROFILE(SMBsearch);
1126 return reply_unknown(inbuf, outbuf);
1129 *mask = *directory = *fname = 0;
1131 /* If we were called as SMBffirst then we must expect close. */
1132 if(CVAL(inbuf,smb_com) == SMBffirst)
1133 expect_close = True;
1135 outsize = set_message(outbuf,1,3,True);
1136 maxentries = SVAL(inbuf,smb_vwv0);
1137 dirtype = SVAL(inbuf,smb_vwv1);
1138 p = smb_buf(inbuf) + 1;
1139 p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status, &mask_contains_wcard);
1140 if (!NT_STATUS_IS_OK(nt_status)) {
1141 END_PROFILE(SMBsearch);
1142 return ERROR_NT(nt_status);
1145 RESOLVE_DFSPATH_WCARD(path, conn, inbuf, outbuf);
1148 status_len = SVAL(p, 0);
1151 /* dirtype &= ~aDIR; */
1153 if (status_len == 0) {
1154 SMB_STRUCT_STAT sbuf;
1157 pstrcpy(directory,path);
1159 unix_convert(directory,conn,0,&bad_path,&sbuf);
1162 if (!check_name(directory,conn))
1165 p = strrchr_m(dir2,'/');
1174 p = strrchr_m(directory,'/');
1180 if (strlen(directory) == 0)
1181 pstrcpy(directory,".");
1182 memset((char *)status,'\0',21);
1183 SCVAL(status,0,(dirtype & 0x1F));
1187 memcpy(status,p,21);
1188 status_dirtype = CVAL(status,0) & 0x1F;
1189 if (status_dirtype != (dirtype & 0x1F))
1190 dirtype = status_dirtype;
1192 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1195 string_set(&conn->dirpath,dptr_path(dptr_num));
1196 pstrcpy(mask, dptr_wcard(dptr_num));
1200 p = smb_buf(outbuf) + 3;
1203 if (status_len == 0) {
1204 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid), mask, mask_contains_wcard, dirtype);
1206 if(dptr_num == -2) {
1207 END_PROFILE(SMBsearch);
1208 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
1210 END_PROFILE(SMBsearch);
1211 return ERROR_DOS(ERRDOS,ERRnofids);
1214 dirtype = dptr_attr(dptr_num);
1217 DEBUG(4,("dptr_num is %d\n",dptr_num));
1220 if ((dirtype&0x1F) == aVOLID) {
1221 memcpy(p,status,21);
1222 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),
1223 0,aVOLID,0,!allow_long_path_components);
1224 dptr_fill(p+12,dptr_num);
1225 if (dptr_zero(p+12) && (status_len==0))
1229 p += DIR_STRUCT_SIZE;
1232 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
1234 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1235 conn->dirpath,lp_dontdescend(SNUM(conn))));
1236 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
1237 check_descend = True;
1239 for (i=numentries;(i<maxentries) && !finished;i++) {
1240 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
1242 memcpy(p,status,21);
1243 make_dir_struct(p,mask,fname,size, mode,date,
1244 !allow_long_path_components);
1245 if (!dptr_fill(p+12,dptr_num)) {
1249 p += DIR_STRUCT_SIZE;
1259 /* If we were called as SMBffirst with smb_search_id == NULL
1260 and no entries were found then return error and close dirptr
1263 if (numentries == 0 || !ok) {
1264 dptr_close(&dptr_num);
1265 } else if(ok && expect_close && status_len == 0) {
1266 /* Close the dptr - we know it's gone */
1267 dptr_close(&dptr_num);
1270 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1271 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique) {
1272 dptr_close(&dptr_num);
1275 if ((numentries == 0) && !mask_contains_wcard) {
1276 return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles);
1279 SSVAL(outbuf,smb_vwv0,numentries);
1280 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1281 SCVAL(smb_buf(outbuf),0,5);
1282 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
1284 /* The replies here are never long name. */
1285 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1286 if (!allow_long_path_components) {
1287 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_LONG_PATH_COMPONENTS));
1290 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1291 SSVAL(outbuf,smb_flg2, (SVAL(outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1293 outsize += DIR_STRUCT_SIZE*numentries;
1294 smb_setlen(outbuf,outsize - 4);
1296 if ((! *directory) && dptr_path(dptr_num))
1297 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1299 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1300 smb_fn_name(CVAL(inbuf,smb_com)),
1301 mask, directory, dirtype, numentries, maxentries ) );
1303 END_PROFILE(SMBsearch);
1307 /****************************************************************************
1308 Reply to a fclose (stop directory search).
1309 ****************************************************************************/
1311 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1320 BOOL path_contains_wcard = False;
1322 START_PROFILE(SMBfclose);
1324 if (lp_posix_pathnames()) {
1325 END_PROFILE(SMBfclose);
1326 return reply_unknown(inbuf, outbuf);
1329 outsize = set_message(outbuf,1,0,True);
1330 p = smb_buf(inbuf) + 1;
1331 p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, &path_contains_wcard);
1332 if (!NT_STATUS_IS_OK(err)) {
1333 END_PROFILE(SMBfclose);
1334 return ERROR_NT(err);
1337 status_len = SVAL(p,0);
1340 if (status_len == 0) {
1341 END_PROFILE(SMBfclose);
1342 return ERROR_DOS(ERRSRV,ERRsrverror);
1345 memcpy(status,p,21);
1347 if(dptr_fetch(status+12,&dptr_num)) {
1348 /* Close the dptr - we know it's gone */
1349 dptr_close(&dptr_num);
1352 SSVAL(outbuf,smb_vwv0,0);
1354 DEBUG(3,("search close\n"));
1356 END_PROFILE(SMBfclose);
1360 /****************************************************************************
1362 ****************************************************************************/
1364 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1372 SMB_STRUCT_STAT sbuf;
1373 BOOL bad_path = False;
1375 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1377 uint32 dos_attr = SVAL(inbuf,smb_vwv1);
1380 uint32 create_disposition;
1381 uint32 create_options = 0;
1383 START_PROFILE(SMBopen);
1385 deny_mode = SVAL(inbuf,smb_vwv0);
1387 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
1388 if (!NT_STATUS_IS_OK(status)) {
1389 END_PROFILE(SMBopen);
1390 return ERROR_NT(status);
1393 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1395 unix_convert(fname,conn,0,&bad_path,&sbuf);
1397 END_PROFILE(SMBopen);
1398 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1401 if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
1402 &access_mask, &share_mode, &create_disposition, &create_options)) {
1403 END_PROFILE(SMBopen);
1404 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1407 status = open_file_ntcreate(conn,fname,&sbuf,
1416 if (!NT_STATUS_IS_OK(status)) {
1417 END_PROFILE(SMBopen);
1418 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1419 /* We have re-scheduled this call. */
1422 return ERROR_NT(status);
1425 size = sbuf.st_size;
1426 fattr = dos_mode(conn,fname,&sbuf);
1427 mtime = sbuf.st_mtime;
1430 DEBUG(3,("attempt to open a directory %s\n",fname));
1431 close_file(fsp,ERROR_CLOSE);
1432 END_PROFILE(SMBopen);
1433 return ERROR_DOS(ERRDOS,ERRnoaccess);
1436 outsize = set_message(outbuf,7,0,True);
1437 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1438 SSVAL(outbuf,smb_vwv1,fattr);
1439 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1440 srv_put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1442 srv_put_dos_date3(outbuf,smb_vwv2,mtime);
1444 SIVAL(outbuf,smb_vwv4,(uint32)size);
1445 SSVAL(outbuf,smb_vwv6,deny_mode);
1447 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1448 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1451 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1452 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1454 END_PROFILE(SMBopen);
1458 /****************************************************************************
1459 Reply to an open and X.
1460 ****************************************************************************/
1462 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1465 uint16 open_flags = SVAL(inbuf,smb_vwv2);
1466 int deny_mode = SVAL(inbuf,smb_vwv3);
1467 uint32 smb_attr = SVAL(inbuf,smb_vwv5);
1468 /* Breakout the oplock request bits so we can set the
1469 reply bits separately. */
1470 int ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1471 int core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1472 int oplock_request = ex_oplock_request | core_oplock_request;
1474 int smb_sattr = SVAL(inbuf,smb_vwv4);
1475 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1477 int smb_ofun = SVAL(inbuf,smb_vwv8);
1481 SMB_STRUCT_STAT sbuf;
1483 BOOL bad_path = False;
1486 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
1487 ssize_t retval = -1;
1490 uint32 create_disposition;
1491 uint32 create_options = 0;
1493 START_PROFILE(SMBopenX);
1495 /* If it's an IPC, pass off the pipe handler. */
1497 if (lp_nt_pipe_support()) {
1498 END_PROFILE(SMBopenX);
1499 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1501 END_PROFILE(SMBopenX);
1502 return ERROR_DOS(ERRSRV,ERRaccess);
1506 /* XXXX we need to handle passed times, sattr and flags */
1507 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
1508 if (!NT_STATUS_IS_OK(status)) {
1509 END_PROFILE(SMBopenX);
1510 return ERROR_NT(status);
1513 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1515 unix_convert(fname,conn,0,&bad_path,&sbuf);
1517 END_PROFILE(SMBopenX);
1518 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1521 if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
1524 &create_disposition,
1526 END_PROFILE(SMBopenX);
1527 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1530 status = open_file_ntcreate(conn,fname,&sbuf,
1539 if (!NT_STATUS_IS_OK(status)) {
1540 END_PROFILE(SMBopenX);
1541 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1542 /* We have re-scheduled this call. */
1545 return ERROR_NT(status);
1548 size = sbuf.st_size;
1550 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1551 if the file is truncated or created. */
1552 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1553 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1554 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1555 close_file(fsp,ERROR_CLOSE);
1556 END_PROFILE(SMBopenX);
1557 return ERROR_NT(NT_STATUS_DISK_FULL);
1559 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1561 close_file(fsp,ERROR_CLOSE);
1562 END_PROFILE(SMBopenX);
1563 return ERROR_NT(NT_STATUS_DISK_FULL);
1565 size = get_allocation_size(conn,fsp,&sbuf);
1568 fattr = dos_mode(conn,fname,&sbuf);
1569 mtime = sbuf.st_mtime;
1571 close_file(fsp,ERROR_CLOSE);
1572 END_PROFILE(SMBopenX);
1573 return ERROR_DOS(ERRDOS,ERRnoaccess);
1576 /* If the caller set the extended oplock request bit
1577 and we granted one (by whatever means) - set the
1578 correct bit for extended oplock reply.
1581 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1582 smb_action |= EXTENDED_OPLOCK_GRANTED;
1585 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1586 smb_action |= EXTENDED_OPLOCK_GRANTED;
1589 /* If the caller set the core oplock request bit
1590 and we granted one (by whatever means) - set the
1591 correct bit for core oplock reply.
1594 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1595 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1598 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1599 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1602 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1603 set_message(outbuf,19,0,True);
1605 set_message(outbuf,15,0,True);
1607 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1608 SSVAL(outbuf,smb_vwv3,fattr);
1609 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1610 srv_put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1612 srv_put_dos_date3(outbuf,smb_vwv4,mtime);
1614 SIVAL(outbuf,smb_vwv6,(uint32)size);
1615 SSVAL(outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1616 SSVAL(outbuf,smb_vwv11,smb_action);
1618 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1619 SIVAL(outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1622 END_PROFILE(SMBopenX);
1623 return chain_reply(inbuf,outbuf,length,bufsize);
1626 /****************************************************************************
1627 Reply to a SMBulogoffX.
1628 conn POINTER CAN BE NULL HERE !
1629 ****************************************************************************/
1631 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1633 uint16 vuid = SVAL(inbuf,smb_uid);
1634 user_struct *vuser = get_valid_user_struct(vuid);
1635 START_PROFILE(SMBulogoffX);
1638 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1640 /* in user level security we are supposed to close any files
1641 open by this user */
1642 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1643 file_close_user(vuid);
1645 invalidate_vuid(vuid);
1647 set_message(outbuf,2,0,True);
1649 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1651 END_PROFILE(SMBulogoffX);
1652 return chain_reply(inbuf,outbuf,length,bufsize);
1655 /****************************************************************************
1656 Reply to a mknew or a create.
1657 ****************************************************************************/
1659 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1664 uint32 fattr = SVAL(inbuf,smb_vwv0);
1665 BOOL bad_path = False;
1667 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1668 SMB_STRUCT_STAT sbuf;
1670 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1671 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1672 uint32 create_disposition;
1673 uint32 create_options = 0;
1675 START_PROFILE(SMBcreate);
1677 com = SVAL(inbuf,smb_com);
1679 srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status);
1680 if (!NT_STATUS_IS_OK(status)) {
1681 END_PROFILE(SMBcreate);
1682 return ERROR_NT(status);
1685 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1687 unix_convert(fname,conn,0,&bad_path,&sbuf);
1689 END_PROFILE(SMBcreate);
1690 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1693 if (fattr & aVOLID) {
1694 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1697 if(com == SMBmknew) {
1698 /* We should fail if file exists. */
1699 create_disposition = FILE_CREATE;
1701 /* Create if file doesn't exist, truncate if it does. */
1702 create_disposition = FILE_OVERWRITE_IF;
1705 /* Open file using ntcreate. */
1706 status = open_file_ntcreate(conn,fname,&sbuf,
1715 if (!NT_STATUS_IS_OK(status)) {
1716 END_PROFILE(SMBcreate);
1717 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1718 /* We have re-scheduled this call. */
1721 return ERROR_NT(status);
1724 outsize = set_message(outbuf,1,0,True);
1725 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1727 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1728 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1731 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1732 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1735 DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
1736 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) );
1738 END_PROFILE(SMBcreate);
1742 /****************************************************************************
1743 Reply to a create temporary file.
1744 ****************************************************************************/
1746 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1750 uint32 fattr = SVAL(inbuf,smb_vwv0);
1751 BOOL bad_path = False;
1753 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1755 SMB_STRUCT_STAT sbuf;
1758 unsigned int namelen;
1760 START_PROFILE(SMBctemp);
1762 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 END_PROFILE(SMBctemp);
1765 return ERROR_NT(status);
1768 pstrcat(fname,"/TMXXXXXX");
1770 pstrcat(fname,"TMXXXXXX");
1773 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1775 unix_convert(fname,conn,0,&bad_path,&sbuf);
1777 END_PROFILE(SMBctemp);
1778 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1781 tmpfd = smb_mkstemp(fname);
1783 END_PROFILE(SMBctemp);
1784 return(UNIXERROR(ERRDOS,ERRnoaccess));
1787 SMB_VFS_STAT(conn,fname,&sbuf);
1789 /* We should fail if file does not exist. */
1790 status = open_file_ntcreate(conn,fname,&sbuf,
1791 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
1792 FILE_SHARE_READ|FILE_SHARE_WRITE,
1799 /* close fd from smb_mkstemp() */
1802 if (!NT_STATUS_IS_OK(status)) {
1803 END_PROFILE(SMBctemp);
1804 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1805 /* We have re-scheduled this call. */
1808 return ERROR_NT(status);
1811 outsize = set_message(outbuf,1,0,True);
1812 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1814 /* the returned filename is relative to the directory */
1815 s = strrchr_m(fname, '/');
1822 p = smb_buf(outbuf);
1824 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
1825 thing in the byte section. JRA */
1826 SSVALS(p, 0, -1); /* what is this? not in spec */
1828 namelen = srvstr_push(outbuf, p, s, -1, STR_ASCII|STR_TERMINATE);
1830 outsize = set_message_end(outbuf, p);
1832 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1833 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1836 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1837 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1840 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
1841 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
1842 (unsigned int)sbuf.st_mode ) );
1844 END_PROFILE(SMBctemp);
1848 /*******************************************************************
1849 Check if a user is allowed to rename a file.
1850 ********************************************************************/
1852 static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, SMB_STRUCT_STAT *pst)
1858 if (!CAN_WRITE(conn)) {
1859 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1862 fmode = dos_mode(conn,fname,pst);
1863 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
1864 return NT_STATUS_NO_SUCH_FILE;
1867 if (S_ISDIR(pst->st_mode)) {
1868 return NT_STATUS_OK;
1871 status = open_file_ntcreate(conn, fname, pst,
1873 FILE_SHARE_READ|FILE_SHARE_WRITE,
1876 FILE_ATTRIBUTE_NORMAL,
1880 if (!NT_STATUS_IS_OK(status)) {
1883 close_file(fsp,NORMAL_CLOSE);
1884 return NT_STATUS_OK;
1887 /*******************************************************************
1888 Check if a user is allowed to delete a file.
1889 ********************************************************************/
1891 NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL bad_path, BOOL check_is_at_open)
1893 SMB_STRUCT_STAT sbuf;
1898 DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype ));
1900 if (!CAN_WRITE(conn)) {
1901 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1904 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
1905 if(errno == ENOENT) {
1907 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1909 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1912 return map_nt_error_from_unix(errno);
1915 fattr = dos_mode(conn,fname,&sbuf);
1917 /* Can't delete a directory. */
1919 return NT_STATUS_FILE_IS_A_DIRECTORY;
1923 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1924 return NT_STATUS_OBJECT_NAME_INVALID;
1925 #endif /* JRATEST */
1927 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
1929 On a Windows share, a file with read-only dosmode can be opened with
1930 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
1931 fails with NT_STATUS_CANNOT_DELETE error.
1933 This semantic causes a problem that a user can not
1934 rename a file with read-only dosmode on a Samba share
1935 from a Windows command prompt (i.e. cmd.exe, but can rename
1936 from Windows Explorer).
1939 if (!check_is_at_open && !lp_delete_readonly(SNUM(conn))) {
1940 if (fattr & aRONLY) {
1941 return NT_STATUS_CANNOT_DELETE;
1944 if ((fattr & ~dirtype) & (aHIDDEN | aSYSTEM)) {
1945 return NT_STATUS_NO_SUCH_FILE;
1948 if (check_is_at_open) {
1949 if (!can_delete_file_in_directory(conn, fname)) {
1950 return NT_STATUS_ACCESS_DENIED;
1953 /* On open checks the open itself will check the share mode, so
1954 don't do it here as we'll get it wrong. */
1956 status = open_file_ntcreate(conn, fname, &sbuf,
1961 FILE_ATTRIBUTE_NORMAL,
1965 if (!NT_STATUS_IS_OK(status)) {
1968 close_file(fsp,NORMAL_CLOSE);
1970 return NT_STATUS_OK;
1973 /****************************************************************************
1974 The guts of the unlink command, split out so it may be called by the NT SMB
1976 ****************************************************************************/
1978 NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
1979 char *name, BOOL has_wild)
1986 NTSTATUS error = NT_STATUS_OK;
1987 BOOL bad_path = False;
1989 SMB_STRUCT_STAT sbuf;
1991 *directory = *mask = 0;
1993 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1996 * Feel my pain, this code needs rewriting *very* badly! -- vl
1998 pstrcpy(orig_name, name);
2000 p = strrchr_m(name,'/');
2002 pstrcpy(directory,".");
2006 pstrcpy(directory,name);
2011 * We should only check the mangled cache
2012 * here if unix_convert failed. This means
2013 * that the path in 'mask' doesn't exist
2014 * on the file system and so we need to look
2015 * for a possible mangle. This patch from
2016 * Tine Smukavec <valentin.smukavec@hermes.si>.
2019 if (!rc && mangle_is_mangled(mask,conn->params))
2020 mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
2026 pstrcat(directory,"/");
2027 pstrcat(directory,mask);
2028 error = can_delete(conn,directory,dirtype,bad_path,False);
2029 if (!NT_STATUS_IS_OK(error))
2032 if (SMB_VFS_UNLINK(conn,directory) == 0) {
2036 if (parent_dirname_talloc(tmp_talloc_ctx(), orig_name,
2038 notify_action(conn, dir, fname,
2039 NOTIFY_ACTION_REMOVED);
2040 TALLOC_FREE(dir); /* not strictly necessary */
2044 struct smb_Dir *dir_hnd = NULL;
2047 if (strequal(mask,"????????.???"))
2050 if (check_name(directory,conn))
2051 dir_hnd = OpenDir(conn, directory, mask, dirtype);
2053 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2054 the pattern matches against the long name, otherwise the short name
2055 We don't implement this yet XXXX
2060 error = NT_STATUS_NO_SUCH_FILE;
2062 while ((dname = ReadDirName(dir_hnd, &offset))) {
2065 BOOL sys_direntry = False;
2066 pstrcpy(fname,dname);
2068 if (!is_visible_file(conn, directory, dname, &st, True)) {
2072 /* Quick check for "." and ".." */
2073 if (fname[0] == '.') {
2074 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
2075 if ((dirtype & FILE_ATTRIBUTE_DIRECTORY) && (dirtype & FILE_ATTRIBUTE_SYSTEM)) {
2076 sys_direntry = True;
2083 if(!mask_match(fname, mask, conn->case_sensitive))
2087 error = NT_STATUS_OBJECT_NAME_INVALID;
2088 DEBUG(3,("unlink_internals: system directory delete denied [%s] mask [%s]\n",
2093 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
2094 error = can_delete(conn,fname,dirtype,bad_path,False);
2095 if (!NT_STATUS_IS_OK(error)) {
2098 if (SMB_VFS_UNLINK(conn,fname) == 0)
2100 notify_action(conn, directory, dname, NOTIFY_ACTION_REMOVED);
2101 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
2107 if (count == 0 && NT_STATUS_IS_OK(error)) {
2108 error = map_nt_error_from_unix(errno);
2114 /****************************************************************************
2116 ****************************************************************************/
2118 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
2125 BOOL path_contains_wcard = False;
2127 START_PROFILE(SMBunlink);
2129 dirtype = SVAL(inbuf,smb_vwv0);
2131 srvstr_get_path_wcard(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard);
2132 if (!NT_STATUS_IS_OK(status)) {
2133 END_PROFILE(SMBunlink);
2134 return ERROR_NT(status);
2137 RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
2139 DEBUG(3,("reply_unlink : %s\n",name));
2141 status = unlink_internals(conn, dirtype, name, path_contains_wcard);
2142 if (!NT_STATUS_IS_OK(status)) {
2143 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
2144 /* We have re-scheduled this call. */
2147 return ERROR_NT(status);
2151 * Win2k needs a changenotify request response before it will
2152 * update after a rename..
2154 process_pending_change_notify_queue((time_t)0);
2156 outsize = set_message(outbuf,0,0,False);
2158 END_PROFILE(SMBunlink);
2162 /****************************************************************************
2164 ****************************************************************************/
2166 static void fail_readraw(void)
2169 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
2171 exit_server_cleanly(errstr);
2174 #if defined(WITH_SENDFILE)
2175 /****************************************************************************
2176 Fake (read/write) sendfile. Returns -1 on read or write fail.
2177 ****************************************************************************/
2179 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, int bufsize)
2183 /* Paranioa check... */
2184 if (nread > bufsize) {
2189 ret = read_file(fsp,buf,startpos,nread);
2195 /* If we had a short read, fill with zeros. */
2197 memset(buf, '\0', nread - ret);
2200 if (write_data(smbd_server_fd(),buf,nread) != nread) {
2204 return (ssize_t)nread;
2208 /****************************************************************************
2209 Use sendfile in readbraw.
2210 ****************************************************************************/
2212 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
2213 ssize_t mincount, char *outbuf, int out_buffsize)
2217 #if defined(WITH_SENDFILE)
2219 * We can only use sendfile on a non-chained packet
2220 * but we can use on a non-oplocked file. tridge proved this
2221 * on a train in Germany :-). JRA.
2222 * reply_readbraw has already checked the length.
2225 if ( (chain_size == 0) && (nread > 0) &&
2226 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2229 _smb_setlen(outbuf,nread);
2230 header.data = (uint8 *)outbuf;
2234 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) {
2235 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2236 if (errno == ENOSYS) {
2237 goto normal_readbraw;
2241 * Special hack for broken Linux with no working sendfile. If we
2242 * return EINTR we sent the header but not the rest of the data.
2243 * Fake this up by doing read/write calls.
2245 if (errno == EINTR) {
2246 /* Ensure we don't do this again. */
2247 set_use_sendfile(SNUM(conn), False);
2248 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2250 if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
2251 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2252 fsp->fsp_name, strerror(errno) ));
2253 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2258 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2259 fsp->fsp_name, strerror(errno) ));
2260 exit_server_cleanly("send_file_readbraw sendfile failed");
2270 ret = read_file(fsp,outbuf+4,startpos,nread);
2271 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2280 _smb_setlen(outbuf,ret);
2281 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2285 /****************************************************************************
2286 Reply to a readbraw (core+ protocol).
2287 ****************************************************************************/
2289 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
2291 ssize_t maxcount,mincount;
2294 char *header = outbuf;
2296 START_PROFILE(SMBreadbraw);
2298 if (srv_is_signing_active()) {
2299 exit_server_cleanly("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
2303 * Special check if an oplock break has been issued
2304 * and the readraw request croses on the wire, we must
2305 * return a zero length response here.
2308 fsp = file_fsp(inbuf,smb_vwv0);
2310 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
2312 * fsp could be NULL here so use the value from the packet. JRA.
2314 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
2315 _smb_setlen(header,0);
2316 if (write_data(smbd_server_fd(),header,4) != 4)
2318 END_PROFILE(SMBreadbraw);
2322 CHECK_FSP(fsp,conn);
2324 flush_write_cache(fsp, READRAW_FLUSH);
2326 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
2327 if(CVAL(inbuf,smb_wct) == 10) {
2329 * This is a large offset (64 bit) read.
2331 #ifdef LARGE_SMB_OFF_T
2333 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
2335 #else /* !LARGE_SMB_OFF_T */
2338 * Ensure we haven't been sent a >32 bit offset.
2341 if(IVAL(inbuf,smb_vwv8) != 0) {
2342 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
2343 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
2344 _smb_setlen(header,0);
2345 if (write_data(smbd_server_fd(),header,4) != 4)
2347 END_PROFILE(SMBreadbraw);
2351 #endif /* LARGE_SMB_OFF_T */
2354 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
2355 _smb_setlen(header,0);
2356 if (write_data(smbd_server_fd(),header,4) != 4)
2358 END_PROFILE(SMBreadbraw);
2362 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
2363 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
2365 /* ensure we don't overrun the packet size */
2366 maxcount = MIN(65535,maxcount);
2368 if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2372 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
2376 if (startpos >= size) {
2379 nread = MIN(maxcount,(size - startpos));
2383 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2384 if (nread < mincount)
2388 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos,
2389 (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) );
2391 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
2393 DEBUG(5,("readbraw finished\n"));
2394 END_PROFILE(SMBreadbraw);
2399 #define DBGC_CLASS DBGC_LOCKING
2401 /****************************************************************************
2402 Reply to a lockread (core+ protocol).
2403 ****************************************************************************/
2405 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
2413 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2414 struct byte_range_lock *br_lck = NULL;
2415 START_PROFILE(SMBlockread);
2417 CHECK_FSP(fsp,conn);
2418 if (!CHECK_READ(fsp,inbuf)) {
2419 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2422 release_level_2_oplocks_on_change(fsp);
2424 numtoread = SVAL(inbuf,smb_vwv1);
2425 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2427 outsize = set_message(outbuf,5,3,True);
2428 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2429 data = smb_buf(outbuf) + 3;
2432 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2433 * protocol request that predates the read/write lock concept.
2434 * Thus instead of asking for a read lock here we need to ask
2435 * for a write lock. JRA.
2436 * Note that the requested lock size is unaffected by max_recv.
2439 br_lck = do_lock(fsp,
2440 (uint32)SVAL(inbuf,smb_pid),
2441 (SMB_BIG_UINT)numtoread,
2442 (SMB_BIG_UINT)startpos,
2445 False, /* Non-blocking lock. */
2447 TALLOC_FREE(br_lck);
2449 if (NT_STATUS_V(status)) {
2450 END_PROFILE(SMBlockread);
2451 return ERROR_NT(status);
2455 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2458 if (numtoread > max_recv) {
2459 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2460 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2461 (unsigned int)numtoread, (unsigned int)max_recv ));
2462 numtoread = MIN(numtoread,max_recv);
2464 nread = read_file(fsp,data,startpos,numtoread);
2467 END_PROFILE(SMBlockread);
2468 return(UNIXERROR(ERRDOS,ERRnoaccess));
2472 SSVAL(outbuf,smb_vwv0,nread);
2473 SSVAL(outbuf,smb_vwv5,nread+3);
2474 SSVAL(smb_buf(outbuf),1,nread);
2476 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2477 fsp->fnum, (int)numtoread, (int)nread));
2479 END_PROFILE(SMBlockread);
2484 #define DBGC_CLASS DBGC_ALL
2486 /****************************************************************************
2488 ****************************************************************************/
2490 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2497 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2498 START_PROFILE(SMBread);
2500 CHECK_FSP(fsp,conn);
2501 if (!CHECK_READ(fsp,inbuf)) {
2502 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2505 numtoread = SVAL(inbuf,smb_vwv1);
2506 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2508 outsize = set_message(outbuf,5,3,True);
2509 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2511 * The requested read size cannot be greater than max_recv. JRA.
2513 if (numtoread > max_recv) {
2514 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
2515 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2516 (unsigned int)numtoread, (unsigned int)max_recv ));
2517 numtoread = MIN(numtoread,max_recv);
2520 data = smb_buf(outbuf) + 3;
2522 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2523 END_PROFILE(SMBread);
2524 return ERROR_DOS(ERRDOS,ERRlock);
2528 nread = read_file(fsp,data,startpos,numtoread);
2531 END_PROFILE(SMBread);
2532 return(UNIXERROR(ERRDOS,ERRnoaccess));
2536 SSVAL(outbuf,smb_vwv0,nread);
2537 SSVAL(outbuf,smb_vwv5,nread+3);
2538 SCVAL(smb_buf(outbuf),0,1);
2539 SSVAL(smb_buf(outbuf),1,nread);
2541 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2542 fsp->fnum, (int)numtoread, (int)nread ) );
2544 END_PROFILE(SMBread);
2548 /****************************************************************************
2549 Reply to a read and X - possibly using sendfile.
2550 ****************************************************************************/
2552 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
2553 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
2557 char *data = smb_buf(outbuf);
2559 #if defined(WITH_SENDFILE)
2561 * We can only use sendfile on a non-chained packet
2562 * but we can use on a non-oplocked file. tridge proved this
2563 * on a train in Germany :-). JRA.
2566 if ((chain_size == 0) && (CVAL(inbuf,smb_vwv0) == 0xFF) &&
2567 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
2568 SMB_STRUCT_STAT sbuf;
2571 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1)
2572 return(UNIXERROR(ERRDOS,ERRnoaccess));
2574 if (startpos > sbuf.st_size)
2577 if (smb_maxcnt > (sbuf.st_size - startpos))
2578 smb_maxcnt = (sbuf.st_size - startpos);
2580 if (smb_maxcnt == 0)
2584 * Set up the packet header before send. We
2585 * assume here the sendfile will work (get the
2586 * correct amount of data).
2589 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2590 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
2591 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2592 SSVAL(outbuf,smb_vwv7,((smb_maxcnt >> 16) & 1));
2593 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
2594 SCVAL(outbuf,smb_vwv0,0xFF);
2595 set_message(outbuf,12,smb_maxcnt,False);
2596 header.data = (uint8 *)outbuf;
2597 header.length = data - outbuf;
2600 if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
2601 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2602 if (errno == ENOSYS) {
2607 * Special hack for broken Linux with no working sendfile. If we
2608 * return EINTR we sent the header but not the rest of the data.
2609 * Fake this up by doing read/write calls.
2612 if (errno == EINTR) {
2613 /* Ensure we don't do this again. */
2614 set_use_sendfile(SNUM(conn), False);
2615 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
2617 if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
2618 len_outbuf - (data-outbuf))) == -1) {
2619 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2620 fsp->fsp_name, strerror(errno) ));
2621 exit_server_cleanly("send_file_readX: fake_sendfile failed");
2623 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
2624 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2625 /* Returning -1 here means successful sendfile. */
2629 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2630 fsp->fsp_name, strerror(errno) ));
2631 exit_server_cleanly("send_file_readX sendfile failed");
2634 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2635 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2636 /* Returning -1 here means successful sendfile. */
2644 nread = read_file(fsp,data,startpos,smb_maxcnt);
2647 return(UNIXERROR(ERRDOS,ERRnoaccess));
2650 outsize = set_message(outbuf,12,nread,False);
2651 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2652 SSVAL(outbuf,smb_vwv5,nread);
2653 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2654 SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
2655 SSVAL(smb_buf(outbuf),-2,nread);
2657 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2658 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2660 /* Returning the number of bytes we want to send back - including header. */
2664 /****************************************************************************
2665 Reply to a read and X.
2666 ****************************************************************************/
2668 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2670 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2671 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2673 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2675 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2678 START_PROFILE(SMBreadX);
2680 /* If it's an IPC, pass off the pipe handler. */
2682 END_PROFILE(SMBreadX);
2683 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2686 CHECK_FSP(fsp,conn);
2687 if (!CHECK_READ(fsp,inbuf)) {
2688 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2691 set_message(outbuf,12,0,True);
2693 if (global_client_caps & CAP_LARGE_READX) {
2694 if (SVAL(inbuf,smb_vwv7) == 1) {
2695 smb_maxcnt |= (1<<16);
2697 if (smb_maxcnt > BUFFER_SIZE) {
2698 DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n",
2699 (unsigned int)smb_maxcnt, (unsigned int)BUFFER_SIZE));
2700 END_PROFILE(SMBreadX);
2701 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2705 if(CVAL(inbuf,smb_wct) == 12) {
2706 #ifdef LARGE_SMB_OFF_T
2708 * This is a large offset (64 bit) read.
2710 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2712 #else /* !LARGE_SMB_OFF_T */
2715 * Ensure we haven't been sent a >32 bit offset.
2718 if(IVAL(inbuf,smb_vwv10) != 0) {
2719 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2720 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2721 END_PROFILE(SMBreadX);
2722 return ERROR_DOS(ERRDOS,ERRbadaccess);
2725 #endif /* LARGE_SMB_OFF_T */
2729 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2730 END_PROFILE(SMBreadX);
2731 return ERROR_DOS(ERRDOS,ERRlock);
2734 if (schedule_aio_read_and_X(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt)) {
2735 END_PROFILE(SMBreadX);
2739 nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
2741 nread = chain_reply(inbuf,outbuf,length,bufsize);
2743 END_PROFILE(SMBreadX);
2747 /****************************************************************************
2748 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2749 ****************************************************************************/
2751 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2754 ssize_t total_written=0;
2755 size_t numtowrite=0;
2760 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2762 START_PROFILE(SMBwritebraw);
2764 if (srv_is_signing_active()) {
2765 exit_server_cleanly("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2768 CHECK_FSP(fsp,conn);
2769 if (!CHECK_WRITE(fsp)) {
2770 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2773 tcount = IVAL(inbuf,smb_vwv1);
2774 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2775 write_through = BITSETW(inbuf+smb_vwv7,0);
2777 /* We have to deal with slightly different formats depending
2778 on whether we are using the core+ or lanman1.0 protocol */
2780 if(Protocol <= PROTOCOL_COREPLUS) {
2781 numtowrite = SVAL(smb_buf(inbuf),-2);
2782 data = smb_buf(inbuf);
2784 numtowrite = SVAL(inbuf,smb_vwv10);
2785 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2788 /* force the error type */
2789 SCVAL(inbuf,smb_com,SMBwritec);
2790 SCVAL(outbuf,smb_com,SMBwritec);
2792 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2793 END_PROFILE(SMBwritebraw);
2794 return(ERROR_DOS(ERRDOS,ERRlock));
2798 nwritten = write_file(fsp,data,startpos,numtowrite);
2800 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2801 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2803 if (nwritten < (ssize_t)numtowrite) {
2804 END_PROFILE(SMBwritebraw);
2805 return(UNIXERROR(ERRHRD,ERRdiskfull));
2808 total_written = nwritten;
2810 /* Return a message to the redirector to tell it to send more bytes */
2811 SCVAL(outbuf,smb_com,SMBwritebraw);
2812 SSVALS(outbuf,smb_vwv0,-1);
2813 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2815 if (!send_smb(smbd_server_fd(),outbuf))
2816 exit_server_cleanly("reply_writebraw: send_smb failed.");
2818 /* Now read the raw data into the buffer and write it */
2819 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
2820 exit_server_cleanly("secondary writebraw failed");
2823 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2824 numtowrite = smb_len(inbuf);
2826 /* Set up outbuf to return the correct return */
2827 outsize = set_message(outbuf,1,0,True);
2828 SCVAL(outbuf,smb_com,SMBwritec);
2830 if (numtowrite != 0) {
2832 if (numtowrite > BUFFER_SIZE) {
2833 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2834 (unsigned int)numtowrite ));
2835 exit_server_cleanly("secondary writebraw failed");
2838 if (tcount > nwritten+numtowrite) {
2839 DEBUG(3,("Client overestimated the write %d %d %d\n",
2840 (int)tcount,(int)nwritten,(int)numtowrite));
2843 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2844 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2846 exit_server_cleanly("secondary writebraw failed");
2849 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2850 if (nwritten == -1) {
2851 END_PROFILE(SMBwritebraw);
2852 return(UNIXERROR(ERRHRD,ERRdiskfull));
2855 if (nwritten < (ssize_t)numtowrite) {
2856 SCVAL(outbuf,smb_rcls,ERRHRD);
2857 SSVAL(outbuf,smb_err,ERRdiskfull);
2861 total_written += nwritten;
2864 SSVAL(outbuf,smb_vwv0,total_written);
2866 sync_file(conn, fsp, write_through);
2868 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2869 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2871 /* we won't return a status if write through is not selected - this follows what WfWg does */
2872 END_PROFILE(SMBwritebraw);
2873 if (!write_through && total_written==tcount) {
2875 #if RABBIT_PELLET_FIX
2877 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2878 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2880 if (!send_keepalive(smbd_server_fd()))
2881 exit_server_cleanly("reply_writebraw: send of keepalive failed");
2890 #define DBGC_CLASS DBGC_LOCKING
2892 /****************************************************************************
2893 Reply to a writeunlock (core+).
2894 ****************************************************************************/
2896 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2897 int size, int dum_buffsize)
2899 ssize_t nwritten = -1;
2903 NTSTATUS status = NT_STATUS_OK;
2904 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2906 START_PROFILE(SMBwriteunlock);
2908 CHECK_FSP(fsp,conn);
2909 if (!CHECK_WRITE(fsp)) {
2910 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2913 numtowrite = SVAL(inbuf,smb_vwv1);
2914 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2915 data = smb_buf(inbuf) + 3;
2917 if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2918 END_PROFILE(SMBwriteunlock);
2919 return ERROR_DOS(ERRDOS,ERRlock);
2922 /* The special X/Open SMB protocol handling of
2923 zero length writes is *NOT* done for
2925 if(numtowrite == 0) {
2928 nwritten = write_file(fsp,data,startpos,numtowrite);
2931 sync_file(conn, fsp, False /* write through */);
2933 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2934 END_PROFILE(SMBwriteunlock);
2935 return(UNIXERROR(ERRHRD,ERRdiskfull));
2939 status = do_unlock(fsp,
2940 (uint32)SVAL(inbuf,smb_pid),
2941 (SMB_BIG_UINT)numtowrite,
2942 (SMB_BIG_UINT)startpos,
2945 if (NT_STATUS_V(status)) {
2946 END_PROFILE(SMBwriteunlock);
2947 return ERROR_NT(status);
2951 outsize = set_message(outbuf,1,0,True);
2953 SSVAL(outbuf,smb_vwv0,nwritten);
2955 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2956 fsp->fnum, (int)numtowrite, (int)nwritten));
2958 END_PROFILE(SMBwriteunlock);
2963 #define DBGC_CLASS DBGC_ALL
2965 /****************************************************************************
2967 ****************************************************************************/
2969 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2972 ssize_t nwritten = -1;
2975 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2977 START_PROFILE(SMBwrite);
2979 /* If it's an IPC, pass off the pipe handler. */
2981 END_PROFILE(SMBwrite);
2982 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2985 CHECK_FSP(fsp,conn);
2986 if (!CHECK_WRITE(fsp)) {
2987 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2990 numtowrite = SVAL(inbuf,smb_vwv1);
2991 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2992 data = smb_buf(inbuf) + 3;
2994 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2995 END_PROFILE(SMBwrite);
2996 return ERROR_DOS(ERRDOS,ERRlock);
3000 * X/Open SMB protocol says that if smb_vwv1 is
3001 * zero then the file size should be extended or
3002 * truncated to the size given in smb_vwv[2-3].
3005 if(numtowrite == 0) {
3007 * This is actually an allocate call, and set EOF. JRA.
3009 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3011 END_PROFILE(SMBwrite);
3012 return ERROR_NT(NT_STATUS_DISK_FULL);
3014 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3016 END_PROFILE(SMBwrite);
3017 return ERROR_NT(NT_STATUS_DISK_FULL);
3020 nwritten = write_file(fsp,data,startpos,numtowrite);
3022 sync_file(conn, fsp, False);
3024 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3025 END_PROFILE(SMBwrite);
3026 return(UNIXERROR(ERRHRD,ERRdiskfull));
3029 outsize = set_message(outbuf,1,0,True);
3031 SSVAL(outbuf,smb_vwv0,nwritten);
3033 if (nwritten < (ssize_t)numtowrite) {
3034 SCVAL(outbuf,smb_rcls,ERRHRD);
3035 SSVAL(outbuf,smb_err,ERRdiskfull);
3038 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3040 END_PROFILE(SMBwrite);
3044 /****************************************************************************
3045 Reply to a write and X.
3046 ****************************************************************************/
3048 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3050 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
3051 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
3052 size_t numtowrite = SVAL(inbuf,smb_vwv10);
3053 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
3054 ssize_t nwritten = -1;
3055 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
3056 unsigned int smblen = smb_len(inbuf);
3058 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
3059 START_PROFILE(SMBwriteX);
3061 /* If it's an IPC, pass off the pipe handler. */
3063 END_PROFILE(SMBwriteX);
3064 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
3067 CHECK_FSP(fsp,conn);
3068 if (!CHECK_WRITE(fsp)) {
3069 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3072 set_message(outbuf,6,0,True);
3074 /* Deal with possible LARGE_WRITEX */
3076 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
3079 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
3080 END_PROFILE(SMBwriteX);
3081 return ERROR_DOS(ERRDOS,ERRbadmem);
3084 data = smb_base(inbuf) + smb_doff;
3086 if(CVAL(inbuf,smb_wct) == 14) {
3087 #ifdef LARGE_SMB_OFF_T
3089 * This is a large offset (64 bit) write.
3091 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
3093 #else /* !LARGE_SMB_OFF_T */
3096 * Ensure we haven't been sent a >32 bit offset.
3099 if(IVAL(inbuf,smb_vwv12) != 0) {
3100 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
3101 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
3102 END_PROFILE(SMBwriteX);
3103 return ERROR_DOS(ERRDOS,ERRbadaccess);
3106 #endif /* LARGE_SMB_OFF_T */
3109 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3110 END_PROFILE(SMBwriteX);
3111 return ERROR_DOS(ERRDOS,ERRlock);
3114 /* X/Open SMB protocol says that, unlike SMBwrite
3115 if the length is zero then NO truncation is
3116 done, just a write of zero. To truncate a file,
3119 if(numtowrite == 0) {
3123 if (schedule_aio_write_and_X(conn, inbuf, outbuf, length, bufsize,
3124 fsp,data,startpos,numtowrite)) {
3125 END_PROFILE(SMBwriteX);
3129 nwritten = write_file(fsp,data,startpos,numtowrite);
3132 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3133 END_PROFILE(SMBwriteX);
3134 return(UNIXERROR(ERRHRD,ERRdiskfull));
3137 SSVAL(outbuf,smb_vwv2,nwritten);
3139 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
3141 if (nwritten < (ssize_t)numtowrite) {
3142 SCVAL(outbuf,smb_rcls,ERRHRD);
3143 SSVAL(outbuf,smb_err,ERRdiskfull);
3146 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
3147 fsp->fnum, (int)numtowrite, (int)nwritten));
3149 sync_file(conn, fsp, write_through);
3151 END_PROFILE(SMBwriteX);
3152 return chain_reply(inbuf,outbuf,length,bufsize);
3155 /****************************************************************************
3157 ****************************************************************************/
3159 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
3165 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3166 START_PROFILE(SMBlseek);
3168 CHECK_FSP(fsp,conn);
3170 flush_write_cache(fsp, SEEK_FLUSH);
3172 mode = SVAL(inbuf,smb_vwv1) & 3;
3173 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
3174 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
3183 res = fsp->fh->pos + startpos;
3194 if (umode == SEEK_END) {
3195 if((res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,startpos,umode)) == -1) {
3196 if(errno == EINVAL) {
3197 SMB_OFF_T current_pos = startpos;
3198 SMB_STRUCT_STAT sbuf;
3200 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
3201 END_PROFILE(SMBlseek);
3202 return(UNIXERROR(ERRDOS,ERRnoaccess));
3205 current_pos += sbuf.st_size;
3207 res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,0,SEEK_SET);
3212 END_PROFILE(SMBlseek);
3213 return(UNIXERROR(ERRDOS,ERRnoaccess));
3219 outsize = set_message(outbuf,2,0,True);
3220 SIVAL(outbuf,smb_vwv0,res);
3222 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
3223 fsp->fnum, (double)startpos, (double)res, mode));
3225 END_PROFILE(SMBlseek);
3229 /****************************************************************************
3231 ****************************************************************************/
3233 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
3235 int outsize = set_message(outbuf,0,0,False);
3236 uint16 fnum = SVAL(inbuf,smb_vwv0);
3237 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3238 START_PROFILE(SMBflush);
3241 CHECK_FSP(fsp,conn);
3244 file_sync_all(conn);
3246 sync_file(conn,fsp, True);
3249 DEBUG(3,("flush\n"));
3250 END_PROFILE(SMBflush);
3254 /****************************************************************************
3256 conn POINTER CAN BE NULL HERE !
3257 ****************************************************************************/
3259 int reply_exit(connection_struct *conn,
3260 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3263 START_PROFILE(SMBexit);
3265 file_close_pid(SVAL(inbuf,smb_pid),SVAL(inbuf,smb_uid));
3267 outsize = set_message(outbuf,0,0,False);
3269 DEBUG(3,("exit\n"));
3271 END_PROFILE(SMBexit);
3275 /****************************************************************************
3276 Reply to a close - has to deal with closing a directory opened by NT SMB's.
3277 ****************************************************************************/
3279 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
3284 int32 eclass = 0, err = 0;
3285 files_struct *fsp = NULL;
3286 START_PROFILE(SMBclose);
3288 outsize = set_message(outbuf,0,0,False);
3290 /* If it's an IPC, pass off to the pipe handler. */
3292 END_PROFILE(SMBclose);
3293 return reply_pipe_close(conn, inbuf,outbuf);
3296 fsp = file_fsp(inbuf,smb_vwv0);
3299 * We can only use CHECK_FSP if we know it's not a directory.
3302 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
3303 END_PROFILE(SMBclose);
3304 return ERROR_DOS(ERRDOS,ERRbadfid);
3307 if(fsp->is_directory) {
3309 * Special case - close NT SMB directory handle.
3311 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
3312 close_file(fsp,NORMAL_CLOSE);
3315 * Close ordinary file.
3320 /* Save the name for time set in close. */
3321 pstrcpy( file_name, fsp->fsp_name);
3323 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
3324 fsp->fh->fd, fsp->fnum,
3325 conn->num_files_open));
3328 * Take care of any time sent in the close.
3331 mtime = srv_make_unix_date3(inbuf+smb_vwv1);
3332 fsp_set_pending_modtime(fsp, mtime);
3335 * close_file() returns the unix errno if an error
3336 * was detected on close - normally this is due to
3337 * a disk full error. If not then it was probably an I/O error.
3340 if((close_err = close_file(fsp,NORMAL_CLOSE)) != 0) {
3342 END_PROFILE(SMBclose);
3343 return (UNIXERROR(ERRHRD,ERRgeneral));
3347 /* We have a cached error */
3349 END_PROFILE(SMBclose);
3350 return ERROR_DOS(eclass,err);
3353 END_PROFILE(SMBclose);
3357 /****************************************************************************
3358 Reply to a writeclose (Core+ protocol).
3359 ****************************************************************************/
3361 int reply_writeclose(connection_struct *conn,
3362 char *inbuf,char *outbuf, int size, int dum_buffsize)
3365 ssize_t nwritten = -1;
3371 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3372 START_PROFILE(SMBwriteclose);
3374 CHECK_FSP(fsp,conn);
3375 if (!CHECK_WRITE(fsp)) {
3376 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3379 numtowrite = SVAL(inbuf,smb_vwv1);
3380 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
3381 mtime = srv_make_unix_date3(inbuf+smb_vwv4);
3382 data = smb_buf(inbuf) + 1;
3384 if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3385 END_PROFILE(SMBwriteclose);
3386 return ERROR_DOS(ERRDOS,ERRlock);
3389 nwritten = write_file(fsp,data,startpos,numtowrite);
3391 set_filetime(conn, fsp->fsp_name,mtime);
3394 * More insanity. W2K only closes the file if writelen > 0.
3399 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
3401 close_err = close_file(fsp,NORMAL_CLOSE);
3404 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
3405 fsp->fnum, (int)numtowrite, (int)nwritten,
3406 conn->num_files_open));
3408 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3409 END_PROFILE(SMBwriteclose);
3410 return(UNIXERROR(ERRHRD,ERRdiskfull));
3413 if(close_err != 0) {
3415 END_PROFILE(SMBwriteclose);
3416 return(UNIXERROR(ERRHRD,ERRgeneral));
3419 outsize = set_message(outbuf,1,0,True);
3421 SSVAL(outbuf,smb_vwv0,nwritten);
3422 END_PROFILE(SMBwriteclose);
3427 #define DBGC_CLASS DBGC_LOCKING
3429 /****************************************************************************
3431 ****************************************************************************/
3433 int reply_lock(connection_struct *conn,
3434 char *inbuf,char *outbuf, int length, int dum_buffsize)
3436 int outsize = set_message(outbuf,0,0,False);
3437 SMB_BIG_UINT count,offset;
3439 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3440 struct byte_range_lock *br_lck = NULL;
3442 START_PROFILE(SMBlock);
3444 CHECK_FSP(fsp,conn);
3446 release_level_2_oplocks_on_change(fsp);
3448 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
3449 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
3451 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3452 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
3454 br_lck = do_lock(fsp,
3455 (uint32)SVAL(inbuf,smb_pid),
3460 False, /* Non-blocking lock. */
3463 TALLOC_FREE(br_lck);
3465 if (NT_STATUS_V(status)) {
3466 END_PROFILE(SMBlock);
3467 return ERROR_NT(status);
3470 END_PROFILE(SMBlock);
3474 /****************************************************************************
3476 ****************************************************************************/
3478 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
3481 int outsize = set_message(outbuf,0,0,False);
3482 SMB_BIG_UINT count,offset;
3484 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3485 START_PROFILE(SMBunlock);
3487 CHECK_FSP(fsp,conn);
3489 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
3490 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
3492 status = do_unlock(fsp,
3493 (uint32)SVAL(inbuf,smb_pid),
3498 if (NT_STATUS_V(status)) {
3499 END_PROFILE(SMBunlock);
3500 return ERROR_NT(status);
3503 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3504 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
3506 END_PROFILE(SMBunlock);
3511 #define DBGC_CLASS DBGC_ALL
3513 /****************************************************************************
3515 conn POINTER CAN BE NULL HERE !
3516 ****************************************************************************/
3518 int reply_tdis(connection_struct *conn,
3519 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3521 int outsize = set_message(outbuf,0,0,False);
3523 START_PROFILE(SMBtdis);
3525 vuid = SVAL(inbuf,smb_uid);
3528 DEBUG(4,("Invalid connection in tdis\n"));
3529 END_PROFILE(SMBtdis);
3530 return ERROR_DOS(ERRSRV,ERRinvnid);
3535 close_cnum(conn,vuid);
3537 END_PROFILE(SMBtdis);
3541 /****************************************************************************
3543 conn POINTER CAN BE NULL HERE !
3544 ****************************************************************************/
3546 int reply_echo(connection_struct *conn,
3547 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3549 int smb_reverb = SVAL(inbuf,smb_vwv0);
3551 unsigned int data_len = smb_buflen(inbuf);
3552 int outsize = set_message(outbuf,1,data_len,True);
3553 START_PROFILE(SMBecho);
3555 if (data_len > BUFFER_SIZE) {
3556 DEBUG(0,("reply_echo: data_len too large.\n"));
3557 END_PROFILE(SMBecho);
3561 /* copy any incoming data back out */
3563 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
3565 if (smb_reverb > 100) {
3566 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
3570 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
3571 SSVAL(outbuf,smb_vwv0,seq_num);
3573 smb_setlen(outbuf,outsize - 4);
3576 if (!send_smb(smbd_server_fd(),outbuf))
3577 exit_server_cleanly("reply_echo: send_smb failed.");
3580 DEBUG(3,("echo %d times\n", smb_reverb));
3584 END_PROFILE(SMBecho);
3588 /****************************************************************************
3589 Reply to a printopen.
3590 ****************************************************************************/
3592 int reply_printopen(connection_struct *conn,
3593 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3599 START_PROFILE(SMBsplopen);
3601 if (!CAN_PRINT(conn)) {
3602 END_PROFILE(SMBsplopen);
3603 return ERROR_DOS(ERRDOS,ERRnoaccess);
3606 /* Open for exclusive use, write only. */
3607 status = print_fsp_open(conn, NULL, &fsp);
3609 if (!NT_STATUS_IS_OK(status)) {
3610 END_PROFILE(SMBsplopen);
3611 return(ERROR_NT(status));
3614 outsize = set_message(outbuf,1,0,True);
3615 SSVAL(outbuf,smb_vwv0,fsp->fnum);
3617 DEBUG(3,("openprint fd=%d fnum=%d\n",
3618 fsp->fh->fd, fsp->fnum));
3620 END_PROFILE(SMBsplopen);
3624 /****************************************************************************
3625 Reply to a printclose.
3626 ****************************************************************************/
3628 int reply_printclose(connection_struct *conn,
3629 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3631 int outsize = set_message(outbuf,0,0,False);
3632 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3634 START_PROFILE(SMBsplclose);
3636 CHECK_FSP(fsp,conn);
3638 if (!CAN_PRINT(conn)) {
3639 END_PROFILE(SMBsplclose);
3640 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
3643 DEBUG(3,("printclose fd=%d fnum=%d\n",
3644 fsp->fh->fd,fsp->fnum));
3646 close_err = close_file(fsp,NORMAL_CLOSE);
3648 if(close_err != 0) {
3650 END_PROFILE(SMBsplclose);
3651 return(UNIXERROR(ERRHRD,ERRgeneral));
3654 END_PROFILE(SMBsplclose);
3658 /****************************************************************************
3659 Reply to a printqueue.
3660 ****************************************************************************/
3662 int reply_printqueue(connection_struct *conn,
3663 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3665 int outsize = set_message(outbuf,2,3,True);
3666 int max_count = SVAL(inbuf,smb_vwv0);
3667 int start_index = SVAL(inbuf,smb_vwv1);
3668 START_PROFILE(SMBsplretq);
3670 /* we used to allow the client to get the cnum wrong, but that
3671 is really quite gross and only worked when there was only
3672 one printer - I think we should now only accept it if they
3673 get it right (tridge) */
3674 if (!CAN_PRINT(conn)) {
3675 END_PROFILE(SMBsplretq);
3676 return ERROR_DOS(ERRDOS,ERRnoaccess);
3679 SSVAL(outbuf,smb_vwv0,0);
3680 SSVAL(outbuf,smb_vwv1,0);
3681 SCVAL(smb_buf(outbuf),0,1);
3682 SSVAL(smb_buf(outbuf),1,0);
3684 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3685 start_index, max_count));
3688 print_queue_struct *queue = NULL;
3689 print_status_struct status;
3690 char *p = smb_buf(outbuf) + 3;
3691 int count = print_queue_status(SNUM(conn), &queue, &status);
3692 int num_to_get = ABS(max_count);
3693 int first = (max_count>0?start_index:start_index+max_count+1);
3699 num_to_get = MIN(num_to_get,count-first);
3702 for (i=first;i<first+num_to_get;i++) {
3703 srv_put_dos_date2(p,0,queue[i].time);
3704 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
3705 SSVAL(p,5, queue[i].job);
3706 SIVAL(p,7,queue[i].size);
3708 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
3713 outsize = set_message(outbuf,2,28*count+3,False);
3714 SSVAL(outbuf,smb_vwv0,count);
3715 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
3716 SCVAL(smb_buf(outbuf),0,1);
3717 SSVAL(smb_buf(outbuf),1,28*count);
3722 DEBUG(3,("%d entries returned in queue\n",count));
3725 END_PROFILE(SMBsplretq);
3729 /****************************************************************************
3730 Reply to a printwrite.
3731 ****************************************************************************/
3733 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3736 int outsize = set_message(outbuf,0,0,False);
3738 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3740 START_PROFILE(SMBsplwr);
3742 if (!CAN_PRINT(conn)) {
3743 END_PROFILE(SMBsplwr);
3744 return ERROR_DOS(ERRDOS,ERRnoaccess);
3747 CHECK_FSP(fsp,conn);
3748 if (!CHECK_WRITE(fsp)) {
3749 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3752 numtowrite = SVAL(smb_buf(inbuf),1);
3753 data = smb_buf(inbuf) + 3;
3755 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
3756 END_PROFILE(SMBsplwr);
3757 return(UNIXERROR(ERRHRD,ERRdiskfull));
3760 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3762 END_PROFILE(SMBsplwr);
3766 /****************************************************************************
3768 ****************************************************************************/
3770 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3775 BOOL bad_path = False;
3776 SMB_STRUCT_STAT sbuf;
3778 START_PROFILE(SMBmkdir);
3780 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
3781 if (!NT_STATUS_IS_OK(status)) {
3782 END_PROFILE(SMBmkdir);
3783 return ERROR_NT(status);
3786 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
3788 unix_convert(directory,conn,0,&bad_path,&sbuf);
3790 status = create_directory(conn, directory);
3792 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
3794 if (!NT_STATUS_IS_OK(status)) {
3796 if (!use_nt_status()
3797 && NT_STATUS_EQUAL(status,
3798 NT_STATUS_OBJECT_NAME_COLLISION)) {
3800 * Yes, in the DOS error code case we get a
3801 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
3802 * samba4 torture test.
3804 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
3807 END_PROFILE(SMBmkdir);
3808 return ERROR_NT(status);
3811 outsize = set_message(outbuf,0,0,False);
3813 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
3815 END_PROFILE(SMBmkdir);
3819 /****************************************************************************
3820 Static function used by reply_rmdir to delete an entire directory
3821 tree recursively. Return False on ok, True on fail.
3822 ****************************************************************************/
3824 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
3826 const char *dname = NULL;
3829 struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
3834 while((dname = ReadDirName(dir_hnd, &offset))) {
3838 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3841 if (!is_visible_file(conn, directory, dname, &st, False))
3844 /* Construct the full name. */
3845 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3851 pstrcpy(fullname, directory);
3852 pstrcat(fullname, "/");
3853 pstrcat(fullname, dname);
3855 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
3860 if(st.st_mode & S_IFDIR) {
3861 if(recursive_rmdir(conn, fullname)!=0) {
3865 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
3869 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
3878 /****************************************************************************
3879 The internals of the rmdir code - called elsewhere.
3880 ****************************************************************************/
3882 BOOL rmdir_internals(connection_struct *conn, const char *directory)
3887 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3888 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
3890 * Check to see if the only thing in this directory are
3891 * vetoed files/directories. If so then delete them and
3892 * retry. If we fail to delete any of them (and we *don't*
3893 * do a recursive delete) then fail the rmdir.
3895 BOOL all_veto_files = True;
3897 struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
3899 if(dir_hnd != NULL) {
3901 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
3902 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3904 if (!is_visible_file(conn, directory, dname, &st, False))
3906 if(!IS_VETO_PATH(conn, dname)) {
3907 all_veto_files = False;
3912 if(all_veto_files) {
3913 RewindDir(dir_hnd,&dirpos);
3914 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
3917 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3919 if (!is_visible_file(conn, directory, dname, &st, False))
3922 /* Construct the full name. */
3923 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3928 pstrcpy(fullname, directory);
3929 pstrcat(fullname, "/");
3930 pstrcat(fullname, dname);
3932 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
3934 if(st.st_mode & S_IFDIR) {
3935 if(lp_recursive_veto_delete(SNUM(conn))) {
3936 if(recursive_rmdir(conn, fullname) != 0)
3939 if(SMB_VFS_RMDIR(conn,fullname) != 0)
3941 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
3945 /* Retry the rmdir */
3946 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3956 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
3957 "%s\n", directory,strerror(errno)));
3963 const char *dirname;
3965 if (parent_dirname_talloc(tmp_talloc_ctx(), directory,
3966 &parent_dir, &dirname)) {
3967 notify_action(conn, parent_dir, dirname,
3968 NOTIFY_ACTION_REMOVED);
3969 TALLOC_FREE(parent_dir); /* Not strictly necessary */
3976 /****************************************************************************
3978 ****************************************************************************/
3980 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3985 BOOL bad_path = False;
3986 SMB_STRUCT_STAT sbuf;
3988 START_PROFILE(SMBrmdir);
3990 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
3991 if (!NT_STATUS_IS_OK(status)) {
3992 END_PROFILE(SMBrmdir);
3993 return ERROR_NT(status);
3996 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
3998 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
4000 END_PROFILE(SMBrmdir);
4001 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4004 if (check_name(directory,conn)) {
4005 dptr_closepath(directory,SVAL(inbuf,smb_pid));
4006 ok = rmdir_internals(conn, directory);
4010 END_PROFILE(SMBrmdir);
4011 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
4014 outsize = set_message(outbuf,0,0,False);
4016 DEBUG( 3, ( "rmdir %s\n", directory ) );
4018 END_PROFILE(SMBrmdir);
4022 /*******************************************************************
4023 Resolve wildcards in a filename rename.
4024 Note that name is in UNIX charset and thus potentially can be more
4025 than fstring buffer (255 bytes) especially in default UTF-8 case.
4026 Therefore, we use pstring inside and all calls should ensure that
4027 name2 is at least pstring-long (they do already)
4028 ********************************************************************/
4030 static BOOL resolve_wildcards(const char *name1, char *name2)
4032 pstring root1,root2;
4034 char *p,*p2, *pname1, *pname2;
4035 int available_space, actual_space;
4038 pname1 = strrchr_m(name1,'/');
4039 pname2 = strrchr_m(name2,'/');
4041 if (!pname1 || !pname2)
4044 pstrcpy(root1,pname1);
4045 pstrcpy(root2,pname2);
4046 p = strrchr_m(root1,'.');
4053 p = strrchr_m(root2,'.');
4067 } else if (*p2 == '*') {
4083 } else if (*p2 == '*') {
4093 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
4096 actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
4097 if (actual_space >= available_space - 1) {
4098 DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
4099 actual_space - available_space));
4102 pstrcpy_base(pname2, root2, name2);
4108 /****************************************************************************
4109 Ensure open files have their names updated. Updated to notify other smbd's
4111 ****************************************************************************/
4113 static void rename_open_files(connection_struct *conn, struct share_mode_lock *lck,
4114 SMB_DEV_T dev, SMB_INO_T inode, const char *newname)
4117 BOOL did_rename = False;
4119 for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
4120 /* fsp_name is a relative path under the fsp. To change this for other
4121 sharepaths we need to manipulate relative paths. */
4122 /* TODO - create the absolute path and manipulate the newname
4123 relative to the sharepath. */
4124 if (fsp->conn != conn) {
4127 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
4128 fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
4129 fsp->fsp_name, newname ));
4130 string_set(&fsp->fsp_name, newname);
4135 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
4136 (unsigned int)dev, (double)inode, newname ));
4139 /* Send messages to all smbd's (not ourself) that the name has changed. */
4140 rename_share_filename(lck, conn->connectpath, newname);
4143 /****************************************************************************
4144 We need to check if the source path is a parent directory of the destination
4145 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
4146 refuse the rename with a sharing violation. Under UNIX the above call can
4147 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
4148 probably need to check that the client is a Windows one before disallowing
4149 this as a UNIX client (one with UNIX extensions) can know the source is a
4150 symlink and make this decision intelligently. Found by an excellent bug
4151 report from <AndyLiebman@aol.com>.
4152 ****************************************************************************/
4154 static BOOL rename_path_prefix_equal(const char *src, const char *dest)
4156 const char *psrc = src;
4157 const char *pdst = dest;
4160 if (psrc[0] == '.' && psrc[1] == '/') {
4163 if (pdst[0] == '.' && pdst[1] == '/') {
4166 if ((slen = strlen(psrc)) > strlen(pdst)) {
4169 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
4172 /****************************************************************************
4173 Rename an open file - given an fsp.
4174 ****************************************************************************/
4176 NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, uint32 attrs, BOOL replace_if_exists)
4178 SMB_STRUCT_STAT sbuf;
4179 BOOL bad_path = False;
4180 pstring newname_last_component;
4181 NTSTATUS error = NT_STATUS_OK;
4184 struct share_mode_lock *lck = NULL;
4187 rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
4189 /* Quick check for "." and ".." */
4190 if (!bad_path && newname_last_component[0] == '.') {
4191 if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) {
4192 return NT_STATUS_ACCESS_DENIED;
4195 if (!rcdest && bad_path) {
4196 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
4199 /* Ensure newname contains a '/' */
4200 if(strrchr_m(newname,'/') == 0) {
4203 pstrcpy(tmpstr, "./");
4204 pstrcat(tmpstr, newname);
4205 pstrcpy(newname, tmpstr);
4209 * Check for special case with case preserving and not
4210 * case sensitive. If the old last component differs from the original
4211 * last component only by case, then we should allow
4212 * the rename (user is trying to change the case of the
4216 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
4217 strequal(newname, fsp->fsp_name)) {
4219 pstring newname_modified_last_component;
4222 * Get the last component of the modified name.
4223 * Note that we guarantee that newname contains a '/'
4226 p = strrchr_m(newname,'/');
4227 pstrcpy(newname_modified_last_component,p+1);
4229 if(strcsequal(newname_modified_last_component,
4230 newname_last_component) == False) {
4232 * Replace the modified last component with
4235 pstrcpy(p+1, newname_last_component);
4240 * If the src and dest names are identical - including case,
4241 * don't do the rename, just return success.
4244 if (strcsequal(fsp->fsp_name, newname)) {
4245 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
4247 return NT_STATUS_OK;
4250 dest_exists = vfs_object_exist(conn,newname,NULL);
4252 if(!replace_if_exists && dest_exists) {
4253 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
4254 fsp->fsp_name,newname));
4255 return NT_STATUS_OBJECT_NAME_COLLISION;
4258 error = can_rename(conn,newname,attrs,&sbuf);
4260 if (dest_exists && !NT_STATUS_IS_OK(error)) {
4261 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4262 nt_errstr(error), fsp->fsp_name,newname));
4263 if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
4264 error = NT_STATUS_ACCESS_DENIED;
4268 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
4269 return NT_STATUS_ACCESS_DENIED;
4272 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
4274 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
4275 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
4276 fsp->fsp_name,newname));
4277 rename_open_files(conn, lck, fsp->dev, fsp->inode, newname);
4279 return NT_STATUS_OK;
4284 if (errno == ENOTDIR || errno == EISDIR) {
4285 error = NT_STATUS_OBJECT_NAME_COLLISION;
4287 error = map_nt_error_from_unix(errno);
4290 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
4291 nt_errstr(error), fsp->fsp_name,newname));
4296 /****************************************************************************
4297 The guts of the rename command, split out so it may be called by the NT SMB
4299 ****************************************************************************/
4301 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint32 attrs, BOOL replace_if_exists, BOOL has_wild)
4305 pstring last_component_src;
4306 pstring last_component_dest;
4308 BOOL bad_path_src = False;
4309 BOOL bad_path_dest = False;
4311 NTSTATUS error = NT_STATUS_OK;
4314 SMB_STRUCT_STAT sbuf1, sbuf2;
4315 struct share_mode_lock *lck = NULL;
4317 *directory = *mask = 0;
4322 rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1);
4323 if (!rc && bad_path_src) {
4324 if (ms_has_wild(last_component_src))
4325 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4326 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
4329 /* Quick check for "." and ".." */
4330 if (last_component_src[0] == '.') {
4331 if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) {
4332 return NT_STATUS_OBJECT_NAME_INVALID;
4336 rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2);
4338 /* Quick check for "." and ".." */
4339 if (last_component_dest[0] == '.') {
4340 if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) {
4341 return NT_STATUS_OBJECT_NAME_INVALID;
4346 * Split the old name into directory and last component
4347 * strings. Note that unix_convert may have stripped off a
4348 * leading ./ from both name and newname if the rename is
4349 * at the root of the share. We need to make sure either both
4350 * name and newname contain a / character or neither of them do
4351 * as this is checked in resolve_wildcards().
4354 p = strrchr_m(name,'/');
4356 pstrcpy(directory,".");
4360 pstrcpy(directory,name);
4362 *p = '/'; /* Replace needed for exceptional test below. */
4366 * We should only check the mangled cache
4367 * here if unix_convert failed. This means
4368 * that the path in 'mask' doesn't exist
4369 * on the file system and so we need to look
4370 * for a possible mangle. This patch from
4371 * Tine Smukavec <valentin.smukavec@hermes.si>.
4374 if (!rc && mangle_is_mangled(mask, conn->params))
4375 mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
4379 * No wildcards - just process the one file.
4381 BOOL is_short_name = mangle_is_8_3(name, True, conn->params);
4383 /* Add a terminating '/' to the directory name. */
4384 pstrcat(directory,"/");
4385 pstrcat(directory,mask);
4387 /* Ensure newname contains a '/' also */
4388 if(strrchr_m(newname,'/') == 0) {
4391 pstrcpy(tmpstr, "./");
4392 pstrcat(tmpstr, newname);
4393 pstrcpy(newname, tmpstr);
4396 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
4397 directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
4398 conn->case_sensitive, conn->case_preserve, conn->short_case_preserve, directory,
4399 newname, last_component_dest, is_short_name));
4402 * Check for special case with case preserving and not
4403 * case sensitive, if directory and newname are identical,
4404 * and the old last component differs from the original
4405 * last component only by case, then we should allow
4406 * the rename (user is trying to change the case of the
4409 if((conn->case_sensitive == False) &&
4410 (((conn->case_preserve == True) &&
4411 (is_short_name == False)) ||
4412 ((conn->short_case_preserve == True) &&
4413 (is_short_name == True))) &&
4414 strcsequal(directory, newname)) {
4415 pstring modified_last_component;
4418 * Get the last component of the modified name.
4419 * Note that we guarantee that newname contains a '/'
4422 p = strrchr_m(newname,'/');
4423 pstrcpy(modified_last_component,p+1);
4425 if(strcsequal(modified_last_component,
4426 last_component_dest) == False) {
4428 * Replace the modified last component with
4431 pstrcpy(p+1, last_component_dest);
4435 resolve_wildcards(directory,newname);
4438 * The source object must exist.
4441 if (!vfs_object_exist(conn, directory, &sbuf1)) {
4442 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
4443 directory,newname));
4445 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
4447 * Must return different errors depending on whether the parent
4448 * directory existed or not.
4451 p = strrchr_m(directory, '/');
4453 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4455 if (vfs_object_exist(conn, directory, NULL))
4456 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4457 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
4459 error = map_nt_error_from_unix(errno);
4460 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4461 nt_errstr(error), directory,newname));
4466 if (!rcdest && bad_path_dest) {
4467 if (ms_has_wild(last_component_dest))
4468 return NT_STATUS_OBJECT_NAME_INVALID;
4469 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
4472 error = can_rename(conn,directory,attrs,&sbuf1);
4474 if (!NT_STATUS_IS_OK(error)) {
4475 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4476 nt_errstr(error), directory,newname));
4481 * If the src and dest names are identical - including case,
4482 * don't do the rename, just return success.
4485 if (strcsequal(directory, newname)) {
4486 rename_open_files(conn, NULL, sbuf1.st_dev, sbuf1.st_ino, newname);
4487 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
4488 return NT_STATUS_OK;
4491 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
4492 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
4493 directory,newname));
4494 return NT_STATUS_OBJECT_NAME_COLLISION;
4497 if (rename_path_prefix_equal(directory, newname)) {
4498 return NT_STATUS_SHARING_VIOLATION;
4501 lck = get_share_mode_lock(NULL, sbuf1.st_dev, sbuf1.st_ino, NULL, NULL);
4503 if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
4504 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
4505 directory,newname));
4506 rename_open_files(conn, lck, sbuf1.st_dev, sbuf1.st_ino, newname);
4508 return NT_STATUS_OK;
4512 if (errno == ENOTDIR || errno == EISDIR)
4513 error = NT_STATUS_OBJECT_NAME_COLLISION;
4515 error = map_nt_error_from_unix(errno);
4517 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4518 nt_errstr(error), directory,newname));
4523 * Wildcards - process each file that matches.
4525 struct smb_Dir *dir_hnd = NULL;
4529 if (strequal(mask,"????????.???"))
4532 if (check_name(directory,conn))
4533 dir_hnd = OpenDir(conn, directory, mask, attrs);
4537 error = NT_STATUS_NO_SUCH_FILE;
4538 /* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
4540 while ((dname = ReadDirName(dir_hnd, &offset))) {
4542 BOOL sysdir_entry = False;
4544 pstrcpy(fname,dname);
4546 /* Quick check for "." and ".." */
4547 if (fname[0] == '.') {
4548 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
4550 sysdir_entry = True;
4557 if (!is_visible_file(conn, directory, dname, &sbuf1, False))
4560 if(!mask_match(fname, mask, conn->case_sensitive))
4564 error = NT_STATUS_OBJECT_NAME_INVALID;
4568 error = NT_STATUS_ACCESS_DENIED;
4569 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
4570 if (!vfs_object_exist(conn, fname, &sbuf1)) {
4571 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
4572 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
4575 error = can_rename(conn,fname,attrs,&sbuf1);
4576 if (!NT_STATUS_IS_OK(error)) {
4577 DEBUG(6,("rename %s refused\n", fname));
4580 pstrcpy(destname,newname);
4582 if (!resolve_wildcards(fname,destname)) {
4583 DEBUG(6,("resolve_wildcards %s %s failed\n",
4588 if (strcsequal(fname,destname)) {
4589 rename_open_files(conn, NULL, sbuf1.st_dev, sbuf1.st_ino, newname);
4590 DEBUG(3,("rename_internals: identical names in wildcard rename %s - success\n", fname));
4592 error = NT_STATUS_OK;
4596 if (!replace_if_exists &&
4597 vfs_file_exist(conn,destname, NULL)) {
4598 DEBUG(6,("file_exist %s\n", destname));
4599 error = NT_STATUS_OBJECT_NAME_COLLISION;
4603 if (rename_path_prefix_equal(fname, destname)) {
4604 return NT_STATUS_SHARING_VIOLATION;
4607 lck = get_share_mode_lock(NULL, sbuf1.st_dev, sbuf1.st_ino, NULL, NULL);
4609 if (!SMB_VFS_RENAME(conn,fname,destname)) {
4610 rename_open_files(conn, lck, sbuf1.st_dev, sbuf1.st_ino, newname);
4612 error = NT_STATUS_OK;
4615 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
4620 if (!NT_STATUS_EQUAL(error,NT_STATUS_NO_SUCH_FILE)) {
4621 if (!rcdest && bad_path_dest) {
4622 if (ms_has_wild(last_component_dest))
4623 return NT_STATUS_OBJECT_NAME_INVALID;
4624 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
4629 if (count == 0 && NT_STATUS_IS_OK(error)) {
4630 error = map_nt_error_from_unix(errno);
4636 /****************************************************************************
4638 ****************************************************************************/
4640 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
4647 uint32 attrs = SVAL(inbuf,smb_vwv0);
4649 BOOL path1_contains_wcard = False;
4650 BOOL path2_contains_wcard = False;
4652 START_PROFILE(SMBmv);
4654 p = smb_buf(inbuf) + 1;
4655 p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &path1_contains_wcard);
4656 if (!NT_STATUS_IS_OK(status)) {
4658 return ERROR_NT(status);
4661 p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &path2_contains_wcard);
4662 if (!NT_STATUS_IS_OK(status)) {
4664 return ERROR_NT(status);
4667 RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
4668 RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
4670 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
4672 status = rename_internals(conn, name, newname, attrs, False, path1_contains_wcard);
4673 if (!NT_STATUS_IS_OK(status)) {
4675 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4676 /* We have re-scheduled this call. */
4679 return ERROR_NT(status);
4683 * Win2k needs a changenotify request response before it will
4684 * update after a rename..
4686 process_pending_change_notify_queue((time_t)0);
4687 outsize = set_message(outbuf,0,0,False);
4693 /*******************************************************************
4694 Copy a file as part of a reply_copy.
4695 ******************************************************************/
4697 BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
4698 int count,BOOL target_is_directory, int *err_ret)
4700 SMB_STRUCT_STAT src_sbuf, sbuf2;
4702 files_struct *fsp1,*fsp2;
4705 uint32 new_create_disposition;
4710 pstrcpy(dest,dest1);
4711 if (target_is_directory) {
4712 char *p = strrchr_m(src,'/');
4722 if (!vfs_file_exist(conn,src,&src_sbuf)) {
4726 if (!target_is_directory && count) {
4727 new_create_disposition = FILE_OPEN;
4729 if (!map_open_params_to_ntcreate(dest1,0,ofun,
4730 NULL, NULL, &new_create_disposition, NULL)) {
4735 status = open_file_ntcreate(conn,src,&src_sbuf,
4737 FILE_SHARE_READ|FILE_SHARE_WRITE,
4740 FILE_ATTRIBUTE_NORMAL,
4744 if (!NT_STATUS_IS_OK(status)) {
4748 dosattrs = dos_mode(conn, src, &src_sbuf);
4749 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
4750 ZERO_STRUCTP(&sbuf2);
4753 status = open_file_ntcreate(conn,dest,&sbuf2,
4755 FILE_SHARE_READ|FILE_SHARE_WRITE,
4756 new_create_disposition,
4762 if (!NT_STATUS_IS_OK(status)) {
4763 close_file(fsp1,ERROR_CLOSE);
4767 if ((ofun&3) == 1) {
4768 if(SMB_VFS_LSEEK(fsp2,fsp2->fh->fd,0,SEEK_END) == -1) {
4769 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
4771 * Stop the copy from occurring.
4774 src_sbuf.st_size = 0;
4778 if (src_sbuf.st_size) {
4779 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
4782 close_file(fsp1,NORMAL_CLOSE);
4784 /* Ensure the modtime is set correctly on the destination file. */
4785 fsp_set_pending_modtime( fsp2, src_sbuf.st_mtime);
4788 * As we are opening fsp1 read-only we only expect
4789 * an error on close on fsp2 if we are out of space.
4790 * Thus we don't look at the error return from the
4793 *err_ret = close_file(fsp2,NORMAL_CLOSE);
4795 return(ret == (SMB_OFF_T)src_sbuf.st_size);
4798 /****************************************************************************
4799 Reply to a file copy.
4800 ****************************************************************************/
4802 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4807 pstring mask,newname;
4810 int error = ERRnoaccess;
4814 int tid2 = SVAL(inbuf,smb_vwv0);
4815 int ofun = SVAL(inbuf,smb_vwv1);
4816 int flags = SVAL(inbuf,smb_vwv2);
4817 BOOL target_is_directory=False;
4818 BOOL bad_path1 = False;
4819 BOOL bad_path2 = False;
4820 BOOL path_contains_wcard1 = False;
4821 BOOL path_contains_wcard2 = False;
4823 SMB_STRUCT_STAT sbuf1, sbuf2;
4825 START_PROFILE(SMBcopy);
4827 *directory = *mask = 0;
4830 p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard1);
4831 if (!NT_STATUS_IS_OK(status)) {
4832 END_PROFILE(SMBcopy);
4833 return ERROR_NT(status);
4835 p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &path_contains_wcard2);
4836 if (!NT_STATUS_IS_OK(status)) {
4837 END_PROFILE(SMBcopy);
4838 return ERROR_NT(status);
4841 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
4843 if (tid2 != conn->cnum) {
4844 /* can't currently handle inter share copies XXXX */
4845 DEBUG(3,("Rejecting inter-share copy\n"));
4846 END_PROFILE(SMBcopy);
4847 return ERROR_DOS(ERRSRV,ERRinvdevice);
4850 RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
4851 RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
4853 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
4854 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
4856 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
4858 if ((flags&1) && target_is_directory) {
4859 END_PROFILE(SMBcopy);
4860 return ERROR_DOS(ERRDOS,ERRbadfile);
4863 if ((flags&2) && !target_is_directory) {
4864 END_PROFILE(SMBcopy);
4865 return ERROR_DOS(ERRDOS,ERRbadpath);
4868 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
4869 /* wants a tree copy! XXXX */
4870 DEBUG(3,("Rejecting tree copy\n"));
4871 END_PROFILE(SMBcopy);
4872 return ERROR_DOS(ERRSRV,ERRerror);
4875 p = strrchr_m(name,'/');
4877 pstrcpy(directory,"./");
4881 pstrcpy(directory,name);
4886 * We should only check the mangled cache
4887 * here if unix_convert failed. This means
4888 * that the path in 'mask' doesn't exist
4889 * on the file system and so we need to look
4890 * for a possible mangle. This patch from
4891 * Tine Smukavec <valentin.smukavec@hermes.si>.
4894 if (!rc && mangle_is_mangled(mask, conn->params))
4895 mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
4897 has_wild = path_contains_wcard1;
4900 pstrcat(directory,"/");
4901 pstrcat(directory,mask);
4902 if (resolve_wildcards(directory,newname) &&
4903 copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
4907 END_PROFILE(SMBcopy);
4908 return(UNIXERROR(ERRHRD,ERRgeneral));
4911 exists = vfs_file_exist(conn,directory,NULL);
4914 struct smb_Dir *dir_hnd = NULL;
4918 if (strequal(mask,"????????.???"))
4921 if (check_name(directory,conn))
4922 dir_hnd = OpenDir(conn, directory, mask, 0);
4928 while ((dname = ReadDirName(dir_hnd, &offset))) {
4930 pstrcpy(fname,dname);
4932 if (!is_visible_file(conn, directory, dname, &sbuf1, False))
4935 if(!mask_match(fname, mask, conn->case_sensitive))
4938 error = ERRnoaccess;
4939 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
4940 pstrcpy(destname,newname);
4941 if (resolve_wildcards(fname,destname) &&
4942 copy_file(fname,destname,conn,ofun,
4943 count,target_is_directory,&err))
4945 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
4953 /* Error on close... */
4955 END_PROFILE(SMBcopy);
4956 return(UNIXERROR(ERRHRD,ERRgeneral));
4960 END_PROFILE(SMBcopy);
4961 return ERROR_DOS(ERRDOS,error);
4963 if((errno == ENOENT) && (bad_path1 || bad_path2) &&
4965 /* Samba 3.0.22 has ERRDOS/ERRbadpath in the
4966 * DOS error code case
4968 return ERROR_DOS(ERRDOS, ERRbadpath);
4970 END_PROFILE(SMBcopy);
4971 return(UNIXERROR(ERRDOS,error));
4975 outsize = set_message(outbuf,1,0,True);
4976 SSVAL(outbuf,smb_vwv0,count);
4978 END_PROFILE(SMBcopy);
4982 /****************************************************************************
4984 ****************************************************************************/
4986 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4994 START_PROFILE(pathworks_setdir);
4997 if (!CAN_SETDIR(snum)) {
4998 END_PROFILE(pathworks_setdir);
4999 return ERROR_DOS(ERRDOS,ERRnoaccess);
5002 srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status);
5003 if (!NT_STATUS_IS_OK(status)) {
5004 END_PROFILE(pathworks_setdir);
5005 return ERROR_NT(status);
5008 RESOLVE_DFSPATH(newdir, conn, inbuf, outbuf);
5010 if (strlen(newdir) == 0) {
5013 ok = vfs_directory_exist(conn,newdir,NULL);
5015 set_conn_connectpath(conn,newdir);
5019 END_PROFILE(pathworks_setdir);
5020 return ERROR_DOS(ERRDOS,ERRbadpath);
5023 outsize = set_message(outbuf,0,0,False);
5024 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
5026 DEBUG(3,("setdir %s\n", newdir));
5028 END_PROFILE(pathworks_setdir);
5033 #define DBGC_CLASS DBGC_LOCKING
5035 /****************************************************************************
5036 Get a lock pid, dealing with large count requests.
5037 ****************************************************************************/
5039 uint32 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
5041 if(!large_file_format)
5042 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
5044 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
5047 /****************************************************************************
5048 Get a lock count, dealing with large count requests.
5049 ****************************************************************************/
5051 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
5053 SMB_BIG_UINT count = 0;
5055 if(!large_file_format) {
5056 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
5059 #if defined(HAVE_LONGLONG)
5060 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
5061 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
5062 #else /* HAVE_LONGLONG */
5065 * NT4.x seems to be broken in that it sends large file (64 bit)
5066 * lockingX calls even if the CAP_LARGE_FILES was *not*
5067 * negotiated. For boxes without large unsigned ints truncate the
5068 * lock count by dropping the top 32 bits.
5071 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
5072 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
5073 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
5074 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
5075 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
5078 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
5079 #endif /* HAVE_LONGLONG */
5085 #if !defined(HAVE_LONGLONG)
5086 /****************************************************************************
5087 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
5088 ****************************************************************************/
5090 static uint32 map_lock_offset(uint32 high, uint32 low)
5094 uint32 highcopy = high;
5097 * Try and find out how many significant bits there are in high.
5100 for(i = 0; highcopy; i++)
5104 * We use 31 bits not 32 here as POSIX
5105 * lock offsets may not be negative.
5108 mask = (~0) << (31 - i);
5111 return 0; /* Fail. */
5117 #endif /* !defined(HAVE_LONGLONG) */
5119 /****************************************************************************
5120 Get a lock offset, dealing with large offset requests.
5121 ****************************************************************************/
5123 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
5125 SMB_BIG_UINT offset = 0;
5129 if(!large_file_format) {
5130 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
5133 #if defined(HAVE_LONGLONG)
5134 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
5135 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
5136 #else /* HAVE_LONGLONG */
5139 * NT4.x seems to be broken in that it sends large file (64 bit)
5140 * lockingX calls even if the CAP_LARGE_FILES was *not*
5141 * negotiated. For boxes without large unsigned ints mangle the
5142 * lock offset by mapping the top 32 bits onto the lower 32.
5145 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
5146 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
5147 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
5150 if((new_low = map_lock_offset(high, low)) == 0) {
5152 return (SMB_BIG_UINT)-1;
5155 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
5156 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
5157 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
5158 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
5161 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
5162 #endif /* HAVE_LONGLONG */
5168 /****************************************************************************
5169 Reply to a lockingX request.
5170 ****************************************************************************/
5172 int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
5173 int length, int bufsize)
5175 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
5176 unsigned char locktype = CVAL(inbuf,smb_vwv3);
5177 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
5178 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
5179 uint16 num_locks = SVAL(inbuf,smb_vwv7);
5180 SMB_BIG_UINT count = 0, offset = 0;
5182 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
5185 BOOL large_file_format =
5186 (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
5188 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5190 START_PROFILE(SMBlockingX);
5192 CHECK_FSP(fsp,conn);
5194 data = smb_buf(inbuf);
5196 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
5197 /* we don't support these - and CANCEL_LOCK makes w2k
5198 and XP reboot so I don't really want to be
5199 compatible! (tridge) */
5200 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
5203 /* Check if this is an oplock break on a file
5204 we have granted an oplock on.
5206 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
5207 /* Client can insist on breaking to none. */
5208 BOOL break_to_none = (oplocklevel == 0);
5211 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
5212 "for fnum = %d\n", (unsigned int)oplocklevel,
5216 * Make sure we have granted an exclusive or batch oplock on
5220 if (fsp->oplock_type == 0) {
5222 /* The Samba4 nbench simulator doesn't understand
5223 the difference between break to level2 and break
5224 to none from level2 - it sends oplock break
5225 replies in both cases. Don't keep logging an error
5226 message here - just ignore it. JRA. */
5228 DEBUG(5,("reply_lockingX: Error : oplock break from "
5229 "client for fnum = %d (oplock=%d) and no "
5230 "oplock granted on this file (%s).\n",
5231 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
5233 /* if this is a pure oplock break request then don't
5235 if (num_locks == 0 && num_ulocks == 0) {
5236 END_PROFILE(SMBlockingX);
5239 END_PROFILE(SMBlockingX);
5240 return ERROR_DOS(ERRDOS,ERRlock);
5244 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
5246 result = remove_oplock(fsp);
5248 result = downgrade_oplock(fsp);
5252 DEBUG(0, ("reply_lockingX: error in removing "
5253 "oplock on file %s\n", fsp->fsp_name));
5254 /* Hmmm. Is this panic justified? */
5255 smb_panic("internal tdb error");
5258 reply_to_oplock_break_requests(fsp);
5260 /* if this is a pure oplock break request then don't send a
5262 if (num_locks == 0 && num_ulocks == 0) {
5263 /* Sanity check - ensure a pure oplock break is not a
5265 if(CVAL(inbuf,smb_vwv0) != 0xff)
5266 DEBUG(0,("reply_lockingX: Error : pure oplock "
5267 "break is a chained %d request !\n",
5268 (unsigned int)CVAL(inbuf,smb_vwv0) ));
5269 END_PROFILE(SMBlockingX);
5275 * We do this check *after* we have checked this is not a oplock break
5276 * response message. JRA.
5279 release_level_2_oplocks_on_change(fsp);
5281 /* Data now points at the beginning of the list
5282 of smb_unlkrng structs */
5283 for(i = 0; i < (int)num_ulocks; i++) {
5284 lock_pid = get_lock_pid( data, i, large_file_format);
5285 count = get_lock_count( data, i, large_file_format);
5286 offset = get_lock_offset( data, i, large_file_format, &err);
5289 * There is no error code marked "stupid client bug".... :-).
5292 END_PROFILE(SMBlockingX);
5293 return ERROR_DOS(ERRDOS,ERRnoaccess);
5296 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
5297 "pid %u, file %s\n", (double)offset, (double)count,
5298 (unsigned int)lock_pid, fsp->fsp_name ));
5300 status = do_unlock(fsp,
5306 if (NT_STATUS_V(status)) {
5307 END_PROFILE(SMBlockingX);
5308 return ERROR_NT(status);
5312 /* Setup the timeout in seconds. */
5314 if (!lp_blocking_locks(SNUM(conn))) {
5318 /* Now do any requested locks */
5319 data += ((large_file_format ? 20 : 10)*num_ulocks);
5321 /* Data now points at the beginning of the list
5322 of smb_lkrng structs */
5324 for(i = 0; i < (int)num_locks; i++) {
5325 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
5326 READ_LOCK:WRITE_LOCK);
5327 lock_pid = get_lock_pid( data, i, large_file_format);
5328 count = get_lock_count( data, i, large_file_format);
5329 offset = get_lock_offset( data, i, large_file_format, &err);
5332 * There is no error code marked "stupid client bug".... :-).
5335 END_PROFILE(SMBlockingX);
5336 return ERROR_DOS(ERRDOS,ERRnoaccess);
5339 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
5340 "%u, file %s timeout = %d\n", (double)offset,
5341 (double)count, (unsigned int)lock_pid,
5342 fsp->fsp_name, (int)lock_timeout ));
5344 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
5345 if (lp_blocking_locks(SNUM(conn))) {
5347 /* Schedule a message to ourselves to
5348 remove the blocking lock record and
5349 return the right error. */
5351 if (!blocking_lock_cancel(fsp,
5357 NT_STATUS_FILE_LOCK_CONFLICT)) {
5358 END_PROFILE(SMBlockingX);
5359 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation));
5362 /* Remove a matching pending lock. */
5363 status = do_lock_cancel(fsp,
5369 BOOL blocking_lock = lock_timeout ? True : False;
5370 BOOL defer_lock = False;
5371 struct byte_range_lock *br_lck;
5373 br_lck = do_lock(fsp,
5382 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
5383 /* Windows internal resolution for blocking locks seems
5384 to be about 200ms... Don't wait for less than that. JRA. */
5385 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
5386 lock_timeout = lp_lock_spin_time();
5391 /* This heuristic seems to match W2K3 very well. If a
5392 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
5393 it pretends we asked for a timeout of between 150 - 300 milliseconds as
5394 far as I can tell. Replacement for do_lock_spin(). JRA. */
5396 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
5397 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
5399 lock_timeout = lp_lock_spin_time();
5402 if (br_lck && defer_lock) {
5404 * A blocking lock was requested. Package up
5405 * this smb into a queued request and push it
5406 * onto the blocking lock queue.
5408 if(push_blocking_lock_request(br_lck,
5418 TALLOC_FREE(br_lck);
5419 END_PROFILE(SMBlockingX);
5424 TALLOC_FREE(br_lck);
5427 if (NT_STATUS_V(status)) {
5428 END_PROFILE(SMBlockingX);
5429 return ERROR_NT(status);
5433 /* If any of the above locks failed, then we must unlock
5434 all of the previous locks (X/Open spec). */
5436 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
5440 * Ensure we don't do a remove on the lock that just failed,
5441 * as under POSIX rules, if we have a lock already there, we
5442 * will delete it (and we shouldn't) .....
5444 for(i--; i >= 0; i--) {
5445 lock_pid = get_lock_pid( data, i, large_file_format);
5446 count = get_lock_count( data, i, large_file_format);
5447 offset = get_lock_offset( data, i, large_file_format,
5451 * There is no error code marked "stupid client
5455 END_PROFILE(SMBlockingX);
5456 return ERROR_DOS(ERRDOS,ERRnoaccess);
5465 END_PROFILE(SMBlockingX);
5466 return ERROR_NT(status);
5469 set_message(outbuf,2,0,True);
5471 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
5472 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
5474 END_PROFILE(SMBlockingX);
5475 return chain_reply(inbuf,outbuf,length,bufsize);
5479 #define DBGC_CLASS DBGC_ALL
5481 /****************************************************************************
5482 Reply to a SMBreadbmpx (read block multiplex) request.
5483 ****************************************************************************/
5485 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
5496 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5497 START_PROFILE(SMBreadBmpx);
5499 /* this function doesn't seem to work - disable by default */
5500 if (!lp_readbmpx()) {
5501 END_PROFILE(SMBreadBmpx);
5502 return ERROR_DOS(ERRSRV,ERRuseSTD);
5505 outsize = set_message(outbuf,8,0,True);
5507 CHECK_FSP(fsp,conn);
5508 if (!CHECK_READ(fsp,inbuf)) {
5509 return(ERROR_DOS(ERRDOS,ERRbadaccess));
5512 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
5513 maxcount = SVAL(inbuf,smb_vwv3);
5515 data = smb_buf(outbuf);
5516 pad = ((long)data)%4;
5521 max_per_packet = bufsize-(outsize+pad);
5525 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
5526 END_PROFILE(SMBreadBmpx);
5527 return ERROR_DOS(ERRDOS,ERRlock);
5531 size_t N = MIN(max_per_packet,tcount-total_read);
5533 nread = read_file(fsp,data,startpos,N);
5538 if (nread < (ssize_t)N)
5539 tcount = total_read + nread;
5541 set_message(outbuf,8,nread+pad,False);
5542 SIVAL(outbuf,smb_vwv0,startpos);
5543 SSVAL(outbuf,smb_vwv2,tcount);
5544 SSVAL(outbuf,smb_vwv6,nread);
5545 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
5548 if (!send_smb(smbd_server_fd(),outbuf))
5549 exit_server_cleanly("reply_readbmpx: send_smb failed.");
5551 total_read += nread;
5553 } while (total_read < (ssize_t)tcount);
5555 END_PROFILE(SMBreadBmpx);
5559 /****************************************************************************
5560 Reply to a SMBsetattrE.
5561 ****************************************************************************/
5563 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
5565 struct utimbuf unix_times;
5567 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5568 START_PROFILE(SMBsetattrE);
5570 outsize = set_message(outbuf,0,0,False);
5572 if(!fsp || (fsp->conn != conn)) {
5573 END_PROFILE(SMBsetattrE);
5574 return ERROR_DOS(ERRDOS,ERRbadfid);
5578 * Convert the DOS times into unix times. Ignore create
5579 * time as UNIX can't set this.
5582 unix_times.actime = srv_make_unix_date2(inbuf+smb_vwv3);
5583 unix_times.modtime = srv_make_unix_date2(inbuf+smb_vwv5);
5586 * Patch from Ray Frush <frush@engr.colostate.edu>
5587 * Sometimes times are sent as zero - ignore them.
5590 if (null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
5591 /* Ignore request */
5592 if( DEBUGLVL( 3 ) ) {
5593 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
5594 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
5596 END_PROFILE(SMBsetattrE);
5598 } else if (!null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
5599 /* set modify time = to access time if modify time was unset */
5600 unix_times.modtime = unix_times.actime;
5603 /* Set the date on this file */
5604 /* Should we set pending modtime here ? JRA */
5605 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
5606 END_PROFILE(SMBsetattrE);
5607 return ERROR_DOS(ERRDOS,ERRnoaccess);
5610 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
5611 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
5613 END_PROFILE(SMBsetattrE);
5618 /* Back from the dead for OS/2..... JRA. */
5620 /****************************************************************************
5621 Reply to a SMBwritebmpx (write block multiplex primary) request.
5622 ****************************************************************************/
5624 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
5627 ssize_t nwritten = -1;
5634 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5635 START_PROFILE(SMBwriteBmpx);
5637 CHECK_FSP(fsp,conn);
5638 if (!CHECK_WRITE(fsp)) {
5639 return(ERROR_DOS(ERRDOS,ERRbadaccess));
5641 if (HAS_CACHED_ERROR(fsp)) {
5642 return(CACHED_ERROR(fsp));
5645 tcount = SVAL(inbuf,smb_vwv1);
5646 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
5647 write_through = BITSETW(inbuf+smb_vwv7,0);
5648 numtowrite = SVAL(inbuf,smb_vwv10);
5649 smb_doff = SVAL(inbuf,smb_vwv11);
5651 data = smb_base(inbuf) + smb_doff;
5653 /* If this fails we need to send an SMBwriteC response,
5654 not an SMBwritebmpx - set this up now so we don't forget */
5655 SCVAL(outbuf,smb_com,SMBwritec);
5657 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
5658 END_PROFILE(SMBwriteBmpx);
5659 return(ERROR_DOS(ERRDOS,ERRlock));
5662 nwritten = write_file(fsp,data,startpos,numtowrite);
5664 sync_file(conn, fsp, write_through);
5666 if(nwritten < (ssize_t)numtowrite) {
5667 END_PROFILE(SMBwriteBmpx);
5668 return(UNIXERROR(ERRHRD,ERRdiskfull));
5671 /* If the maximum to be written to this file
5672 is greater than what we just wrote then set
5673 up a secondary struct to be attached to this
5674 fd, we will use this to cache error messages etc. */
5676 if((ssize_t)tcount > nwritten) {
5677 write_bmpx_struct *wbms;
5678 if(fsp->wbmpx_ptr != NULL)
5679 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
5681 wbms = SMB_MALLOC_P(write_bmpx_struct);
5683 DEBUG(0,("Out of memory in reply_readmpx\n"));
5684 END_PROFILE(SMBwriteBmpx);
5685 return(ERROR_DOS(ERRSRV,ERRnoresource));
5687 wbms->wr_mode = write_through;
5688 wbms->wr_discard = False; /* No errors yet */
5689 wbms->wr_total_written = nwritten;
5690 wbms->wr_errclass = 0;
5692 fsp->wbmpx_ptr = wbms;
5695 /* We are returning successfully, set the message type back to
5697 SCVAL(outbuf,smb_com,SMBwriteBmpx);
5699 outsize = set_message(outbuf,1,0,True);
5701 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
5703 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
5704 fsp->fnum, (int)numtowrite, (int)nwritten ) );
5706 if (write_through && tcount==nwritten) {
5707 /* We need to send both a primary and a secondary response */
5708 smb_setlen(outbuf,outsize - 4);
5710 if (!send_smb(smbd_server_fd(),outbuf))
5711 exit_server_cleanly("reply_writebmpx: send_smb failed.");
5713 /* Now the secondary */
5714 outsize = set_message(outbuf,1,0,True);
5715 SCVAL(outbuf,smb_com,SMBwritec);
5716 SSVAL(outbuf,smb_vwv0,nwritten);
5719 END_PROFILE(SMBwriteBmpx);
5723 /****************************************************************************
5724 Reply to a SMBwritebs (write block multiplex secondary) request.
5725 ****************************************************************************/
5727 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
5730 ssize_t nwritten = -1;
5737 write_bmpx_struct *wbms;
5738 BOOL send_response = False;
5739 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5740 START_PROFILE(SMBwriteBs);
5742 CHECK_FSP(fsp,conn);
5743 if (!CHECK_WRITE(fsp)) {
5744 return(ERROR_DOS(ERRDOS,ERRbadaccess));
5747 tcount = SVAL(inbuf,smb_vwv1);
5748 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
5749 numtowrite = SVAL(inbuf,smb_vwv6);
5750 smb_doff = SVAL(inbuf,smb_vwv7);
5752 data = smb_base(inbuf) + smb_doff;
5754 /* We need to send an SMBwriteC response, not an SMBwritebs */
5755 SCVAL(outbuf,smb_com,SMBwritec);
5757 /* This fd should have an auxiliary struct attached,
5758 check that it does */
5759 wbms = fsp->wbmpx_ptr;
5761 END_PROFILE(SMBwriteBs);
5765 /* If write through is set we can return errors, else we must cache them */
5766 write_through = wbms->wr_mode;
5768 /* Check for an earlier error */
5769 if(wbms->wr_discard) {
5770 END_PROFILE(SMBwriteBs);
5771 return -1; /* Just discard the packet */
5774 nwritten = write_file(fsp,data,startpos,numtowrite);
5776 sync_file(conn, fsp, write_through);
5778 if (nwritten < (ssize_t)numtowrite) {
5780 /* We are returning an error - we can delete the aux struct */
5783 fsp->wbmpx_ptr = NULL;
5784 END_PROFILE(SMBwriteBs);
5785 return(ERROR_DOS(ERRHRD,ERRdiskfull));
5787 wbms->wr_errclass = ERRHRD;
5788 wbms->wr_error = ERRdiskfull;
5789 wbms->wr_status = NT_STATUS_DISK_FULL;
5790 wbms->wr_discard = True;
5791 END_PROFILE(SMBwriteBs);
5795 /* Increment the total written, if this matches tcount
5796 we can discard the auxiliary struct (hurrah !) and return a writeC */
5797 wbms->wr_total_written += nwritten;
5798 if(wbms->wr_total_written >= tcount) {
5799 if (write_through) {
5800 outsize = set_message(outbuf,1,0,True);
5801 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
5802 send_response = True;
5806 fsp->wbmpx_ptr = NULL;
5810 END_PROFILE(SMBwriteBs);
5814 END_PROFILE(SMBwriteBs);
5818 /****************************************************************************
5819 Reply to a SMBgetattrE.
5820 ****************************************************************************/
5822 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
5824 SMB_STRUCT_STAT sbuf;
5827 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5828 START_PROFILE(SMBgetattrE);
5830 outsize = set_message(outbuf,11,0,True);
5832 if(!fsp || (fsp->conn != conn)) {
5833 END_PROFILE(SMBgetattrE);
5834 return ERROR_DOS(ERRDOS,ERRbadfid);
5837 /* Do an fstat on this file */
5838 if(fsp_stat(fsp, &sbuf)) {
5839 END_PROFILE(SMBgetattrE);
5840 return(UNIXERROR(ERRDOS,ERRnoaccess));
5843 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
5846 * Convert the times into dos times. Set create
5847 * date to be last modify date as UNIX doesn't save
5851 srv_put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
5852 srv_put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
5853 /* Should we check pending modtime here ? JRA */
5854 srv_put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
5857 SIVAL(outbuf,smb_vwv6,0);
5858 SIVAL(outbuf,smb_vwv8,0);
5860 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
5861 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
5862 SIVAL(outbuf,smb_vwv8,allocation_size);
5864 SSVAL(outbuf,smb_vwv10, mode);
5866 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
5868 END_PROFILE(SMBgetattrE);