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-2007.
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 a findfirst/findnext
41 path or anything including wildcards.
42 We're assuming here that '/' is not the second byte in any multibyte char
43 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
45 ****************************************************************************/
47 /* Custom version for processing POSIX paths. */
48 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
50 static NTSTATUS
check_path_syntax_internal(char *path
,
52 BOOL
*p_last_component_contains_wcard
)
56 NTSTATUS ret
= NT_STATUS_OK
;
57 BOOL start_of_name_component
= True
;
59 *p_last_component_contains_wcard
= False
;
62 if (IS_PATH_SEP(*s
,posix_path
)) {
64 * Safe to assume is not the second part of a mb char
65 * as this is handled below.
67 /* Eat multiple '/' or '\\' */
68 while (IS_PATH_SEP(*s
,posix_path
)) {
71 if ((d
!= path
) && (*s
!= '\0')) {
72 /* We only care about non-leading or trailing '/' or '\\' */
76 start_of_name_component
= True
;
78 *p_last_component_contains_wcard
= False
;
82 if (start_of_name_component
) {
83 if ((s
[0] == '.') && (s
[1] == '.') && (IS_PATH_SEP(s
[2],posix_path
) || s
[2] == '\0')) {
84 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
87 * No mb char starts with '.' so we're safe checking the directory separator here.
90 /* If we just added a '/' - delete it */
91 if ((d
> path
) && (*(d
-1) == '/')) {
96 /* Are we at the start ? Can't go back further if so. */
98 ret
= NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
101 /* Go back one level... */
102 /* We know this is safe as '/' cannot be part of a mb sequence. */
103 /* NOTE - if this assumption is invalid we are not in good shape... */
104 /* Decrement d first as d points to the *next* char to write into. */
105 for (d
--; d
> path
; d
--) {
109 s
+= 2; /* Else go past the .. */
110 /* We're still at the start of a name component, just the previous one. */
113 } else if ((s
[0] == '.') && ((s
[1] == '\0') || IS_PATH_SEP(s
[1],posix_path
))) {
126 return NT_STATUS_OBJECT_NAME_INVALID
;
134 *p_last_component_contains_wcard
= True
;
143 /* Get the size of the next MB character. */
144 next_codepoint(s
,&siz
);
162 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
164 return NT_STATUS_INVALID_PARAMETER
;
167 start_of_name_component
= False
;
174 /****************************************************************************
175 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
176 No wildcards allowed.
177 ****************************************************************************/
179 NTSTATUS
check_path_syntax(char *path
)
182 return check_path_syntax_internal(path
, False
, &ignore
);
185 /****************************************************************************
186 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
187 Wildcards allowed - p_contains_wcard returns true if the last component contained
189 ****************************************************************************/
191 NTSTATUS
check_path_syntax_wcard(char *path
, BOOL
*p_contains_wcard
)
193 return check_path_syntax_internal(path
, False
, p_contains_wcard
);
196 /****************************************************************************
197 Check the path for a POSIX client.
198 We're assuming here that '/' is not the second byte in any multibyte char
199 set (a safe assumption).
200 ****************************************************************************/
202 NTSTATUS
check_path_syntax_posix(char *path
)
205 return check_path_syntax_internal(path
, True
, &ignore
);
208 /****************************************************************************
209 Pull a string and check the path allowing a wilcard - provide for error return.
210 ****************************************************************************/
212 size_t srvstr_get_path_wcard(char *inbuf
, char *dest
, const char *src
, size_t dest_len
, size_t src_len
, int flags
,
213 NTSTATUS
*err
, BOOL
*contains_wcard
)
217 SMB_ASSERT(dest_len
== sizeof(pstring
));
221 ret
= srvstr_pull_buf( inbuf
, dest
, src
, dest_len
, flags
);
223 ret
= srvstr_pull( inbuf
, dest
, src
, dest_len
, src_len
, flags
);
226 *contains_wcard
= False
;
228 if (SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
) {
230 * For a DFS path the function parse_dfs_path()
231 * will do the path processing, just make a copy.
237 if (lp_posix_pathnames()) {
238 *err
= check_path_syntax_posix(dest
);
240 *err
= check_path_syntax_wcard(dest
, contains_wcard
);
246 /****************************************************************************
247 Pull a string and check the path - provide for error return.
248 ****************************************************************************/
250 size_t srvstr_get_path(char *inbuf
, char *dest
, const char *src
, size_t dest_len
, size_t src_len
, int flags
, NTSTATUS
*err
)
254 SMB_ASSERT(dest_len
== sizeof(pstring
));
258 ret
= srvstr_pull_buf( inbuf
, dest
, src
, dest_len
, flags
);
260 ret
= srvstr_pull( inbuf
, dest
, src
, dest_len
, src_len
, flags
);
263 if (SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
) {
265 * For a DFS path the function parse_dfs_path()
266 * will do the path processing, just make a copy.
272 if (lp_posix_pathnames()) {
273 *err
= check_path_syntax_posix(dest
);
275 *err
= check_path_syntax(dest
);
281 /****************************************************************************
282 Reply to a special message.
283 ****************************************************************************/
285 int reply_special(char *inbuf
,char *outbuf
)
288 int msg_type
= CVAL(inbuf
,0);
289 int msg_flags
= CVAL(inbuf
,1);
293 static BOOL already_got_session
= False
;
297 memset(outbuf
,'\0',smb_size
);
299 smb_setlen(inbuf
,outbuf
,0);
302 case 0x81: /* session request */
304 if (already_got_session
) {
305 exit_server_cleanly("multiple session request not permitted");
308 SCVAL(outbuf
,0,0x82);
310 if (name_len(inbuf
+4) > 50 ||
311 name_len(inbuf
+4 + name_len(inbuf
+ 4)) > 50) {
312 DEBUG(0,("Invalid name length in session request\n"));
315 name_extract(inbuf
,4,name1
);
316 name_type
= name_extract(inbuf
,4 + name_len(inbuf
+ 4),name2
);
317 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
320 set_local_machine_name(name1
, True
);
321 set_remote_machine_name(name2
, True
);
323 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
324 get_local_machine_name(), get_remote_machine_name(),
327 if (name_type
== 'R') {
328 /* We are being asked for a pathworks session ---
330 SCVAL(outbuf
, 0,0x83);
334 /* only add the client's machine name to the list
335 of possibly valid usernames if we are operating
336 in share mode security */
337 if (lp_security() == SEC_SHARE
) {
338 add_session_user(get_remote_machine_name());
341 reload_services(True
);
344 already_got_session
= True
;
347 case 0x89: /* session keepalive request
348 (some old clients produce this?) */
349 SCVAL(outbuf
,0,SMBkeepalive
);
353 case 0x82: /* positive session response */
354 case 0x83: /* negative session response */
355 case 0x84: /* retarget session response */
356 DEBUG(0,("Unexpected session response\n"));
359 case SMBkeepalive
: /* session keepalive */
364 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
365 msg_type
, msg_flags
));
370 /****************************************************************************
372 conn POINTER CAN BE NULL HERE !
373 ****************************************************************************/
375 int reply_tcon(connection_struct
*conn
,
376 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
383 uint16 vuid
= SVAL(inbuf
,smb_uid
);
387 DATA_BLOB password_blob
;
389 START_PROFILE(SMBtcon
);
391 *service_buf
= *password
= *dev
= 0;
393 p
= smb_buf(inbuf
)+1;
394 p
+= srvstr_pull_buf(inbuf
, service_buf
, p
, sizeof(service_buf
), STR_TERMINATE
) + 1;
395 pwlen
= srvstr_pull_buf(inbuf
, password
, p
, sizeof(password
), STR_TERMINATE
) + 1;
397 p
+= srvstr_pull_buf(inbuf
, dev
, p
, sizeof(dev
), STR_TERMINATE
) + 1;
399 p
= strrchr_m(service_buf
,'\\');
403 service
= service_buf
;
406 password_blob
= data_blob(password
, pwlen
+1);
408 conn
= make_connection(service
,password_blob
,dev
,vuid
,&nt_status
);
410 data_blob_clear_free(&password_blob
);
413 END_PROFILE(SMBtcon
);
414 return ERROR_NT(nt_status
);
417 outsize
= set_message(inbuf
,outbuf
,2,0,True
);
418 SSVAL(outbuf
,smb_vwv0
,max_recv
);
419 SSVAL(outbuf
,smb_vwv1
,conn
->cnum
);
420 SSVAL(outbuf
,smb_tid
,conn
->cnum
);
422 DEBUG(3,("tcon service=%s cnum=%d\n",
423 service
, conn
->cnum
));
425 END_PROFILE(SMBtcon
);
429 /****************************************************************************
430 Reply to a tcon and X.
431 conn POINTER CAN BE NULL HERE !
432 ****************************************************************************/
434 int reply_tcon_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
439 /* what the cleint thinks the device is */
440 fstring client_devicetype
;
441 /* what the server tells the client the share represents */
442 const char *server_devicetype
;
444 uint16 vuid
= SVAL(inbuf
,smb_uid
);
445 int passlen
= SVAL(inbuf
,smb_vwv3
);
448 uint16 tcon_flags
= SVAL(inbuf
,smb_vwv2
);
450 START_PROFILE(SMBtconX
);
452 *service
= *client_devicetype
= 0;
454 /* we might have to close an old one */
455 if ((SVAL(inbuf
,smb_vwv2
) & 0x1) && conn
) {
456 close_cnum(conn
,vuid
);
459 if (passlen
> MAX_PASS_LEN
) {
460 return ERROR_DOS(ERRDOS
,ERRbuftoosmall
);
463 if (global_encrypted_passwords_negotiated
) {
464 password
= data_blob(smb_buf(inbuf
),passlen
);
465 if (lp_security() == SEC_SHARE
) {
467 * Security = share always has a pad byte
468 * after the password.
470 p
= smb_buf(inbuf
) + passlen
+ 1;
472 p
= smb_buf(inbuf
) + passlen
;
475 password
= data_blob(smb_buf(inbuf
),passlen
+1);
476 /* Ensure correct termination */
477 password
.data
[passlen
]=0;
478 p
= smb_buf(inbuf
) + passlen
+ 1;
481 p
+= srvstr_pull_buf(inbuf
, path
, p
, sizeof(path
), STR_TERMINATE
);
484 * the service name can be either: \\server\share
485 * or share directly like on the DELL PowerVault 705
488 q
= strchr_m(path
+2,'\\');
490 END_PROFILE(SMBtconX
);
491 return(ERROR_DOS(ERRDOS
,ERRnosuchshare
));
493 fstrcpy(service
,q
+1);
496 fstrcpy(service
,path
);
498 p
+= srvstr_pull(inbuf
, client_devicetype
, p
, sizeof(client_devicetype
), 6, STR_ASCII
);
500 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype
, service
));
502 conn
= make_connection(service
,password
,client_devicetype
,vuid
,&nt_status
);
504 data_blob_clear_free(&password
);
507 END_PROFILE(SMBtconX
);
508 return ERROR_NT(nt_status
);
512 server_devicetype
= "IPC";
513 else if ( IS_PRINT(conn
) )
514 server_devicetype
= "LPT1:";
516 server_devicetype
= "A:";
518 if (Protocol
< PROTOCOL_NT1
) {
519 set_message(inbuf
,outbuf
,2,0,True
);
521 p
+= srvstr_push(outbuf
, p
, server_devicetype
, -1,
522 STR_TERMINATE
|STR_ASCII
);
523 set_message_end(inbuf
,outbuf
,p
);
525 /* NT sets the fstype of IPC$ to the null string */
526 const char *fstype
= IS_IPC(conn
) ? "" : lp_fstype(SNUM(conn
));
528 if (tcon_flags
& TCONX_FLAG_EXTENDED_RESPONSE
) {
529 /* Return permissions. */
533 set_message(inbuf
,outbuf
,7,0,True
);
536 perm1
= FILE_ALL_ACCESS
;
537 perm2
= FILE_ALL_ACCESS
;
539 perm1
= CAN_WRITE(conn
) ?
544 SIVAL(outbuf
, smb_vwv3
, perm1
);
545 SIVAL(outbuf
, smb_vwv5
, perm2
);
547 set_message(inbuf
,outbuf
,3,0,True
);
551 p
+= srvstr_push(outbuf
, p
, server_devicetype
, -1,
552 STR_TERMINATE
|STR_ASCII
);
553 p
+= srvstr_push(outbuf
, p
, fstype
, -1,
556 set_message_end(inbuf
,outbuf
,p
);
558 /* what does setting this bit do? It is set by NT4 and
559 may affect the ability to autorun mounted cdroms */
560 SSVAL(outbuf
, smb_vwv2
, SMB_SUPPORT_SEARCH_BITS
|
561 (lp_csc_policy(SNUM(conn
)) << 2));
563 init_dfsroot(conn
, inbuf
, outbuf
);
567 DEBUG(3,("tconX service=%s \n",
570 /* set the incoming and outgoing tid to the just created one */
571 SSVAL(inbuf
,smb_tid
,conn
->cnum
);
572 SSVAL(outbuf
,smb_tid
,conn
->cnum
);
574 END_PROFILE(SMBtconX
);
575 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
578 /****************************************************************************
579 Reply to an unknown type.
580 ****************************************************************************/
582 int reply_unknown(char *inbuf
,char *outbuf
)
585 type
= CVAL(inbuf
,smb_com
);
587 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
588 smb_fn_name(type
), type
, type
));
590 return(ERROR_DOS(ERRSRV
,ERRunknownsmb
));
593 /****************************************************************************
595 conn POINTER CAN BE NULL HERE !
596 ****************************************************************************/
598 int reply_ioctl(connection_struct
*conn
,
599 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
601 uint16 device
= SVAL(inbuf
,smb_vwv1
);
602 uint16 function
= SVAL(inbuf
,smb_vwv2
);
603 uint32 ioctl_code
= (device
<< 16) + function
;
604 int replysize
, outsize
;
606 START_PROFILE(SMBioctl
);
608 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code
));
610 switch (ioctl_code
) {
611 case IOCTL_QUERY_JOB_INFO
:
615 END_PROFILE(SMBioctl
);
616 return(ERROR_DOS(ERRSRV
,ERRnosupport
));
619 outsize
= set_message(inbuf
,outbuf
,8,replysize
+1,True
);
620 SSVAL(outbuf
,smb_vwv1
,replysize
); /* Total data bytes returned */
621 SSVAL(outbuf
,smb_vwv5
,replysize
); /* Data bytes this buffer */
622 SSVAL(outbuf
,smb_vwv6
,52); /* Offset to data */
623 p
= smb_buf(outbuf
) + 1; /* Allow for alignment */
625 switch (ioctl_code
) {
626 case IOCTL_QUERY_JOB_INFO
:
628 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
630 END_PROFILE(SMBioctl
);
631 return(UNIXERROR(ERRDOS
,ERRbadfid
));
633 SSVAL(p
,0,fsp
->rap_print_jobid
); /* Job number */
634 srvstr_push(outbuf
, p
+2, global_myname(), 15, STR_TERMINATE
|STR_ASCII
);
636 srvstr_push(outbuf
, p
+18, lp_servicename(SNUM(conn
)), 13, STR_TERMINATE
|STR_ASCII
);
642 END_PROFILE(SMBioctl
);
646 /****************************************************************************
647 Strange checkpath NTSTATUS mapping.
648 ****************************************************************************/
650 static NTSTATUS
map_checkpath_error(const char *inbuf
, NTSTATUS status
)
652 /* Strange DOS error code semantics only for checkpath... */
653 if (!(SVAL(inbuf
,smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
)) {
654 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID
,status
)) {
655 /* We need to map to ERRbadpath */
656 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
662 /****************************************************************************
663 Reply to a checkpath.
664 ****************************************************************************/
666 int reply_checkpath(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
670 SMB_STRUCT_STAT sbuf
;
673 START_PROFILE(SMBcheckpath
);
675 srvstr_get_path(inbuf
, name
, smb_buf(inbuf
) + 1, sizeof(name
), 0, STR_TERMINATE
, &status
);
676 if (!NT_STATUS_IS_OK(status
)) {
677 END_PROFILE(SMBcheckpath
);
678 status
= map_checkpath_error(inbuf
, status
);
679 return ERROR_NT(status
);
682 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, name
);
683 if (!NT_STATUS_IS_OK(status
)) {
684 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
685 END_PROFILE(SMBcheckpath
);
686 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
691 DEBUG(3,("reply_checkpath %s mode=%d\n", name
, (int)SVAL(inbuf
,smb_vwv0
)));
693 status
= unix_convert(conn
, name
, False
, NULL
, &sbuf
);
694 if (!NT_STATUS_IS_OK(status
)) {
698 status
= check_name(conn
, name
);
699 if (!NT_STATUS_IS_OK(status
)) {
700 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name
,nt_errstr(status
)));
704 if (!VALID_STAT(sbuf
) && (SMB_VFS_STAT(conn
,name
,&sbuf
) != 0)) {
705 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name
,strerror(errno
)));
706 status
= map_nt_error_from_unix(errno
);
710 if (!S_ISDIR(sbuf
.st_mode
)) {
711 END_PROFILE(SMBcheckpath
);
712 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY
,ERRDOS
,ERRbadpath
);
715 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
717 END_PROFILE(SMBcheckpath
);
722 END_PROFILE(SMBcheckpath
);
724 /* We special case this - as when a Windows machine
725 is parsing a path is steps through the components
726 one at a time - if a component fails it expects
727 ERRbadpath, not ERRbadfile.
729 status
= map_checkpath_error(inbuf
, status
);
730 if(NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
732 * Windows returns different error codes if
733 * the parent directory is valid but not the
734 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
735 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
736 * if the path is invalid.
738 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND
,ERRDOS
,ERRbadpath
);
741 return ERROR_NT(status
);
744 /****************************************************************************
746 ****************************************************************************/
748 int reply_getatr(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
752 SMB_STRUCT_STAT sbuf
;
759 START_PROFILE(SMBgetatr
);
761 p
= smb_buf(inbuf
) + 1;
762 p
+= srvstr_get_path(inbuf
, fname
, p
, sizeof(fname
), 0, STR_TERMINATE
, &status
);
763 if (!NT_STATUS_IS_OK(status
)) {
764 END_PROFILE(SMBgetatr
);
765 return ERROR_NT(status
);
768 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
769 if (!NT_STATUS_IS_OK(status
)) {
770 END_PROFILE(SMBgetatr
);
771 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
772 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
774 return ERROR_NT(status
);
777 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
778 under WfWg - weird! */
779 if (*fname
== '\0') {
780 mode
= aHIDDEN
| aDIR
;
781 if (!CAN_WRITE(conn
)) {
787 status
= unix_convert(conn
, fname
, False
, NULL
,&sbuf
);
788 if (!NT_STATUS_IS_OK(status
)) {
789 END_PROFILE(SMBgetatr
);
790 return ERROR_NT(status
);
792 status
= check_name(conn
, fname
);
793 if (!NT_STATUS_IS_OK(status
)) {
794 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname
,nt_errstr(status
)));
795 END_PROFILE(SMBgetatr
);
796 return ERROR_NT(status
);
798 if (!VALID_STAT(sbuf
) && (SMB_VFS_STAT(conn
,fname
,&sbuf
) != 0)) {
799 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname
,strerror(errno
)));
800 return UNIXERROR(ERRDOS
,ERRbadfile
);
803 mode
= dos_mode(conn
,fname
,&sbuf
);
805 mtime
= sbuf
.st_mtime
;
811 outsize
= set_message(inbuf
,outbuf
,10,0,True
);
813 SSVAL(outbuf
,smb_vwv0
,mode
);
814 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
815 srv_put_dos_date3(outbuf
,smb_vwv1
,mtime
& ~1);
817 srv_put_dos_date3(outbuf
,smb_vwv1
,mtime
);
819 SIVAL(outbuf
,smb_vwv3
,(uint32
)size
);
821 if (Protocol
>= PROTOCOL_NT1
) {
822 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
, smb_flg2
) | FLAGS2_IS_LONG_NAME
);
825 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname
, mode
, (unsigned int)size
) );
827 END_PROFILE(SMBgetatr
);
831 /****************************************************************************
833 ****************************************************************************/
835 int reply_setatr(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
841 SMB_STRUCT_STAT sbuf
;
845 START_PROFILE(SMBsetatr
);
847 p
= smb_buf(inbuf
) + 1;
848 p
+= srvstr_get_path(inbuf
, fname
, p
, sizeof(fname
), 0, STR_TERMINATE
, &status
);
849 if (!NT_STATUS_IS_OK(status
)) {
850 END_PROFILE(SMBsetatr
);
851 return ERROR_NT(status
);
854 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
855 if (!NT_STATUS_IS_OK(status
)) {
856 END_PROFILE(SMBsetatr
);
857 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
858 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
860 return ERROR_NT(status
);
863 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
864 if (!NT_STATUS_IS_OK(status
)) {
865 END_PROFILE(SMBsetatr
);
866 return ERROR_NT(status
);
869 status
= check_name(conn
, fname
);
870 if (!NT_STATUS_IS_OK(status
)) {
871 END_PROFILE(SMBsetatr
);
872 return ERROR_NT(status
);
875 if (fname
[0] == '.' && fname
[1] == '\0') {
877 * Not sure here is the right place to catch this
878 * condition. Might be moved to somewhere else later -- vl
880 END_PROFILE(SMBsetatr
);
881 return ERROR_NT(NT_STATUS_ACCESS_DENIED
);
884 mode
= SVAL(inbuf
,smb_vwv0
);
885 mtime
= srv_make_unix_date3(inbuf
+smb_vwv1
);
887 if (mode
!= FILE_ATTRIBUTE_NORMAL
) {
888 if (VALID_STAT_OF_DIR(sbuf
))
893 if (file_set_dosmode(conn
,fname
,mode
,&sbuf
,False
) != 0) {
894 END_PROFILE(SMBsetatr
);
895 return UNIXERROR(ERRDOS
, ERRnoaccess
);
899 if (!set_filetime(conn
,fname
,convert_time_t_to_timespec(mtime
))) {
900 END_PROFILE(SMBsetatr
);
901 return UNIXERROR(ERRDOS
, ERRnoaccess
);
904 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
906 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname
, mode
) );
908 END_PROFILE(SMBsetatr
);
912 /****************************************************************************
914 ****************************************************************************/
916 int reply_dskattr(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
919 SMB_BIG_UINT dfree
,dsize
,bsize
;
920 START_PROFILE(SMBdskattr
);
922 if (get_dfree_info(conn
,".",True
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
923 END_PROFILE(SMBdskattr
);
924 return(UNIXERROR(ERRHRD
,ERRgeneral
));
927 outsize
= set_message(inbuf
,outbuf
,5,0,True
);
929 if (Protocol
<= PROTOCOL_LANMAN2
) {
930 double total_space
, free_space
;
931 /* we need to scale this to a number that DOS6 can handle. We
932 use floating point so we can handle large drives on systems
933 that don't have 64 bit integers
935 we end up displaying a maximum of 2G to DOS systems
937 total_space
= dsize
* (double)bsize
;
938 free_space
= dfree
* (double)bsize
;
940 dsize
= (total_space
+63*512) / (64*512);
941 dfree
= (free_space
+63*512) / (64*512);
943 if (dsize
> 0xFFFF) dsize
= 0xFFFF;
944 if (dfree
> 0xFFFF) dfree
= 0xFFFF;
946 SSVAL(outbuf
,smb_vwv0
,dsize
);
947 SSVAL(outbuf
,smb_vwv1
,64); /* this must be 64 for dos systems */
948 SSVAL(outbuf
,smb_vwv2
,512); /* and this must be 512 */
949 SSVAL(outbuf
,smb_vwv3
,dfree
);
951 SSVAL(outbuf
,smb_vwv0
,dsize
);
952 SSVAL(outbuf
,smb_vwv1
,bsize
/512);
953 SSVAL(outbuf
,smb_vwv2
,512);
954 SSVAL(outbuf
,smb_vwv3
,dfree
);
957 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree
));
959 END_PROFILE(SMBdskattr
);
963 /****************************************************************************
965 Can be called from SMBsearch, SMBffirst or SMBfunique.
966 ****************************************************************************/
968 int reply_search(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
978 unsigned int numentries
= 0;
979 unsigned int maxentries
= 0;
980 BOOL finished
= False
;
986 BOOL check_descend
= False
;
987 BOOL expect_close
= False
;
989 BOOL mask_contains_wcard
= False
;
990 BOOL allow_long_path_components
= (SVAL(inbuf
,smb_flg2
) & FLAGS2_LONG_PATH_COMPONENTS
) ? True
: False
;
992 START_PROFILE(SMBsearch
);
994 if (lp_posix_pathnames()) {
995 END_PROFILE(SMBsearch
);
996 return reply_unknown(inbuf
, outbuf
);
999 *mask
= *directory
= *fname
= 0;
1001 /* If we were called as SMBffirst then we must expect close. */
1002 if(CVAL(inbuf
,smb_com
) == SMBffirst
) {
1003 expect_close
= True
;
1006 outsize
= set_message(inbuf
,outbuf
,1,3,True
);
1007 maxentries
= SVAL(inbuf
,smb_vwv0
);
1008 dirtype
= SVAL(inbuf
,smb_vwv1
);
1009 p
= smb_buf(inbuf
) + 1;
1010 p
+= srvstr_get_path_wcard(inbuf
, path
, p
, sizeof(path
), 0, STR_TERMINATE
, &nt_status
, &mask_contains_wcard
);
1011 if (!NT_STATUS_IS_OK(nt_status
)) {
1012 END_PROFILE(SMBsearch
);
1013 return ERROR_NT(nt_status
);
1016 nt_status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, path
, &mask_contains_wcard
);
1017 if (!NT_STATUS_IS_OK(nt_status
)) {
1018 END_PROFILE(SMBsearch
);
1019 if (NT_STATUS_EQUAL(nt_status
,NT_STATUS_PATH_NOT_COVERED
)) {
1020 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
1022 return ERROR_NT(nt_status
);
1026 status_len
= SVAL(p
, 0);
1029 /* dirtype &= ~aDIR; */
1031 if (status_len
== 0) {
1032 SMB_STRUCT_STAT sbuf
;
1034 pstrcpy(directory
,path
);
1035 nt_status
= unix_convert(conn
, directory
, True
, NULL
, &sbuf
);
1036 if (!NT_STATUS_IS_OK(nt_status
)) {
1037 END_PROFILE(SMBsearch
);
1038 return ERROR_NT(nt_status
);
1041 nt_status
= check_name(conn
, directory
);
1042 if (!NT_STATUS_IS_OK(nt_status
)) {
1043 END_PROFILE(SMBsearch
);
1044 return ERROR_NT(nt_status
);
1047 p
= strrchr_m(directory
,'/');
1049 pstrcpy(mask
,directory
);
1050 pstrcpy(directory
,".");
1056 if (*directory
== '\0') {
1057 pstrcpy(directory
,".");
1059 memset((char *)status
,'\0',21);
1060 SCVAL(status
,0,(dirtype
& 0x1F));
1064 memcpy(status
,p
,21);
1065 status_dirtype
= CVAL(status
,0) & 0x1F;
1066 if (status_dirtype
!= (dirtype
& 0x1F)) {
1067 dirtype
= status_dirtype
;
1070 conn
->dirptr
= dptr_fetch(status
+12,&dptr_num
);
1071 if (!conn
->dirptr
) {
1074 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1075 pstrcpy(mask
, dptr_wcard(dptr_num
));
1077 * For a 'continue' search we have no string. So
1078 * check from the initial saved string.
1080 mask_contains_wcard
= ms_has_wild(mask
);
1083 p
= smb_buf(outbuf
) + 3;
1085 if (status_len
== 0) {
1086 nt_status
= dptr_create(conn
,
1090 SVAL(inbuf
,smb_pid
),
1092 mask_contains_wcard
,
1095 if (!NT_STATUS_IS_OK(nt_status
)) {
1096 return ERROR_NT(nt_status
);
1098 dptr_num
= dptr_dnum(conn
->dirptr
);
1100 dirtype
= dptr_attr(dptr_num
);
1103 DEBUG(4,("dptr_num is %d\n",dptr_num
));
1105 if ((dirtype
&0x1F) == aVOLID
) {
1106 memcpy(p
,status
,21);
1107 make_dir_struct(p
,"???????????",volume_label(SNUM(conn
)),
1108 0,aVOLID
,0,!allow_long_path_components
);
1109 dptr_fill(p
+12,dptr_num
);
1110 if (dptr_zero(p
+12) && (status_len
==0)) {
1115 p
+= DIR_STRUCT_SIZE
;
1118 maxentries
= MIN(maxentries
, ((BUFFER_SIZE
- (p
- outbuf
))/DIR_STRUCT_SIZE
));
1120 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1121 conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1122 if (in_list(conn
->dirpath
, lp_dontdescend(SNUM(conn
)),True
)) {
1123 check_descend
= True
;
1126 for (i
=numentries
;(i
<maxentries
) && !finished
;i
++) {
1127 finished
= !get_dir_entry(conn
,mask
,dirtype
,fname
,&size
,&mode
,&date
,check_descend
);
1129 memcpy(p
,status
,21);
1130 make_dir_struct(p
,mask
,fname
,size
, mode
,date
,
1131 !allow_long_path_components
);
1132 if (!dptr_fill(p
+12,dptr_num
)) {
1136 p
+= DIR_STRUCT_SIZE
;
1143 /* If we were called as SMBffirst with smb_search_id == NULL
1144 and no entries were found then return error and close dirptr
1147 if (numentries
== 0) {
1148 dptr_close(&dptr_num
);
1149 } else if(expect_close
&& status_len
== 0) {
1150 /* Close the dptr - we know it's gone */
1151 dptr_close(&dptr_num
);
1154 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1155 if(dptr_num
>= 0 && CVAL(inbuf
,smb_com
) == SMBfunique
) {
1156 dptr_close(&dptr_num
);
1159 if ((numentries
== 0) && !mask_contains_wcard
) {
1160 return ERROR_BOTH(STATUS_NO_MORE_FILES
,ERRDOS
,ERRnofiles
);
1163 SSVAL(outbuf
,smb_vwv0
,numentries
);
1164 SSVAL(outbuf
,smb_vwv1
,3 + numentries
* DIR_STRUCT_SIZE
);
1165 SCVAL(smb_buf(outbuf
),0,5);
1166 SSVAL(smb_buf(outbuf
),1,numentries
*DIR_STRUCT_SIZE
);
1168 /* The replies here are never long name. */
1169 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
, smb_flg2
) & (~FLAGS2_IS_LONG_NAME
));
1170 if (!allow_long_path_components
) {
1171 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
, smb_flg2
) & (~FLAGS2_LONG_PATH_COMPONENTS
));
1174 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1175 SSVAL(outbuf
,smb_flg2
, (SVAL(outbuf
, smb_flg2
) & (~FLAGS2_UNICODE_STRINGS
)));
1177 outsize
+= DIR_STRUCT_SIZE
*numentries
;
1178 smb_setlen(inbuf
,outbuf
,outsize
- 4);
1180 if ((! *directory
) && dptr_path(dptr_num
))
1181 slprintf(directory
, sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1183 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1184 smb_fn_name(CVAL(inbuf
,smb_com
)),
1185 mask
, directory
, dirtype
, numentries
, maxentries
) );
1187 END_PROFILE(SMBsearch
);
1191 /****************************************************************************
1192 Reply to a fclose (stop directory search).
1193 ****************************************************************************/
1195 int reply_fclose(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1204 BOOL path_contains_wcard
= False
;
1206 START_PROFILE(SMBfclose
);
1208 if (lp_posix_pathnames()) {
1209 END_PROFILE(SMBfclose
);
1210 return reply_unknown(inbuf
, outbuf
);
1213 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
1214 p
= smb_buf(inbuf
) + 1;
1215 p
+= srvstr_get_path_wcard(inbuf
, path
, p
, sizeof(path
), 0, STR_TERMINATE
, &err
, &path_contains_wcard
);
1216 if (!NT_STATUS_IS_OK(err
)) {
1217 END_PROFILE(SMBfclose
);
1218 return ERROR_NT(err
);
1221 status_len
= SVAL(p
,0);
1224 if (status_len
== 0) {
1225 END_PROFILE(SMBfclose
);
1226 return ERROR_DOS(ERRSRV
,ERRsrverror
);
1229 memcpy(status
,p
,21);
1231 if(dptr_fetch(status
+12,&dptr_num
)) {
1232 /* Close the dptr - we know it's gone */
1233 dptr_close(&dptr_num
);
1236 SSVAL(outbuf
,smb_vwv0
,0);
1238 DEBUG(3,("search close\n"));
1240 END_PROFILE(SMBfclose
);
1244 /****************************************************************************
1246 ****************************************************************************/
1248 int reply_open(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1256 SMB_STRUCT_STAT sbuf
;
1258 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1260 uint32 dos_attr
= SVAL(inbuf
,smb_vwv1
);
1263 uint32 create_disposition
;
1264 uint32 create_options
= 0;
1266 START_PROFILE(SMBopen
);
1268 deny_mode
= SVAL(inbuf
,smb_vwv0
);
1270 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
)+1, sizeof(fname
), 0, STR_TERMINATE
, &status
);
1271 if (!NT_STATUS_IS_OK(status
)) {
1272 END_PROFILE(SMBopen
);
1273 return ERROR_NT(status
);
1276 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
1277 if (!NT_STATUS_IS_OK(status
)) {
1278 END_PROFILE(SMBopen
);
1279 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1280 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
1282 return ERROR_NT(status
);
1285 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
1286 if (!NT_STATUS_IS_OK(status
)) {
1287 END_PROFILE(SMBopen
);
1288 return ERROR_NT(status
);
1291 status
= check_name(conn
, fname
);
1292 if (!NT_STATUS_IS_OK(status
)) {
1293 END_PROFILE(SMBopen
);
1294 return ERROR_NT(status
);
1297 if (!map_open_params_to_ntcreate(fname
, deny_mode
, OPENX_FILE_EXISTS_OPEN
,
1298 &access_mask
, &share_mode
, &create_disposition
, &create_options
)) {
1299 END_PROFILE(SMBopen
);
1300 return ERROR_NT(NT_STATUS_DOS(ERRDOS
, ERRbadaccess
));
1303 status
= open_file_ntcreate(conn
,fname
,&sbuf
,
1312 if (!NT_STATUS_IS_OK(status
)) {
1313 END_PROFILE(SMBopen
);
1314 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1315 /* We have re-scheduled this call. */
1318 return ERROR_NT(status
);
1321 size
= sbuf
.st_size
;
1322 fattr
= dos_mode(conn
,fname
,&sbuf
);
1323 mtime
= sbuf
.st_mtime
;
1326 DEBUG(3,("attempt to open a directory %s\n",fname
));
1327 close_file(fsp
,ERROR_CLOSE
);
1328 END_PROFILE(SMBopen
);
1329 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1332 outsize
= set_message(inbuf
,outbuf
,7,0,True
);
1333 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
1334 SSVAL(outbuf
,smb_vwv1
,fattr
);
1335 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
1336 srv_put_dos_date3(outbuf
,smb_vwv2
,mtime
& ~1);
1338 srv_put_dos_date3(outbuf
,smb_vwv2
,mtime
);
1340 SIVAL(outbuf
,smb_vwv4
,(uint32
)size
);
1341 SSVAL(outbuf
,smb_vwv6
,deny_mode
);
1343 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1344 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1347 if(EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1348 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1350 END_PROFILE(SMBopen
);
1354 /****************************************************************************
1355 Reply to an open and X.
1356 ****************************************************************************/
1358 int reply_open_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
1361 uint16 open_flags
= SVAL(inbuf
,smb_vwv2
);
1362 int deny_mode
= SVAL(inbuf
,smb_vwv3
);
1363 uint32 smb_attr
= SVAL(inbuf
,smb_vwv5
);
1364 /* Breakout the oplock request bits so we can set the
1365 reply bits separately. */
1366 int ex_oplock_request
= EXTENDED_OPLOCK_REQUEST(inbuf
);
1367 int core_oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1368 int oplock_request
= ex_oplock_request
| core_oplock_request
;
1370 int smb_sattr
= SVAL(inbuf
,smb_vwv4
);
1371 uint32 smb_time
= make_unix_date3(inbuf
+smb_vwv6
);
1373 int smb_ofun
= SVAL(inbuf
,smb_vwv8
);
1376 SMB_STRUCT_STAT sbuf
;
1380 SMB_BIG_UINT allocation_size
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv9
);
1381 ssize_t retval
= -1;
1384 uint32 create_disposition
;
1385 uint32 create_options
= 0;
1387 START_PROFILE(SMBopenX
);
1389 /* If it's an IPC, pass off the pipe handler. */
1391 if (lp_nt_pipe_support()) {
1392 END_PROFILE(SMBopenX
);
1393 return reply_open_pipe_and_X(conn
, inbuf
,outbuf
,length
,bufsize
);
1395 END_PROFILE(SMBopenX
);
1396 return ERROR_DOS(ERRSRV
,ERRaccess
);
1400 /* XXXX we need to handle passed times, sattr and flags */
1401 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
), sizeof(fname
), 0, STR_TERMINATE
, &status
);
1402 if (!NT_STATUS_IS_OK(status
)) {
1403 END_PROFILE(SMBopenX
);
1404 return ERROR_NT(status
);
1407 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
1408 if (!NT_STATUS_IS_OK(status
)) {
1409 END_PROFILE(SMBopenX
);
1410 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1411 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
1413 return ERROR_NT(status
);
1416 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
1417 if (!NT_STATUS_IS_OK(status
)) {
1418 END_PROFILE(SMBopenX
);
1419 return ERROR_NT(status
);
1422 status
= check_name(conn
, fname
);
1423 if (!NT_STATUS_IS_OK(status
)) {
1424 END_PROFILE(SMBopenX
);
1425 return ERROR_NT(status
);
1428 if (!map_open_params_to_ntcreate(fname
, deny_mode
, smb_ofun
,
1431 &create_disposition
,
1433 END_PROFILE(SMBopenX
);
1434 return ERROR_NT(NT_STATUS_DOS(ERRDOS
, ERRbadaccess
));
1437 status
= open_file_ntcreate(conn
,fname
,&sbuf
,
1446 if (!NT_STATUS_IS_OK(status
)) {
1447 END_PROFILE(SMBopenX
);
1448 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1449 /* We have re-scheduled this call. */
1452 return ERROR_NT(status
);
1455 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1456 if the file is truncated or created. */
1457 if (((smb_action
== FILE_WAS_CREATED
) || (smb_action
== FILE_WAS_OVERWRITTEN
)) && allocation_size
) {
1458 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
, allocation_size
);
1459 if (vfs_allocate_file_space(fsp
, fsp
->initial_allocation_size
) == -1) {
1460 close_file(fsp
,ERROR_CLOSE
);
1461 END_PROFILE(SMBopenX
);
1462 return ERROR_NT(NT_STATUS_DISK_FULL
);
1464 retval
= vfs_set_filelen(fsp
, (SMB_OFF_T
)allocation_size
);
1466 close_file(fsp
,ERROR_CLOSE
);
1467 END_PROFILE(SMBopenX
);
1468 return ERROR_NT(NT_STATUS_DISK_FULL
);
1470 sbuf
.st_size
= get_allocation_size(conn
,fsp
,&sbuf
);
1473 fattr
= dos_mode(conn
,fname
,&sbuf
);
1474 mtime
= sbuf
.st_mtime
;
1476 close_file(fsp
,ERROR_CLOSE
);
1477 END_PROFILE(SMBopenX
);
1478 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1481 /* If the caller set the extended oplock request bit
1482 and we granted one (by whatever means) - set the
1483 correct bit for extended oplock reply.
1486 if (ex_oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1487 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1490 if(ex_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1491 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1494 /* If the caller set the core oplock request bit
1495 and we granted one (by whatever means) - set the
1496 correct bit for core oplock reply.
1499 if (core_oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1500 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1503 if(core_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1504 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1507 if (open_flags
& EXTENDED_RESPONSE_REQUIRED
) {
1508 set_message(inbuf
,outbuf
,19,0,True
);
1510 set_message(inbuf
,outbuf
,15,0,True
);
1512 SSVAL(outbuf
,smb_vwv2
,fsp
->fnum
);
1513 SSVAL(outbuf
,smb_vwv3
,fattr
);
1514 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
1515 srv_put_dos_date3(outbuf
,smb_vwv4
,mtime
& ~1);
1517 srv_put_dos_date3(outbuf
,smb_vwv4
,mtime
);
1519 SIVAL(outbuf
,smb_vwv6
,(uint32
)sbuf
.st_size
);
1520 SSVAL(outbuf
,smb_vwv8
,GET_OPENX_MODE(deny_mode
));
1521 SSVAL(outbuf
,smb_vwv11
,smb_action
);
1523 if (open_flags
& EXTENDED_RESPONSE_REQUIRED
) {
1524 SIVAL(outbuf
, smb_vwv15
, STD_RIGHT_ALL_ACCESS
);
1527 END_PROFILE(SMBopenX
);
1528 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
1531 /****************************************************************************
1532 Reply to a SMBulogoffX.
1533 conn POINTER CAN BE NULL HERE !
1534 ****************************************************************************/
1536 int reply_ulogoffX(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
1538 uint16 vuid
= SVAL(inbuf
,smb_uid
);
1539 user_struct
*vuser
= get_valid_user_struct(vuid
);
1540 START_PROFILE(SMBulogoffX
);
1543 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid
));
1545 /* in user level security we are supposed to close any files
1546 open by this user */
1547 if ((vuser
!= 0) && (lp_security() != SEC_SHARE
))
1548 file_close_user(vuid
);
1550 invalidate_vuid(vuid
);
1552 set_message(inbuf
,outbuf
,2,0,True
);
1554 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid
) );
1556 END_PROFILE(SMBulogoffX
);
1557 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
1560 /****************************************************************************
1561 Reply to a mknew or a create.
1562 ****************************************************************************/
1564 int reply_mknew(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1569 uint32 fattr
= SVAL(inbuf
,smb_vwv0
);
1570 struct timespec ts
[2];
1572 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1573 SMB_STRUCT_STAT sbuf
;
1575 uint32 access_mask
= FILE_GENERIC_READ
| FILE_GENERIC_WRITE
;
1576 uint32 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
1577 uint32 create_disposition
;
1578 uint32 create_options
= 0;
1580 START_PROFILE(SMBcreate
);
1582 com
= SVAL(inbuf
,smb_com
);
1584 ts
[1] = convert_time_t_to_timespec(srv_make_unix_date3(inbuf
+ smb_vwv1
)); /* mtime. */
1586 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
) + 1, sizeof(fname
), 0, STR_TERMINATE
, &status
);
1587 if (!NT_STATUS_IS_OK(status
)) {
1588 END_PROFILE(SMBcreate
);
1589 return ERROR_NT(status
);
1592 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
1593 if (!NT_STATUS_IS_OK(status
)) {
1594 END_PROFILE(SMBcreate
);
1595 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1596 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
1598 return ERROR_NT(status
);
1601 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
1602 if (!NT_STATUS_IS_OK(status
)) {
1603 END_PROFILE(SMBcreate
);
1604 return ERROR_NT(status
);
1607 status
= check_name(conn
, fname
);
1608 if (!NT_STATUS_IS_OK(status
)) {
1609 END_PROFILE(SMBcreate
);
1610 return ERROR_NT(status
);
1613 if (fattr
& aVOLID
) {
1614 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname
));
1617 if(com
== SMBmknew
) {
1618 /* We should fail if file exists. */
1619 create_disposition
= FILE_CREATE
;
1621 /* Create if file doesn't exist, truncate if it does. */
1622 create_disposition
= FILE_OVERWRITE_IF
;
1625 /* Open file using ntcreate. */
1626 status
= open_file_ntcreate(conn
,fname
,&sbuf
,
1635 if (!NT_STATUS_IS_OK(status
)) {
1636 END_PROFILE(SMBcreate
);
1637 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1638 /* We have re-scheduled this call. */
1641 return ERROR_NT(status
);
1644 ts
[0] = get_atimespec(&sbuf
); /* atime. */
1645 file_ntimes(conn
, fname
, ts
);
1647 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
1648 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
1650 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1651 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1654 if(EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1655 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1658 DEBUG( 2, ( "reply_mknew: file %s\n", fname
) );
1659 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname
, fsp
->fh
->fd
, (unsigned int)fattr
) );
1661 END_PROFILE(SMBcreate
);
1665 /****************************************************************************
1666 Reply to a create temporary file.
1667 ****************************************************************************/
1669 int reply_ctemp(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
1673 uint32 fattr
= SVAL(inbuf
,smb_vwv0
);
1675 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1677 SMB_STRUCT_STAT sbuf
;
1680 unsigned int namelen
;
1682 START_PROFILE(SMBctemp
);
1684 srvstr_get_path(inbuf
, fname
, smb_buf(inbuf
)+1, sizeof(fname
), 0, STR_TERMINATE
, &status
);
1685 if (!NT_STATUS_IS_OK(status
)) {
1686 END_PROFILE(SMBctemp
);
1687 return ERROR_NT(status
);
1690 pstrcat(fname
,"/TMXXXXXX");
1692 pstrcat(fname
,"TMXXXXXX");
1695 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
1696 if (!NT_STATUS_IS_OK(status
)) {
1697 END_PROFILE(SMBctemp
);
1698 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1699 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
1701 return ERROR_NT(status
);
1704 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
1705 if (!NT_STATUS_IS_OK(status
)) {
1706 END_PROFILE(SMBctemp
);
1707 return ERROR_NT(status
);
1710 status
= check_name(conn
, fname
);
1711 if (!NT_STATUS_IS_OK(status
)) {
1712 END_PROFILE(SMBctemp
);
1713 return ERROR_NT(status
);
1716 tmpfd
= smb_mkstemp(fname
);
1718 END_PROFILE(SMBctemp
);
1719 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1722 SMB_VFS_STAT(conn
,fname
,&sbuf
);
1724 /* We should fail if file does not exist. */
1725 status
= open_file_ntcreate(conn
,fname
,&sbuf
,
1726 FILE_GENERIC_READ
| FILE_GENERIC_WRITE
,
1727 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1734 /* close fd from smb_mkstemp() */
1737 if (!NT_STATUS_IS_OK(status
)) {
1738 END_PROFILE(SMBctemp
);
1739 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
1740 /* We have re-scheduled this call. */
1743 return ERROR_NT(status
);
1746 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
1747 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
1749 /* the returned filename is relative to the directory */
1750 s
= strrchr_m(fname
, '/');
1757 p
= smb_buf(outbuf
);
1759 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
1760 thing in the byte section. JRA */
1761 SSVALS(p
, 0, -1); /* what is this? not in spec */
1763 namelen
= srvstr_push(outbuf
, p
, s
, -1, STR_ASCII
|STR_TERMINATE
);
1765 outsize
= set_message_end(inbuf
,outbuf
, p
);
1767 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1768 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1771 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1772 SCVAL(outbuf
,smb_flg
,CVAL(outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1775 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname
) );
1776 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname
, fsp
->fh
->fd
,
1777 (unsigned int)sbuf
.st_mode
) );
1779 END_PROFILE(SMBctemp
);
1783 /*******************************************************************
1784 Check if a user is allowed to rename a file.
1785 ********************************************************************/
1787 static NTSTATUS
can_rename(connection_struct
*conn
, files_struct
*fsp
,
1788 uint16 dirtype
, SMB_STRUCT_STAT
*pst
)
1792 if (!CAN_WRITE(conn
)) {
1793 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
1796 fmode
= dos_mode(conn
, fsp
->fsp_name
, pst
);
1797 if ((fmode
& ~dirtype
) & (aHIDDEN
| aSYSTEM
)) {
1798 return NT_STATUS_NO_SUCH_FILE
;
1801 if (S_ISDIR(pst
->st_mode
)) {
1802 return NT_STATUS_OK
;
1805 if (fsp
->access_mask
& DELETE_ACCESS
) {
1806 return NT_STATUS_OK
;
1809 return NT_STATUS_ACCESS_DENIED
;
1812 /*******************************************************************
1813 * unlink a file with all relevant access checks
1814 *******************************************************************/
1816 static NTSTATUS
do_unlink(connection_struct
*conn
, char *fname
,
1817 uint32 dirtype
, BOOL can_defer
)
1819 SMB_STRUCT_STAT sbuf
;
1822 uint32 dirtype_orig
= dirtype
;
1825 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname
, dirtype
));
1827 if (!CAN_WRITE(conn
)) {
1828 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
1831 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
) != 0) {
1832 return map_nt_error_from_unix(errno
);
1835 fattr
= dos_mode(conn
,fname
,&sbuf
);
1837 if (dirtype
& FILE_ATTRIBUTE_NORMAL
) {
1838 dirtype
= aDIR
|aARCH
|aRONLY
;
1841 dirtype
&= (aDIR
|aARCH
|aRONLY
|aHIDDEN
|aSYSTEM
);
1843 return NT_STATUS_NO_SUCH_FILE
;
1846 if (!dir_check_ftype(conn
, fattr
, dirtype
)) {
1848 return NT_STATUS_FILE_IS_A_DIRECTORY
;
1850 return NT_STATUS_NO_SUCH_FILE
;
1853 if (dirtype_orig
& 0x8000) {
1854 /* These will never be set for POSIX. */
1855 return NT_STATUS_NO_SUCH_FILE
;
1859 if ((fattr
& dirtype
) & FILE_ATTRIBUTE_DIRECTORY
) {
1860 return NT_STATUS_FILE_IS_A_DIRECTORY
;
1863 if ((fattr
& ~dirtype
) & (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
)) {
1864 return NT_STATUS_NO_SUCH_FILE
;
1867 if (dirtype
& 0xFF00) {
1868 /* These will never be set for POSIX. */
1869 return NT_STATUS_NO_SUCH_FILE
;
1874 return NT_STATUS_NO_SUCH_FILE
;
1877 /* Can't delete a directory. */
1879 return NT_STATUS_FILE_IS_A_DIRECTORY
;
1884 else if (dirtype
& aDIR
) /* Asked for a directory and it isn't. */
1885 return NT_STATUS_OBJECT_NAME_INVALID
;
1886 #endif /* JRATEST */
1888 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
1890 On a Windows share, a file with read-only dosmode can be opened with
1891 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
1892 fails with NT_STATUS_CANNOT_DELETE error.
1894 This semantic causes a problem that a user can not
1895 rename a file with read-only dosmode on a Samba share
1896 from a Windows command prompt (i.e. cmd.exe, but can rename
1897 from Windows Explorer).
1900 if (!lp_delete_readonly(SNUM(conn
))) {
1901 if (fattr
& aRONLY
) {
1902 return NT_STATUS_CANNOT_DELETE
;
1906 /* On open checks the open itself will check the share mode, so
1907 don't do it here as we'll get it wrong. */
1909 status
= open_file_ntcreate(conn
, fname
, &sbuf
,
1914 FILE_ATTRIBUTE_NORMAL
,
1915 can_defer
? 0 : INTERNAL_OPEN_ONLY
,
1918 if (!NT_STATUS_IS_OK(status
)) {
1919 DEBUG(10, ("open_file_ntcreate failed: %s\n",
1920 nt_errstr(status
)));
1924 /* The set is across all open files on this dev/inode pair. */
1925 if (!set_delete_on_close(fsp
, True
, ¤t_user
.ut
)) {
1926 close_file(fsp
, NORMAL_CLOSE
);
1927 return NT_STATUS_ACCESS_DENIED
;
1930 return close_file(fsp
,NORMAL_CLOSE
);
1933 /****************************************************************************
1934 The guts of the unlink command, split out so it may be called by the NT SMB
1936 ****************************************************************************/
1938 NTSTATUS
unlink_internals(connection_struct
*conn
, uint32 dirtype
,
1939 char *name
, BOOL has_wild
, BOOL can_defer
)
1945 NTSTATUS status
= NT_STATUS_OK
;
1946 SMB_STRUCT_STAT sbuf
;
1948 *directory
= *mask
= 0;
1950 status
= unix_convert(conn
, name
, has_wild
, NULL
, &sbuf
);
1951 if (!NT_STATUS_IS_OK(status
)) {
1955 p
= strrchr_m(name
,'/');
1957 pstrcpy(directory
,".");
1961 pstrcpy(directory
,name
);
1966 * We should only check the mangled cache
1967 * here if unix_convert failed. This means
1968 * that the path in 'mask' doesn't exist
1969 * on the file system and so we need to look
1970 * for a possible mangle. This patch from
1971 * Tine Smukavec <valentin.smukavec@hermes.si>.
1974 if (!VALID_STAT(sbuf
) && mangle_is_mangled(mask
,conn
->params
))
1975 mangle_check_cache( mask
, sizeof(pstring
)-1, conn
->params
);
1978 pstrcat(directory
,"/");
1979 pstrcat(directory
,mask
);
1981 dirtype
= FILE_ATTRIBUTE_NORMAL
;
1984 status
= check_name(conn
, directory
);
1985 if (!NT_STATUS_IS_OK(status
)) {
1989 status
= do_unlink(conn
,directory
,dirtype
,can_defer
);
1990 if (!NT_STATUS_IS_OK(status
)) {
1996 struct smb_Dir
*dir_hnd
= NULL
;
2000 if ((dirtype
& SAMBA_ATTRIBUTES_MASK
) == aDIR
) {
2001 return NT_STATUS_OBJECT_NAME_INVALID
;
2004 if (strequal(mask
,"????????.???")) {
2008 status
= check_name(conn
, directory
);
2009 if (!NT_STATUS_IS_OK(status
)) {
2013 dir_hnd
= OpenDir(conn
, directory
, mask
, dirtype
);
2014 if (dir_hnd
== NULL
) {
2015 return map_nt_error_from_unix(errno
);
2018 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2019 the pattern matches against the long name, otherwise the short name
2020 We don't implement this yet XXXX
2023 status
= NT_STATUS_NO_SUCH_FILE
;
2025 while ((dname
= ReadDirName(dir_hnd
, &offset
))) {
2028 pstrcpy(fname
,dname
);
2030 if (!is_visible_file(conn
, directory
, dname
, &st
, True
)) {
2034 /* Quick check for "." and ".." */
2035 if (fname
[0] == '.') {
2036 if (!fname
[1] || (fname
[1] == '.' && !fname
[2])) {
2041 if(!mask_match(fname
, mask
, conn
->case_sensitive
)) {
2045 slprintf(fname
,sizeof(fname
)-1, "%s/%s",directory
,dname
);
2047 status
= check_name(conn
, fname
);
2048 if (!NT_STATUS_IS_OK(status
)) {
2053 status
= do_unlink(conn
, fname
, dirtype
, can_defer
);
2054 if (!NT_STATUS_IS_OK(status
)) {
2059 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",
2065 if (count
== 0 && NT_STATUS_IS_OK(status
)) {
2066 status
= map_nt_error_from_unix(errno
);
2072 /****************************************************************************
2074 ****************************************************************************/
2076 int reply_unlink(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
,
2083 BOOL path_contains_wcard
= False
;
2085 START_PROFILE(SMBunlink
);
2087 dirtype
= SVAL(inbuf
,smb_vwv0
);
2089 srvstr_get_path_wcard(inbuf
, name
, smb_buf(inbuf
) + 1, sizeof(name
), 0, STR_TERMINATE
, &status
, &path_contains_wcard
);
2090 if (!NT_STATUS_IS_OK(status
)) {
2091 END_PROFILE(SMBunlink
);
2092 return ERROR_NT(status
);
2095 status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, name
, &path_contains_wcard
);
2096 if (!NT_STATUS_IS_OK(status
)) {
2097 END_PROFILE(SMBunlink
);
2098 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
2099 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
2101 return ERROR_NT(status
);
2104 DEBUG(3,("reply_unlink : %s\n",name
));
2106 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
);
2116 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
2118 END_PROFILE(SMBunlink
);
2122 /****************************************************************************
2124 ****************************************************************************/
2126 static void fail_readraw(void)
2129 slprintf(errstr
, sizeof(errstr
)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
2131 exit_server_cleanly(errstr
);
2134 /****************************************************************************
2135 Fake (read/write) sendfile. Returns -1 on read or write fail.
2136 ****************************************************************************/
2138 static ssize_t
fake_sendfile(files_struct
*fsp
, SMB_OFF_T startpos
, size_t nread
, char *buf
, size_t bufsize
)
2140 size_t tosend
= nread
;
2142 while (tosend
> 0) {
2146 if (tosend
> bufsize
) {
2151 ret
= read_file(fsp
,buf
,startpos
,cur_read
);
2156 /* If we had a short read, fill with zeros. */
2157 if (ret
< cur_read
) {
2158 memset(buf
, '\0', cur_read
- ret
);
2161 if (write_data(smbd_server_fd(),buf
,cur_read
) != cur_read
) {
2165 startpos
+= cur_read
;
2168 return (ssize_t
)nread
;
2171 /****************************************************************************
2172 Use sendfile in readbraw.
2173 ****************************************************************************/
2175 void send_file_readbraw(connection_struct
*conn
, files_struct
*fsp
, SMB_OFF_T startpos
, size_t nread
,
2176 ssize_t mincount
, char *outbuf
, int out_buffsize
)
2180 #if defined(WITH_SENDFILE)
2182 * We can only use sendfile on a non-chained packet
2183 * but we can use on a non-oplocked file. tridge proved this
2184 * on a train in Germany :-). JRA.
2185 * reply_readbraw has already checked the length.
2188 if ( (chain_size
== 0) && (nread
> 0) &&
2189 (fsp
->wcp
== NULL
) && lp_use_sendfile(SNUM(conn
)) ) {
2192 _smb_setlen(outbuf
,nread
);
2193 header
.data
= (uint8
*)outbuf
;
2197 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp
, fsp
->fh
->fd
, &header
, startpos
, nread
) == -1) {
2198 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2199 if (errno
== ENOSYS
) {
2200 goto normal_readbraw
;
2204 * Special hack for broken Linux with no working sendfile. If we
2205 * return EINTR we sent the header but not the rest of the data.
2206 * Fake this up by doing read/write calls.
2208 if (errno
== EINTR
) {
2209 /* Ensure we don't do this again. */
2210 set_use_sendfile(SNUM(conn
), False
);
2211 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2213 if (fake_sendfile(fsp
, startpos
, nread
, outbuf
+ 4, out_buffsize
- 4) == -1) {
2214 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2215 fsp
->fsp_name
, strerror(errno
) ));
2216 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2221 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2222 fsp
->fsp_name
, strerror(errno
) ));
2223 exit_server_cleanly("send_file_readbraw sendfile failed");
2233 ret
= read_file(fsp
,outbuf
+4,startpos
,nread
);
2234 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2243 _smb_setlen(outbuf
,ret
);
2244 if (write_data(smbd_server_fd(),outbuf
,4+ret
) != 4+ret
)
2248 /****************************************************************************
2249 Reply to a readbraw (core+ protocol).
2250 ****************************************************************************/
2252 int reply_readbraw(connection_struct
*conn
, char *inbuf
, char *outbuf
, int dum_size
, int out_buffsize
)
2254 ssize_t maxcount
,mincount
;
2257 char *header
= outbuf
;
2259 START_PROFILE(SMBreadbraw
);
2261 if (srv_is_signing_active()) {
2262 exit_server_cleanly("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
2266 * Special check if an oplock break has been issued
2267 * and the readraw request croses on the wire, we must
2268 * return a zero length response here.
2271 fsp
= file_fsp(inbuf
,smb_vwv0
);
2273 if (!FNUM_OK(fsp
,conn
) || !fsp
->can_read
) {
2275 * fsp could be NULL here so use the value from the packet. JRA.
2277 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf
,smb_vwv0
)));
2278 _smb_setlen(header
,0);
2279 if (write_data(smbd_server_fd(),header
,4) != 4)
2281 END_PROFILE(SMBreadbraw
);
2285 CHECK_FSP(fsp
,conn
);
2287 flush_write_cache(fsp
, READRAW_FLUSH
);
2289 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv1
);
2290 if(CVAL(inbuf
,smb_wct
) == 10) {
2292 * This is a large offset (64 bit) read.
2294 #ifdef LARGE_SMB_OFF_T
2296 startpos
|= (((SMB_OFF_T
)IVAL(inbuf
,smb_vwv8
)) << 32);
2298 #else /* !LARGE_SMB_OFF_T */
2301 * Ensure we haven't been sent a >32 bit offset.
2304 if(IVAL(inbuf
,smb_vwv8
) != 0) {
2305 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
2306 64 bit offsets.\n", (unsigned int)IVAL(inbuf
,smb_vwv8
) ));
2307 _smb_setlen(header
,0);
2308 if (write_data(smbd_server_fd(),header
,4) != 4)
2310 END_PROFILE(SMBreadbraw
);
2314 #endif /* LARGE_SMB_OFF_T */
2317 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos
));
2318 _smb_setlen(header
,0);
2319 if (write_data(smbd_server_fd(),header
,4) != 4)
2321 END_PROFILE(SMBreadbraw
);
2325 maxcount
= (SVAL(inbuf
,smb_vwv3
) & 0xFFFF);
2326 mincount
= (SVAL(inbuf
,smb_vwv4
) & 0xFFFF);
2328 /* ensure we don't overrun the packet size */
2329 maxcount
= MIN(65535,maxcount
);
2331 if (!is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)maxcount
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
2335 if (SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
,&st
) == 0) {
2339 if (startpos
>= size
) {
2342 nread
= MIN(maxcount
,(size
- startpos
));
2346 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2347 if (nread
< mincount
)
2351 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp
->fnum
, (double)startpos
,
2352 (unsigned long)maxcount
, (unsigned long)mincount
, (unsigned long)nread
) );
2354 send_file_readbraw(conn
, fsp
, startpos
, nread
, mincount
, outbuf
, out_buffsize
);
2356 DEBUG(5,("readbraw finished\n"));
2357 END_PROFILE(SMBreadbraw
);
2362 #define DBGC_CLASS DBGC_LOCKING
2364 /****************************************************************************
2365 Reply to a lockread (core+ protocol).
2366 ****************************************************************************/
2368 int reply_lockread(connection_struct
*conn
, char *inbuf
,char *outbuf
, int length
, int dum_buffsiz
)
2376 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2377 struct byte_range_lock
*br_lck
= NULL
;
2378 START_PROFILE(SMBlockread
);
2380 CHECK_FSP(fsp
,conn
);
2381 if (!CHECK_READ(fsp
,inbuf
)) {
2382 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2385 release_level_2_oplocks_on_change(fsp
);
2387 numtoread
= SVAL(inbuf
,smb_vwv1
);
2388 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2390 outsize
= set_message(inbuf
,outbuf
,5,3,True
);
2391 numtoread
= MIN(BUFFER_SIZE
-outsize
,numtoread
);
2392 data
= smb_buf(outbuf
) + 3;
2395 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2396 * protocol request that predates the read/write lock concept.
2397 * Thus instead of asking for a read lock here we need to ask
2398 * for a write lock. JRA.
2399 * Note that the requested lock size is unaffected by max_recv.
2402 br_lck
= do_lock(smbd_messaging_context(),
2404 (uint32
)SVAL(inbuf
,smb_pid
),
2405 (SMB_BIG_UINT
)numtoread
,
2406 (SMB_BIG_UINT
)startpos
,
2409 False
, /* Non-blocking lock. */
2412 TALLOC_FREE(br_lck
);
2414 if (NT_STATUS_V(status
)) {
2415 END_PROFILE(SMBlockread
);
2416 return ERROR_NT(status
);
2420 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2423 if (numtoread
> max_recv
) {
2424 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2425 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2426 (unsigned int)numtoread
, (unsigned int)max_recv
));
2427 numtoread
= MIN(numtoread
,max_recv
);
2429 nread
= read_file(fsp
,data
,startpos
,numtoread
);
2432 END_PROFILE(SMBlockread
);
2433 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2437 SSVAL(outbuf
,smb_vwv0
,nread
);
2438 SSVAL(outbuf
,smb_vwv5
,nread
+3);
2439 SSVAL(smb_buf(outbuf
),1,nread
);
2441 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2442 fsp
->fnum
, (int)numtoread
, (int)nread
));
2444 END_PROFILE(SMBlockread
);
2449 #define DBGC_CLASS DBGC_ALL
2451 /****************************************************************************
2453 ****************************************************************************/
2455 int reply_read(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
2462 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2463 START_PROFILE(SMBread
);
2465 CHECK_FSP(fsp
,conn
);
2466 if (!CHECK_READ(fsp
,inbuf
)) {
2467 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2470 numtoread
= SVAL(inbuf
,smb_vwv1
);
2471 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2473 outsize
= set_message(inbuf
,outbuf
,5,3,True
);
2474 numtoread
= MIN(BUFFER_SIZE
-outsize
,numtoread
);
2476 * The requested read size cannot be greater than max_recv. JRA.
2478 if (numtoread
> max_recv
) {
2479 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
2480 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2481 (unsigned int)numtoread
, (unsigned int)max_recv
));
2482 numtoread
= MIN(numtoread
,max_recv
);
2485 data
= smb_buf(outbuf
) + 3;
2487 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)numtoread
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
2488 END_PROFILE(SMBread
);
2489 return ERROR_DOS(ERRDOS
,ERRlock
);
2493 nread
= read_file(fsp
,data
,startpos
,numtoread
);
2496 END_PROFILE(SMBread
);
2497 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2501 SSVAL(outbuf
,smb_vwv0
,nread
);
2502 SSVAL(outbuf
,smb_vwv5
,nread
+3);
2503 SCVAL(smb_buf(outbuf
),0,1);
2504 SSVAL(smb_buf(outbuf
),1,nread
);
2506 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2507 fsp
->fnum
, (int)numtoread
, (int)nread
) );
2509 END_PROFILE(SMBread
);
2513 /****************************************************************************
2515 ****************************************************************************/
2517 static int setup_readX_header(char *inbuf
, char *outbuf
, size_t smb_maxcnt
)
2520 char *data
= smb_buf(outbuf
);
2522 SSVAL(outbuf
,smb_vwv2
,0xFFFF); /* Remaining - must be -1. */
2523 SSVAL(outbuf
,smb_vwv5
,smb_maxcnt
);
2524 SSVAL(outbuf
,smb_vwv6
,smb_offset(data
,outbuf
));
2525 SSVAL(outbuf
,smb_vwv7
,(smb_maxcnt
>> 16));
2526 SSVAL(smb_buf(outbuf
),-2,smb_maxcnt
);
2527 SCVAL(outbuf
,smb_vwv0
,0xFF);
2528 outsize
= set_message(inbuf
, outbuf
,12,smb_maxcnt
,False
);
2529 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
2530 _smb_setlen_large(outbuf
,(smb_size
+ 12*2 + smb_maxcnt
- 4));
2534 /****************************************************************************
2535 Reply to a read and X - possibly using sendfile.
2536 ****************************************************************************/
2538 int send_file_readX(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
, int len_outbuf
,
2539 files_struct
*fsp
, SMB_OFF_T startpos
, size_t smb_maxcnt
)
2541 SMB_STRUCT_STAT sbuf
;
2544 char *data
= smb_buf(outbuf
);
2546 if(SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
, &sbuf
) == -1) {
2547 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2550 if (startpos
> sbuf
.st_size
) {
2554 if (smb_maxcnt
> (sbuf
.st_size
- startpos
)) {
2555 smb_maxcnt
= (sbuf
.st_size
- startpos
);
2558 if (smb_maxcnt
== 0) {
2562 #if defined(WITH_SENDFILE)
2564 * We can only use sendfile on a non-chained packet
2565 * but we can use on a non-oplocked file. tridge proved this
2566 * on a train in Germany :-). JRA.
2569 if ((chain_size
== 0) && (CVAL(inbuf
,smb_vwv0
) == 0xFF) &&
2570 lp_use_sendfile(SNUM(conn
)) && (fsp
->wcp
== NULL
) ) {
2574 * Set up the packet header before send. We
2575 * assume here the sendfile will work (get the
2576 * correct amount of data).
2579 setup_readX_header(inbuf
,outbuf
,smb_maxcnt
);
2580 set_message(inbuf
,outbuf
,12,smb_maxcnt
,False
);
2581 header
.data
= (uint8
*)outbuf
;
2582 header
.length
= data
- outbuf
;
2585 if ((nread
= SMB_VFS_SENDFILE( smbd_server_fd(), fsp
, fsp
->fh
->fd
, &header
, startpos
, smb_maxcnt
)) == -1) {
2586 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2587 if (errno
== ENOSYS
) {
2592 * Special hack for broken Linux with no working sendfile. If we
2593 * return EINTR we sent the header but not the rest of the data.
2594 * Fake this up by doing read/write calls.
2597 if (errno
== EINTR
) {
2598 /* Ensure we don't do this again. */
2599 set_use_sendfile(SNUM(conn
), False
);
2600 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
2602 if ((nread
= fake_sendfile(fsp
, startpos
, smb_maxcnt
, data
,
2603 len_outbuf
- (data
-outbuf
))) == -1) {
2604 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2605 fsp
->fsp_name
, strerror(errno
) ));
2606 exit_server_cleanly("send_file_readX: fake_sendfile failed");
2608 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
2609 fsp
->fnum
, (int)smb_maxcnt
, (int)nread
) );
2610 /* Returning -1 here means successful sendfile. */
2614 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2615 fsp
->fsp_name
, strerror(errno
) ));
2616 exit_server_cleanly("send_file_readX sendfile failed");
2619 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2620 fsp
->fnum
, (int)smb_maxcnt
, (int)nread
) );
2621 /* Returning -1 here means successful sendfile. */
2629 if ((smb_maxcnt
& 0xFF0000) > 0x10000) {
2630 int sendlen
= setup_readX_header(inbuf
,outbuf
,smb_maxcnt
) - smb_maxcnt
;
2631 /* Send out the header. */
2632 if (write_data(smbd_server_fd(),outbuf
,sendlen
) != sendlen
) {
2633 DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
2634 fsp
->fsp_name
, strerror(errno
) ));
2635 exit_server_cleanly("send_file_readX sendfile failed");
2637 if ((nread
= fake_sendfile(fsp
, startpos
, smb_maxcnt
, data
,
2638 len_outbuf
- (data
-outbuf
))) == -1) {
2639 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2640 fsp
->fsp_name
, strerror(errno
) ));
2641 exit_server_cleanly("send_file_readX: fake_sendfile failed");
2645 nread
= read_file(fsp
,data
,startpos
,smb_maxcnt
);
2648 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2651 outsize
= setup_readX_header(inbuf
, outbuf
,nread
);
2653 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2654 fsp
->fnum
, (int)smb_maxcnt
, (int)nread
) );
2656 /* Returning the number of bytes we want to send back - including header. */
2661 /****************************************************************************
2662 Reply to a read and X.
2663 ****************************************************************************/
2665 int reply_read_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
2667 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv2
);
2668 SMB_OFF_T startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
2670 size_t smb_maxcnt
= SVAL(inbuf
,smb_vwv5
);
2671 BOOL big_readX
= False
;
2673 size_t smb_mincnt
= SVAL(inbuf
,smb_vwv6
);
2676 START_PROFILE(SMBreadX
);
2678 /* If it's an IPC, pass off the pipe handler. */
2680 END_PROFILE(SMBreadX
);
2681 return reply_pipe_read_and_X(inbuf
,outbuf
,length
,bufsize
);
2684 CHECK_FSP(fsp
,conn
);
2685 if (!CHECK_READ(fsp
,inbuf
)) {
2686 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2689 set_message(inbuf
,outbuf
,12,0,True
);
2691 if (global_client_caps
& CAP_LARGE_READX
) {
2692 size_t upper_size
= SVAL(inbuf
,smb_vwv7
);
2693 smb_maxcnt
|= (upper_size
<<16);
2694 if (upper_size
> 1) {
2695 /* Can't do this on a chained packet. */
2696 if ((CVAL(inbuf
,smb_vwv0
) != 0xFF)) {
2697 return ERROR_NT(NT_STATUS_NOT_SUPPORTED
);
2699 /* We currently don't do this on signed or sealed data. */
2700 if (srv_is_signing_active() || srv_encryption_on()) {
2701 return ERROR_NT(NT_STATUS_NOT_SUPPORTED
);
2703 /* Is there room in the reply for this data ? */
2704 if (smb_maxcnt
> (0xFFFFFF - (smb_size
-4 + 12*2))) {
2705 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2711 if(CVAL(inbuf
,smb_wct
) == 12) {
2712 #ifdef LARGE_SMB_OFF_T
2714 * This is a large offset (64 bit) read.
2716 startpos
|= (((SMB_OFF_T
)IVAL(inbuf
,smb_vwv10
)) << 32);
2718 #else /* !LARGE_SMB_OFF_T */
2721 * Ensure we haven't been sent a >32 bit offset.
2724 if(IVAL(inbuf
,smb_vwv10
) != 0) {
2725 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2726 64 bit offsets.\n", (unsigned int)IVAL(inbuf
,smb_vwv10
) ));
2727 END_PROFILE(SMBreadX
);
2728 return ERROR_DOS(ERRDOS
,ERRbadaccess
);
2731 #endif /* LARGE_SMB_OFF_T */
2735 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)smb_maxcnt
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
2736 END_PROFILE(SMBreadX
);
2737 return ERROR_DOS(ERRDOS
,ERRlock
);
2740 if (!big_readX
&& schedule_aio_read_and_X(conn
, inbuf
, outbuf
, length
, bufsize
, fsp
, startpos
, smb_maxcnt
)) {
2741 END_PROFILE(SMBreadX
);
2745 nread
= send_file_readX(conn
, inbuf
, outbuf
, length
, bufsize
, fsp
, startpos
, smb_maxcnt
);
2746 /* Only call chain_reply if not an error. */
2747 if (nread
!= -1 && SVAL(outbuf
,smb_rcls
) == 0) {
2748 nread
= chain_reply(inbuf
,outbuf
,length
,bufsize
);
2751 END_PROFILE(SMBreadX
);
2755 /****************************************************************************
2756 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2757 ****************************************************************************/
2759 int reply_writebraw(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
2762 ssize_t total_written
=0;
2763 size_t numtowrite
=0;
2768 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2771 START_PROFILE(SMBwritebraw
);
2773 if (srv_is_signing_active()) {
2774 exit_server_cleanly("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2777 CHECK_FSP(fsp
,conn
);
2778 if (!CHECK_WRITE(fsp
)) {
2779 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2782 tcount
= IVAL(inbuf
,smb_vwv1
);
2783 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
2784 write_through
= BITSETW(inbuf
+smb_vwv7
,0);
2786 /* We have to deal with slightly different formats depending
2787 on whether we are using the core+ or lanman1.0 protocol */
2789 if(Protocol
<= PROTOCOL_COREPLUS
) {
2790 numtowrite
= SVAL(smb_buf(inbuf
),-2);
2791 data
= smb_buf(inbuf
);
2793 numtowrite
= SVAL(inbuf
,smb_vwv10
);
2794 data
= smb_base(inbuf
) + SVAL(inbuf
, smb_vwv11
);
2797 /* force the error type */
2798 SCVAL(inbuf
,smb_com
,SMBwritec
);
2799 SCVAL(outbuf
,smb_com
,SMBwritec
);
2801 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)tcount
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
2802 END_PROFILE(SMBwritebraw
);
2803 return(ERROR_DOS(ERRDOS
,ERRlock
));
2807 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
2809 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2810 fsp
->fnum
, (double)startpos
, (int)numtowrite
, (int)nwritten
, (int)write_through
));
2812 if (nwritten
< (ssize_t
)numtowrite
) {
2813 END_PROFILE(SMBwritebraw
);
2814 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
2817 total_written
= nwritten
;
2819 /* Return a message to the redirector to tell it to send more bytes */
2820 SCVAL(outbuf
,smb_com
,SMBwritebraw
);
2821 SSVALS(outbuf
,smb_vwv0
,-1);
2822 outsize
= set_message(inbuf
,outbuf
,Protocol
>PROTOCOL_COREPLUS
?1:0,0,True
);
2824 if (!send_smb(smbd_server_fd(),outbuf
))
2825 exit_server_cleanly("reply_writebraw: send_smb failed.");
2827 /* Now read the raw data into the buffer and write it */
2828 if (read_smb_length(smbd_server_fd(),inbuf
,SMB_SECONDARY_WAIT
) == -1) {
2829 exit_server_cleanly("secondary writebraw failed");
2832 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2833 numtowrite
= smb_len(inbuf
);
2835 /* Set up outbuf to return the correct return */
2836 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
2837 SCVAL(outbuf
,smb_com
,SMBwritec
);
2839 if (numtowrite
!= 0) {
2841 if (numtowrite
> BUFFER_SIZE
) {
2842 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2843 (unsigned int)numtowrite
));
2844 exit_server_cleanly("secondary writebraw failed");
2847 if (tcount
> nwritten
+numtowrite
) {
2848 DEBUG(3,("Client overestimated the write %d %d %d\n",
2849 (int)tcount
,(int)nwritten
,(int)numtowrite
));
2852 if (read_data( smbd_server_fd(), inbuf
+4, numtowrite
) != numtowrite
) {
2853 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2855 exit_server_cleanly("secondary writebraw failed");
2858 nwritten
= write_file(fsp
,inbuf
+4,startpos
+nwritten
,numtowrite
);
2859 if (nwritten
== -1) {
2860 END_PROFILE(SMBwritebraw
);
2861 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
2864 if (nwritten
< (ssize_t
)numtowrite
) {
2865 SCVAL(outbuf
,smb_rcls
,ERRHRD
);
2866 SSVAL(outbuf
,smb_err
,ERRdiskfull
);
2870 total_written
+= nwritten
;
2873 SSVAL(outbuf
,smb_vwv0
,total_written
);
2875 status
= sync_file(conn
, fsp
, write_through
);
2876 if (!NT_STATUS_IS_OK(status
)) {
2877 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
2878 fsp
->fsp_name
, nt_errstr(status
) ));
2879 END_PROFILE(SMBwritebraw
);
2880 return ERROR_NT(status
);
2883 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2884 fsp
->fnum
, (double)startpos
, (int)numtowrite
,(int)total_written
));
2886 /* we won't return a status if write through is not selected - this follows what WfWg does */
2887 END_PROFILE(SMBwritebraw
);
2888 if (!write_through
&& total_written
==tcount
) {
2890 #if RABBIT_PELLET_FIX
2892 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2893 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2895 if (!send_keepalive(smbd_server_fd()))
2896 exit_server_cleanly("reply_writebraw: send of keepalive failed");
2905 #define DBGC_CLASS DBGC_LOCKING
2907 /****************************************************************************
2908 Reply to a writeunlock (core+).
2909 ****************************************************************************/
2911 int reply_writeunlock(connection_struct
*conn
, char *inbuf
,char *outbuf
,
2912 int size
, int dum_buffsize
)
2914 ssize_t nwritten
= -1;
2918 NTSTATUS status
= NT_STATUS_OK
;
2919 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
2921 START_PROFILE(SMBwriteunlock
);
2923 CHECK_FSP(fsp
,conn
);
2924 if (!CHECK_WRITE(fsp
)) {
2925 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
2928 numtowrite
= SVAL(inbuf
,smb_vwv1
);
2929 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
2930 data
= smb_buf(inbuf
) + 3;
2932 if (numtowrite
&& is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
2933 END_PROFILE(SMBwriteunlock
);
2934 return ERROR_DOS(ERRDOS
,ERRlock
);
2937 /* The special X/Open SMB protocol handling of
2938 zero length writes is *NOT* done for
2940 if(numtowrite
== 0) {
2943 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
2946 status
= sync_file(conn
, fsp
, False
/* write through */);
2947 if (!NT_STATUS_IS_OK(status
)) {
2948 END_PROFILE(SMBwriteunlock
);
2949 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
2950 fsp
->fsp_name
, nt_errstr(status
) ));
2951 return ERROR_NT(status
);
2954 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
2955 END_PROFILE(SMBwriteunlock
);
2956 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
2960 status
= do_unlock(smbd_messaging_context(),
2962 (uint32
)SVAL(inbuf
,smb_pid
),
2963 (SMB_BIG_UINT
)numtowrite
,
2964 (SMB_BIG_UINT
)startpos
,
2967 if (NT_STATUS_V(status
)) {
2968 END_PROFILE(SMBwriteunlock
);
2969 return ERROR_NT(status
);
2973 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
2975 SSVAL(outbuf
,smb_vwv0
,nwritten
);
2977 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2978 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
2980 END_PROFILE(SMBwriteunlock
);
2985 #define DBGC_CLASS DBGC_ALL
2987 /****************************************************************************
2989 ****************************************************************************/
2991 int reply_write(connection_struct
*conn
, char *inbuf
,char *outbuf
,int size
,int dum_buffsize
)
2994 ssize_t nwritten
= -1;
2997 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3000 START_PROFILE(SMBwrite
);
3002 /* If it's an IPC, pass off the pipe handler. */
3004 END_PROFILE(SMBwrite
);
3005 return reply_pipe_write(inbuf
,outbuf
,size
,dum_buffsize
);
3008 CHECK_FSP(fsp
,conn
);
3009 if (!CHECK_WRITE(fsp
)) {
3010 END_PROFILE(SMBwrite
);
3011 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3014 numtowrite
= SVAL(inbuf
,smb_vwv1
);
3015 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
3016 data
= smb_buf(inbuf
) + 3;
3018 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
3019 END_PROFILE(SMBwrite
);
3020 return ERROR_DOS(ERRDOS
,ERRlock
);
3024 * X/Open SMB protocol says that if smb_vwv1 is
3025 * zero then the file size should be extended or
3026 * truncated to the size given in smb_vwv[2-3].
3029 if(numtowrite
== 0) {
3031 * This is actually an allocate call, and set EOF. JRA.
3033 nwritten
= vfs_allocate_file_space(fsp
, (SMB_OFF_T
)startpos
);
3035 END_PROFILE(SMBwrite
);
3036 return ERROR_NT(NT_STATUS_DISK_FULL
);
3038 nwritten
= vfs_set_filelen(fsp
, (SMB_OFF_T
)startpos
);
3040 END_PROFILE(SMBwrite
);
3041 return ERROR_NT(NT_STATUS_DISK_FULL
);
3044 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
3046 status
= sync_file(conn
, fsp
, False
);
3047 if (!NT_STATUS_IS_OK(status
)) {
3048 END_PROFILE(SMBwrite
);
3049 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3050 fsp
->fsp_name
, nt_errstr(status
) ));
3051 return ERROR_NT(status
);
3054 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
3055 END_PROFILE(SMBwrite
);
3056 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3059 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
3061 SSVAL(outbuf
,smb_vwv0
,nwritten
);
3063 if (nwritten
< (ssize_t
)numtowrite
) {
3064 SCVAL(outbuf
,smb_rcls
,ERRHRD
);
3065 SSVAL(outbuf
,smb_err
,ERRdiskfull
);
3068 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
3070 END_PROFILE(SMBwrite
);
3074 /****************************************************************************
3075 Reply to a write and X.
3076 ****************************************************************************/
3078 int reply_write_and_X(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3080 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv2
);
3081 SMB_OFF_T startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
3082 size_t numtowrite
= SVAL(inbuf
,smb_vwv10
);
3083 BOOL write_through
= BITSETW(inbuf
+smb_vwv7
,0);
3084 ssize_t nwritten
= -1;
3085 unsigned int smb_doff
= SVAL(inbuf
,smb_vwv11
);
3086 unsigned int smblen
= smb_len(inbuf
);
3088 BOOL large_writeX
= ((CVAL(inbuf
,smb_wct
) == 14) && (smblen
> 0xFFFF));
3090 START_PROFILE(SMBwriteX
);
3092 /* If it's an IPC, pass off the pipe handler. */
3094 END_PROFILE(SMBwriteX
);
3095 return reply_pipe_write_and_X(inbuf
,outbuf
,length
,bufsize
);
3098 CHECK_FSP(fsp
,conn
);
3099 if (!CHECK_WRITE(fsp
)) {
3100 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3103 set_message(inbuf
,outbuf
,6,0,True
);
3105 /* Deal with possible LARGE_WRITEX */
3107 numtowrite
|= ((((size_t)SVAL(inbuf
,smb_vwv9
)) & 1 )<<16);
3110 if(smb_doff
> smblen
|| (smb_doff
+ numtowrite
> smblen
)) {
3111 END_PROFILE(SMBwriteX
);
3112 return ERROR_DOS(ERRDOS
,ERRbadmem
);
3115 data
= smb_base(inbuf
) + smb_doff
;
3117 if(CVAL(inbuf
,smb_wct
) == 14) {
3118 #ifdef LARGE_SMB_OFF_T
3120 * This is a large offset (64 bit) write.
3122 startpos
|= (((SMB_OFF_T
)IVAL(inbuf
,smb_vwv12
)) << 32);
3124 #else /* !LARGE_SMB_OFF_T */
3127 * Ensure we haven't been sent a >32 bit offset.
3130 if(IVAL(inbuf
,smb_vwv12
) != 0) {
3131 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
3132 64 bit offsets.\n", (unsigned int)IVAL(inbuf
,smb_vwv12
) ));
3133 END_PROFILE(SMBwriteX
);
3134 return ERROR_DOS(ERRDOS
,ERRbadaccess
);
3137 #endif /* LARGE_SMB_OFF_T */
3140 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
3141 END_PROFILE(SMBwriteX
);
3142 return ERROR_DOS(ERRDOS
,ERRlock
);
3145 /* X/Open SMB protocol says that, unlike SMBwrite
3146 if the length is zero then NO truncation is
3147 done, just a write of zero. To truncate a file,
3150 if(numtowrite
== 0) {
3154 if (schedule_aio_write_and_X(conn
, inbuf
, outbuf
, length
, bufsize
,
3155 fsp
,data
,startpos
,numtowrite
)) {
3156 END_PROFILE(SMBwriteX
);
3160 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
3163 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
3164 END_PROFILE(SMBwriteX
);
3165 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3168 SSVAL(outbuf
,smb_vwv2
,nwritten
);
3170 SSVAL(outbuf
,smb_vwv4
,(nwritten
>>16)&1);
3172 if (nwritten
< (ssize_t
)numtowrite
) {
3173 SCVAL(outbuf
,smb_rcls
,ERRHRD
);
3174 SSVAL(outbuf
,smb_err
,ERRdiskfull
);
3177 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
3178 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
3180 status
= sync_file(conn
, fsp
, write_through
);
3181 if (!NT_STATUS_IS_OK(status
)) {
3182 END_PROFILE(SMBwriteX
);
3183 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
3184 fsp
->fsp_name
, nt_errstr(status
) ));
3185 return ERROR_NT(status
);
3188 END_PROFILE(SMBwriteX
);
3189 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
3192 /****************************************************************************
3194 ****************************************************************************/
3196 int reply_lseek(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
3202 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3203 START_PROFILE(SMBlseek
);
3205 CHECK_FSP(fsp
,conn
);
3207 flush_write_cache(fsp
, SEEK_FLUSH
);
3209 mode
= SVAL(inbuf
,smb_vwv1
) & 3;
3210 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
3211 startpos
= (SMB_OFF_T
)IVALS(inbuf
,smb_vwv2
);
3220 res
= fsp
->fh
->pos
+ startpos
;
3231 if (umode
== SEEK_END
) {
3232 if((res
= SMB_VFS_LSEEK(fsp
,fsp
->fh
->fd
,startpos
,umode
)) == -1) {
3233 if(errno
== EINVAL
) {
3234 SMB_OFF_T current_pos
= startpos
;
3235 SMB_STRUCT_STAT sbuf
;
3237 if(SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
, &sbuf
) == -1) {
3238 END_PROFILE(SMBlseek
);
3239 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3242 current_pos
+= sbuf
.st_size
;
3244 res
= SMB_VFS_LSEEK(fsp
,fsp
->fh
->fd
,0,SEEK_SET
);
3249 END_PROFILE(SMBlseek
);
3250 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3256 outsize
= set_message(inbuf
,outbuf
,2,0,True
);
3257 SIVAL(outbuf
,smb_vwv0
,res
);
3259 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
3260 fsp
->fnum
, (double)startpos
, (double)res
, mode
));
3262 END_PROFILE(SMBlseek
);
3266 /****************************************************************************
3268 ****************************************************************************/
3270 int reply_flush(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
3272 int outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3273 uint16 fnum
= SVAL(inbuf
,smb_vwv0
);
3274 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3275 START_PROFILE(SMBflush
);
3278 CHECK_FSP(fsp
,conn
);
3281 file_sync_all(conn
);
3283 NTSTATUS status
= sync_file(conn
, fsp
, True
);
3284 if (!NT_STATUS_IS_OK(status
)) {
3285 END_PROFILE(SMBflush
);
3286 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
3287 fsp
->fsp_name
, nt_errstr(status
) ));
3288 return ERROR_NT(status
);
3292 DEBUG(3,("flush\n"));
3293 END_PROFILE(SMBflush
);
3297 /****************************************************************************
3299 conn POINTER CAN BE NULL HERE !
3300 ****************************************************************************/
3302 int reply_exit(connection_struct
*conn
,
3303 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3306 START_PROFILE(SMBexit
);
3308 file_close_pid(SVAL(inbuf
,smb_pid
),SVAL(inbuf
,smb_uid
));
3310 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3312 DEBUG(3,("exit\n"));
3314 END_PROFILE(SMBexit
);
3318 /****************************************************************************
3319 Reply to a close - has to deal with closing a directory opened by NT SMB's.
3320 ****************************************************************************/
3322 int reply_close(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
,
3325 NTSTATUS status
= NT_STATUS_OK
;
3327 files_struct
*fsp
= NULL
;
3328 START_PROFILE(SMBclose
);
3330 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3332 /* If it's an IPC, pass off to the pipe handler. */
3334 END_PROFILE(SMBclose
);
3335 return reply_pipe_close(conn
, inbuf
,outbuf
);
3338 fsp
= file_fsp(inbuf
,smb_vwv0
);
3341 * We can only use CHECK_FSP if we know it's not a directory.
3344 if(!fsp
|| (fsp
->conn
!= conn
) || (fsp
->vuid
!= current_user
.vuid
)) {
3345 END_PROFILE(SMBclose
);
3346 return ERROR_DOS(ERRDOS
,ERRbadfid
);
3349 if(fsp
->is_directory
) {
3351 * Special case - close NT SMB directory handle.
3353 DEBUG(3,("close directory fnum=%d\n", fsp
->fnum
));
3354 status
= close_file(fsp
,NORMAL_CLOSE
);
3357 * Close ordinary file.
3360 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
3361 fsp
->fh
->fd
, fsp
->fnum
,
3362 conn
->num_files_open
));
3365 * Take care of any time sent in the close.
3368 fsp_set_pending_modtime(fsp
,
3369 convert_time_t_to_timespec(srv_make_unix_date3(inbuf
+smb_vwv1
)));
3372 * close_file() returns the unix errno if an error
3373 * was detected on close - normally this is due to
3374 * a disk full error. If not then it was probably an I/O error.
3377 status
= close_file(fsp
,NORMAL_CLOSE
);
3380 if(!NT_STATUS_IS_OK(status
)) {
3381 END_PROFILE(SMBclose
);
3382 return ERROR_NT(status
);
3385 END_PROFILE(SMBclose
);
3389 /****************************************************************************
3390 Reply to a writeclose (Core+ protocol).
3391 ****************************************************************************/
3393 int reply_writeclose(connection_struct
*conn
,
3394 char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
3397 ssize_t nwritten
= -1;
3399 NTSTATUS close_status
= NT_STATUS_OK
;
3402 struct timespec mtime
;
3403 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3404 START_PROFILE(SMBwriteclose
);
3406 CHECK_FSP(fsp
,conn
);
3407 if (!CHECK_WRITE(fsp
)) {
3408 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3411 numtowrite
= SVAL(inbuf
,smb_vwv1
);
3412 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
3413 mtime
= convert_time_t_to_timespec(srv_make_unix_date3(inbuf
+smb_vwv4
));
3414 data
= smb_buf(inbuf
) + 1;
3416 if (numtowrite
&& is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)numtowrite
,(SMB_BIG_UINT
)startpos
, WRITE_LOCK
)) {
3417 END_PROFILE(SMBwriteclose
);
3418 return ERROR_DOS(ERRDOS
,ERRlock
);
3421 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
3423 set_filetime(conn
, fsp
->fsp_name
, mtime
);
3426 * More insanity. W2K only closes the file if writelen > 0.
3431 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
3433 close_status
= close_file(fsp
,NORMAL_CLOSE
);
3436 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
3437 fsp
->fnum
, (int)numtowrite
, (int)nwritten
,
3438 conn
->num_files_open
));
3440 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
3441 END_PROFILE(SMBwriteclose
);
3442 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3445 if(!NT_STATUS_IS_OK(close_status
)) {
3446 END_PROFILE(SMBwriteclose
);
3447 return ERROR_NT(close_status
);
3450 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
3452 SSVAL(outbuf
,smb_vwv0
,nwritten
);
3453 END_PROFILE(SMBwriteclose
);
3458 #define DBGC_CLASS DBGC_LOCKING
3460 /****************************************************************************
3462 ****************************************************************************/
3464 int reply_lock(connection_struct
*conn
,
3465 char *inbuf
,char *outbuf
, int length
, int dum_buffsize
)
3467 int outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3468 SMB_BIG_UINT count
,offset
;
3470 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3471 struct byte_range_lock
*br_lck
= NULL
;
3473 START_PROFILE(SMBlock
);
3475 CHECK_FSP(fsp
,conn
);
3477 release_level_2_oplocks_on_change(fsp
);
3479 count
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv1
);
3480 offset
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv3
);
3482 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3483 fsp
->fh
->fd
, fsp
->fnum
, (double)offset
, (double)count
));
3485 br_lck
= do_lock(smbd_messaging_context(),
3487 (uint32
)SVAL(inbuf
,smb_pid
),
3492 False
, /* Non-blocking lock. */
3496 TALLOC_FREE(br_lck
);
3498 if (NT_STATUS_V(status
)) {
3499 END_PROFILE(SMBlock
);
3500 return ERROR_NT(status
);
3503 END_PROFILE(SMBlock
);
3507 /****************************************************************************
3509 ****************************************************************************/
3511 int reply_unlock(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
,
3514 int outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3515 SMB_BIG_UINT count
,offset
;
3517 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3518 START_PROFILE(SMBunlock
);
3520 CHECK_FSP(fsp
,conn
);
3522 count
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv1
);
3523 offset
= (SMB_BIG_UINT
)IVAL(inbuf
,smb_vwv3
);
3525 status
= do_unlock(smbd_messaging_context(),
3527 (uint32
)SVAL(inbuf
,smb_pid
),
3532 if (NT_STATUS_V(status
)) {
3533 END_PROFILE(SMBunlock
);
3534 return ERROR_NT(status
);
3537 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3538 fsp
->fh
->fd
, fsp
->fnum
, (double)offset
, (double)count
) );
3540 END_PROFILE(SMBunlock
);
3545 #define DBGC_CLASS DBGC_ALL
3547 /****************************************************************************
3549 conn POINTER CAN BE NULL HERE !
3550 ****************************************************************************/
3552 int reply_tdis(connection_struct
*conn
,
3553 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3555 int outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3557 START_PROFILE(SMBtdis
);
3559 vuid
= SVAL(inbuf
,smb_uid
);
3562 DEBUG(4,("Invalid connection in tdis\n"));
3563 END_PROFILE(SMBtdis
);
3564 return ERROR_DOS(ERRSRV
,ERRinvnid
);
3569 close_cnum(conn
,vuid
);
3571 END_PROFILE(SMBtdis
);
3575 /****************************************************************************
3577 conn POINTER CAN BE NULL HERE !
3578 ****************************************************************************/
3580 int reply_echo(connection_struct
*conn
,
3581 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3583 int smb_reverb
= SVAL(inbuf
,smb_vwv0
);
3585 unsigned int data_len
= smb_buflen(inbuf
);
3586 int outsize
= set_message(inbuf
,outbuf
,1,data_len
,True
);
3587 START_PROFILE(SMBecho
);
3589 if (data_len
> BUFFER_SIZE
) {
3590 DEBUG(0,("reply_echo: data_len too large.\n"));
3591 END_PROFILE(SMBecho
);
3595 /* copy any incoming data back out */
3597 memcpy(smb_buf(outbuf
),smb_buf(inbuf
),data_len
);
3599 if (smb_reverb
> 100) {
3600 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb
));
3604 for (seq_num
=1 ; seq_num
<= smb_reverb
; seq_num
++) {
3605 SSVAL(outbuf
,smb_vwv0
,seq_num
);
3607 smb_setlen(inbuf
,outbuf
,outsize
- 4);
3610 if (!send_smb(smbd_server_fd(),outbuf
))
3611 exit_server_cleanly("reply_echo: send_smb failed.");
3614 DEBUG(3,("echo %d times\n", smb_reverb
));
3618 END_PROFILE(SMBecho
);
3622 /****************************************************************************
3623 Reply to a printopen.
3624 ****************************************************************************/
3626 int reply_printopen(connection_struct
*conn
,
3627 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3633 START_PROFILE(SMBsplopen
);
3635 if (!CAN_PRINT(conn
)) {
3636 END_PROFILE(SMBsplopen
);
3637 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
3640 /* Open for exclusive use, write only. */
3641 status
= print_fsp_open(conn
, NULL
, &fsp
);
3643 if (!NT_STATUS_IS_OK(status
)) {
3644 END_PROFILE(SMBsplopen
);
3645 return(ERROR_NT(status
));
3648 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
3649 SSVAL(outbuf
,smb_vwv0
,fsp
->fnum
);
3651 DEBUG(3,("openprint fd=%d fnum=%d\n",
3652 fsp
->fh
->fd
, fsp
->fnum
));
3654 END_PROFILE(SMBsplopen
);
3658 /****************************************************************************
3659 Reply to a printclose.
3660 ****************************************************************************/
3662 int reply_printclose(connection_struct
*conn
,
3663 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3665 int outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3666 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3668 START_PROFILE(SMBsplclose
);
3670 CHECK_FSP(fsp
,conn
);
3672 if (!CAN_PRINT(conn
)) {
3673 END_PROFILE(SMBsplclose
);
3674 return ERROR_NT(NT_STATUS_DOS(ERRSRV
, ERRerror
));
3677 DEBUG(3,("printclose fd=%d fnum=%d\n",
3678 fsp
->fh
->fd
,fsp
->fnum
));
3680 status
= close_file(fsp
,NORMAL_CLOSE
);
3682 if(!NT_STATUS_IS_OK(status
)) {
3683 END_PROFILE(SMBsplclose
);
3684 return ERROR_NT(status
);
3687 END_PROFILE(SMBsplclose
);
3691 /****************************************************************************
3692 Reply to a printqueue.
3693 ****************************************************************************/
3695 int reply_printqueue(connection_struct
*conn
,
3696 char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3698 int outsize
= set_message(inbuf
,outbuf
,2,3,True
);
3699 int max_count
= SVAL(inbuf
,smb_vwv0
);
3700 int start_index
= SVAL(inbuf
,smb_vwv1
);
3701 START_PROFILE(SMBsplretq
);
3703 /* we used to allow the client to get the cnum wrong, but that
3704 is really quite gross and only worked when there was only
3705 one printer - I think we should now only accept it if they
3706 get it right (tridge) */
3707 if (!CAN_PRINT(conn
)) {
3708 END_PROFILE(SMBsplretq
);
3709 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
3712 SSVAL(outbuf
,smb_vwv0
,0);
3713 SSVAL(outbuf
,smb_vwv1
,0);
3714 SCVAL(smb_buf(outbuf
),0,1);
3715 SSVAL(smb_buf(outbuf
),1,0);
3717 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3718 start_index
, max_count
));
3721 print_queue_struct
*queue
= NULL
;
3722 print_status_struct status
;
3723 char *p
= smb_buf(outbuf
) + 3;
3724 int count
= print_queue_status(SNUM(conn
), &queue
, &status
);
3725 int num_to_get
= ABS(max_count
);
3726 int first
= (max_count
>0?start_index
:start_index
+max_count
+1);
3732 num_to_get
= MIN(num_to_get
,count
-first
);
3735 for (i
=first
;i
<first
+num_to_get
;i
++) {
3736 srv_put_dos_date2(p
,0,queue
[i
].time
);
3737 SCVAL(p
,4,(queue
[i
].status
==LPQ_PRINTING
?2:3));
3738 SSVAL(p
,5, queue
[i
].job
);
3739 SIVAL(p
,7,queue
[i
].size
);
3741 srvstr_push(outbuf
, p
+12, queue
[i
].fs_user
, 16, STR_ASCII
);
3746 outsize
= set_message(inbuf
,outbuf
,2,28*count
+3,False
);
3747 SSVAL(outbuf
,smb_vwv0
,count
);
3748 SSVAL(outbuf
,smb_vwv1
,(max_count
>0?first
+count
:first
-1));
3749 SCVAL(smb_buf(outbuf
),0,1);
3750 SSVAL(smb_buf(outbuf
),1,28*count
);
3755 DEBUG(3,("%d entries returned in queue\n",count
));
3758 END_PROFILE(SMBsplretq
);
3762 /****************************************************************************
3763 Reply to a printwrite.
3764 ****************************************************************************/
3766 int reply_printwrite(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3769 int outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3771 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
3773 START_PROFILE(SMBsplwr
);
3775 if (!CAN_PRINT(conn
)) {
3776 END_PROFILE(SMBsplwr
);
3777 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
3780 CHECK_FSP(fsp
,conn
);
3781 if (!CHECK_WRITE(fsp
)) {
3782 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
3785 numtowrite
= SVAL(smb_buf(inbuf
),1);
3786 data
= smb_buf(inbuf
) + 3;
3788 if (write_file(fsp
,data
,-1,numtowrite
) != numtowrite
) {
3789 END_PROFILE(SMBsplwr
);
3790 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
3793 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp
->fnum
, numtowrite
) );
3795 END_PROFILE(SMBsplwr
);
3799 /****************************************************************************
3801 ****************************************************************************/
3803 int reply_mkdir(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
3808 SMB_STRUCT_STAT sbuf
;
3810 START_PROFILE(SMBmkdir
);
3812 srvstr_get_path(inbuf
, directory
, smb_buf(inbuf
) + 1, sizeof(directory
), 0, STR_TERMINATE
, &status
);
3813 if (!NT_STATUS_IS_OK(status
)) {
3814 END_PROFILE(SMBmkdir
);
3815 return ERROR_NT(status
);
3818 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, directory
);
3819 if (!NT_STATUS_IS_OK(status
)) {
3820 END_PROFILE(SMBmkdir
);
3821 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
3822 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
3824 return ERROR_NT(status
);
3827 status
= unix_convert(conn
, directory
, False
, NULL
, &sbuf
);
3828 if (!NT_STATUS_IS_OK(status
)) {
3829 END_PROFILE(SMBmkdir
);
3830 return ERROR_NT(status
);
3833 status
= check_name(conn
, directory
);
3834 if (!NT_STATUS_IS_OK(status
)) {
3835 END_PROFILE(SMBmkdir
);
3836 return ERROR_NT(status
);
3839 status
= create_directory(conn
, directory
);
3841 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status
)));
3843 if (!NT_STATUS_IS_OK(status
)) {
3845 if (!use_nt_status()
3846 && NT_STATUS_EQUAL(status
,
3847 NT_STATUS_OBJECT_NAME_COLLISION
)) {
3849 * Yes, in the DOS error code case we get a
3850 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
3851 * samba4 torture test.
3853 status
= NT_STATUS_DOS(ERRDOS
, ERRnoaccess
);
3856 END_PROFILE(SMBmkdir
);
3857 return ERROR_NT(status
);
3860 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
3862 DEBUG( 3, ( "mkdir %s ret=%d\n", directory
, outsize
) );
3864 END_PROFILE(SMBmkdir
);
3868 /****************************************************************************
3869 Static function used by reply_rmdir to delete an entire directory
3870 tree recursively. Return True on ok, False on fail.
3871 ****************************************************************************/
3873 static BOOL
recursive_rmdir(connection_struct
*conn
, char *directory
)
3875 const char *dname
= NULL
;
3878 struct smb_Dir
*dir_hnd
= OpenDir(conn
, directory
, NULL
, 0);
3883 while((dname
= ReadDirName(dir_hnd
, &offset
))) {
3887 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0))
3890 if (!is_visible_file(conn
, directory
, dname
, &st
, False
))
3893 /* Construct the full name. */
3894 if(strlen(directory
) + strlen(dname
) + 1 >= sizeof(fullname
)) {
3900 pstrcpy(fullname
, directory
);
3901 pstrcat(fullname
, "/");
3902 pstrcat(fullname
, dname
);
3904 if(SMB_VFS_LSTAT(conn
,fullname
, &st
) != 0) {
3909 if(st
.st_mode
& S_IFDIR
) {
3910 if(!recursive_rmdir(conn
, fullname
)) {
3914 if(SMB_VFS_RMDIR(conn
,fullname
) != 0) {
3918 } else if(SMB_VFS_UNLINK(conn
,fullname
) != 0) {
3927 /****************************************************************************
3928 The internals of the rmdir code - called elsewhere.
3929 ****************************************************************************/
3931 NTSTATUS
rmdir_internals(connection_struct
*conn
, const char *directory
)
3936 /* Might be a symlink. */
3937 if(SMB_VFS_LSTAT(conn
, directory
, &st
) != 0) {
3938 return map_nt_error_from_unix(errno
);
3941 if (S_ISLNK(st
.st_mode
)) {
3942 /* Is what it points to a directory ? */
3943 if(SMB_VFS_STAT(conn
, directory
, &st
) != 0) {
3944 return map_nt_error_from_unix(errno
);
3946 if (!(S_ISDIR(st
.st_mode
))) {
3947 return NT_STATUS_NOT_A_DIRECTORY
;
3949 ret
= SMB_VFS_UNLINK(conn
,directory
);
3951 ret
= SMB_VFS_RMDIR(conn
,directory
);
3954 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
3955 FILE_NOTIFY_CHANGE_DIR_NAME
,
3957 return NT_STATUS_OK
;
3960 if(((errno
== ENOTEMPTY
)||(errno
== EEXIST
)) && lp_veto_files(SNUM(conn
))) {
3962 * Check to see if the only thing in this directory are
3963 * vetoed files/directories. If so then delete them and
3964 * retry. If we fail to delete any of them (and we *don't*
3965 * do a recursive delete) then fail the rmdir.
3969 struct smb_Dir
*dir_hnd
= OpenDir(conn
, directory
, NULL
, 0);
3971 if(dir_hnd
== NULL
) {
3976 while ((dname
= ReadDirName(dir_hnd
,&dirpos
))) {
3977 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0))
3979 if (!is_visible_file(conn
, directory
, dname
, &st
, False
))
3981 if(!IS_VETO_PATH(conn
, dname
)) {
3988 /* We only have veto files/directories. Recursive delete. */
3990 RewindDir(dir_hnd
,&dirpos
);
3991 while ((dname
= ReadDirName(dir_hnd
,&dirpos
))) {
3994 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0))
3996 if (!is_visible_file(conn
, directory
, dname
, &st
, False
))
3999 /* Construct the full name. */
4000 if(strlen(directory
) + strlen(dname
) + 1 >= sizeof(fullname
)) {
4005 pstrcpy(fullname
, directory
);
4006 pstrcat(fullname
, "/");
4007 pstrcat(fullname
, dname
);
4009 if(SMB_VFS_LSTAT(conn
,fullname
, &st
) != 0)
4011 if(st
.st_mode
& S_IFDIR
) {
4012 if(lp_recursive_veto_delete(SNUM(conn
))) {
4013 if(!recursive_rmdir(conn
, fullname
))
4016 if(SMB_VFS_RMDIR(conn
,fullname
) != 0)
4018 } else if(SMB_VFS_UNLINK(conn
,fullname
) != 0)
4022 /* Retry the rmdir */
4023 ret
= SMB_VFS_RMDIR(conn
,directory
);
4029 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
4030 "%s\n", directory
,strerror(errno
)));
4031 return map_nt_error_from_unix(errno
);
4034 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
4035 FILE_NOTIFY_CHANGE_DIR_NAME
,
4038 return NT_STATUS_OK
;
4041 /****************************************************************************
4043 ****************************************************************************/
4045 int reply_rmdir(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
4049 SMB_STRUCT_STAT sbuf
;
4051 START_PROFILE(SMBrmdir
);
4053 srvstr_get_path(inbuf
, directory
, smb_buf(inbuf
) + 1, sizeof(directory
), 0, STR_TERMINATE
, &status
);
4054 if (!NT_STATUS_IS_OK(status
)) {
4055 END_PROFILE(SMBrmdir
);
4056 return ERROR_NT(status
);
4059 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, directory
);
4060 if (!NT_STATUS_IS_OK(status
)) {
4061 END_PROFILE(SMBrmdir
);
4062 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
4063 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
4065 return ERROR_NT(status
);
4068 status
= unix_convert(conn
, directory
, False
, NULL
, &sbuf
);
4069 if (!NT_STATUS_IS_OK(status
)) {
4070 END_PROFILE(SMBrmdir
);
4071 return ERROR_NT(status
);
4074 status
= check_name(conn
, directory
);
4075 if (!NT_STATUS_IS_OK(status
)) {
4076 END_PROFILE(SMBrmdir
);
4077 return ERROR_NT(status
);
4080 dptr_closepath(directory
,SVAL(inbuf
,smb_pid
));
4081 status
= rmdir_internals(conn
, directory
);
4082 if (!NT_STATUS_IS_OK(status
)) {
4083 END_PROFILE(SMBrmdir
);
4084 return ERROR_NT(status
);
4087 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
4089 DEBUG( 3, ( "rmdir %s\n", directory
) );
4091 END_PROFILE(SMBrmdir
);
4095 /*******************************************************************
4096 Resolve wildcards in a filename rename.
4097 Note that name is in UNIX charset and thus potentially can be more
4098 than fstring buffer (255 bytes) especially in default UTF-8 case.
4099 Therefore, we use pstring inside and all calls should ensure that
4100 name2 is at least pstring-long (they do already)
4101 ********************************************************************/
4103 static BOOL
resolve_wildcards(const char *name1
, char *name2
)
4105 pstring root1
,root2
;
4107 char *p
,*p2
, *pname1
, *pname2
;
4108 int available_space
, actual_space
;
4110 pname1
= strrchr_m(name1
,'/');
4111 pname2
= strrchr_m(name2
,'/');
4113 if (!pname1
|| !pname2
)
4116 pstrcpy(root1
,pname1
);
4117 pstrcpy(root2
,pname2
);
4118 p
= strrchr_m(root1
,'.');
4125 p
= strrchr_m(root2
,'.');
4139 } else if (*p2
== '*') {
4155 } else if (*p2
== '*') {
4165 available_space
= sizeof(pstring
) - PTR_DIFF(pname2
, name2
);
4168 actual_space
= snprintf(pname2
, available_space
- 1, "%s.%s", root2
, ext2
);
4169 if (actual_space
>= available_space
- 1) {
4170 DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
4171 actual_space
- available_space
));
4174 pstrcpy_base(pname2
, root2
, name2
);
4180 /****************************************************************************
4181 Ensure open files have their names updated. Updated to notify other smbd's
4183 ****************************************************************************/
4185 static void rename_open_files(connection_struct
*conn
,
4186 struct share_mode_lock
*lck
,
4187 const char *newname
)
4190 BOOL did_rename
= False
;
4192 for(fsp
= file_find_di_first(lck
->id
); fsp
;
4193 fsp
= file_find_di_next(fsp
)) {
4194 /* fsp_name is a relative path under the fsp. To change this for other
4195 sharepaths we need to manipulate relative paths. */
4196 /* TODO - create the absolute path and manipulate the newname
4197 relative to the sharepath. */
4198 if (fsp
->conn
!= conn
) {
4201 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
4202 fsp
->fnum
, file_id_static_string(&fsp
->file_id
),
4203 fsp
->fsp_name
, newname
));
4204 string_set(&fsp
->fsp_name
, newname
);
4209 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
4210 file_id_static_string(&lck
->id
), newname
));
4213 /* Send messages to all smbd's (not ourself) that the name has changed. */
4214 rename_share_filename(smbd_messaging_context(), lck
, conn
->connectpath
,
4218 /****************************************************************************
4219 We need to check if the source path is a parent directory of the destination
4220 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
4221 refuse the rename with a sharing violation. Under UNIX the above call can
4222 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
4223 probably need to check that the client is a Windows one before disallowing
4224 this as a UNIX client (one with UNIX extensions) can know the source is a
4225 symlink and make this decision intelligently. Found by an excellent bug
4226 report from <AndyLiebman@aol.com>.
4227 ****************************************************************************/
4229 static BOOL
rename_path_prefix_equal(const char *src
, const char *dest
)
4231 const char *psrc
= src
;
4232 const char *pdst
= dest
;
4235 if (psrc
[0] == '.' && psrc
[1] == '/') {
4238 if (pdst
[0] == '.' && pdst
[1] == '/') {
4241 if ((slen
= strlen(psrc
)) > strlen(pdst
)) {
4244 return ((memcmp(psrc
, pdst
, slen
) == 0) && pdst
[slen
] == '/');
4248 * Do the notify calls from a rename
4251 static void notify_rename(connection_struct
*conn
, BOOL is_dir
,
4252 const char *oldpath
, const char *newpath
)
4254 char *olddir
, *newdir
;
4255 const char *oldname
, *newname
;
4258 mask
= is_dir
? FILE_NOTIFY_CHANGE_DIR_NAME
4259 : FILE_NOTIFY_CHANGE_FILE_NAME
;
4261 if (!parent_dirname_talloc(NULL
, oldpath
, &olddir
, &oldname
)
4262 || !parent_dirname_talloc(NULL
, newpath
, &newdir
, &newname
)) {
4263 TALLOC_FREE(olddir
);
4267 if (strcmp(olddir
, newdir
) == 0) {
4268 notify_fname(conn
, NOTIFY_ACTION_OLD_NAME
, mask
, oldpath
);
4269 notify_fname(conn
, NOTIFY_ACTION_NEW_NAME
, mask
, newpath
);
4272 notify_fname(conn
, NOTIFY_ACTION_REMOVED
, mask
, oldpath
);
4273 notify_fname(conn
, NOTIFY_ACTION_ADDED
, mask
, newpath
);
4275 TALLOC_FREE(olddir
);
4276 TALLOC_FREE(newdir
);
4278 /* this is a strange one. w2k3 gives an additional event for
4279 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
4280 files, but not directories */
4282 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
4283 FILE_NOTIFY_CHANGE_ATTRIBUTES
4284 |FILE_NOTIFY_CHANGE_CREATION
,
4289 /****************************************************************************
4290 Rename an open file - given an fsp.
4291 ****************************************************************************/
4293 NTSTATUS
rename_internals_fsp(connection_struct
*conn
, files_struct
*fsp
, pstring newname
, uint32 attrs
, BOOL replace_if_exists
)
4295 SMB_STRUCT_STAT sbuf
, sbuf1
;
4296 pstring newname_last_component
;
4297 NTSTATUS status
= NT_STATUS_OK
;
4298 struct share_mode_lock
*lck
= NULL
;
4303 status
= unix_convert(conn
, newname
, False
, newname_last_component
, &sbuf
);
4305 /* If an error we expect this to be NT_STATUS_OBJECT_PATH_NOT_FOUND */
4307 if (!NT_STATUS_IS_OK(status
) && !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
, status
)) {
4311 status
= check_name(conn
, newname
);
4312 if (!NT_STATUS_IS_OK(status
)) {
4316 /* Ensure newname contains a '/' */
4317 if(strrchr_m(newname
,'/') == 0) {
4320 pstrcpy(tmpstr
, "./");
4321 pstrcat(tmpstr
, newname
);
4322 pstrcpy(newname
, tmpstr
);
4326 * Check for special case with case preserving and not
4327 * case sensitive. If the old last component differs from the original
4328 * last component only by case, then we should allow
4329 * the rename (user is trying to change the case of the
4333 if((conn
->case_sensitive
== False
) && (conn
->case_preserve
== True
) &&
4334 strequal(newname
, fsp
->fsp_name
)) {
4336 pstring newname_modified_last_component
;
4339 * Get the last component of the modified name.
4340 * Note that we guarantee that newname contains a '/'
4343 p
= strrchr_m(newname
,'/');
4344 pstrcpy(newname_modified_last_component
,p
+1);
4346 if(strcsequal(newname_modified_last_component
,
4347 newname_last_component
) == False
) {
4349 * Replace the modified last component with
4352 pstrcpy(p
+1, newname_last_component
);
4357 * If the src and dest names are identical - including case,
4358 * don't do the rename, just return success.
4361 if (strcsequal(fsp
->fsp_name
, newname
)) {
4362 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
4364 return NT_STATUS_OK
;
4368 * Have vfs_object_exist also fill sbuf1
4370 dst_exists
= vfs_object_exist(conn
, newname
, &sbuf1
);
4372 if(!replace_if_exists
&& dst_exists
) {
4373 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
4374 fsp
->fsp_name
,newname
));
4375 return NT_STATUS_OBJECT_NAME_COLLISION
;
4378 if (dst_exists
&& file_find_di_first(file_id_sbuf(&sbuf1
)) != NULL
) {
4379 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
4380 return NT_STATUS_ACCESS_DENIED
;
4383 /* Ensure we have a valid stat struct for the source. */
4384 if (fsp
->fh
->fd
!= -1) {
4385 if (SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
,&sbuf
) == -1) {
4386 return map_nt_error_from_unix(errno
);
4389 if (SMB_VFS_STAT(conn
,fsp
->fsp_name
,&sbuf
) == -1) {
4390 return map_nt_error_from_unix(errno
);
4394 status
= can_rename(conn
, fsp
, attrs
, &sbuf
);
4396 if (!NT_STATUS_IS_OK(status
)) {
4397 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
4398 nt_errstr(status
), fsp
->fsp_name
,newname
));
4399 if (NT_STATUS_EQUAL(status
,NT_STATUS_SHARING_VIOLATION
))
4400 status
= NT_STATUS_ACCESS_DENIED
;
4404 if (rename_path_prefix_equal(fsp
->fsp_name
, newname
)) {
4405 return NT_STATUS_ACCESS_DENIED
;
4408 lck
= get_share_mode_lock(NULL
, fsp
->file_id
, NULL
, NULL
);
4411 * We have the file open ourselves, so not being able to get the
4412 * corresponding share mode lock is a fatal error.
4415 SMB_ASSERT(lck
!= NULL
);
4417 if(SMB_VFS_RENAME(conn
,fsp
->fsp_name
, newname
) == 0) {
4418 uint32 create_options
= fsp
->fh
->private_options
;
4420 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
4421 fsp
->fsp_name
,newname
));
4423 rename_open_files(conn
, lck
, newname
);
4425 notify_rename(conn
, fsp
->is_directory
, fsp
->fsp_name
, newname
);
4428 * A rename acts as a new file create w.r.t. allowing an initial delete
4429 * on close, probably because in Windows there is a new handle to the
4430 * new file. If initial delete on close was requested but not
4431 * originally set, we need to set it here. This is probably not 100% correct,
4432 * but will work for the CIFSFS client which in non-posix mode
4433 * depends on these semantics. JRA.
4436 set_allow_initial_delete_on_close(lck
, fsp
, True
);
4438 if (create_options
& FILE_DELETE_ON_CLOSE
) {
4439 status
= can_set_delete_on_close(fsp
, True
, 0);
4441 if (NT_STATUS_IS_OK(status
)) {
4442 /* Note that here we set the *inital* delete on close flag,
4443 * not the regular one. The magic gets handled in close. */
4444 fsp
->initial_delete_on_close
= True
;
4448 return NT_STATUS_OK
;
4453 if (errno
== ENOTDIR
|| errno
== EISDIR
) {
4454 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
4456 status
= map_nt_error_from_unix(errno
);
4459 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
4460 nt_errstr(status
), fsp
->fsp_name
,newname
));
4465 /****************************************************************************
4466 The guts of the rename command, split out so it may be called by the NT SMB
4468 ****************************************************************************/
4470 NTSTATUS
rename_internals(connection_struct
*conn
,
4474 BOOL replace_if_exists
,
4480 pstring last_component_src
;
4481 pstring last_component_dest
;
4484 NTSTATUS status
= NT_STATUS_OK
;
4485 SMB_STRUCT_STAT sbuf1
, sbuf2
;
4486 struct smb_Dir
*dir_hnd
= NULL
;
4491 *directory
= *mask
= 0;
4496 status
= unix_convert(conn
, name
, src_has_wild
, last_component_src
, &sbuf1
);
4497 if (!NT_STATUS_IS_OK(status
)) {
4501 status
= unix_convert(conn
, newname
, dest_has_wild
, last_component_dest
, &sbuf2
);
4502 if (!NT_STATUS_IS_OK(status
)) {
4507 * Split the old name into directory and last component
4508 * strings. Note that unix_convert may have stripped off a
4509 * leading ./ from both name and newname if the rename is
4510 * at the root of the share. We need to make sure either both
4511 * name and newname contain a / character or neither of them do
4512 * as this is checked in resolve_wildcards().
4515 p
= strrchr_m(name
,'/');
4517 pstrcpy(directory
,".");
4521 pstrcpy(directory
,name
);
4523 *p
= '/'; /* Replace needed for exceptional test below. */
4527 * We should only check the mangled cache
4528 * here if unix_convert failed. This means
4529 * that the path in 'mask' doesn't exist
4530 * on the file system and so we need to look
4531 * for a possible mangle. This patch from
4532 * Tine Smukavec <valentin.smukavec@hermes.si>.
4535 if (!VALID_STAT(sbuf1
) && mangle_is_mangled(mask
, conn
->params
)) {
4536 mangle_check_cache( mask
, sizeof(pstring
)-1, conn
->params
);
4539 if (!src_has_wild
) {
4543 * No wildcards - just process the one file.
4545 BOOL is_short_name
= mangle_is_8_3(name
, True
, conn
->params
);
4547 /* Add a terminating '/' to the directory name. */
4548 pstrcat(directory
,"/");
4549 pstrcat(directory
,mask
);
4551 /* Ensure newname contains a '/' also */
4552 if(strrchr_m(newname
,'/') == 0) {
4555 pstrcpy(tmpstr
, "./");
4556 pstrcat(tmpstr
, newname
);
4557 pstrcpy(newname
, tmpstr
);
4560 DEBUG(3, ("rename_internals: case_sensitive = %d, "
4561 "case_preserve = %d, short case preserve = %d, "
4562 "directory = %s, newname = %s, "
4563 "last_component_dest = %s, is_8_3 = %d\n",
4564 conn
->case_sensitive
, conn
->case_preserve
,
4565 conn
->short_case_preserve
, directory
,
4566 newname
, last_component_dest
, is_short_name
));
4568 /* The dest name still may have wildcards. */
4569 if (dest_has_wild
) {
4570 if (!resolve_wildcards(directory
,newname
)) {
4571 DEBUG(6, ("rename_internals: resolve_wildcards %s %s failed\n",
4572 directory
,newname
));
4573 return NT_STATUS_NO_MEMORY
;
4578 SMB_VFS_STAT(conn
, directory
, &sbuf1
);
4580 status
= S_ISDIR(sbuf1
.st_mode
) ?
4581 open_directory(conn
, directory
, &sbuf1
,
4583 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4584 FILE_OPEN
, 0, 0, NULL
,
4586 : open_file_ntcreate(conn
, directory
, &sbuf1
,
4588 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4589 FILE_OPEN
, 0, 0, 0, NULL
,
4592 if (!NT_STATUS_IS_OK(status
)) {
4593 DEBUG(3, ("Could not open rename source %s: %s\n",
4594 directory
, nt_errstr(status
)));
4598 status
= rename_internals_fsp(conn
, fsp
, newname
, attrs
,
4601 close_file(fsp
, NORMAL_CLOSE
);
4603 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
4604 nt_errstr(status
), directory
,newname
));
4610 * Wildcards - process each file that matches.
4612 if (strequal(mask
,"????????.???")) {
4616 status
= check_name(conn
, directory
);
4617 if (!NT_STATUS_IS_OK(status
)) {
4621 dir_hnd
= OpenDir(conn
, directory
, mask
, attrs
);
4622 if (dir_hnd
== NULL
) {
4623 return map_nt_error_from_unix(errno
);
4626 status
= NT_STATUS_NO_SUCH_FILE
;
4628 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
4629 * - gentest fix. JRA
4632 while ((dname
= ReadDirName(dir_hnd
, &offset
))) {
4635 BOOL sysdir_entry
= False
;
4637 pstrcpy(fname
,dname
);
4639 /* Quick check for "." and ".." */
4640 if (fname
[0] == '.') {
4641 if (!fname
[1] || (fname
[1] == '.' && !fname
[2])) {
4643 sysdir_entry
= True
;
4650 if (!is_visible_file(conn
, directory
, dname
, &sbuf1
, False
)) {
4654 if(!mask_match(fname
, mask
, conn
->case_sensitive
)) {
4659 status
= NT_STATUS_OBJECT_NAME_INVALID
;
4663 slprintf(fname
, sizeof(fname
)-1, "%s/%s", directory
, dname
);
4665 pstrcpy(destname
,newname
);
4667 if (!resolve_wildcards(fname
,destname
)) {
4668 DEBUG(6, ("resolve_wildcards %s %s failed\n",
4674 SMB_VFS_STAT(conn
, fname
, &sbuf1
);
4676 status
= S_ISDIR(sbuf1
.st_mode
) ?
4677 open_directory(conn
, fname
, &sbuf1
,
4679 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4680 FILE_OPEN
, 0, 0, NULL
,
4682 : open_file_ntcreate(conn
, fname
, &sbuf1
,
4684 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4685 FILE_OPEN
, 0, 0, 0, NULL
,
4688 if (!NT_STATUS_IS_OK(status
)) {
4689 DEBUG(3,("rename_internals: open_file_ntcreate "
4690 "returned %s rename %s -> %s\n",
4691 nt_errstr(status
), directory
, newname
));
4695 status
= rename_internals_fsp(conn
, fsp
, destname
, attrs
,
4698 close_file(fsp
, NORMAL_CLOSE
);
4700 if (!NT_STATUS_IS_OK(status
)) {
4701 DEBUG(3, ("rename_internals_fsp returned %s for "
4702 "rename %s -> %s\n", nt_errstr(status
),
4703 directory
, newname
));
4709 DEBUG(3,("rename_internals: doing rename on %s -> "
4710 "%s\n",fname
,destname
));
4714 if (count
== 0 && NT_STATUS_IS_OK(status
)) {
4715 status
= map_nt_error_from_unix(errno
);
4721 /****************************************************************************
4723 ****************************************************************************/
4725 int reply_mv(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
,
4732 uint32 attrs
= SVAL(inbuf
,smb_vwv0
);
4734 BOOL src_has_wcard
= False
;
4735 BOOL dest_has_wcard
= False
;
4737 START_PROFILE(SMBmv
);
4739 p
= smb_buf(inbuf
) + 1;
4740 p
+= srvstr_get_path_wcard(inbuf
, name
, p
, sizeof(name
), 0, STR_TERMINATE
, &status
, &src_has_wcard
);
4741 if (!NT_STATUS_IS_OK(status
)) {
4743 return ERROR_NT(status
);
4746 p
+= srvstr_get_path_wcard(inbuf
, newname
, p
, sizeof(newname
), 0, STR_TERMINATE
, &status
, &dest_has_wcard
);
4747 if (!NT_STATUS_IS_OK(status
)) {
4749 return ERROR_NT(status
);
4752 status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, name
, &src_has_wcard
);
4753 if (!NT_STATUS_IS_OK(status
)) {
4755 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
4756 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
4758 return ERROR_NT(status
);
4761 status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, newname
, &dest_has_wcard
);
4762 if (!NT_STATUS_IS_OK(status
)) {
4764 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
4765 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
4767 return ERROR_NT(status
);
4770 DEBUG(3,("reply_mv : %s -> %s\n",name
,newname
));
4772 status
= rename_internals(conn
, name
, newname
, attrs
, False
, src_has_wcard
, dest_has_wcard
);
4773 if (!NT_STATUS_IS_OK(status
)) {
4775 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
4776 /* We have re-scheduled this call. */
4779 return ERROR_NT(status
);
4782 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
4788 /*******************************************************************
4789 Copy a file as part of a reply_copy.
4790 ******************************************************************/
4793 * TODO: check error codes on all callers
4796 NTSTATUS
copy_file(connection_struct
*conn
,
4801 BOOL target_is_directory
)
4803 SMB_STRUCT_STAT src_sbuf
, sbuf2
;
4805 files_struct
*fsp1
,*fsp2
;
4808 uint32 new_create_disposition
;
4811 pstrcpy(dest
,dest1
);
4812 if (target_is_directory
) {
4813 char *p
= strrchr_m(src
,'/');
4823 if (!vfs_file_exist(conn
,src
,&src_sbuf
)) {
4824 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4827 if (!target_is_directory
&& count
) {
4828 new_create_disposition
= FILE_OPEN
;
4830 if (!map_open_params_to_ntcreate(dest1
,0,ofun
,
4831 NULL
, NULL
, &new_create_disposition
, NULL
)) {
4832 return NT_STATUS_INVALID_PARAMETER
;
4836 status
= open_file_ntcreate(conn
,src
,&src_sbuf
,
4838 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4841 FILE_ATTRIBUTE_NORMAL
,
4845 if (!NT_STATUS_IS_OK(status
)) {
4849 dosattrs
= dos_mode(conn
, src
, &src_sbuf
);
4850 if (SMB_VFS_STAT(conn
,dest
,&sbuf2
) == -1) {
4851 ZERO_STRUCTP(&sbuf2
);
4854 status
= open_file_ntcreate(conn
,dest
,&sbuf2
,
4856 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4857 new_create_disposition
,
4863 if (!NT_STATUS_IS_OK(status
)) {
4864 close_file(fsp1
,ERROR_CLOSE
);
4868 if ((ofun
&3) == 1) {
4869 if(SMB_VFS_LSEEK(fsp2
,fsp2
->fh
->fd
,0,SEEK_END
) == -1) {
4870 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno
) ));
4872 * Stop the copy from occurring.
4875 src_sbuf
.st_size
= 0;
4879 if (src_sbuf
.st_size
) {
4880 ret
= vfs_transfer_file(fsp1
, fsp2
, src_sbuf
.st_size
);
4883 close_file(fsp1
,NORMAL_CLOSE
);
4885 /* Ensure the modtime is set correctly on the destination file. */
4886 fsp_set_pending_modtime( fsp2
, get_mtimespec(&src_sbuf
));
4889 * As we are opening fsp1 read-only we only expect
4890 * an error on close on fsp2 if we are out of space.
4891 * Thus we don't look at the error return from the
4894 status
= close_file(fsp2
,NORMAL_CLOSE
);
4896 if (!NT_STATUS_IS_OK(status
)) {
4900 if (ret
!= (SMB_OFF_T
)src_sbuf
.st_size
) {
4901 return NT_STATUS_DISK_FULL
;
4904 return NT_STATUS_OK
;
4907 /****************************************************************************
4908 Reply to a file copy.
4909 ****************************************************************************/
4911 int reply_copy(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
4916 pstring mask
,newname
;
4919 int error
= ERRnoaccess
;
4921 int tid2
= SVAL(inbuf
,smb_vwv0
);
4922 int ofun
= SVAL(inbuf
,smb_vwv1
);
4923 int flags
= SVAL(inbuf
,smb_vwv2
);
4924 BOOL target_is_directory
=False
;
4925 BOOL source_has_wild
= False
;
4926 BOOL dest_has_wild
= False
;
4927 SMB_STRUCT_STAT sbuf1
, sbuf2
;
4929 START_PROFILE(SMBcopy
);
4931 *directory
= *mask
= 0;
4934 p
+= srvstr_get_path_wcard(inbuf
, name
, p
, sizeof(name
), 0, STR_TERMINATE
, &status
, &source_has_wild
);
4935 if (!NT_STATUS_IS_OK(status
)) {
4936 END_PROFILE(SMBcopy
);
4937 return ERROR_NT(status
);
4939 p
+= srvstr_get_path_wcard(inbuf
, newname
, p
, sizeof(newname
), 0, STR_TERMINATE
, &status
, &dest_has_wild
);
4940 if (!NT_STATUS_IS_OK(status
)) {
4941 END_PROFILE(SMBcopy
);
4942 return ERROR_NT(status
);
4945 DEBUG(3,("reply_copy : %s -> %s\n",name
,newname
));
4947 if (tid2
!= conn
->cnum
) {
4948 /* can't currently handle inter share copies XXXX */
4949 DEBUG(3,("Rejecting inter-share copy\n"));
4950 END_PROFILE(SMBcopy
);
4951 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
4954 status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, name
, &source_has_wild
);
4955 if (!NT_STATUS_IS_OK(status
)) {
4956 END_PROFILE(SMBcopy
);
4957 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
4958 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
4960 return ERROR_NT(status
);
4963 status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, newname
, &dest_has_wild
);
4964 if (!NT_STATUS_IS_OK(status
)) {
4965 END_PROFILE(SMBcopy
);
4966 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
4967 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
4969 return ERROR_NT(status
);
4972 status
= unix_convert(conn
, name
, source_has_wild
, NULL
, &sbuf1
);
4973 if (!NT_STATUS_IS_OK(status
)) {
4974 END_PROFILE(SMBcopy
);
4975 return ERROR_NT(status
);
4978 status
= unix_convert(conn
, newname
, dest_has_wild
, NULL
, &sbuf2
);
4979 if (!NT_STATUS_IS_OK(status
)) {
4980 END_PROFILE(SMBcopy
);
4981 return ERROR_NT(status
);
4984 target_is_directory
= VALID_STAT_OF_DIR(sbuf2
);
4986 if ((flags
&1) && target_is_directory
) {
4987 END_PROFILE(SMBcopy
);
4988 return ERROR_DOS(ERRDOS
,ERRbadfile
);
4991 if ((flags
&2) && !target_is_directory
) {
4992 END_PROFILE(SMBcopy
);
4993 return ERROR_DOS(ERRDOS
,ERRbadpath
);
4996 if ((flags
&(1<<5)) && VALID_STAT_OF_DIR(sbuf1
)) {
4997 /* wants a tree copy! XXXX */
4998 DEBUG(3,("Rejecting tree copy\n"));
4999 END_PROFILE(SMBcopy
);
5000 return ERROR_DOS(ERRSRV
,ERRerror
);
5003 p
= strrchr_m(name
,'/');
5005 pstrcpy(directory
,"./");
5009 pstrcpy(directory
,name
);
5014 * We should only check the mangled cache
5015 * here if unix_convert failed. This means
5016 * that the path in 'mask' doesn't exist
5017 * on the file system and so we need to look
5018 * for a possible mangle. This patch from
5019 * Tine Smukavec <valentin.smukavec@hermes.si>.
5022 if (!VALID_STAT(sbuf1
) && mangle_is_mangled(mask
, conn
->params
)) {
5023 mangle_check_cache( mask
, sizeof(pstring
)-1, conn
->params
);
5026 if (!source_has_wild
) {
5027 pstrcat(directory
,"/");
5028 pstrcat(directory
,mask
);
5029 if (dest_has_wild
) {
5030 if (!resolve_wildcards(directory
,newname
)) {
5031 END_PROFILE(SMBcopy
);
5032 return ERROR_NT(NT_STATUS_NO_MEMORY
);
5036 status
= check_name(conn
, directory
);
5037 if (!NT_STATUS_IS_OK(status
)) {
5038 return ERROR_NT(status
);
5041 status
= check_name(conn
, newname
);
5042 if (!NT_STATUS_IS_OK(status
)) {
5043 return ERROR_NT(status
);
5046 status
= copy_file(conn
,directory
,newname
,ofun
,
5047 count
,target_is_directory
);
5049 if(!NT_STATUS_IS_OK(status
)) {
5050 END_PROFILE(SMBcopy
);
5051 return ERROR_NT(status
);
5056 struct smb_Dir
*dir_hnd
= NULL
;
5061 if (strequal(mask
,"????????.???"))
5064 status
= check_name(conn
, directory
);
5065 if (!NT_STATUS_IS_OK(status
)) {
5066 return ERROR_NT(status
);
5069 dir_hnd
= OpenDir(conn
, directory
, mask
, 0);
5070 if (dir_hnd
== NULL
) {
5071 status
= map_nt_error_from_unix(errno
);
5072 return ERROR_NT(status
);
5077 while ((dname
= ReadDirName(dir_hnd
, &offset
))) {
5079 pstrcpy(fname
,dname
);
5081 if (!is_visible_file(conn
, directory
, dname
, &sbuf1
, False
)) {
5085 if(!mask_match(fname
, mask
, conn
->case_sensitive
)) {
5089 error
= ERRnoaccess
;
5090 slprintf(fname
,sizeof(fname
)-1, "%s/%s",directory
,dname
);
5091 pstrcpy(destname
,newname
);
5092 if (!resolve_wildcards(fname
,destname
)) {
5096 status
= check_name(conn
, fname
);
5097 if (!NT_STATUS_IS_OK(status
)) {
5098 return ERROR_NT(status
);
5101 status
= check_name(conn
, destname
);
5102 if (!NT_STATUS_IS_OK(status
)) {
5103 return ERROR_NT(status
);
5106 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname
, destname
));
5108 status
= copy_file(conn
,fname
,destname
,ofun
,
5109 count
,target_is_directory
);
5110 if (NT_STATUS_IS_OK(status
)) {
5119 /* Error on close... */
5121 END_PROFILE(SMBcopy
);
5122 return(UNIXERROR(ERRHRD
,ERRgeneral
));
5125 END_PROFILE(SMBcopy
);
5126 return ERROR_DOS(ERRDOS
,error
);
5129 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
5130 SSVAL(outbuf
,smb_vwv0
,count
);
5132 END_PROFILE(SMBcopy
);
5136 /****************************************************************************
5138 ****************************************************************************/
5140 int reply_setdir(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
5147 START_PROFILE(pathworks_setdir
);
5150 if (!CAN_SETDIR(snum
)) {
5151 END_PROFILE(pathworks_setdir
);
5152 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5155 srvstr_get_path(inbuf
, newdir
, smb_buf(inbuf
) + 1, sizeof(newdir
), 0, STR_TERMINATE
, &status
);
5156 if (!NT_STATUS_IS_OK(status
)) {
5157 END_PROFILE(pathworks_setdir
);
5158 return ERROR_NT(status
);
5161 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, newdir
);
5162 if (!NT_STATUS_IS_OK(status
)) {
5163 END_PROFILE(pathworks_setdir
);
5164 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5165 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
5167 return ERROR_NT(status
);
5170 if (strlen(newdir
) != 0) {
5171 if (!vfs_directory_exist(conn
,newdir
,NULL
)) {
5172 END_PROFILE(pathworks_setdir
);
5173 return ERROR_DOS(ERRDOS
,ERRbadpath
);
5175 set_conn_connectpath(conn
,newdir
);
5178 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
5179 SCVAL(outbuf
,smb_reh
,CVAL(inbuf
,smb_reh
));
5181 DEBUG(3,("setdir %s\n", newdir
));
5183 END_PROFILE(pathworks_setdir
);
5188 #define DBGC_CLASS DBGC_LOCKING
5190 /****************************************************************************
5191 Get a lock pid, dealing with large count requests.
5192 ****************************************************************************/
5194 uint32
get_lock_pid( char *data
, int data_offset
, BOOL large_file_format
)
5196 if(!large_file_format
)
5197 return (uint32
)SVAL(data
,SMB_LPID_OFFSET(data_offset
));
5199 return (uint32
)SVAL(data
,SMB_LARGE_LPID_OFFSET(data_offset
));
5202 /****************************************************************************
5203 Get a lock count, dealing with large count requests.
5204 ****************************************************************************/
5206 SMB_BIG_UINT
get_lock_count( char *data
, int data_offset
, BOOL large_file_format
)
5208 SMB_BIG_UINT count
= 0;
5210 if(!large_file_format
) {
5211 count
= (SMB_BIG_UINT
)IVAL(data
,SMB_LKLEN_OFFSET(data_offset
));
5214 #if defined(HAVE_LONGLONG)
5215 count
= (((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
))) << 32) |
5216 ((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
)));
5217 #else /* HAVE_LONGLONG */
5220 * NT4.x seems to be broken in that it sends large file (64 bit)
5221 * lockingX calls even if the CAP_LARGE_FILES was *not*
5222 * negotiated. For boxes without large unsigned ints truncate the
5223 * lock count by dropping the top 32 bits.
5226 if(IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
)) != 0) {
5227 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
5228 (unsigned int)IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
)),
5229 (unsigned int)IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
)) ));
5230 SIVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
),0);
5233 count
= (SMB_BIG_UINT
)IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
));
5234 #endif /* HAVE_LONGLONG */
5240 #if !defined(HAVE_LONGLONG)
5241 /****************************************************************************
5242 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
5243 ****************************************************************************/
5245 static uint32
map_lock_offset(uint32 high
, uint32 low
)
5249 uint32 highcopy
= high
;
5252 * Try and find out how many significant bits there are in high.
5255 for(i
= 0; highcopy
; i
++)
5259 * We use 31 bits not 32 here as POSIX
5260 * lock offsets may not be negative.
5263 mask
= (~0) << (31 - i
);
5266 return 0; /* Fail. */
5272 #endif /* !defined(HAVE_LONGLONG) */
5274 /****************************************************************************
5275 Get a lock offset, dealing with large offset requests.
5276 ****************************************************************************/
5278 SMB_BIG_UINT
get_lock_offset( char *data
, int data_offset
, BOOL large_file_format
, BOOL
*err
)
5280 SMB_BIG_UINT offset
= 0;
5284 if(!large_file_format
) {
5285 offset
= (SMB_BIG_UINT
)IVAL(data
,SMB_LKOFF_OFFSET(data_offset
));
5288 #if defined(HAVE_LONGLONG)
5289 offset
= (((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
))) << 32) |
5290 ((SMB_BIG_UINT
) IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
)));
5291 #else /* HAVE_LONGLONG */
5294 * NT4.x seems to be broken in that it sends large file (64 bit)
5295 * lockingX calls even if the CAP_LARGE_FILES was *not*
5296 * negotiated. For boxes without large unsigned ints mangle the
5297 * lock offset by mapping the top 32 bits onto the lower 32.
5300 if(IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
)) != 0) {
5301 uint32 low
= IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
));
5302 uint32 high
= IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
));
5305 if((new_low
= map_lock_offset(high
, low
)) == 0) {
5307 return (SMB_BIG_UINT
)-1;
5310 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
5311 (unsigned int)high
, (unsigned int)low
, (unsigned int)new_low
));
5312 SIVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
),0);
5313 SIVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
),new_low
);
5316 offset
= (SMB_BIG_UINT
)IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
));
5317 #endif /* HAVE_LONGLONG */
5323 /****************************************************************************
5324 Reply to a lockingX request.
5325 ****************************************************************************/
5327 int reply_lockingX(connection_struct
*conn
, char *inbuf
, char *outbuf
,
5328 int length
, int bufsize
)
5330 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv2
);
5331 unsigned char locktype
= CVAL(inbuf
,smb_vwv3
);
5332 unsigned char oplocklevel
= CVAL(inbuf
,smb_vwv3
+1);
5333 uint16 num_ulocks
= SVAL(inbuf
,smb_vwv6
);
5334 uint16 num_locks
= SVAL(inbuf
,smb_vwv7
);
5335 SMB_BIG_UINT count
= 0, offset
= 0;
5337 int32 lock_timeout
= IVAL(inbuf
,smb_vwv4
);
5340 BOOL large_file_format
=
5341 (locktype
& LOCKING_ANDX_LARGE_FILES
)?True
:False
;
5343 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
5345 START_PROFILE(SMBlockingX
);
5347 CHECK_FSP(fsp
,conn
);
5349 data
= smb_buf(inbuf
);
5351 if (locktype
& LOCKING_ANDX_CHANGE_LOCKTYPE
) {
5352 /* we don't support these - and CANCEL_LOCK makes w2k
5353 and XP reboot so I don't really want to be
5354 compatible! (tridge) */
5355 return ERROR_NT(NT_STATUS_DOS(ERRDOS
, ERRnoatomiclocks
));
5358 /* Check if this is an oplock break on a file
5359 we have granted an oplock on.
5361 if ((locktype
& LOCKING_ANDX_OPLOCK_RELEASE
)) {
5362 /* Client can insist on breaking to none. */
5363 BOOL break_to_none
= (oplocklevel
== 0);
5366 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
5367 "for fnum = %d\n", (unsigned int)oplocklevel
,
5371 * Make sure we have granted an exclusive or batch oplock on
5375 if (fsp
->oplock_type
== 0) {
5377 /* The Samba4 nbench simulator doesn't understand
5378 the difference between break to level2 and break
5379 to none from level2 - it sends oplock break
5380 replies in both cases. Don't keep logging an error
5381 message here - just ignore it. JRA. */
5383 DEBUG(5,("reply_lockingX: Error : oplock break from "
5384 "client for fnum = %d (oplock=%d) and no "
5385 "oplock granted on this file (%s).\n",
5386 fsp
->fnum
, fsp
->oplock_type
, fsp
->fsp_name
));
5388 /* if this is a pure oplock break request then don't
5390 if (num_locks
== 0 && num_ulocks
== 0) {
5391 END_PROFILE(SMBlockingX
);
5394 END_PROFILE(SMBlockingX
);
5395 return ERROR_DOS(ERRDOS
,ERRlock
);
5399 if ((fsp
->sent_oplock_break
== BREAK_TO_NONE_SENT
) ||
5401 result
= remove_oplock(fsp
);
5403 result
= downgrade_oplock(fsp
);
5407 DEBUG(0, ("reply_lockingX: error in removing "
5408 "oplock on file %s\n", fsp
->fsp_name
));
5409 /* Hmmm. Is this panic justified? */
5410 smb_panic("internal tdb error");
5413 reply_to_oplock_break_requests(fsp
);
5415 /* if this is a pure oplock break request then don't send a
5417 if (num_locks
== 0 && num_ulocks
== 0) {
5418 /* Sanity check - ensure a pure oplock break is not a
5420 if(CVAL(inbuf
,smb_vwv0
) != 0xff)
5421 DEBUG(0,("reply_lockingX: Error : pure oplock "
5422 "break is a chained %d request !\n",
5423 (unsigned int)CVAL(inbuf
,smb_vwv0
) ));
5424 END_PROFILE(SMBlockingX
);
5430 * We do this check *after* we have checked this is not a oplock break
5431 * response message. JRA.
5434 release_level_2_oplocks_on_change(fsp
);
5436 /* Data now points at the beginning of the list
5437 of smb_unlkrng structs */
5438 for(i
= 0; i
< (int)num_ulocks
; i
++) {
5439 lock_pid
= get_lock_pid( data
, i
, large_file_format
);
5440 count
= get_lock_count( data
, i
, large_file_format
);
5441 offset
= get_lock_offset( data
, i
, large_file_format
, &err
);
5444 * There is no error code marked "stupid client bug".... :-).
5447 END_PROFILE(SMBlockingX
);
5448 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5451 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
5452 "pid %u, file %s\n", (double)offset
, (double)count
,
5453 (unsigned int)lock_pid
, fsp
->fsp_name
));
5455 status
= do_unlock(smbd_messaging_context(),
5462 if (NT_STATUS_V(status
)) {
5463 END_PROFILE(SMBlockingX
);
5464 return ERROR_NT(status
);
5468 /* Setup the timeout in seconds. */
5470 if (!lp_blocking_locks(SNUM(conn
))) {
5474 /* Now do any requested locks */
5475 data
+= ((large_file_format
? 20 : 10)*num_ulocks
);
5477 /* Data now points at the beginning of the list
5478 of smb_lkrng structs */
5480 for(i
= 0; i
< (int)num_locks
; i
++) {
5481 enum brl_type lock_type
= ((locktype
& LOCKING_ANDX_SHARED_LOCK
) ?
5482 READ_LOCK
:WRITE_LOCK
);
5483 lock_pid
= get_lock_pid( data
, i
, large_file_format
);
5484 count
= get_lock_count( data
, i
, large_file_format
);
5485 offset
= get_lock_offset( data
, i
, large_file_format
, &err
);
5488 * There is no error code marked "stupid client bug".... :-).
5491 END_PROFILE(SMBlockingX
);
5492 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5495 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
5496 "%u, file %s timeout = %d\n", (double)offset
,
5497 (double)count
, (unsigned int)lock_pid
,
5498 fsp
->fsp_name
, (int)lock_timeout
));
5500 if (locktype
& LOCKING_ANDX_CANCEL_LOCK
) {
5501 if (lp_blocking_locks(SNUM(conn
))) {
5503 /* Schedule a message to ourselves to
5504 remove the blocking lock record and
5505 return the right error. */
5507 if (!blocking_lock_cancel(fsp
,
5513 NT_STATUS_FILE_LOCK_CONFLICT
)) {
5514 END_PROFILE(SMBlockingX
);
5515 return ERROR_NT(NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
));
5518 /* Remove a matching pending lock. */
5519 status
= do_lock_cancel(fsp
,
5525 BOOL blocking_lock
= lock_timeout
? True
: False
;
5526 BOOL defer_lock
= False
;
5527 struct byte_range_lock
*br_lck
;
5528 uint32 block_smbpid
;
5530 br_lck
= do_lock(smbd_messaging_context(),
5541 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
5542 /* Windows internal resolution for blocking locks seems
5543 to be about 200ms... Don't wait for less than that. JRA. */
5544 if (lock_timeout
!= -1 && lock_timeout
< lp_lock_spin_time()) {
5545 lock_timeout
= lp_lock_spin_time();
5550 /* This heuristic seems to match W2K3 very well. If a
5551 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
5552 it pretends we asked for a timeout of between 150 - 300 milliseconds as
5553 far as I can tell. Replacement for do_lock_spin(). JRA. */
5555 if (br_lck
&& lp_blocking_locks(SNUM(conn
)) && !blocking_lock
&&
5556 NT_STATUS_EQUAL((status
), NT_STATUS_FILE_LOCK_CONFLICT
)) {
5558 lock_timeout
= lp_lock_spin_time();
5561 if (br_lck
&& defer_lock
) {
5563 * A blocking lock was requested. Package up
5564 * this smb into a queued request and push it
5565 * onto the blocking lock queue.
5567 if(push_blocking_lock_request(br_lck
,
5578 TALLOC_FREE(br_lck
);
5579 END_PROFILE(SMBlockingX
);
5584 TALLOC_FREE(br_lck
);
5587 if (NT_STATUS_V(status
)) {
5588 END_PROFILE(SMBlockingX
);
5589 return ERROR_NT(status
);
5593 /* If any of the above locks failed, then we must unlock
5594 all of the previous locks (X/Open spec). */
5596 if (!(locktype
& LOCKING_ANDX_CANCEL_LOCK
) &&
5600 * Ensure we don't do a remove on the lock that just failed,
5601 * as under POSIX rules, if we have a lock already there, we
5602 * will delete it (and we shouldn't) .....
5604 for(i
--; i
>= 0; i
--) {
5605 lock_pid
= get_lock_pid( data
, i
, large_file_format
);
5606 count
= get_lock_count( data
, i
, large_file_format
);
5607 offset
= get_lock_offset( data
, i
, large_file_format
,
5611 * There is no error code marked "stupid client
5615 END_PROFILE(SMBlockingX
);
5616 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5619 do_unlock(smbd_messaging_context(),
5626 END_PROFILE(SMBlockingX
);
5627 return ERROR_NT(status
);
5630 set_message(inbuf
,outbuf
,2,0,True
);
5632 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
5633 fsp
->fnum
, (unsigned int)locktype
, num_locks
, num_ulocks
));
5635 END_PROFILE(SMBlockingX
);
5636 return chain_reply(inbuf
,outbuf
,length
,bufsize
);
5640 #define DBGC_CLASS DBGC_ALL
5642 /****************************************************************************
5643 Reply to a SMBreadbmpx (read block multiplex) request.
5644 ****************************************************************************/
5646 int reply_readbmpx(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
5657 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5658 START_PROFILE(SMBreadBmpx
);
5660 /* this function doesn't seem to work - disable by default */
5661 if (!lp_readbmpx()) {
5662 END_PROFILE(SMBreadBmpx
);
5663 return ERROR_DOS(ERRSRV
,ERRuseSTD
);
5666 outsize
= set_message(inbuf
,outbuf
,8,0,True
);
5668 CHECK_FSP(fsp
,conn
);
5669 if (!CHECK_READ(fsp
,inbuf
)) {
5670 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
5673 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv1
);
5674 maxcount
= SVAL(inbuf
,smb_vwv3
);
5676 data
= smb_buf(outbuf
);
5677 pad
= ((long)data
)%4;
5682 max_per_packet
= bufsize
-(outsize
+pad
);
5686 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)maxcount
,(SMB_BIG_UINT
)startpos
, READ_LOCK
)) {
5687 END_PROFILE(SMBreadBmpx
);
5688 return ERROR_DOS(ERRDOS
,ERRlock
);
5692 size_t N
= MIN(max_per_packet
,tcount
-total_read
);
5694 nread
= read_file(fsp
,data
,startpos
,N
);
5699 if (nread
< (ssize_t
)N
)
5700 tcount
= total_read
+ nread
;
5702 set_message(inbuf
,outbuf
,8,nread
+pad
,False
);
5703 SIVAL(outbuf
,smb_vwv0
,startpos
);
5704 SSVAL(outbuf
,smb_vwv2
,tcount
);
5705 SSVAL(outbuf
,smb_vwv6
,nread
);
5706 SSVAL(outbuf
,smb_vwv7
,smb_offset(data
,outbuf
));
5709 if (!send_smb(smbd_server_fd(),outbuf
))
5710 exit_server_cleanly("reply_readbmpx: send_smb failed.");
5712 total_read
+= nread
;
5714 } while (total_read
< (ssize_t
)tcount
);
5716 END_PROFILE(SMBreadBmpx
);
5720 /****************************************************************************
5721 Reply to a SMBsetattrE.
5722 ****************************************************************************/
5724 int reply_setattrE(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
5726 struct timespec ts
[2];
5728 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5729 START_PROFILE(SMBsetattrE
);
5731 outsize
= set_message(inbuf
,outbuf
,0,0,False
);
5733 if(!fsp
|| (fsp
->conn
!= conn
)) {
5734 END_PROFILE(SMBsetattrE
);
5735 return ERROR_DOS(ERRDOS
,ERRbadfid
);
5739 * Convert the DOS times into unix times. Ignore create
5740 * time as UNIX can't set this.
5743 ts
[0] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf
+smb_vwv3
)); /* atime. */
5744 ts
[1] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf
+smb_vwv5
)); /* mtime. */
5747 * Patch from Ray Frush <frush@engr.colostate.edu>
5748 * Sometimes times are sent as zero - ignore them.
5751 if (null_timespec(ts
[0]) && null_timespec(ts
[1])) {
5752 /* Ignore request */
5753 if( DEBUGLVL( 3 ) ) {
5754 dbgtext( "reply_setattrE fnum=%d ", fsp
->fnum
);
5755 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
5757 END_PROFILE(SMBsetattrE
);
5759 } else if (!null_timespec(ts
[0]) && null_timespec(ts
[1])) {
5760 /* set modify time = to access time if modify time was unset */
5764 /* Set the date on this file */
5765 /* Should we set pending modtime here ? JRA */
5766 if(file_ntimes(conn
, fsp
->fsp_name
, ts
)) {
5767 END_PROFILE(SMBsetattrE
);
5768 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
5771 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
5773 (unsigned int)ts
[0].tv_sec
,
5774 (unsigned int)ts
[1].tv_sec
));
5776 END_PROFILE(SMBsetattrE
);
5781 /* Back from the dead for OS/2..... JRA. */
5783 /****************************************************************************
5784 Reply to a SMBwritebmpx (write block multiplex primary) request.
5785 ****************************************************************************/
5787 int reply_writebmpx(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
5790 ssize_t nwritten
= -1;
5797 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5799 START_PROFILE(SMBwriteBmpx
);
5801 CHECK_FSP(fsp
,conn
);
5802 if (!CHECK_WRITE(fsp
)) {
5803 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
5805 if (HAS_CACHED_ERROR(fsp
)) {
5806 return(CACHED_ERROR(fsp
));
5809 tcount
= SVAL(inbuf
,smb_vwv1
);
5810 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv3
);
5811 write_through
= BITSETW(inbuf
+smb_vwv7
,0);
5812 numtowrite
= SVAL(inbuf
,smb_vwv10
);
5813 smb_doff
= SVAL(inbuf
,smb_vwv11
);
5815 data
= smb_base(inbuf
) + smb_doff
;
5817 /* If this fails we need to send an SMBwriteC response,
5818 not an SMBwritebmpx - set this up now so we don't forget */
5819 SCVAL(outbuf
,smb_com
,SMBwritec
);
5821 if (is_locked(fsp
,(uint32
)SVAL(inbuf
,smb_pid
),(SMB_BIG_UINT
)tcount
,(SMB_BIG_UINT
)startpos
,WRITE_LOCK
)) {
5822 END_PROFILE(SMBwriteBmpx
);
5823 return(ERROR_DOS(ERRDOS
,ERRlock
));
5826 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
5828 status
= sync_file(conn
, fsp
, write_through
);
5829 if (!NT_STATUS_IS_OK(status
)) {
5830 END_PROFILE(SMBwriteBmpx
);
5831 DEBUG(5,("reply_writebmpx: sync_file for %s returned %s\n",
5832 fsp
->fsp_name
, nt_errstr(status
) ));
5833 return ERROR_NT(status
);
5836 if(nwritten
< (ssize_t
)numtowrite
) {
5837 END_PROFILE(SMBwriteBmpx
);
5838 return(UNIXERROR(ERRHRD
,ERRdiskfull
));
5841 /* If the maximum to be written to this file
5842 is greater than what we just wrote then set
5843 up a secondary struct to be attached to this
5844 fd, we will use this to cache error messages etc. */
5846 if((ssize_t
)tcount
> nwritten
) {
5847 write_bmpx_struct
*wbms
;
5848 if(fsp
->wbmpx_ptr
!= NULL
)
5849 wbms
= fsp
->wbmpx_ptr
; /* Use an existing struct */
5851 wbms
= SMB_MALLOC_P(write_bmpx_struct
);
5853 DEBUG(0,("Out of memory in reply_readmpx\n"));
5854 END_PROFILE(SMBwriteBmpx
);
5855 return(ERROR_DOS(ERRSRV
,ERRnoresource
));
5857 wbms
->wr_mode
= write_through
;
5858 wbms
->wr_discard
= False
; /* No errors yet */
5859 wbms
->wr_total_written
= nwritten
;
5860 wbms
->wr_errclass
= 0;
5862 fsp
->wbmpx_ptr
= wbms
;
5865 /* We are returning successfully, set the message type back to
5867 SCVAL(outbuf
,smb_com
,SMBwriteBmpx
);
5869 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
5871 SSVALS(outbuf
,smb_vwv0
,-1); /* We don't support smb_remaining */
5873 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
5874 fsp
->fnum
, (int)numtowrite
, (int)nwritten
) );
5876 if (write_through
&& tcount
==nwritten
) {
5877 /* We need to send both a primary and a secondary response */
5878 smb_setlen(inbuf
,outbuf
,outsize
- 4);
5880 if (!send_smb(smbd_server_fd(),outbuf
))
5881 exit_server_cleanly("reply_writebmpx: send_smb failed.");
5883 /* Now the secondary */
5884 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
5885 SCVAL(outbuf
,smb_com
,SMBwritec
);
5886 SSVAL(outbuf
,smb_vwv0
,nwritten
);
5889 END_PROFILE(SMBwriteBmpx
);
5893 /****************************************************************************
5894 Reply to a SMBwritebs (write block multiplex secondary) request.
5895 ****************************************************************************/
5897 int reply_writebs(connection_struct
*conn
, char *inbuf
,char *outbuf
, int dum_size
, int dum_buffsize
)
5900 ssize_t nwritten
= -1;
5907 write_bmpx_struct
*wbms
;
5908 BOOL send_response
= False
;
5909 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5911 START_PROFILE(SMBwriteBs
);
5913 CHECK_FSP(fsp
,conn
);
5914 if (!CHECK_WRITE(fsp
)) {
5915 return(ERROR_DOS(ERRDOS
,ERRbadaccess
));
5918 tcount
= SVAL(inbuf
,smb_vwv1
);
5919 startpos
= IVAL_TO_SMB_OFF_T(inbuf
,smb_vwv2
);
5920 numtowrite
= SVAL(inbuf
,smb_vwv6
);
5921 smb_doff
= SVAL(inbuf
,smb_vwv7
);
5923 data
= smb_base(inbuf
) + smb_doff
;
5925 /* We need to send an SMBwriteC response, not an SMBwritebs */
5926 SCVAL(outbuf
,smb_com
,SMBwritec
);
5928 /* This fd should have an auxiliary struct attached,
5929 check that it does */
5930 wbms
= fsp
->wbmpx_ptr
;
5932 END_PROFILE(SMBwriteBs
);
5936 /* If write through is set we can return errors, else we must cache them */
5937 write_through
= wbms
->wr_mode
;
5939 /* Check for an earlier error */
5940 if(wbms
->wr_discard
) {
5941 END_PROFILE(SMBwriteBs
);
5942 return -1; /* Just discard the packet */
5945 nwritten
= write_file(fsp
,data
,startpos
,numtowrite
);
5947 status
= sync_file(conn
, fsp
, write_through
);
5949 if (nwritten
< (ssize_t
)numtowrite
|| !NT_STATUS_IS_OK(status
)) {
5951 /* We are returning an error - we can delete the aux struct */
5954 fsp
->wbmpx_ptr
= NULL
;
5955 END_PROFILE(SMBwriteBs
);
5956 return(ERROR_DOS(ERRHRD
,ERRdiskfull
));
5958 wbms
->wr_errclass
= ERRHRD
;
5959 wbms
->wr_error
= ERRdiskfull
;
5960 wbms
->wr_status
= NT_STATUS_DISK_FULL
;
5961 wbms
->wr_discard
= True
;
5962 END_PROFILE(SMBwriteBs
);
5966 /* Increment the total written, if this matches tcount
5967 we can discard the auxiliary struct (hurrah !) and return a writeC */
5968 wbms
->wr_total_written
+= nwritten
;
5969 if(wbms
->wr_total_written
>= tcount
) {
5970 if (write_through
) {
5971 outsize
= set_message(inbuf
,outbuf
,1,0,True
);
5972 SSVAL(outbuf
,smb_vwv0
,wbms
->wr_total_written
);
5973 send_response
= True
;
5977 fsp
->wbmpx_ptr
= NULL
;
5981 END_PROFILE(SMBwriteBs
);
5985 END_PROFILE(SMBwriteBs
);
5989 /****************************************************************************
5990 Reply to a SMBgetattrE.
5991 ****************************************************************************/
5993 int reply_getattrE(connection_struct
*conn
, char *inbuf
,char *outbuf
, int size
, int dum_buffsize
)
5995 SMB_STRUCT_STAT sbuf
;
5998 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv0
);
5999 START_PROFILE(SMBgetattrE
);
6001 outsize
= set_message(inbuf
,outbuf
,11,0,True
);
6003 if(!fsp
|| (fsp
->conn
!= conn
)) {
6004 END_PROFILE(SMBgetattrE
);
6005 return ERROR_DOS(ERRDOS
,ERRbadfid
);
6008 /* Do an fstat on this file */
6009 if(fsp_stat(fsp
, &sbuf
)) {
6010 END_PROFILE(SMBgetattrE
);
6011 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
6014 mode
= dos_mode(conn
,fsp
->fsp_name
,&sbuf
);
6017 * Convert the times into dos times. Set create
6018 * date to be last modify date as UNIX doesn't save
6022 srv_put_dos_date2(outbuf
,smb_vwv0
,get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
))));
6023 srv_put_dos_date2(outbuf
,smb_vwv2
,sbuf
.st_atime
);
6024 /* Should we check pending modtime here ? JRA */
6025 srv_put_dos_date2(outbuf
,smb_vwv4
,sbuf
.st_mtime
);
6028 SIVAL(outbuf
,smb_vwv6
,0);
6029 SIVAL(outbuf
,smb_vwv8
,0);
6031 uint32 allocation_size
= get_allocation_size(conn
,fsp
, &sbuf
);
6032 SIVAL(outbuf
,smb_vwv6
,(uint32
)sbuf
.st_size
);
6033 SIVAL(outbuf
,smb_vwv8
,allocation_size
);
6035 SSVAL(outbuf
,smb_vwv10
, mode
);
6037 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp
->fnum
));
6039 END_PROFILE(SMBgetattrE
);