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.
7 Copyright (C) Volker Lendecke 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This file handles most of the reply_ calls that the server
24 makes to handle specific protocols
28 #include "system/filesys.h"
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32 #include "fake_file.h"
33 #include "rpc_client/rpc_client.h"
34 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
35 #include "../librpc/gen_ndr/open_files.h"
36 #include "rpc_client/cli_spoolss.h"
37 #include "rpc_client/init_spoolss.h"
38 #include "rpc_server/rpc_ncacn_np.h"
39 #include "libcli/security/security.h"
40 #include "libsmb/nmblib.h"
42 #include "smbprofile.h"
43 #include "../lib/tsocket/tsocket.h"
44 #include "lib/tevent_wait.h"
45 #include "libcli/smb/smb_signing.h"
47 /****************************************************************************
48 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
49 path or anything including wildcards.
50 We're assuming here that '/' is not the second byte in any multibyte char
51 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
53 ****************************************************************************/
55 /* Custom version for processing POSIX paths. */
56 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
58 static NTSTATUS
check_path_syntax_internal(char *path
,
60 bool *p_last_component_contains_wcard
)
64 NTSTATUS ret
= NT_STATUS_OK
;
65 bool start_of_name_component
= True
;
66 bool stream_started
= false;
68 *p_last_component_contains_wcard
= False
;
75 return NT_STATUS_OBJECT_NAME_INVALID
;
78 return NT_STATUS_OBJECT_NAME_INVALID
;
80 if (strchr_m(&s
[1], ':')) {
81 return NT_STATUS_OBJECT_NAME_INVALID
;
87 if ((*s
== ':') && !posix_path
&& !stream_started
) {
88 if (*p_last_component_contains_wcard
) {
89 return NT_STATUS_OBJECT_NAME_INVALID
;
91 /* Stream names allow more characters than file names.
92 We're overloading posix_path here to allow a wider
93 range of characters. If stream_started is true this
94 is still a Windows path even if posix_path is true.
97 stream_started
= true;
98 start_of_name_component
= false;
102 return NT_STATUS_OBJECT_NAME_INVALID
;
106 if (!stream_started
&& IS_PATH_SEP(*s
,posix_path
)) {
108 * Safe to assume is not the second part of a mb char
109 * as this is handled below.
111 /* Eat multiple '/' or '\\' */
112 while (IS_PATH_SEP(*s
,posix_path
)) {
115 if ((d
!= path
) && (*s
!= '\0')) {
116 /* We only care about non-leading or trailing '/' or '\\' */
120 start_of_name_component
= True
;
122 *p_last_component_contains_wcard
= False
;
126 if (start_of_name_component
) {
127 if ((s
[0] == '.') && (s
[1] == '.') && (IS_PATH_SEP(s
[2],posix_path
) || s
[2] == '\0')) {
128 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
131 * No mb char starts with '.' so we're safe checking the directory separator here.
134 /* If we just added a '/' - delete it */
135 if ((d
> path
) && (*(d
-1) == '/')) {
140 /* Are we at the start ? Can't go back further if so. */
142 ret
= NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
145 /* Go back one level... */
146 /* We know this is safe as '/' cannot be part of a mb sequence. */
147 /* NOTE - if this assumption is invalid we are not in good shape... */
148 /* Decrement d first as d points to the *next* char to write into. */
149 for (d
--; d
> path
; d
--) {
153 s
+= 2; /* Else go past the .. */
154 /* We're still at the start of a name component, just the previous one. */
157 } else if ((s
[0] == '.') && ((s
[1] == '\0') || IS_PATH_SEP(s
[1],posix_path
))) {
169 if (*s
<= 0x1f || *s
== '|') {
170 return NT_STATUS_OBJECT_NAME_INVALID
;
178 *p_last_component_contains_wcard
= True
;
187 /* Get the size of the next MB character. */
188 next_codepoint(s
,&siz
);
206 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
208 return NT_STATUS_INVALID_PARAMETER
;
211 start_of_name_component
= False
;
219 /****************************************************************************
220 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
221 No wildcards allowed.
222 ****************************************************************************/
224 NTSTATUS
check_path_syntax(char *path
)
227 return check_path_syntax_internal(path
, False
, &ignore
);
230 /****************************************************************************
231 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
232 Wildcards allowed - p_contains_wcard returns true if the last component contained
234 ****************************************************************************/
236 NTSTATUS
check_path_syntax_wcard(char *path
, bool *p_contains_wcard
)
238 return check_path_syntax_internal(path
, False
, p_contains_wcard
);
241 /****************************************************************************
242 Check the path for a POSIX client.
243 We're assuming here that '/' is not the second byte in any multibyte char
244 set (a safe assumption).
245 ****************************************************************************/
247 NTSTATUS
check_path_syntax_posix(char *path
)
250 return check_path_syntax_internal(path
, True
, &ignore
);
253 /****************************************************************************
254 Pull a string and check the path allowing a wilcard - provide for error return.
255 ****************************************************************************/
257 size_t srvstr_get_path_wcard(TALLOC_CTX
*ctx
,
258 const char *base_ptr
,
265 bool *contains_wcard
)
271 ret
= srvstr_pull_talloc(ctx
, base_ptr
, smb_flags2
, pp_dest
, src
,
275 *err
= NT_STATUS_INVALID_PARAMETER
;
279 *contains_wcard
= False
;
281 if (smb_flags2
& FLAGS2_DFS_PATHNAMES
) {
283 * For a DFS path the function parse_dfs_path()
284 * will do the path processing, just make a copy.
290 if (lp_posix_pathnames()) {
291 *err
= check_path_syntax_posix(*pp_dest
);
293 *err
= check_path_syntax_wcard(*pp_dest
, contains_wcard
);
299 /****************************************************************************
300 Pull a string and check the path - provide for error return.
301 ****************************************************************************/
303 size_t srvstr_get_path(TALLOC_CTX
*ctx
,
304 const char *base_ptr
,
313 return srvstr_get_path_wcard(ctx
, base_ptr
, smb_flags2
, pp_dest
, src
,
314 src_len
, flags
, err
, &ignore
);
317 size_t srvstr_get_path_req_wcard(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
318 char **pp_dest
, const char *src
, int flags
,
319 NTSTATUS
*err
, bool *contains_wcard
)
321 ssize_t bufrem
= smbreq_bufrem(req
, src
);
324 *err
= NT_STATUS_INVALID_PARAMETER
;
328 return srvstr_get_path_wcard(mem_ctx
, (const char *)req
->inbuf
,
329 req
->flags2
, pp_dest
, src
, bufrem
, flags
,
330 err
, contains_wcard
);
333 size_t srvstr_get_path_req(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
334 char **pp_dest
, const char *src
, int flags
,
338 return srvstr_get_path_req_wcard(mem_ctx
, req
, pp_dest
, src
,
339 flags
, err
, &ignore
);
343 * pull a string from the smb_buf part of a packet. In this case the
344 * string can either be null terminated or it can be terminated by the
345 * end of the smbbuf area
347 size_t srvstr_pull_req_talloc(TALLOC_CTX
*ctx
, struct smb_request
*req
,
348 char **dest
, const uint8_t *src
, int flags
)
350 ssize_t bufrem
= smbreq_bufrem(req
, src
);
356 return pull_string_talloc(ctx
, req
->inbuf
, req
->flags2
, dest
, src
,
360 /****************************************************************************
361 Check if we have a correct fsp pointing to a file. Basic check for open fsp.
362 ****************************************************************************/
364 bool check_fsp_open(connection_struct
*conn
, struct smb_request
*req
,
367 if ((fsp
== NULL
) || (conn
== NULL
)) {
368 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
371 if ((conn
!= fsp
->conn
) || (req
->vuid
!= fsp
->vuid
)) {
372 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
378 /****************************************************************************
379 Check if we have a correct fsp pointing to a file.
380 ****************************************************************************/
382 bool check_fsp(connection_struct
*conn
, struct smb_request
*req
,
385 if (!check_fsp_open(conn
, req
, fsp
)) {
388 if (fsp
->is_directory
) {
389 reply_nterror(req
, NT_STATUS_INVALID_DEVICE_REQUEST
);
392 if (fsp
->fh
->fd
== -1) {
393 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
396 fsp
->num_smb_operations
++;
400 /****************************************************************************
401 Check if we have a correct fsp pointing to a quota fake file. Replacement for
402 the CHECK_NTQUOTA_HANDLE_OK macro.
403 ****************************************************************************/
405 bool check_fsp_ntquota_handle(connection_struct
*conn
, struct smb_request
*req
,
408 if (!check_fsp_open(conn
, req
, fsp
)) {
412 if (fsp
->is_directory
) {
416 if (fsp
->fake_file_handle
== NULL
) {
420 if (fsp
->fake_file_handle
->type
!= FAKE_FILE_TYPE_QUOTA
) {
424 if (fsp
->fake_file_handle
->private_data
== NULL
) {
431 static bool netbios_session_retarget(struct smbd_server_connection
*sconn
,
432 const char *name
, int name_type
)
435 char *trim_name_type
;
436 const char *retarget_parm
;
439 int retarget_type
= 0x20;
440 int retarget_port
= NBT_SMB_PORT
;
441 struct sockaddr_storage retarget_addr
;
442 struct sockaddr_in
*in_addr
;
446 if (get_socket_port(sconn
->sock
) != NBT_SMB_PORT
) {
450 trim_name
= talloc_strdup(talloc_tos(), name
);
451 if (trim_name
== NULL
) {
454 trim_char(trim_name
, ' ', ' ');
456 trim_name_type
= talloc_asprintf(trim_name
, "%s#%2.2x", trim_name
,
458 if (trim_name_type
== NULL
) {
462 retarget_parm
= lp_parm_const_string(-1, "netbios retarget",
463 trim_name_type
, NULL
);
464 if (retarget_parm
== NULL
) {
465 retarget_parm
= lp_parm_const_string(-1, "netbios retarget",
468 if (retarget_parm
== NULL
) {
472 retarget
= talloc_strdup(trim_name
, retarget_parm
);
473 if (retarget
== NULL
) {
477 DEBUG(10, ("retargeting %s to %s\n", trim_name_type
, retarget
));
479 p
= strchr(retarget
, ':');
482 retarget_port
= atoi(p
);
485 p
= strchr_m(retarget
, '#');
488 if (sscanf(p
, "%x", &retarget_type
) != 1) {
493 ret
= resolve_name(retarget
, &retarget_addr
, retarget_type
, false);
495 DEBUG(10, ("could not resolve %s\n", retarget
));
499 if (retarget_addr
.ss_family
!= AF_INET
) {
500 DEBUG(10, ("Retarget target not an IPv4 addr\n"));
504 in_addr
= (struct sockaddr_in
*)(void *)&retarget_addr
;
506 _smb_setlen(outbuf
, 6);
507 SCVAL(outbuf
, 0, 0x84);
508 *(uint32_t *)(outbuf
+4) = in_addr
->sin_addr
.s_addr
;
509 *(uint16_t *)(outbuf
+8) = htons(retarget_port
);
511 if (!srv_send_smb(sconn
, (char *)outbuf
, false, 0, false,
513 exit_server_cleanly("netbios_session_retarget: srv_send_smb "
519 TALLOC_FREE(trim_name
);
523 static void reply_called_name_not_present(char *outbuf
)
525 smb_setlen(outbuf
, 1);
526 SCVAL(outbuf
, 0, 0x83);
527 SCVAL(outbuf
, 4, 0x82);
530 /****************************************************************************
531 Reply to a (netbios-level) special message.
532 ****************************************************************************/
534 void reply_special(struct smbd_server_connection
*sconn
, char *inbuf
, size_t inbuf_size
)
536 int msg_type
= CVAL(inbuf
,0);
537 int msg_flags
= CVAL(inbuf
,1);
539 * We only really use 4 bytes of the outbuf, but for the smb_setlen
540 * calculation & friends (srv_send_smb uses that) we need the full smb
543 char outbuf
[smb_size
];
545 memset(outbuf
, '\0', sizeof(outbuf
));
547 smb_setlen(outbuf
,0);
550 case NBSSrequest
: /* session request */
552 /* inbuf_size is guarenteed to be at least 4. */
554 int name_type1
, name_type2
;
555 int name_len1
, name_len2
;
559 if (sconn
->nbt
.got_session
) {
560 exit_server_cleanly("multiple session request not permitted");
563 SCVAL(outbuf
,0,NBSSpositive
);
566 /* inbuf_size is guaranteed to be at least 4. */
567 name_len1
= name_len((unsigned char *)(inbuf
+4),inbuf_size
- 4);
568 if (name_len1
<= 0 || name_len1
> inbuf_size
- 4) {
569 DEBUG(0,("Invalid name length in session request\n"));
570 reply_called_name_not_present(outbuf
);
573 name_len2
= name_len((unsigned char *)(inbuf
+4+name_len1
),inbuf_size
- 4 - name_len1
);
574 if (name_len2
<= 0 || name_len2
> inbuf_size
- 4 - name_len1
) {
575 DEBUG(0,("Invalid name length in session request\n"));
576 reply_called_name_not_present(outbuf
);
580 name_type1
= name_extract((unsigned char *)inbuf
,
581 inbuf_size
,(unsigned int)4,name1
);
582 name_type2
= name_extract((unsigned char *)inbuf
,
583 inbuf_size
,(unsigned int)(4 + name_len1
),name2
);
585 if (name_type1
== -1 || name_type2
== -1) {
586 DEBUG(0,("Invalid name type in session request\n"));
587 reply_called_name_not_present(outbuf
);
591 DEBUG(2,("netbios connect: name1=%s0x%x name2=%s0x%x\n",
592 name1
, name_type1
, name2
, name_type2
));
594 if (netbios_session_retarget(sconn
, name1
, name_type1
)) {
595 exit_server_cleanly("retargeted client");
599 * Windows NT/2k uses "*SMBSERVER" and XP uses
600 * "*SMBSERV" arrggg!!!
602 if (strequal(name1
, "*SMBSERVER ")
603 || strequal(name1
, "*SMBSERV ")) {
606 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
609 exit_server_cleanly("could not allocate raddr");
612 fstrcpy(name1
, raddr
);
615 set_local_machine_name(name1
, True
);
616 set_remote_machine_name(name2
, True
);
618 if (is_ipaddress(sconn
->remote_hostname
)) {
619 char *p
= discard_const_p(char, sconn
->remote_hostname
);
623 sconn
->remote_hostname
= talloc_strdup(sconn
,
624 get_remote_machine_name());
625 if (sconn
->remote_hostname
== NULL
) {
626 exit_server_cleanly("could not copy remote name");
628 sconn
->conn
->remote_hostname
= sconn
->remote_hostname
;
631 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
632 get_local_machine_name(), get_remote_machine_name(),
635 if (name_type2
== 'R') {
636 /* We are being asked for a pathworks session ---
638 reply_called_name_not_present(outbuf
);
642 reload_services(sconn
, conn_snum_used
, true);
645 sconn
->nbt
.got_session
= true;
649 case 0x89: /* session keepalive request
650 (some old clients produce this?) */
651 SCVAL(outbuf
,0,NBSSkeepalive
);
655 case NBSSpositive
: /* positive session response */
656 case NBSSnegative
: /* negative session response */
657 case NBSSretarget
: /* retarget session response */
658 DEBUG(0,("Unexpected session response\n"));
661 case NBSSkeepalive
: /* session keepalive */
666 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
667 msg_type
, msg_flags
));
669 srv_send_smb(sconn
, outbuf
, false, 0, false, NULL
);
671 if (CVAL(outbuf
, 0) != 0x82) {
672 exit_server_cleanly("invalid netbios session");
677 /****************************************************************************
679 conn POINTER CAN BE NULL HERE !
680 ****************************************************************************/
682 void reply_tcon(struct smb_request
*req
)
684 connection_struct
*conn
= req
->conn
;
686 char *service_buf
= NULL
;
687 char *password
= NULL
;
693 TALLOC_CTX
*ctx
= talloc_tos();
694 struct smbd_server_connection
*sconn
= req
->sconn
;
695 NTTIME now
= timeval_to_nttime(&req
->request_time
);
697 START_PROFILE(SMBtcon
);
699 if (req
->buflen
< 4) {
700 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
701 END_PROFILE(SMBtcon
);
706 p
+= srvstr_pull_req_talloc(ctx
, req
, &service_buf
, p
, STR_TERMINATE
);
708 pwlen
= srvstr_pull_req_talloc(ctx
, req
, &password
, p
, STR_TERMINATE
);
710 p
+= srvstr_pull_req_talloc(ctx
, req
, &dev
, p
, STR_TERMINATE
);
713 if (service_buf
== NULL
|| password
== NULL
|| dev
== NULL
) {
714 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
715 END_PROFILE(SMBtcon
);
718 p2
= strrchr_m(service_buf
,'\\');
722 service
= service_buf
;
725 conn
= make_connection(sconn
, now
, service
, dev
,
726 req
->vuid
,&nt_status
);
730 reply_nterror(req
, nt_status
);
731 END_PROFILE(SMBtcon
);
735 reply_outbuf(req
, 2, 0);
736 SSVAL(req
->outbuf
,smb_vwv0
,sconn
->smb1
.negprot
.max_recv
);
737 SSVAL(req
->outbuf
,smb_vwv1
,conn
->cnum
);
738 SSVAL(req
->outbuf
,smb_tid
,conn
->cnum
);
740 DEBUG(3,("tcon service=%s cnum=%d\n",
741 service
, conn
->cnum
));
743 END_PROFILE(SMBtcon
);
747 /****************************************************************************
748 Reply to a tcon and X.
749 conn POINTER CAN BE NULL HERE !
750 ****************************************************************************/
752 void reply_tcon_and_X(struct smb_request
*req
)
754 connection_struct
*conn
= req
->conn
;
755 const char *service
= NULL
;
756 TALLOC_CTX
*ctx
= talloc_tos();
757 /* what the cleint thinks the device is */
758 char *client_devicetype
= NULL
;
759 /* what the server tells the client the share represents */
760 const char *server_devicetype
;
767 struct smbXsrv_session
*session
= NULL
;
768 NTTIME now
= timeval_to_nttime(&req
->request_time
);
769 bool session_key_updated
= false;
770 uint16_t optional_support
= 0;
771 struct smbd_server_connection
*sconn
= req
->sconn
;
773 START_PROFILE(SMBtconX
);
776 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
777 END_PROFILE(SMBtconX
);
781 passlen
= SVAL(req
->vwv
+3, 0);
782 tcon_flags
= SVAL(req
->vwv
+2, 0);
784 /* we might have to close an old one */
785 if ((tcon_flags
& TCONX_FLAG_DISCONNECT_TID
) && conn
) {
786 struct smbXsrv_tcon
*tcon
;
794 * TODO: cancel all outstanding requests on the tcon
796 status
= smbXsrv_tcon_disconnect(tcon
, req
->vuid
);
797 if (!NT_STATUS_IS_OK(status
)) {
798 DEBUG(0, ("reply_tcon_and_X: "
799 "smbXsrv_tcon_disconnect() failed: %s\n",
802 * If we hit this case, there is something completely
803 * wrong, so we better disconnect the transport connection.
805 END_PROFILE(SMBtconX
);
806 exit_server(__location__
": smbXsrv_tcon_disconnect failed");
813 if ((passlen
> MAX_PASS_LEN
) || (passlen
>= req
->buflen
)) {
814 reply_force_doserror(req
, ERRDOS
, ERRbuftoosmall
);
815 END_PROFILE(SMBtconX
);
819 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
820 p
= req
->buf
+ passlen
;
822 p
= req
->buf
+ passlen
+ 1;
825 p
+= srvstr_pull_req_talloc(ctx
, req
, &path
, p
, STR_TERMINATE
);
828 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
829 END_PROFILE(SMBtconX
);
834 * the service name can be either: \\server\share
835 * or share directly like on the DELL PowerVault 705
838 q
= strchr_m(path
+2,'\\');
840 reply_nterror(req
, NT_STATUS_BAD_NETWORK_NAME
);
841 END_PROFILE(SMBtconX
);
849 p
+= srvstr_pull_talloc(ctx
, req
->inbuf
, req
->flags2
,
850 &client_devicetype
, p
,
851 MIN(6, smbreq_bufrem(req
, p
)), STR_ASCII
);
853 if (client_devicetype
== NULL
) {
854 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
855 END_PROFILE(SMBtconX
);
859 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype
, service
));
861 nt_status
= smb1srv_session_lookup(req
->sconn
->conn
,
862 req
->vuid
, now
, &session
);
863 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_USER_SESSION_DELETED
)) {
864 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
865 END_PROFILE(SMBtconX
);
868 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
869 reply_nterror(req
, nt_status
);
870 END_PROFILE(SMBtconX
);
873 if (!NT_STATUS_IS_OK(nt_status
)) {
874 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
875 END_PROFILE(SMBtconX
);
879 if (session
->global
->auth_session_info
== NULL
) {
880 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
881 END_PROFILE(SMBtconX
);
886 * If there is no application key defined yet
889 * This means we setup the application key on the
890 * first tcon that happens via the given session.
892 * Once the application key is defined, it does not
895 if (session
->global
->application_key
.length
== 0 &&
896 session
->global
->signing_key
.length
> 0)
898 struct smbXsrv_session
*x
= session
;
899 struct auth_session_info
*session_info
=
900 session
->global
->auth_session_info
;
901 uint8_t session_key
[16];
903 ZERO_STRUCT(session_key
);
904 memcpy(session_key
, x
->global
->signing_key
.data
,
905 MIN(x
->global
->signing_key
.length
, sizeof(session_key
)));
908 * The application key is truncated/padded to 16 bytes
910 x
->global
->application_key
= data_blob_talloc(x
->global
,
912 sizeof(session_key
));
913 ZERO_STRUCT(session_key
);
914 if (x
->global
->application_key
.data
== NULL
) {
915 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
916 END_PROFILE(SMBtconX
);
920 if (tcon_flags
& TCONX_FLAG_EXTENDED_SIGNATURES
) {
921 smb_key_derivation(x
->global
->application_key
.data
,
922 x
->global
->application_key
.length
,
923 x
->global
->application_key
.data
);
924 optional_support
|= SMB_EXTENDED_SIGNATURES
;
928 * Place the application key into the session_info
930 data_blob_clear_free(&session_info
->session_key
);
931 session_info
->session_key
= data_blob_dup_talloc(session_info
,
932 x
->global
->application_key
);
933 if (session_info
->session_key
.data
== NULL
) {
934 data_blob_clear_free(&x
->global
->application_key
);
935 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
936 END_PROFILE(SMBtconX
);
939 session_key_updated
= true;
942 conn
= make_connection(sconn
, now
, service
, client_devicetype
,
943 req
->vuid
, &nt_status
);
947 if (session_key_updated
) {
948 struct smbXsrv_session
*x
= session
;
949 struct auth_session_info
*session_info
=
950 session
->global
->auth_session_info
;
951 data_blob_clear_free(&x
->global
->application_key
);
952 data_blob_clear_free(&session_info
->session_key
);
954 reply_nterror(req
, nt_status
);
955 END_PROFILE(SMBtconX
);
960 server_devicetype
= "IPC";
961 else if ( IS_PRINT(conn
) )
962 server_devicetype
= "LPT1:";
964 server_devicetype
= "A:";
966 if (get_Protocol() < PROTOCOL_NT1
) {
967 reply_outbuf(req
, 2, 0);
968 if (message_push_string(&req
->outbuf
, server_devicetype
,
969 STR_TERMINATE
|STR_ASCII
) == -1) {
970 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
971 END_PROFILE(SMBtconX
);
975 /* NT sets the fstype of IPC$ to the null string */
976 const char *fstype
= IS_IPC(conn
) ? "" : lp_fstype(SNUM(conn
));
978 if (tcon_flags
& TCONX_FLAG_EXTENDED_RESPONSE
) {
979 /* Return permissions. */
983 reply_outbuf(req
, 7, 0);
986 perm1
= FILE_ALL_ACCESS
;
987 perm2
= FILE_ALL_ACCESS
;
989 perm1
= conn
->share_access
;
992 SIVAL(req
->outbuf
, smb_vwv3
, perm1
);
993 SIVAL(req
->outbuf
, smb_vwv5
, perm2
);
995 reply_outbuf(req
, 3, 0);
998 if ((message_push_string(&req
->outbuf
, server_devicetype
,
999 STR_TERMINATE
|STR_ASCII
) == -1)
1000 || (message_push_string(&req
->outbuf
, fstype
,
1001 STR_TERMINATE
) == -1)) {
1002 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1003 END_PROFILE(SMBtconX
);
1007 /* what does setting this bit do? It is set by NT4 and
1008 may affect the ability to autorun mounted cdroms */
1009 optional_support
|= SMB_SUPPORT_SEARCH_BITS
;
1011 (lp_csc_policy(SNUM(conn
)) << SMB_CSC_POLICY_SHIFT
);
1013 if (lp_msdfs_root(SNUM(conn
)) && lp_host_msdfs()) {
1014 DEBUG(2,("Serving %s as a Dfs root\n",
1015 lp_servicename(ctx
, SNUM(conn
)) ));
1016 optional_support
|= SMB_SHARE_IN_DFS
;
1019 SSVAL(req
->outbuf
, smb_vwv2
, optional_support
);
1022 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
1023 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
1025 DEBUG(3,("tconX service=%s \n",
1028 /* set the incoming and outgoing tid to the just created one */
1029 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_tid
,conn
->cnum
);
1030 SSVAL(req
->outbuf
,smb_tid
,conn
->cnum
);
1032 END_PROFILE(SMBtconX
);
1034 req
->tid
= conn
->cnum
;
1037 /****************************************************************************
1038 Reply to an unknown type.
1039 ****************************************************************************/
1041 void reply_unknown_new(struct smb_request
*req
, uint8 type
)
1043 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
1044 smb_fn_name(type
), type
, type
));
1045 reply_force_doserror(req
, ERRSRV
, ERRunknownsmb
);
1049 /****************************************************************************
1051 conn POINTER CAN BE NULL HERE !
1052 ****************************************************************************/
1054 void reply_ioctl(struct smb_request
*req
)
1056 connection_struct
*conn
= req
->conn
;
1063 START_PROFILE(SMBioctl
);
1066 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1067 END_PROFILE(SMBioctl
);
1071 device
= SVAL(req
->vwv
+1, 0);
1072 function
= SVAL(req
->vwv
+2, 0);
1073 ioctl_code
= (device
<< 16) + function
;
1075 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code
));
1077 switch (ioctl_code
) {
1078 case IOCTL_QUERY_JOB_INFO
:
1082 reply_force_doserror(req
, ERRSRV
, ERRnosupport
);
1083 END_PROFILE(SMBioctl
);
1087 reply_outbuf(req
, 8, replysize
+1);
1088 SSVAL(req
->outbuf
,smb_vwv1
,replysize
); /* Total data bytes returned */
1089 SSVAL(req
->outbuf
,smb_vwv5
,replysize
); /* Data bytes this buffer */
1090 SSVAL(req
->outbuf
,smb_vwv6
,52); /* Offset to data */
1091 p
= smb_buf(req
->outbuf
);
1092 memset(p
, '\0', replysize
+1); /* valgrind-safe. */
1093 p
+= 1; /* Allow for alignment */
1095 switch (ioctl_code
) {
1096 case IOCTL_QUERY_JOB_INFO
:
1098 files_struct
*fsp
= file_fsp(
1099 req
, SVAL(req
->vwv
+0, 0));
1101 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1102 END_PROFILE(SMBioctl
);
1106 SSVAL(p
, 0, print_spool_rap_jobid(fsp
->print_file
));
1108 srvstr_push((char *)req
->outbuf
, req
->flags2
, p
+2,
1109 lp_netbios_name(), 15,
1110 STR_TERMINATE
|STR_ASCII
);
1112 srvstr_push((char *)req
->outbuf
, req
->flags2
,
1114 lp_servicename(talloc_tos(),
1116 13, STR_TERMINATE
|STR_ASCII
);
1118 memset(p
+18, 0, 13);
1124 END_PROFILE(SMBioctl
);
1128 /****************************************************************************
1129 Strange checkpath NTSTATUS mapping.
1130 ****************************************************************************/
1132 static NTSTATUS
map_checkpath_error(uint16_t flags2
, NTSTATUS status
)
1134 /* Strange DOS error code semantics only for checkpath... */
1135 if (!(flags2
& FLAGS2_32_BIT_ERROR_CODES
)) {
1136 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID
,status
)) {
1137 /* We need to map to ERRbadpath */
1138 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1144 /****************************************************************************
1145 Reply to a checkpath.
1146 ****************************************************************************/
1148 void reply_checkpath(struct smb_request
*req
)
1150 connection_struct
*conn
= req
->conn
;
1151 struct smb_filename
*smb_fname
= NULL
;
1154 TALLOC_CTX
*ctx
= talloc_tos();
1156 START_PROFILE(SMBcheckpath
);
1158 srvstr_get_path_req(ctx
, req
, &name
, (const char *)req
->buf
+ 1,
1159 STR_TERMINATE
, &status
);
1161 if (!NT_STATUS_IS_OK(status
)) {
1162 status
= map_checkpath_error(req
->flags2
, status
);
1163 reply_nterror(req
, status
);
1164 END_PROFILE(SMBcheckpath
);
1168 DEBUG(3,("reply_checkpath %s mode=%d\n", name
, (int)SVAL(req
->vwv
+0, 0)));
1170 status
= filename_convert(ctx
,
1172 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1178 if (!NT_STATUS_IS_OK(status
)) {
1179 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1180 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
1181 ERRSRV
, ERRbadpath
);
1182 END_PROFILE(SMBcheckpath
);
1188 if (!VALID_STAT(smb_fname
->st
) &&
1189 (SMB_VFS_STAT(conn
, smb_fname
) != 0)) {
1190 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",
1191 smb_fname_str_dbg(smb_fname
), strerror(errno
)));
1192 status
= map_nt_error_from_unix(errno
);
1196 if (!S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
1197 reply_botherror(req
, NT_STATUS_NOT_A_DIRECTORY
,
1198 ERRDOS
, ERRbadpath
);
1202 reply_outbuf(req
, 0, 0);
1205 /* We special case this - as when a Windows machine
1206 is parsing a path is steps through the components
1207 one at a time - if a component fails it expects
1208 ERRbadpath, not ERRbadfile.
1210 status
= map_checkpath_error(req
->flags2
, status
);
1211 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1213 * Windows returns different error codes if
1214 * the parent directory is valid but not the
1215 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
1216 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
1217 * if the path is invalid.
1219 reply_botherror(req
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
1220 ERRDOS
, ERRbadpath
);
1224 reply_nterror(req
, status
);
1227 TALLOC_FREE(smb_fname
);
1228 END_PROFILE(SMBcheckpath
);
1232 /****************************************************************************
1234 ****************************************************************************/
1236 void reply_getatr(struct smb_request
*req
)
1238 connection_struct
*conn
= req
->conn
;
1239 struct smb_filename
*smb_fname
= NULL
;
1246 TALLOC_CTX
*ctx
= talloc_tos();
1247 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
1249 START_PROFILE(SMBgetatr
);
1251 p
= (const char *)req
->buf
+ 1;
1252 p
+= srvstr_get_path_req(ctx
, req
, &fname
, p
, STR_TERMINATE
, &status
);
1253 if (!NT_STATUS_IS_OK(status
)) {
1254 reply_nterror(req
, status
);
1258 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1259 under WfWg - weird! */
1260 if (*fname
== '\0') {
1261 mode
= FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_DIRECTORY
;
1262 if (!CAN_WRITE(conn
)) {
1263 mode
|= FILE_ATTRIBUTE_READONLY
;
1268 status
= filename_convert(ctx
,
1270 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1275 if (!NT_STATUS_IS_OK(status
)) {
1276 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1277 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
1278 ERRSRV
, ERRbadpath
);
1281 reply_nterror(req
, status
);
1284 if (!VALID_STAT(smb_fname
->st
) &&
1285 (SMB_VFS_STAT(conn
, smb_fname
) != 0)) {
1286 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
1287 smb_fname_str_dbg(smb_fname
),
1289 reply_nterror(req
, map_nt_error_from_unix(errno
));
1293 mode
= dos_mode(conn
, smb_fname
);
1294 size
= smb_fname
->st
.st_ex_size
;
1296 if (ask_sharemode
) {
1297 struct timespec write_time_ts
;
1298 struct file_id fileid
;
1300 ZERO_STRUCT(write_time_ts
);
1301 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
1302 get_file_infos(fileid
, 0, NULL
, &write_time_ts
);
1303 if (!null_timespec(write_time_ts
)) {
1304 update_stat_ex_mtime(&smb_fname
->st
, write_time_ts
);
1308 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1309 if (mode
& FILE_ATTRIBUTE_DIRECTORY
) {
1314 reply_outbuf(req
, 10, 0);
1316 SSVAL(req
->outbuf
,smb_vwv0
,mode
);
1317 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
1318 srv_put_dos_date3((char *)req
->outbuf
,smb_vwv1
,mtime
& ~1);
1320 srv_put_dos_date3((char *)req
->outbuf
,smb_vwv1
,mtime
);
1322 SIVAL(req
->outbuf
,smb_vwv3
,(uint32
)size
);
1324 if (get_Protocol() >= PROTOCOL_NT1
) {
1325 SSVAL(req
->outbuf
, smb_flg2
,
1326 SVAL(req
->outbuf
, smb_flg2
) | FLAGS2_IS_LONG_NAME
);
1329 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n",
1330 smb_fname_str_dbg(smb_fname
), mode
, (unsigned int)size
));
1333 TALLOC_FREE(smb_fname
);
1335 END_PROFILE(SMBgetatr
);
1339 /****************************************************************************
1341 ****************************************************************************/
1343 void reply_setatr(struct smb_request
*req
)
1345 struct smb_file_time ft
;
1346 connection_struct
*conn
= req
->conn
;
1347 struct smb_filename
*smb_fname
= NULL
;
1353 TALLOC_CTX
*ctx
= talloc_tos();
1355 START_PROFILE(SMBsetatr
);
1360 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1364 p
= (const char *)req
->buf
+ 1;
1365 p
+= srvstr_get_path_req(ctx
, req
, &fname
, p
, STR_TERMINATE
, &status
);
1366 if (!NT_STATUS_IS_OK(status
)) {
1367 reply_nterror(req
, status
);
1371 status
= filename_convert(ctx
,
1373 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1378 if (!NT_STATUS_IS_OK(status
)) {
1379 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1380 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
1381 ERRSRV
, ERRbadpath
);
1384 reply_nterror(req
, status
);
1388 if (smb_fname
->base_name
[0] == '.' &&
1389 smb_fname
->base_name
[1] == '\0') {
1391 * Not sure here is the right place to catch this
1392 * condition. Might be moved to somewhere else later -- vl
1394 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1398 mode
= SVAL(req
->vwv
+0, 0);
1399 mtime
= srv_make_unix_date3(req
->vwv
+1);
1401 if (mode
!= FILE_ATTRIBUTE_NORMAL
) {
1402 if (VALID_STAT_OF_DIR(smb_fname
->st
))
1403 mode
|= FILE_ATTRIBUTE_DIRECTORY
;
1405 mode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
1407 status
= check_access(conn
, NULL
, smb_fname
,
1408 FILE_WRITE_ATTRIBUTES
);
1409 if (!NT_STATUS_IS_OK(status
)) {
1410 reply_nterror(req
, status
);
1414 if (file_set_dosmode(conn
, smb_fname
, mode
, NULL
,
1416 reply_nterror(req
, map_nt_error_from_unix(errno
));
1421 ft
.mtime
= convert_time_t_to_timespec(mtime
);
1422 status
= smb_set_file_time(conn
, NULL
, smb_fname
, &ft
, true);
1423 if (!NT_STATUS_IS_OK(status
)) {
1424 reply_nterror(req
, status
);
1428 reply_outbuf(req
, 0, 0);
1430 DEBUG(3, ("setatr name=%s mode=%d\n", smb_fname_str_dbg(smb_fname
),
1433 TALLOC_FREE(smb_fname
);
1434 END_PROFILE(SMBsetatr
);
1438 /****************************************************************************
1440 ****************************************************************************/
1442 void reply_dskattr(struct smb_request
*req
)
1444 connection_struct
*conn
= req
->conn
;
1445 uint64_t dfree
,dsize
,bsize
;
1446 START_PROFILE(SMBdskattr
);
1448 if (get_dfree_info(conn
,".",True
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
1449 reply_nterror(req
, map_nt_error_from_unix(errno
));
1450 END_PROFILE(SMBdskattr
);
1454 reply_outbuf(req
, 5, 0);
1456 if (get_Protocol() <= PROTOCOL_LANMAN2
) {
1457 double total_space
, free_space
;
1458 /* we need to scale this to a number that DOS6 can handle. We
1459 use floating point so we can handle large drives on systems
1460 that don't have 64 bit integers
1462 we end up displaying a maximum of 2G to DOS systems
1464 total_space
= dsize
* (double)bsize
;
1465 free_space
= dfree
* (double)bsize
;
1467 dsize
= (uint64_t)((total_space
+63*512) / (64*512));
1468 dfree
= (uint64_t)((free_space
+63*512) / (64*512));
1470 if (dsize
> 0xFFFF) dsize
= 0xFFFF;
1471 if (dfree
> 0xFFFF) dfree
= 0xFFFF;
1473 SSVAL(req
->outbuf
,smb_vwv0
,dsize
);
1474 SSVAL(req
->outbuf
,smb_vwv1
,64); /* this must be 64 for dos systems */
1475 SSVAL(req
->outbuf
,smb_vwv2
,512); /* and this must be 512 */
1476 SSVAL(req
->outbuf
,smb_vwv3
,dfree
);
1478 SSVAL(req
->outbuf
,smb_vwv0
,dsize
);
1479 SSVAL(req
->outbuf
,smb_vwv1
,bsize
/512);
1480 SSVAL(req
->outbuf
,smb_vwv2
,512);
1481 SSVAL(req
->outbuf
,smb_vwv3
,dfree
);
1484 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree
));
1486 END_PROFILE(SMBdskattr
);
1491 * Utility function to split the filename from the directory.
1493 static NTSTATUS
split_fname_dir_mask(TALLOC_CTX
*ctx
, const char *fname_in
,
1494 char **fname_dir_out
,
1495 char **fname_mask_out
)
1497 const char *p
= NULL
;
1498 char *fname_dir
= NULL
;
1499 char *fname_mask
= NULL
;
1501 p
= strrchr_m(fname_in
, '/');
1503 fname_dir
= talloc_strdup(ctx
, ".");
1504 fname_mask
= talloc_strdup(ctx
, fname_in
);
1506 fname_dir
= talloc_strndup(ctx
, fname_in
,
1507 PTR_DIFF(p
, fname_in
));
1508 fname_mask
= talloc_strdup(ctx
, p
+1);
1511 if (!fname_dir
|| !fname_mask
) {
1512 TALLOC_FREE(fname_dir
);
1513 TALLOC_FREE(fname_mask
);
1514 return NT_STATUS_NO_MEMORY
;
1517 *fname_dir_out
= fname_dir
;
1518 *fname_mask_out
= fname_mask
;
1519 return NT_STATUS_OK
;
1522 /****************************************************************************
1524 Can be called from SMBsearch, SMBffirst or SMBfunique.
1525 ****************************************************************************/
1527 void reply_search(struct smb_request
*req
)
1529 connection_struct
*conn
= req
->conn
;
1531 const char *mask
= NULL
;
1532 char *directory
= NULL
;
1533 struct smb_filename
*smb_fname
= NULL
;
1537 struct timespec date
;
1539 unsigned int numentries
= 0;
1540 unsigned int maxentries
= 0;
1541 bool finished
= False
;
1546 bool check_descend
= False
;
1547 bool expect_close
= False
;
1549 bool mask_contains_wcard
= False
;
1550 bool allow_long_path_components
= (req
->flags2
& FLAGS2_LONG_PATH_COMPONENTS
) ? True
: False
;
1551 TALLOC_CTX
*ctx
= talloc_tos();
1552 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
1553 struct dptr_struct
*dirptr
= NULL
;
1554 struct smbd_server_connection
*sconn
= req
->sconn
;
1556 START_PROFILE(SMBsearch
);
1559 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1563 if (lp_posix_pathnames()) {
1564 reply_unknown_new(req
, req
->cmd
);
1568 /* If we were called as SMBffirst then we must expect close. */
1569 if(req
->cmd
== SMBffirst
) {
1570 expect_close
= True
;
1573 reply_outbuf(req
, 1, 3);
1574 maxentries
= SVAL(req
->vwv
+0, 0);
1575 dirtype
= SVAL(req
->vwv
+1, 0);
1576 p
= (const char *)req
->buf
+ 1;
1577 p
+= srvstr_get_path_req_wcard(ctx
, req
, &path
, p
, STR_TERMINATE
,
1578 &nt_status
, &mask_contains_wcard
);
1579 if (!NT_STATUS_IS_OK(nt_status
)) {
1580 reply_nterror(req
, nt_status
);
1585 status_len
= SVAL(p
, 0);
1588 /* dirtype &= ~FILE_ATTRIBUTE_DIRECTORY; */
1590 if (status_len
== 0) {
1591 nt_status
= filename_convert(ctx
, conn
,
1592 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1594 UCF_ALWAYS_ALLOW_WCARD_LCOMP
,
1595 &mask_contains_wcard
,
1597 if (!NT_STATUS_IS_OK(nt_status
)) {
1598 if (NT_STATUS_EQUAL(nt_status
,NT_STATUS_PATH_NOT_COVERED
)) {
1599 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
1600 ERRSRV
, ERRbadpath
);
1603 reply_nterror(req
, nt_status
);
1607 directory
= smb_fname
->base_name
;
1609 p
= strrchr_m(directory
,'/');
1610 if ((p
!= NULL
) && (*directory
!= '/')) {
1612 directory
= talloc_strndup(ctx
, directory
,
1613 PTR_DIFF(p
, directory
));
1616 directory
= talloc_strdup(ctx
,".");
1620 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1624 memset((char *)status
,'\0',21);
1625 SCVAL(status
,0,(dirtype
& 0x1F));
1627 nt_status
= dptr_create(conn
,
1635 mask_contains_wcard
,
1638 if (!NT_STATUS_IS_OK(nt_status
)) {
1639 reply_nterror(req
, nt_status
);
1642 dptr_num
= dptr_dnum(dirptr
);
1645 const char *dirpath
;
1647 memcpy(status
,p
,21);
1648 status_dirtype
= CVAL(status
,0) & 0x1F;
1649 if (status_dirtype
!= (dirtype
& 0x1F)) {
1650 dirtype
= status_dirtype
;
1653 dirptr
= dptr_fetch(sconn
, status
+12,&dptr_num
);
1657 dirpath
= dptr_path(sconn
, dptr_num
);
1658 directory
= talloc_strdup(ctx
, dirpath
);
1660 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1664 mask
= dptr_wcard(sconn
, dptr_num
);
1669 * For a 'continue' search we have no string. So
1670 * check from the initial saved string.
1672 mask_contains_wcard
= ms_has_wild(mask
);
1673 dirtype
= dptr_attr(sconn
, dptr_num
);
1676 DEBUG(4,("dptr_num is %d\n",dptr_num
));
1678 /* Initialize per SMBsearch/SMBffirst/SMBfunique operation data */
1679 dptr_init_search_op(dirptr
);
1681 if ((dirtype
&0x1F) == FILE_ATTRIBUTE_VOLUME
) {
1682 char buf
[DIR_STRUCT_SIZE
];
1683 memcpy(buf
,status
,21);
1684 if (!make_dir_struct(ctx
,buf
,"???????????",volume_label(ctx
, SNUM(conn
)),
1685 0,FILE_ATTRIBUTE_VOLUME
,0,!allow_long_path_components
)) {
1686 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1689 dptr_fill(sconn
, buf
+12,dptr_num
);
1690 if (dptr_zero(buf
+12) && (status_len
==0)) {
1695 if (message_push_blob(&req
->outbuf
,
1696 data_blob_const(buf
, sizeof(buf
)))
1698 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1703 size_t hdr_size
= ((uint8_t *)smb_buf(req
->outbuf
) + 3 - req
->outbuf
);
1704 size_t available_space
= sconn
->smb1
.sessions
.max_send
- hdr_size
;
1706 maxentries
= MIN(maxentries
, available_space
/DIR_STRUCT_SIZE
);
1708 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1709 directory
,lp_dont_descend(ctx
, SNUM(conn
))));
1710 if (in_list(directory
, lp_dont_descend(ctx
, SNUM(conn
)),True
)) {
1711 check_descend
= True
;
1714 for (i
=numentries
;(i
<maxentries
) && !finished
;i
++) {
1715 finished
= !get_dir_entry(ctx
,
1726 char buf
[DIR_STRUCT_SIZE
];
1727 memcpy(buf
,status
,21);
1728 if (!make_dir_struct(ctx
,
1734 convert_timespec_to_time_t(date
),
1735 !allow_long_path_components
)) {
1736 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1739 if (!dptr_fill(sconn
, buf
+12,dptr_num
)) {
1742 if (message_push_blob(&req
->outbuf
,
1743 data_blob_const(buf
, sizeof(buf
)))
1745 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1755 /* If we were called as SMBffirst with smb_search_id == NULL
1756 and no entries were found then return error and close dirptr
1759 if (numentries
== 0) {
1760 dptr_close(sconn
, &dptr_num
);
1761 } else if(expect_close
&& status_len
== 0) {
1762 /* Close the dptr - we know it's gone */
1763 dptr_close(sconn
, &dptr_num
);
1766 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1767 if(dptr_num
>= 0 && req
->cmd
== SMBfunique
) {
1768 dptr_close(sconn
, &dptr_num
);
1771 if ((numentries
== 0) && !mask_contains_wcard
) {
1772 reply_botherror(req
, STATUS_NO_MORE_FILES
, ERRDOS
, ERRnofiles
);
1776 SSVAL(req
->outbuf
,smb_vwv0
,numentries
);
1777 SSVAL(req
->outbuf
,smb_vwv1
,3 + numentries
* DIR_STRUCT_SIZE
);
1778 SCVAL(smb_buf(req
->outbuf
),0,5);
1779 SSVAL(smb_buf(req
->outbuf
),1,numentries
*DIR_STRUCT_SIZE
);
1781 /* The replies here are never long name. */
1782 SSVAL(req
->outbuf
, smb_flg2
,
1783 SVAL(req
->outbuf
, smb_flg2
) & (~FLAGS2_IS_LONG_NAME
));
1784 if (!allow_long_path_components
) {
1785 SSVAL(req
->outbuf
, smb_flg2
,
1786 SVAL(req
->outbuf
, smb_flg2
)
1787 & (~FLAGS2_LONG_PATH_COMPONENTS
));
1790 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1791 SSVAL(req
->outbuf
, smb_flg2
,
1792 (SVAL(req
->outbuf
, smb_flg2
) & (~FLAGS2_UNICODE_STRINGS
)));
1794 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1795 smb_fn_name(req
->cmd
),
1802 TALLOC_FREE(directory
);
1803 TALLOC_FREE(smb_fname
);
1804 END_PROFILE(SMBsearch
);
1808 /****************************************************************************
1809 Reply to a fclose (stop directory search).
1810 ****************************************************************************/
1812 void reply_fclose(struct smb_request
*req
)
1820 bool path_contains_wcard
= False
;
1821 TALLOC_CTX
*ctx
= talloc_tos();
1822 struct smbd_server_connection
*sconn
= req
->sconn
;
1824 START_PROFILE(SMBfclose
);
1826 if (lp_posix_pathnames()) {
1827 reply_unknown_new(req
, req
->cmd
);
1828 END_PROFILE(SMBfclose
);
1832 p
= (const char *)req
->buf
+ 1;
1833 p
+= srvstr_get_path_req_wcard(ctx
, req
, &path
, p
, STR_TERMINATE
,
1834 &err
, &path_contains_wcard
);
1835 if (!NT_STATUS_IS_OK(err
)) {
1836 reply_nterror(req
, err
);
1837 END_PROFILE(SMBfclose
);
1841 status_len
= SVAL(p
,0);
1844 if (status_len
== 0) {
1845 reply_force_doserror(req
, ERRSRV
, ERRsrverror
);
1846 END_PROFILE(SMBfclose
);
1850 memcpy(status
,p
,21);
1852 if(dptr_fetch(sconn
, status
+12,&dptr_num
)) {
1853 /* Close the dptr - we know it's gone */
1854 dptr_close(sconn
, &dptr_num
);
1857 reply_outbuf(req
, 1, 0);
1858 SSVAL(req
->outbuf
,smb_vwv0
,0);
1860 DEBUG(3,("search close\n"));
1862 END_PROFILE(SMBfclose
);
1866 /****************************************************************************
1868 ****************************************************************************/
1870 void reply_open(struct smb_request
*req
)
1872 connection_struct
*conn
= req
->conn
;
1873 struct smb_filename
*smb_fname
= NULL
;
1885 uint32 create_disposition
;
1886 uint32 create_options
= 0;
1887 uint32_t private_flags
= 0;
1889 TALLOC_CTX
*ctx
= talloc_tos();
1891 START_PROFILE(SMBopen
);
1894 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1898 oplock_request
= CORE_OPLOCK_REQUEST(req
->inbuf
);
1899 deny_mode
= SVAL(req
->vwv
+0, 0);
1900 dos_attr
= SVAL(req
->vwv
+1, 0);
1902 srvstr_get_path_req(ctx
, req
, &fname
, (const char *)req
->buf
+1,
1903 STR_TERMINATE
, &status
);
1904 if (!NT_STATUS_IS_OK(status
)) {
1905 reply_nterror(req
, status
);
1909 if (!map_open_params_to_ntcreate(fname
, deny_mode
,
1910 OPENX_FILE_EXISTS_OPEN
, &access_mask
,
1911 &share_mode
, &create_disposition
,
1912 &create_options
, &private_flags
)) {
1913 reply_force_doserror(req
, ERRDOS
, ERRbadaccess
);
1917 status
= filename_convert(ctx
,
1919 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1921 UCF_PREP_CREATEFILE
,
1924 if (!NT_STATUS_IS_OK(status
)) {
1925 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1926 reply_botherror(req
,
1927 NT_STATUS_PATH_NOT_COVERED
,
1928 ERRSRV
, ERRbadpath
);
1931 reply_nterror(req
, status
);
1935 status
= SMB_VFS_CREATE_FILE(
1938 0, /* root_dir_fid */
1939 smb_fname
, /* fname */
1940 access_mask
, /* access_mask */
1941 share_mode
, /* share_access */
1942 create_disposition
, /* create_disposition*/
1943 create_options
, /* create_options */
1944 dos_attr
, /* file_attributes */
1945 oplock_request
, /* oplock_request */
1946 0, /* allocation_size */
1953 if (!NT_STATUS_IS_OK(status
)) {
1954 if (open_was_deferred(req
->sconn
, req
->mid
)) {
1955 /* We have re-scheduled this call. */
1958 reply_openerror(req
, status
);
1962 /* Ensure we're pointing at the correct stat struct. */
1963 TALLOC_FREE(smb_fname
);
1964 smb_fname
= fsp
->fsp_name
;
1966 size
= smb_fname
->st
.st_ex_size
;
1967 fattr
= dos_mode(conn
, smb_fname
);
1969 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1971 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1972 DEBUG(3,("attempt to open a directory %s\n",
1974 close_file(req
, fsp
, ERROR_CLOSE
);
1975 reply_botherror(req
, NT_STATUS_ACCESS_DENIED
,
1976 ERRDOS
, ERRnoaccess
);
1980 reply_outbuf(req
, 7, 0);
1981 SSVAL(req
->outbuf
,smb_vwv0
,fsp
->fnum
);
1982 SSVAL(req
->outbuf
,smb_vwv1
,fattr
);
1983 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
1984 srv_put_dos_date3((char *)req
->outbuf
,smb_vwv2
,mtime
& ~1);
1986 srv_put_dos_date3((char *)req
->outbuf
,smb_vwv2
,mtime
);
1988 SIVAL(req
->outbuf
,smb_vwv4
,(uint32
)size
);
1989 SSVAL(req
->outbuf
,smb_vwv6
,deny_mode
);
1991 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1992 SCVAL(req
->outbuf
,smb_flg
,
1993 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
1996 if(EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1997 SCVAL(req
->outbuf
,smb_flg
,
1998 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2001 END_PROFILE(SMBopen
);
2005 /****************************************************************************
2006 Reply to an open and X.
2007 ****************************************************************************/
2009 void reply_open_and_X(struct smb_request
*req
)
2011 connection_struct
*conn
= req
->conn
;
2012 struct smb_filename
*smb_fname
= NULL
;
2017 /* Breakout the oplock request bits so we can set the
2018 reply bits separately. */
2019 int ex_oplock_request
;
2020 int core_oplock_request
;
2023 int smb_sattr
= SVAL(req
->vwv
+4, 0);
2024 uint32 smb_time
= make_unix_date3(req
->vwv
+6);
2032 uint64_t allocation_size
;
2033 ssize_t retval
= -1;
2036 uint32 create_disposition
;
2037 uint32 create_options
= 0;
2038 uint32_t private_flags
= 0;
2039 TALLOC_CTX
*ctx
= talloc_tos();
2041 START_PROFILE(SMBopenX
);
2043 if (req
->wct
< 15) {
2044 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2048 open_flags
= SVAL(req
->vwv
+2, 0);
2049 deny_mode
= SVAL(req
->vwv
+3, 0);
2050 smb_attr
= SVAL(req
->vwv
+5, 0);
2051 ex_oplock_request
= EXTENDED_OPLOCK_REQUEST(req
->inbuf
);
2052 core_oplock_request
= CORE_OPLOCK_REQUEST(req
->inbuf
);
2053 oplock_request
= ex_oplock_request
| core_oplock_request
;
2054 smb_ofun
= SVAL(req
->vwv
+8, 0);
2055 allocation_size
= (uint64_t)IVAL(req
->vwv
+9, 0);
2057 /* If it's an IPC, pass off the pipe handler. */
2059 if (lp_nt_pipe_support()) {
2060 reply_open_pipe_and_X(conn
, req
);
2062 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
2067 /* XXXX we need to handle passed times, sattr and flags */
2068 srvstr_get_path_req(ctx
, req
, &fname
, (const char *)req
->buf
,
2069 STR_TERMINATE
, &status
);
2070 if (!NT_STATUS_IS_OK(status
)) {
2071 reply_nterror(req
, status
);
2075 if (!map_open_params_to_ntcreate(fname
, deny_mode
,
2077 &access_mask
, &share_mode
,
2078 &create_disposition
,
2081 reply_force_doserror(req
, ERRDOS
, ERRbadaccess
);
2085 status
= filename_convert(ctx
,
2087 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2089 UCF_PREP_CREATEFILE
,
2092 if (!NT_STATUS_IS_OK(status
)) {
2093 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
2094 reply_botherror(req
,
2095 NT_STATUS_PATH_NOT_COVERED
,
2096 ERRSRV
, ERRbadpath
);
2099 reply_nterror(req
, status
);
2103 status
= SMB_VFS_CREATE_FILE(
2106 0, /* root_dir_fid */
2107 smb_fname
, /* fname */
2108 access_mask
, /* access_mask */
2109 share_mode
, /* share_access */
2110 create_disposition
, /* create_disposition*/
2111 create_options
, /* create_options */
2112 smb_attr
, /* file_attributes */
2113 oplock_request
, /* oplock_request */
2114 0, /* allocation_size */
2119 &smb_action
); /* pinfo */
2121 if (!NT_STATUS_IS_OK(status
)) {
2122 if (open_was_deferred(req
->sconn
, req
->mid
)) {
2123 /* We have re-scheduled this call. */
2126 reply_openerror(req
, status
);
2130 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
2131 if the file is truncated or created. */
2132 if (((smb_action
== FILE_WAS_CREATED
) || (smb_action
== FILE_WAS_OVERWRITTEN
)) && allocation_size
) {
2133 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
, allocation_size
);
2134 if (vfs_allocate_file_space(fsp
, fsp
->initial_allocation_size
) == -1) {
2135 close_file(req
, fsp
, ERROR_CLOSE
);
2136 reply_nterror(req
, NT_STATUS_DISK_FULL
);
2139 retval
= vfs_set_filelen(fsp
, (off_t
)allocation_size
);
2141 close_file(req
, fsp
, ERROR_CLOSE
);
2142 reply_nterror(req
, NT_STATUS_DISK_FULL
);
2145 status
= vfs_stat_fsp(fsp
);
2146 if (!NT_STATUS_IS_OK(status
)) {
2147 close_file(req
, fsp
, ERROR_CLOSE
);
2148 reply_nterror(req
, status
);
2153 fattr
= dos_mode(conn
, fsp
->fsp_name
);
2154 mtime
= convert_timespec_to_time_t(fsp
->fsp_name
->st
.st_ex_mtime
);
2155 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
2156 close_file(req
, fsp
, ERROR_CLOSE
);
2157 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2161 /* If the caller set the extended oplock request bit
2162 and we granted one (by whatever means) - set the
2163 correct bit for extended oplock reply.
2166 if (ex_oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
2167 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
2170 if(ex_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
2171 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
2174 /* If the caller set the core oplock request bit
2175 and we granted one (by whatever means) - set the
2176 correct bit for core oplock reply.
2179 if (open_flags
& EXTENDED_RESPONSE_REQUIRED
) {
2180 reply_outbuf(req
, 19, 0);
2182 reply_outbuf(req
, 15, 0);
2185 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
2186 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
2188 if (core_oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
2189 SCVAL(req
->outbuf
, smb_flg
,
2190 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2193 if(core_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
2194 SCVAL(req
->outbuf
, smb_flg
,
2195 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2198 SSVAL(req
->outbuf
,smb_vwv2
,fsp
->fnum
);
2199 SSVAL(req
->outbuf
,smb_vwv3
,fattr
);
2200 if(lp_dos_filetime_resolution(SNUM(conn
)) ) {
2201 srv_put_dos_date3((char *)req
->outbuf
,smb_vwv4
,mtime
& ~1);
2203 srv_put_dos_date3((char *)req
->outbuf
,smb_vwv4
,mtime
);
2205 SIVAL(req
->outbuf
,smb_vwv6
,(uint32
)fsp
->fsp_name
->st
.st_ex_size
);
2206 SSVAL(req
->outbuf
,smb_vwv8
,GET_OPENX_MODE(deny_mode
));
2207 SSVAL(req
->outbuf
,smb_vwv11
,smb_action
);
2209 if (open_flags
& EXTENDED_RESPONSE_REQUIRED
) {
2210 SIVAL(req
->outbuf
, smb_vwv15
, SEC_STD_ALL
);
2214 TALLOC_FREE(smb_fname
);
2215 END_PROFILE(SMBopenX
);
2219 /****************************************************************************
2220 Reply to a SMBulogoffX.
2221 ****************************************************************************/
2223 void reply_ulogoffX(struct smb_request
*req
)
2225 struct smbd_server_connection
*sconn
= req
->sconn
;
2226 struct user_struct
*vuser
;
2227 struct smbXsrv_session
*session
= NULL
;
2230 START_PROFILE(SMBulogoffX
);
2232 vuser
= get_valid_user_struct(sconn
, req
->vuid
);
2235 DEBUG(3,("ulogoff, vuser id %llu does not map to user.\n",
2236 (unsigned long long)req
->vuid
));
2238 req
->vuid
= UID_FIELD_INVALID
;
2239 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
2240 END_PROFILE(SMBulogoffX
);
2244 session
= vuser
->session
;
2248 * TODO: cancel all outstanding requests on the session
2250 status
= smbXsrv_session_logoff(session
);
2251 if (!NT_STATUS_IS_OK(status
)) {
2252 DEBUG(0, ("reply_ulogoff: "
2253 "smbXsrv_session_logoff() failed: %s\n",
2254 nt_errstr(status
)));
2256 * If we hit this case, there is something completely
2257 * wrong, so we better disconnect the transport connection.
2259 END_PROFILE(SMBulogoffX
);
2260 exit_server(__location__
": smbXsrv_session_logoff failed");
2264 TALLOC_FREE(session
);
2266 reply_outbuf(req
, 2, 0);
2267 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
2268 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
2270 DEBUG(3, ("ulogoffX vuid=%llu\n",
2271 (unsigned long long)req
->vuid
));
2273 END_PROFILE(SMBulogoffX
);
2274 req
->vuid
= UID_FIELD_INVALID
;
2277 /****************************************************************************
2278 Reply to a mknew or a create.
2279 ****************************************************************************/
2281 void reply_mknew(struct smb_request
*req
)
2283 connection_struct
*conn
= req
->conn
;
2284 struct smb_filename
*smb_fname
= NULL
;
2287 struct smb_file_time ft
;
2289 int oplock_request
= 0;
2291 uint32 access_mask
= FILE_GENERIC_READ
| FILE_GENERIC_WRITE
;
2292 uint32 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
2293 uint32 create_disposition
;
2294 uint32 create_options
= 0;
2295 TALLOC_CTX
*ctx
= talloc_tos();
2297 START_PROFILE(SMBcreate
);
2301 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2305 fattr
= SVAL(req
->vwv
+0, 0);
2306 oplock_request
= CORE_OPLOCK_REQUEST(req
->inbuf
);
2309 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date3(req
->vwv
+1));
2311 srvstr_get_path_req(ctx
, req
, &fname
, (const char *)req
->buf
+ 1,
2312 STR_TERMINATE
, &status
);
2313 if (!NT_STATUS_IS_OK(status
)) {
2314 reply_nterror(req
, status
);
2318 status
= filename_convert(ctx
,
2320 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2322 UCF_PREP_CREATEFILE
,
2325 if (!NT_STATUS_IS_OK(status
)) {
2326 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
2327 reply_botherror(req
,
2328 NT_STATUS_PATH_NOT_COVERED
,
2329 ERRSRV
, ERRbadpath
);
2332 reply_nterror(req
, status
);
2336 if (fattr
& FILE_ATTRIBUTE_VOLUME
) {
2337 DEBUG(0,("Attempt to create file (%s) with volid set - "
2338 "please report this\n",
2339 smb_fname_str_dbg(smb_fname
)));
2342 if(req
->cmd
== SMBmknew
) {
2343 /* We should fail if file exists. */
2344 create_disposition
= FILE_CREATE
;
2346 /* Create if file doesn't exist, truncate if it does. */
2347 create_disposition
= FILE_OVERWRITE_IF
;
2350 status
= SMB_VFS_CREATE_FILE(
2353 0, /* root_dir_fid */
2354 smb_fname
, /* fname */
2355 access_mask
, /* access_mask */
2356 share_mode
, /* share_access */
2357 create_disposition
, /* create_disposition*/
2358 create_options
, /* create_options */
2359 fattr
, /* file_attributes */
2360 oplock_request
, /* oplock_request */
2361 0, /* allocation_size */
2362 0, /* private_flags */
2368 if (!NT_STATUS_IS_OK(status
)) {
2369 if (open_was_deferred(req
->sconn
, req
->mid
)) {
2370 /* We have re-scheduled this call. */
2373 reply_openerror(req
, status
);
2377 ft
.atime
= smb_fname
->st
.st_ex_atime
; /* atime. */
2378 status
= smb_set_file_time(conn
, fsp
, smb_fname
, &ft
, true);
2379 if (!NT_STATUS_IS_OK(status
)) {
2380 END_PROFILE(SMBcreate
);
2384 reply_outbuf(req
, 1, 0);
2385 SSVAL(req
->outbuf
,smb_vwv0
,fsp
->fnum
);
2387 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
2388 SCVAL(req
->outbuf
,smb_flg
,
2389 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2392 if(EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
2393 SCVAL(req
->outbuf
,smb_flg
,
2394 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2397 DEBUG(2, ("reply_mknew: file %s\n", smb_fname_str_dbg(smb_fname
)));
2398 DEBUG(3, ("reply_mknew %s fd=%d dmode=0x%x\n",
2399 smb_fname_str_dbg(smb_fname
), fsp
->fh
->fd
,
2400 (unsigned int)fattr
));
2403 TALLOC_FREE(smb_fname
);
2404 END_PROFILE(SMBcreate
);
2408 /****************************************************************************
2409 Reply to a create temporary file.
2410 ****************************************************************************/
2412 void reply_ctemp(struct smb_request
*req
)
2414 connection_struct
*conn
= req
->conn
;
2415 struct smb_filename
*smb_fname
= NULL
;
2416 char *wire_name
= NULL
;
2424 TALLOC_CTX
*ctx
= talloc_tos();
2426 START_PROFILE(SMBctemp
);
2429 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2433 fattr
= SVAL(req
->vwv
+0, 0);
2434 oplock_request
= CORE_OPLOCK_REQUEST(req
->inbuf
);
2436 srvstr_get_path_req(ctx
, req
, &wire_name
, (const char *)req
->buf
+1,
2437 STR_TERMINATE
, &status
);
2438 if (!NT_STATUS_IS_OK(status
)) {
2439 reply_nterror(req
, status
);
2443 for (i
= 0; i
< 10; i
++) {
2445 fname
= talloc_asprintf(ctx
,
2448 generate_random_str_list(ctx
, 5, "0123456789"));
2450 fname
= talloc_asprintf(ctx
,
2452 generate_random_str_list(ctx
, 5, "0123456789"));
2456 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2460 status
= filename_convert(ctx
, conn
,
2461 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2463 UCF_PREP_CREATEFILE
,
2466 if (!NT_STATUS_IS_OK(status
)) {
2467 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
2468 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2469 ERRSRV
, ERRbadpath
);
2472 reply_nterror(req
, status
);
2476 /* Create the file. */
2477 status
= SMB_VFS_CREATE_FILE(
2480 0, /* root_dir_fid */
2481 smb_fname
, /* fname */
2482 FILE_GENERIC_READ
| FILE_GENERIC_WRITE
, /* access_mask */
2483 FILE_SHARE_READ
| FILE_SHARE_WRITE
, /* share_access */
2484 FILE_CREATE
, /* create_disposition*/
2485 0, /* create_options */
2486 fattr
, /* file_attributes */
2487 oplock_request
, /* oplock_request */
2488 0, /* allocation_size */
2489 0, /* private_flags */
2495 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
2497 TALLOC_FREE(smb_fname
);
2501 if (!NT_STATUS_IS_OK(status
)) {
2502 if (open_was_deferred(req
->sconn
, req
->mid
)) {
2503 /* We have re-scheduled this call. */
2506 reply_openerror(req
, status
);
2514 /* Collision after 10 times... */
2515 reply_nterror(req
, status
);
2519 reply_outbuf(req
, 1, 0);
2520 SSVAL(req
->outbuf
,smb_vwv0
,fsp
->fnum
);
2522 /* the returned filename is relative to the directory */
2523 s
= strrchr_m(fsp
->fsp_name
->base_name
, '/');
2525 s
= fsp
->fsp_name
->base_name
;
2531 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2532 thing in the byte section. JRA */
2533 SSVALS(p
, 0, -1); /* what is this? not in spec */
2535 if (message_push_string(&req
->outbuf
, s
, STR_ASCII
|STR_TERMINATE
)
2537 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2541 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
2542 SCVAL(req
->outbuf
, smb_flg
,
2543 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2546 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
2547 SCVAL(req
->outbuf
, smb_flg
,
2548 CVAL(req
->outbuf
,smb_flg
)|CORE_OPLOCK_GRANTED
);
2551 DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp
)));
2552 DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp
),
2553 fsp
->fh
->fd
, (unsigned int)smb_fname
->st
.st_ex_mode
));
2555 TALLOC_FREE(smb_fname
);
2556 TALLOC_FREE(wire_name
);
2557 END_PROFILE(SMBctemp
);
2561 /*******************************************************************
2562 Check if a user is allowed to rename a file.
2563 ********************************************************************/
2565 static NTSTATUS
can_rename(connection_struct
*conn
, files_struct
*fsp
,
2568 if (!CAN_WRITE(conn
)) {
2569 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
2572 if ((dirtype
& (FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_SYSTEM
)) !=
2573 (FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_SYSTEM
)) {
2574 /* Only bother to read the DOS attribute if we might deny the
2575 rename on the grounds of attribute missmatch. */
2576 uint32_t fmode
= dos_mode(conn
, fsp
->fsp_name
);
2577 if ((fmode
& ~dirtype
) & (FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_SYSTEM
)) {
2578 return NT_STATUS_NO_SUCH_FILE
;
2582 if (S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
2583 if (fsp
->posix_open
) {
2584 return NT_STATUS_OK
;
2587 /* If no pathnames are open below this
2588 directory, allow the rename. */
2590 if (file_find_subpath(fsp
)) {
2591 return NT_STATUS_ACCESS_DENIED
;
2593 return NT_STATUS_OK
;
2596 if (fsp
->access_mask
& (DELETE_ACCESS
|FILE_WRITE_ATTRIBUTES
)) {
2597 return NT_STATUS_OK
;
2600 return NT_STATUS_ACCESS_DENIED
;
2603 /*******************************************************************
2604 * unlink a file with all relevant access checks
2605 *******************************************************************/
2607 static NTSTATUS
do_unlink(connection_struct
*conn
,
2608 struct smb_request
*req
,
2609 struct smb_filename
*smb_fname
,
2614 uint32 dirtype_orig
= dirtype
;
2617 bool posix_paths
= lp_posix_pathnames();
2619 DEBUG(10,("do_unlink: %s, dirtype = %d\n",
2620 smb_fname_str_dbg(smb_fname
),
2623 if (!CAN_WRITE(conn
)) {
2624 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
2628 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
2630 ret
= SMB_VFS_STAT(conn
, smb_fname
);
2633 return map_nt_error_from_unix(errno
);
2636 fattr
= dos_mode(conn
, smb_fname
);
2638 if (dirtype
& FILE_ATTRIBUTE_NORMAL
) {
2639 dirtype
= FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
;
2642 dirtype
&= (FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
);
2644 return NT_STATUS_NO_SUCH_FILE
;
2647 if (!dir_check_ftype(fattr
, dirtype
)) {
2648 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
2649 return NT_STATUS_FILE_IS_A_DIRECTORY
;
2651 return NT_STATUS_NO_SUCH_FILE
;
2654 if (dirtype_orig
& 0x8000) {
2655 /* These will never be set for POSIX. */
2656 return NT_STATUS_NO_SUCH_FILE
;
2660 if ((fattr
& dirtype
) & FILE_ATTRIBUTE_DIRECTORY
) {
2661 return NT_STATUS_FILE_IS_A_DIRECTORY
;
2664 if ((fattr
& ~dirtype
) & (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
)) {
2665 return NT_STATUS_NO_SUCH_FILE
;
2668 if (dirtype
& 0xFF00) {
2669 /* These will never be set for POSIX. */
2670 return NT_STATUS_NO_SUCH_FILE
;
2675 return NT_STATUS_NO_SUCH_FILE
;
2678 /* Can't delete a directory. */
2679 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
2680 return NT_STATUS_FILE_IS_A_DIRECTORY
;
2685 else if (dirtype
& FILE_ATTRIBUTE_DIRECTORY
) /* Asked for a directory and it isn't. */
2686 return NT_STATUS_OBJECT_NAME_INVALID
;
2687 #endif /* JRATEST */
2689 /* On open checks the open itself will check the share mode, so
2690 don't do it here as we'll get it wrong. */
2692 status
= SMB_VFS_CREATE_FILE
2695 0, /* root_dir_fid */
2696 smb_fname
, /* fname */
2697 DELETE_ACCESS
, /* access_mask */
2698 FILE_SHARE_NONE
, /* share_access */
2699 FILE_OPEN
, /* create_disposition*/
2700 FILE_NON_DIRECTORY_FILE
, /* create_options */
2701 /* file_attributes */
2702 posix_paths
? FILE_FLAG_POSIX_SEMANTICS
|0777 :
2703 FILE_ATTRIBUTE_NORMAL
,
2704 0, /* oplock_request */
2705 0, /* allocation_size */
2706 0, /* private_flags */
2712 if (!NT_STATUS_IS_OK(status
)) {
2713 DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
2714 nt_errstr(status
)));
2718 status
= can_set_delete_on_close(fsp
, fattr
);
2719 if (!NT_STATUS_IS_OK(status
)) {
2720 DEBUG(10, ("do_unlink can_set_delete_on_close for file %s - "
2722 smb_fname_str_dbg(smb_fname
),
2723 nt_errstr(status
)));
2724 close_file(req
, fsp
, NORMAL_CLOSE
);
2728 /* The set is across all open files on this dev/inode pair. */
2729 if (!set_delete_on_close(fsp
, True
,
2730 conn
->session_info
->security_token
,
2731 conn
->session_info
->unix_token
)) {
2732 close_file(req
, fsp
, NORMAL_CLOSE
);
2733 return NT_STATUS_ACCESS_DENIED
;
2736 return close_file(req
, fsp
, NORMAL_CLOSE
);
2739 /****************************************************************************
2740 The guts of the unlink command, split out so it may be called by the NT SMB
2742 ****************************************************************************/
2744 NTSTATUS
unlink_internals(connection_struct
*conn
, struct smb_request
*req
,
2745 uint32 dirtype
, struct smb_filename
*smb_fname
,
2748 char *fname_dir
= NULL
;
2749 char *fname_mask
= NULL
;
2751 NTSTATUS status
= NT_STATUS_OK
;
2752 TALLOC_CTX
*ctx
= talloc_tos();
2754 /* Split up the directory from the filename/mask. */
2755 status
= split_fname_dir_mask(ctx
, smb_fname
->base_name
,
2756 &fname_dir
, &fname_mask
);
2757 if (!NT_STATUS_IS_OK(status
)) {
2762 * We should only check the mangled cache
2763 * here if unix_convert failed. This means
2764 * that the path in 'mask' doesn't exist
2765 * on the file system and so we need to look
2766 * for a possible mangle. This patch from
2767 * Tine Smukavec <valentin.smukavec@hermes.si>.
2770 if (!VALID_STAT(smb_fname
->st
) &&
2771 mangle_is_mangled(fname_mask
, conn
->params
)) {
2772 char *new_mask
= NULL
;
2773 mangle_lookup_name_from_8_3(ctx
, fname_mask
,
2774 &new_mask
, conn
->params
);
2776 TALLOC_FREE(fname_mask
);
2777 fname_mask
= new_mask
;
2784 * Only one file needs to be unlinked. Append the mask back
2785 * onto the directory.
2787 TALLOC_FREE(smb_fname
->base_name
);
2788 if (ISDOT(fname_dir
)) {
2789 /* Ensure we use canonical names on open. */
2790 smb_fname
->base_name
= talloc_asprintf(smb_fname
,
2794 smb_fname
->base_name
= talloc_asprintf(smb_fname
,
2799 if (!smb_fname
->base_name
) {
2800 status
= NT_STATUS_NO_MEMORY
;
2804 dirtype
= FILE_ATTRIBUTE_NORMAL
;
2807 status
= check_name(conn
, smb_fname
->base_name
);
2808 if (!NT_STATUS_IS_OK(status
)) {
2812 status
= do_unlink(conn
, req
, smb_fname
, dirtype
);
2813 if (!NT_STATUS_IS_OK(status
)) {
2819 struct smb_Dir
*dir_hnd
= NULL
;
2821 const char *dname
= NULL
;
2822 char *talloced
= NULL
;
2824 if ((dirtype
& SAMBA_ATTRIBUTES_MASK
) == FILE_ATTRIBUTE_DIRECTORY
) {
2825 status
= NT_STATUS_OBJECT_NAME_INVALID
;
2829 if (strequal(fname_mask
,"????????.???")) {
2830 TALLOC_FREE(fname_mask
);
2831 fname_mask
= talloc_strdup(ctx
, "*");
2833 status
= NT_STATUS_NO_MEMORY
;
2838 status
= check_name(conn
, fname_dir
);
2839 if (!NT_STATUS_IS_OK(status
)) {
2843 dir_hnd
= OpenDir(talloc_tos(), conn
, fname_dir
, fname_mask
,
2845 if (dir_hnd
== NULL
) {
2846 status
= map_nt_error_from_unix(errno
);
2850 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2851 the pattern matches against the long name, otherwise the short name
2852 We don't implement this yet XXXX
2855 status
= NT_STATUS_NO_SUCH_FILE
;
2857 while ((dname
= ReadDirName(dir_hnd
, &offset
,
2858 &smb_fname
->st
, &talloced
))) {
2859 TALLOC_CTX
*frame
= talloc_stackframe();
2861 if (!is_visible_file(conn
, fname_dir
, dname
,
2862 &smb_fname
->st
, true)) {
2864 TALLOC_FREE(talloced
);
2868 /* Quick check for "." and ".." */
2869 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
2871 TALLOC_FREE(talloced
);
2875 if(!mask_match(dname
, fname_mask
,
2876 conn
->case_sensitive
)) {
2878 TALLOC_FREE(talloced
);
2882 TALLOC_FREE(smb_fname
->base_name
);
2883 if (ISDOT(fname_dir
)) {
2884 /* Ensure we use canonical names on open. */
2885 smb_fname
->base_name
=
2886 talloc_asprintf(smb_fname
, "%s",
2889 smb_fname
->base_name
=
2890 talloc_asprintf(smb_fname
, "%s/%s",
2894 if (!smb_fname
->base_name
) {
2895 TALLOC_FREE(dir_hnd
);
2896 status
= NT_STATUS_NO_MEMORY
;
2898 TALLOC_FREE(talloced
);
2902 status
= check_name(conn
, smb_fname
->base_name
);
2903 if (!NT_STATUS_IS_OK(status
)) {
2904 TALLOC_FREE(dir_hnd
);
2906 TALLOC_FREE(talloced
);
2910 status
= do_unlink(conn
, req
, smb_fname
, dirtype
);
2911 if (!NT_STATUS_IS_OK(status
)) {
2912 TALLOC_FREE(dir_hnd
);
2914 TALLOC_FREE(talloced
);
2919 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2920 smb_fname
->base_name
));
2923 TALLOC_FREE(talloced
);
2925 TALLOC_FREE(dir_hnd
);
2928 if (count
== 0 && NT_STATUS_IS_OK(status
) && errno
!= 0) {
2929 status
= map_nt_error_from_unix(errno
);
2933 TALLOC_FREE(fname_dir
);
2934 TALLOC_FREE(fname_mask
);
2938 /****************************************************************************
2940 ****************************************************************************/
2942 void reply_unlink(struct smb_request
*req
)
2944 connection_struct
*conn
= req
->conn
;
2946 struct smb_filename
*smb_fname
= NULL
;
2949 bool path_contains_wcard
= False
;
2950 TALLOC_CTX
*ctx
= talloc_tos();
2952 START_PROFILE(SMBunlink
);
2955 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2959 dirtype
= SVAL(req
->vwv
+0, 0);
2961 srvstr_get_path_req_wcard(ctx
, req
, &name
, (const char *)req
->buf
+ 1,
2962 STR_TERMINATE
, &status
,
2963 &path_contains_wcard
);
2964 if (!NT_STATUS_IS_OK(status
)) {
2965 reply_nterror(req
, status
);
2969 status
= filename_convert(ctx
, conn
,
2970 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2972 UCF_COND_ALLOW_WCARD_LCOMP
,
2973 &path_contains_wcard
,
2975 if (!NT_STATUS_IS_OK(status
)) {
2976 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
2977 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2978 ERRSRV
, ERRbadpath
);
2981 reply_nterror(req
, status
);
2985 DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname
)));
2987 status
= unlink_internals(conn
, req
, dirtype
, smb_fname
,
2988 path_contains_wcard
);
2989 if (!NT_STATUS_IS_OK(status
)) {
2990 if (open_was_deferred(req
->sconn
, req
->mid
)) {
2991 /* We have re-scheduled this call. */
2994 reply_nterror(req
, status
);
2998 reply_outbuf(req
, 0, 0);
3000 TALLOC_FREE(smb_fname
);
3001 END_PROFILE(SMBunlink
);
3005 /****************************************************************************
3007 ****************************************************************************/
3009 static void fail_readraw(void)
3011 const char *errstr
= talloc_asprintf(talloc_tos(),
3012 "FAIL ! reply_readbraw: socket write fail (%s)",
3017 exit_server_cleanly(errstr
);
3020 /****************************************************************************
3021 Fake (read/write) sendfile. Returns -1 on read or write fail.
3022 ****************************************************************************/
3024 ssize_t
fake_sendfile(files_struct
*fsp
, off_t startpos
, size_t nread
)
3027 size_t tosend
= nread
;
3034 bufsize
= MIN(nread
, 65536);
3036 if (!(buf
= SMB_MALLOC_ARRAY(char, bufsize
))) {
3040 while (tosend
> 0) {
3044 if (tosend
> bufsize
) {
3049 ret
= read_file(fsp
,buf
,startpos
,cur_read
);
3055 /* If we had a short read, fill with zeros. */
3056 if (ret
< cur_read
) {
3057 memset(buf
+ ret
, '\0', cur_read
- ret
);
3060 if (write_data(fsp
->conn
->sconn
->sock
, buf
, cur_read
)
3062 char addr
[INET6_ADDRSTRLEN
];
3064 * Try and give an error message saying what
3067 DEBUG(0, ("write_data failed for client %s. "
3069 get_peer_addr(fsp
->conn
->sconn
->sock
, addr
,
3076 startpos
+= cur_read
;
3080 return (ssize_t
)nread
;
3083 /****************************************************************************
3084 Deal with the case of sendfile reading less bytes from the file than
3085 requested. Fill with zeros (all we can do).
3086 ****************************************************************************/
3088 void sendfile_short_send(files_struct
*fsp
,
3093 #define SHORT_SEND_BUFSIZE 1024
3094 if (nread
< headersize
) {
3095 DEBUG(0,("sendfile_short_send: sendfile failed to send "
3096 "header for file %s (%s). Terminating\n",
3097 fsp_str_dbg(fsp
), strerror(errno
)));
3098 exit_server_cleanly("sendfile_short_send failed");
3101 nread
-= headersize
;
3103 if (nread
< smb_maxcnt
) {
3104 char *buf
= SMB_CALLOC_ARRAY(char, SHORT_SEND_BUFSIZE
);
3106 exit_server_cleanly("sendfile_short_send: "
3110 DEBUG(0,("sendfile_short_send: filling truncated file %s "
3111 "with zeros !\n", fsp_str_dbg(fsp
)));
3113 while (nread
< smb_maxcnt
) {
3115 * We asked for the real file size and told sendfile
3116 * to not go beyond the end of the file. But it can
3117 * happen that in between our fstat call and the
3118 * sendfile call the file was truncated. This is very
3119 * bad because we have already announced the larger
3120 * number of bytes to the client.
3122 * The best we can do now is to send 0-bytes, just as
3123 * a read from a hole in a sparse file would do.
3125 * This should happen rarely enough that I don't care
3126 * about efficiency here :-)
3130 to_write
= MIN(SHORT_SEND_BUFSIZE
, smb_maxcnt
- nread
);
3131 if (write_data(fsp
->conn
->sconn
->sock
, buf
, to_write
)
3133 char addr
[INET6_ADDRSTRLEN
];
3135 * Try and give an error message saying what
3138 DEBUG(0, ("write_data failed for client %s. "
3141 fsp
->conn
->sconn
->sock
, addr
,
3144 exit_server_cleanly("sendfile_short_send: "
3145 "write_data failed");
3153 /****************************************************************************
3154 Return a readbraw error (4 bytes of zero).
3155 ****************************************************************************/
3157 static void reply_readbraw_error(struct smbd_server_connection
*sconn
)
3163 smbd_lock_socket(sconn
);
3164 if (write_data(sconn
->sock
,header
,4) != 4) {
3165 char addr
[INET6_ADDRSTRLEN
];
3167 * Try and give an error message saying what
3170 DEBUG(0, ("write_data failed for client %s. "
3172 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
3177 smbd_unlock_socket(sconn
);
3180 /****************************************************************************
3181 Use sendfile in readbraw.
3182 ****************************************************************************/
3184 static void send_file_readbraw(connection_struct
*conn
,
3185 struct smb_request
*req
,
3191 struct smbd_server_connection
*sconn
= req
->sconn
;
3192 char *outbuf
= NULL
;
3196 * We can only use sendfile on a non-chained packet
3197 * but we can use on a non-oplocked file. tridge proved this
3198 * on a train in Germany :-). JRA.
3199 * reply_readbraw has already checked the length.
3202 if ( !req_is_in_chain(req
) && (nread
> 0) && (fsp
->base_fsp
== NULL
) &&
3203 (fsp
->wcp
== NULL
) &&
3204 lp_use_sendfile(SNUM(conn
), req
->sconn
->smb1
.signing_state
) ) {
3205 ssize_t sendfile_read
= -1;
3207 DATA_BLOB header_blob
;
3209 _smb_setlen(header
,nread
);
3210 header_blob
= data_blob_const(header
, 4);
3212 sendfile_read
= SMB_VFS_SENDFILE(sconn
->sock
, fsp
,
3213 &header_blob
, startpos
,
3215 if (sendfile_read
== -1) {
3216 /* Returning ENOSYS means no data at all was sent.
3217 * Do this as a normal read. */
3218 if (errno
== ENOSYS
) {
3219 goto normal_readbraw
;
3223 * Special hack for broken Linux with no working sendfile. If we
3224 * return EINTR we sent the header but not the rest of the data.
3225 * Fake this up by doing read/write calls.
3227 if (errno
== EINTR
) {
3228 /* Ensure we don't do this again. */
3229 set_use_sendfile(SNUM(conn
), False
);
3230 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
3232 if (fake_sendfile(fsp
, startpos
, nread
) == -1) {
3233 DEBUG(0,("send_file_readbraw: "
3234 "fake_sendfile failed for "
3238 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
3243 DEBUG(0,("send_file_readbraw: sendfile failed for "
3244 "file %s (%s). Terminating\n",
3245 fsp_str_dbg(fsp
), strerror(errno
)));
3246 exit_server_cleanly("send_file_readbraw sendfile failed");
3247 } else if (sendfile_read
== 0) {
3249 * Some sendfile implementations return 0 to indicate
3250 * that there was a short read, but nothing was
3251 * actually written to the socket. In this case,
3252 * fallback to the normal read path so the header gets
3253 * the correct byte count.
3255 DEBUG(3, ("send_file_readbraw: sendfile sent zero "
3256 "bytes falling back to the normal read: "
3257 "%s\n", fsp_str_dbg(fsp
)));
3258 goto normal_readbraw
;
3261 /* Deal with possible short send. */
3262 if (sendfile_read
!= 4+nread
) {
3263 sendfile_short_send(fsp
, sendfile_read
, 4, nread
);
3270 outbuf
= talloc_array(NULL
, char, nread
+4);
3272 DEBUG(0,("send_file_readbraw: talloc_array failed for size %u.\n",
3273 (unsigned)(nread
+4)));
3274 reply_readbraw_error(sconn
);
3279 ret
= read_file(fsp
,outbuf
+4,startpos
,nread
);
3280 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
3289 _smb_setlen(outbuf
,ret
);
3290 if (write_data(sconn
->sock
, outbuf
, 4+ret
) != 4+ret
) {
3291 char addr
[INET6_ADDRSTRLEN
];
3293 * Try and give an error message saying what
3296 DEBUG(0, ("write_data failed for client %s. "
3298 get_peer_addr(fsp
->conn
->sconn
->sock
, addr
,
3305 TALLOC_FREE(outbuf
);
3308 /****************************************************************************
3309 Reply to a readbraw (core+ protocol).
3310 ****************************************************************************/
3312 void reply_readbraw(struct smb_request
*req
)
3314 connection_struct
*conn
= req
->conn
;
3315 struct smbd_server_connection
*sconn
= req
->sconn
;
3316 ssize_t maxcount
,mincount
;
3320 struct lock_struct lock
;
3323 START_PROFILE(SMBreadbraw
);
3325 if (srv_is_signing_active(sconn
) || req
->encrypted
) {
3326 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
3327 "raw reads/writes are disallowed.");
3331 reply_readbraw_error(sconn
);
3332 END_PROFILE(SMBreadbraw
);
3336 if (sconn
->smb1
.echo_handler
.trusted_fde
) {
3337 DEBUG(2,("SMBreadbraw rejected with NOT_SUPPORTED because of "
3338 "'async smb echo handler = yes'\n"));
3339 reply_readbraw_error(sconn
);
3340 END_PROFILE(SMBreadbraw
);
3345 * Special check if an oplock break has been issued
3346 * and the readraw request croses on the wire, we must
3347 * return a zero length response here.
3350 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
3353 * We have to do a check_fsp by hand here, as
3354 * we must always return 4 zero bytes on error,
3358 if (!fsp
|| !conn
|| conn
!= fsp
->conn
||
3359 req
->vuid
!= fsp
->vuid
||
3360 fsp
->is_directory
|| fsp
->fh
->fd
== -1) {
3362 * fsp could be NULL here so use the value from the packet. JRA.
3364 DEBUG(3,("reply_readbraw: fnum %d not valid "
3366 (int)SVAL(req
->vwv
+0, 0)));
3367 reply_readbraw_error(sconn
);
3368 END_PROFILE(SMBreadbraw
);
3372 /* Do a "by hand" version of CHECK_READ. */
3373 if (!(fsp
->can_read
||
3374 ((req
->flags2
& FLAGS2_READ_PERMIT_EXECUTE
) &&
3375 (fsp
->access_mask
& FILE_EXECUTE
)))) {
3376 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
3377 (int)SVAL(req
->vwv
+0, 0)));
3378 reply_readbraw_error(sconn
);
3379 END_PROFILE(SMBreadbraw
);
3383 flush_write_cache(fsp
, SAMBA_READRAW_FLUSH
);
3385 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+1, 0);
3386 if(req
->wct
== 10) {
3388 * This is a large offset (64 bit) read.
3391 startpos
|= (((off_t
)IVAL(req
->vwv
+8, 0)) << 32);
3394 DEBUG(0,("reply_readbraw: negative 64 bit "
3395 "readraw offset (%.0f) !\n",
3396 (double)startpos
));
3397 reply_readbraw_error(sconn
);
3398 END_PROFILE(SMBreadbraw
);
3403 maxcount
= (SVAL(req
->vwv
+3, 0) & 0xFFFF);
3404 mincount
= (SVAL(req
->vwv
+4, 0) & 0xFFFF);
3406 /* ensure we don't overrun the packet size */
3407 maxcount
= MIN(65535,maxcount
);
3409 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
3410 (uint64_t)startpos
, (uint64_t)maxcount
, READ_LOCK
,
3413 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
3414 reply_readbraw_error(sconn
);
3415 END_PROFILE(SMBreadbraw
);
3419 if (fsp_stat(fsp
) == 0) {
3420 size
= fsp
->fsp_name
->st
.st_ex_size
;
3423 if (startpos
>= size
) {
3426 nread
= MIN(maxcount
,(size
- startpos
));
3429 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
3430 if (nread
< mincount
)
3434 DEBUG( 3, ( "reply_readbraw: %s start=%.0f max=%lu "
3435 "min=%lu nread=%lu\n",
3436 fsp_fnum_dbg(fsp
), (double)startpos
,
3437 (unsigned long)maxcount
,
3438 (unsigned long)mincount
,
3439 (unsigned long)nread
) );
3441 send_file_readbraw(conn
, req
, fsp
, startpos
, nread
, mincount
);
3443 DEBUG(5,("reply_readbraw finished\n"));
3445 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
3447 END_PROFILE(SMBreadbraw
);
3452 #define DBGC_CLASS DBGC_LOCKING
3454 /****************************************************************************
3455 Reply to a lockread (core+ protocol).
3456 ****************************************************************************/
3458 void reply_lockread(struct smb_request
*req
)
3460 connection_struct
*conn
= req
->conn
;
3468 struct byte_range_lock
*br_lck
= NULL
;
3470 struct smbd_server_connection
*sconn
= req
->sconn
;
3472 START_PROFILE(SMBlockread
);
3475 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3476 END_PROFILE(SMBlockread
);
3480 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
3482 if (!check_fsp(conn
, req
, fsp
)) {
3483 END_PROFILE(SMBlockread
);
3487 if (!CHECK_READ(fsp
,req
)) {
3488 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3489 END_PROFILE(SMBlockread
);
3493 numtoread
= SVAL(req
->vwv
+1, 0);
3494 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+2, 0);
3497 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
3498 * protocol request that predates the read/write lock concept.
3499 * Thus instead of asking for a read lock here we need to ask
3500 * for a write lock. JRA.
3501 * Note that the requested lock size is unaffected by max_send.
3504 br_lck
= do_lock(req
->sconn
->msg_ctx
,
3506 (uint64_t)req
->smbpid
,
3507 (uint64_t)numtoread
,
3511 False
, /* Non-blocking lock. */
3514 TALLOC_FREE(br_lck
);
3516 if (NT_STATUS_V(status
)) {
3517 reply_nterror(req
, status
);
3518 END_PROFILE(SMBlockread
);
3523 * However the requested READ size IS affected by max_send. Insanity.... JRA.
3525 maxtoread
= sconn
->smb1
.sessions
.max_send
- (smb_size
+ 5*2 + 3);
3527 if (numtoread
> maxtoread
) {
3528 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u/%u). \
3529 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3530 (unsigned int)numtoread
, (unsigned int)maxtoread
,
3531 (unsigned int)sconn
->smb1
.sessions
.max_send
));
3532 numtoread
= maxtoread
;
3535 reply_outbuf(req
, 5, numtoread
+ 3);
3537 data
= smb_buf(req
->outbuf
) + 3;
3539 nread
= read_file(fsp
,data
,startpos
,numtoread
);
3542 reply_nterror(req
, map_nt_error_from_unix(errno
));
3543 END_PROFILE(SMBlockread
);
3547 srv_set_message((char *)req
->outbuf
, 5, nread
+3, False
);
3549 SSVAL(req
->outbuf
,smb_vwv0
,nread
);
3550 SSVAL(req
->outbuf
,smb_vwv5
,nread
+3);
3551 p
= smb_buf(req
->outbuf
);
3552 SCVAL(p
,0,0); /* pad byte. */
3555 DEBUG(3,("lockread %s num=%d nread=%d\n",
3556 fsp_fnum_dbg(fsp
), (int)numtoread
, (int)nread
));
3558 END_PROFILE(SMBlockread
);
3563 #define DBGC_CLASS DBGC_ALL
3565 /****************************************************************************
3567 ****************************************************************************/
3569 void reply_read(struct smb_request
*req
)
3571 connection_struct
*conn
= req
->conn
;
3578 struct lock_struct lock
;
3579 struct smbd_server_connection
*sconn
= req
->sconn
;
3581 START_PROFILE(SMBread
);
3584 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3585 END_PROFILE(SMBread
);
3589 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
3591 if (!check_fsp(conn
, req
, fsp
)) {
3592 END_PROFILE(SMBread
);
3596 if (!CHECK_READ(fsp
,req
)) {
3597 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3598 END_PROFILE(SMBread
);
3602 numtoread
= SVAL(req
->vwv
+1, 0);
3603 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+2, 0);
3606 * The requested read size cannot be greater than max_send. JRA.
3608 maxtoread
= sconn
->smb1
.sessions
.max_send
- (smb_size
+ 5*2 + 3);
3610 if (numtoread
> maxtoread
) {
3611 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u/%u). \
3612 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3613 (unsigned int)numtoread
, (unsigned int)maxtoread
,
3614 (unsigned int)sconn
->smb1
.sessions
.max_send
));
3615 numtoread
= maxtoread
;
3618 reply_outbuf(req
, 5, numtoread
+3);
3620 data
= smb_buf(req
->outbuf
) + 3;
3622 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
3623 (uint64_t)startpos
, (uint64_t)numtoread
, READ_LOCK
,
3626 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
3627 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
3628 END_PROFILE(SMBread
);
3633 nread
= read_file(fsp
,data
,startpos
,numtoread
);
3636 reply_nterror(req
, map_nt_error_from_unix(errno
));
3640 srv_set_message((char *)req
->outbuf
, 5, nread
+3, False
);
3642 SSVAL(req
->outbuf
,smb_vwv0
,nread
);
3643 SSVAL(req
->outbuf
,smb_vwv5
,nread
+3);
3644 SCVAL(smb_buf(req
->outbuf
),0,1);
3645 SSVAL(smb_buf(req
->outbuf
),1,nread
);
3647 DEBUG(3, ("read %s num=%d nread=%d\n",
3648 fsp_fnum_dbg(fsp
), (int)numtoread
, (int)nread
));
3651 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
3653 END_PROFILE(SMBread
);
3657 /****************************************************************************
3659 ****************************************************************************/
3661 static int setup_readX_header(struct smb_request
*req
, char *outbuf
,
3666 outsize
= srv_set_message(outbuf
,12,smb_maxcnt
,False
);
3668 memset(outbuf
+smb_vwv0
,'\0',24); /* valgrind init. */
3670 SCVAL(outbuf
,smb_vwv0
,0xFF);
3671 SSVAL(outbuf
,smb_vwv2
,0xFFFF); /* Remaining - must be -1. */
3672 SSVAL(outbuf
,smb_vwv5
,smb_maxcnt
);
3673 SSVAL(outbuf
,smb_vwv6
,
3674 (smb_wct
- 4) /* offset from smb header to wct */
3675 + 1 /* the wct field */
3676 + 12 * sizeof(uint16_t) /* vwv */
3677 + 2); /* the buflen field */
3678 SSVAL(outbuf
,smb_vwv7
,(smb_maxcnt
>> 16));
3679 SSVAL(outbuf
,smb_vwv11
,smb_maxcnt
);
3680 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3681 _smb_setlen_large(outbuf
,(smb_size
+ 12*2 + smb_maxcnt
- 4));
3685 /****************************************************************************
3686 Reply to a read and X - possibly using sendfile.
3687 ****************************************************************************/
3689 static void send_file_readX(connection_struct
*conn
, struct smb_request
*req
,
3690 files_struct
*fsp
, off_t startpos
,
3694 struct lock_struct lock
;
3695 int saved_errno
= 0;
3697 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
3698 (uint64_t)startpos
, (uint64_t)smb_maxcnt
, READ_LOCK
,
3701 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
3702 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
3707 * We can only use sendfile on a non-chained packet
3708 * but we can use on a non-oplocked file. tridge proved this
3709 * on a train in Germany :-). JRA.
3712 if (!req_is_in_chain(req
) &&
3714 (fsp
->base_fsp
== NULL
) &&
3715 (fsp
->wcp
== NULL
) &&
3716 lp_use_sendfile(SNUM(conn
), req
->sconn
->smb1
.signing_state
) ) {
3717 uint8 headerbuf
[smb_size
+ 12 * 2];
3720 if(fsp_stat(fsp
) == -1) {
3721 reply_nterror(req
, map_nt_error_from_unix(errno
));
3725 if (!S_ISREG(fsp
->fsp_name
->st
.st_ex_mode
) ||
3726 (startpos
> fsp
->fsp_name
->st
.st_ex_size
) ||
3727 (smb_maxcnt
> (fsp
->fsp_name
->st
.st_ex_size
- startpos
))) {
3729 * We already know that we would do a short read, so don't
3730 * try the sendfile() path.
3732 goto nosendfile_read
;
3736 * Set up the packet header before send. We
3737 * assume here the sendfile will work (get the
3738 * correct amount of data).
3741 header
= data_blob_const(headerbuf
, sizeof(headerbuf
));
3743 construct_reply_common_req(req
, (char *)headerbuf
);
3744 setup_readX_header(req
, (char *)headerbuf
, smb_maxcnt
);
3746 nread
= SMB_VFS_SENDFILE(req
->sconn
->sock
, fsp
, &header
,
3747 startpos
, smb_maxcnt
);
3749 /* Returning ENOSYS means no data at all was sent.
3750 Do this as a normal read. */
3751 if (errno
== ENOSYS
) {
3756 * Special hack for broken Linux with no working sendfile. If we
3757 * return EINTR we sent the header but not the rest of the data.
3758 * Fake this up by doing read/write calls.
3761 if (errno
== EINTR
) {
3762 /* Ensure we don't do this again. */
3763 set_use_sendfile(SNUM(conn
), False
);
3764 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3765 nread
= fake_sendfile(fsp
, startpos
,
3768 DEBUG(0,("send_file_readX: "
3769 "fake_sendfile failed for "
3773 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3775 DEBUG(3, ("send_file_readX: fake_sendfile %s max=%d nread=%d\n",
3776 fsp_fnum_dbg(fsp
), (int)smb_maxcnt
, (int)nread
));
3777 /* No outbuf here means successful sendfile. */
3781 DEBUG(0,("send_file_readX: sendfile failed for file "
3782 "%s (%s). Terminating\n", fsp_str_dbg(fsp
),
3784 exit_server_cleanly("send_file_readX sendfile failed");
3785 } else if (nread
== 0) {
3787 * Some sendfile implementations return 0 to indicate
3788 * that there was a short read, but nothing was
3789 * actually written to the socket. In this case,
3790 * fallback to the normal read path so the header gets
3791 * the correct byte count.
3793 DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
3794 "falling back to the normal read: %s\n",
3799 DEBUG(3, ("send_file_readX: sendfile %s max=%d nread=%d\n",
3800 fsp_fnum_dbg(fsp
), (int)smb_maxcnt
, (int)nread
));
3802 /* Deal with possible short send. */
3803 if (nread
!= smb_maxcnt
+ sizeof(headerbuf
)) {
3804 sendfile_short_send(fsp
, nread
, sizeof(headerbuf
), smb_maxcnt
);
3806 /* No outbuf here means successful sendfile. */
3807 SMB_PERFCOUNT_SET_MSGLEN_OUT(&req
->pcd
, nread
);
3808 SMB_PERFCOUNT_END(&req
->pcd
);
3814 if ((smb_maxcnt
& 0xFF0000) > 0x10000) {
3815 uint8 headerbuf
[smb_size
+ 2*12];
3817 construct_reply_common_req(req
, (char *)headerbuf
);
3818 setup_readX_header(req
, (char *)headerbuf
, smb_maxcnt
);
3820 /* Send out the header. */
3821 if (write_data(req
->sconn
->sock
, (char *)headerbuf
,
3822 sizeof(headerbuf
)) != sizeof(headerbuf
)) {
3824 char addr
[INET6_ADDRSTRLEN
];
3826 * Try and give an error message saying what
3829 DEBUG(0, ("write_data failed for client %s. "
3831 get_peer_addr(req
->sconn
->sock
, addr
,
3835 DEBUG(0,("send_file_readX: write_data failed for file "
3836 "%s (%s). Terminating\n", fsp_str_dbg(fsp
),
3838 exit_server_cleanly("send_file_readX sendfile failed");
3840 nread
= fake_sendfile(fsp
, startpos
, smb_maxcnt
);
3842 DEBUG(0,("send_file_readX: fake_sendfile failed for "
3843 "file %s (%s).\n", fsp_str_dbg(fsp
),
3845 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3852 reply_outbuf(req
, 12, smb_maxcnt
);
3853 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
3854 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
3856 nread
= read_file(fsp
, smb_buf(req
->outbuf
), startpos
, smb_maxcnt
);
3857 saved_errno
= errno
;
3859 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
3862 reply_nterror(req
, map_nt_error_from_unix(saved_errno
));
3866 setup_readX_header(req
, (char *)req
->outbuf
, nread
);
3868 DEBUG(3, ("send_file_readX %s max=%d nread=%d\n",
3869 fsp_fnum_dbg(fsp
), (int)smb_maxcnt
, (int)nread
));
3873 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
3874 TALLOC_FREE(req
->outbuf
);
3878 /****************************************************************************
3879 Work out how much space we have for a read return.
3880 ****************************************************************************/
3882 static size_t calc_max_read_pdu(const struct smb_request
*req
)
3884 if (req
->sconn
->conn
->protocol
< PROTOCOL_NT1
) {
3885 return req
->sconn
->smb1
.sessions
.max_send
;
3888 if (!lp_large_readwrite()) {
3889 return req
->sconn
->smb1
.sessions
.max_send
;
3892 if (req_is_in_chain(req
)) {
3893 return req
->sconn
->smb1
.sessions
.max_send
;
3896 if (req
->encrypted
) {
3898 * Don't take encrypted traffic up to the
3899 * limit. There are padding considerations
3900 * that make that tricky.
3902 return req
->sconn
->smb1
.sessions
.max_send
;
3905 if (srv_is_signing_active(req
->sconn
)) {
3909 if (!lp_unix_extensions()) {
3914 * We can do ultra-large POSIX reads.
3919 /****************************************************************************
3920 Calculate how big a read can be. Copes with all clients. It's always
3921 safe to return a short read - Windows does this.
3922 ****************************************************************************/
3924 static size_t calc_read_size(const struct smb_request
*req
,
3928 size_t max_pdu
= calc_max_read_pdu(req
);
3929 size_t total_size
= 0;
3930 size_t hdr_len
= MIN_SMB_SIZE
+ VWV(12);
3931 size_t max_len
= max_pdu
- hdr_len
;
3934 * Windows explicitly ignores upper size of 0xFFFF.
3935 * See [MS-SMB].pdf <26> Section 2.2.4.2.1:
3936 * We must do the same as these will never fit even in
3937 * an extended size NetBIOS packet.
3939 if (upper_size
== 0xFFFF) {
3943 if (req
->sconn
->conn
->protocol
< PROTOCOL_NT1
) {
3947 total_size
= ((upper_size
<<16) | lower_size
);
3950 * LARGE_READX test shows it's always safe to return
3951 * a short read. Windows does so.
3953 return MIN(total_size
, max_len
);
3956 /****************************************************************************
3957 Reply to a read and X.
3958 ****************************************************************************/
3960 void reply_read_and_X(struct smb_request
*req
)
3962 connection_struct
*conn
= req
->conn
;
3967 bool big_readX
= False
;
3969 size_t smb_mincnt
= SVAL(req
->vwv
+6, 0);
3972 START_PROFILE(SMBreadX
);
3974 if ((req
->wct
!= 10) && (req
->wct
!= 12)) {
3975 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3979 fsp
= file_fsp(req
, SVAL(req
->vwv
+2, 0));
3980 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+3, 0);
3981 smb_maxcnt
= SVAL(req
->vwv
+5, 0);
3983 /* If it's an IPC, pass off the pipe handler. */
3985 reply_pipe_read_and_X(req
);
3986 END_PROFILE(SMBreadX
);
3990 if (!check_fsp(conn
, req
, fsp
)) {
3991 END_PROFILE(SMBreadX
);
3995 if (!CHECK_READ(fsp
,req
)) {
3996 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3997 END_PROFILE(SMBreadX
);
4001 upper_size
= SVAL(req
->vwv
+7, 0);
4002 smb_maxcnt
= calc_read_size(req
, upper_size
, smb_maxcnt
);
4003 if (smb_maxcnt
> (0x1FFFF - (MIN_SMB_SIZE
+ VWV(12)))) {
4005 * This is a heuristic to avoid keeping large
4006 * outgoing buffers around over long-lived aio
4012 if (req
->wct
== 12) {
4014 * This is a large offset (64 bit) read.
4016 startpos
|= (((off_t
)IVAL(req
->vwv
+10, 0)) << 32);
4021 NTSTATUS status
= schedule_aio_read_and_X(conn
,
4026 if (NT_STATUS_IS_OK(status
)) {
4027 /* Read scheduled - we're done. */
4030 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
4031 /* Real error - report to client. */
4032 END_PROFILE(SMBreadX
);
4033 reply_nterror(req
, status
);
4036 /* NT_STATUS_RETRY - fall back to sync read. */
4039 smbd_lock_socket(req
->sconn
);
4040 send_file_readX(conn
, req
, fsp
, startpos
, smb_maxcnt
);
4041 smbd_unlock_socket(req
->sconn
);
4044 END_PROFILE(SMBreadX
);
4048 /****************************************************************************
4049 Error replies to writebraw must have smb_wct == 1. Fix this up.
4050 ****************************************************************************/
4052 void error_to_writebrawerr(struct smb_request
*req
)
4054 uint8
*old_outbuf
= req
->outbuf
;
4056 reply_outbuf(req
, 1, 0);
4058 memcpy(req
->outbuf
, old_outbuf
, smb_size
);
4059 TALLOC_FREE(old_outbuf
);
4062 /****************************************************************************
4063 Read 4 bytes of a smb packet and return the smb length of the packet.
4064 Store the result in the buffer. This version of the function will
4065 never return a session keepalive (length of zero).
4066 Timeout is in milliseconds.
4067 ****************************************************************************/
4069 static NTSTATUS
read_smb_length(int fd
, char *inbuf
, unsigned int timeout
,
4072 uint8_t msgtype
= NBSSkeepalive
;
4074 while (msgtype
== NBSSkeepalive
) {
4077 status
= read_smb_length_return_keepalive(fd
, inbuf
, timeout
,
4079 if (!NT_STATUS_IS_OK(status
)) {
4080 char addr
[INET6_ADDRSTRLEN
];
4081 /* Try and give an error message
4082 * saying what client failed. */
4083 DEBUG(0, ("read_fd_with_timeout failed for "
4084 "client %s read error = %s.\n",
4085 get_peer_addr(fd
,addr
,sizeof(addr
)),
4086 nt_errstr(status
)));
4090 msgtype
= CVAL(inbuf
, 0);
4093 DEBUG(10,("read_smb_length: got smb length of %lu\n",
4094 (unsigned long)len
));
4096 return NT_STATUS_OK
;
4099 /****************************************************************************
4100 Reply to a writebraw (core+ or LANMAN1.0 protocol).
4101 ****************************************************************************/
4103 void reply_writebraw(struct smb_request
*req
)
4105 connection_struct
*conn
= req
->conn
;
4108 ssize_t total_written
=0;
4109 size_t numtowrite
=0;
4112 const char *data
=NULL
;
4115 struct lock_struct lock
;
4118 START_PROFILE(SMBwritebraw
);
4121 * If we ever reply with an error, it must have the SMB command
4122 * type of SMBwritec, not SMBwriteBraw, as this tells the client
4125 SCVAL(discard_const_p(uint8_t, req
->inbuf
),smb_com
,SMBwritec
);
4127 if (srv_is_signing_active(req
->sconn
)) {
4128 END_PROFILE(SMBwritebraw
);
4129 exit_server_cleanly("reply_writebraw: SMB signing is active - "
4130 "raw reads/writes are disallowed.");
4133 if (req
->wct
< 12) {
4134 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4135 error_to_writebrawerr(req
);
4136 END_PROFILE(SMBwritebraw
);
4140 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
4141 DEBUG(2,("SMBwritebraw rejected with NOT_SUPPORTED because of "
4142 "'async smb echo handler = yes'\n"));
4143 reply_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
4144 error_to_writebrawerr(req
);
4145 END_PROFILE(SMBwritebraw
);
4149 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
4150 if (!check_fsp(conn
, req
, fsp
)) {
4151 error_to_writebrawerr(req
);
4152 END_PROFILE(SMBwritebraw
);
4156 if (!CHECK_WRITE(fsp
)) {
4157 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
4158 error_to_writebrawerr(req
);
4159 END_PROFILE(SMBwritebraw
);
4163 tcount
= IVAL(req
->vwv
+1, 0);
4164 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+3, 0);
4165 write_through
= BITSETW(req
->vwv
+7,0);
4167 /* We have to deal with slightly different formats depending
4168 on whether we are using the core+ or lanman1.0 protocol */
4170 if(get_Protocol() <= PROTOCOL_COREPLUS
) {
4171 numtowrite
= SVAL(smb_buf_const(req
->inbuf
),-2);
4172 data
= smb_buf_const(req
->inbuf
);
4174 numtowrite
= SVAL(req
->vwv
+10, 0);
4175 data
= smb_base(req
->inbuf
) + SVAL(req
->vwv
+11, 0);
4178 /* Ensure we don't write bytes past the end of this packet. */
4179 if (data
+ numtowrite
> smb_base(req
->inbuf
) + smb_len(req
->inbuf
)) {
4180 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4181 error_to_writebrawerr(req
);
4182 END_PROFILE(SMBwritebraw
);
4186 if (!fsp
->print_file
) {
4187 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
4188 (uint64_t)startpos
, (uint64_t)tcount
, WRITE_LOCK
,
4191 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
4192 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
4193 error_to_writebrawerr(req
);
4194 END_PROFILE(SMBwritebraw
);
4200 nwritten
= write_file(req
,fsp
,data
,startpos
,numtowrite
);
4203 DEBUG(3, ("reply_writebraw: initial write %s start=%.0f num=%d "
4204 "wrote=%d sync=%d\n",
4205 fsp_fnum_dbg(fsp
), (double)startpos
, (int)numtowrite
,
4206 (int)nwritten
, (int)write_through
));
4208 if (nwritten
< (ssize_t
)numtowrite
) {
4209 reply_nterror(req
, NT_STATUS_DISK_FULL
);
4210 error_to_writebrawerr(req
);
4214 total_written
= nwritten
;
4216 /* Allocate a buffer of 64k + length. */
4217 buf
= talloc_array(NULL
, char, 65540);
4219 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4220 error_to_writebrawerr(req
);
4224 /* Return a SMBwritebraw message to the redirector to tell
4225 * it to send more bytes */
4227 memcpy(buf
, req
->inbuf
, smb_size
);
4228 srv_set_message(buf
,get_Protocol()>PROTOCOL_COREPLUS
?1:0,0,True
);
4229 SCVAL(buf
,smb_com
,SMBwritebraw
);
4230 SSVALS(buf
,smb_vwv0
,0xFFFF);
4232 if (!srv_send_smb(req
->sconn
,
4234 false, 0, /* no signing */
4235 IS_CONN_ENCRYPTED(conn
),
4237 exit_server_cleanly("reply_writebraw: srv_send_smb "
4241 /* Now read the raw data into the buffer and write it */
4242 status
= read_smb_length(req
->sconn
->sock
, buf
, SMB_SECONDARY_WAIT
,
4244 if (!NT_STATUS_IS_OK(status
)) {
4245 exit_server_cleanly("secondary writebraw failed");
4248 /* Set up outbuf to return the correct size */
4249 reply_outbuf(req
, 1, 0);
4251 if (numtowrite
!= 0) {
4253 if (numtowrite
> 0xFFFF) {
4254 DEBUG(0,("reply_writebraw: Oversize secondary write "
4255 "raw requested (%u). Terminating\n",
4256 (unsigned int)numtowrite
));
4257 exit_server_cleanly("secondary writebraw failed");
4260 if (tcount
> nwritten
+numtowrite
) {
4261 DEBUG(3,("reply_writebraw: Client overestimated the "
4263 (int)tcount
,(int)nwritten
,(int)numtowrite
));
4266 status
= read_data(req
->sconn
->sock
, buf
+4, numtowrite
);
4268 if (!NT_STATUS_IS_OK(status
)) {
4269 char addr
[INET6_ADDRSTRLEN
];
4270 /* Try and give an error message
4271 * saying what client failed. */
4272 DEBUG(0, ("reply_writebraw: Oversize secondary write "
4273 "raw read failed (%s) for client %s. "
4274 "Terminating\n", nt_errstr(status
),
4275 get_peer_addr(req
->sconn
->sock
, addr
,
4277 exit_server_cleanly("secondary writebraw failed");
4280 nwritten
= write_file(req
,fsp
,buf
+4,startpos
+nwritten
,numtowrite
);
4281 if (nwritten
== -1) {
4283 reply_nterror(req
, map_nt_error_from_unix(errno
));
4284 error_to_writebrawerr(req
);
4288 if (nwritten
< (ssize_t
)numtowrite
) {
4289 SCVAL(req
->outbuf
,smb_rcls
,ERRHRD
);
4290 SSVAL(req
->outbuf
,smb_err
,ERRdiskfull
);
4294 total_written
+= nwritten
;
4299 SSVAL(req
->outbuf
,smb_vwv0
,total_written
);
4301 status
= sync_file(conn
, fsp
, write_through
);
4302 if (!NT_STATUS_IS_OK(status
)) {
4303 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
4304 fsp_str_dbg(fsp
), nt_errstr(status
)));
4305 reply_nterror(req
, status
);
4306 error_to_writebrawerr(req
);
4310 DEBUG(3,("reply_writebraw: secondart write %s start=%.0f num=%d "
4312 fsp_fnum_dbg(fsp
), (double)startpos
, (int)numtowrite
,
4313 (int)total_written
));
4315 if (!fsp
->print_file
) {
4316 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
4319 /* We won't return a status if write through is not selected - this
4320 * follows what WfWg does */
4321 END_PROFILE(SMBwritebraw
);
4323 if (!write_through
&& total_written
==tcount
) {
4325 #if RABBIT_PELLET_FIX
4327 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
4328 * sending a NBSSkeepalive. Thanks to DaveCB at Sun for this.
4331 if (!send_keepalive(req
->sconn
->sock
)) {
4332 exit_server_cleanly("reply_writebraw: send of "
4333 "keepalive failed");
4336 TALLOC_FREE(req
->outbuf
);
4341 if (!fsp
->print_file
) {
4342 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
4345 END_PROFILE(SMBwritebraw
);
4350 #define DBGC_CLASS DBGC_LOCKING
4352 /****************************************************************************
4353 Reply to a writeunlock (core+).
4354 ****************************************************************************/
4356 void reply_writeunlock(struct smb_request
*req
)
4358 connection_struct
*conn
= req
->conn
;
4359 ssize_t nwritten
= -1;
4363 NTSTATUS status
= NT_STATUS_OK
;
4365 struct lock_struct lock
;
4366 int saved_errno
= 0;
4368 START_PROFILE(SMBwriteunlock
);
4371 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4372 END_PROFILE(SMBwriteunlock
);
4376 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
4378 if (!check_fsp(conn
, req
, fsp
)) {
4379 END_PROFILE(SMBwriteunlock
);
4383 if (!CHECK_WRITE(fsp
)) {
4384 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
4385 END_PROFILE(SMBwriteunlock
);
4389 numtowrite
= SVAL(req
->vwv
+1, 0);
4390 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+2, 0);
4391 data
= (const char *)req
->buf
+ 3;
4393 if (!fsp
->print_file
&& numtowrite
> 0) {
4394 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
4395 (uint64_t)startpos
, (uint64_t)numtowrite
, WRITE_LOCK
,
4398 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
4399 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
4400 END_PROFILE(SMBwriteunlock
);
4405 /* The special X/Open SMB protocol handling of
4406 zero length writes is *NOT* done for
4408 if(numtowrite
== 0) {
4411 nwritten
= write_file(req
,fsp
,data
,startpos
,numtowrite
);
4412 saved_errno
= errno
;
4415 status
= sync_file(conn
, fsp
, False
/* write through */);
4416 if (!NT_STATUS_IS_OK(status
)) {
4417 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
4418 fsp_str_dbg(fsp
), nt_errstr(status
)));
4419 reply_nterror(req
, status
);
4424 reply_nterror(req
, map_nt_error_from_unix(saved_errno
));
4428 if((nwritten
< numtowrite
) && (numtowrite
!= 0)) {
4429 reply_nterror(req
, NT_STATUS_DISK_FULL
);
4433 if (numtowrite
&& !fsp
->print_file
) {
4434 status
= do_unlock(req
->sconn
->msg_ctx
,
4436 (uint64_t)req
->smbpid
,
4437 (uint64_t)numtowrite
,
4441 if (NT_STATUS_V(status
)) {
4442 reply_nterror(req
, status
);
4447 reply_outbuf(req
, 1, 0);
4449 SSVAL(req
->outbuf
,smb_vwv0
,nwritten
);
4451 DEBUG(3, ("writeunlock %s num=%d wrote=%d\n",
4452 fsp_fnum_dbg(fsp
), (int)numtowrite
, (int)nwritten
));
4455 if (numtowrite
&& !fsp
->print_file
) {
4456 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
4459 END_PROFILE(SMBwriteunlock
);
4464 #define DBGC_CLASS DBGC_ALL
4466 /****************************************************************************
4468 ****************************************************************************/
4470 void reply_write(struct smb_request
*req
)
4472 connection_struct
*conn
= req
->conn
;
4474 ssize_t nwritten
= -1;
4478 struct lock_struct lock
;
4480 int saved_errno
= 0;
4482 START_PROFILE(SMBwrite
);
4485 END_PROFILE(SMBwrite
);
4486 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4490 /* If it's an IPC, pass off the pipe handler. */
4492 reply_pipe_write(req
);
4493 END_PROFILE(SMBwrite
);
4497 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
4499 if (!check_fsp(conn
, req
, fsp
)) {
4500 END_PROFILE(SMBwrite
);
4504 if (!CHECK_WRITE(fsp
)) {
4505 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
4506 END_PROFILE(SMBwrite
);
4510 numtowrite
= SVAL(req
->vwv
+1, 0);
4511 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+2, 0);
4512 data
= (const char *)req
->buf
+ 3;
4514 if (!fsp
->print_file
) {
4515 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
4516 (uint64_t)startpos
, (uint64_t)numtowrite
, WRITE_LOCK
,
4519 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
4520 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
4521 END_PROFILE(SMBwrite
);
4527 * X/Open SMB protocol says that if smb_vwv1 is
4528 * zero then the file size should be extended or
4529 * truncated to the size given in smb_vwv[2-3].
4532 if(numtowrite
== 0) {
4534 * This is actually an allocate call, and set EOF. JRA.
4536 nwritten
= vfs_allocate_file_space(fsp
, (off_t
)startpos
);
4538 reply_nterror(req
, NT_STATUS_DISK_FULL
);
4541 nwritten
= vfs_set_filelen(fsp
, (off_t
)startpos
);
4543 reply_nterror(req
, NT_STATUS_DISK_FULL
);
4546 trigger_write_time_update_immediate(fsp
);
4548 nwritten
= write_file(req
,fsp
,data
,startpos
,numtowrite
);
4551 status
= sync_file(conn
, fsp
, False
);
4552 if (!NT_STATUS_IS_OK(status
)) {
4553 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
4554 fsp_str_dbg(fsp
), nt_errstr(status
)));
4555 reply_nterror(req
, status
);
4560 reply_nterror(req
, map_nt_error_from_unix(saved_errno
));
4564 if((nwritten
== 0) && (numtowrite
!= 0)) {
4565 reply_nterror(req
, NT_STATUS_DISK_FULL
);
4569 reply_outbuf(req
, 1, 0);
4571 SSVAL(req
->outbuf
,smb_vwv0
,nwritten
);
4573 if (nwritten
< (ssize_t
)numtowrite
) {
4574 SCVAL(req
->outbuf
,smb_rcls
,ERRHRD
);
4575 SSVAL(req
->outbuf
,smb_err
,ERRdiskfull
);
4578 DEBUG(3, ("write %s num=%d wrote=%d\n", fsp_fnum_dbg(fsp
), (int)numtowrite
, (int)nwritten
));
4581 if (!fsp
->print_file
) {
4582 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
4585 END_PROFILE(SMBwrite
);
4589 /****************************************************************************
4590 Ensure a buffer is a valid writeX for recvfile purposes.
4591 ****************************************************************************/
4593 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
4594 (2*14) + /* word count (including bcc) */ \
4597 bool is_valid_writeX_buffer(struct smbd_server_connection
*sconn
,
4598 const uint8_t *inbuf
)
4601 unsigned int doff
= 0;
4602 size_t len
= smb_len_large(inbuf
);
4604 struct smbXsrv_open
*op
= NULL
;
4605 struct files_struct
*fsp
= NULL
;
4608 if (is_encrypted_packet(sconn
, inbuf
)) {
4609 /* Can't do this on encrypted
4614 if (CVAL(inbuf
,smb_com
) != SMBwriteX
) {
4618 if (CVAL(inbuf
,smb_vwv0
) != 0xFF ||
4619 CVAL(inbuf
,smb_wct
) != 14) {
4620 DEBUG(10,("is_valid_writeX_buffer: chained or "
4621 "invalid word length.\n"));
4625 fnum
= SVAL(inbuf
, smb_vwv2
);
4626 status
= smb1srv_open_lookup(sconn
->conn
,
4630 if (!NT_STATUS_IS_OK(status
)) {
4631 DEBUG(10,("is_valid_writeX_buffer: bad fnum\n"));
4636 DEBUG(10,("is_valid_writeX_buffer: bad fsp\n"));
4639 if (fsp
->conn
== NULL
) {
4640 DEBUG(10,("is_valid_writeX_buffer: bad fsp->conn\n"));
4644 if (IS_IPC(fsp
->conn
)) {
4645 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
4648 if (IS_PRINT(fsp
->conn
)) {
4649 DEBUG(10,("is_valid_writeX_buffer: printing tid\n"));
4652 doff
= SVAL(inbuf
,smb_vwv11
);
4654 numtowrite
= SVAL(inbuf
,smb_vwv10
);
4656 if (len
> doff
&& len
- doff
> 0xFFFF) {
4657 numtowrite
|= (((size_t)SVAL(inbuf
,smb_vwv9
))<<16);
4660 if (numtowrite
== 0) {
4661 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
4665 /* Ensure the sizes match up. */
4666 if (doff
< STANDARD_WRITE_AND_X_HEADER_SIZE
) {
4667 /* no pad byte...old smbclient :-( */
4668 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
4670 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE
));
4674 if (len
- doff
!= numtowrite
) {
4675 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
4676 "len = %u, doff = %u, numtowrite = %u\n",
4679 (unsigned int)numtowrite
));
4683 DEBUG(10,("is_valid_writeX_buffer: true "
4684 "len = %u, doff = %u, numtowrite = %u\n",
4687 (unsigned int)numtowrite
));
4692 /****************************************************************************
4693 Reply to a write and X.
4694 ****************************************************************************/
4696 void reply_write_and_X(struct smb_request
*req
)
4698 connection_struct
*conn
= req
->conn
;
4700 struct lock_struct lock
;
4705 unsigned int smb_doff
;
4706 unsigned int smblen
;
4709 int saved_errno
= 0;
4711 START_PROFILE(SMBwriteX
);
4713 if ((req
->wct
!= 12) && (req
->wct
!= 14)) {
4714 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4718 numtowrite
= SVAL(req
->vwv
+10, 0);
4719 smb_doff
= SVAL(req
->vwv
+11, 0);
4720 smblen
= smb_len(req
->inbuf
);
4722 if (req
->unread_bytes
> 0xFFFF ||
4723 (smblen
> smb_doff
&&
4724 smblen
- smb_doff
> 0xFFFF)) {
4725 numtowrite
|= (((size_t)SVAL(req
->vwv
+9, 0))<<16);
4728 if (req
->unread_bytes
) {
4729 /* Can't do a recvfile write on IPC$ */
4731 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4734 if (numtowrite
!= req
->unread_bytes
) {
4735 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4739 if (smb_doff
> smblen
|| smb_doff
+ numtowrite
< numtowrite
||
4740 smb_doff
+ numtowrite
> smblen
) {
4741 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4746 /* If it's an IPC, pass off the pipe handler. */
4748 if (req
->unread_bytes
) {
4749 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4752 reply_pipe_write_and_X(req
);
4756 fsp
= file_fsp(req
, SVAL(req
->vwv
+2, 0));
4757 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+3, 0);
4758 write_through
= BITSETW(req
->vwv
+7,0);
4760 if (!check_fsp(conn
, req
, fsp
)) {
4764 if (!CHECK_WRITE(fsp
)) {
4765 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
4769 data
= smb_base(req
->inbuf
) + smb_doff
;
4771 if(req
->wct
== 14) {
4773 * This is a large offset (64 bit) write.
4775 startpos
|= (((off_t
)IVAL(req
->vwv
+12, 0)) << 32);
4779 /* X/Open SMB protocol says that, unlike SMBwrite
4780 if the length is zero then NO truncation is
4781 done, just a write of zero. To truncate a file,
4784 if(numtowrite
== 0) {
4787 if (req
->unread_bytes
== 0) {
4788 status
= schedule_aio_write_and_X(conn
,
4795 if (NT_STATUS_IS_OK(status
)) {
4796 /* write scheduled - we're done. */
4799 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
4800 /* Real error - report to client. */
4801 reply_nterror(req
, status
);
4804 /* NT_STATUS_RETRY - fall through to sync write. */
4807 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
4808 (uint64_t)startpos
, (uint64_t)numtowrite
, WRITE_LOCK
,
4811 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
4812 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
4816 nwritten
= write_file(req
,fsp
,data
,startpos
,numtowrite
);
4817 saved_errno
= errno
;
4819 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
4823 reply_nterror(req
, map_nt_error_from_unix(saved_errno
));
4827 if((nwritten
== 0) && (numtowrite
!= 0)) {
4828 reply_nterror(req
, NT_STATUS_DISK_FULL
);
4832 reply_outbuf(req
, 6, 0);
4833 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
4834 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
4835 SSVAL(req
->outbuf
,smb_vwv2
,nwritten
);
4836 SSVAL(req
->outbuf
,smb_vwv4
,nwritten
>>16);
4838 DEBUG(3,("writeX %s num=%d wrote=%d\n",
4839 fsp_fnum_dbg(fsp
), (int)numtowrite
, (int)nwritten
));
4841 status
= sync_file(conn
, fsp
, write_through
);
4842 if (!NT_STATUS_IS_OK(status
)) {
4843 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4844 fsp_str_dbg(fsp
), nt_errstr(status
)));
4845 reply_nterror(req
, status
);
4849 END_PROFILE(SMBwriteX
);
4853 if (req
->unread_bytes
) {
4854 /* writeX failed. drain socket. */
4855 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
4856 req
->unread_bytes
) {
4857 smb_panic("failed to drain pending bytes");
4859 req
->unread_bytes
= 0;
4862 END_PROFILE(SMBwriteX
);
4866 /****************************************************************************
4868 ****************************************************************************/
4870 void reply_lseek(struct smb_request
*req
)
4872 connection_struct
*conn
= req
->conn
;
4878 START_PROFILE(SMBlseek
);
4881 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4882 END_PROFILE(SMBlseek
);
4886 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
4888 if (!check_fsp(conn
, req
, fsp
)) {
4892 flush_write_cache(fsp
, SAMBA_SEEK_FLUSH
);
4894 mode
= SVAL(req
->vwv
+1, 0) & 3;
4895 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4896 startpos
= (off_t
)IVALS(req
->vwv
+2, 0);
4905 res
= fsp
->fh
->pos
+ startpos
;
4916 if (umode
== SEEK_END
) {
4917 if((res
= SMB_VFS_LSEEK(fsp
,startpos
,umode
)) == -1) {
4918 if(errno
== EINVAL
) {
4919 off_t current_pos
= startpos
;
4921 if(fsp_stat(fsp
) == -1) {
4923 map_nt_error_from_unix(errno
));
4924 END_PROFILE(SMBlseek
);
4928 current_pos
+= fsp
->fsp_name
->st
.st_ex_size
;
4930 res
= SMB_VFS_LSEEK(fsp
,0,SEEK_SET
);
4935 reply_nterror(req
, map_nt_error_from_unix(errno
));
4936 END_PROFILE(SMBlseek
);
4943 reply_outbuf(req
, 2, 0);
4944 SIVAL(req
->outbuf
,smb_vwv0
,res
);
4946 DEBUG(3,("lseek %s ofs=%.0f newpos = %.0f mode=%d\n",
4947 fsp_fnum_dbg(fsp
), (double)startpos
, (double)res
, mode
));
4949 END_PROFILE(SMBlseek
);
4953 /****************************************************************************
4955 ****************************************************************************/
4957 void reply_flush(struct smb_request
*req
)
4959 connection_struct
*conn
= req
->conn
;
4963 START_PROFILE(SMBflush
);
4966 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4970 fnum
= SVAL(req
->vwv
+0, 0);
4971 fsp
= file_fsp(req
, fnum
);
4973 if ((fnum
!= 0xFFFF) && !check_fsp(conn
, req
, fsp
)) {
4978 file_sync_all(conn
);
4980 NTSTATUS status
= sync_file(conn
, fsp
, True
);
4981 if (!NT_STATUS_IS_OK(status
)) {
4982 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4983 fsp_str_dbg(fsp
), nt_errstr(status
)));
4984 reply_nterror(req
, status
);
4985 END_PROFILE(SMBflush
);
4990 reply_outbuf(req
, 0, 0);
4992 DEBUG(3,("flush\n"));
4993 END_PROFILE(SMBflush
);
4997 /****************************************************************************
4999 conn POINTER CAN BE NULL HERE !
5000 ****************************************************************************/
5002 void reply_exit(struct smb_request
*req
)
5004 START_PROFILE(SMBexit
);
5006 file_close_pid(req
->sconn
, req
->smbpid
, req
->vuid
);
5008 reply_outbuf(req
, 0, 0);
5010 DEBUG(3,("exit\n"));
5012 END_PROFILE(SMBexit
);
5016 struct reply_close_state
{
5018 struct smb_request
*smbreq
;
5021 static void do_smb1_close(struct tevent_req
*req
);
5023 void reply_close(struct smb_request
*req
)
5025 connection_struct
*conn
= req
->conn
;
5026 NTSTATUS status
= NT_STATUS_OK
;
5027 files_struct
*fsp
= NULL
;
5028 START_PROFILE(SMBclose
);
5031 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5032 END_PROFILE(SMBclose
);
5036 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
5039 * We can only use check_fsp if we know it's not a directory.
5042 if (!check_fsp_open(conn
, req
, fsp
)) {
5043 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5044 END_PROFILE(SMBclose
);
5048 DEBUG(3, ("Close %s fd=%d %s (numopen=%d)\n",
5049 fsp
->is_directory
? "directory" : "file",
5050 fsp
->fh
->fd
, fsp_fnum_dbg(fsp
),
5051 conn
->num_files_open
));
5053 if (!fsp
->is_directory
) {
5057 * Take care of any time sent in the close.
5060 t
= srv_make_unix_date3(req
->vwv
+1);
5061 set_close_write_time(fsp
, convert_time_t_to_timespec(t
));
5064 if (fsp
->num_aio_requests
!= 0) {
5066 struct reply_close_state
*state
;
5068 DEBUG(10, ("closing with aio %u requests pending\n",
5069 fsp
->num_aio_requests
));
5072 * We depend on the aio_extra destructor to take care of this
5073 * close request once fsp->num_aio_request drops to 0.
5076 fsp
->deferred_close
= tevent_wait_send(
5077 fsp
, fsp
->conn
->sconn
->ev_ctx
);
5078 if (fsp
->deferred_close
== NULL
) {
5079 status
= NT_STATUS_NO_MEMORY
;
5083 state
= talloc(fsp
, struct reply_close_state
);
5084 if (state
== NULL
) {
5085 TALLOC_FREE(fsp
->deferred_close
);
5086 status
= NT_STATUS_NO_MEMORY
;
5090 state
->smbreq
= talloc_move(fsp
, &req
);
5091 tevent_req_set_callback(fsp
->deferred_close
, do_smb1_close
,
5093 END_PROFILE(SMBclose
);
5098 * close_file() returns the unix errno if an error was detected on
5099 * close - normally this is due to a disk full error. If not then it
5100 * was probably an I/O error.
5103 status
= close_file(req
, fsp
, NORMAL_CLOSE
);
5105 if (!NT_STATUS_IS_OK(status
)) {
5106 reply_nterror(req
, status
);
5107 END_PROFILE(SMBclose
);
5111 reply_outbuf(req
, 0, 0);
5112 END_PROFILE(SMBclose
);
5116 static void do_smb1_close(struct tevent_req
*req
)
5118 struct reply_close_state
*state
= tevent_req_callback_data(
5119 req
, struct reply_close_state
);
5120 struct smb_request
*smbreq
;
5124 ret
= tevent_wait_recv(req
);
5127 DEBUG(10, ("tevent_wait_recv returned %s\n",
5130 * Continue anyway, this should never happen
5135 * fsp->smb2_close_request right now is a talloc grandchild of
5136 * fsp. When we close_file(fsp), it would go with it. No chance to
5139 smbreq
= talloc_move(talloc_tos(), &state
->smbreq
);
5141 status
= close_file(smbreq
, state
->fsp
, NORMAL_CLOSE
);
5142 if (NT_STATUS_IS_OK(status
)) {
5143 reply_outbuf(smbreq
, 0, 0);
5145 reply_nterror(smbreq
, status
);
5147 if (!srv_send_smb(smbreq
->sconn
,
5148 (char *)smbreq
->outbuf
,
5151 IS_CONN_ENCRYPTED(smbreq
->conn
)||smbreq
->encrypted
,
5153 exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
5156 TALLOC_FREE(smbreq
);
5159 /****************************************************************************
5160 Reply to a writeclose (Core+ protocol).
5161 ****************************************************************************/
5163 void reply_writeclose(struct smb_request
*req
)
5165 connection_struct
*conn
= req
->conn
;
5167 ssize_t nwritten
= -1;
5168 NTSTATUS close_status
= NT_STATUS_OK
;
5171 struct timespec mtime
;
5173 struct lock_struct lock
;
5175 START_PROFILE(SMBwriteclose
);
5178 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5179 END_PROFILE(SMBwriteclose
);
5183 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
5185 if (!check_fsp(conn
, req
, fsp
)) {
5186 END_PROFILE(SMBwriteclose
);
5189 if (!CHECK_WRITE(fsp
)) {
5190 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
5191 END_PROFILE(SMBwriteclose
);
5195 numtowrite
= SVAL(req
->vwv
+1, 0);
5196 startpos
= IVAL_TO_SMB_OFF_T(req
->vwv
+2, 0);
5197 mtime
= convert_time_t_to_timespec(srv_make_unix_date3(req
->vwv
+4));
5198 data
= (const char *)req
->buf
+ 1;
5200 if (fsp
->print_file
== NULL
) {
5201 init_strict_lock_struct(fsp
, (uint64_t)req
->smbpid
,
5202 (uint64_t)startpos
, (uint64_t)numtowrite
, WRITE_LOCK
,
5205 if (!SMB_VFS_STRICT_LOCK(conn
, fsp
, &lock
)) {
5206 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
5207 END_PROFILE(SMBwriteclose
);
5212 nwritten
= write_file(req
,fsp
,data
,startpos
,numtowrite
);
5214 if (fsp
->print_file
== NULL
) {
5215 SMB_VFS_STRICT_UNLOCK(conn
, fsp
, &lock
);
5218 set_close_write_time(fsp
, mtime
);
5221 * More insanity. W2K only closes the file if writelen > 0.
5225 DEBUG(3,("writeclose %s num=%d wrote=%d (numopen=%d)\n",
5226 fsp_fnum_dbg(fsp
), (int)numtowrite
, (int)nwritten
,
5227 (numtowrite
) ? conn
->num_files_open
- 1 : conn
->num_files_open
));
5230 DEBUG(3,("reply_writeclose: zero length write doesn't close "
5231 "file %s\n", fsp_str_dbg(fsp
)));
5232 close_status
= close_file(req
, fsp
, NORMAL_CLOSE
);
5236 if(((nwritten
== 0) && (numtowrite
!= 0))||(nwritten
< 0)) {
5237 reply_nterror(req
, NT_STATUS_DISK_FULL
);
5241 if(!NT_STATUS_IS_OK(close_status
)) {
5242 reply_nterror(req
, close_status
);
5246 reply_outbuf(req
, 1, 0);
5248 SSVAL(req
->outbuf
,smb_vwv0
,nwritten
);
5252 END_PROFILE(SMBwriteclose
);
5257 #define DBGC_CLASS DBGC_LOCKING
5259 /****************************************************************************
5261 ****************************************************************************/
5263 void reply_lock(struct smb_request
*req
)
5265 connection_struct
*conn
= req
->conn
;
5266 uint64_t count
,offset
;
5269 struct byte_range_lock
*br_lck
= NULL
;
5271 START_PROFILE(SMBlock
);
5274 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5275 END_PROFILE(SMBlock
);
5279 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
5281 if (!check_fsp(conn
, req
, fsp
)) {
5282 END_PROFILE(SMBlock
);
5286 count
= (uint64_t)IVAL(req
->vwv
+1, 0);
5287 offset
= (uint64_t)IVAL(req
->vwv
+3, 0);
5289 DEBUG(3,("lock fd=%d %s offset=%.0f count=%.0f\n",
5290 fsp
->fh
->fd
, fsp_fnum_dbg(fsp
), (double)offset
, (double)count
));
5292 br_lck
= do_lock(req
->sconn
->msg_ctx
,
5294 (uint64_t)req
->smbpid
,
5299 False
, /* Non-blocking lock. */
5303 TALLOC_FREE(br_lck
);
5305 if (NT_STATUS_V(status
)) {
5306 reply_nterror(req
, status
);
5307 END_PROFILE(SMBlock
);
5311 reply_outbuf(req
, 0, 0);
5313 END_PROFILE(SMBlock
);
5317 /****************************************************************************
5319 ****************************************************************************/
5321 void reply_unlock(struct smb_request
*req
)
5323 connection_struct
*conn
= req
->conn
;
5324 uint64_t count
,offset
;
5328 START_PROFILE(SMBunlock
);
5331 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5332 END_PROFILE(SMBunlock
);
5336 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
5338 if (!check_fsp(conn
, req
, fsp
)) {
5339 END_PROFILE(SMBunlock
);
5343 count
= (uint64_t)IVAL(req
->vwv
+1, 0);
5344 offset
= (uint64_t)IVAL(req
->vwv
+3, 0);
5346 status
= do_unlock(req
->sconn
->msg_ctx
,
5348 (uint64_t)req
->smbpid
,
5353 if (NT_STATUS_V(status
)) {
5354 reply_nterror(req
, status
);
5355 END_PROFILE(SMBunlock
);
5359 DEBUG( 3, ( "unlock fd=%d %s offset=%.0f count=%.0f\n",
5360 fsp
->fh
->fd
, fsp_fnum_dbg(fsp
), (double)offset
, (double)count
) );
5362 reply_outbuf(req
, 0, 0);
5364 END_PROFILE(SMBunlock
);
5369 #define DBGC_CLASS DBGC_ALL
5371 /****************************************************************************
5373 conn POINTER CAN BE NULL HERE !
5374 ****************************************************************************/
5376 void reply_tdis(struct smb_request
*req
)
5379 connection_struct
*conn
= req
->conn
;
5380 struct smbXsrv_tcon
*tcon
;
5382 START_PROFILE(SMBtdis
);
5385 DEBUG(4,("Invalid connection in tdis\n"));
5386 reply_force_doserror(req
, ERRSRV
, ERRinvnid
);
5387 END_PROFILE(SMBtdis
);
5395 * TODO: cancel all outstanding requests on the tcon
5397 status
= smbXsrv_tcon_disconnect(tcon
, req
->vuid
);
5398 if (!NT_STATUS_IS_OK(status
)) {
5399 DEBUG(0, ("reply_tdis: "
5400 "smbXsrv_tcon_disconnect() failed: %s\n",
5401 nt_errstr(status
)));
5403 * If we hit this case, there is something completely
5404 * wrong, so we better disconnect the transport connection.
5406 END_PROFILE(SMBtdis
);
5407 exit_server(__location__
": smbXsrv_tcon_disconnect failed");
5413 reply_outbuf(req
, 0, 0);
5414 END_PROFILE(SMBtdis
);
5418 /****************************************************************************
5420 conn POINTER CAN BE NULL HERE !
5421 ****************************************************************************/
5423 void reply_echo(struct smb_request
*req
)
5425 connection_struct
*conn
= req
->conn
;
5426 struct smb_perfcount_data local_pcd
;
5427 struct smb_perfcount_data
*cur_pcd
;
5431 START_PROFILE(SMBecho
);
5433 smb_init_perfcount_data(&local_pcd
);
5436 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5437 END_PROFILE(SMBecho
);
5441 smb_reverb
= SVAL(req
->vwv
+0, 0);
5443 reply_outbuf(req
, 1, req
->buflen
);
5445 /* copy any incoming data back out */
5446 if (req
->buflen
> 0) {
5447 memcpy(smb_buf(req
->outbuf
), req
->buf
, req
->buflen
);
5450 if (smb_reverb
> 100) {
5451 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb
));
5455 for (seq_num
= 1 ; seq_num
<= smb_reverb
; seq_num
++) {
5457 /* this makes sure we catch the request pcd */
5458 if (seq_num
== smb_reverb
) {
5459 cur_pcd
= &req
->pcd
;
5461 SMB_PERFCOUNT_COPY_CONTEXT(&req
->pcd
, &local_pcd
);
5462 cur_pcd
= &local_pcd
;
5465 SSVAL(req
->outbuf
,smb_vwv0
,seq_num
);
5467 show_msg((char *)req
->outbuf
);
5468 if (!srv_send_smb(req
->sconn
,
5469 (char *)req
->outbuf
,
5470 true, req
->seqnum
+1,
5471 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
5473 exit_server_cleanly("reply_echo: srv_send_smb failed.");
5476 DEBUG(3,("echo %d times\n", smb_reverb
));
5478 TALLOC_FREE(req
->outbuf
);
5480 END_PROFILE(SMBecho
);
5484 /****************************************************************************
5485 Reply to a printopen.
5486 ****************************************************************************/
5488 void reply_printopen(struct smb_request
*req
)
5490 connection_struct
*conn
= req
->conn
;
5494 START_PROFILE(SMBsplopen
);
5497 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5498 END_PROFILE(SMBsplopen
);
5502 if (!CAN_PRINT(conn
)) {
5503 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
5504 END_PROFILE(SMBsplopen
);
5508 status
= file_new(req
, conn
, &fsp
);
5509 if(!NT_STATUS_IS_OK(status
)) {
5510 reply_nterror(req
, status
);
5511 END_PROFILE(SMBsplopen
);
5515 /* Open for exclusive use, write only. */
5516 status
= print_spool_open(fsp
, NULL
, req
->vuid
);
5518 if (!NT_STATUS_IS_OK(status
)) {
5519 file_free(req
, fsp
);
5520 reply_nterror(req
, status
);
5521 END_PROFILE(SMBsplopen
);
5525 reply_outbuf(req
, 1, 0);
5526 SSVAL(req
->outbuf
,smb_vwv0
,fsp
->fnum
);
5528 DEBUG(3,("openprint fd=%d %s\n",
5529 fsp
->fh
->fd
, fsp_fnum_dbg(fsp
)));
5531 END_PROFILE(SMBsplopen
);
5535 /****************************************************************************
5536 Reply to a printclose.
5537 ****************************************************************************/
5539 void reply_printclose(struct smb_request
*req
)
5541 connection_struct
*conn
= req
->conn
;
5545 START_PROFILE(SMBsplclose
);
5548 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5549 END_PROFILE(SMBsplclose
);
5553 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
5555 if (!check_fsp(conn
, req
, fsp
)) {
5556 END_PROFILE(SMBsplclose
);
5560 if (!CAN_PRINT(conn
)) {
5561 reply_force_doserror(req
, ERRSRV
, ERRerror
);
5562 END_PROFILE(SMBsplclose
);
5566 DEBUG(3,("printclose fd=%d %s\n",
5567 fsp
->fh
->fd
, fsp_fnum_dbg(fsp
)));
5569 status
= close_file(req
, fsp
, NORMAL_CLOSE
);
5571 if(!NT_STATUS_IS_OK(status
)) {
5572 reply_nterror(req
, status
);
5573 END_PROFILE(SMBsplclose
);
5577 reply_outbuf(req
, 0, 0);
5579 END_PROFILE(SMBsplclose
);
5583 /****************************************************************************
5584 Reply to a printqueue.
5585 ****************************************************************************/
5587 void reply_printqueue(struct smb_request
*req
)
5589 connection_struct
*conn
= req
->conn
;
5593 START_PROFILE(SMBsplretq
);
5596 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5597 END_PROFILE(SMBsplretq
);
5601 max_count
= SVAL(req
->vwv
+0, 0);
5602 start_index
= SVAL(req
->vwv
+1, 0);
5604 /* we used to allow the client to get the cnum wrong, but that
5605 is really quite gross and only worked when there was only
5606 one printer - I think we should now only accept it if they
5607 get it right (tridge) */
5608 if (!CAN_PRINT(conn
)) {
5609 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
5610 END_PROFILE(SMBsplretq
);
5614 reply_outbuf(req
, 2, 3);
5615 SSVAL(req
->outbuf
,smb_vwv0
,0);
5616 SSVAL(req
->outbuf
,smb_vwv1
,0);
5617 SCVAL(smb_buf(req
->outbuf
),0,1);
5618 SSVAL(smb_buf(req
->outbuf
),1,0);
5620 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
5621 start_index
, max_count
));
5624 TALLOC_CTX
*mem_ctx
= talloc_tos();
5627 const char *sharename
= lp_servicename(mem_ctx
, SNUM(conn
));
5628 struct rpc_pipe_client
*cli
= NULL
;
5629 struct dcerpc_binding_handle
*b
= NULL
;
5630 struct policy_handle handle
;
5631 struct spoolss_DevmodeContainer devmode_ctr
;
5632 union spoolss_JobInfo
*info
;
5634 uint32_t num_to_get
;
5638 ZERO_STRUCT(handle
);
5640 status
= rpc_pipe_open_interface(conn
,
5643 conn
->sconn
->remote_address
,
5644 conn
->sconn
->msg_ctx
,
5646 if (!NT_STATUS_IS_OK(status
)) {
5647 DEBUG(0, ("reply_printqueue: "
5648 "could not connect to spoolss: %s\n",
5649 nt_errstr(status
)));
5650 reply_nterror(req
, status
);
5653 b
= cli
->binding_handle
;
5655 ZERO_STRUCT(devmode_ctr
);
5657 status
= dcerpc_spoolss_OpenPrinter(b
, mem_ctx
,
5660 SEC_FLAG_MAXIMUM_ALLOWED
,
5663 if (!NT_STATUS_IS_OK(status
)) {
5664 reply_nterror(req
, status
);
5667 if (!W_ERROR_IS_OK(werr
)) {
5668 reply_nterror(req
, werror_to_ntstatus(werr
));
5672 werr
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
5680 if (!W_ERROR_IS_OK(werr
)) {
5681 reply_nterror(req
, werror_to_ntstatus(werr
));
5685 if (max_count
> 0) {
5686 first
= start_index
;
5688 first
= start_index
+ max_count
+ 1;
5691 if (first
>= count
) {
5694 num_to_get
= first
+ MIN(ABS(max_count
), count
- first
);
5697 for (i
= first
; i
< num_to_get
; i
++) {
5700 time_t qtime
= spoolss_Time_to_time_t(&info
[i
].info2
.submitted
);
5702 uint16_t qrapjobid
= pjobid_to_rap(sharename
,
5703 info
[i
].info2
.job_id
);
5705 if (info
[i
].info2
.status
== JOB_STATUS_PRINTING
) {
5711 srv_put_dos_date2(p
, 0, qtime
);
5712 SCVAL(p
, 4, qstatus
);
5713 SSVAL(p
, 5, qrapjobid
);
5714 SIVAL(p
, 7, info
[i
].info2
.size
);
5716 srvstr_push(blob
, req
->flags2
, p
+12,
5717 info
[i
].info2
.notify_name
, 16, STR_ASCII
);
5719 if (message_push_blob(
5722 blob
, sizeof(blob
))) == -1) {
5723 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5729 SSVAL(req
->outbuf
,smb_vwv0
,count
);
5730 SSVAL(req
->outbuf
,smb_vwv1
,
5731 (max_count
>0?first
+count
:first
-1));
5732 SCVAL(smb_buf(req
->outbuf
),0,1);
5733 SSVAL(smb_buf(req
->outbuf
),1,28*count
);
5737 DEBUG(3, ("%u entries returned in queue\n",
5741 if (b
&& is_valid_policy_hnd(&handle
)) {
5742 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &werr
);
5747 END_PROFILE(SMBsplretq
);
5751 /****************************************************************************
5752 Reply to a printwrite.
5753 ****************************************************************************/
5755 void reply_printwrite(struct smb_request
*req
)
5757 connection_struct
*conn
= req
->conn
;
5762 START_PROFILE(SMBsplwr
);
5765 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5766 END_PROFILE(SMBsplwr
);
5770 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
5772 if (!check_fsp(conn
, req
, fsp
)) {
5773 END_PROFILE(SMBsplwr
);
5777 if (!fsp
->print_file
) {
5778 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
5779 END_PROFILE(SMBsplwr
);
5783 if (!CHECK_WRITE(fsp
)) {
5784 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
5785 END_PROFILE(SMBsplwr
);
5789 numtowrite
= SVAL(req
->buf
, 1);
5791 if (req
->buflen
< numtowrite
+ 3) {
5792 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5793 END_PROFILE(SMBsplwr
);
5797 data
= (const char *)req
->buf
+ 3;
5799 if (write_file(req
,fsp
,data
,(off_t
)-1,numtowrite
) != numtowrite
) {
5800 reply_nterror(req
, map_nt_error_from_unix(errno
));
5801 END_PROFILE(SMBsplwr
);
5805 DEBUG(3, ("printwrite %s num=%d\n", fsp_fnum_dbg(fsp
), numtowrite
));
5807 END_PROFILE(SMBsplwr
);
5811 /****************************************************************************
5813 ****************************************************************************/
5815 void reply_mkdir(struct smb_request
*req
)
5817 connection_struct
*conn
= req
->conn
;
5818 struct smb_filename
*smb_dname
= NULL
;
5819 char *directory
= NULL
;
5821 TALLOC_CTX
*ctx
= talloc_tos();
5823 START_PROFILE(SMBmkdir
);
5825 srvstr_get_path_req(ctx
, req
, &directory
, (const char *)req
->buf
+ 1,
5826 STR_TERMINATE
, &status
);
5827 if (!NT_STATUS_IS_OK(status
)) {
5828 reply_nterror(req
, status
);
5832 status
= filename_convert(ctx
, conn
,
5833 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5835 UCF_PREP_CREATEFILE
,
5838 if (!NT_STATUS_IS_OK(status
)) {
5839 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5840 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
5841 ERRSRV
, ERRbadpath
);
5844 reply_nterror(req
, status
);
5848 status
= create_directory(conn
, req
, smb_dname
);
5850 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status
)));
5852 if (!NT_STATUS_IS_OK(status
)) {
5854 if (!use_nt_status()
5855 && NT_STATUS_EQUAL(status
,
5856 NT_STATUS_OBJECT_NAME_COLLISION
)) {
5858 * Yes, in the DOS error code case we get a
5859 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
5860 * samba4 torture test.
5862 status
= NT_STATUS_DOS(ERRDOS
, ERRnoaccess
);
5865 reply_nterror(req
, status
);
5869 reply_outbuf(req
, 0, 0);
5871 DEBUG(3, ("mkdir %s\n", smb_dname
->base_name
));
5873 TALLOC_FREE(smb_dname
);
5874 END_PROFILE(SMBmkdir
);
5878 /****************************************************************************
5880 ****************************************************************************/
5882 void reply_rmdir(struct smb_request
*req
)
5884 connection_struct
*conn
= req
->conn
;
5885 struct smb_filename
*smb_dname
= NULL
;
5886 char *directory
= NULL
;
5888 TALLOC_CTX
*ctx
= talloc_tos();
5889 files_struct
*fsp
= NULL
;
5891 struct smbd_server_connection
*sconn
= req
->sconn
;
5893 START_PROFILE(SMBrmdir
);
5895 srvstr_get_path_req(ctx
, req
, &directory
, (const char *)req
->buf
+ 1,
5896 STR_TERMINATE
, &status
);
5897 if (!NT_STATUS_IS_OK(status
)) {
5898 reply_nterror(req
, status
);
5902 status
= filename_convert(ctx
, conn
,
5903 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5908 if (!NT_STATUS_IS_OK(status
)) {
5909 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5910 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
5911 ERRSRV
, ERRbadpath
);
5914 reply_nterror(req
, status
);
5918 if (is_ntfs_stream_smb_fname(smb_dname
)) {
5919 reply_nterror(req
, NT_STATUS_NOT_A_DIRECTORY
);
5923 status
= SMB_VFS_CREATE_FILE(
5926 0, /* root_dir_fid */
5927 smb_dname
, /* fname */
5928 DELETE_ACCESS
, /* access_mask */
5929 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5931 FILE_OPEN
, /* create_disposition*/
5932 FILE_DIRECTORY_FILE
, /* create_options */
5933 FILE_ATTRIBUTE_DIRECTORY
, /* file_attributes */
5934 0, /* oplock_request */
5935 0, /* allocation_size */
5936 0, /* private_flags */
5942 if (!NT_STATUS_IS_OK(status
)) {
5943 if (open_was_deferred(req
->sconn
, req
->mid
)) {
5944 /* We have re-scheduled this call. */
5947 reply_nterror(req
, status
);
5951 status
= can_set_delete_on_close(fsp
, FILE_ATTRIBUTE_DIRECTORY
);
5952 if (!NT_STATUS_IS_OK(status
)) {
5953 close_file(req
, fsp
, ERROR_CLOSE
);
5954 reply_nterror(req
, status
);
5958 if (!set_delete_on_close(fsp
, true,
5959 conn
->session_info
->security_token
,
5960 conn
->session_info
->unix_token
)) {
5961 close_file(req
, fsp
, ERROR_CLOSE
);
5962 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
5966 status
= close_file(req
, fsp
, NORMAL_CLOSE
);
5967 if (!NT_STATUS_IS_OK(status
)) {
5968 reply_nterror(req
, status
);
5970 reply_outbuf(req
, 0, 0);
5973 dptr_closepath(sconn
, smb_dname
->base_name
, req
->smbpid
);
5975 DEBUG(3, ("rmdir %s\n", smb_fname_str_dbg(smb_dname
)));
5977 TALLOC_FREE(smb_dname
);
5978 END_PROFILE(SMBrmdir
);
5982 /*******************************************************************
5983 Resolve wildcards in a filename rename.
5984 ********************************************************************/
5986 static bool resolve_wildcards(TALLOC_CTX
*ctx
,
5991 char *name2_copy
= NULL
;
5996 char *p
,*p2
, *pname1
, *pname2
;
5998 name2_copy
= talloc_strdup(ctx
, name2
);
6003 pname1
= strrchr_m(name1
,'/');
6004 pname2
= strrchr_m(name2_copy
,'/');
6006 if (!pname1
|| !pname2
) {
6010 /* Truncate the copy of name2 at the last '/' */
6013 /* Now go past the '/' */
6017 root1
= talloc_strdup(ctx
, pname1
);
6018 root2
= talloc_strdup(ctx
, pname2
);
6020 if (!root1
|| !root2
) {
6024 p
= strrchr_m(root1
,'.');
6027 ext1
= talloc_strdup(ctx
, p
+1);
6029 ext1
= talloc_strdup(ctx
, "");
6031 p
= strrchr_m(root2
,'.');
6034 ext2
= talloc_strdup(ctx
, p
+1);
6036 ext2
= talloc_strdup(ctx
, "");
6039 if (!ext1
|| !ext2
) {
6047 /* Hmmm. Should this be mb-aware ? */
6050 } else if (*p2
== '*') {
6052 root2
= talloc_asprintf(ctx
, "%s%s",
6071 /* Hmmm. Should this be mb-aware ? */
6074 } else if (*p2
== '*') {
6076 ext2
= talloc_asprintf(ctx
, "%s%s",
6092 *pp_newname
= talloc_asprintf(ctx
, "%s/%s.%s",
6097 *pp_newname
= talloc_asprintf(ctx
, "%s/%s",
6109 /****************************************************************************
6110 Ensure open files have their names updated. Updated to notify other smbd's
6112 ****************************************************************************/
6114 static void rename_open_files(connection_struct
*conn
,
6115 struct share_mode_lock
*lck
,
6117 uint32_t orig_name_hash
,
6118 const struct smb_filename
*smb_fname_dst
)
6121 bool did_rename
= False
;
6123 uint32_t new_name_hash
= 0;
6125 for(fsp
= file_find_di_first(conn
->sconn
, id
); fsp
;
6126 fsp
= file_find_di_next(fsp
)) {
6127 /* fsp_name is a relative path under the fsp. To change this for other
6128 sharepaths we need to manipulate relative paths. */
6129 /* TODO - create the absolute path and manipulate the newname
6130 relative to the sharepath. */
6131 if (!strequal(fsp
->conn
->connectpath
, conn
->connectpath
)) {
6134 if (fsp
->name_hash
!= orig_name_hash
) {
6137 DEBUG(10, ("rename_open_files: renaming file %s "
6138 "(file_id %s) from %s -> %s\n", fsp_fnum_dbg(fsp
),
6139 file_id_string_tos(&fsp
->file_id
), fsp_str_dbg(fsp
),
6140 smb_fname_str_dbg(smb_fname_dst
)));
6142 status
= fsp_set_smb_fname(fsp
, smb_fname_dst
);
6143 if (NT_STATUS_IS_OK(status
)) {
6145 new_name_hash
= fsp
->name_hash
;
6150 DEBUG(10, ("rename_open_files: no open files on file_id %s "
6151 "for %s\n", file_id_string_tos(&id
),
6152 smb_fname_str_dbg(smb_fname_dst
)));
6155 /* Send messages to all smbd's (not ourself) that the name has changed. */
6156 rename_share_filename(conn
->sconn
->msg_ctx
, lck
, id
, conn
->connectpath
,
6157 orig_name_hash
, new_name_hash
,
6162 /****************************************************************************
6163 We need to check if the source path is a parent directory of the destination
6164 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
6165 refuse the rename with a sharing violation. Under UNIX the above call can
6166 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
6167 probably need to check that the client is a Windows one before disallowing
6168 this as a UNIX client (one with UNIX extensions) can know the source is a
6169 symlink and make this decision intelligently. Found by an excellent bug
6170 report from <AndyLiebman@aol.com>.
6171 ****************************************************************************/
6173 static bool rename_path_prefix_equal(const struct smb_filename
*smb_fname_src
,
6174 const struct smb_filename
*smb_fname_dst
)
6176 const char *psrc
= smb_fname_src
->base_name
;
6177 const char *pdst
= smb_fname_dst
->base_name
;
6180 if (psrc
[0] == '.' && psrc
[1] == '/') {
6183 if (pdst
[0] == '.' && pdst
[1] == '/') {
6186 if ((slen
= strlen(psrc
)) > strlen(pdst
)) {
6189 return ((memcmp(psrc
, pdst
, slen
) == 0) && pdst
[slen
] == '/');
6193 * Do the notify calls from a rename
6196 static void notify_rename(connection_struct
*conn
, bool is_dir
,
6197 const struct smb_filename
*smb_fname_src
,
6198 const struct smb_filename
*smb_fname_dst
)
6200 char *parent_dir_src
= NULL
;
6201 char *parent_dir_dst
= NULL
;
6204 mask
= is_dir
? FILE_NOTIFY_CHANGE_DIR_NAME
6205 : FILE_NOTIFY_CHANGE_FILE_NAME
;
6207 if (!parent_dirname(talloc_tos(), smb_fname_src
->base_name
,
6208 &parent_dir_src
, NULL
) ||
6209 !parent_dirname(talloc_tos(), smb_fname_dst
->base_name
,
6210 &parent_dir_dst
, NULL
)) {
6214 if (strcmp(parent_dir_src
, parent_dir_dst
) == 0) {
6215 notify_fname(conn
, NOTIFY_ACTION_OLD_NAME
, mask
,
6216 smb_fname_src
->base_name
);
6217 notify_fname(conn
, NOTIFY_ACTION_NEW_NAME
, mask
,
6218 smb_fname_dst
->base_name
);
6221 notify_fname(conn
, NOTIFY_ACTION_REMOVED
, mask
,
6222 smb_fname_src
->base_name
);
6223 notify_fname(conn
, NOTIFY_ACTION_ADDED
, mask
,
6224 smb_fname_dst
->base_name
);
6227 /* this is a strange one. w2k3 gives an additional event for
6228 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
6229 files, but not directories */
6231 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
6232 FILE_NOTIFY_CHANGE_ATTRIBUTES
6233 |FILE_NOTIFY_CHANGE_CREATION
,
6234 smb_fname_dst
->base_name
);
6237 TALLOC_FREE(parent_dir_src
);
6238 TALLOC_FREE(parent_dir_dst
);
6241 /****************************************************************************
6242 Returns an error if the parent directory for a filename is open in an
6244 ****************************************************************************/
6246 static NTSTATUS
parent_dirname_compatible_open(connection_struct
*conn
,
6247 const struct smb_filename
*smb_fname_dst_in
)
6249 char *parent_dir
= NULL
;
6250 struct smb_filename smb_fname_parent
;
6252 files_struct
*fsp
= NULL
;
6255 if (!parent_dirname(talloc_tos(), smb_fname_dst_in
->base_name
,
6256 &parent_dir
, NULL
)) {
6257 return NT_STATUS_NO_MEMORY
;
6259 ZERO_STRUCT(smb_fname_parent
);
6260 smb_fname_parent
.base_name
= parent_dir
;
6262 ret
= SMB_VFS_LSTAT(conn
, &smb_fname_parent
);
6264 return map_nt_error_from_unix(errno
);
6268 * We're only checking on this smbd here, mostly good
6269 * enough.. and will pass tests.
6272 id
= vfs_file_id_from_sbuf(conn
, &smb_fname_parent
.st
);
6273 for (fsp
= file_find_di_first(conn
->sconn
, id
); fsp
;
6274 fsp
= file_find_di_next(fsp
)) {
6275 if (fsp
->access_mask
& DELETE_ACCESS
) {
6276 return NT_STATUS_SHARING_VIOLATION
;
6279 return NT_STATUS_OK
;
6282 /****************************************************************************
6283 Rename an open file - given an fsp.
6284 ****************************************************************************/
6286 NTSTATUS
rename_internals_fsp(connection_struct
*conn
,
6288 const struct smb_filename
*smb_fname_dst_in
,
6290 bool replace_if_exists
)
6292 TALLOC_CTX
*ctx
= talloc_tos();
6293 struct smb_filename
*smb_fname_dst
= NULL
;
6294 NTSTATUS status
= NT_STATUS_OK
;
6295 struct share_mode_lock
*lck
= NULL
;
6296 bool dst_exists
, old_is_stream
, new_is_stream
;
6298 status
= check_name(conn
, smb_fname_dst_in
->base_name
);
6299 if (!NT_STATUS_IS_OK(status
)) {
6303 status
= parent_dirname_compatible_open(conn
, smb_fname_dst_in
);
6304 if (!NT_STATUS_IS_OK(status
)) {
6308 /* Make a copy of the dst smb_fname structs */
6310 smb_fname_dst
= cp_smb_filename(ctx
, smb_fname_dst_in
);
6311 if (smb_fname_dst
== NULL
) {
6312 status
= NT_STATUS_NO_MEMORY
;
6317 * Check for special case with case preserving and not
6318 * case sensitive. If the old last component differs from the original
6319 * last component only by case, then we should allow
6320 * the rename (user is trying to change the case of the
6323 if((conn
->case_sensitive
== False
) && (conn
->case_preserve
== True
) &&
6324 strequal(fsp
->fsp_name
->base_name
, smb_fname_dst
->base_name
) &&
6325 strequal(fsp
->fsp_name
->stream_name
, smb_fname_dst
->stream_name
)) {
6327 char *fname_dst_lcomp_base_mod
= NULL
;
6328 struct smb_filename
*smb_fname_orig_lcomp
= NULL
;
6331 * Get the last component of the destination name.
6333 last_slash
= strrchr_m(smb_fname_dst
->base_name
, '/');
6335 fname_dst_lcomp_base_mod
= talloc_strdup(ctx
, last_slash
+ 1);
6337 fname_dst_lcomp_base_mod
= talloc_strdup(ctx
, smb_fname_dst
->base_name
);
6339 if (!fname_dst_lcomp_base_mod
) {
6340 status
= NT_STATUS_NO_MEMORY
;
6345 * Create an smb_filename struct using the original last
6346 * component of the destination.
6348 smb_fname_orig_lcomp
= synthetic_smb_fname_split(
6349 ctx
, smb_fname_dst
->original_lcomp
, NULL
);
6350 if (smb_fname_orig_lcomp
== NULL
) {
6351 status
= NT_STATUS_NO_MEMORY
;
6352 TALLOC_FREE(fname_dst_lcomp_base_mod
);
6356 /* If the base names only differ by case, use original. */
6357 if(!strcsequal(fname_dst_lcomp_base_mod
,
6358 smb_fname_orig_lcomp
->base_name
)) {
6361 * Replace the modified last component with the
6365 *last_slash
= '\0'; /* Truncate at the '/' */
6366 tmp
= talloc_asprintf(smb_fname_dst
,
6368 smb_fname_dst
->base_name
,
6369 smb_fname_orig_lcomp
->base_name
);
6371 tmp
= talloc_asprintf(smb_fname_dst
,
6373 smb_fname_orig_lcomp
->base_name
);
6376 status
= NT_STATUS_NO_MEMORY
;
6377 TALLOC_FREE(fname_dst_lcomp_base_mod
);
6378 TALLOC_FREE(smb_fname_orig_lcomp
);
6381 TALLOC_FREE(smb_fname_dst
->base_name
);
6382 smb_fname_dst
->base_name
= tmp
;
6385 /* If the stream_names only differ by case, use original. */
6386 if(!strcsequal(smb_fname_dst
->stream_name
,
6387 smb_fname_orig_lcomp
->stream_name
)) {
6389 /* Use the original stream. */
6390 tmp
= talloc_strdup(smb_fname_dst
,
6391 smb_fname_orig_lcomp
->stream_name
);
6393 status
= NT_STATUS_NO_MEMORY
;
6394 TALLOC_FREE(fname_dst_lcomp_base_mod
);
6395 TALLOC_FREE(smb_fname_orig_lcomp
);
6398 TALLOC_FREE(smb_fname_dst
->stream_name
);
6399 smb_fname_dst
->stream_name
= tmp
;
6401 TALLOC_FREE(fname_dst_lcomp_base_mod
);
6402 TALLOC_FREE(smb_fname_orig_lcomp
);
6406 * If the src and dest names are identical - including case,
6407 * don't do the rename, just return success.
6410 if (strcsequal(fsp
->fsp_name
->base_name
, smb_fname_dst
->base_name
) &&
6411 strcsequal(fsp
->fsp_name
->stream_name
,
6412 smb_fname_dst
->stream_name
)) {
6413 DEBUG(3, ("rename_internals_fsp: identical names in rename %s "
6414 "- returning success\n",
6415 smb_fname_str_dbg(smb_fname_dst
)));
6416 status
= NT_STATUS_OK
;
6420 old_is_stream
= is_ntfs_stream_smb_fname(fsp
->fsp_name
);
6421 new_is_stream
= is_ntfs_stream_smb_fname(smb_fname_dst
);
6423 /* Return the correct error code if both names aren't streams. */
6424 if (!old_is_stream
&& new_is_stream
) {
6425 status
= NT_STATUS_OBJECT_NAME_INVALID
;
6429 if (old_is_stream
&& !new_is_stream
) {
6430 status
= NT_STATUS_INVALID_PARAMETER
;
6434 dst_exists
= SMB_VFS_STAT(conn
, smb_fname_dst
) == 0;
6436 if(!replace_if_exists
&& dst_exists
) {
6437 DEBUG(3, ("rename_internals_fsp: dest exists doing rename "
6438 "%s -> %s\n", smb_fname_str_dbg(fsp
->fsp_name
),
6439 smb_fname_str_dbg(smb_fname_dst
)));
6440 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
6445 struct file_id fileid
= vfs_file_id_from_sbuf(conn
,
6446 &smb_fname_dst
->st
);
6447 files_struct
*dst_fsp
= file_find_di_first(conn
->sconn
,
6449 /* The file can be open when renaming a stream */
6450 if (dst_fsp
&& !new_is_stream
) {
6451 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
6452 status
= NT_STATUS_ACCESS_DENIED
;
6457 /* Ensure we have a valid stat struct for the source. */
6458 status
= vfs_stat_fsp(fsp
);
6459 if (!NT_STATUS_IS_OK(status
)) {
6463 status
= can_rename(conn
, fsp
, attrs
);
6465 if (!NT_STATUS_IS_OK(status
)) {
6466 DEBUG(3, ("rename_internals_fsp: Error %s rename %s -> %s\n",
6467 nt_errstr(status
), smb_fname_str_dbg(fsp
->fsp_name
),
6468 smb_fname_str_dbg(smb_fname_dst
)));
6469 if (NT_STATUS_EQUAL(status
,NT_STATUS_SHARING_VIOLATION
))
6470 status
= NT_STATUS_ACCESS_DENIED
;
6474 if (rename_path_prefix_equal(fsp
->fsp_name
, smb_fname_dst
)) {
6475 status
= NT_STATUS_ACCESS_DENIED
;
6478 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
6481 * We have the file open ourselves, so not being able to get the
6482 * corresponding share mode lock is a fatal error.
6485 SMB_ASSERT(lck
!= NULL
);
6487 if(SMB_VFS_RENAME(conn
, fsp
->fsp_name
, smb_fname_dst
) == 0) {
6488 uint32 create_options
= fsp
->fh
->private_options
;
6490 DEBUG(3, ("rename_internals_fsp: succeeded doing rename on "
6491 "%s -> %s\n", smb_fname_str_dbg(fsp
->fsp_name
),
6492 smb_fname_str_dbg(smb_fname_dst
)));
6494 if (!fsp
->is_directory
&&
6495 !lp_posix_pathnames() &&
6496 (lp_map_archive(SNUM(conn
)) ||
6497 lp_store_dos_attributes(SNUM(conn
)))) {
6498 /* We must set the archive bit on the newly
6500 if (SMB_VFS_STAT(conn
, smb_fname_dst
) == 0) {
6501 uint32_t old_dosmode
= dos_mode(conn
,
6503 file_set_dosmode(conn
,
6505 old_dosmode
| FILE_ATTRIBUTE_ARCHIVE
,
6511 notify_rename(conn
, fsp
->is_directory
, fsp
->fsp_name
,
6514 rename_open_files(conn
, lck
, fsp
->file_id
, fsp
->name_hash
,
6518 * A rename acts as a new file create w.r.t. allowing an initial delete
6519 * on close, probably because in Windows there is a new handle to the
6520 * new file. If initial delete on close was requested but not
6521 * originally set, we need to set it here. This is probably not 100% correct,
6522 * but will work for the CIFSFS client which in non-posix mode
6523 * depends on these semantics. JRA.
6526 if (create_options
& FILE_DELETE_ON_CLOSE
) {
6527 status
= can_set_delete_on_close(fsp
, 0);
6529 if (NT_STATUS_IS_OK(status
)) {
6530 /* Note that here we set the *inital* delete on close flag,
6531 * not the regular one. The magic gets handled in close. */
6532 fsp
->initial_delete_on_close
= True
;
6536 status
= NT_STATUS_OK
;
6542 if (errno
== ENOTDIR
|| errno
== EISDIR
) {
6543 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
6545 status
= map_nt_error_from_unix(errno
);
6548 DEBUG(3, ("rename_internals_fsp: Error %s rename %s -> %s\n",
6549 nt_errstr(status
), smb_fname_str_dbg(fsp
->fsp_name
),
6550 smb_fname_str_dbg(smb_fname_dst
)));
6553 TALLOC_FREE(smb_fname_dst
);
6558 /****************************************************************************
6559 The guts of the rename command, split out so it may be called by the NT SMB
6561 ****************************************************************************/
6563 NTSTATUS
rename_internals(TALLOC_CTX
*ctx
,
6564 connection_struct
*conn
,
6565 struct smb_request
*req
,
6566 struct smb_filename
*smb_fname_src
,
6567 struct smb_filename
*smb_fname_dst
,
6569 bool replace_if_exists
,
6572 uint32_t access_mask
)
6574 char *fname_src_dir
= NULL
;
6575 char *fname_src_mask
= NULL
;
6577 NTSTATUS status
= NT_STATUS_OK
;
6578 struct smb_Dir
*dir_hnd
= NULL
;
6579 const char *dname
= NULL
;
6580 char *talloced
= NULL
;
6582 int create_options
= 0;
6583 bool posix_pathnames
= lp_posix_pathnames();
6587 * Split the old name into directory and last component
6588 * strings. Note that unix_convert may have stripped off a
6589 * leading ./ from both name and newname if the rename is
6590 * at the root of the share. We need to make sure either both
6591 * name and newname contain a / character or neither of them do
6592 * as this is checked in resolve_wildcards().
6595 /* Split up the directory from the filename/mask. */
6596 status
= split_fname_dir_mask(ctx
, smb_fname_src
->base_name
,
6597 &fname_src_dir
, &fname_src_mask
);
6598 if (!NT_STATUS_IS_OK(status
)) {
6599 status
= NT_STATUS_NO_MEMORY
;
6604 * We should only check the mangled cache
6605 * here if unix_convert failed. This means
6606 * that the path in 'mask' doesn't exist
6607 * on the file system and so we need to look
6608 * for a possible mangle. This patch from
6609 * Tine Smukavec <valentin.smukavec@hermes.si>.
6612 if (!VALID_STAT(smb_fname_src
->st
) &&
6613 mangle_is_mangled(fname_src_mask
, conn
->params
)) {
6614 char *new_mask
= NULL
;
6615 mangle_lookup_name_from_8_3(ctx
, fname_src_mask
, &new_mask
,
6618 TALLOC_FREE(fname_src_mask
);
6619 fname_src_mask
= new_mask
;
6623 if (!src_has_wild
) {
6627 * Only one file needs to be renamed. Append the mask back
6628 * onto the directory.
6630 TALLOC_FREE(smb_fname_src
->base_name
);
6631 if (ISDOT(fname_src_dir
)) {
6632 /* Ensure we use canonical names on open. */
6633 smb_fname_src
->base_name
= talloc_asprintf(smb_fname_src
,
6637 smb_fname_src
->base_name
= talloc_asprintf(smb_fname_src
,
6642 if (!smb_fname_src
->base_name
) {
6643 status
= NT_STATUS_NO_MEMORY
;
6647 DEBUG(3, ("rename_internals: case_sensitive = %d, "
6648 "case_preserve = %d, short case preserve = %d, "
6649 "directory = %s, newname = %s, "
6650 "last_component_dest = %s\n",
6651 conn
->case_sensitive
, conn
->case_preserve
,
6652 conn
->short_case_preserve
,
6653 smb_fname_str_dbg(smb_fname_src
),
6654 smb_fname_str_dbg(smb_fname_dst
),
6655 smb_fname_dst
->original_lcomp
));
6657 /* The dest name still may have wildcards. */
6658 if (dest_has_wild
) {
6659 char *fname_dst_mod
= NULL
;
6660 if (!resolve_wildcards(smb_fname_dst
,
6661 smb_fname_src
->base_name
,
6662 smb_fname_dst
->base_name
,
6664 DEBUG(6, ("rename_internals: resolve_wildcards "
6666 smb_fname_src
->base_name
,
6667 smb_fname_dst
->base_name
));
6668 status
= NT_STATUS_NO_MEMORY
;
6671 TALLOC_FREE(smb_fname_dst
->base_name
);
6672 smb_fname_dst
->base_name
= fname_dst_mod
;
6675 ZERO_STRUCT(smb_fname_src
->st
);
6676 if (posix_pathnames
) {
6677 rc
= SMB_VFS_LSTAT(conn
, smb_fname_src
);
6679 rc
= SMB_VFS_STAT(conn
, smb_fname_src
);
6682 status
= map_nt_error_from_unix_common(errno
);
6686 if (S_ISDIR(smb_fname_src
->st
.st_ex_mode
)) {
6687 create_options
|= FILE_DIRECTORY_FILE
;
6690 status
= SMB_VFS_CREATE_FILE(
6693 0, /* root_dir_fid */
6694 smb_fname_src
, /* fname */
6695 access_mask
, /* access_mask */
6696 (FILE_SHARE_READ
| /* share_access */
6698 FILE_OPEN
, /* create_disposition*/
6699 create_options
, /* create_options */
6700 posix_pathnames
? FILE_FLAG_POSIX_SEMANTICS
|0777 : 0, /* file_attributes */
6701 0, /* oplock_request */
6702 0, /* allocation_size */
6703 0, /* private_flags */
6709 if (!NT_STATUS_IS_OK(status
)) {
6710 DEBUG(3, ("Could not open rename source %s: %s\n",
6711 smb_fname_str_dbg(smb_fname_src
),
6712 nt_errstr(status
)));
6716 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6717 attrs
, replace_if_exists
);
6719 close_file(req
, fsp
, NORMAL_CLOSE
);
6721 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
6722 nt_errstr(status
), smb_fname_str_dbg(smb_fname_src
),
6723 smb_fname_str_dbg(smb_fname_dst
)));
6729 * Wildcards - process each file that matches.
6731 if (strequal(fname_src_mask
, "????????.???")) {
6732 TALLOC_FREE(fname_src_mask
);
6733 fname_src_mask
= talloc_strdup(ctx
, "*");
6734 if (!fname_src_mask
) {
6735 status
= NT_STATUS_NO_MEMORY
;
6740 status
= check_name(conn
, fname_src_dir
);
6741 if (!NT_STATUS_IS_OK(status
)) {
6745 dir_hnd
= OpenDir(talloc_tos(), conn
, fname_src_dir
, fname_src_mask
,
6747 if (dir_hnd
== NULL
) {
6748 status
= map_nt_error_from_unix(errno
);
6752 status
= NT_STATUS_NO_SUCH_FILE
;
6754 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6755 * - gentest fix. JRA
6758 while ((dname
= ReadDirName(dir_hnd
, &offset
, &smb_fname_src
->st
,
6760 files_struct
*fsp
= NULL
;
6761 char *destname
= NULL
;
6762 bool sysdir_entry
= False
;
6764 /* Quick check for "." and ".." */
6765 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
6766 if (attrs
& FILE_ATTRIBUTE_DIRECTORY
) {
6767 sysdir_entry
= True
;
6769 TALLOC_FREE(talloced
);
6774 if (!is_visible_file(conn
, fname_src_dir
, dname
,
6775 &smb_fname_src
->st
, false)) {
6776 TALLOC_FREE(talloced
);
6780 if(!mask_match(dname
, fname_src_mask
, conn
->case_sensitive
)) {
6781 TALLOC_FREE(talloced
);
6786 status
= NT_STATUS_OBJECT_NAME_INVALID
;
6790 TALLOC_FREE(smb_fname_src
->base_name
);
6791 if (ISDOT(fname_src_dir
)) {
6792 /* Ensure we use canonical names on open. */
6793 smb_fname_src
->base_name
= talloc_asprintf(smb_fname_src
,
6797 smb_fname_src
->base_name
= talloc_asprintf(smb_fname_src
,
6802 if (!smb_fname_src
->base_name
) {
6803 status
= NT_STATUS_NO_MEMORY
;
6807 if (!resolve_wildcards(ctx
, smb_fname_src
->base_name
,
6808 smb_fname_dst
->base_name
,
6810 DEBUG(6, ("resolve_wildcards %s %s failed\n",
6811 smb_fname_src
->base_name
, destname
));
6812 TALLOC_FREE(talloced
);
6816 status
= NT_STATUS_NO_MEMORY
;
6820 TALLOC_FREE(smb_fname_dst
->base_name
);
6821 smb_fname_dst
->base_name
= destname
;
6823 ZERO_STRUCT(smb_fname_src
->st
);
6824 if (posix_pathnames
) {
6825 SMB_VFS_LSTAT(conn
, smb_fname_src
);
6827 SMB_VFS_STAT(conn
, smb_fname_src
);
6832 if (S_ISDIR(smb_fname_src
->st
.st_ex_mode
)) {
6833 create_options
|= FILE_DIRECTORY_FILE
;
6836 status
= SMB_VFS_CREATE_FILE(
6839 0, /* root_dir_fid */
6840 smb_fname_src
, /* fname */
6841 access_mask
, /* access_mask */
6842 (FILE_SHARE_READ
| /* share_access */
6844 FILE_OPEN
, /* create_disposition*/
6845 create_options
, /* create_options */
6846 posix_pathnames
? FILE_FLAG_POSIX_SEMANTICS
|0777 : 0, /* file_attributes */
6847 0, /* oplock_request */
6848 0, /* allocation_size */
6849 0, /* private_flags */
6855 if (!NT_STATUS_IS_OK(status
)) {
6856 DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE "
6857 "returned %s rename %s -> %s\n",
6859 smb_fname_str_dbg(smb_fname_src
),
6860 smb_fname_str_dbg(smb_fname_dst
)));
6864 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6866 if (!smb_fname_dst
->original_lcomp
) {
6867 status
= NT_STATUS_NO_MEMORY
;
6871 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6872 attrs
, replace_if_exists
);
6874 close_file(req
, fsp
, NORMAL_CLOSE
);
6876 if (!NT_STATUS_IS_OK(status
)) {
6877 DEBUG(3, ("rename_internals_fsp returned %s for "
6878 "rename %s -> %s\n", nt_errstr(status
),
6879 smb_fname_str_dbg(smb_fname_src
),
6880 smb_fname_str_dbg(smb_fname_dst
)));
6886 DEBUG(3,("rename_internals: doing rename on %s -> "
6887 "%s\n", smb_fname_str_dbg(smb_fname_src
),
6888 smb_fname_str_dbg(smb_fname_src
)));
6889 TALLOC_FREE(talloced
);
6891 TALLOC_FREE(dir_hnd
);
6893 if (count
== 0 && NT_STATUS_IS_OK(status
) && errno
!= 0) {
6894 status
= map_nt_error_from_unix(errno
);
6898 TALLOC_FREE(talloced
);
6899 TALLOC_FREE(fname_src_dir
);
6900 TALLOC_FREE(fname_src_mask
);
6904 /****************************************************************************
6906 ****************************************************************************/
6908 void reply_mv(struct smb_request
*req
)
6910 connection_struct
*conn
= req
->conn
;
6912 char *newname
= NULL
;
6916 bool src_has_wcard
= False
;
6917 bool dest_has_wcard
= False
;
6918 TALLOC_CTX
*ctx
= talloc_tos();
6919 struct smb_filename
*smb_fname_src
= NULL
;
6920 struct smb_filename
*smb_fname_dst
= NULL
;
6921 uint32_t src_ucf_flags
= lp_posix_pathnames() ? UCF_UNIX_NAME_LOOKUP
: UCF_COND_ALLOW_WCARD_LCOMP
;
6922 uint32_t dst_ucf_flags
= UCF_SAVE_LCOMP
| (lp_posix_pathnames() ? 0 : UCF_COND_ALLOW_WCARD_LCOMP
);
6923 bool stream_rename
= false;
6925 START_PROFILE(SMBmv
);
6928 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
6932 attrs
= SVAL(req
->vwv
+0, 0);
6934 p
= (const char *)req
->buf
+ 1;
6935 p
+= srvstr_get_path_req_wcard(ctx
, req
, &name
, p
, STR_TERMINATE
,
6936 &status
, &src_has_wcard
);
6937 if (!NT_STATUS_IS_OK(status
)) {
6938 reply_nterror(req
, status
);
6942 p
+= srvstr_get_path_req_wcard(ctx
, req
, &newname
, p
, STR_TERMINATE
,
6943 &status
, &dest_has_wcard
);
6944 if (!NT_STATUS_IS_OK(status
)) {
6945 reply_nterror(req
, status
);
6949 if (!lp_posix_pathnames()) {
6950 /* The newname must begin with a ':' if the
6951 name contains a ':'. */
6952 if (strchr_m(name
, ':')) {
6953 if (newname
[0] != ':') {
6954 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
6957 stream_rename
= true;
6961 status
= filename_convert(ctx
,
6963 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6969 if (!NT_STATUS_IS_OK(status
)) {
6970 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
6971 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
6972 ERRSRV
, ERRbadpath
);
6975 reply_nterror(req
, status
);
6979 status
= filename_convert(ctx
,
6981 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6987 if (!NT_STATUS_IS_OK(status
)) {
6988 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
6989 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
6990 ERRSRV
, ERRbadpath
);
6993 reply_nterror(req
, status
);
6997 if (stream_rename
) {
6998 /* smb_fname_dst->base_name must be the same as
6999 smb_fname_src->base_name. */
7000 TALLOC_FREE(smb_fname_dst
->base_name
);
7001 smb_fname_dst
->base_name
= talloc_strdup(smb_fname_dst
,
7002 smb_fname_src
->base_name
);
7003 if (!smb_fname_dst
->base_name
) {
7004 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7009 DEBUG(3,("reply_mv : %s -> %s\n", smb_fname_str_dbg(smb_fname_src
),
7010 smb_fname_str_dbg(smb_fname_dst
)));
7012 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
, smb_fname_dst
,
7013 attrs
, False
, src_has_wcard
, dest_has_wcard
,
7015 if (!NT_STATUS_IS_OK(status
)) {
7016 if (open_was_deferred(req
->sconn
, req
->mid
)) {
7017 /* We have re-scheduled this call. */
7020 reply_nterror(req
, status
);
7024 reply_outbuf(req
, 0, 0);
7026 TALLOC_FREE(smb_fname_src
);
7027 TALLOC_FREE(smb_fname_dst
);
7032 /*******************************************************************
7033 Copy a file as part of a reply_copy.
7034 ******************************************************************/
7037 * TODO: check error codes on all callers
7040 NTSTATUS
copy_file(TALLOC_CTX
*ctx
,
7041 connection_struct
*conn
,
7042 struct smb_filename
*smb_fname_src
,
7043 struct smb_filename
*smb_fname_dst
,
7046 bool target_is_directory
)
7048 struct smb_filename
*smb_fname_dst_tmp
= NULL
;
7050 files_struct
*fsp1
,*fsp2
;
7052 uint32 new_create_disposition
;
7056 smb_fname_dst_tmp
= cp_smb_filename(ctx
, smb_fname_dst
);
7057 if (smb_fname_dst_tmp
== NULL
) {
7058 return NT_STATUS_NO_MEMORY
;
7062 * If the target is a directory, extract the last component from the
7063 * src filename and append it to the dst filename
7065 if (target_is_directory
) {
7068 /* dest/target can't be a stream if it's a directory. */
7069 SMB_ASSERT(smb_fname_dst
->stream_name
== NULL
);
7071 p
= strrchr_m(smb_fname_src
->base_name
,'/');
7075 p
= smb_fname_src
->base_name
;
7077 smb_fname_dst_tmp
->base_name
=
7078 talloc_asprintf_append(smb_fname_dst_tmp
->base_name
, "/%s",
7080 if (!smb_fname_dst_tmp
->base_name
) {
7081 status
= NT_STATUS_NO_MEMORY
;
7086 status
= vfs_file_exist(conn
, smb_fname_src
);
7087 if (!NT_STATUS_IS_OK(status
)) {
7091 if (!target_is_directory
&& count
) {
7092 new_create_disposition
= FILE_OPEN
;
7094 if (!map_open_params_to_ntcreate(smb_fname_dst_tmp
->base_name
,
7097 &new_create_disposition
,
7100 status
= NT_STATUS_INVALID_PARAMETER
;
7105 /* Open the src file for reading. */
7106 status
= SMB_VFS_CREATE_FILE(
7109 0, /* root_dir_fid */
7110 smb_fname_src
, /* fname */
7111 FILE_GENERIC_READ
, /* access_mask */
7112 FILE_SHARE_READ
| FILE_SHARE_WRITE
, /* share_access */
7113 FILE_OPEN
, /* create_disposition*/
7114 0, /* create_options */
7115 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
7116 INTERNAL_OPEN_ONLY
, /* oplock_request */
7117 0, /* allocation_size */
7118 0, /* private_flags */
7124 if (!NT_STATUS_IS_OK(status
)) {
7128 dosattrs
= dos_mode(conn
, smb_fname_src
);
7130 if (SMB_VFS_STAT(conn
, smb_fname_dst_tmp
) == -1) {
7131 ZERO_STRUCTP(&smb_fname_dst_tmp
->st
);
7134 /* Open the dst file for writing. */
7135 status
= SMB_VFS_CREATE_FILE(
7138 0, /* root_dir_fid */
7139 smb_fname_dst
, /* fname */
7140 FILE_GENERIC_WRITE
, /* access_mask */
7141 FILE_SHARE_READ
| FILE_SHARE_WRITE
, /* share_access */
7142 new_create_disposition
, /* create_disposition*/
7143 0, /* create_options */
7144 dosattrs
, /* file_attributes */
7145 INTERNAL_OPEN_ONLY
, /* oplock_request */
7146 0, /* allocation_size */
7147 0, /* private_flags */
7153 if (!NT_STATUS_IS_OK(status
)) {
7154 close_file(NULL
, fsp1
, ERROR_CLOSE
);
7158 if (ofun
& OPENX_FILE_EXISTS_OPEN
) {
7159 ret
= SMB_VFS_LSEEK(fsp2
, 0, SEEK_END
);
7161 DEBUG(0, ("error - vfs lseek returned error %s\n",
7163 status
= map_nt_error_from_unix(errno
);
7164 close_file(NULL
, fsp1
, ERROR_CLOSE
);
7165 close_file(NULL
, fsp2
, ERROR_CLOSE
);
7170 /* Do the actual copy. */
7171 if (smb_fname_src
->st
.st_ex_size
) {
7172 ret
= vfs_transfer_file(fsp1
, fsp2
, smb_fname_src
->st
.st_ex_size
);
7177 close_file(NULL
, fsp1
, NORMAL_CLOSE
);
7179 /* Ensure the modtime is set correctly on the destination file. */
7180 set_close_write_time(fsp2
, smb_fname_src
->st
.st_ex_mtime
);
7183 * As we are opening fsp1 read-only we only expect
7184 * an error on close on fsp2 if we are out of space.
7185 * Thus we don't look at the error return from the
7188 status
= close_file(NULL
, fsp2
, NORMAL_CLOSE
);
7190 if (!NT_STATUS_IS_OK(status
)) {
7194 if (ret
!= (off_t
)smb_fname_src
->st
.st_ex_size
) {
7195 status
= NT_STATUS_DISK_FULL
;
7199 status
= NT_STATUS_OK
;
7202 TALLOC_FREE(smb_fname_dst_tmp
);
7206 /****************************************************************************
7207 Reply to a file copy.
7208 ****************************************************************************/
7210 void reply_copy(struct smb_request
*req
)
7212 connection_struct
*conn
= req
->conn
;
7213 struct smb_filename
*smb_fname_src
= NULL
;
7214 struct smb_filename
*smb_fname_dst
= NULL
;
7215 char *fname_src
= NULL
;
7216 char *fname_dst
= NULL
;
7217 char *fname_src_mask
= NULL
;
7218 char *fname_src_dir
= NULL
;
7221 int error
= ERRnoaccess
;
7225 bool target_is_directory
=False
;
7226 bool source_has_wild
= False
;
7227 bool dest_has_wild
= False
;
7229 TALLOC_CTX
*ctx
= talloc_tos();
7231 START_PROFILE(SMBcopy
);
7234 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7238 tid2
= SVAL(req
->vwv
+0, 0);
7239 ofun
= SVAL(req
->vwv
+1, 0);
7240 flags
= SVAL(req
->vwv
+2, 0);
7242 p
= (const char *)req
->buf
;
7243 p
+= srvstr_get_path_req_wcard(ctx
, req
, &fname_src
, p
, STR_TERMINATE
,
7244 &status
, &source_has_wild
);
7245 if (!NT_STATUS_IS_OK(status
)) {
7246 reply_nterror(req
, status
);
7249 p
+= srvstr_get_path_req_wcard(ctx
, req
, &fname_dst
, p
, STR_TERMINATE
,
7250 &status
, &dest_has_wild
);
7251 if (!NT_STATUS_IS_OK(status
)) {
7252 reply_nterror(req
, status
);
7256 DEBUG(3,("reply_copy : %s -> %s\n", fname_src
, fname_dst
));
7258 if (tid2
!= conn
->cnum
) {
7259 /* can't currently handle inter share copies XXXX */
7260 DEBUG(3,("Rejecting inter-share copy\n"));
7261 reply_nterror(req
, NT_STATUS_BAD_DEVICE_TYPE
);
7265 status
= filename_convert(ctx
, conn
,
7266 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
7268 UCF_COND_ALLOW_WCARD_LCOMP
,
7271 if (!NT_STATUS_IS_OK(status
)) {
7272 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
7273 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
7274 ERRSRV
, ERRbadpath
);
7277 reply_nterror(req
, status
);
7281 status
= filename_convert(ctx
, conn
,
7282 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
7284 UCF_COND_ALLOW_WCARD_LCOMP
,
7287 if (!NT_STATUS_IS_OK(status
)) {
7288 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
7289 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
7290 ERRSRV
, ERRbadpath
);
7293 reply_nterror(req
, status
);
7297 target_is_directory
= VALID_STAT_OF_DIR(smb_fname_dst
->st
);
7299 if ((flags
&1) && target_is_directory
) {
7300 reply_nterror(req
, NT_STATUS_NO_SUCH_FILE
);
7304 if ((flags
&2) && !target_is_directory
) {
7305 reply_nterror(req
, NT_STATUS_OBJECT_PATH_NOT_FOUND
);
7309 if ((flags
&(1<<5)) && VALID_STAT_OF_DIR(smb_fname_src
->st
)) {
7310 /* wants a tree copy! XXXX */
7311 DEBUG(3,("Rejecting tree copy\n"));
7312 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7316 /* Split up the directory from the filename/mask. */
7317 status
= split_fname_dir_mask(ctx
, smb_fname_src
->base_name
,
7318 &fname_src_dir
, &fname_src_mask
);
7319 if (!NT_STATUS_IS_OK(status
)) {
7320 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7325 * We should only check the mangled cache
7326 * here if unix_convert failed. This means
7327 * that the path in 'mask' doesn't exist
7328 * on the file system and so we need to look
7329 * for a possible mangle. This patch from
7330 * Tine Smukavec <valentin.smukavec@hermes.si>.
7332 if (!VALID_STAT(smb_fname_src
->st
) &&
7333 mangle_is_mangled(fname_src_mask
, conn
->params
)) {
7334 char *new_mask
= NULL
;
7335 mangle_lookup_name_from_8_3(ctx
, fname_src_mask
,
7336 &new_mask
, conn
->params
);
7338 /* Use demangled name if one was successfully found. */
7340 TALLOC_FREE(fname_src_mask
);
7341 fname_src_mask
= new_mask
;
7345 if (!source_has_wild
) {
7348 * Only one file needs to be copied. Append the mask back onto
7351 TALLOC_FREE(smb_fname_src
->base_name
);
7352 if (ISDOT(fname_src_dir
)) {
7353 /* Ensure we use canonical names on open. */
7354 smb_fname_src
->base_name
= talloc_asprintf(smb_fname_src
,
7358 smb_fname_src
->base_name
= talloc_asprintf(smb_fname_src
,
7363 if (!smb_fname_src
->base_name
) {
7364 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7368 if (dest_has_wild
) {
7369 char *fname_dst_mod
= NULL
;
7370 if (!resolve_wildcards(smb_fname_dst
,
7371 smb_fname_src
->base_name
,
7372 smb_fname_dst
->base_name
,
7374 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7377 TALLOC_FREE(smb_fname_dst
->base_name
);
7378 smb_fname_dst
->base_name
= fname_dst_mod
;
7381 status
= check_name(conn
, smb_fname_src
->base_name
);
7382 if (!NT_STATUS_IS_OK(status
)) {
7383 reply_nterror(req
, status
);
7387 status
= check_name(conn
, smb_fname_dst
->base_name
);
7388 if (!NT_STATUS_IS_OK(status
)) {
7389 reply_nterror(req
, status
);
7393 status
= copy_file(ctx
, conn
, smb_fname_src
, smb_fname_dst
,
7394 ofun
, count
, target_is_directory
);
7396 if(!NT_STATUS_IS_OK(status
)) {
7397 reply_nterror(req
, status
);
7403 struct smb_Dir
*dir_hnd
= NULL
;
7404 const char *dname
= NULL
;
7405 char *talloced
= NULL
;
7409 * There is a wildcard that requires us to actually read the
7410 * src dir and copy each file matching the mask to the dst.
7411 * Right now streams won't be copied, but this could
7412 * presumably be added with a nested loop for reach dir entry.
7414 SMB_ASSERT(!smb_fname_src
->stream_name
);
7415 SMB_ASSERT(!smb_fname_dst
->stream_name
);
7417 smb_fname_src
->stream_name
= NULL
;
7418 smb_fname_dst
->stream_name
= NULL
;
7420 if (strequal(fname_src_mask
,"????????.???")) {
7421 TALLOC_FREE(fname_src_mask
);
7422 fname_src_mask
= talloc_strdup(ctx
, "*");
7423 if (!fname_src_mask
) {
7424 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7429 status
= check_name(conn
, fname_src_dir
);
7430 if (!NT_STATUS_IS_OK(status
)) {
7431 reply_nterror(req
, status
);
7435 dir_hnd
= OpenDir(ctx
, conn
, fname_src_dir
, fname_src_mask
, 0);
7436 if (dir_hnd
== NULL
) {
7437 status
= map_nt_error_from_unix(errno
);
7438 reply_nterror(req
, status
);
7444 /* Iterate over the src dir copying each entry to the dst. */
7445 while ((dname
= ReadDirName(dir_hnd
, &offset
,
7446 &smb_fname_src
->st
, &talloced
))) {
7447 char *destname
= NULL
;
7449 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
7450 TALLOC_FREE(talloced
);
7454 if (!is_visible_file(conn
, fname_src_dir
, dname
,
7455 &smb_fname_src
->st
, false)) {
7456 TALLOC_FREE(talloced
);
7460 if(!mask_match(dname
, fname_src_mask
,
7461 conn
->case_sensitive
)) {
7462 TALLOC_FREE(talloced
);
7466 error
= ERRnoaccess
;
7468 /* Get the src smb_fname struct setup. */
7469 TALLOC_FREE(smb_fname_src
->base_name
);
7470 if (ISDOT(fname_src_dir
)) {
7471 /* Ensure we use canonical names on open. */
7472 smb_fname_src
->base_name
=
7473 talloc_asprintf(smb_fname_src
, "%s",
7476 smb_fname_src
->base_name
=
7477 talloc_asprintf(smb_fname_src
, "%s/%s",
7478 fname_src_dir
, dname
);
7481 if (!smb_fname_src
->base_name
) {
7482 TALLOC_FREE(dir_hnd
);
7483 TALLOC_FREE(talloced
);
7484 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7488 if (!resolve_wildcards(ctx
, smb_fname_src
->base_name
,
7489 smb_fname_dst
->base_name
,
7491 TALLOC_FREE(talloced
);
7495 TALLOC_FREE(dir_hnd
);
7496 TALLOC_FREE(talloced
);
7497 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7501 TALLOC_FREE(smb_fname_dst
->base_name
);
7502 smb_fname_dst
->base_name
= destname
;
7504 status
= check_name(conn
, smb_fname_src
->base_name
);
7505 if (!NT_STATUS_IS_OK(status
)) {
7506 TALLOC_FREE(dir_hnd
);
7507 TALLOC_FREE(talloced
);
7508 reply_nterror(req
, status
);
7512 status
= check_name(conn
, smb_fname_dst
->base_name
);
7513 if (!NT_STATUS_IS_OK(status
)) {
7514 TALLOC_FREE(dir_hnd
);
7515 TALLOC_FREE(talloced
);
7516 reply_nterror(req
, status
);
7520 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",
7521 smb_fname_src
->base_name
,
7522 smb_fname_dst
->base_name
));
7524 status
= copy_file(ctx
, conn
, smb_fname_src
,
7525 smb_fname_dst
, ofun
, count
,
7526 target_is_directory
);
7527 if (NT_STATUS_IS_OK(status
)) {
7531 TALLOC_FREE(talloced
);
7533 TALLOC_FREE(dir_hnd
);
7537 reply_nterror(req
, dos_to_ntstatus(ERRDOS
, error
));
7541 reply_outbuf(req
, 1, 0);
7542 SSVAL(req
->outbuf
,smb_vwv0
,count
);
7544 TALLOC_FREE(smb_fname_src
);
7545 TALLOC_FREE(smb_fname_dst
);
7546 TALLOC_FREE(fname_src
);
7547 TALLOC_FREE(fname_dst
);
7548 TALLOC_FREE(fname_src_mask
);
7549 TALLOC_FREE(fname_src_dir
);
7551 END_PROFILE(SMBcopy
);
7556 #define DBGC_CLASS DBGC_LOCKING
7558 /****************************************************************************
7559 Get a lock pid, dealing with large count requests.
7560 ****************************************************************************/
7562 uint64_t get_lock_pid(const uint8_t *data
, int data_offset
,
7563 bool large_file_format
)
7565 if(!large_file_format
)
7566 return (uint64_t)SVAL(data
,SMB_LPID_OFFSET(data_offset
));
7568 return (uint64_t)SVAL(data
,SMB_LARGE_LPID_OFFSET(data_offset
));
7571 /****************************************************************************
7572 Get a lock count, dealing with large count requests.
7573 ****************************************************************************/
7575 uint64_t get_lock_count(const uint8_t *data
, int data_offset
,
7576 bool large_file_format
)
7580 if(!large_file_format
) {
7581 count
= (uint64_t)IVAL(data
,SMB_LKLEN_OFFSET(data_offset
));
7584 * No BVAL, this is reversed!
7586 count
= (((uint64_t) IVAL(data
,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset
))) << 32) |
7587 ((uint64_t) IVAL(data
,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset
)));
7593 /****************************************************************************
7594 Get a lock offset, dealing with large offset requests.
7595 ****************************************************************************/
7597 uint64_t get_lock_offset(const uint8_t *data
, int data_offset
,
7598 bool large_file_format
)
7600 uint64_t offset
= 0;
7602 if(!large_file_format
) {
7603 offset
= (uint64_t)IVAL(data
,SMB_LKOFF_OFFSET(data_offset
));
7606 * No BVAL, this is reversed!
7608 offset
= (((uint64_t) IVAL(data
,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset
))) << 32) |
7609 ((uint64_t) IVAL(data
,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset
)));
7615 NTSTATUS
smbd_do_locking(struct smb_request
*req
,
7620 struct smbd_lock_element
*locks
,
7623 connection_struct
*conn
= req
->conn
;
7625 NTSTATUS status
= NT_STATUS_OK
;
7629 /* Setup the timeout in seconds. */
7631 if (!lp_blocking_locks(SNUM(conn
))) {
7635 for(i
= 0; i
< (int)num_locks
; i
++) {
7636 struct smbd_lock_element
*e
= &locks
[i
];
7638 DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for smblctx "
7639 "%llu, file %s timeout = %d\n",
7642 (unsigned long long)e
->smblctx
,
7646 if (type
& LOCKING_ANDX_CANCEL_LOCK
) {
7647 struct blocking_lock_record
*blr
= NULL
;
7649 if (num_locks
> 1) {
7651 * MS-CIFS (2.2.4.32.1) states that a cancel is honored if and only
7652 * if the lock vector contains one entry. When given mutliple cancel
7653 * requests in a single PDU we expect the server to return an
7654 * error. Windows servers seem to accept the request but only
7655 * cancel the first lock.
7656 * JRA - Do what Windows does (tm) :-).
7660 /* MS-CIFS (2.2.4.32.1) behavior. */
7661 return NT_STATUS_DOS(ERRDOS
,
7662 ERRcancelviolation
);
7664 /* Windows behavior. */
7666 DEBUG(10,("smbd_do_locking: ignoring subsequent "
7667 "cancel request\n"));
7673 if (lp_blocking_locks(SNUM(conn
))) {
7675 /* Schedule a message to ourselves to
7676 remove the blocking lock record and
7677 return the right error. */
7679 blr
= blocking_lock_cancel_smb1(fsp
,
7685 NT_STATUS_FILE_LOCK_CONFLICT
);
7687 return NT_STATUS_DOS(
7689 ERRcancelviolation
);
7692 /* Remove a matching pending lock. */
7693 status
= do_lock_cancel(fsp
,
7699 bool blocking_lock
= timeout
? true : false;
7700 bool defer_lock
= false;
7701 struct byte_range_lock
*br_lck
;
7702 uint64_t block_smblctx
;
7704 br_lck
= do_lock(req
->sconn
->msg_ctx
,
7715 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
7716 /* Windows internal resolution for blocking locks seems
7717 to be about 200ms... Don't wait for less than that. JRA. */
7718 if (timeout
!= -1 && timeout
< lp_lock_spin_time()) {
7719 timeout
= lp_lock_spin_time();
7724 /* If a lock sent with timeout of zero would fail, and
7725 * this lock has been requested multiple times,
7726 * according to brl_lock_failed() we convert this
7727 * request to a blocking lock with a timeout of between
7728 * 150 - 300 milliseconds.
7730 * If lp_lock_spin_time() has been set to 0, we skip
7731 * this blocking retry and fail immediately.
7733 * Replacement for do_lock_spin(). JRA. */
7735 if (!req
->sconn
->using_smb2
&&
7736 br_lck
&& lp_blocking_locks(SNUM(conn
)) &&
7737 lp_lock_spin_time() && !blocking_lock
&&
7738 NT_STATUS_EQUAL((status
),
7739 NT_STATUS_FILE_LOCK_CONFLICT
))
7742 timeout
= lp_lock_spin_time();
7745 if (br_lck
&& defer_lock
) {
7747 * A blocking lock was requested. Package up
7748 * this smb into a queued request and push it
7749 * onto the blocking lock queue.
7751 if(push_blocking_lock_request(br_lck
,
7762 TALLOC_FREE(br_lck
);
7764 return NT_STATUS_OK
;
7768 TALLOC_FREE(br_lck
);
7771 if (!NT_STATUS_IS_OK(status
)) {
7776 /* If any of the above locks failed, then we must unlock
7777 all of the previous locks (X/Open spec). */
7779 if (num_locks
!= 0 && !NT_STATUS_IS_OK(status
)) {
7781 if (type
& LOCKING_ANDX_CANCEL_LOCK
) {
7782 i
= -1; /* we want to skip the for loop */
7786 * Ensure we don't do a remove on the lock that just failed,
7787 * as under POSIX rules, if we have a lock already there, we
7788 * will delete it (and we shouldn't) .....
7790 for(i
--; i
>= 0; i
--) {
7791 struct smbd_lock_element
*e
= &locks
[i
];
7793 do_unlock(req
->sconn
->msg_ctx
,
7803 DEBUG(3, ("smbd_do_locking: %s type=%d num_locks=%d\n",
7804 fsp_fnum_dbg(fsp
), (unsigned int)type
, num_locks
));
7806 return NT_STATUS_OK
;
7809 NTSTATUS
smbd_do_unlocking(struct smb_request
*req
,
7811 uint16_t num_ulocks
,
7812 struct smbd_lock_element
*ulocks
)
7816 for(i
= 0; i
< (int)num_ulocks
; i
++) {
7817 struct smbd_lock_element
*e
= &ulocks
[i
];
7820 DEBUG(10,("%s: unlock start=%.0f, len=%.0f for "
7821 "pid %u, file %s\n", __func__
,
7824 (unsigned int)e
->smblctx
,
7827 if (e
->brltype
!= UNLOCK_LOCK
) {
7828 /* this can only happen with SMB2 */
7829 return NT_STATUS_INVALID_PARAMETER
;
7832 status
= do_unlock(req
->sconn
->msg_ctx
,
7839 DEBUG(10, ("%s: unlock returned %s\n", __func__
,
7840 nt_errstr(status
)));
7842 if (!NT_STATUS_IS_OK(status
)) {
7847 DEBUG(3, ("%s: %s num_ulocks=%d\n", __func__
, fsp_fnum_dbg(fsp
),
7850 return NT_STATUS_OK
;
7853 /****************************************************************************
7854 Reply to a lockingX request.
7855 ****************************************************************************/
7857 void reply_lockingX(struct smb_request
*req
)
7859 connection_struct
*conn
= req
->conn
;
7861 unsigned char locktype
;
7862 unsigned char oplocklevel
;
7867 const uint8_t *data
;
7868 bool large_file_format
;
7869 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
7870 struct smbd_lock_element
*ulocks
;
7871 struct smbd_lock_element
*locks
;
7874 START_PROFILE(SMBlockingX
);
7877 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7878 END_PROFILE(SMBlockingX
);
7882 fsp
= file_fsp(req
, SVAL(req
->vwv
+2, 0));
7883 locktype
= CVAL(req
->vwv
+3, 0);
7884 oplocklevel
= CVAL(req
->vwv
+3, 1);
7885 num_ulocks
= SVAL(req
->vwv
+6, 0);
7886 num_locks
= SVAL(req
->vwv
+7, 0);
7887 lock_timeout
= IVAL(req
->vwv
+4, 0);
7888 large_file_format
= (locktype
& LOCKING_ANDX_LARGE_FILES
)?True
:False
;
7890 if (!check_fsp(conn
, req
, fsp
)) {
7891 END_PROFILE(SMBlockingX
);
7897 if (locktype
& LOCKING_ANDX_CHANGE_LOCKTYPE
) {
7898 /* we don't support these - and CANCEL_LOCK makes w2k
7899 and XP reboot so I don't really want to be
7900 compatible! (tridge) */
7901 reply_force_doserror(req
, ERRDOS
, ERRnoatomiclocks
);
7902 END_PROFILE(SMBlockingX
);
7906 /* Check if this is an oplock break on a file
7907 we have granted an oplock on.
7909 if ((locktype
& LOCKING_ANDX_OPLOCK_RELEASE
)) {
7910 /* Client can insist on breaking to none. */
7911 bool break_to_none
= (oplocklevel
== 0);
7914 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
7915 "for %s\n", (unsigned int)oplocklevel
,
7916 fsp_fnum_dbg(fsp
)));
7919 * Make sure we have granted an exclusive or batch oplock on
7923 if (fsp
->oplock_type
== 0) {
7925 /* The Samba4 nbench simulator doesn't understand
7926 the difference between break to level2 and break
7927 to none from level2 - it sends oplock break
7928 replies in both cases. Don't keep logging an error
7929 message here - just ignore it. JRA. */
7931 DEBUG(5,("reply_lockingX: Error : oplock break from "
7932 "client for %s (oplock=%d) and no "
7933 "oplock granted on this file (%s).\n",
7934 fsp_fnum_dbg(fsp
), fsp
->oplock_type
,
7937 /* if this is a pure oplock break request then don't
7939 if (num_locks
== 0 && num_ulocks
== 0) {
7940 END_PROFILE(SMBlockingX
);
7943 END_PROFILE(SMBlockingX
);
7944 reply_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
7949 if ((fsp
->sent_oplock_break
== BREAK_TO_NONE_SENT
) ||
7951 result
= remove_oplock(fsp
);
7953 result
= downgrade_oplock(fsp
);
7957 DEBUG(0, ("reply_lockingX: error in removing "
7958 "oplock on file %s\n", fsp_str_dbg(fsp
)));
7959 /* Hmmm. Is this panic justified? */
7960 smb_panic("internal tdb error");
7963 /* if this is a pure oplock break request then don't send a
7965 if (num_locks
== 0 && num_ulocks
== 0) {
7966 /* Sanity check - ensure a pure oplock break is not a
7968 if(CVAL(req
->vwv
+0, 0) != 0xff)
7969 DEBUG(0,("reply_lockingX: Error : pure oplock "
7970 "break is a chained %d request !\n",
7971 (unsigned int)CVAL(req
->vwv
+0, 0)));
7972 END_PROFILE(SMBlockingX
);
7978 (num_ulocks
+ num_locks
) * (large_file_format
? 20 : 10)) {
7979 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7980 END_PROFILE(SMBlockingX
);
7984 ulocks
= talloc_array(req
, struct smbd_lock_element
, num_ulocks
);
7985 if (ulocks
== NULL
) {
7986 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7987 END_PROFILE(SMBlockingX
);
7991 locks
= talloc_array(req
, struct smbd_lock_element
, num_locks
);
7992 if (locks
== NULL
) {
7993 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
7994 END_PROFILE(SMBlockingX
);
7998 /* Data now points at the beginning of the list
7999 of smb_unlkrng structs */
8000 for(i
= 0; i
< (int)num_ulocks
; i
++) {
8001 ulocks
[i
].smblctx
= get_lock_pid(data
, i
, large_file_format
);
8002 ulocks
[i
].count
= get_lock_count(data
, i
, large_file_format
);
8003 ulocks
[i
].offset
= get_lock_offset(data
, i
, large_file_format
);
8004 ulocks
[i
].brltype
= UNLOCK_LOCK
;
8007 /* Now do any requested locks */
8008 data
+= ((large_file_format
? 20 : 10)*num_ulocks
);
8010 /* Data now points at the beginning of the list
8011 of smb_lkrng structs */
8013 for(i
= 0; i
< (int)num_locks
; i
++) {
8014 locks
[i
].smblctx
= get_lock_pid(data
, i
, large_file_format
);
8015 locks
[i
].count
= get_lock_count(data
, i
, large_file_format
);
8016 locks
[i
].offset
= get_lock_offset(data
, i
, large_file_format
);
8018 if (locktype
& LOCKING_ANDX_SHARED_LOCK
) {
8019 if (locktype
& LOCKING_ANDX_CANCEL_LOCK
) {
8020 locks
[i
].brltype
= PENDING_READ_LOCK
;
8022 locks
[i
].brltype
= READ_LOCK
;
8025 if (locktype
& LOCKING_ANDX_CANCEL_LOCK
) {
8026 locks
[i
].brltype
= PENDING_WRITE_LOCK
;
8028 locks
[i
].brltype
= WRITE_LOCK
;
8033 status
= smbd_do_unlocking(req
, fsp
, num_ulocks
, ulocks
);
8034 if (!NT_STATUS_IS_OK(status
)) {
8035 END_PROFILE(SMBlockingX
);
8036 reply_nterror(req
, status
);
8040 status
= smbd_do_locking(req
, fsp
,
8041 locktype
, lock_timeout
,
8044 if (!NT_STATUS_IS_OK(status
)) {
8045 END_PROFILE(SMBlockingX
);
8046 reply_nterror(req
, status
);
8050 END_PROFILE(SMBlockingX
);
8054 reply_outbuf(req
, 2, 0);
8055 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
8056 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
8058 DEBUG(3, ("lockingX %s type=%d num_locks=%d num_ulocks=%d\n",
8059 fsp_fnum_dbg(fsp
), (unsigned int)locktype
, num_locks
, num_ulocks
));
8061 END_PROFILE(SMBlockingX
);
8065 #define DBGC_CLASS DBGC_ALL
8067 /****************************************************************************
8068 Reply to a SMBreadbmpx (read block multiplex) request.
8069 Always reply with an error, if someone has a platform really needs this,
8070 please contact vl@samba.org
8071 ****************************************************************************/
8073 void reply_readbmpx(struct smb_request
*req
)
8075 START_PROFILE(SMBreadBmpx
);
8076 reply_force_doserror(req
, ERRSRV
, ERRuseSTD
);
8077 END_PROFILE(SMBreadBmpx
);
8081 /****************************************************************************
8082 Reply to a SMBreadbs (read block multiplex secondary) request.
8083 Always reply with an error, if someone has a platform really needs this,
8084 please contact vl@samba.org
8085 ****************************************************************************/
8087 void reply_readbs(struct smb_request
*req
)
8089 START_PROFILE(SMBreadBs
);
8090 reply_force_doserror(req
, ERRSRV
, ERRuseSTD
);
8091 END_PROFILE(SMBreadBs
);
8095 /****************************************************************************
8096 Reply to a SMBsetattrE.
8097 ****************************************************************************/
8099 void reply_setattrE(struct smb_request
*req
)
8101 connection_struct
*conn
= req
->conn
;
8102 struct smb_file_time ft
;
8106 START_PROFILE(SMBsetattrE
);
8110 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8114 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
8116 if(!fsp
|| (fsp
->conn
!= conn
)) {
8117 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8122 * Convert the DOS times into unix times.
8125 ft
.atime
= convert_time_t_to_timespec(
8126 srv_make_unix_date2(req
->vwv
+3));
8127 ft
.mtime
= convert_time_t_to_timespec(
8128 srv_make_unix_date2(req
->vwv
+5));
8129 ft
.create_time
= convert_time_t_to_timespec(
8130 srv_make_unix_date2(req
->vwv
+1));
8132 reply_outbuf(req
, 0, 0);
8135 * Patch from Ray Frush <frush@engr.colostate.edu>
8136 * Sometimes times are sent as zero - ignore them.
8139 /* Ensure we have a valid stat struct for the source. */
8140 status
= vfs_stat_fsp(fsp
);
8141 if (!NT_STATUS_IS_OK(status
)) {
8142 reply_nterror(req
, status
);
8146 if (!(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
8147 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8151 status
= smb_set_file_time(conn
, fsp
, fsp
->fsp_name
, &ft
, true);
8152 if (!NT_STATUS_IS_OK(status
)) {
8153 reply_nterror(req
, status
);
8157 DEBUG( 3, ( "reply_setattrE %s actime=%u modtime=%u "
8160 (unsigned int)ft
.atime
.tv_sec
,
8161 (unsigned int)ft
.mtime
.tv_sec
,
8162 (unsigned int)ft
.create_time
.tv_sec
8165 END_PROFILE(SMBsetattrE
);
8170 /* Back from the dead for OS/2..... JRA. */
8172 /****************************************************************************
8173 Reply to a SMBwritebmpx (write block multiplex primary) request.
8174 Always reply with an error, if someone has a platform really needs this,
8175 please contact vl@samba.org
8176 ****************************************************************************/
8178 void reply_writebmpx(struct smb_request
*req
)
8180 START_PROFILE(SMBwriteBmpx
);
8181 reply_force_doserror(req
, ERRSRV
, ERRuseSTD
);
8182 END_PROFILE(SMBwriteBmpx
);
8186 /****************************************************************************
8187 Reply to a SMBwritebs (write block multiplex secondary) request.
8188 Always reply with an error, if someone has a platform really needs this,
8189 please contact vl@samba.org
8190 ****************************************************************************/
8192 void reply_writebs(struct smb_request
*req
)
8194 START_PROFILE(SMBwriteBs
);
8195 reply_force_doserror(req
, ERRSRV
, ERRuseSTD
);
8196 END_PROFILE(SMBwriteBs
);
8200 /****************************************************************************
8201 Reply to a SMBgetattrE.
8202 ****************************************************************************/
8204 void reply_getattrE(struct smb_request
*req
)
8206 connection_struct
*conn
= req
->conn
;
8209 struct timespec create_ts
;
8211 START_PROFILE(SMBgetattrE
);
8214 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8215 END_PROFILE(SMBgetattrE
);
8219 fsp
= file_fsp(req
, SVAL(req
->vwv
+0, 0));
8221 if(!fsp
|| (fsp
->conn
!= conn
)) {
8222 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8223 END_PROFILE(SMBgetattrE
);
8227 /* Do an fstat on this file */
8229 reply_nterror(req
, map_nt_error_from_unix(errno
));
8230 END_PROFILE(SMBgetattrE
);
8234 mode
= dos_mode(conn
, fsp
->fsp_name
);
8237 * Convert the times into dos times. Set create
8238 * date to be last modify date as UNIX doesn't save
8242 reply_outbuf(req
, 11, 0);
8244 create_ts
= get_create_timespec(conn
, fsp
, fsp
->fsp_name
);
8245 srv_put_dos_date2((char *)req
->outbuf
, smb_vwv0
, create_ts
.tv_sec
);
8246 srv_put_dos_date2((char *)req
->outbuf
, smb_vwv2
,
8247 convert_timespec_to_time_t(fsp
->fsp_name
->st
.st_ex_atime
));
8248 /* Should we check pending modtime here ? JRA */
8249 srv_put_dos_date2((char *)req
->outbuf
, smb_vwv4
,
8250 convert_timespec_to_time_t(fsp
->fsp_name
->st
.st_ex_mtime
));
8252 if (mode
& FILE_ATTRIBUTE_DIRECTORY
) {
8253 SIVAL(req
->outbuf
, smb_vwv6
, 0);
8254 SIVAL(req
->outbuf
, smb_vwv8
, 0);
8256 uint32 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
, &fsp
->fsp_name
->st
);
8257 SIVAL(req
->outbuf
, smb_vwv6
, (uint32
)fsp
->fsp_name
->st
.st_ex_size
);
8258 SIVAL(req
->outbuf
, smb_vwv8
, allocation_size
);
8260 SSVAL(req
->outbuf
,smb_vwv10
, mode
);
8262 DEBUG( 3, ( "reply_getattrE %s\n", fsp_fnum_dbg(fsp
)));
8264 END_PROFILE(SMBgetattrE
);