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
;
135 switch(next_mb_char_size(s
)) {
146 DEBUG(0,("check_path_syntax: character length assumptions invalid !\n"));
148 return NT_STATUS_INVALID_PARAMETER
;
151 if (start_of_name_component
&& num_bad_components
) {
152 num_bad_components
++;
154 start_of_name_component
= False
;
157 if (NT_STATUS_EQUAL(ret
, NT_STATUS_OBJECT_NAME_INVALID
)) {
158 if (num_bad_components
> 1) {
159 ret
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
167 /****************************************************************************
168 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
169 path or anything including wildcards.
170 We're assuming here that '/' is not the second byte in any multibyte char
171 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
173 ****************************************************************************/
175 NTSTATUS
check_path_syntax_wcard(pstring destname
, const pstring srcname
, BOOL
*p_contains_wcard
)
178 const char *s
= srcname
;
179 NTSTATUS ret
= NT_STATUS_OK
;
180 BOOL start_of_name_component
= True
;
181 unsigned int num_bad_components
= 0;
183 *p_contains_wcard
= False
;
186 if (IS_DIRECTORY_SEP(*s
)) {
188 * Safe to assume is not the second part of a mb char as this is handled below.
190 /* Eat multiple '/' or '\\' */
191 while (IS_DIRECTORY_SEP(*s
)) {
194 if ((d
!= destname
) && (*s
!= '\0')) {
195 /* We only care about non-leading or trailing '/' or '\\' */
199 start_of_name_component
= True
;
203 if (start_of_name_component
) {
204 if ((s
[0] == '.') && (s
[1] == '.') && (IS_DIRECTORY_SEP(s
[2]) || s
[2] == '\0')) {
205 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
208 * No mb char starts with '.' so we're safe checking the directory separator here.
211 /* If we just added a '/' - delete it */
212 if ((d
> destname
) && (*(d
-1) == '/')) {
217 /* Are we at the start ? Can't go back further if so. */
219 ret
= NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
222 /* Go back one level... */
223 /* We know this is safe as '/' cannot be part of a mb sequence. */
224 /* NOTE - if this assumption is invalid we are not in good shape... */
225 /* Decrement d first as d points to the *next* char to write into. */
226 for (d
--; d
> destname
; d
--) {
230 s
+= 2; /* Else go past the .. */
231 /* We're still at the start of a name component, just the previous one. */
233 if (num_bad_components
) {
234 /* Hmmm. Should we only decrement the bad_components if
235 we're removing a bad component ? Need to check this. JRA. */
236 num_bad_components
--;
241 } else if ((s
[0] == '.') && ((s
[1] == '\0') || IS_DIRECTORY_SEP(s
[1]))) {
242 /* Component of pathname can't be "." only. */
243 ret
= NT_STATUS_OBJECT_NAME_INVALID
;
244 num_bad_components
++;
252 return NT_STATUS_OBJECT_NAME_INVALID
;
254 if (!*p_contains_wcard
) {
261 *p_contains_wcard
= True
;
269 switch(next_mb_char_size(s
)) {
283 DEBUG(0,("check_path_syntax_wcard: character length assumptions invalid !\n"));
285 return NT_STATUS_INVALID_PARAMETER
;
288 if (start_of_name_component
&& num_bad_components
) {
289 num_bad_components
++;
291 start_of_name_component
= False
;
294 if (NT_STATUS_EQUAL(ret
, NT_STATUS_OBJECT_NAME_INVALID
)) {
295 /* For some strange reason being called from findfirst changes
296 the num_components number to cause the error return to change. JRA. */
297 if (num_bad_components
> 2) {
298 ret
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
306 /****************************************************************************
307 Check the path for a POSIX client.
308 We're assuming here that '/' is not the second byte in any multibyte char
309 set (a safe assumption).
310 ****************************************************************************/
312 NTSTATUS
check_path_syntax_posix(pstring destname
, const pstring srcname
)
315 const char *s
= srcname
;
316 NTSTATUS ret
= NT_STATUS_OK
;
317 BOOL start_of_name_component
= True
;
322 * Safe to assume is not the second part of a mb char as this is handled below.
324 /* Eat multiple '/' or '\\' */
328 if ((d
!= destname
) && (*s
!= '\0')) {
329 /* We only care about non-leading or trailing '/' */
333 start_of_name_component
= True
;
337 if (start_of_name_component
) {
338 if ((s
[0] == '.') && (s
[1] == '.') && (s
[2] == '/' || s
[2] == '\0')) {
339 /* Uh oh - "/../" or "/..\0" ! */
342 * No mb char starts with '.' so we're safe checking the directory separator here.
345 /* If we just added a '/' - delete it */
346 if ((d
> destname
) && (*(d
-1) == '/')) {
351 /* Are we at the start ? Can't go back further if so. */
353 ret
= NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
356 /* Go back one level... */
357 /* We know this is safe as '/' cannot be part of a mb sequence. */
358 /* NOTE - if this assumption is invalid we are not in good shape... */
359 /* Decrement d first as d points to the *next* char to write into. */
360 for (d
--; d
> destname
; d
--) {
364 s
+= 2; /* Else go past the .. */
367 } else if ((s
[0] == '.') && ((s
[1] == '\0') || (s
[1] == '/'))) {
377 switch(next_mb_char_size(s
)) {
391 DEBUG(0,("check_path_syntax_posix: character length assumptions invalid !\n"));
393 return NT_STATUS_INVALID_PARAMETER
;
396 start_of_name_component
= False
;
403 /****************************************************************************
404 Pull a string and check the path allowing a wilcard - provide for error return.
405 ****************************************************************************/
407 size_t srvstr_get_path_wcard(char *inbuf
, char *dest
, const char *src
, size_t dest_len
, size_t src_len
, int flags
,
408 NTSTATUS
*err
, BOOL
*contains_wcard
)
411 char *tmppath_ptr
= tmppath
;
414 SMB_ASSERT(dest_len
== sizeof(pstring
));
418 ret
= srvstr_pull_buf( inbuf
, tmppath_ptr
, src
, dest_len
, flags
);
420 ret
= srvstr_pull( inbuf
, tmppath_ptr
, src
, dest_len
, src_len
, flags
);
423 *contains_wcard
= False
;
425 if (lp_posix_pathnames()) {
426 *err
= check_path_syntax_posix(dest
, tmppath
);
428 *err
= check_path_syntax_wcard(dest
, tmppath
, contains_wcard
);
433 /****************************************************************************
434 Pull a string and check the path - provide for error return.
435 ****************************************************************************/
437 size_t srvstr_get_path(char *inbuf
, char *dest
, const char *src
, size_t dest_len
, size_t src_len
, int flags
, NTSTATUS
*err
)
440 char *tmppath_ptr
= tmppath
;
443 SMB_ASSERT(dest_len
== sizeof(pstring
));
447 ret
= srvstr_pull_buf( inbuf
, tmppath_ptr
, src
, dest_len
, flags
);
449 ret
= srvstr_pull( inbuf
, tmppath_ptr
, src
, dest_len
, src_len
, flags
);
451 if (lp_posix_pathnames()) {
452 *err
= check_path_syntax_posix(dest
, tmppath
);
454 *err
= check_path_syntax(dest
, tmppath
);
459 /****************************************************************************
460 Reply to a special message.
461 ****************************************************************************/
463 int reply_special(char *inbuf
,char *outbuf
)
466 int msg_type
= CVAL(inbuf
,0);
467 int msg_flags
= CVAL(inbuf
,1);
471 static BOOL already_got_session
= False
;
475 memset(outbuf
,'\0',smb_size
);
477 smb_setlen(outbuf
,0);
480 case 0x81: /* session request */
482 if (already_got_session
) {
483 exit_server("multiple session request not permitted");
486 SCVAL(outbuf
,0,0x82);
488 if (name_len(inbuf
+4) > 50 ||
489 name_len(inbuf
+4 + name_len(inbuf
+ 4)) > 50) {
490 DEBUG(0,("Invalid name length in session request\n"));
493 name_extract(inbuf
,4,name1
);
494 name_type
= name_extract(inbuf
,4 + name_len(inbuf
+ 4),name2
);
495 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
498 set_local_machine_name(name1
, True
);
499 set_remote_machine_name(name2
, True
);
501 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
502 get_local_machine_name(), get_remote_machine_name(),
505 if (name_type
== 'R') {
506 /* We are being asked for a pathworks session ---
508 SCVAL(outbuf
, 0,0x83);
512 /* only add the client's machine name to the list
513 of possibly valid usernames if we are operating
514 in share mode security */
515 if (lp_security() == SEC_SHARE
) {
516 add_session_user(get_remote_machine_name());
519 reload_services(True
);
522 already_got_session
= True
;
525 case 0x89: /* session keepalive request
526 (some old clients produce this?) */
527 SCVAL(outbuf
,0,SMBkeepalive
);
531 case 0x82: /* positive session response */
532 case 0x83: /* negative session response */
533 case 0x84: /* retarget session response */
534 DEBUG(0,("Unexpected session response\n"));
537 case SMBkeepalive
: /* session keepalive */
542 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
543 msg_type
, msg_flags
));
548 /****************************************************************************
550 conn POINTER CAN BE NULL HERE !
551 ****************************************************************************/
553 int reply_tcon(connection_struct
*conn
,
554 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
561 uint16 vuid
= SVAL(inbuf
,smb_uid
);
565 DATA_BLOB password_blob
;
567 START_PROFILE(SMBtcon
);
569 *service_buf
= *password
= *dev
= 0;
571 p
= smb_buf(inbuf
)+1;
572 p
+= srvstr_pull_buf(inbuf
, service_buf
, p
, sizeof(service_buf
), STR_TERMINATE
) + 1;
573 pwlen
= srvstr_pull_buf(inbuf
, password
, p
, sizeof(password
), STR_TERMINATE
) + 1;
575 p
+= srvstr_pull_buf(inbuf
, dev
, p
, sizeof(dev
), STR_TERMINATE
) + 1;
577 p
= strrchr_m(service_buf
,'\\');
581 service
= service_buf
;
584 password_blob
= data_blob(password
, pwlen
+1);
586 conn
= make_connection(service
,password_blob
,dev
,vuid
,&nt_status
);
588 data_blob_clear_free(&password_blob
);
591 END_PROFILE(SMBtcon
);
592 return ERROR_NT(nt_status
);
595 outsize
= set_message(outbuf
,2,0,True
);
596 SSVAL(outbuf
,smb_vwv0
,max_recv
);
597 SSVAL(outbuf
,smb_vwv1
,conn
->cnum
);
598 SSVAL(outbuf
,smb_tid
,conn
->cnum
);
600 DEBUG(3,("tcon service=%s cnum=%d\n",
601 service
, conn
->cnum
));
603 END_PROFILE(SMBtcon
);
607 /****************************************************************************
608 Reply to a tcon and X.
609 conn POINTER CAN BE NULL HERE !
610 ****************************************************************************/
612 int reply_tcon_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
617 /* what the cleint thinks the device is */
618 fstring client_devicetype
;
619 /* what the server tells the client the share represents */
620 const char *server_devicetype
;
622 uint16 vuid
= SVAL(inbuf
,smb_uid
);
623 int passlen
= SVAL(inbuf
,smb_vwv3
);
627 START_PROFILE(SMBtconX
);
629 *service
= *client_devicetype
= 0;
631 /* we might have to close an old one */
632 if ((SVAL(inbuf
,smb_vwv2
) & 0x1) && conn
) {
633 close_cnum(conn
,vuid
);
636 if (passlen
> MAX_PASS_LEN
) {
637 return ERROR_DOS(ERRDOS
,ERRbuftoosmall
);
640 if (global_encrypted_passwords_negotiated
) {
641 password
= data_blob(smb_buf(inbuf
),passlen
);
643 password
= data_blob(smb_buf(inbuf
),passlen
+1);
644 /* Ensure correct termination */
645 password
.data
[passlen
]=0;
648 p
= smb_buf(inbuf
) + passlen
;
649 p
+= srvstr_pull_buf(inbuf
, path
, p
, sizeof(path
), STR_TERMINATE
);
652 * the service name can be either: \\server\share
653 * or share directly like on the DELL PowerVault 705
656 q
= strchr_m(path
+2,'\\');
658 END_PROFILE(SMBtconX
);
659 return(ERROR_DOS(ERRDOS
,ERRnosuchshare
));
661 fstrcpy(service
,q
+1);
664 fstrcpy(service
,path
);
666 p
+= srvstr_pull(inbuf
, client_devicetype
, p
, sizeof(client_devicetype
), 6, STR_ASCII
);
668 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype
, service
));
670 conn
= make_connection(service
,password
,client_devicetype
,vuid
,&nt_status
);
672 data_blob_clear_free(&password
);
675 END_PROFILE(SMBtconX
);
676 return ERROR_NT(nt_status
);
680 server_devicetype
= "IPC";
681 else if ( IS_PRINT(conn
) )
682 server_devicetype
= "LPT1:";
684 server_devicetype
= "A:";
686 if (Protocol
< PROTOCOL_NT1
) {
687 set_message(outbuf
,2,0,True
);
689 p
+= srvstr_push(outbuf
, p
, server_devicetype
, -1,
690 STR_TERMINATE
|STR_ASCII
);
691 set_message_end(outbuf
,p
);
693 /* NT sets the fstype of IPC$ to the null string */
694 const char *fstype
= IS_IPC(conn
) ? "" : lp_fstype(SNUM(conn
));
696 set_message(outbuf
,3,0,True
);
699 p
+= srvstr_push(outbuf
, p
, server_devicetype
, -1,
700 STR_TERMINATE
|STR_ASCII
);
701 p
+= srvstr_push(outbuf
, p
, fstype
, -1,
704 set_message_end(outbuf
,p
);
706 /* what does setting this bit do? It is set by NT4 and
707 may affect the ability to autorun mounted cdroms */
708 SSVAL(outbuf
, smb_vwv2
, SMB_SUPPORT_SEARCH_BITS
|
709 (lp_csc_policy(SNUM(conn
)) << 2));
711 init_dfsroot(conn
, inbuf
, outbuf
);
715 DEBUG(3,("tconX service=%s \n",
718 /* set the incoming and outgoing tid to the just created one */
719 SSVAL(inbuf
,smb_tid
,conn
->cnum
);
720 SSVAL(outbuf
,smb_tid
,conn
->cnum
);
722 END_PROFILE(SMBtconX
);
723 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
726 /****************************************************************************
727 Reply to an unknown type.
728 ****************************************************************************/
730 int reply_unknown(char *inbuf
,char *outbuf
)
733 type
= CVAL(inbuf
,smb_com
);
735 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
736 smb_fn_name(type
), type
, type
));
738 return(ERROR_DOS(ERRSRV
,ERRunknownsmb
));
741 /****************************************************************************
743 conn POINTER CAN BE NULL HERE !
744 ****************************************************************************/
746 int reply_ioctl(connection_struct
*conn
,
747 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
749 uint16 device
= SVAL(inbuf
,smb_vwv1
);
750 uint16 function
= SVAL(inbuf
,smb_vwv2
);
751 uint32 ioctl_code
= (device
<< 16) + function
;
752 int replysize
, outsize
;
754 START_PROFILE(SMBioctl
);
756 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code
));
758 switch (ioctl_code
) {
759 case IOCTL_QUERY_JOB_INFO
:
763 END_PROFILE(SMBioctl
);
764 return(ERROR_DOS(ERRSRV
,ERRnosupport
));
767 outsize
= set_message(outbuf
,8,replysize
+1,True
);
768 SSVAL(outbuf
,smb_vwv1
,replysize
); /* Total data bytes returned */
769 SSVAL(outbuf
,smb_vwv5
,replysize
); /* Data bytes this buffer */
770 SSVAL(outbuf
,smb_vwv6
,52); /* Offset to data */
771 p
= smb_buf(outbuf
) + 1; /* Allow for alignment */
773 switch (ioctl_code
) {
774 case IOCTL_QUERY_JOB_INFO
:
776 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
778 END_PROFILE(SMBioctl
);
779 return(UNIXERROR(ERRDOS
,ERRbadfid
));
781 SSVAL(p
,0,fsp
->rap_print_jobid
); /* Job number */
782 srvstr_push(outbuf
, p
+2, global_myname(), 15, STR_TERMINATE
|STR_ASCII
);
784 srvstr_push(outbuf
, p
+18, lp_servicename(SNUM(conn
)), 13, STR_TERMINATE
|STR_ASCII
);
790 END_PROFILE(SMBioctl
);
794 /****************************************************************************
796 ****************************************************************************/
798 int reply_chkpth(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
803 BOOL bad_path
= False
;
804 SMB_STRUCT_STAT sbuf
;
807 START_PROFILE(SMBchkpth
);
809 srvstr_get_path(inbuf
, name
, smb_buf(inbuf
) + 1, sizeof(name
), 0, STR_TERMINATE
, &status
);
810 if (!NT_STATUS_IS_OK(status
)) {
811 END_PROFILE(SMBchkpth
);
812 return ERROR_NT(status
);
815 RESOLVE_DFSPATH(name
, conn
, inbuf
, outbuf
);
817 unix_convert(name
,conn
,0,&bad_path
,&sbuf
);
819 END_PROFILE(SMBchkpth
);
820 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
823 if (check_name(name
,conn
)) {
824 if (VALID_STAT(sbuf
) || SMB_VFS_STAT(conn
,name
,&sbuf
) == 0)
825 if (!(ok
= S_ISDIR(sbuf
.st_mode
))) {
826 END_PROFILE(SMBchkpth
);
827 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY
,ERRDOS
,ERRbadpath
);
832 /* We special case this - as when a Windows machine
833 is parsing a path is steps through the components
834 one at a time - if a component fails it expects
835 ERRbadpath, not ERRbadfile.
837 if(errno
== ENOENT
) {
839 * Windows returns different error codes if
840 * the parent directory is valid but not the
841 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
842 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
843 * if the path is invalid. This is different from set_bad_path_error()
844 * in the non-NT error case.
846 END_PROFILE(SMBchkpth
);
847 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND
,ERRDOS
,ERRbadpath
);
850 END_PROFILE(SMBchkpth
);
851 return(UNIXERROR(ERRDOS
,ERRbadpath
));
854 outsize
= set_message(outbuf
,0,0,False
);
855 DEBUG(3,("chkpth %s mode=%d\n", name
, (int)SVAL(inbuf
,smb_vwv0
)));
857 END_PROFILE(SMBchkpth
);
861 /****************************************************************************
863 ****************************************************************************/
865 int reply_getatr(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
869 SMB_STRUCT_STAT sbuf
;
874 BOOL bad_path
= False
;
878 START_PROFILE(SMBgetatr
);
880 p
= smb_buf(inbuf
) + 1;
881 p
+= srvstr_get_path(inbuf
, fname
, p
, sizeof(fname
), 0, STR_TERMINATE
, &status
);
882 if (!NT_STATUS_IS_OK(status
)) {
883 END_PROFILE(SMBgetatr
);
884 return ERROR_NT(status
);
887 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
889 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
890 under WfWg - weird! */
892 mode
= aHIDDEN
| aDIR
;
893 if (!CAN_WRITE(conn
))
899 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
901 END_PROFILE(SMBgetatr
);
902 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
904 if (check_name(fname
,conn
)) {
905 if (VALID_STAT(sbuf
) || SMB_VFS_STAT(conn
,fname
,&sbuf
) == 0) {
906 mode
= dos_mode(conn
,fname
,&sbuf
);
908 mtime
= sbuf
.st_mtime
;
913 DEBUG(3,("stat of %s failed (%s)\n",fname
,strerror(errno
)));
919 END_PROFILE(SMBgetatr
);
920 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadfile
);
923 outsize
= set_message(outbuf
,10,0,True
);
925 SSVAL(outbuf
,smb_vwv0
,mode
);
926 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
927 srv_put_dos_date3(outbuf
,smb_vwv1
,mtime
& ~1);
929 srv_put_dos_date3(outbuf
,smb_vwv1
,mtime
);
931 SIVAL(outbuf
,smb_vwv3
,(uint32
)size
);
933 if (Protocol
>= PROTOCOL_NT1
) {
934 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
, smb_flg2
) | FLAGS2_IS_LONG_NAME
);
937 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname
, mode
, (uint32
)size
) );
939 END_PROFILE(SMBgetatr
);
943 /****************************************************************************
945 ****************************************************************************/
947 int reply_setatr(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
954 SMB_STRUCT_STAT sbuf
;
955 BOOL bad_path
= False
;
959 START_PROFILE(SMBsetatr
);
961 p
= smb_buf(inbuf
) + 1;
962 p
+= srvstr_get_path(inbuf
, fname
, p
, sizeof(fname
), 0, STR_TERMINATE
, &status
);
963 if (!NT_STATUS_IS_OK(status
)) {
964 END_PROFILE(SMBsetatr
);
965 return ERROR_NT(status
);
968 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
970 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
972 END_PROFILE(SMBsetatr
);
973 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
976 mode
= SVAL(inbuf
,smb_vwv0
);
977 mtime
= srv_make_unix_date3(inbuf
+smb_vwv1
);
979 if (mode
!= FILE_ATTRIBUTE_NORMAL
) {
980 if (VALID_STAT_OF_DIR(sbuf
))
985 if (check_name(fname
,conn
)) {
986 ok
= (file_set_dosmode(conn
,fname
,mode
,&sbuf
,False
) == 0);
993 ok
= set_filetime(conn
,fname
,mtime
);
996 END_PROFILE(SMBsetatr
);
997 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRnoaccess
);
1000 outsize
= set_message(outbuf
,0,0,False
);
1002 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname
, mode
) );
1004 END_PROFILE(SMBsetatr
);
1008 /****************************************************************************
1010 ****************************************************************************/
1012 int reply_dskattr(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1015 SMB_BIG_UINT dfree
,dsize
,bsize
;
1016 START_PROFILE(SMBdskattr
);
1018 if (get_dfree_info(conn
,".",True
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
1019 END_PROFILE(SMBdskattr
);
1020 return(UNIXERROR(ERRHRD
,ERRgeneral
));
1023 outsize
= set_message(outbuf
,5,0,True
);
1025 if (Protocol
<= PROTOCOL_LANMAN2
) {
1026 double total_space
, free_space
;
1027 /* we need to scale this to a number that DOS6 can handle. We
1028 use floating point so we can handle large drives on systems
1029 that don't have 64 bit integers
1031 we end up displaying a maximum of 2G to DOS systems
1033 total_space
= dsize
* (double)bsize
;
1034 free_space
= dfree
* (double)bsize
;
1036 dsize
= (total_space
+63*512) / (64*512);
1037 dfree
= (free_space
+63*512) / (64*512);
1039 if (dsize
> 0xFFFF) dsize
= 0xFFFF;
1040 if (dfree
> 0xFFFF) dfree
= 0xFFFF;
1042 SSVAL(outbuf
,smb_vwv0
,dsize
);
1043 SSVAL(outbuf
,smb_vwv1
,64); /* this must be 64 for dos systems */
1044 SSVAL(outbuf
,smb_vwv2
,512); /* and this must be 512 */
1045 SSVAL(outbuf
,smb_vwv3
,dfree
);
1047 SSVAL(outbuf
,smb_vwv0
,dsize
);
1048 SSVAL(outbuf
,smb_vwv1
,bsize
/512);
1049 SSVAL(outbuf
,smb_vwv2
,512);
1050 SSVAL(outbuf
,smb_vwv3
,dfree
);
1053 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree
));
1055 END_PROFILE(SMBdskattr
);
1059 /****************************************************************************
1061 Can be called from SMBsearch, SMBffirst or SMBfunique.
1062 ****************************************************************************/
1064 int reply_search(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1074 unsigned int numentries
= 0;
1075 unsigned int maxentries
= 0;
1076 BOOL finished
= False
;
1083 BOOL check_descend
= False
;
1084 BOOL expect_close
= False
;
1085 BOOL can_open
= True
;
1086 BOOL bad_path
= False
;
1088 BOOL mask_contains_wcard
= False
;
1089 BOOL allow_long_path_components
= (SVAL(inbuf
,smb_flg2
) & FLAGS2_LONG_PATH_COMPONENTS
) ? True
: False
;
1091 START_PROFILE(SMBsearch
);
1093 if (lp_posix_pathnames()) {
1094 END_PROFILE(SMBsearch
);
1095 return reply_unknown(inbuf
, outbuf
);
1098 *mask
= *directory
= *fname
= 0;
1100 /* If we were called as SMBffirst then we must expect close. */
1101 if(CVAL(inbuf
,smb_com
) == SMBffirst
)
1102 expect_close
= True
;
1104 outsize
= set_message(outbuf
,1,3,True
);
1105 maxentries
= SVAL(inbuf
,smb_vwv0
);
1106 dirtype
= SVAL(inbuf
,smb_vwv1
);
1107 p
= smb_buf(inbuf
) + 1;
1108 p
+= srvstr_get_path_wcard(inbuf
, path
, p
, sizeof(path
), 0, STR_TERMINATE
, &nt_status
, &mask_contains_wcard
);
1109 if (!NT_STATUS_IS_OK(nt_status
)) {
1110 END_PROFILE(SMBsearch
);
1111 return ERROR_NT(nt_status
);
1114 RESOLVE_DFSPATH_WCARD(path
, conn
, inbuf
, outbuf
);
1117 status_len
= SVAL(p
, 0);
1120 /* dirtype &= ~aDIR; */
1122 if (status_len
== 0) {
1123 SMB_STRUCT_STAT sbuf
;
1126 pstrcpy(directory
,path
);
1128 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
1131 if (!check_name(directory
,conn
))
1134 p
= strrchr_m(dir2
,'/');
1143 p
= strrchr_m(directory
,'/');
1149 if (strlen(directory
) == 0)
1150 pstrcpy(directory
,".");
1151 memset((char *)status
,'\0',21);
1152 SCVAL(status
,0,(dirtype
& 0x1F));
1156 memcpy(status
,p
,21);
1157 status_dirtype
= CVAL(status
,0) & 0x1F;
1158 if (status_dirtype
!= (dirtype
& 0x1F))
1159 dirtype
= status_dirtype
;
1161 conn
->dirptr
= dptr_fetch(status
+12,&dptr_num
);
1164 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1165 pstrcpy(mask
, dptr_wcard(dptr_num
));
1169 p
= smb_buf(outbuf
) + 3;
1172 if (status_len
== 0) {
1173 dptr_num
= dptr_create(conn
,directory
,True
,expect_close
,SVAL(inbuf
,smb_pid
), mask
, mask_contains_wcard
, dirtype
);
1175 if(dptr_num
== -2) {
1176 END_PROFILE(SMBsearch
);
1177 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRnofids
);
1179 END_PROFILE(SMBsearch
);
1180 return ERROR_DOS(ERRDOS
,ERRnofids
);
1183 dirtype
= dptr_attr(dptr_num
);
1186 DEBUG(4,("dptr_num is %d\n",dptr_num
));
1189 if ((dirtype
&0x1F) == aVOLID
) {
1190 memcpy(p
,status
,21);
1191 make_dir_struct(p
,"???????????",volume_label(SNUM(conn
)),
1192 0,aVOLID
,0,!allow_long_path_components
);
1193 dptr_fill(p
+12,dptr_num
);
1194 if (dptr_zero(p
+12) && (status_len
==0))
1198 p
+= DIR_STRUCT_SIZE
;
1201 maxentries
= MIN(maxentries
, ((BUFFER_SIZE
- (p
- outbuf
))/DIR_STRUCT_SIZE
));
1203 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1204 conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1205 if (in_list(conn
->dirpath
, lp_dontdescend(SNUM(conn
)),True
))
1206 check_descend
= True
;
1208 for (i
=numentries
;(i
<maxentries
) && !finished
;i
++) {
1209 finished
= !get_dir_entry(conn
,mask
,dirtype
,fname
,&size
,&mode
,&date
,check_descend
);
1211 memcpy(p
,status
,21);
1212 make_dir_struct(p
,mask
,fname
,size
, mode
,date
,
1213 !allow_long_path_components
);
1214 if (!dptr_fill(p
+12,dptr_num
)) {
1218 p
+= DIR_STRUCT_SIZE
;
1228 /* If we were called as SMBffirst with smb_search_id == NULL
1229 and no entries were found then return error and close dirptr
1232 if (numentries
== 0 || !ok
) {
1233 dptr_close(&dptr_num
);
1234 } else if(ok
&& expect_close
&& status_len
== 0) {
1235 /* Close the dptr - we know it's gone */
1236 dptr_close(&dptr_num
);
1239 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1240 if(dptr_num
>= 0 && CVAL(inbuf
,smb_com
) == SMBfunique
) {
1241 dptr_close(&dptr_num
);
1244 if ((numentries
== 0) && !mask_contains_wcard
) {
1245 return ERROR_BOTH(STATUS_NO_MORE_FILES
,ERRDOS
,ERRnofiles
);
1248 SSVAL(outbuf
,smb_vwv0
,numentries
);
1249 SSVAL(outbuf
,smb_vwv1
,3 + numentries
* DIR_STRUCT_SIZE
);
1250 SCVAL(smb_buf(outbuf
),0,5);
1251 SSVAL(smb_buf(outbuf
),1,numentries
*DIR_STRUCT_SIZE
);
1253 /* The replies here are never long name. */
1254 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
, smb_flg2
) & (~FLAGS2_IS_LONG_NAME
));
1255 if (!allow_long_path_components
) {
1256 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
, smb_flg2
) & (~FLAGS2_LONG_PATH_COMPONENTS
));
1259 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1260 SSVAL(outbuf
,smb_flg2
, (SVAL(outbuf
, smb_flg2
) & (~FLAGS2_UNICODE_STRINGS
)));
1262 outsize
+= DIR_STRUCT_SIZE
*numentries
;
1263 smb_setlen(outbuf
,outsize
- 4);
1265 if ((! *directory
) && dptr_path(dptr_num
))
1266 slprintf(directory
, sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1268 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1269 smb_fn_name(CVAL(inbuf
,smb_com
)),
1270 mask
, directory
, dirtype
, numentries
, maxentries
) );
1272 END_PROFILE(SMBsearch
);
1276 /****************************************************************************
1277 Reply to a fclose (stop directory search).
1278 ****************************************************************************/
1280 int reply_fclose(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1289 BOOL path_contains_wcard
= False
;
1291 START_PROFILE(SMBfclose
);
1293 if (lp_posix_pathnames()) {
1294 END_PROFILE(SMBfclose
);
1295 return reply_unknown(inbuf
, outbuf
);
1298 outsize
= set_message(outbuf
,1,0,True
);
1299 p
= smb_buf(inbuf
) + 1;
1300 p
+= srvstr_get_path_wcard(inbuf
, path
, p
, sizeof(path
), 0, STR_TERMINATE
, &err
, &path_contains_wcard
);
1301 if (!NT_STATUS_IS_OK(err
)) {
1302 END_PROFILE(SMBfclose
);
1303 return ERROR_NT(err
);
1306 status_len
= SVAL(p
,0);
1309 if (status_len
== 0) {
1310 END_PROFILE(SMBfclose
);
1311 return ERROR_DOS(ERRSRV
,ERRsrverror
);
1314 memcpy(status
,p
,21);
1316 if(dptr_fetch(status
+12,&dptr_num
)) {
1317 /* Close the dptr - we know it's gone */
1318 dptr_close(&dptr_num
);
1321 SSVAL(outbuf
,smb_vwv0
,0);
1323 DEBUG(3,("search close\n"));
1325 END_PROFILE(SMBfclose
);
1329 /****************************************************************************
1331 ****************************************************************************/
1333 int reply_open(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1341 SMB_STRUCT_STAT sbuf
;
1342 BOOL bad_path
= False
;
1344 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1346 uint32 dos_attr
= SVAL(inbuf
,smb_vwv1
);
1349 uint32 create_disposition
;
1350 uint32 create_options
= 0;
1352 START_PROFILE(SMBopen
);
1354 deny_mode
= SVAL(inbuf
,smb_vwv0
);
1356 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
)+1, sizeof(fname
), 0, STR_TERMINATE
, &status
);
1357 if (!NT_STATUS_IS_OK(status
)) {
1358 END_PROFILE(SMBopen
);
1359 return ERROR_NT(status
);
1362 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1364 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1366 END_PROFILE(SMBopen
);
1367 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1370 if (!map_open_params_to_ntcreate(fname
, deny_mode
, OPENX_FILE_EXISTS_OPEN
,
1371 &access_mask
, &share_mode
, &create_disposition
, &create_options
)) {
1372 END_PROFILE(SMBopen
);
1373 return ERROR_FORCE_DOS(ERRDOS
, ERRbadaccess
);
1376 fsp
= open_file_ntcreate(conn
,fname
,&sbuf
,
1386 END_PROFILE(SMBopen
);
1387 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1388 /* We have re-scheduled this call. */
1391 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRnoaccess
);
1394 size
= sbuf
.st_size
;
1395 fattr
= dos_mode(conn
,fname
,&sbuf
);
1396 mtime
= sbuf
.st_mtime
;
1399 DEBUG(3,("attempt to open a directory %s\n",fname
));
1400 close_file(fsp
,ERROR_CLOSE
);
1401 END_PROFILE(SMBopen
);
1402 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1405 outsize
= set_message(outbuf
,7,0,True
);
1406 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
1407 SSVAL(outbuf
,smb_vwv1
,fattr
);
1408 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
1409 srv_put_dos_date3(outbuf
,smb_vwv2
,mtime
& ~1);
1411 srv_put_dos_date3(outbuf
,smb_vwv2
,mtime
);
1413 SIVAL(outbuf
,smb_vwv4
,(uint32
)size
);
1414 SSVAL(outbuf
,smb_vwv6
,deny_mode
);
1416 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1417 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1420 if(EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1421 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1423 END_PROFILE(SMBopen
);
1427 /****************************************************************************
1428 Reply to an open and X.
1429 ****************************************************************************/
1431 int reply_open_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
1434 uint16 open_flags
= SVAL(inbuf
,smb_vwv2
);
1435 int deny_mode
= SVAL(inbuf
,smb_vwv3
);
1436 uint32 smb_attr
= SVAL(inbuf
,smb_vwv5
);
1437 /* Breakout the oplock request bits so we can set the
1438 reply bits separately. */
1439 int ex_oplock_request
= EXTENDED_OPLOCK_REQUEST(inbuf
);
1440 int core_oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1441 int oplock_request
= ex_oplock_request
| core_oplock_request
;
1443 int smb_sattr
= SVAL(inbuf
,smb_vwv4
);
1444 uint32 smb_time
= make_unix_date3(inbuf
+smb_vwv6
);
1446 int smb_ofun
= SVAL(inbuf
,smb_vwv8
);
1450 SMB_STRUCT_STAT sbuf
;
1452 BOOL bad_path
= False
;
1455 SMB_BIG_UINT allocation_size
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv9
);
1456 ssize_t retval
= -1;
1459 uint32 create_disposition
;
1460 uint32 create_options
= 0;
1462 START_PROFILE(SMBopenX
);
1464 /* If it's an IPC, pass off the pipe handler. */
1466 if (lp_nt_pipe_support()) {
1467 END_PROFILE(SMBopenX
);
1468 return reply_open_pipe_and_X(conn
, inbuf
,outbuf
,length
,bufsize
);
1470 END_PROFILE(SMBopenX
);
1471 return ERROR_DOS(ERRSRV
,ERRaccess
);
1475 /* XXXX we need to handle passed times, sattr and flags */
1476 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
), sizeof(fname
), 0, STR_TERMINATE
, &status
);
1477 if (!NT_STATUS_IS_OK(status
)) {
1478 END_PROFILE(SMBopenX
);
1479 return ERROR_NT(status
);
1482 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1484 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1486 END_PROFILE(SMBopenX
);
1487 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1490 if (!map_open_params_to_ntcreate(fname
, deny_mode
, smb_ofun
,
1493 &create_disposition
,
1495 END_PROFILE(SMBopenX
);
1496 return ERROR_FORCE_DOS(ERRDOS
, ERRbadaccess
);
1499 fsp
= open_file_ntcreate(conn
,fname
,&sbuf
,
1509 END_PROFILE(SMBopenX
);
1510 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1511 /* We have re-scheduled this call. */
1514 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRnoaccess
);
1517 size
= sbuf
.st_size
;
1519 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1520 if the file is truncated or created. */
1521 if (((smb_action
== FILE_WAS_CREATED
) || (smb_action
== FILE_WAS_OVERWRITTEN
)) && allocation_size
) {
1522 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
, allocation_size
);
1523 if (vfs_allocate_file_space(fsp
, fsp
->initial_allocation_size
) == -1) {
1524 close_file(fsp
,ERROR_CLOSE
);
1525 END_PROFILE(SMBopenX
);
1526 return ERROR_NT(NT_STATUS_DISK_FULL
);
1528 retval
= vfs_set_filelen(fsp
, (SMB_OFF_T
)allocation_size
);
1530 close_file(fsp
,ERROR_CLOSE
);
1531 END_PROFILE(SMBopenX
);
1532 return ERROR_NT(NT_STATUS_DISK_FULL
);
1534 size
= get_allocation_size(conn
,fsp
,&sbuf
);
1537 fattr
= dos_mode(conn
,fname
,&sbuf
);
1538 mtime
= sbuf
.st_mtime
;
1540 close_file(fsp
,ERROR_CLOSE
);
1541 END_PROFILE(SMBopenX
);
1542 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1545 /* If the caller set the extended oplock request bit
1546 and we granted one (by whatever means) - set the
1547 correct bit for extended oplock reply.
1550 if (ex_oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1551 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1554 if(ex_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1555 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1558 /* If the caller set the core oplock request bit
1559 and we granted one (by whatever means) - set the
1560 correct bit for core oplock reply.
1563 if (core_oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1564 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1567 if(core_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1568 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1571 if (open_flags
& EXTENDED_RESPONSE_REQUIRED
) {
1572 set_message(outbuf
,19,0,True
);
1574 set_message(outbuf
,15,0,True
);
1576 SSVAL(outbuf
,smb_vwv2
,fsp
->fnum
);
1577 SSVAL(outbuf
,smb_vwv3
,fattr
);
1578 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
1579 srv_put_dos_date3(outbuf
,smb_vwv4
,mtime
& ~1);
1581 srv_put_dos_date3(outbuf
,smb_vwv4
,mtime
);
1583 SIVAL(outbuf
,smb_vwv6
,(uint32
)size
);
1584 SSVAL(outbuf
,smb_vwv8
,GET_OPENX_MODE(deny_mode
));
1585 SSVAL(outbuf
,smb_vwv11
,smb_action
);
1587 if (open_flags
& EXTENDED_RESPONSE_REQUIRED
) {
1588 SIVAL(outbuf
, smb_vwv15
, STD_RIGHT_ALL_ACCESS
);
1591 END_PROFILE(SMBopenX
);
1592 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
1595 /****************************************************************************
1596 Reply to a SMBulogoffX.
1597 conn POINTER CAN BE NULL HERE !
1598 ****************************************************************************/
1600 int reply_ulogoffX(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
1602 uint16 vuid
= SVAL(inbuf
,smb_uid
);
1603 user_struct
*vuser
= get_valid_user_struct(vuid
);
1604 START_PROFILE(SMBulogoffX
);
1607 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid
));
1609 /* in user level security we are supposed to close any files
1610 open by this user */
1611 if ((vuser
!= 0) && (lp_security() != SEC_SHARE
))
1612 file_close_user(vuid
);
1614 invalidate_vuid(vuid
);
1616 set_message(outbuf
,2,0,True
);
1618 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid
) );
1620 END_PROFILE(SMBulogoffX
);
1621 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
1624 /****************************************************************************
1625 Reply to a mknew or a create.
1626 ****************************************************************************/
1628 int reply_mknew(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1633 uint32 fattr
= SVAL(inbuf
,smb_vwv0
);
1634 BOOL bad_path
= False
;
1636 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1637 SMB_STRUCT_STAT sbuf
;
1639 uint32 access_mask
= FILE_GENERIC_READ
| FILE_GENERIC_WRITE
;
1640 uint32 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
1641 uint32 create_disposition
;
1642 uint32 create_options
= 0;
1644 START_PROFILE(SMBcreate
);
1646 com
= SVAL(inbuf
,smb_com
);
1648 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
) + 1, sizeof(fname
), 0, STR_TERMINATE
, &status
);
1649 if (!NT_STATUS_IS_OK(status
)) {
1650 END_PROFILE(SMBcreate
);
1651 return ERROR_NT(status
);
1654 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1656 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1658 END_PROFILE(SMBcreate
);
1659 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1662 if (fattr
& aVOLID
) {
1663 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname
));
1666 if(com
== SMBmknew
) {
1667 /* We should fail if file exists. */
1668 create_disposition
= FILE_CREATE
;
1670 /* Create if file doesn't exist, truncate if it does. */
1671 create_disposition
= FILE_OVERWRITE_IF
;
1674 /* Open file using ntcreate. */
1675 fsp
= open_file_ntcreate(conn
,fname
,&sbuf
,
1685 END_PROFILE(SMBcreate
);
1686 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1687 /* We have re-scheduled this call. */
1690 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRnoaccess
);
1693 outsize
= set_message(outbuf
,1,0,True
);
1694 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
1696 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1697 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1700 if(EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1701 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1704 DEBUG( 2, ( "reply_mknew: file %s\n", fname
) );
1705 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname
, fsp
->fh
->fd
, (unsigned int)fattr
) );
1707 END_PROFILE(SMBcreate
);
1711 /****************************************************************************
1712 Reply to a create temporary file.
1713 ****************************************************************************/
1715 int reply_ctemp(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1719 uint32 fattr
= SVAL(inbuf
,smb_vwv0
);
1720 BOOL bad_path
= False
;
1722 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1724 SMB_STRUCT_STAT sbuf
;
1727 unsigned int namelen
;
1729 START_PROFILE(SMBctemp
);
1731 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
)+1, sizeof(fname
), 0, STR_TERMINATE
, &status
);
1732 if (!NT_STATUS_IS_OK(status
)) {
1733 END_PROFILE(SMBctemp
);
1734 return ERROR_NT(status
);
1737 pstrcat(fname
,"/TMXXXXXX");
1739 pstrcat(fname
,"TMXXXXXX");
1742 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1744 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1746 END_PROFILE(SMBctemp
);
1747 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1750 tmpfd
= smb_mkstemp(fname
);
1752 END_PROFILE(SMBctemp
);
1753 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1756 SMB_VFS_STAT(conn
,fname
,&sbuf
);
1758 /* We should fail if file does not exist. */
1759 fsp
= open_file_ntcreate(conn
,fname
,&sbuf
,
1760 FILE_GENERIC_READ
| FILE_GENERIC_WRITE
,
1761 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1768 /* close fd from smb_mkstemp() */
1772 END_PROFILE(SMBctemp
);
1773 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1774 /* We have re-scheduled this call. */
1777 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRnoaccess
);
1780 outsize
= set_message(outbuf
,1,0,True
);
1781 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
1783 /* the returned filename is relative to the directory */
1784 s
= strrchr_m(fname
, '/');
1791 p
= smb_buf(outbuf
);
1793 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
1794 thing in the byte section. JRA */
1795 SSVALS(p
, 0, -1); /* what is this? not in spec */
1797 namelen
= srvstr_push(outbuf
, p
, s
, -1, STR_ASCII
|STR_TERMINATE
);
1799 outsize
= set_message_end(outbuf
, p
);
1801 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1802 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1805 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1806 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1809 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname
) );
1810 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname
, fsp
->fh
->fd
,
1811 (unsigned int)sbuf
.st_mode
) );
1813 END_PROFILE(SMBctemp
);
1817 /*******************************************************************
1818 Check if a user is allowed to rename a file.
1819 ********************************************************************/
1821 static NTSTATUS
can_rename(connection_struct
*conn
, char *fname
, uint16 dirtype
, SMB_STRUCT_STAT
*pst
)
1826 if (!CAN_WRITE(conn
)) {
1827 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
1830 fmode
= dos_mode(conn
,fname
,pst
);
1831 if ((fmode
& ~dirtype
) & (aHIDDEN
| aSYSTEM
)) {
1832 return NT_STATUS_NO_SUCH_FILE
;
1835 if (S_ISDIR(pst
->st_mode
)) {
1836 return NT_STATUS_OK
;
1839 /* We need a better way to return NT status codes from open... */
1840 set_saved_ntstatus(NT_STATUS_OK
);
1842 fsp
= open_file_ntcreate(conn
, fname
, pst
,
1844 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1847 FILE_ATTRIBUTE_NORMAL
,
1852 NTSTATUS ret
= get_saved_ntstatus();
1853 if (!NT_STATUS_IS_OK(ret
)) {
1854 set_saved_ntstatus(NT_STATUS_OK
);
1857 set_saved_ntstatus(NT_STATUS_OK
);
1858 return NT_STATUS_ACCESS_DENIED
;
1860 close_file(fsp
,NORMAL_CLOSE
);
1861 return NT_STATUS_OK
;
1864 /*******************************************************************
1865 Check if a user is allowed to delete a file.
1866 ********************************************************************/
1868 NTSTATUS
can_delete(connection_struct
*conn
, char *fname
, uint32 dirtype
, BOOL bad_path
, BOOL check_is_at_open
)
1870 SMB_STRUCT_STAT sbuf
;
1874 DEBUG(10,("can_delete: %s, dirtype = %d\n", fname
, dirtype
));
1876 if (!CAN_WRITE(conn
)) {
1877 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
1880 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
) != 0) {
1881 if(errno
== ENOENT
) {
1883 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1885 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1888 return map_nt_error_from_unix(errno
);
1891 fattr
= dos_mode(conn
,fname
,&sbuf
);
1893 /* Can't delete a directory. */
1895 return NT_STATUS_FILE_IS_A_DIRECTORY
;
1899 else if (dirtype
& aDIR
) /* Asked for a directory and it isn't. */
1900 return NT_STATUS_OBJECT_NAME_INVALID
;
1901 #endif /* JRATEST */
1903 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
1905 On a Windows share, a file with read-only dosmode can be opened with
1906 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
1907 fails with NT_STATUS_CANNOT_DELETE error.
1909 This semantic causes a problem that a user can not
1910 rename a file with read-only dosmode on a Samba share
1911 from a Windows command prompt (i.e. cmd.exe, but can rename
1912 from Windows Explorer).
1915 if (!check_is_at_open
&& !lp_delete_readonly(SNUM(conn
))) {
1916 if (fattr
& aRONLY
) {
1917 return NT_STATUS_CANNOT_DELETE
;
1920 if ((fattr
& ~dirtype
) & (aHIDDEN
| aSYSTEM
)) {
1921 return NT_STATUS_NO_SUCH_FILE
;
1924 if (check_is_at_open
) {
1925 if (!can_delete_file_in_directory(conn
, fname
)) {
1926 return NT_STATUS_ACCESS_DENIED
;
1929 /* On open checks the open itself will check the share mode, so
1930 don't do it here as we'll get it wrong. */
1932 /* We need a better way to return NT status codes from open... */
1933 set_saved_ntstatus(NT_STATUS_OK
);
1935 fsp
= open_file_ntcreate(conn
, fname
, &sbuf
,
1940 FILE_ATTRIBUTE_NORMAL
,
1945 NTSTATUS ret
= get_saved_ntstatus();
1946 if (!NT_STATUS_IS_OK(ret
)) {
1947 set_saved_ntstatus(NT_STATUS_OK
);
1950 set_saved_ntstatus(NT_STATUS_OK
);
1951 return NT_STATUS_ACCESS_DENIED
;
1953 close_file(fsp
,NORMAL_CLOSE
);
1955 return NT_STATUS_OK
;
1958 /****************************************************************************
1959 The guts of the unlink command, split out so it may be called by the NT SMB
1961 ****************************************************************************/
1963 NTSTATUS
unlink_internals(connection_struct
*conn
, uint32 dirtype
, char *name
, BOOL has_wild
)
1969 NTSTATUS error
= NT_STATUS_OK
;
1970 BOOL bad_path
= False
;
1972 SMB_STRUCT_STAT sbuf
;
1974 *directory
= *mask
= 0;
1976 rc
= unix_convert(name
,conn
,0,&bad_path
,&sbuf
);
1978 p
= strrchr_m(name
,'/');
1980 pstrcpy(directory
,".");
1984 pstrcpy(directory
,name
);
1989 * We should only check the mangled cache
1990 * here if unix_convert failed. This means
1991 * that the path in 'mask' doesn't exist
1992 * on the file system and so we need to look
1993 * for a possible mangle. This patch from
1994 * Tine Smukavec <valentin.smukavec@hermes.si>.
1997 if (!rc
&& mangle_is_mangled(mask
,SNUM(conn
)))
1998 mangle_check_cache( mask
, sizeof(pstring
)-1, SNUM(conn
));
2001 pstrcat(directory
,"/");
2002 pstrcat(directory
,mask
);
2003 error
= can_delete(conn
,directory
,dirtype
,bad_path
,False
);
2004 if (!NT_STATUS_IS_OK(error
))
2007 if (SMB_VFS_UNLINK(conn
,directory
) == 0) {
2011 struct smb_Dir
*dir_hnd
= NULL
;
2014 if (strequal(mask
,"????????.???"))
2017 if (check_name(directory
,conn
))
2018 dir_hnd
= OpenDir(conn
, directory
, mask
, dirtype
);
2020 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2021 the pattern matches against the long name, otherwise the short name
2022 We don't implement this yet XXXX
2027 error
= NT_STATUS_NO_SUCH_FILE
;
2029 while ((dname
= ReadDirName(dir_hnd
, &offset
))) {
2032 BOOL sys_direntry
= False
;
2033 pstrcpy(fname
,dname
);
2035 if (!is_visible_file(conn
, directory
, dname
, &st
, True
)) {
2039 /* Quick check for "." and ".." */
2040 if (fname
[0] == '.') {
2041 if (!fname
[1] || (fname
[1] == '.' && !fname
[2])) {
2042 if ((dirtype
& FILE_ATTRIBUTE_DIRECTORY
) && (dirtype
& FILE_ATTRIBUTE_SYSTEM
)) {
2043 sys_direntry
= True
;
2050 if(!mask_match(fname
, mask
, conn
->case_sensitive
))
2054 error
= NT_STATUS_OBJECT_NAME_INVALID
;
2055 DEBUG(3,("unlink_internals: system directory delete denied [%s] mask [%s]\n",
2060 slprintf(fname
,sizeof(fname
)-1, "%s/%s",directory
,dname
);
2061 error
= can_delete(conn
,fname
,dirtype
,bad_path
,False
);
2062 if (!NT_STATUS_IS_OK(error
)) {
2065 if (SMB_VFS_UNLINK(conn
,fname
) == 0)
2067 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname
));
2073 if (count
== 0 && NT_STATUS_IS_OK(error
)) {
2074 error
= map_nt_error_from_unix(errno
);
2080 /****************************************************************************
2082 ****************************************************************************/
2084 int reply_unlink(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
,
2091 BOOL path_contains_wcard
= False
;
2093 START_PROFILE(SMBunlink
);
2095 dirtype
= SVAL(inbuf
,smb_vwv0
);
2097 srvstr_get_path_wcard(inbuf
, name
, smb_buf(inbuf
) + 1, sizeof(name
), 0, STR_TERMINATE
, &status
, &path_contains_wcard
);
2098 if (!NT_STATUS_IS_OK(status
)) {
2099 END_PROFILE(SMBunlink
);
2100 return ERROR_NT(status
);
2103 RESOLVE_DFSPATH_WCARD(name
, conn
, inbuf
, outbuf
);
2105 DEBUG(3,("reply_unlink : %s\n",name
));
2107 status
= unlink_internals(conn
, dirtype
, name
, path_contains_wcard
);
2108 if (!NT_STATUS_IS_OK(status
)) {
2109 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
2110 /* We have re-scheduled this call. */
2113 return ERROR_NT(status
);
2117 * Win2k needs a changenotify request response before it will
2118 * update after a rename..
2120 process_pending_change_notify_queue((time_t)0);
2122 outsize
= set_message(outbuf
,0,0,False
);
2124 END_PROFILE(SMBunlink
);
2128 /****************************************************************************
2130 ****************************************************************************/
2132 static void fail_readraw(void)
2135 slprintf(errstr
, sizeof(errstr
)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
2137 exit_server(errstr
);
2140 #if defined(WITH_SENDFILE)
2141 /****************************************************************************
2142 Fake (read/write) sendfile. Returns -1 on read or write fail.
2143 ****************************************************************************/
2145 static ssize_t
fake_sendfile(files_struct
*fsp
, SMB_OFF_T startpos
, size_t nread
, char *buf
, int bufsize
)
2149 /* Paranioa check... */
2150 if (nread
> bufsize
) {
2155 ret
= read_file(fsp
,buf
,startpos
,nread
);
2161 /* If we had a short read, fill with zeros. */
2163 memset(buf
, '\0', nread
- ret
);
2166 if (write_data(smbd_server_fd(),buf
,nread
) != nread
) {
2170 return (ssize_t
)nread
;
2174 /****************************************************************************
2175 Use sendfile in readbraw.
2176 ****************************************************************************/
2178 void send_file_readbraw(connection_struct
*conn
, files_struct
*fsp
, SMB_OFF_T startpos
, size_t nread
,
2179 ssize_t mincount
, char *outbuf
, int out_buffsize
)
2183 #if defined(WITH_SENDFILE)
2185 * We can only use sendfile on a non-chained packet
2186 * but we can use on a non-oplocked file. tridge proved this
2187 * on a train in Germany :-). JRA.
2188 * reply_readbraw has already checked the length.
2191 if ( (chain_size
== 0) && (nread
> 0) &&
2192 (fsp
->wcp
== NULL
) && lp_use_sendfile(SNUM(conn
)) ) {
2195 _smb_setlen(outbuf
,nread
);
2196 header
.data
= (uint8
*)outbuf
;
2200 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp
, fsp
->fh
->fd
, &header
, startpos
, nread
) == -1) {
2201 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2202 if (errno
== ENOSYS
) {
2203 goto normal_readbraw
;
2207 * Special hack for broken Linux with no working sendfile. If we
2208 * return EINTR we sent the header but not the rest of the data.
2209 * Fake this up by doing read/write calls.
2211 if (errno
== EINTR
) {
2212 /* Ensure we don't do this again. */
2213 set_use_sendfile(SNUM(conn
), False
);
2214 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2216 if (fake_sendfile(fsp
, startpos
, nread
, outbuf
+ 4, out_buffsize
- 4) == -1) {
2217 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2218 fsp
->fsp_name
, strerror(errno
) ));
2219 exit_server("send_file_readbraw fake_sendfile failed");
2224 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2225 fsp
->fsp_name
, strerror(errno
) ));
2226 exit_server("send_file_readbraw sendfile failed");
2236 ret
= read_file(fsp
,outbuf
+4,startpos
,nread
);
2237 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2246 _smb_setlen(outbuf
,ret
);
2247 if (write_data(smbd_server_fd(),outbuf
,4+ret
) != 4+ret
)
2251 /****************************************************************************
2252 Reply to a readbraw (core+ protocol).
2253 ****************************************************************************/
2255 int reply_readbraw(connection_struct
*conn
, char *inbuf
, char *outbuf
, int dum_size
, int out_buffsize
)
2257 ssize_t maxcount
,mincount
;
2260 char *header
= outbuf
;
2262 START_PROFILE(SMBreadbraw
);
2264 if (srv_is_signing_active()) {
2265 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
2269 * Special check if an oplock break has been issued
2270 * and the readraw request croses on the wire, we must
2271 * return a zero length response here.
2274 fsp
= file_fsp(inbuf
,smb_vwv0
);
2276 if (!FNUM_OK(fsp
,conn
) || !fsp
->can_read
) {
2278 * fsp could be NULL here so use the value from the packet. JRA.
2280 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf
,smb_vwv0
)));
2281 _smb_setlen(header
,0);
2282 if (write_data(smbd_server_fd(),header
,4) != 4)
2284 END_PROFILE(SMBreadbraw
);
2288 CHECK_FSP(fsp
,conn
);
2290 flush_write_cache(fsp
, READRAW_FLUSH
);
2292 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv1
);
2293 if(CVAL(inbuf
,smb_wct
) == 10) {
2295 * This is a large offset (64 bit) read.
2297 #ifdef LARGE_SMB_OFF_T
2299 startpos
|= (((SMB_OFF_T
)IVAL(inbuf
,smb_vwv8
)) << 32);
2301 #else /* !LARGE_SMB_OFF_T */
2304 * Ensure we haven't been sent a >32 bit offset.
2307 if(IVAL(inbuf
,smb_vwv8
) != 0) {
2308 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
2309 64 bit offsets.\n", (unsigned int)IVAL(inbuf
,smb_vwv8
) ));
2310 _smb_setlen(header
,0);
2311 if (write_data(smbd_server_fd(),header
,4) != 4)
2313 END_PROFILE(SMBreadbraw
);
2317 #endif /* LARGE_SMB_OFF_T */
2320 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos
));
2321 _smb_setlen(header
,0);
2322 if (write_data(smbd_server_fd(),header
,4) != 4)
2324 END_PROFILE(SMBreadbraw
);
2328 maxcount
= (SVAL(inbuf
,smb_vwv3
) & 0xFFFF);
2329 mincount
= (SVAL(inbuf
,smb_vwv4
) & 0xFFFF);
2331 /* ensure we don't overrun the packet size */
2332 maxcount
= MIN(65535,maxcount
);
2334 if (!is_locked(fsp
,(SMB_BIG_UINT
)maxcount
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
2338 if (SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
,&st
) == 0) {
2342 if (startpos
>= size
) {
2345 nread
= MIN(maxcount
,(size
- startpos
));
2349 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2350 if (nread
< mincount
)
2354 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp
->fnum
, (double)startpos
,
2355 (unsigned long)maxcount
, (unsigned long)mincount
, (unsigned long)nread
) );
2357 send_file_readbraw(conn
, fsp
, startpos
, nread
, mincount
, outbuf
, out_buffsize
);
2359 DEBUG(5,("readbraw finished\n"));
2360 END_PROFILE(SMBreadbraw
);
2365 #define DBGC_CLASS DBGC_LOCKING
2367 /****************************************************************************
2368 Reply to a lockread (core+ protocol).
2369 ****************************************************************************/
2371 int reply_lockread(connection_struct
*conn
, char *inbuf
,char *outbuf
, int length
, int dum_buffsiz
)
2379 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2380 BOOL my_lock_ctx
= False
;
2381 START_PROFILE(SMBlockread
);
2383 CHECK_FSP(fsp
,conn
);
2384 if (!CHECK_READ(fsp
,inbuf
)) {
2385 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2388 release_level_2_oplocks_on_change(fsp
);
2390 numtoread
= SVAL(inbuf
,smb_vwv1
);
2391 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2393 outsize
= set_message(outbuf
,5,3,True
);
2394 numtoread
= MIN(BUFFER_SIZE
-outsize
,numtoread
);
2395 data
= smb_buf(outbuf
) + 3;
2398 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2399 * protocol request that predates the read/write lock concept.
2400 * Thus instead of asking for a read lock here we need to ask
2401 * for a write lock. JRA.
2402 * Note that the requested lock size is unaffected by max_recv.
2405 status
= do_lock_spin(fsp
,
2406 SVAL(inbuf
,smb_pid
),
2407 (SMB_BIG_UINT
)numtoread
,
2408 (SMB_BIG_UINT
)startpos
,
2413 if (NT_STATUS_V(status
)) {
2416 * We used to make lockread a blocking lock. It turns out
2417 * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
2421 if (lp_blocking_locks(SNUM(conn
)) && !my_lock_ctx
&& ERROR_WAS_LOCK_DENIED(status
)) {
2423 * A blocking lock was requested. Package up
2424 * this smb into a queued request and push it
2425 * onto the blocking lock queue.
2427 if(push_blocking_lock_request(inbuf
, length
,
2431 SVAL(inbuf
,smb_pid
),
2434 (SMB_BIG_UINT
)startpos
,
2435 (SMB_BIG_UINT
)numtoread
)) {
2436 END_PROFILE(SMBlockread
);
2441 END_PROFILE(SMBlockread
);
2442 return ERROR_NT(status
);
2446 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2449 if (numtoread
> max_recv
) {
2450 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2451 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2452 (unsigned int)numtoread
, (unsigned int)max_recv
));
2453 numtoread
= MIN(numtoread
,max_recv
);
2455 nread
= read_file(fsp
,data
,startpos
,numtoread
);
2458 END_PROFILE(SMBlockread
);
2459 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2463 SSVAL(outbuf
,smb_vwv0
,nread
);
2464 SSVAL(outbuf
,smb_vwv5
,nread
+3);
2465 SSVAL(smb_buf(outbuf
),1,nread
);
2467 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2468 fsp
->fnum
, (int)numtoread
, (int)nread
));
2470 END_PROFILE(SMBlockread
);
2475 #define DBGC_CLASS DBGC_ALL
2477 /****************************************************************************
2479 ****************************************************************************/
2481 int reply_read(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
2488 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2489 START_PROFILE(SMBread
);
2491 CHECK_FSP(fsp
,conn
);
2492 if (!CHECK_READ(fsp
,inbuf
)) {
2493 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2496 numtoread
= SVAL(inbuf
,smb_vwv1
);
2497 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2499 outsize
= set_message(outbuf
,5,3,True
);
2500 numtoread
= MIN(BUFFER_SIZE
-outsize
,numtoread
);
2502 * The requested read size cannot be greater than max_recv. JRA.
2504 if (numtoread
> max_recv
) {
2505 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
2506 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2507 (unsigned int)numtoread
, (unsigned int)max_recv
));
2508 numtoread
= MIN(numtoread
,max_recv
);
2511 data
= smb_buf(outbuf
) + 3;
2513 if (is_locked(fsp
,(SMB_BIG_UINT
)numtoread
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
2514 END_PROFILE(SMBread
);
2515 return ERROR_DOS(ERRDOS
,ERRlock
);
2519 nread
= read_file(fsp
,data
,startpos
,numtoread
);
2522 END_PROFILE(SMBread
);
2523 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2527 SSVAL(outbuf
,smb_vwv0
,nread
);
2528 SSVAL(outbuf
,smb_vwv5
,nread
+3);
2529 SCVAL(smb_buf(outbuf
),0,1);
2530 SSVAL(smb_buf(outbuf
),1,nread
);
2532 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2533 fsp
->fnum
, (int)numtoread
, (int)nread
) );
2535 END_PROFILE(SMBread
);
2539 /****************************************************************************
2540 Reply to a read and X - possibly using sendfile.
2541 ****************************************************************************/
2543 int send_file_readX(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
, int len_outbuf
,
2544 files_struct
*fsp
, SMB_OFF_T startpos
, size_t smb_maxcnt
)
2548 char *data
= smb_buf(outbuf
);
2550 #if defined(WITH_SENDFILE)
2552 * We can only use sendfile on a non-chained packet
2553 * but we can use on a non-oplocked file. tridge proved this
2554 * on a train in Germany :-). JRA.
2557 if ((chain_size
== 0) && (CVAL(inbuf
,smb_vwv0
) == 0xFF) &&
2558 lp_use_sendfile(SNUM(conn
)) && (fsp
->wcp
== NULL
) ) {
2559 SMB_STRUCT_STAT sbuf
;
2562 if(SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
, &sbuf
) == -1)
2563 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2565 if (startpos
> sbuf
.st_size
)
2568 if (smb_maxcnt
> (sbuf
.st_size
- startpos
))
2569 smb_maxcnt
= (sbuf
.st_size
- startpos
);
2571 if (smb_maxcnt
== 0)
2575 * Set up the packet header before send. We
2576 * assume here the sendfile will work (get the
2577 * correct amount of data).
2580 SSVAL(outbuf
,smb_vwv2
,0xFFFF); /* Remaining - must be -1. */
2581 SSVAL(outbuf
,smb_vwv5
,smb_maxcnt
);
2582 SSVAL(outbuf
,smb_vwv6
,smb_offset(data
,outbuf
));
2583 SSVAL(outbuf
,smb_vwv7
,((smb_maxcnt
>> 16) & 1));
2584 SSVAL(smb_buf(outbuf
),-2,smb_maxcnt
);
2585 SCVAL(outbuf
,smb_vwv0
,0xFF);
2586 set_message(outbuf
,12,smb_maxcnt
,False
);
2587 header
.data
= (uint8
*)outbuf
;
2588 header
.length
= data
- outbuf
;
2591 if ((nread
= SMB_VFS_SENDFILE( smbd_server_fd(), fsp
, fsp
->fh
->fd
, &header
, startpos
, smb_maxcnt
)) == -1) {
2592 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2593 if (errno
== ENOSYS
) {
2598 * Special hack for broken Linux with no working sendfile. If we
2599 * return EINTR we sent the header but not the rest of the data.
2600 * Fake this up by doing read/write calls.
2603 if (errno
== EINTR
) {
2604 /* Ensure we don't do this again. */
2605 set_use_sendfile(SNUM(conn
), False
);
2606 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
2608 if ((nread
= fake_sendfile(fsp
, startpos
, smb_maxcnt
, data
,
2609 len_outbuf
- (data
-outbuf
))) == -1) {
2610 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2611 fsp
->fsp_name
, strerror(errno
) ));
2612 exit_server("send_file_readX: fake_sendfile failed");
2614 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
2615 fsp
->fnum
, (int)smb_maxcnt
, (int)nread
) );
2616 /* Returning -1 here means successful sendfile. */
2620 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2621 fsp
->fsp_name
, strerror(errno
) ));
2622 exit_server("send_file_readX sendfile failed");
2625 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2626 fsp
->fnum
, (int)smb_maxcnt
, (int)nread
) );
2627 /* Returning -1 here means successful sendfile. */
2635 nread
= read_file(fsp
,data
,startpos
,smb_maxcnt
);
2638 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2641 outsize
= set_message(outbuf
,12,nread
,False
);
2642 SSVAL(outbuf
,smb_vwv2
,0xFFFF); /* Remaining - must be -1. */
2643 SSVAL(outbuf
,smb_vwv5
,nread
);
2644 SSVAL(outbuf
,smb_vwv6
,smb_offset(data
,outbuf
));
2645 SSVAL(outbuf
,smb_vwv7
,((nread
>> 16) & 1));
2646 SSVAL(smb_buf(outbuf
),-2,nread
);
2648 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2649 fsp
->fnum
, (int)smb_maxcnt
, (int)nread
) );
2651 /* Returning the number of bytes we want to send back - including header. */
2655 /****************************************************************************
2656 Reply to a read and X.
2657 ****************************************************************************/
2659 int reply_read_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
2661 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv2
);
2662 SMB_OFF_T startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
2664 size_t smb_maxcnt
= SVAL(inbuf
,smb_vwv5
);
2666 size_t smb_mincnt
= SVAL(inbuf
,smb_vwv6
);
2669 START_PROFILE(SMBreadX
);
2671 /* If it's an IPC, pass off the pipe handler. */
2673 END_PROFILE(SMBreadX
);
2674 return reply_pipe_read_and_X(inbuf
,outbuf
,length
,bufsize
);
2677 CHECK_FSP(fsp
,conn
);
2678 if (!CHECK_READ(fsp
,inbuf
)) {
2679 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2682 set_message(outbuf
,12,0,True
);
2684 if (global_client_caps
& CAP_LARGE_READX
) {
2685 if (SVAL(inbuf
,smb_vwv7
) == 1) {
2686 smb_maxcnt
|= (1<<16);
2688 if (smb_maxcnt
> BUFFER_SIZE
) {
2689 DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n",
2690 (unsigned int)smb_maxcnt
, (unsigned int)BUFFER_SIZE
));
2691 END_PROFILE(SMBreadX
);
2692 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2696 if(CVAL(inbuf
,smb_wct
) == 12) {
2697 #ifdef LARGE_SMB_OFF_T
2699 * This is a large offset (64 bit) read.
2701 startpos
|= (((SMB_OFF_T
)IVAL(inbuf
,smb_vwv10
)) << 32);
2703 #else /* !LARGE_SMB_OFF_T */
2706 * Ensure we haven't been sent a >32 bit offset.
2709 if(IVAL(inbuf
,smb_vwv10
) != 0) {
2710 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2711 64 bit offsets.\n", (unsigned int)IVAL(inbuf
,smb_vwv10
) ));
2712 END_PROFILE(SMBreadX
);
2713 return ERROR_DOS(ERRDOS
,ERRbadaccess
);
2716 #endif /* LARGE_SMB_OFF_T */
2720 if (is_locked(fsp
,(SMB_BIG_UINT
)smb_maxcnt
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
2721 END_PROFILE(SMBreadX
);
2722 return ERROR_DOS(ERRDOS
,ERRlock
);
2725 if (schedule_aio_read_and_X(conn
, inbuf
, outbuf
, length
, bufsize
, fsp
, startpos
, smb_maxcnt
)) {
2726 END_PROFILE(SMBreadX
);
2730 nread
= send_file_readX(conn
, inbuf
, outbuf
, length
, bufsize
, fsp
, startpos
, smb_maxcnt
);
2732 nread
= chain_reply(inbuf
,outbuf
,length
,bufsize
);
2734 END_PROFILE(SMBreadX
);
2738 /****************************************************************************
2739 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2740 ****************************************************************************/
2742 int reply_writebraw(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
2745 ssize_t total_written
=0;
2746 size_t numtowrite
=0;
2751 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2753 START_PROFILE(SMBwritebraw
);
2755 if (srv_is_signing_active()) {
2756 exit_server("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2759 CHECK_FSP(fsp
,conn
);
2760 if (!CHECK_WRITE(fsp
)) {
2761 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2764 tcount
= IVAL(inbuf
,smb_vwv1
);
2765 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
2766 write_through
= BITSETW(inbuf
+smb_vwv7
,0);
2768 /* We have to deal with slightly different formats depending
2769 on whether we are using the core+ or lanman1.0 protocol */
2771 if(Protocol
<= PROTOCOL_COREPLUS
) {
2772 numtowrite
= SVAL(smb_buf(inbuf
),-2);
2773 data
= smb_buf(inbuf
);
2775 numtowrite
= SVAL(inbuf
,smb_vwv10
);
2776 data
= smb_base(inbuf
) + SVAL(inbuf
, smb_vwv11
);
2779 /* force the error type */
2780 SCVAL(inbuf
,smb_com
,SMBwritec
);
2781 SCVAL(outbuf
,smb_com
,SMBwritec
);
2783 if (is_locked(fsp
,(SMB_BIG_UINT
)tcount
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
2784 END_PROFILE(SMBwritebraw
);
2785 return(ERROR_DOS(ERRDOS
,ERRlock
));
2789 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
2791 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2792 fsp
->fnum
, (double)startpos
, (int)numtowrite
, (int)nwritten
, (int)write_through
));
2794 if (nwritten
< (ssize_t
)numtowrite
) {
2795 END_PROFILE(SMBwritebraw
);
2796 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
2799 total_written
= nwritten
;
2801 /* Return a message to the redirector to tell it to send more bytes */
2802 SCVAL(outbuf
,smb_com
,SMBwritebraw
);
2803 SSVALS(outbuf
,smb_vwv0
,-1);
2804 outsize
= set_message(outbuf
,Protocol
>PROTOCOL_COREPLUS
?1:0,0,True
);
2806 if (!send_smb(smbd_server_fd(),outbuf
))
2807 exit_server("reply_writebraw: send_smb failed.");
2809 /* Now read the raw data into the buffer and write it */
2810 if (read_smb_length(smbd_server_fd(),inbuf
,SMB_SECONDARY_WAIT
) == -1) {
2811 exit_server("secondary writebraw failed");
2814 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2815 numtowrite
= smb_len(inbuf
);
2817 /* Set up outbuf to return the correct return */
2818 outsize
= set_message(outbuf
,1,0,True
);
2819 SCVAL(outbuf
,smb_com
,SMBwritec
);
2821 if (numtowrite
!= 0) {
2823 if (numtowrite
> BUFFER_SIZE
) {
2824 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2825 (unsigned int)numtowrite
));
2826 exit_server("secondary writebraw failed");
2829 if (tcount
> nwritten
+numtowrite
) {
2830 DEBUG(3,("Client overestimated the write %d %d %d\n",
2831 (int)tcount
,(int)nwritten
,(int)numtowrite
));
2834 if (read_data( smbd_server_fd(), inbuf
+4, numtowrite
) != numtowrite
) {
2835 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2837 exit_server("secondary writebraw failed");
2840 nwritten
= write_file(fsp
,inbuf
+4,startpos
+nwritten
,numtowrite
);
2842 if (nwritten
< (ssize_t
)numtowrite
) {
2843 SCVAL(outbuf
,smb_rcls
,ERRHRD
);
2844 SSVAL(outbuf
,smb_err
,ERRdiskfull
);
2848 total_written
+= nwritten
;
2851 SSVAL(outbuf
,smb_vwv0
,total_written
);
2853 sync_file(conn
, fsp
, write_through
);
2855 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2856 fsp
->fnum
, (double)startpos
, (int)numtowrite
,(int)total_written
));
2858 /* we won't return a status if write through is not selected - this follows what WfWg does */
2859 END_PROFILE(SMBwritebraw
);
2860 if (!write_through
&& total_written
==tcount
) {
2862 #if RABBIT_PELLET_FIX
2864 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2865 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2867 if (!send_keepalive(smbd_server_fd()))
2868 exit_server("reply_writebraw: send of keepalive failed");
2877 #define DBGC_CLASS DBGC_LOCKING
2879 /****************************************************************************
2880 Reply to a writeunlock (core+).
2881 ****************************************************************************/
2883 int reply_writeunlock(connection_struct
*conn
, char *inbuf
,char *outbuf
,
2884 int size
, int dum_buffsize
)
2886 ssize_t nwritten
= -1;
2890 NTSTATUS status
= NT_STATUS_OK
;
2891 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2893 START_PROFILE(SMBwriteunlock
);
2895 CHECK_FSP(fsp
,conn
);
2896 if (!CHECK_WRITE(fsp
)) {
2897 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2900 numtowrite
= SVAL(inbuf
,smb_vwv1
);
2901 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2902 data
= smb_buf(inbuf
) + 3;
2904 if (numtowrite
&& is_locked(fsp
,(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
2905 END_PROFILE(SMBwriteunlock
);
2906 return ERROR_DOS(ERRDOS
,ERRlock
);
2909 /* The special X/Open SMB protocol handling of
2910 zero length writes is *NOT* done for
2912 if(numtowrite
== 0) {
2915 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
2918 sync_file(conn
, fsp
, False
/* write through */);
2920 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
2921 END_PROFILE(SMBwriteunlock
);
2922 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
2926 status
= do_unlock(fsp
,
2927 SVAL(inbuf
,smb_pid
),
2928 (SMB_BIG_UINT
)numtowrite
,
2929 (SMB_BIG_UINT
)startpos
,
2932 if (NT_STATUS_V(status
)) {
2933 END_PROFILE(SMBwriteunlock
);
2934 return ERROR_NT(status
);
2938 outsize
= set_message(outbuf
,1,0,True
);
2940 SSVAL(outbuf
,smb_vwv0
,nwritten
);
2942 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2943 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
2945 END_PROFILE(SMBwriteunlock
);
2950 #define DBGC_CLASS DBGC_ALL
2952 /****************************************************************************
2954 ****************************************************************************/
2956 int reply_write(connection_struct
*conn
, char *inbuf
,char *outbuf
,int size
,int dum_buffsize
)
2959 ssize_t nwritten
= -1;
2962 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2964 START_PROFILE(SMBwrite
);
2966 /* If it's an IPC, pass off the pipe handler. */
2968 END_PROFILE(SMBwrite
);
2969 return reply_pipe_write(inbuf
,outbuf
,size
,dum_buffsize
);
2972 CHECK_FSP(fsp
,conn
);
2973 if (!CHECK_WRITE(fsp
)) {
2974 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2977 numtowrite
= SVAL(inbuf
,smb_vwv1
);
2978 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2979 data
= smb_buf(inbuf
) + 3;
2981 if (is_locked(fsp
,(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
2982 END_PROFILE(SMBwrite
);
2983 return ERROR_DOS(ERRDOS
,ERRlock
);
2987 * X/Open SMB protocol says that if smb_vwv1 is
2988 * zero then the file size should be extended or
2989 * truncated to the size given in smb_vwv[2-3].
2992 if(numtowrite
== 0) {
2994 * This is actually an allocate call, and set EOF. JRA.
2996 nwritten
= vfs_allocate_file_space(fsp
, (SMB_OFF_T
)startpos
);
2998 END_PROFILE(SMBwrite
);
2999 return ERROR_NT(NT_STATUS_DISK_FULL
);
3001 nwritten
= vfs_set_filelen(fsp
, (SMB_OFF_T
)startpos
);
3003 END_PROFILE(SMBwrite
);
3004 return ERROR_NT(NT_STATUS_DISK_FULL
);
3007 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
3009 sync_file(conn
, fsp
, False
);
3011 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
3012 END_PROFILE(SMBwrite
);
3013 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3016 outsize
= set_message(outbuf
,1,0,True
);
3018 SSVAL(outbuf
,smb_vwv0
,nwritten
);
3020 if (nwritten
< (ssize_t
)numtowrite
) {
3021 SCVAL(outbuf
,smb_rcls
,ERRHRD
);
3022 SSVAL(outbuf
,smb_err
,ERRdiskfull
);
3025 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
3027 END_PROFILE(SMBwrite
);
3031 /****************************************************************************
3032 Reply to a write and X.
3033 ****************************************************************************/
3035 int reply_write_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3037 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv2
);
3038 SMB_OFF_T startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
3039 size_t numtowrite
= SVAL(inbuf
,smb_vwv10
);
3040 BOOL write_through
= BITSETW(inbuf
+smb_vwv7
,0);
3041 ssize_t nwritten
= -1;
3042 unsigned int smb_doff
= SVAL(inbuf
,smb_vwv11
);
3043 unsigned int smblen
= smb_len(inbuf
);
3045 BOOL large_writeX
= ((CVAL(inbuf
,smb_wct
) == 14) && (smblen
> 0xFFFF));
3046 START_PROFILE(SMBwriteX
);
3048 /* If it's an IPC, pass off the pipe handler. */
3050 END_PROFILE(SMBwriteX
);
3051 return reply_pipe_write_and_X(inbuf
,outbuf
,length
,bufsize
);
3054 CHECK_FSP(fsp
,conn
);
3055 if (!CHECK_WRITE(fsp
)) {
3056 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3059 set_message(outbuf
,6,0,True
);
3061 /* Deal with possible LARGE_WRITEX */
3063 numtowrite
|= ((((size_t)SVAL(inbuf
,smb_vwv9
)) & 1 )<<16);
3066 if(smb_doff
> smblen
|| (smb_doff
+ numtowrite
> smblen
)) {
3067 END_PROFILE(SMBwriteX
);
3068 return ERROR_DOS(ERRDOS
,ERRbadmem
);
3071 data
= smb_base(inbuf
) + smb_doff
;
3073 if(CVAL(inbuf
,smb_wct
) == 14) {
3074 #ifdef LARGE_SMB_OFF_T
3076 * This is a large offset (64 bit) write.
3078 startpos
|= (((SMB_OFF_T
)IVAL(inbuf
,smb_vwv12
)) << 32);
3080 #else /* !LARGE_SMB_OFF_T */
3083 * Ensure we haven't been sent a >32 bit offset.
3086 if(IVAL(inbuf
,smb_vwv12
) != 0) {
3087 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
3088 64 bit offsets.\n", (unsigned int)IVAL(inbuf
,smb_vwv12
) ));
3089 END_PROFILE(SMBwriteX
);
3090 return ERROR_DOS(ERRDOS
,ERRbadaccess
);
3093 #endif /* LARGE_SMB_OFF_T */
3096 if (is_locked(fsp
,(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
3097 END_PROFILE(SMBwriteX
);
3098 return ERROR_DOS(ERRDOS
,ERRlock
);
3101 /* X/Open SMB protocol says that, unlike SMBwrite
3102 if the length is zero then NO truncation is
3103 done, just a write of zero. To truncate a file,
3106 if(numtowrite
== 0) {
3110 if (schedule_aio_write_and_X(conn
, inbuf
, outbuf
, length
, bufsize
,
3111 fsp
,data
,startpos
,numtowrite
)) {
3112 END_PROFILE(SMBwriteX
);
3116 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
3119 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
3120 END_PROFILE(SMBwriteX
);
3121 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3124 SSVAL(outbuf
,smb_vwv2
,nwritten
);
3126 SSVAL(outbuf
,smb_vwv4
,(nwritten
>>16)&1);
3128 if (nwritten
< (ssize_t
)numtowrite
) {
3129 SCVAL(outbuf
,smb_rcls
,ERRHRD
);
3130 SSVAL(outbuf
,smb_err
,ERRdiskfull
);
3133 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
3134 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
3136 sync_file(conn
, fsp
, write_through
);
3138 END_PROFILE(SMBwriteX
);
3139 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
3142 /****************************************************************************
3144 ****************************************************************************/
3146 int reply_lseek(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
3152 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3153 START_PROFILE(SMBlseek
);
3155 CHECK_FSP(fsp
,conn
);
3157 flush_write_cache(fsp
, SEEK_FLUSH
);
3159 mode
= SVAL(inbuf
,smb_vwv1
) & 3;
3160 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
3161 startpos
= (SMB_OFF_T
)IVALS(inbuf
,smb_vwv2
);
3170 res
= fsp
->fh
->pos
+ startpos
;
3181 if (umode
== SEEK_END
) {
3182 if((res
= SMB_VFS_LSEEK(fsp
,fsp
->fh
->fd
,startpos
,umode
)) == -1) {
3183 if(errno
== EINVAL
) {
3184 SMB_OFF_T current_pos
= startpos
;
3185 SMB_STRUCT_STAT sbuf
;
3187 if(SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
, &sbuf
) == -1) {
3188 END_PROFILE(SMBlseek
);
3189 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3192 current_pos
+= sbuf
.st_size
;
3194 res
= SMB_VFS_LSEEK(fsp
,fsp
->fh
->fd
,0,SEEK_SET
);
3199 END_PROFILE(SMBlseek
);
3200 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3206 outsize
= set_message(outbuf
,2,0,True
);
3207 SIVAL(outbuf
,smb_vwv0
,res
);
3209 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
3210 fsp
->fnum
, (double)startpos
, (double)res
, mode
));
3212 END_PROFILE(SMBlseek
);
3216 /****************************************************************************
3218 ****************************************************************************/
3220 int reply_flush(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
3222 int outsize
= set_message(outbuf
,0,0,False
);
3223 uint16 fnum
= SVAL(inbuf
,smb_vwv0
);
3224 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3225 START_PROFILE(SMBflush
);
3228 CHECK_FSP(fsp
,conn
);
3231 file_sync_all(conn
);
3233 sync_file(conn
,fsp
, True
);
3236 DEBUG(3,("flush\n"));
3237 END_PROFILE(SMBflush
);
3241 /****************************************************************************
3243 conn POINTER CAN BE NULL HERE !
3244 ****************************************************************************/
3246 int reply_exit(connection_struct
*conn
,
3247 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3250 START_PROFILE(SMBexit
);
3252 file_close_pid(SVAL(inbuf
,smb_pid
),SVAL(inbuf
,smb_uid
));
3254 outsize
= set_message(outbuf
,0,0,False
);
3256 DEBUG(3,("exit\n"));
3258 END_PROFILE(SMBexit
);
3262 /****************************************************************************
3263 Reply to a close - has to deal with closing a directory opened by NT SMB's.
3264 ****************************************************************************/
3266 int reply_close(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
,
3271 int32 eclass
= 0, err
= 0;
3272 files_struct
*fsp
= NULL
;
3273 START_PROFILE(SMBclose
);
3275 outsize
= set_message(outbuf
,0,0,False
);
3277 /* If it's an IPC, pass off to the pipe handler. */
3279 END_PROFILE(SMBclose
);
3280 return reply_pipe_close(conn
, inbuf
,outbuf
);
3283 fsp
= file_fsp(inbuf
,smb_vwv0
);
3286 * We can only use CHECK_FSP if we know it's not a directory.
3289 if(!fsp
|| (fsp
->conn
!= conn
) || (fsp
->vuid
!= current_user
.vuid
)) {
3290 END_PROFILE(SMBclose
);
3291 return ERROR_DOS(ERRDOS
,ERRbadfid
);
3294 if(fsp
->is_directory
) {
3296 * Special case - close NT SMB directory handle.
3298 DEBUG(3,("close %s fnum=%d\n", fsp
->is_directory
? "directory" : "stat file open", fsp
->fnum
));
3299 close_file(fsp
,NORMAL_CLOSE
);
3302 * Close ordinary file.
3307 /* Save the name for time set in close. */
3308 pstrcpy( file_name
, fsp
->fsp_name
);
3310 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
3311 fsp
->fh
->fd
, fsp
->fnum
,
3312 conn
->num_files_open
));
3315 * Take care of any time sent in the close.
3318 mtime
= srv_make_unix_date3(inbuf
+smb_vwv1
);
3319 fsp_set_pending_modtime(fsp
, mtime
);
3322 * close_file() returns the unix errno if an error
3323 * was detected on close - normally this is due to
3324 * a disk full error. If not then it was probably an I/O error.
3327 if((close_err
= close_file(fsp
,NORMAL_CLOSE
)) != 0) {
3329 END_PROFILE(SMBclose
);
3330 return (UNIXERROR(ERRHRD
,ERRgeneral
));
3334 /* We have a cached error */
3336 END_PROFILE(SMBclose
);
3337 return ERROR_DOS(eclass
,err
);
3340 END_PROFILE(SMBclose
);
3344 /****************************************************************************
3345 Reply to a writeclose (Core+ protocol).
3346 ****************************************************************************/
3348 int reply_writeclose(connection_struct
*conn
,
3349 char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
3352 ssize_t nwritten
= -1;
3358 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3359 START_PROFILE(SMBwriteclose
);
3361 CHECK_FSP(fsp
,conn
);
3362 if (!CHECK_WRITE(fsp
)) {
3363 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3366 numtowrite
= SVAL(inbuf
,smb_vwv1
);
3367 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
3368 mtime
= srv_make_unix_date3(inbuf
+smb_vwv4
);
3369 data
= smb_buf(inbuf
) + 1;
3371 if (numtowrite
&& is_locked(fsp
,(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
3372 END_PROFILE(SMBwriteclose
);
3373 return ERROR_DOS(ERRDOS
,ERRlock
);
3376 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
3378 set_filetime(conn
, fsp
->fsp_name
,mtime
);
3381 * More insanity. W2K only closes the file if writelen > 0.
3386 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
3388 close_err
= close_file(fsp
,NORMAL_CLOSE
);
3391 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
3392 fsp
->fnum
, (int)numtowrite
, (int)nwritten
,
3393 conn
->num_files_open
));
3395 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
3396 END_PROFILE(SMBwriteclose
);
3397 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3400 if(close_err
!= 0) {
3402 END_PROFILE(SMBwriteclose
);
3403 return(UNIXERROR(ERRHRD
,ERRgeneral
));
3406 outsize
= set_message(outbuf
,1,0,True
);
3408 SSVAL(outbuf
,smb_vwv0
,nwritten
);
3409 END_PROFILE(SMBwriteclose
);
3414 #define DBGC_CLASS DBGC_LOCKING
3416 /****************************************************************************
3418 ****************************************************************************/
3420 int reply_lock(connection_struct
*conn
,
3421 char *inbuf
,char *outbuf
, int length
, int dum_buffsize
)
3423 int outsize
= set_message(outbuf
,0,0,False
);
3424 SMB_BIG_UINT count
,offset
;
3426 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3427 BOOL my_lock_ctx
= False
;
3429 START_PROFILE(SMBlock
);
3431 CHECK_FSP(fsp
,conn
);
3433 release_level_2_oplocks_on_change(fsp
);
3435 count
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv1
);
3436 offset
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv3
);
3438 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3439 fsp
->fh
->fd
, fsp
->fnum
, (double)offset
, (double)count
));
3441 status
= do_lock_spin(fsp
,
3442 SVAL(inbuf
,smb_pid
),
3448 if (NT_STATUS_V(status
)) {
3450 /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
3451 if (lp_blocking_locks(SNUM(conn
)) && !my_lock_ctx
&& ERROR_WAS_LOCK_DENIED(status
)) {
3453 * A blocking lock was requested. Package up
3454 * this smb into a queued request and push it
3455 * onto the blocking lock queue.
3457 if(push_blocking_lock_request(inbuf
, length
,
3461 SVAL(inbuf
,smb_pid
),
3465 END_PROFILE(SMBlock
);
3470 END_PROFILE(SMBlock
);
3471 return ERROR_NT(status
);
3474 END_PROFILE(SMBlock
);
3478 /****************************************************************************
3480 ****************************************************************************/
3482 int reply_unlock(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
,
3485 int outsize
= set_message(outbuf
,0,0,False
);
3486 SMB_BIG_UINT count
,offset
;
3488 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3489 START_PROFILE(SMBunlock
);
3491 CHECK_FSP(fsp
,conn
);
3493 count
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv1
);
3494 offset
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv3
);
3496 status
= do_unlock(fsp
,
3497 SVAL(inbuf
,smb_pid
),
3502 if (NT_STATUS_V(status
)) {
3503 END_PROFILE(SMBunlock
);
3504 return ERROR_NT(status
);
3507 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3508 fsp
->fh
->fd
, fsp
->fnum
, (double)offset
, (double)count
) );
3510 END_PROFILE(SMBunlock
);
3515 #define DBGC_CLASS DBGC_ALL
3517 /****************************************************************************
3519 conn POINTER CAN BE NULL HERE !
3520 ****************************************************************************/
3522 int reply_tdis(connection_struct
*conn
,
3523 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3525 int outsize
= set_message(outbuf
,0,0,False
);
3527 START_PROFILE(SMBtdis
);
3529 vuid
= SVAL(inbuf
,smb_uid
);
3532 DEBUG(4,("Invalid connection in tdis\n"));
3533 END_PROFILE(SMBtdis
);
3534 return ERROR_DOS(ERRSRV
,ERRinvnid
);
3539 close_cnum(conn
,vuid
);
3541 END_PROFILE(SMBtdis
);
3545 /****************************************************************************
3547 conn POINTER CAN BE NULL HERE !
3548 ****************************************************************************/
3550 int reply_echo(connection_struct
*conn
,
3551 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3553 int smb_reverb
= SVAL(inbuf
,smb_vwv0
);
3555 unsigned int data_len
= smb_buflen(inbuf
);
3556 int outsize
= set_message(outbuf
,1,data_len
,True
);
3557 START_PROFILE(SMBecho
);
3559 if (data_len
> BUFFER_SIZE
) {
3560 DEBUG(0,("reply_echo: data_len too large.\n"));
3561 END_PROFILE(SMBecho
);
3565 /* copy any incoming data back out */
3567 memcpy(smb_buf(outbuf
),smb_buf(inbuf
),data_len
);
3569 if (smb_reverb
> 100) {
3570 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb
));
3574 for (seq_num
=1 ; seq_num
<= smb_reverb
; seq_num
++) {
3575 SSVAL(outbuf
,smb_vwv0
,seq_num
);
3577 smb_setlen(outbuf
,outsize
- 4);
3580 if (!send_smb(smbd_server_fd(),outbuf
))
3581 exit_server("reply_echo: send_smb failed.");
3584 DEBUG(3,("echo %d times\n", smb_reverb
));
3588 END_PROFILE(SMBecho
);
3592 /****************************************************************************
3593 Reply to a printopen.
3594 ****************************************************************************/
3596 int reply_printopen(connection_struct
*conn
,
3597 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3601 START_PROFILE(SMBsplopen
);
3603 if (!CAN_PRINT(conn
)) {
3604 END_PROFILE(SMBsplopen
);
3605 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
3608 /* Open for exclusive use, write only. */
3609 fsp
= print_fsp_open(conn
, NULL
);
3612 END_PROFILE(SMBsplopen
);
3613 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3616 outsize
= set_message(outbuf
,1,0,True
);
3617 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
3619 DEBUG(3,("openprint fd=%d fnum=%d\n",
3620 fsp
->fh
->fd
, fsp
->fnum
));
3622 END_PROFILE(SMBsplopen
);
3626 /****************************************************************************
3627 Reply to a printclose.
3628 ****************************************************************************/
3630 int reply_printclose(connection_struct
*conn
,
3631 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3633 int outsize
= set_message(outbuf
,0,0,False
);
3634 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3636 START_PROFILE(SMBsplclose
);
3638 CHECK_FSP(fsp
,conn
);
3640 if (!CAN_PRINT(conn
)) {
3641 END_PROFILE(SMBsplclose
);
3642 return ERROR_NT(NT_STATUS_UNSUCCESSFUL
);
3645 DEBUG(3,("printclose fd=%d fnum=%d\n",
3646 fsp
->fh
->fd
,fsp
->fnum
));
3648 close_err
= close_file(fsp
,NORMAL_CLOSE
);
3650 if(close_err
!= 0) {
3652 END_PROFILE(SMBsplclose
);
3653 return(UNIXERROR(ERRHRD
,ERRgeneral
));
3656 END_PROFILE(SMBsplclose
);
3660 /****************************************************************************
3661 Reply to a printqueue.
3662 ****************************************************************************/
3664 int reply_printqueue(connection_struct
*conn
,
3665 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3667 int outsize
= set_message(outbuf
,2,3,True
);
3668 int max_count
= SVAL(inbuf
,smb_vwv0
);
3669 int start_index
= SVAL(inbuf
,smb_vwv1
);
3670 START_PROFILE(SMBsplretq
);
3672 /* we used to allow the client to get the cnum wrong, but that
3673 is really quite gross and only worked when there was only
3674 one printer - I think we should now only accept it if they
3675 get it right (tridge) */
3676 if (!CAN_PRINT(conn
)) {
3677 END_PROFILE(SMBsplretq
);
3678 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
3681 SSVAL(outbuf
,smb_vwv0
,0);
3682 SSVAL(outbuf
,smb_vwv1
,0);
3683 SCVAL(smb_buf(outbuf
),0,1);
3684 SSVAL(smb_buf(outbuf
),1,0);
3686 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3687 start_index
, max_count
));
3690 print_queue_struct
*queue
= NULL
;
3691 print_status_struct status
;
3692 char *p
= smb_buf(outbuf
) + 3;
3693 int count
= print_queue_status(SNUM(conn
), &queue
, &status
);
3694 int num_to_get
= ABS(max_count
);
3695 int first
= (max_count
>0?start_index
:start_index
+max_count
+1);
3701 num_to_get
= MIN(num_to_get
,count
-first
);
3704 for (i
=first
;i
<first
+num_to_get
;i
++) {
3705 srv_put_dos_date2(p
,0,queue
[i
].time
);
3706 SCVAL(p
,4,(queue
[i
].status
==LPQ_PRINTING
?2:3));
3707 SSVAL(p
,5, queue
[i
].job
);
3708 SIVAL(p
,7,queue
[i
].size
);
3710 srvstr_push(outbuf
, p
+12, queue
[i
].fs_user
, 16, STR_ASCII
);
3715 outsize
= set_message(outbuf
,2,28*count
+3,False
);
3716 SSVAL(outbuf
,smb_vwv0
,count
);
3717 SSVAL(outbuf
,smb_vwv1
,(max_count
>0?first
+count
:first
-1));
3718 SCVAL(smb_buf(outbuf
),0,1);
3719 SSVAL(smb_buf(outbuf
),1,28*count
);
3724 DEBUG(3,("%d entries returned in queue\n",count
));
3727 END_PROFILE(SMBsplretq
);
3731 /****************************************************************************
3732 Reply to a printwrite.
3733 ****************************************************************************/
3735 int reply_printwrite(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3738 int outsize
= set_message(outbuf
,0,0,False
);
3740 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3742 START_PROFILE(SMBsplwr
);
3744 if (!CAN_PRINT(conn
)) {
3745 END_PROFILE(SMBsplwr
);
3746 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
3749 CHECK_FSP(fsp
,conn
);
3750 if (!CHECK_WRITE(fsp
)) {
3751 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3754 numtowrite
= SVAL(smb_buf(inbuf
),1);
3755 data
= smb_buf(inbuf
) + 3;
3757 if (write_file(fsp
,data
,-1,numtowrite
) != numtowrite
) {
3758 END_PROFILE(SMBsplwr
);
3759 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3762 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp
->fnum
, numtowrite
) );
3764 END_PROFILE(SMBsplwr
);
3768 /****************************************************************************
3769 The guts of the mkdir command, split out so it may be called by the NT SMB
3771 ****************************************************************************/
3773 NTSTATUS
mkdir_internal(connection_struct
*conn
, const pstring directory
, BOOL bad_path
)
3777 if(!CAN_WRITE(conn
)) {
3778 DEBUG(5,("mkdir_internal: failing create on read-only share %s\n", lp_servicename(SNUM(conn
))));
3780 return map_nt_error_from_unix(errno
);
3784 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3787 if (!check_name(directory
, conn
)) {
3788 if(errno
== ENOENT
) {
3790 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3792 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3795 return map_nt_error_from_unix(errno
);
3798 ret
= vfs_MkDir(conn
,directory
,unix_mode(conn
,aDIR
,directory
,True
));
3800 if(errno
== ENOENT
) {
3801 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3803 return map_nt_error_from_unix(errno
);
3806 return NT_STATUS_OK
;
3809 /****************************************************************************
3811 ****************************************************************************/
3813 int reply_mkdir(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3818 BOOL bad_path
= False
;
3819 SMB_STRUCT_STAT sbuf
;
3821 START_PROFILE(SMBmkdir
);
3823 srvstr_get_path(inbuf
, directory
, smb_buf(inbuf
) + 1, sizeof(directory
), 0, STR_TERMINATE
, &status
);
3824 if (!NT_STATUS_IS_OK(status
)) {
3825 END_PROFILE(SMBmkdir
);
3826 return ERROR_NT(status
);
3829 RESOLVE_DFSPATH(directory
, conn
, inbuf
, outbuf
);
3831 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
3833 if( is_ntfs_stream_name(directory
)) {
3834 DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory
));
3835 END_PROFILE(SMBmkdir
);
3836 return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY
);
3839 status
= mkdir_internal(conn
, directory
,bad_path
);
3840 if (!NT_STATUS_IS_OK(status
)) {
3841 END_PROFILE(SMBmkdir
);
3842 return ERROR_NT(status
);
3845 if (lp_inherit_owner(SNUM(conn
))) {
3846 /* Ensure we're checking for a symlink here.... */
3847 /* We don't want to get caught by a symlink racer. */
3849 if(SMB_VFS_LSTAT(conn
,directory
, &sbuf
) != 0) {
3850 END_PROFILE(SMBmkdir
);
3851 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3854 if(!S_ISDIR(sbuf
.st_mode
)) {
3855 DEBUG(0,("reply_mkdir: %s is not a directory !\n", directory
));
3856 END_PROFILE(SMBmkdir
);
3857 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3860 change_owner_to_parent(conn
, NULL
, directory
, &sbuf
);
3863 outsize
= set_message(outbuf
,0,0,False
);
3865 DEBUG( 3, ( "mkdir %s ret=%d\n", directory
, outsize
) );
3867 END_PROFILE(SMBmkdir
);
3871 /****************************************************************************
3872 Static function used by reply_rmdir to delete an entire directory
3873 tree recursively. Return False on ok, True on fail.
3874 ****************************************************************************/
3876 static BOOL
recursive_rmdir(connection_struct
*conn
, char *directory
)
3878 const char *dname
= NULL
;
3881 struct smb_Dir
*dir_hnd
= OpenDir(conn
, directory
, NULL
, 0);
3886 while((dname
= ReadDirName(dir_hnd
, &offset
))) {
3890 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0))
3893 if (!is_visible_file(conn
, directory
, dname
, &st
, False
))
3896 /* Construct the full name. */
3897 if(strlen(directory
) + strlen(dname
) + 1 >= sizeof(fullname
)) {
3903 pstrcpy(fullname
, directory
);
3904 pstrcat(fullname
, "/");
3905 pstrcat(fullname
, dname
);
3907 if(SMB_VFS_LSTAT(conn
,fullname
, &st
) != 0) {
3912 if(st
.st_mode
& S_IFDIR
) {
3913 if(recursive_rmdir(conn
, fullname
)!=0) {
3917 if(SMB_VFS_RMDIR(conn
,fullname
) != 0) {
3921 } else if(SMB_VFS_UNLINK(conn
,fullname
) != 0) {
3930 /****************************************************************************
3931 The internals of the rmdir code - called elsewhere.
3932 ****************************************************************************/
3934 BOOL
rmdir_internals(connection_struct
*conn
, char *directory
)
3939 ok
= (SMB_VFS_RMDIR(conn
,directory
) == 0);
3940 if(!ok
&& ((errno
== ENOTEMPTY
)||(errno
== EEXIST
)) && lp_veto_files(SNUM(conn
))) {
3942 * Check to see if the only thing in this directory are
3943 * vetoed files/directories. If so then delete them and
3944 * retry. If we fail to delete any of them (and we *don't*
3945 * do a recursive delete) then fail the rmdir.
3947 BOOL all_veto_files
= True
;
3949 struct smb_Dir
*dir_hnd
= OpenDir(conn
, directory
, NULL
, 0);
3951 if(dir_hnd
!= NULL
) {
3953 while ((dname
= ReadDirName(dir_hnd
,&dirpos
))) {
3954 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0))
3956 if (!is_visible_file(conn
, directory
, dname
, &st
, False
))
3958 if(!IS_VETO_PATH(conn
, dname
)) {
3959 all_veto_files
= False
;
3964 if(all_veto_files
) {
3965 RewindDir(dir_hnd
,&dirpos
);
3966 while ((dname
= ReadDirName(dir_hnd
,&dirpos
))) {
3969 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0))
3971 if (!is_visible_file(conn
, directory
, dname
, &st
, False
))
3974 /* Construct the full name. */
3975 if(strlen(directory
) + strlen(dname
) + 1 >= sizeof(fullname
)) {
3980 pstrcpy(fullname
, directory
);
3981 pstrcat(fullname
, "/");
3982 pstrcat(fullname
, dname
);
3984 if(SMB_VFS_LSTAT(conn
,fullname
, &st
) != 0)
3986 if(st
.st_mode
& S_IFDIR
) {
3987 if(lp_recursive_veto_delete(SNUM(conn
))) {
3988 if(recursive_rmdir(conn
, fullname
) != 0)
3991 if(SMB_VFS_RMDIR(conn
,fullname
) != 0)
3993 } else if(SMB_VFS_UNLINK(conn
,fullname
) != 0)
3997 /* Retry the rmdir */
3998 ok
= (SMB_VFS_RMDIR(conn
,directory
) == 0);
4008 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory
,strerror(errno
)));
4013 /****************************************************************************
4015 ****************************************************************************/
4017 int reply_rmdir(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
4022 BOOL bad_path
= False
;
4023 SMB_STRUCT_STAT sbuf
;
4025 START_PROFILE(SMBrmdir
);
4027 srvstr_get_path(inbuf
, directory
, smb_buf(inbuf
) + 1, sizeof(directory
), 0, STR_TERMINATE
, &status
);
4028 if (!NT_STATUS_IS_OK(status
)) {
4029 END_PROFILE(SMBrmdir
);
4030 return ERROR_NT(status
);
4033 RESOLVE_DFSPATH(directory
, conn
, inbuf
, outbuf
)
4035 unix_convert(directory
,conn
, NULL
,&bad_path
,&sbuf
);
4037 END_PROFILE(SMBrmdir
);
4038 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
4041 if (check_name(directory
,conn
)) {
4042 dptr_closepath(directory
,SVAL(inbuf
,smb_pid
));
4043 ok
= rmdir_internals(conn
, directory
);
4047 END_PROFILE(SMBrmdir
);
4048 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
, ERRbadpath
);
4051 outsize
= set_message(outbuf
,0,0,False
);
4053 DEBUG( 3, ( "rmdir %s\n", directory
) );
4055 END_PROFILE(SMBrmdir
);
4059 /*******************************************************************
4060 Resolve wildcards in a filename rename.
4061 Note that name is in UNIX charset and thus potentially can be more
4062 than fstring buffer (255 bytes) especially in default UTF-8 case.
4063 Therefore, we use pstring inside and all calls should ensure that
4064 name2 is at least pstring-long (they do already)
4065 ********************************************************************/
4067 static BOOL
resolve_wildcards(const char *name1
, char *name2
)
4069 pstring root1
,root2
;
4071 char *p
,*p2
, *pname1
, *pname2
;
4072 int available_space
, actual_space
;
4075 pname1
= strrchr_m(name1
,'/');
4076 pname2
= strrchr_m(name2
,'/');
4078 if (!pname1
|| !pname2
)
4081 pstrcpy(root1
,pname1
);
4082 pstrcpy(root2
,pname2
);
4083 p
= strrchr_m(root1
,'.');
4090 p
= strrchr_m(root2
,'.');
4104 } else if (*p2
== '*') {
4120 } else if (*p2
== '*') {
4130 available_space
= sizeof(pstring
) - PTR_DIFF(pname2
, name2
);
4133 actual_space
= snprintf(pname2
, available_space
- 1, "%s.%s", root2
, ext2
);
4134 if (actual_space
>= available_space
- 1) {
4135 DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
4136 actual_space
- available_space
));
4139 pstrcpy_base(pname2
, root2
, name2
);
4145 /****************************************************************************
4146 Ensure open files have their names updated. Updated to notify other smbd's
4148 ****************************************************************************/
4150 static void rename_open_files(connection_struct
*conn
, struct share_mode_lock
*lck
,
4151 SMB_DEV_T dev
, SMB_INO_T inode
, const char *newname
)
4154 BOOL did_rename
= False
;
4156 for(fsp
= file_find_di_first(dev
, inode
); fsp
; fsp
= file_find_di_next(fsp
)) {
4157 /* fsp_name is a relative path under the fsp. To change this for other
4158 sharepaths we need to manipulate relative paths. */
4159 /* TODO - create the absolute path and manipulate the newname
4160 relative to the sharepath. */
4161 if (fsp
->conn
!= conn
) {
4164 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
4165 fsp
->fnum
, (unsigned int)fsp
->dev
, (double)fsp
->inode
,
4166 fsp
->fsp_name
, newname
));
4167 string_set(&fsp
->fsp_name
, newname
);
4172 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
4173 (unsigned int)dev
, (double)inode
, newname
));
4176 /* Send messages to all smbd's (not ourself) that the name has changed. */
4177 rename_share_filename(lck
, conn
->connectpath
, newname
);
4180 /****************************************************************************
4181 We need to check if the source path is a parent directory of the destination
4182 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
4183 refuse the rename with a sharing violation. Under UNIX the above call can
4184 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
4185 probably need to check that the client is a Windows one before disallowing
4186 this as a UNIX client (one with UNIX extensions) can know the source is a
4187 symlink and make this decision intelligently. Found by an excellent bug
4188 report from <AndyLiebman@aol.com>.
4189 ****************************************************************************/
4191 static BOOL
rename_path_prefix_equal(const char *src
, const char *dest
)
4193 const char *psrc
= src
;
4194 const char *pdst
= dest
;
4197 if (psrc
[0] == '.' && psrc
[1] == '/') {
4200 if (pdst
[0] == '.' && pdst
[1] == '/') {
4203 if ((slen
= strlen(psrc
)) > strlen(pdst
)) {
4206 return ((memcmp(psrc
, pdst
, slen
) == 0) && pdst
[slen
] == '/');
4209 /****************************************************************************
4210 Rename an open file - given an fsp.
4211 ****************************************************************************/
4213 NTSTATUS
rename_internals_fsp(connection_struct
*conn
, files_struct
*fsp
, char *newname
, uint32 attrs
, BOOL replace_if_exists
)
4215 SMB_STRUCT_STAT sbuf
;
4216 BOOL bad_path
= False
;
4217 pstring newname_last_component
;
4218 NTSTATUS error
= NT_STATUS_OK
;
4221 struct share_mode_lock
*lck
= NULL
;
4224 rcdest
= unix_convert(newname
,conn
,newname_last_component
,&bad_path
,&sbuf
);
4226 /* Quick check for "." and ".." */
4227 if (!bad_path
&& newname_last_component
[0] == '.') {
4228 if (!newname_last_component
[1] || (newname_last_component
[1] == '.' && !newname_last_component
[2])) {
4229 return NT_STATUS_ACCESS_DENIED
;
4232 if (!rcdest
&& bad_path
) {
4233 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
4236 /* Ensure newname contains a '/' */
4237 if(strrchr_m(newname
,'/') == 0) {
4240 pstrcpy(tmpstr
, "./");
4241 pstrcat(tmpstr
, newname
);
4242 pstrcpy(newname
, tmpstr
);
4246 * Check for special case with case preserving and not
4247 * case sensitive. If the old last component differs from the original
4248 * last component only by case, then we should allow
4249 * the rename (user is trying to change the case of the
4253 if((conn
->case_sensitive
== False
) && (conn
->case_preserve
== True
) &&
4254 strequal(newname
, fsp
->fsp_name
)) {
4256 pstring newname_modified_last_component
;
4259 * Get the last component of the modified name.
4260 * Note that we guarantee that newname contains a '/'
4263 p
= strrchr_m(newname
,'/');
4264 pstrcpy(newname_modified_last_component
,p
+1);
4266 if(strcsequal(newname_modified_last_component
,
4267 newname_last_component
) == False
) {
4269 * Replace the modified last component with
4272 pstrcpy(p
+1, newname_last_component
);
4277 * If the src and dest names are identical - including case,
4278 * don't do the rename, just return success.
4281 if (strcsequal(fsp
->fsp_name
, newname
)) {
4282 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
4284 return NT_STATUS_OK
;
4287 dest_exists
= vfs_object_exist(conn
,newname
,NULL
);
4289 if(!replace_if_exists
&& dest_exists
) {
4290 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
4291 fsp
->fsp_name
,newname
));
4292 return NT_STATUS_OBJECT_NAME_COLLISION
;
4295 error
= can_rename(conn
,newname
,attrs
,&sbuf
);
4297 if (dest_exists
&& !NT_STATUS_IS_OK(error
)) {
4298 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4299 nt_errstr(error
), fsp
->fsp_name
,newname
));
4300 if (NT_STATUS_EQUAL(error
,NT_STATUS_SHARING_VIOLATION
))
4301 error
= NT_STATUS_ACCESS_DENIED
;
4305 if (rename_path_prefix_equal(fsp
->fsp_name
, newname
)) {
4306 return NT_STATUS_ACCESS_DENIED
;
4309 lck
= get_share_mode_lock(NULL
, fsp
->dev
, fsp
->inode
, NULL
, NULL
);
4311 if(SMB_VFS_RENAME(conn
,fsp
->fsp_name
, newname
) == 0) {
4312 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
4313 fsp
->fsp_name
,newname
));
4314 rename_open_files(conn
, lck
, fsp
->dev
, fsp
->inode
, newname
);
4316 return NT_STATUS_OK
;
4321 if (errno
== ENOTDIR
|| errno
== EISDIR
) {
4322 error
= NT_STATUS_OBJECT_NAME_COLLISION
;
4324 error
= map_nt_error_from_unix(errno
);
4327 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
4328 nt_errstr(error
), fsp
->fsp_name
,newname
));
4333 /****************************************************************************
4334 The guts of the rename command, split out so it may be called by the NT SMB
4336 ****************************************************************************/
4338 NTSTATUS
rename_internals(connection_struct
*conn
, char *name
, char *newname
, uint32 attrs
, BOOL replace_if_exists
, BOOL has_wild
)
4342 pstring last_component_src
;
4343 pstring last_component_dest
;
4345 BOOL bad_path_src
= False
;
4346 BOOL bad_path_dest
= False
;
4348 NTSTATUS error
= NT_STATUS_OK
;
4351 SMB_STRUCT_STAT sbuf1
, sbuf2
;
4352 struct share_mode_lock
*lck
= NULL
;
4354 *directory
= *mask
= 0;
4359 rc
= unix_convert(name
,conn
,last_component_src
,&bad_path_src
,&sbuf1
);
4360 if (!rc
&& bad_path_src
) {
4361 if (ms_has_wild(last_component_src
))
4362 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4363 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
4366 /* Quick check for "." and ".." */
4367 if (last_component_src
[0] == '.') {
4368 if (!last_component_src
[1] || (last_component_src
[1] == '.' && !last_component_src
[2])) {
4369 return NT_STATUS_OBJECT_NAME_INVALID
;
4373 rcdest
= unix_convert(newname
,conn
,last_component_dest
,&bad_path_dest
,&sbuf2
);
4375 /* Quick check for "." and ".." */
4376 if (last_component_dest
[0] == '.') {
4377 if (!last_component_dest
[1] || (last_component_dest
[1] == '.' && !last_component_dest
[2])) {
4378 return NT_STATUS_OBJECT_NAME_INVALID
;
4383 * Split the old name into directory and last component
4384 * strings. Note that unix_convert may have stripped off a
4385 * leading ./ from both name and newname if the rename is
4386 * at the root of the share. We need to make sure either both
4387 * name and newname contain a / character or neither of them do
4388 * as this is checked in resolve_wildcards().
4391 p
= strrchr_m(name
,'/');
4393 pstrcpy(directory
,".");
4397 pstrcpy(directory
,name
);
4399 *p
= '/'; /* Replace needed for exceptional test below. */
4403 * We should only check the mangled cache
4404 * here if unix_convert failed. This means
4405 * that the path in 'mask' doesn't exist
4406 * on the file system and so we need to look
4407 * for a possible mangle. This patch from
4408 * Tine Smukavec <valentin.smukavec@hermes.si>.
4411 if (!rc
&& mangle_is_mangled(mask
,SNUM(conn
)))
4412 mangle_check_cache( mask
, sizeof(pstring
)-1, SNUM(conn
));
4416 * No wildcards - just process the one file.
4418 BOOL is_short_name
= mangle_is_8_3(name
, True
, SNUM(conn
));
4420 /* Add a terminating '/' to the directory name. */
4421 pstrcat(directory
,"/");
4422 pstrcat(directory
,mask
);
4424 /* Ensure newname contains a '/' also */
4425 if(strrchr_m(newname
,'/') == 0) {
4428 pstrcpy(tmpstr
, "./");
4429 pstrcat(tmpstr
, newname
);
4430 pstrcpy(newname
, tmpstr
);
4433 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
4434 directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
4435 conn
->case_sensitive
, conn
->case_preserve
, conn
->short_case_preserve
, directory
,
4436 newname
, last_component_dest
, is_short_name
));
4439 * Check for special case with case preserving and not
4440 * case sensitive, if directory and newname are identical,
4441 * and the old last component differs from the original
4442 * last component only by case, then we should allow
4443 * the rename (user is trying to change the case of the
4446 if((conn
->case_sensitive
== False
) &&
4447 (((conn
->case_preserve
== True
) &&
4448 (is_short_name
== False
)) ||
4449 ((conn
->short_case_preserve
== True
) &&
4450 (is_short_name
== True
))) &&
4451 strcsequal(directory
, newname
)) {
4452 pstring modified_last_component
;
4455 * Get the last component of the modified name.
4456 * Note that we guarantee that newname contains a '/'
4459 p
= strrchr_m(newname
,'/');
4460 pstrcpy(modified_last_component
,p
+1);
4462 if(strcsequal(modified_last_component
,
4463 last_component_dest
) == False
) {
4465 * Replace the modified last component with
4468 pstrcpy(p
+1, last_component_dest
);
4472 resolve_wildcards(directory
,newname
);
4475 * The source object must exist.
4478 if (!vfs_object_exist(conn
, directory
, &sbuf1
)) {
4479 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
4480 directory
,newname
));
4482 if (errno
== ENOTDIR
|| errno
== EISDIR
|| errno
== ENOENT
) {
4484 * Must return different errors depending on whether the parent
4485 * directory existed or not.
4488 p
= strrchr_m(directory
, '/');
4490 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4492 if (vfs_object_exist(conn
, directory
, NULL
))
4493 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4494 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
4496 error
= map_nt_error_from_unix(errno
);
4497 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4498 nt_errstr(error
), directory
,newname
));
4503 if (!rcdest
&& bad_path_dest
) {
4504 if (ms_has_wild(last_component_dest
))
4505 return NT_STATUS_OBJECT_NAME_INVALID
;
4506 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
4509 error
= can_rename(conn
,directory
,attrs
,&sbuf1
);
4511 if (!NT_STATUS_IS_OK(error
)) {
4512 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4513 nt_errstr(error
), directory
,newname
));
4518 * If the src and dest names are identical - including case,
4519 * don't do the rename, just return success.
4522 if (strcsequal(directory
, newname
)) {
4523 rename_open_files(conn
, NULL
, sbuf1
.st_dev
, sbuf1
.st_ino
, newname
);
4524 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory
));
4525 return NT_STATUS_OK
;
4528 if(!replace_if_exists
&& vfs_object_exist(conn
,newname
,NULL
)) {
4529 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
4530 directory
,newname
));
4531 return NT_STATUS_OBJECT_NAME_COLLISION
;
4534 if (rename_path_prefix_equal(directory
, newname
)) {
4535 return NT_STATUS_SHARING_VIOLATION
;
4538 lck
= get_share_mode_lock(NULL
, sbuf1
.st_dev
, sbuf1
.st_ino
, NULL
, NULL
);
4540 if(SMB_VFS_RENAME(conn
,directory
, newname
) == 0) {
4541 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
4542 directory
,newname
));
4543 rename_open_files(conn
, lck
, sbuf1
.st_dev
, sbuf1
.st_ino
, newname
);
4545 return NT_STATUS_OK
;
4549 if (errno
== ENOTDIR
|| errno
== EISDIR
)
4550 error
= NT_STATUS_OBJECT_NAME_COLLISION
;
4552 error
= map_nt_error_from_unix(errno
);
4554 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
4555 nt_errstr(error
), directory
,newname
));
4560 * Wildcards - process each file that matches.
4562 struct smb_Dir
*dir_hnd
= NULL
;
4566 if (strequal(mask
,"????????.???"))
4569 if (check_name(directory
,conn
))
4570 dir_hnd
= OpenDir(conn
, directory
, mask
, attrs
);
4574 error
= NT_STATUS_NO_SUCH_FILE
;
4575 /* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
4577 while ((dname
= ReadDirName(dir_hnd
, &offset
))) {
4579 BOOL sysdir_entry
= False
;
4581 pstrcpy(fname
,dname
);
4583 /* Quick check for "." and ".." */
4584 if (fname
[0] == '.') {
4585 if (!fname
[1] || (fname
[1] == '.' && !fname
[2])) {
4587 sysdir_entry
= True
;
4594 if (!is_visible_file(conn
, directory
, dname
, &sbuf1
, False
))
4597 if(!mask_match(fname
, mask
, conn
->case_sensitive
))
4601 error
= NT_STATUS_OBJECT_NAME_INVALID
;
4605 error
= NT_STATUS_ACCESS_DENIED
;
4606 slprintf(fname
,sizeof(fname
)-1,"%s/%s",directory
,dname
);
4607 if (!vfs_object_exist(conn
, fname
, &sbuf1
)) {
4608 error
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4609 DEBUG(6,("rename %s failed. Error %s\n", fname
, nt_errstr(error
)));
4612 error
= can_rename(conn
,fname
,attrs
,&sbuf1
);
4613 if (!NT_STATUS_IS_OK(error
)) {
4614 DEBUG(6,("rename %s refused\n", fname
));
4617 pstrcpy(destname
,newname
);
4619 if (!resolve_wildcards(fname
,destname
)) {
4620 DEBUG(6,("resolve_wildcards %s %s failed\n",
4625 if (strcsequal(fname
,destname
)) {
4626 rename_open_files(conn
, NULL
, sbuf1
.st_dev
, sbuf1
.st_ino
, newname
);
4627 DEBUG(3,("rename_internals: identical names in wildcard rename %s - success\n", fname
));
4629 error
= NT_STATUS_OK
;
4633 if (!replace_if_exists
&&
4634 vfs_file_exist(conn
,destname
, NULL
)) {
4635 DEBUG(6,("file_exist %s\n", destname
));
4636 error
= NT_STATUS_OBJECT_NAME_COLLISION
;
4640 if (rename_path_prefix_equal(fname
, destname
)) {
4641 return NT_STATUS_SHARING_VIOLATION
;
4644 lck
= get_share_mode_lock(NULL
, sbuf1
.st_dev
, sbuf1
.st_ino
, NULL
, NULL
);
4646 if (!SMB_VFS_RENAME(conn
,fname
,destname
)) {
4647 rename_open_files(conn
, lck
, sbuf1
.st_dev
, sbuf1
.st_ino
, newname
);
4649 error
= NT_STATUS_OK
;
4652 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname
,destname
));
4657 if (!NT_STATUS_EQUAL(error
,NT_STATUS_NO_SUCH_FILE
)) {
4658 if (!rcdest
&& bad_path_dest
) {
4659 if (ms_has_wild(last_component_dest
))
4660 return NT_STATUS_OBJECT_NAME_INVALID
;
4661 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
4666 if (count
== 0 && NT_STATUS_IS_OK(error
)) {
4667 error
= map_nt_error_from_unix(errno
);
4673 /****************************************************************************
4675 ****************************************************************************/
4677 int reply_mv(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
,
4684 uint32 attrs
= SVAL(inbuf
,smb_vwv0
);
4686 BOOL path_contains_wcard
= False
;
4688 START_PROFILE(SMBmv
);
4690 p
= smb_buf(inbuf
) + 1;
4691 p
+= srvstr_get_path_wcard(inbuf
, name
, p
, sizeof(name
), 0, STR_TERMINATE
, &status
, &path_contains_wcard
);
4692 if (!NT_STATUS_IS_OK(status
)) {
4694 return ERROR_NT(status
);
4697 p
+= srvstr_get_path(inbuf
, newname
, p
, sizeof(newname
), 0, STR_TERMINATE
, &status
);
4698 if (!NT_STATUS_IS_OK(status
)) {
4700 return ERROR_NT(status
);
4703 RESOLVE_DFSPATH_WCARD(name
, conn
, inbuf
, outbuf
);
4704 RESOLVE_DFSPATH_WCARD(newname
, conn
, inbuf
, outbuf
);
4706 DEBUG(3,("reply_mv : %s -> %s\n",name
,newname
));
4708 status
= rename_internals(conn
, name
, newname
, attrs
, False
, path_contains_wcard
);
4709 if (!NT_STATUS_IS_OK(status
)) {
4711 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
4712 /* We have re-scheduled this call. */
4715 return ERROR_NT(status
);
4719 * Win2k needs a changenotify request response before it will
4720 * update after a rename..
4722 process_pending_change_notify_queue((time_t)0);
4723 outsize
= set_message(outbuf
,0,0,False
);
4729 /*******************************************************************
4730 Copy a file as part of a reply_copy.
4731 ******************************************************************/
4733 BOOL
copy_file(char *src
,char *dest1
,connection_struct
*conn
, int ofun
,
4734 int count
,BOOL target_is_directory
, int *err_ret
)
4736 SMB_STRUCT_STAT src_sbuf
, sbuf2
;
4738 files_struct
*fsp1
,*fsp2
;
4741 uint32 new_create_disposition
;
4745 pstrcpy(dest
,dest1
);
4746 if (target_is_directory
) {
4747 char *p
= strrchr_m(src
,'/');
4757 if (!vfs_file_exist(conn
,src
,&src_sbuf
)) {
4761 if (!target_is_directory
&& count
) {
4762 new_create_disposition
= FILE_OPEN
;
4764 if (!map_open_params_to_ntcreate(dest1
,0,ofun
,
4765 NULL
, NULL
, &new_create_disposition
, NULL
)) {
4770 fsp1
= open_file_ntcreate(conn
,src
,&src_sbuf
,
4772 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4775 FILE_ATTRIBUTE_NORMAL
,
4783 dosattrs
= dos_mode(conn
, src
, &src_sbuf
);
4784 if (SMB_VFS_STAT(conn
,dest
,&sbuf2
) == -1) {
4785 ZERO_STRUCTP(&sbuf2
);
4788 fsp2
= open_file_ntcreate(conn
,dest
,&sbuf2
,
4790 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4791 new_create_disposition
,
4798 close_file(fsp1
,ERROR_CLOSE
);
4802 if ((ofun
&3) == 1) {
4803 if(SMB_VFS_LSEEK(fsp2
,fsp2
->fh
->fd
,0,SEEK_END
) == -1) {
4804 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno
) ));
4806 * Stop the copy from occurring.
4809 src_sbuf
.st_size
= 0;
4813 if (src_sbuf
.st_size
) {
4814 ret
= vfs_transfer_file(fsp1
, fsp2
, src_sbuf
.st_size
);
4817 close_file(fsp1
,NORMAL_CLOSE
);
4819 /* Ensure the modtime is set correctly on the destination file. */
4820 fsp_set_pending_modtime( fsp2
, src_sbuf
.st_mtime
);
4823 * As we are opening fsp1 read-only we only expect
4824 * an error on close on fsp2 if we are out of space.
4825 * Thus we don't look at the error return from the
4828 *err_ret
= close_file(fsp2
,NORMAL_CLOSE
);
4830 return(ret
== (SMB_OFF_T
)src_sbuf
.st_size
);
4833 /****************************************************************************
4834 Reply to a file copy.
4835 ****************************************************************************/
4837 int reply_copy(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
4842 pstring mask
,newname
;
4845 int error
= ERRnoaccess
;
4849 int tid2
= SVAL(inbuf
,smb_vwv0
);
4850 int ofun
= SVAL(inbuf
,smb_vwv1
);
4851 int flags
= SVAL(inbuf
,smb_vwv2
);
4852 BOOL target_is_directory
=False
;
4853 BOOL bad_path1
= False
;
4854 BOOL bad_path2
= False
;
4855 BOOL path_contains_wcard1
= False
;
4856 BOOL path_contains_wcard2
= False
;
4858 SMB_STRUCT_STAT sbuf1
, sbuf2
;
4860 START_PROFILE(SMBcopy
);
4862 *directory
= *mask
= 0;
4865 p
+= srvstr_get_path_wcard(inbuf
, name
, p
, sizeof(name
), 0, STR_TERMINATE
, &status
, &path_contains_wcard1
);
4866 if (!NT_STATUS_IS_OK(status
)) {
4867 END_PROFILE(SMBcopy
);
4868 return ERROR_NT(status
);
4870 p
+= srvstr_get_path_wcard(inbuf
, newname
, p
, sizeof(newname
), 0, STR_TERMINATE
, &status
, &path_contains_wcard2
);
4871 if (!NT_STATUS_IS_OK(status
)) {
4872 END_PROFILE(SMBcopy
);
4873 return ERROR_NT(status
);
4876 DEBUG(3,("reply_copy : %s -> %s\n",name
,newname
));
4878 if (tid2
!= conn
->cnum
) {
4879 /* can't currently handle inter share copies XXXX */
4880 DEBUG(3,("Rejecting inter-share copy\n"));
4881 END_PROFILE(SMBcopy
);
4882 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
4885 RESOLVE_DFSPATH_WCARD(name
, conn
, inbuf
, outbuf
);
4886 RESOLVE_DFSPATH_WCARD(newname
, conn
, inbuf
, outbuf
);
4888 rc
= unix_convert(name
,conn
,0,&bad_path1
,&sbuf1
);
4889 unix_convert(newname
,conn
,0,&bad_path2
,&sbuf2
);
4891 target_is_directory
= VALID_STAT_OF_DIR(sbuf2
);
4893 if ((flags
&1) && target_is_directory
) {
4894 END_PROFILE(SMBcopy
);
4895 return ERROR_DOS(ERRDOS
,ERRbadfile
);
4898 if ((flags
&2) && !target_is_directory
) {
4899 END_PROFILE(SMBcopy
);
4900 return ERROR_DOS(ERRDOS
,ERRbadpath
);
4903 if ((flags
&(1<<5)) && VALID_STAT_OF_DIR(sbuf1
)) {
4904 /* wants a tree copy! XXXX */
4905 DEBUG(3,("Rejecting tree copy\n"));
4906 END_PROFILE(SMBcopy
);
4907 return ERROR_DOS(ERRSRV
,ERRerror
);
4910 p
= strrchr_m(name
,'/');
4912 pstrcpy(directory
,"./");
4916 pstrcpy(directory
,name
);
4921 * We should only check the mangled cache
4922 * here if unix_convert failed. This means
4923 * that the path in 'mask' doesn't exist
4924 * on the file system and so we need to look
4925 * for a possible mangle. This patch from
4926 * Tine Smukavec <valentin.smukavec@hermes.si>.
4929 if (!rc
&& mangle_is_mangled(mask
, SNUM(conn
)))
4930 mangle_check_cache( mask
, sizeof(pstring
)-1, SNUM(conn
));
4932 has_wild
= path_contains_wcard1
;
4935 pstrcat(directory
,"/");
4936 pstrcat(directory
,mask
);
4937 if (resolve_wildcards(directory
,newname
) &&
4938 copy_file(directory
,newname
,conn
,ofun
, count
,target_is_directory
,&err
))
4942 END_PROFILE(SMBcopy
);
4943 return(UNIXERROR(ERRHRD
,ERRgeneral
));
4946 exists
= vfs_file_exist(conn
,directory
,NULL
);
4949 struct smb_Dir
*dir_hnd
= NULL
;
4953 if (strequal(mask
,"????????.???"))
4956 if (check_name(directory
,conn
))
4957 dir_hnd
= OpenDir(conn
, directory
, mask
, 0);
4963 while ((dname
= ReadDirName(dir_hnd
, &offset
))) {
4965 pstrcpy(fname
,dname
);
4967 if (!is_visible_file(conn
, directory
, dname
, &sbuf1
, False
))
4970 if(!mask_match(fname
, mask
, conn
->case_sensitive
))
4973 error
= ERRnoaccess
;
4974 slprintf(fname
,sizeof(fname
)-1, "%s/%s",directory
,dname
);
4975 pstrcpy(destname
,newname
);
4976 if (resolve_wildcards(fname
,destname
) &&
4977 copy_file(fname
,destname
,conn
,ofun
,
4978 count
,target_is_directory
,&err
))
4980 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname
,destname
));
4988 /* Error on close... */
4990 END_PROFILE(SMBcopy
);
4991 return(UNIXERROR(ERRHRD
,ERRgeneral
));
4995 END_PROFILE(SMBcopy
);
4996 return ERROR_DOS(ERRDOS
,error
);
4998 if((errno
== ENOENT
) && (bad_path1
|| bad_path2
)) {
4999 set_saved_error_triple(ERRDOS
, ERRbadpath
, NT_STATUS_OK
);
5001 END_PROFILE(SMBcopy
);
5002 return(UNIXERROR(ERRDOS
,error
));
5006 outsize
= set_message(outbuf
,1,0,True
);
5007 SSVAL(outbuf
,smb_vwv0
,count
);
5009 END_PROFILE(SMBcopy
);
5013 /****************************************************************************
5015 ****************************************************************************/
5017 int reply_setdir(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
5025 START_PROFILE(pathworks_setdir
);
5028 if (!CAN_SETDIR(snum
)) {
5029 END_PROFILE(pathworks_setdir
);
5030 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5033 srvstr_get_path(inbuf
, newdir
, smb_buf(inbuf
) + 1, sizeof(newdir
), 0, STR_TERMINATE
, &status
);
5034 if (!NT_STATUS_IS_OK(status
)) {
5035 END_PROFILE(pathworks_setdir
);
5036 return ERROR_NT(status
);
5039 RESOLVE_DFSPATH(newdir
, conn
, inbuf
, outbuf
);
5041 if (strlen(newdir
) == 0) {
5044 ok
= vfs_directory_exist(conn
,newdir
,NULL
);
5046 set_conn_connectpath(conn
,newdir
);
5050 END_PROFILE(pathworks_setdir
);
5051 return ERROR_DOS(ERRDOS
,ERRbadpath
);
5054 outsize
= set_message(outbuf
,0,0,False
);
5055 SCVAL(outbuf
,smb_reh
,CVAL(inbuf
,smb_reh
));
5057 DEBUG(3,("setdir %s\n", newdir
));
5059 END_PROFILE(pathworks_setdir
);
5064 #define DBGC_CLASS DBGC_LOCKING
5066 /****************************************************************************
5067 Get a lock pid, dealing with large count requests.
5068 ****************************************************************************/
5070 uint16
get_lock_pid( char *data
, int data_offset
, BOOL large_file_format
)
5072 if(!large_file_format
)
5073 return SVAL(data
,SMB_LPID_OFFSET(data_offset
));
5075 return SVAL(data
,SMB_LARGE_LPID_OFFSET(data_offset
));
5078 /****************************************************************************
5079 Get a lock count, dealing with large count requests.
5080 ****************************************************************************/
5082 SMB_BIG_UINT
get_lock_count( char *data
, int data_offset
, BOOL large_file_format
)
5084 SMB_BIG_UINT count
= 0;
5086 if(!large_file_format
) {
5087 count
= (SMB_BIG_UINT
)IVAL(data
,SMB_LKLEN_OFFSET(data_offset
));
5090 #if defined(HAVE_LONGLONG)
5091 count
= (((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
))) << 32) |
5092 ((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
)));
5093 #else /* HAVE_LONGLONG */
5096 * NT4.x seems to be broken in that it sends large file (64 bit)
5097 * lockingX calls even if the CAP_LARGE_FILES was *not*
5098 * negotiated. For boxes without large unsigned ints truncate the
5099 * lock count by dropping the top 32 bits.
5102 if(IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
)) != 0) {
5103 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
5104 (unsigned int)IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
)),
5105 (unsigned int)IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
)) ));
5106 SIVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
),0);
5109 count
= (SMB_BIG_UINT
)IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
));
5110 #endif /* HAVE_LONGLONG */
5116 #if !defined(HAVE_LONGLONG)
5117 /****************************************************************************
5118 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
5119 ****************************************************************************/
5121 static uint32
map_lock_offset(uint32 high
, uint32 low
)
5125 uint32 highcopy
= high
;
5128 * Try and find out how many significant bits there are in high.
5131 for(i
= 0; highcopy
; i
++)
5135 * We use 31 bits not 32 here as POSIX
5136 * lock offsets may not be negative.
5139 mask
= (~0) << (31 - i
);
5142 return 0; /* Fail. */
5148 #endif /* !defined(HAVE_LONGLONG) */
5150 /****************************************************************************
5151 Get a lock offset, dealing with large offset requests.
5152 ****************************************************************************/
5154 SMB_BIG_UINT
get_lock_offset( char *data
, int data_offset
, BOOL large_file_format
, BOOL
*err
)
5156 SMB_BIG_UINT offset
= 0;
5160 if(!large_file_format
) {
5161 offset
= (SMB_BIG_UINT
)IVAL(data
,SMB_LKOFF_OFFSET(data_offset
));
5164 #if defined(HAVE_LONGLONG)
5165 offset
= (((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
))) << 32) |
5166 ((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
)));
5167 #else /* HAVE_LONGLONG */
5170 * NT4.x seems to be broken in that it sends large file (64 bit)
5171 * lockingX calls even if the CAP_LARGE_FILES was *not*
5172 * negotiated. For boxes without large unsigned ints mangle the
5173 * lock offset by mapping the top 32 bits onto the lower 32.
5176 if(IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
)) != 0) {
5177 uint32 low
= IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
));
5178 uint32 high
= IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
));
5181 if((new_low
= map_lock_offset(high
, low
)) == 0) {
5183 return (SMB_BIG_UINT
)-1;
5186 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
5187 (unsigned int)high
, (unsigned int)low
, (unsigned int)new_low
));
5188 SIVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
),0);
5189 SIVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
),new_low
);
5192 offset
= (SMB_BIG_UINT
)IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
));
5193 #endif /* HAVE_LONGLONG */
5199 /****************************************************************************
5200 Reply to a lockingX request.
5201 ****************************************************************************/
5203 int reply_lockingX(connection_struct
*conn
, char *inbuf
, char *outbuf
,
5204 int length
, int bufsize
)
5206 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv2
);
5207 unsigned char locktype
= CVAL(inbuf
,smb_vwv3
);
5208 unsigned char oplocklevel
= CVAL(inbuf
,smb_vwv3
+1);
5209 uint16 num_ulocks
= SVAL(inbuf
,smb_vwv6
);
5210 uint16 num_locks
= SVAL(inbuf
,smb_vwv7
);
5211 SMB_BIG_UINT count
= 0, offset
= 0;
5213 int32 lock_timeout
= IVAL(inbuf
,smb_vwv4
);
5216 BOOL large_file_format
=
5217 (locktype
& LOCKING_ANDX_LARGE_FILES
)?True
:False
;
5219 BOOL my_lock_ctx
= False
;
5220 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
5222 START_PROFILE(SMBlockingX
);
5224 CHECK_FSP(fsp
,conn
);
5226 data
= smb_buf(inbuf
);
5228 if (locktype
& LOCKING_ANDX_CHANGE_LOCKTYPE
) {
5229 /* we don't support these - and CANCEL_LOCK makes w2k
5230 and XP reboot so I don't really want to be
5231 compatible! (tridge) */
5232 return ERROR_FORCE_DOS(ERRDOS
, ERRnoatomiclocks
);
5235 if (locktype
& LOCKING_ANDX_CANCEL_LOCK
) {
5236 /* Need to make this like a cancel.... JRA. */
5237 return ERROR_NT(NT_STATUS_UNSUCCESSFUL
);
5240 /* Check if this is an oplock break on a file
5241 we have granted an oplock on.
5243 if ((locktype
& LOCKING_ANDX_OPLOCK_RELEASE
)) {
5244 /* Client can insist on breaking to none. */
5245 BOOL break_to_none
= (oplocklevel
== 0);
5248 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
5249 "for fnum = %d\n", (unsigned int)oplocklevel
,
5253 * Make sure we have granted an exclusive or batch oplock on
5257 if (fsp
->oplock_type
== 0) {
5259 /* The Samba4 nbench simulator doesn't understand
5260 the difference between break to level2 and break
5261 to none from level2 - it sends oplock break
5262 replies in both cases. Don't keep logging an error
5263 message here - just ignore it. JRA. */
5265 DEBUG(5,("reply_lockingX: Error : oplock break from "
5266 "client for fnum = %d (oplock=%d) and no "
5267 "oplock granted on this file (%s).\n",
5268 fsp
->fnum
, fsp
->oplock_type
, fsp
->fsp_name
));
5270 /* if this is a pure oplock break request then don't
5272 if (num_locks
== 0 && num_ulocks
== 0) {
5273 END_PROFILE(SMBlockingX
);
5276 END_PROFILE(SMBlockingX
);
5277 return ERROR_DOS(ERRDOS
,ERRlock
);
5281 if ((fsp
->sent_oplock_break
== BREAK_TO_NONE_SENT
) ||
5283 result
= remove_oplock(fsp
);
5285 result
= downgrade_oplock(fsp
);
5289 DEBUG(0, ("reply_lockingX: error in removing "
5290 "oplock on file %s\n", fsp
->fsp_name
));
5291 /* Hmmm. Is this panic justified? */
5292 smb_panic("internal tdb error");
5295 reply_to_oplock_break_requests(fsp
);
5297 /* if this is a pure oplock break request then don't send a
5299 if (num_locks
== 0 && num_ulocks
== 0) {
5300 /* Sanity check - ensure a pure oplock break is not a
5302 if(CVAL(inbuf
,smb_vwv0
) != 0xff)
5303 DEBUG(0,("reply_lockingX: Error : pure oplock "
5304 "break is a chained %d request !\n",
5305 (unsigned int)CVAL(inbuf
,smb_vwv0
) ));
5306 END_PROFILE(SMBlockingX
);
5312 * We do this check *after* we have checked this is not a oplock break
5313 * response message. JRA.
5316 release_level_2_oplocks_on_change(fsp
);
5318 /* Data now points at the beginning of the list
5319 of smb_unlkrng structs */
5320 for(i
= 0; i
< (int)num_ulocks
; i
++) {
5321 lock_pid
= get_lock_pid( data
, i
, large_file_format
);
5322 count
= get_lock_count( data
, i
, large_file_format
);
5323 offset
= get_lock_offset( data
, i
, large_file_format
, &err
);
5326 * There is no error code marked "stupid client bug".... :-).
5329 END_PROFILE(SMBlockingX
);
5330 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5333 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
5334 "pid %u, file %s\n", (double)offset
, (double)count
,
5335 (unsigned int)lock_pid
, fsp
->fsp_name
));
5337 status
= do_unlock(fsp
,
5343 if (NT_STATUS_V(status
)) {
5344 END_PROFILE(SMBlockingX
);
5345 return ERROR_NT(status
);
5349 /* Setup the timeout in seconds. */
5351 lock_timeout
= ((lock_timeout
== -1) ? -1 : (lock_timeout
+999)/1000);
5353 /* Now do any requested locks */
5354 data
+= ((large_file_format
? 20 : 10)*num_ulocks
);
5356 /* Data now points at the beginning of the list
5357 of smb_lkrng structs */
5359 for(i
= 0; i
< (int)num_locks
; i
++) {
5360 enum brl_type lock_type
= ((locktype
& 1) ? READ_LOCK
:WRITE_LOCK
);
5361 lock_pid
= get_lock_pid( data
, i
, large_file_format
);
5362 count
= get_lock_count( data
, i
, large_file_format
);
5363 offset
= get_lock_offset( data
, i
, large_file_format
, &err
);
5366 * There is no error code marked "stupid client bug".... :-).
5369 END_PROFILE(SMBlockingX
);
5370 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5373 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
5374 "%u, file %s timeout = %d\n", (double)offset
,
5375 (double)count
, (unsigned int)lock_pid
,
5376 fsp
->fsp_name
, (int)lock_timeout
));
5378 status
= do_lock_spin(fsp
,
5386 if (NT_STATUS_V(status
)) {
5388 * Interesting fact found by IFSTEST /t
5389 * LockOverlappedTest... Even if it's our own lock
5390 * context, we need to wait here as there may be an
5391 * unlock on the way. So I removed a "&&
5392 * !my_lock_ctx" from the following if statement. JRA.
5394 if ((lock_timeout
!= 0) &&
5395 lp_blocking_locks(SNUM(conn
)) &&
5396 ERROR_WAS_LOCK_DENIED(status
)) {
5398 * A blocking lock was requested. Package up
5399 * this smb into a queued request and push it
5400 * onto the blocking lock queue.
5402 if(push_blocking_lock_request(inbuf
, length
,
5411 END_PROFILE(SMBlockingX
);
5419 /* If any of the above locks failed, then we must unlock
5420 all of the previous locks (X/Open spec). */
5421 if (i
!= num_locks
&& num_locks
!= 0) {
5423 * Ensure we don't do a remove on the lock that just failed,
5424 * as under POSIX rules, if we have a lock already there, we
5425 * will delete it (and we shouldn't) .....
5427 for(i
--; i
>= 0; i
--) {
5428 lock_pid
= get_lock_pid( data
, i
, large_file_format
);
5429 count
= get_lock_count( data
, i
, large_file_format
);
5430 offset
= get_lock_offset( data
, i
, large_file_format
,
5434 * There is no error code marked "stupid client
5438 END_PROFILE(SMBlockingX
);
5439 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5448 END_PROFILE(SMBlockingX
);
5449 return ERROR_NT(status
);
5452 set_message(outbuf
,2,0,True
);
5454 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
5455 fsp
->fnum
, (unsigned int)locktype
, num_locks
, num_ulocks
));
5457 END_PROFILE(SMBlockingX
);
5458 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
5462 #define DBGC_CLASS DBGC_ALL
5464 /****************************************************************************
5465 Reply to a SMBreadbmpx (read block multiplex) request.
5466 ****************************************************************************/
5468 int reply_readbmpx(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
5479 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5480 START_PROFILE(SMBreadBmpx
);
5482 /* this function doesn't seem to work - disable by default */
5483 if (!lp_readbmpx()) {
5484 END_PROFILE(SMBreadBmpx
);
5485 return ERROR_DOS(ERRSRV
,ERRuseSTD
);
5488 outsize
= set_message(outbuf
,8,0,True
);
5490 CHECK_FSP(fsp
,conn
);
5491 if (!CHECK_READ(fsp
,inbuf
)) {
5492 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
5495 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv1
);
5496 maxcount
= SVAL(inbuf
,smb_vwv3
);
5498 data
= smb_buf(outbuf
);
5499 pad
= ((long)data
)%4;
5504 max_per_packet
= bufsize
-(outsize
+pad
);
5508 if (is_locked(fsp
,(SMB_BIG_UINT
)maxcount
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
5509 END_PROFILE(SMBreadBmpx
);
5510 return ERROR_DOS(ERRDOS
,ERRlock
);
5514 size_t N
= MIN(max_per_packet
,tcount
-total_read
);
5516 nread
= read_file(fsp
,data
,startpos
,N
);
5521 if (nread
< (ssize_t
)N
)
5522 tcount
= total_read
+ nread
;
5524 set_message(outbuf
,8,nread
+pad
,False
);
5525 SIVAL(outbuf
,smb_vwv0
,startpos
);
5526 SSVAL(outbuf
,smb_vwv2
,tcount
);
5527 SSVAL(outbuf
,smb_vwv6
,nread
);
5528 SSVAL(outbuf
,smb_vwv7
,smb_offset(data
,outbuf
));
5531 if (!send_smb(smbd_server_fd(),outbuf
))
5532 exit_server("reply_readbmpx: send_smb failed.");
5534 total_read
+= nread
;
5536 } while (total_read
< (ssize_t
)tcount
);
5538 END_PROFILE(SMBreadBmpx
);
5542 /****************************************************************************
5543 Reply to a SMBsetattrE.
5544 ****************************************************************************/
5546 int reply_setattrE(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
5548 struct utimbuf unix_times
;
5550 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5551 START_PROFILE(SMBsetattrE
);
5553 outsize
= set_message(outbuf
,0,0,False
);
5555 if(!fsp
|| (fsp
->conn
!= conn
)) {
5556 END_PROFILE(SMBsetattrE
);
5557 return ERROR_DOS(ERRDOS
,ERRbadfid
);
5561 * Convert the DOS times into unix times. Ignore create
5562 * time as UNIX can't set this.
5565 unix_times
.actime
= srv_make_unix_date2(inbuf
+smb_vwv3
);
5566 unix_times
.modtime
= srv_make_unix_date2(inbuf
+smb_vwv5
);
5569 * Patch from Ray Frush <frush@engr.colostate.edu>
5570 * Sometimes times are sent as zero - ignore them.
5573 if (null_mtime(unix_times
.actime
) && null_mtime(unix_times
.modtime
)) {
5574 /* Ignore request */
5575 if( DEBUGLVL( 3 ) ) {
5576 dbgtext( "reply_setattrE fnum=%d ", fsp
->fnum
);
5577 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
5579 END_PROFILE(SMBsetattrE
);
5581 } else if (!null_mtime(unix_times
.actime
) && null_mtime(unix_times
.modtime
)) {
5582 /* set modify time = to access time if modify time was unset */
5583 unix_times
.modtime
= unix_times
.actime
;
5586 /* Set the date on this file */
5587 /* Should we set pending modtime here ? JRA */
5588 if(file_utime(conn
, fsp
->fsp_name
, &unix_times
)) {
5589 END_PROFILE(SMBsetattrE
);
5590 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5593 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
5594 fsp
->fnum
, (int)unix_times
.actime
, (int)unix_times
.modtime
) );
5596 END_PROFILE(SMBsetattrE
);
5601 /* Back from the dead for OS/2..... JRA. */
5603 /****************************************************************************
5604 Reply to a SMBwritebmpx (write block multiplex primary) request.
5605 ****************************************************************************/
5607 int reply_writebmpx(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
5610 ssize_t nwritten
= -1;
5617 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5618 START_PROFILE(SMBwriteBmpx
);
5620 CHECK_FSP(fsp
,conn
);
5621 if (!CHECK_WRITE(fsp
)) {
5622 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
5624 if (HAS_CACHED_ERROR(fsp
)) {
5625 return(CACHED_ERROR(fsp
));
5628 tcount
= SVAL(inbuf
,smb_vwv1
);
5629 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
5630 write_through
= BITSETW(inbuf
+smb_vwv7
,0);
5631 numtowrite
= SVAL(inbuf
,smb_vwv10
);
5632 smb_doff
= SVAL(inbuf
,smb_vwv11
);
5634 data
= smb_base(inbuf
) + smb_doff
;
5636 /* If this fails we need to send an SMBwriteC response,
5637 not an SMBwritebmpx - set this up now so we don't forget */
5638 SCVAL(outbuf
,smb_com
,SMBwritec
);
5640 if (is_locked(fsp
,(SMB_BIG_UINT
)tcount
,(SMB_BIG_UINT
)startpos
,WRITE_LOCK
)) {
5641 END_PROFILE(SMBwriteBmpx
);
5642 return(ERROR_DOS(ERRDOS
,ERRlock
));
5645 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
5647 sync_file(conn
, fsp
, write_through
);
5649 if(nwritten
< (ssize_t
)numtowrite
) {
5650 END_PROFILE(SMBwriteBmpx
);
5651 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
5654 /* If the maximum to be written to this file
5655 is greater than what we just wrote then set
5656 up a secondary struct to be attached to this
5657 fd, we will use this to cache error messages etc. */
5659 if((ssize_t
)tcount
> nwritten
) {
5660 write_bmpx_struct
*wbms
;
5661 if(fsp
->wbmpx_ptr
!= NULL
)
5662 wbms
= fsp
->wbmpx_ptr
; /* Use an existing struct */
5664 wbms
= SMB_MALLOC_P(write_bmpx_struct
);
5666 DEBUG(0,("Out of memory in reply_readmpx\n"));
5667 END_PROFILE(SMBwriteBmpx
);
5668 return(ERROR_DOS(ERRSRV
,ERRnoresource
));
5670 wbms
->wr_mode
= write_through
;
5671 wbms
->wr_discard
= False
; /* No errors yet */
5672 wbms
->wr_total_written
= nwritten
;
5673 wbms
->wr_errclass
= 0;
5675 fsp
->wbmpx_ptr
= wbms
;
5678 /* We are returning successfully, set the message type back to
5680 SCVAL(outbuf
,smb_com
,SMBwriteBmpx
);
5682 outsize
= set_message(outbuf
,1,0,True
);
5684 SSVALS(outbuf
,smb_vwv0
,-1); /* We don't support smb_remaining */
5686 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
5687 fsp
->fnum
, (int)numtowrite
, (int)nwritten
) );
5689 if (write_through
&& tcount
==nwritten
) {
5690 /* We need to send both a primary and a secondary response */
5691 smb_setlen(outbuf
,outsize
- 4);
5693 if (!send_smb(smbd_server_fd(),outbuf
))
5694 exit_server("reply_writebmpx: send_smb failed.");
5696 /* Now the secondary */
5697 outsize
= set_message(outbuf
,1,0,True
);
5698 SCVAL(outbuf
,smb_com
,SMBwritec
);
5699 SSVAL(outbuf
,smb_vwv0
,nwritten
);
5702 END_PROFILE(SMBwriteBmpx
);
5706 /****************************************************************************
5707 Reply to a SMBwritebs (write block multiplex secondary) request.
5708 ****************************************************************************/
5710 int reply_writebs(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
5713 ssize_t nwritten
= -1;
5720 write_bmpx_struct
*wbms
;
5721 BOOL send_response
= False
;
5722 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5723 START_PROFILE(SMBwriteBs
);
5725 CHECK_FSP(fsp
,conn
);
5726 if (!CHECK_WRITE(fsp
)) {
5727 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
5730 tcount
= SVAL(inbuf
,smb_vwv1
);
5731 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
5732 numtowrite
= SVAL(inbuf
,smb_vwv6
);
5733 smb_doff
= SVAL(inbuf
,smb_vwv7
);
5735 data
= smb_base(inbuf
) + smb_doff
;
5737 /* We need to send an SMBwriteC response, not an SMBwritebs */
5738 SCVAL(outbuf
,smb_com
,SMBwritec
);
5740 /* This fd should have an auxiliary struct attached,
5741 check that it does */
5742 wbms
= fsp
->wbmpx_ptr
;
5744 END_PROFILE(SMBwriteBs
);
5748 /* If write through is set we can return errors, else we must cache them */
5749 write_through
= wbms
->wr_mode
;
5751 /* Check for an earlier error */
5752 if(wbms
->wr_discard
) {
5753 END_PROFILE(SMBwriteBs
);
5754 return -1; /* Just discard the packet */
5757 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
5759 sync_file(conn
, fsp
, write_through
);
5761 if (nwritten
< (ssize_t
)numtowrite
) {
5763 /* We are returning an error - we can delete the aux struct */
5766 fsp
->wbmpx_ptr
= NULL
;
5767 END_PROFILE(SMBwriteBs
);
5768 return(ERROR_DOS(ERRHRD
,ERRdiskfull
));
5770 wbms
->wr_errclass
= ERRHRD
;
5771 wbms
->wr_error
= ERRdiskfull
;
5772 wbms
->wr_status
= NT_STATUS_DISK_FULL
;
5773 wbms
->wr_discard
= True
;
5774 END_PROFILE(SMBwriteBs
);
5778 /* Increment the total written, if this matches tcount
5779 we can discard the auxiliary struct (hurrah !) and return a writeC */
5780 wbms
->wr_total_written
+= nwritten
;
5781 if(wbms
->wr_total_written
>= tcount
) {
5782 if (write_through
) {
5783 outsize
= set_message(outbuf
,1,0,True
);
5784 SSVAL(outbuf
,smb_vwv0
,wbms
->wr_total_written
);
5785 send_response
= True
;
5789 fsp
->wbmpx_ptr
= NULL
;
5793 END_PROFILE(SMBwriteBs
);
5797 END_PROFILE(SMBwriteBs
);
5801 /****************************************************************************
5802 Reply to a SMBgetattrE.
5803 ****************************************************************************/
5805 int reply_getattrE(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
5807 SMB_STRUCT_STAT sbuf
;
5810 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5811 START_PROFILE(SMBgetattrE
);
5813 outsize
= set_message(outbuf
,11,0,True
);
5815 if(!fsp
|| (fsp
->conn
!= conn
)) {
5816 END_PROFILE(SMBgetattrE
);
5817 return ERROR_DOS(ERRDOS
,ERRbadfid
);
5820 /* Do an fstat on this file */
5821 if(fsp_stat(fsp
, &sbuf
)) {
5822 END_PROFILE(SMBgetattrE
);
5823 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
5826 mode
= dos_mode(conn
,fsp
->fsp_name
,&sbuf
);
5829 * Convert the times into dos times. Set create
5830 * date to be last modify date as UNIX doesn't save
5834 srv_put_dos_date2(outbuf
,smb_vwv0
,get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
))));
5835 srv_put_dos_date2(outbuf
,smb_vwv2
,sbuf
.st_atime
);
5836 /* Should we check pending modtime here ? JRA */
5837 srv_put_dos_date2(outbuf
,smb_vwv4
,sbuf
.st_mtime
);
5840 SIVAL(outbuf
,smb_vwv6
,0);
5841 SIVAL(outbuf
,smb_vwv8
,0);
5843 uint32 allocation_size
= get_allocation_size(conn
,fsp
, &sbuf
);
5844 SIVAL(outbuf
,smb_vwv6
,(uint32
)sbuf
.st_size
);
5845 SIVAL(outbuf
,smb_vwv8
,allocation_size
);
5847 SSVAL(outbuf
,smb_vwv10
, mode
);
5849 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp
->fnum
));
5851 END_PROFILE(SMBgetattrE
);