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
29 #include "smbd/globals.h"
30 #include "../librpc/gen_ndr/cli_spoolss.h"
31 #include "rpc_client/cli_spoolss.h"
32 #include "rpc_client/init_spoolss.h"
34 /****************************************************************************
35 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
36 path or anything including wildcards.
37 We're assuming here that '/' is not the second byte in any multibyte char
38 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
40 ****************************************************************************/
42 /* Custom version for processing POSIX paths. */
43 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
45 static NTSTATUS check_path_syntax_internal(char *path,
47 bool *p_last_component_contains_wcard)
51 NTSTATUS ret = NT_STATUS_OK;
52 bool start_of_name_component = True;
53 bool stream_started = false;
55 *p_last_component_contains_wcard = False;
62 return NT_STATUS_OBJECT_NAME_INVALID;
65 return NT_STATUS_OBJECT_NAME_INVALID;
67 if (strchr_m(&s[1], ':')) {
68 return NT_STATUS_OBJECT_NAME_INVALID;
74 if ((*s == ':') && !posix_path && !stream_started) {
75 if (*p_last_component_contains_wcard) {
76 return NT_STATUS_OBJECT_NAME_INVALID;
78 /* Stream names allow more characters than file names.
79 We're overloading posix_path here to allow a wider
80 range of characters. If stream_started is true this
81 is still a Windows path even if posix_path is true.
84 stream_started = true;
85 start_of_name_component = false;
89 return NT_STATUS_OBJECT_NAME_INVALID;
93 if (!stream_started && IS_PATH_SEP(*s,posix_path)) {
95 * Safe to assume is not the second part of a mb char
96 * as this is handled below.
98 /* Eat multiple '/' or '\\' */
99 while (IS_PATH_SEP(*s,posix_path)) {
102 if ((d != path) && (*s != '\0')) {
103 /* We only care about non-leading or trailing '/' or '\\' */
107 start_of_name_component = True;
109 *p_last_component_contains_wcard = False;
113 if (start_of_name_component) {
114 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
115 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
118 * No mb char starts with '.' so we're safe checking the directory separator here.
121 /* If we just added a '/' - delete it */
122 if ((d > path) && (*(d-1) == '/')) {
127 /* Are we at the start ? Can't go back further if so. */
129 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
132 /* Go back one level... */
133 /* We know this is safe as '/' cannot be part of a mb sequence. */
134 /* NOTE - if this assumption is invalid we are not in good shape... */
135 /* Decrement d first as d points to the *next* char to write into. */
136 for (d--; d > path; d--) {
140 s += 2; /* Else go past the .. */
141 /* We're still at the start of a name component, just the previous one. */
144 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
156 if (*s <= 0x1f || *s == '|') {
157 return NT_STATUS_OBJECT_NAME_INVALID;
165 *p_last_component_contains_wcard = True;
174 /* Get the size of the next MB character. */
175 next_codepoint(s,&siz);
193 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
195 return NT_STATUS_INVALID_PARAMETER;
198 start_of_name_component = False;
206 /****************************************************************************
207 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
208 No wildcards allowed.
209 ****************************************************************************/
211 NTSTATUS check_path_syntax(char *path)
214 return check_path_syntax_internal(path, False, &ignore);
217 /****************************************************************************
218 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
219 Wildcards allowed - p_contains_wcard returns true if the last component contained
221 ****************************************************************************/
223 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
225 return check_path_syntax_internal(path, False, p_contains_wcard);
228 /****************************************************************************
229 Check the path for a POSIX client.
230 We're assuming here that '/' is not the second byte in any multibyte char
231 set (a safe assumption).
232 ****************************************************************************/
234 NTSTATUS check_path_syntax_posix(char *path)
237 return check_path_syntax_internal(path, True, &ignore);
240 /****************************************************************************
241 Pull a string and check the path allowing a wilcard - provide for error return.
242 ****************************************************************************/
244 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
245 const char *base_ptr,
252 bool *contains_wcard)
258 ret = srvstr_pull_talloc(ctx, base_ptr, smb_flags2, pp_dest, src,
262 *err = NT_STATUS_INVALID_PARAMETER;
266 *contains_wcard = False;
268 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
270 * For a DFS path the function parse_dfs_path()
271 * will do the path processing, just make a copy.
277 if (lp_posix_pathnames()) {
278 *err = check_path_syntax_posix(*pp_dest);
280 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
286 /****************************************************************************
287 Pull a string and check the path - provide for error return.
288 ****************************************************************************/
290 size_t srvstr_get_path(TALLOC_CTX *ctx,
291 const char *base_ptr,
300 return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src,
301 src_len, flags, err, &ignore);
304 size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req,
305 char **pp_dest, const char *src, int flags,
306 NTSTATUS *err, bool *contains_wcard)
308 return srvstr_get_path_wcard(mem_ctx, (char *)req->inbuf, req->flags2,
309 pp_dest, src, smbreq_bufrem(req, src),
310 flags, err, contains_wcard);
313 size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req,
314 char **pp_dest, const char *src, int flags,
318 return srvstr_get_path_req_wcard(mem_ctx, req, pp_dest, src,
319 flags, err, &ignore);
322 /****************************************************************************
323 Check if we have a correct fsp pointing to a file. Basic check for open fsp.
324 ****************************************************************************/
326 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
329 if ((fsp == NULL) || (conn == NULL)) {
330 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
333 if ((conn != fsp->conn) || (req->vuid != fsp->vuid)) {
334 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
340 /****************************************************************************
341 Check if we have a correct fsp pointing to a file.
342 ****************************************************************************/
344 bool check_fsp(connection_struct *conn, struct smb_request *req,
347 if (!check_fsp_open(conn, req, fsp)) {
350 if (fsp->is_directory) {
351 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
354 if (fsp->fh->fd == -1) {
355 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
358 fsp->num_smb_operations++;
362 /****************************************************************************
363 Check if we have a correct fsp pointing to a quota fake file. Replacement for
364 the CHECK_NTQUOTA_HANDLE_OK macro.
365 ****************************************************************************/
367 bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
370 if (!check_fsp_open(conn, req, fsp)) {
374 if (fsp->is_directory) {
378 if (fsp->fake_file_handle == NULL) {
382 if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
386 if (fsp->fake_file_handle->private_data == NULL) {
393 static bool netbios_session_retarget(struct smbd_server_connection *sconn,
394 const char *name, int name_type)
397 char *trim_name_type;
398 const char *retarget_parm;
401 int retarget_type = 0x20;
402 int retarget_port = 139;
403 struct sockaddr_storage retarget_addr;
404 struct sockaddr_in *in_addr;
408 if (get_socket_port(sconn->sock) != 139) {
412 trim_name = talloc_strdup(talloc_tos(), name);
413 if (trim_name == NULL) {
416 trim_char(trim_name, ' ', ' ');
418 trim_name_type = talloc_asprintf(trim_name, "%s#%2.2x", trim_name,
420 if (trim_name_type == NULL) {
424 retarget_parm = lp_parm_const_string(-1, "netbios retarget",
425 trim_name_type, NULL);
426 if (retarget_parm == NULL) {
427 retarget_parm = lp_parm_const_string(-1, "netbios retarget",
430 if (retarget_parm == NULL) {
434 retarget = talloc_strdup(trim_name, retarget_parm);
435 if (retarget == NULL) {
439 DEBUG(10, ("retargeting %s to %s\n", trim_name_type, retarget));
441 p = strchr(retarget, ':');
444 retarget_port = atoi(p);
447 p = strchr_m(retarget, '#');
450 sscanf(p, "%x", &retarget_type);
453 ret = resolve_name(retarget, &retarget_addr, retarget_type, false);
455 DEBUG(10, ("could not resolve %s\n", retarget));
459 if (retarget_addr.ss_family != AF_INET) {
460 DEBUG(10, ("Retarget target not an IPv4 addr\n"));
464 in_addr = (struct sockaddr_in *)(void *)&retarget_addr;
466 _smb_setlen(outbuf, 6);
467 SCVAL(outbuf, 0, 0x84);
468 *(uint32_t *)(outbuf+4) = in_addr->sin_addr.s_addr;
469 *(uint16_t *)(outbuf+8) = htons(retarget_port);
471 if (!srv_send_smb(sconn->sock, (char *)outbuf, false, 0, false,
473 exit_server_cleanly("netbios_session_regarget: srv_send_smb "
479 TALLOC_FREE(trim_name);
483 /****************************************************************************
484 Reply to a (netbios-level) special message.
485 ****************************************************************************/
487 void reply_special(struct smbd_server_connection *sconn, char *inbuf)
489 int msg_type = CVAL(inbuf,0);
490 int msg_flags = CVAL(inbuf,1);
492 char name_type1, name_type2;
495 * We only really use 4 bytes of the outbuf, but for the smb_setlen
496 * calculation & friends (srv_send_smb uses that) we need the full smb
499 char outbuf[smb_size];
503 memset(outbuf, '\0', sizeof(outbuf));
505 smb_setlen(outbuf,0);
508 case 0x81: /* session request */
510 if (sconn->nbt.got_session) {
511 exit_server_cleanly("multiple session request not permitted");
514 SCVAL(outbuf,0,0x82);
516 if (name_len(inbuf+4) > 50 ||
517 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
518 DEBUG(0,("Invalid name length in session request\n"));
521 name_type1 = name_extract(inbuf,4,name1);
522 name_type2 = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
523 DEBUG(2,("netbios connect: name1=%s0x%x name2=%s0x%x\n",
524 name1, name_type1, name2, name_type2));
526 if (netbios_session_retarget(sconn, name1, name_type1)) {
527 exit_server_cleanly("retargeted client");
530 set_local_machine_name(name1, True);
531 set_remote_machine_name(name2, True);
533 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
534 get_local_machine_name(), get_remote_machine_name(),
537 if (name_type2 == 'R') {
538 /* We are being asked for a pathworks session ---
540 SCVAL(outbuf, 0,0x83);
544 /* only add the client's machine name to the list
545 of possibly valid usernames if we are operating
546 in share mode security */
547 if (lp_security() == SEC_SHARE) {
548 add_session_user(sconn, get_remote_machine_name());
551 reload_services(sconn->msg_ctx, True);
554 sconn->nbt.got_session = true;
557 case 0x89: /* session keepalive request
558 (some old clients produce this?) */
559 SCVAL(outbuf,0,SMBkeepalive);
563 case 0x82: /* positive session response */
564 case 0x83: /* negative session response */
565 case 0x84: /* retarget session response */
566 DEBUG(0,("Unexpected session response\n"));
569 case SMBkeepalive: /* session keepalive */
574 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
575 msg_type, msg_flags));
577 srv_send_smb(sconn->sock, outbuf, false, 0, false, NULL);
581 /****************************************************************************
583 conn POINTER CAN BE NULL HERE !
584 ****************************************************************************/
586 void reply_tcon(struct smb_request *req)
588 connection_struct *conn = req->conn;
590 char *service_buf = NULL;
591 char *password = NULL;
596 DATA_BLOB password_blob;
597 TALLOC_CTX *ctx = talloc_tos();
598 struct smbd_server_connection *sconn = req->sconn;
600 START_PROFILE(SMBtcon);
602 if (req->buflen < 4) {
603 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
604 END_PROFILE(SMBtcon);
608 p = (const char *)req->buf + 1;
609 p += srvstr_pull_req_talloc(ctx, req, &service_buf, p, STR_TERMINATE);
611 pwlen = srvstr_pull_req_talloc(ctx, req, &password, p, STR_TERMINATE);
613 p += srvstr_pull_req_talloc(ctx, req, &dev, p, STR_TERMINATE);
616 if (service_buf == NULL || password == NULL || dev == NULL) {
617 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
618 END_PROFILE(SMBtcon);
621 p = strrchr_m(service_buf,'\\');
625 service = service_buf;
628 password_blob = data_blob(password, pwlen+1);
630 conn = make_connection(sconn,service,password_blob,dev,
631 req->vuid,&nt_status);
634 data_blob_clear_free(&password_blob);
637 reply_nterror(req, nt_status);
638 END_PROFILE(SMBtcon);
642 reply_outbuf(req, 2, 0);
643 SSVAL(req->outbuf,smb_vwv0,sconn->smb1.negprot.max_recv);
644 SSVAL(req->outbuf,smb_vwv1,conn->cnum);
645 SSVAL(req->outbuf,smb_tid,conn->cnum);
647 DEBUG(3,("tcon service=%s cnum=%d\n",
648 service, conn->cnum));
650 END_PROFILE(SMBtcon);
654 /****************************************************************************
655 Reply to a tcon and X.
656 conn POINTER CAN BE NULL HERE !
657 ****************************************************************************/
659 void reply_tcon_and_X(struct smb_request *req)
661 connection_struct *conn = req->conn;
662 const char *service = NULL;
664 TALLOC_CTX *ctx = talloc_tos();
665 /* what the cleint thinks the device is */
666 char *client_devicetype = NULL;
667 /* what the server tells the client the share represents */
668 const char *server_devicetype;
674 struct smbd_server_connection *sconn = req->sconn;
676 START_PROFILE(SMBtconX);
679 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
680 END_PROFILE(SMBtconX);
684 passlen = SVAL(req->vwv+3, 0);
685 tcon_flags = SVAL(req->vwv+2, 0);
687 /* we might have to close an old one */
688 if ((tcon_flags & 0x1) && conn) {
689 close_cnum(conn,req->vuid);
694 if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) {
695 reply_force_doserror(req, ERRDOS, ERRbuftoosmall);
696 END_PROFILE(SMBtconX);
700 if (sconn->smb1.negprot.encrypted_passwords) {
701 password = data_blob_talloc(talloc_tos(), req->buf, passlen);
702 if (lp_security() == SEC_SHARE) {
704 * Security = share always has a pad byte
705 * after the password.
707 p = (const char *)req->buf + passlen + 1;
709 p = (const char *)req->buf + passlen;
712 password = data_blob_talloc(talloc_tos(), req->buf, passlen+1);
713 /* Ensure correct termination */
714 password.data[passlen]=0;
715 p = (const char *)req->buf + passlen + 1;
718 p += srvstr_pull_req_talloc(ctx, req, &path, p, STR_TERMINATE);
721 data_blob_clear_free(&password);
722 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
723 END_PROFILE(SMBtconX);
728 * the service name can be either: \\server\share
729 * or share directly like on the DELL PowerVault 705
732 q = strchr_m(path+2,'\\');
734 data_blob_clear_free(&password);
735 reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME);
736 END_PROFILE(SMBtconX);
744 p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
745 &client_devicetype, p,
746 MIN(6, smbreq_bufrem(req, p)), STR_ASCII);
748 if (client_devicetype == NULL) {
749 data_blob_clear_free(&password);
750 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
751 END_PROFILE(SMBtconX);
755 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
757 conn = make_connection(sconn, service, password, client_devicetype,
758 req->vuid, &nt_status);
761 data_blob_clear_free(&password);
764 reply_nterror(req, nt_status);
765 END_PROFILE(SMBtconX);
770 server_devicetype = "IPC";
771 else if ( IS_PRINT(conn) )
772 server_devicetype = "LPT1:";
774 server_devicetype = "A:";
776 if (get_Protocol() < PROTOCOL_NT1) {
777 reply_outbuf(req, 2, 0);
778 if (message_push_string(&req->outbuf, server_devicetype,
779 STR_TERMINATE|STR_ASCII) == -1) {
780 reply_nterror(req, NT_STATUS_NO_MEMORY);
781 END_PROFILE(SMBtconX);
785 /* NT sets the fstype of IPC$ to the null string */
786 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
788 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
789 /* Return permissions. */
793 reply_outbuf(req, 7, 0);
796 perm1 = FILE_ALL_ACCESS;
797 perm2 = FILE_ALL_ACCESS;
799 perm1 = CAN_WRITE(conn) ?
804 SIVAL(req->outbuf, smb_vwv3, perm1);
805 SIVAL(req->outbuf, smb_vwv5, perm2);
807 reply_outbuf(req, 3, 0);
810 if ((message_push_string(&req->outbuf, server_devicetype,
811 STR_TERMINATE|STR_ASCII) == -1)
812 || (message_push_string(&req->outbuf, fstype,
813 STR_TERMINATE) == -1)) {
814 reply_nterror(req, NT_STATUS_NO_MEMORY);
815 END_PROFILE(SMBtconX);
819 /* what does setting this bit do? It is set by NT4 and
820 may affect the ability to autorun mounted cdroms */
821 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
822 (lp_csc_policy(SNUM(conn)) << 2));
824 if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {
825 DEBUG(2,("Serving %s as a Dfs root\n",
826 lp_servicename(SNUM(conn)) ));
827 SSVAL(req->outbuf, smb_vwv2,
828 SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2));
833 DEBUG(3,("tconX service=%s \n",
836 /* set the incoming and outgoing tid to the just created one */
837 SSVAL(req->inbuf,smb_tid,conn->cnum);
838 SSVAL(req->outbuf,smb_tid,conn->cnum);
840 END_PROFILE(SMBtconX);
842 req->tid = conn->cnum;
847 /****************************************************************************
848 Reply to an unknown type.
849 ****************************************************************************/
851 void reply_unknown_new(struct smb_request *req, uint8 type)
853 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
854 smb_fn_name(type), type, type));
855 reply_force_doserror(req, ERRSRV, ERRunknownsmb);
859 /****************************************************************************
861 conn POINTER CAN BE NULL HERE !
862 ****************************************************************************/
864 void reply_ioctl(struct smb_request *req)
866 connection_struct *conn = req->conn;
873 START_PROFILE(SMBioctl);
876 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
877 END_PROFILE(SMBioctl);
881 device = SVAL(req->vwv+1, 0);
882 function = SVAL(req->vwv+2, 0);
883 ioctl_code = (device << 16) + function;
885 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
887 switch (ioctl_code) {
888 case IOCTL_QUERY_JOB_INFO:
892 reply_force_doserror(req, ERRSRV, ERRnosupport);
893 END_PROFILE(SMBioctl);
897 reply_outbuf(req, 8, replysize+1);
898 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
899 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
900 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
901 p = smb_buf(req->outbuf);
902 memset(p, '\0', replysize+1); /* valgrind-safe. */
903 p += 1; /* Allow for alignment */
905 switch (ioctl_code) {
906 case IOCTL_QUERY_JOB_INFO:
908 files_struct *fsp = file_fsp(
909 req, SVAL(req->vwv+0, 0));
911 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
912 END_PROFILE(SMBioctl);
916 if (fsp->print_file) {
917 SSVAL(p, 0, fsp->print_file->rap_jobid);
921 srvstr_push((char *)req->outbuf, req->flags2, p+2,
923 STR_TERMINATE|STR_ASCII);
925 srvstr_push((char *)req->outbuf, req->flags2,
926 p+18, lp_servicename(SNUM(conn)),
927 13, STR_TERMINATE|STR_ASCII);
935 END_PROFILE(SMBioctl);
939 /****************************************************************************
940 Strange checkpath NTSTATUS mapping.
941 ****************************************************************************/
943 static NTSTATUS map_checkpath_error(uint16_t flags2, NTSTATUS status)
945 /* Strange DOS error code semantics only for checkpath... */
946 if (!(flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
947 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
948 /* We need to map to ERRbadpath */
949 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
955 /****************************************************************************
956 Reply to a checkpath.
957 ****************************************************************************/
959 void reply_checkpath(struct smb_request *req)
961 connection_struct *conn = req->conn;
962 struct smb_filename *smb_fname = NULL;
965 TALLOC_CTX *ctx = talloc_tos();
967 START_PROFILE(SMBcheckpath);
969 srvstr_get_path_req(ctx, req, &name, (const char *)req->buf + 1,
970 STR_TERMINATE, &status);
972 if (!NT_STATUS_IS_OK(status)) {
973 status = map_checkpath_error(req->flags2, status);
974 reply_nterror(req, status);
975 END_PROFILE(SMBcheckpath);
979 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
981 status = filename_convert(ctx,
983 req->flags2 & FLAGS2_DFS_PATHNAMES,
989 if (!NT_STATUS_IS_OK(status)) {
990 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
991 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
993 END_PROFILE(SMBcheckpath);
999 if (!VALID_STAT(smb_fname->st) &&
1000 (SMB_VFS_STAT(conn, smb_fname) != 0)) {
1001 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",
1002 smb_fname_str_dbg(smb_fname), strerror(errno)));
1003 status = map_nt_error_from_unix(errno);
1007 if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
1008 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
1009 ERRDOS, ERRbadpath);
1013 reply_outbuf(req, 0, 0);
1016 /* We special case this - as when a Windows machine
1017 is parsing a path is steps through the components
1018 one at a time - if a component fails it expects
1019 ERRbadpath, not ERRbadfile.
1021 status = map_checkpath_error(req->flags2, status);
1022 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1024 * Windows returns different error codes if
1025 * the parent directory is valid but not the
1026 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
1027 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
1028 * if the path is invalid.
1030 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1031 ERRDOS, ERRbadpath);
1035 reply_nterror(req, status);
1038 TALLOC_FREE(smb_fname);
1039 END_PROFILE(SMBcheckpath);
1043 /****************************************************************************
1045 ****************************************************************************/
1047 void reply_getatr(struct smb_request *req)
1049 connection_struct *conn = req->conn;
1050 struct smb_filename *smb_fname = NULL;
1057 TALLOC_CTX *ctx = talloc_tos();
1058 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1060 START_PROFILE(SMBgetatr);
1062 p = (const char *)req->buf + 1;
1063 p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
1064 if (!NT_STATUS_IS_OK(status)) {
1065 reply_nterror(req, status);
1069 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1070 under WfWg - weird! */
1071 if (*fname == '\0') {
1072 mode = aHIDDEN | aDIR;
1073 if (!CAN_WRITE(conn)) {
1079 status = filename_convert(ctx,
1081 req->flags2 & FLAGS2_DFS_PATHNAMES,
1086 if (!NT_STATUS_IS_OK(status)) {
1087 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1088 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1089 ERRSRV, ERRbadpath);
1092 reply_nterror(req, status);
1095 if (!VALID_STAT(smb_fname->st) &&
1096 (SMB_VFS_STAT(conn, smb_fname) != 0)) {
1097 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
1098 smb_fname_str_dbg(smb_fname),
1100 reply_nterror(req, map_nt_error_from_unix(errno));
1104 mode = dos_mode(conn, smb_fname);
1105 size = smb_fname->st.st_ex_size;
1107 if (ask_sharemode) {
1108 struct timespec write_time_ts;
1109 struct file_id fileid;
1111 ZERO_STRUCT(write_time_ts);
1112 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1113 get_file_infos(fileid, NULL, &write_time_ts);
1114 if (!null_timespec(write_time_ts)) {
1115 update_stat_ex_mtime(&smb_fname->st, write_time_ts);
1119 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1125 reply_outbuf(req, 10, 0);
1127 SSVAL(req->outbuf,smb_vwv0,mode);
1128 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1129 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1131 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1133 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1135 if (get_Protocol() >= PROTOCOL_NT1) {
1136 SSVAL(req->outbuf, smb_flg2,
1137 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1140 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n",
1141 smb_fname_str_dbg(smb_fname), mode, (unsigned int)size));
1144 TALLOC_FREE(smb_fname);
1146 END_PROFILE(SMBgetatr);
1150 /****************************************************************************
1152 ****************************************************************************/
1154 void reply_setatr(struct smb_request *req)
1156 struct smb_file_time ft;
1157 connection_struct *conn = req->conn;
1158 struct smb_filename *smb_fname = NULL;
1164 TALLOC_CTX *ctx = talloc_tos();
1166 START_PROFILE(SMBsetatr);
1171 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1175 p = (const char *)req->buf + 1;
1176 p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 reply_nterror(req, status);
1182 status = filename_convert(ctx,
1184 req->flags2 & FLAGS2_DFS_PATHNAMES,
1189 if (!NT_STATUS_IS_OK(status)) {
1190 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1191 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1192 ERRSRV, ERRbadpath);
1195 reply_nterror(req, status);
1199 if (smb_fname->base_name[0] == '.' &&
1200 smb_fname->base_name[1] == '\0') {
1202 * Not sure here is the right place to catch this
1203 * condition. Might be moved to somewhere else later -- vl
1205 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1209 mode = SVAL(req->vwv+0, 0);
1210 mtime = srv_make_unix_date3(req->vwv+1);
1212 ft.mtime = convert_time_t_to_timespec(mtime);
1213 status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 reply_nterror(req, status);
1219 if (mode != FILE_ATTRIBUTE_NORMAL) {
1220 if (VALID_STAT_OF_DIR(smb_fname->st))
1225 if (file_set_dosmode(conn, smb_fname, mode, NULL,
1227 reply_nterror(req, map_nt_error_from_unix(errno));
1232 reply_outbuf(req, 0, 0);
1234 DEBUG(3, ("setatr name=%s mode=%d\n", smb_fname_str_dbg(smb_fname),
1237 TALLOC_FREE(smb_fname);
1238 END_PROFILE(SMBsetatr);
1242 /****************************************************************************
1244 ****************************************************************************/
1246 void reply_dskattr(struct smb_request *req)
1248 connection_struct *conn = req->conn;
1249 uint64_t dfree,dsize,bsize;
1250 START_PROFILE(SMBdskattr);
1252 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
1253 reply_nterror(req, map_nt_error_from_unix(errno));
1254 END_PROFILE(SMBdskattr);
1258 reply_outbuf(req, 5, 0);
1260 if (get_Protocol() <= PROTOCOL_LANMAN2) {
1261 double total_space, free_space;
1262 /* we need to scale this to a number that DOS6 can handle. We
1263 use floating point so we can handle large drives on systems
1264 that don't have 64 bit integers
1266 we end up displaying a maximum of 2G to DOS systems
1268 total_space = dsize * (double)bsize;
1269 free_space = dfree * (double)bsize;
1271 dsize = (uint64_t)((total_space+63*512) / (64*512));
1272 dfree = (uint64_t)((free_space+63*512) / (64*512));
1274 if (dsize > 0xFFFF) dsize = 0xFFFF;
1275 if (dfree > 0xFFFF) dfree = 0xFFFF;
1277 SSVAL(req->outbuf,smb_vwv0,dsize);
1278 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1279 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1280 SSVAL(req->outbuf,smb_vwv3,dfree);
1282 SSVAL(req->outbuf,smb_vwv0,dsize);
1283 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1284 SSVAL(req->outbuf,smb_vwv2,512);
1285 SSVAL(req->outbuf,smb_vwv3,dfree);
1288 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1290 END_PROFILE(SMBdskattr);
1295 * Utility function to split the filename from the directory.
1297 static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in,
1298 char **fname_dir_out,
1299 char **fname_mask_out)
1301 const char *p = NULL;
1302 char *fname_dir = NULL;
1303 char *fname_mask = NULL;
1305 p = strrchr_m(fname_in, '/');
1307 fname_dir = talloc_strdup(ctx, ".");
1308 fname_mask = talloc_strdup(ctx, fname_in);
1310 fname_dir = talloc_strndup(ctx, fname_in,
1311 PTR_DIFF(p, fname_in));
1312 fname_mask = talloc_strdup(ctx, p+1);
1315 if (!fname_dir || !fname_mask) {
1316 TALLOC_FREE(fname_dir);
1317 TALLOC_FREE(fname_mask);
1318 return NT_STATUS_NO_MEMORY;
1321 *fname_dir_out = fname_dir;
1322 *fname_mask_out = fname_mask;
1323 return NT_STATUS_OK;
1326 /****************************************************************************
1328 Can be called from SMBsearch, SMBffirst or SMBfunique.
1329 ****************************************************************************/
1331 void reply_search(struct smb_request *req)
1333 connection_struct *conn = req->conn;
1335 const char *mask = NULL;
1336 char *directory = NULL;
1337 struct smb_filename *smb_fname = NULL;
1341 struct timespec date;
1343 unsigned int numentries = 0;
1344 unsigned int maxentries = 0;
1345 bool finished = False;
1350 bool check_descend = False;
1351 bool expect_close = False;
1353 bool mask_contains_wcard = False;
1354 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1355 TALLOC_CTX *ctx = talloc_tos();
1356 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1357 struct dptr_struct *dirptr = NULL;
1358 struct smbd_server_connection *sconn = req->sconn;
1360 START_PROFILE(SMBsearch);
1363 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1367 if (lp_posix_pathnames()) {
1368 reply_unknown_new(req, req->cmd);
1372 /* If we were called as SMBffirst then we must expect close. */
1373 if(req->cmd == SMBffirst) {
1374 expect_close = True;
1377 reply_outbuf(req, 1, 3);
1378 maxentries = SVAL(req->vwv+0, 0);
1379 dirtype = SVAL(req->vwv+1, 0);
1380 p = (const char *)req->buf + 1;
1381 p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
1382 &nt_status, &mask_contains_wcard);
1383 if (!NT_STATUS_IS_OK(nt_status)) {
1384 reply_nterror(req, nt_status);
1389 status_len = SVAL(p, 0);
1392 /* dirtype &= ~aDIR; */
1394 if (status_len == 0) {
1395 nt_status = filename_convert(ctx, conn,
1396 req->flags2 & FLAGS2_DFS_PATHNAMES,
1398 UCF_ALWAYS_ALLOW_WCARD_LCOMP,
1399 &mask_contains_wcard,
1401 if (!NT_STATUS_IS_OK(nt_status)) {
1402 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1403 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1404 ERRSRV, ERRbadpath);
1407 reply_nterror(req, nt_status);
1411 directory = smb_fname->base_name;
1413 p = strrchr_m(directory,'/');
1414 if ((p != NULL) && (*directory != '/')) {
1416 directory = talloc_strndup(ctx, directory,
1417 PTR_DIFF(p, directory));
1420 directory = talloc_strdup(ctx,".");
1424 reply_nterror(req, NT_STATUS_NO_MEMORY);
1428 memset((char *)status,'\0',21);
1429 SCVAL(status,0,(dirtype & 0x1F));
1431 nt_status = dptr_create(conn,
1437 mask_contains_wcard,
1440 if (!NT_STATUS_IS_OK(nt_status)) {
1441 reply_nterror(req, nt_status);
1444 dptr_num = dptr_dnum(dirptr);
1447 const char *dirpath;
1449 memcpy(status,p,21);
1450 status_dirtype = CVAL(status,0) & 0x1F;
1451 if (status_dirtype != (dirtype & 0x1F)) {
1452 dirtype = status_dirtype;
1455 dirptr = dptr_fetch(sconn, status+12,&dptr_num);
1459 dirpath = dptr_path(sconn, dptr_num);
1460 directory = talloc_strdup(ctx, dirpath);
1462 reply_nterror(req, NT_STATUS_NO_MEMORY);
1466 mask = dptr_wcard(sconn, dptr_num);
1471 * For a 'continue' search we have no string. So
1472 * check from the initial saved string.
1474 mask_contains_wcard = ms_has_wild(mask);
1475 dirtype = dptr_attr(sconn, dptr_num);
1478 DEBUG(4,("dptr_num is %d\n",dptr_num));
1480 /* Initialize per SMBsearch/SMBffirst/SMBfunique operation data */
1481 dptr_init_search_op(dirptr);
1483 if ((dirtype&0x1F) == aVOLID) {
1484 char buf[DIR_STRUCT_SIZE];
1485 memcpy(buf,status,21);
1486 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1487 0,aVOLID,0,!allow_long_path_components)) {
1488 reply_nterror(req, NT_STATUS_NO_MEMORY);
1491 dptr_fill(sconn, buf+12,dptr_num);
1492 if (dptr_zero(buf+12) && (status_len==0)) {
1497 if (message_push_blob(&req->outbuf,
1498 data_blob_const(buf, sizeof(buf)))
1500 reply_nterror(req, NT_STATUS_NO_MEMORY);
1508 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1511 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1512 directory,lp_dontdescend(SNUM(conn))));
1513 if (in_list(directory, lp_dontdescend(SNUM(conn)),True)) {
1514 check_descend = True;
1517 for (i=numentries;(i<maxentries) && !finished;i++) {
1518 finished = !get_dir_entry(ctx,
1529 char buf[DIR_STRUCT_SIZE];
1530 memcpy(buf,status,21);
1531 if (!make_dir_struct(ctx,
1537 convert_timespec_to_time_t(date),
1538 !allow_long_path_components)) {
1539 reply_nterror(req, NT_STATUS_NO_MEMORY);
1542 if (!dptr_fill(sconn, buf+12,dptr_num)) {
1545 if (message_push_blob(&req->outbuf,
1546 data_blob_const(buf, sizeof(buf)))
1548 reply_nterror(req, NT_STATUS_NO_MEMORY);
1558 /* If we were called as SMBffirst with smb_search_id == NULL
1559 and no entries were found then return error and close dirptr
1562 if (numentries == 0) {
1563 dptr_close(sconn, &dptr_num);
1564 } else if(expect_close && status_len == 0) {
1565 /* Close the dptr - we know it's gone */
1566 dptr_close(sconn, &dptr_num);
1569 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1570 if(dptr_num >= 0 && req->cmd == SMBfunique) {
1571 dptr_close(sconn, &dptr_num);
1574 if ((numentries == 0) && !mask_contains_wcard) {
1575 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1579 SSVAL(req->outbuf,smb_vwv0,numentries);
1580 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1581 SCVAL(smb_buf(req->outbuf),0,5);
1582 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1584 /* The replies here are never long name. */
1585 SSVAL(req->outbuf, smb_flg2,
1586 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1587 if (!allow_long_path_components) {
1588 SSVAL(req->outbuf, smb_flg2,
1589 SVAL(req->outbuf, smb_flg2)
1590 & (~FLAGS2_LONG_PATH_COMPONENTS));
1593 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1594 SSVAL(req->outbuf, smb_flg2,
1595 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1597 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1598 smb_fn_name(req->cmd),
1605 TALLOC_FREE(directory);
1606 TALLOC_FREE(smb_fname);
1607 END_PROFILE(SMBsearch);
1611 /****************************************************************************
1612 Reply to a fclose (stop directory search).
1613 ****************************************************************************/
1615 void reply_fclose(struct smb_request *req)
1623 bool path_contains_wcard = False;
1624 TALLOC_CTX *ctx = talloc_tos();
1625 struct smbd_server_connection *sconn = req->sconn;
1627 START_PROFILE(SMBfclose);
1629 if (lp_posix_pathnames()) {
1630 reply_unknown_new(req, req->cmd);
1631 END_PROFILE(SMBfclose);
1635 p = (const char *)req->buf + 1;
1636 p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
1637 &err, &path_contains_wcard);
1638 if (!NT_STATUS_IS_OK(err)) {
1639 reply_nterror(req, err);
1640 END_PROFILE(SMBfclose);
1644 status_len = SVAL(p,0);
1647 if (status_len == 0) {
1648 reply_force_doserror(req, ERRSRV, ERRsrverror);
1649 END_PROFILE(SMBfclose);
1653 memcpy(status,p,21);
1655 if(dptr_fetch(sconn, status+12,&dptr_num)) {
1656 /* Close the dptr - we know it's gone */
1657 dptr_close(sconn, &dptr_num);
1660 reply_outbuf(req, 1, 0);
1661 SSVAL(req->outbuf,smb_vwv0,0);
1663 DEBUG(3,("search close\n"));
1665 END_PROFILE(SMBfclose);
1669 /****************************************************************************
1671 ****************************************************************************/
1673 void reply_open(struct smb_request *req)
1675 connection_struct *conn = req->conn;
1676 struct smb_filename *smb_fname = NULL;
1688 uint32 create_disposition;
1689 uint32 create_options = 0;
1690 uint32_t private_flags = 0;
1692 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1693 TALLOC_CTX *ctx = talloc_tos();
1695 START_PROFILE(SMBopen);
1698 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1702 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1703 deny_mode = SVAL(req->vwv+0, 0);
1704 dos_attr = SVAL(req->vwv+1, 0);
1706 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
1707 STR_TERMINATE, &status);
1708 if (!NT_STATUS_IS_OK(status)) {
1709 reply_nterror(req, status);
1713 status = filename_convert(ctx,
1715 req->flags2 & FLAGS2_DFS_PATHNAMES,
1720 if (!NT_STATUS_IS_OK(status)) {
1721 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1722 reply_botherror(req,
1723 NT_STATUS_PATH_NOT_COVERED,
1724 ERRSRV, ERRbadpath);
1727 reply_nterror(req, status);
1731 if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
1732 OPENX_FILE_EXISTS_OPEN, &access_mask,
1733 &share_mode, &create_disposition,
1734 &create_options, &private_flags)) {
1735 reply_force_doserror(req, ERRDOS, ERRbadaccess);
1739 status = SMB_VFS_CREATE_FILE(
1742 0, /* root_dir_fid */
1743 smb_fname, /* fname */
1744 access_mask, /* access_mask */
1745 share_mode, /* share_access */
1746 create_disposition, /* create_disposition*/
1747 create_options, /* create_options */
1748 dos_attr, /* file_attributes */
1749 oplock_request, /* oplock_request */
1750 0, /* allocation_size */
1757 if (!NT_STATUS_IS_OK(status)) {
1758 if (open_was_deferred(req->mid)) {
1759 /* We have re-scheduled this call. */
1762 reply_openerror(req, status);
1766 size = smb_fname->st.st_ex_size;
1767 fattr = dos_mode(conn, smb_fname);
1769 /* Deal with other possible opens having a modified
1771 if (ask_sharemode) {
1772 struct timespec write_time_ts;
1774 ZERO_STRUCT(write_time_ts);
1775 get_file_infos(fsp->file_id, NULL, &write_time_ts);
1776 if (!null_timespec(write_time_ts)) {
1777 update_stat_ex_mtime(&smb_fname->st, write_time_ts);
1781 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1784 DEBUG(3,("attempt to open a directory %s\n",
1786 close_file(req, fsp, ERROR_CLOSE);
1787 reply_botherror(req, NT_STATUS_ACCESS_DENIED,
1788 ERRDOS, ERRnoaccess);
1792 reply_outbuf(req, 7, 0);
1793 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1794 SSVAL(req->outbuf,smb_vwv1,fattr);
1795 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1796 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1798 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1800 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1801 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1803 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1804 SCVAL(req->outbuf,smb_flg,
1805 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1808 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1809 SCVAL(req->outbuf,smb_flg,
1810 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1813 TALLOC_FREE(smb_fname);
1814 END_PROFILE(SMBopen);
1818 /****************************************************************************
1819 Reply to an open and X.
1820 ****************************************************************************/
1822 void reply_open_and_X(struct smb_request *req)
1824 connection_struct *conn = req->conn;
1825 struct smb_filename *smb_fname = NULL;
1830 /* Breakout the oplock request bits so we can set the
1831 reply bits separately. */
1832 int ex_oplock_request;
1833 int core_oplock_request;
1836 int smb_sattr = SVAL(req->vwv+4, 0);
1837 uint32 smb_time = make_unix_date3(req->vwv+6);
1845 uint64_t allocation_size;
1846 ssize_t retval = -1;
1849 uint32 create_disposition;
1850 uint32 create_options = 0;
1851 uint32_t private_flags = 0;
1852 TALLOC_CTX *ctx = talloc_tos();
1854 START_PROFILE(SMBopenX);
1856 if (req->wct < 15) {
1857 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1861 open_flags = SVAL(req->vwv+2, 0);
1862 deny_mode = SVAL(req->vwv+3, 0);
1863 smb_attr = SVAL(req->vwv+5, 0);
1864 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1865 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1866 oplock_request = ex_oplock_request | core_oplock_request;
1867 smb_ofun = SVAL(req->vwv+8, 0);
1868 allocation_size = (uint64_t)IVAL(req->vwv+9, 0);
1870 /* If it's an IPC, pass off the pipe handler. */
1872 if (lp_nt_pipe_support()) {
1873 reply_open_pipe_and_X(conn, req);
1875 reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
1880 /* XXXX we need to handle passed times, sattr and flags */
1881 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
1882 STR_TERMINATE, &status);
1883 if (!NT_STATUS_IS_OK(status)) {
1884 reply_nterror(req, status);
1888 status = filename_convert(ctx,
1890 req->flags2 & FLAGS2_DFS_PATHNAMES,
1895 if (!NT_STATUS_IS_OK(status)) {
1896 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1897 reply_botherror(req,
1898 NT_STATUS_PATH_NOT_COVERED,
1899 ERRSRV, ERRbadpath);
1902 reply_nterror(req, status);
1906 if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
1907 &access_mask, &share_mode,
1908 &create_disposition,
1911 reply_force_doserror(req, ERRDOS, ERRbadaccess);
1915 status = SMB_VFS_CREATE_FILE(
1918 0, /* root_dir_fid */
1919 smb_fname, /* fname */
1920 access_mask, /* access_mask */
1921 share_mode, /* share_access */
1922 create_disposition, /* create_disposition*/
1923 create_options, /* create_options */
1924 smb_attr, /* file_attributes */
1925 oplock_request, /* oplock_request */
1926 0, /* allocation_size */
1931 &smb_action); /* pinfo */
1933 if (!NT_STATUS_IS_OK(status)) {
1934 if (open_was_deferred(req->mid)) {
1935 /* We have re-scheduled this call. */
1938 reply_openerror(req, status);
1942 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1943 if the file is truncated or created. */
1944 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1945 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1946 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1947 close_file(req, fsp, ERROR_CLOSE);
1948 reply_nterror(req, NT_STATUS_DISK_FULL);
1951 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1953 close_file(req, fsp, ERROR_CLOSE);
1954 reply_nterror(req, NT_STATUS_DISK_FULL);
1957 smb_fname->st.st_ex_size =
1958 SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st);
1961 fattr = dos_mode(conn, smb_fname);
1962 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1964 close_file(req, fsp, ERROR_CLOSE);
1965 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1969 /* If the caller set the extended oplock request bit
1970 and we granted one (by whatever means) - set the
1971 correct bit for extended oplock reply.
1974 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1975 smb_action |= EXTENDED_OPLOCK_GRANTED;
1978 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1979 smb_action |= EXTENDED_OPLOCK_GRANTED;
1982 /* If the caller set the core oplock request bit
1983 and we granted one (by whatever means) - set the
1984 correct bit for core oplock reply.
1987 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1988 reply_outbuf(req, 19, 0);
1990 reply_outbuf(req, 15, 0);
1993 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1994 SCVAL(req->outbuf, smb_flg,
1995 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1998 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1999 SCVAL(req->outbuf, smb_flg,
2000 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2003 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
2004 SSVAL(req->outbuf,smb_vwv3,fattr);
2005 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
2006 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
2008 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
2010 SIVAL(req->outbuf,smb_vwv6,(uint32)smb_fname->st.st_ex_size);
2011 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
2012 SSVAL(req->outbuf,smb_vwv11,smb_action);
2014 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
2015 SIVAL(req->outbuf, smb_vwv15, SEC_STD_ALL);
2020 TALLOC_FREE(smb_fname);
2021 END_PROFILE(SMBopenX);
2025 /****************************************************************************
2026 Reply to a SMBulogoffX.
2027 ****************************************************************************/
2029 void reply_ulogoffX(struct smb_request *req)
2031 struct smbd_server_connection *sconn = req->sconn;
2034 START_PROFILE(SMBulogoffX);
2036 vuser = get_valid_user_struct(sconn, req->vuid);
2039 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
2043 /* in user level security we are supposed to close any files
2044 open by this user */
2045 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
2046 file_close_user(req->vuid);
2049 invalidate_vuid(sconn, req->vuid);
2051 reply_outbuf(req, 2, 0);
2053 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
2055 END_PROFILE(SMBulogoffX);
2056 req->vuid = UID_FIELD_INVALID;
2060 /****************************************************************************
2061 Reply to a mknew or a create.
2062 ****************************************************************************/
2064 void reply_mknew(struct smb_request *req)
2066 connection_struct *conn = req->conn;
2067 struct smb_filename *smb_fname = NULL;
2070 struct smb_file_time ft;
2072 int oplock_request = 0;
2074 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2075 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2076 uint32 create_disposition;
2077 uint32 create_options = 0;
2078 TALLOC_CTX *ctx = talloc_tos();
2080 START_PROFILE(SMBcreate);
2084 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2088 fattr = SVAL(req->vwv+0, 0);
2089 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2092 ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
2094 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
2095 STR_TERMINATE, &status);
2096 if (!NT_STATUS_IS_OK(status)) {
2097 reply_nterror(req, status);
2101 status = filename_convert(ctx,
2103 req->flags2 & FLAGS2_DFS_PATHNAMES,
2108 if (!NT_STATUS_IS_OK(status)) {
2109 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2110 reply_botherror(req,
2111 NT_STATUS_PATH_NOT_COVERED,
2112 ERRSRV, ERRbadpath);
2115 reply_nterror(req, status);
2119 if (fattr & aVOLID) {
2120 DEBUG(0,("Attempt to create file (%s) with volid set - "
2121 "please report this\n",
2122 smb_fname_str_dbg(smb_fname)));
2125 if(req->cmd == SMBmknew) {
2126 /* We should fail if file exists. */
2127 create_disposition = FILE_CREATE;
2129 /* Create if file doesn't exist, truncate if it does. */
2130 create_disposition = FILE_OVERWRITE_IF;
2133 status = SMB_VFS_CREATE_FILE(
2136 0, /* root_dir_fid */
2137 smb_fname, /* fname */
2138 access_mask, /* access_mask */
2139 share_mode, /* share_access */
2140 create_disposition, /* create_disposition*/
2141 create_options, /* create_options */
2142 fattr, /* file_attributes */
2143 oplock_request, /* oplock_request */
2144 0, /* allocation_size */
2145 0, /* private_flags */
2151 if (!NT_STATUS_IS_OK(status)) {
2152 if (open_was_deferred(req->mid)) {
2153 /* We have re-scheduled this call. */
2156 reply_openerror(req, status);
2160 ft.atime = smb_fname->st.st_ex_atime; /* atime. */
2161 status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
2162 if (!NT_STATUS_IS_OK(status)) {
2163 END_PROFILE(SMBcreate);
2167 reply_outbuf(req, 1, 0);
2168 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2170 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2171 SCVAL(req->outbuf,smb_flg,
2172 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2175 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2176 SCVAL(req->outbuf,smb_flg,
2177 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2180 DEBUG(2, ("reply_mknew: file %s\n", smb_fname_str_dbg(smb_fname)));
2181 DEBUG(3, ("reply_mknew %s fd=%d dmode=0x%x\n",
2182 smb_fname_str_dbg(smb_fname), fsp->fh->fd,
2183 (unsigned int)fattr));
2186 TALLOC_FREE(smb_fname);
2187 END_PROFILE(SMBcreate);
2191 /****************************************************************************
2192 Reply to a create temporary file.
2193 ****************************************************************************/
2195 void reply_ctemp(struct smb_request *req)
2197 connection_struct *conn = req->conn;
2198 struct smb_filename *smb_fname = NULL;
2206 TALLOC_CTX *ctx = talloc_tos();
2208 START_PROFILE(SMBctemp);
2211 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2215 fattr = SVAL(req->vwv+0, 0);
2216 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2218 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
2219 STR_TERMINATE, &status);
2220 if (!NT_STATUS_IS_OK(status)) {
2221 reply_nterror(req, status);
2225 fname = talloc_asprintf(ctx,
2229 fname = talloc_strdup(ctx, "TMXXXXXX");
2233 reply_nterror(req, NT_STATUS_NO_MEMORY);
2237 status = filename_convert(ctx, conn,
2238 req->flags2 & FLAGS2_DFS_PATHNAMES,
2243 if (!NT_STATUS_IS_OK(status)) {
2244 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2245 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2246 ERRSRV, ERRbadpath);
2249 reply_nterror(req, status);
2253 tmpfd = mkstemp(smb_fname->base_name);
2255 reply_nterror(req, map_nt_error_from_unix(errno));
2259 SMB_VFS_STAT(conn, smb_fname);
2261 /* We should fail if file does not exist. */
2262 status = SMB_VFS_CREATE_FILE(
2265 0, /* root_dir_fid */
2266 smb_fname, /* fname */
2267 FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */
2268 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
2269 FILE_OPEN, /* create_disposition*/
2270 0, /* create_options */
2271 fattr, /* file_attributes */
2272 oplock_request, /* oplock_request */
2273 0, /* allocation_size */
2274 0, /* private_flags */
2280 /* close fd from mkstemp() */
2283 if (!NT_STATUS_IS_OK(status)) {
2284 if (open_was_deferred(req->mid)) {
2285 /* We have re-scheduled this call. */
2288 reply_openerror(req, status);
2292 reply_outbuf(req, 1, 0);
2293 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2295 /* the returned filename is relative to the directory */
2296 s = strrchr_m(fsp->fsp_name->base_name, '/');
2298 s = fsp->fsp_name->base_name;
2304 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2305 thing in the byte section. JRA */
2306 SSVALS(p, 0, -1); /* what is this? not in spec */
2308 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2310 reply_nterror(req, NT_STATUS_NO_MEMORY);
2314 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2315 SCVAL(req->outbuf, smb_flg,
2316 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2319 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2320 SCVAL(req->outbuf, smb_flg,
2321 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2324 DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp)));
2325 DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp),
2326 fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
2328 TALLOC_FREE(smb_fname);
2329 END_PROFILE(SMBctemp);
2333 /*******************************************************************
2334 Check if a user is allowed to rename a file.
2335 ********************************************************************/
2337 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2342 if (!CAN_WRITE(conn)) {
2343 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2346 fmode = dos_mode(conn, fsp->fsp_name);
2347 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2348 return NT_STATUS_NO_SUCH_FILE;
2351 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
2352 if (fsp->posix_open) {
2353 return NT_STATUS_OK;
2356 /* If no pathnames are open below this
2357 directory, allow the rename. */
2359 if (file_find_subpath(fsp)) {
2360 return NT_STATUS_ACCESS_DENIED;
2362 return NT_STATUS_OK;
2365 if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2366 return NT_STATUS_OK;
2369 return NT_STATUS_ACCESS_DENIED;
2372 /*******************************************************************
2373 * unlink a file with all relevant access checks
2374 *******************************************************************/
2376 static NTSTATUS do_unlink(connection_struct *conn,
2377 struct smb_request *req,
2378 struct smb_filename *smb_fname,
2383 uint32 dirtype_orig = dirtype;
2386 bool posix_paths = lp_posix_pathnames();
2388 DEBUG(10,("do_unlink: %s, dirtype = %d\n",
2389 smb_fname_str_dbg(smb_fname),
2392 if (!CAN_WRITE(conn)) {
2393 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2397 ret = SMB_VFS_LSTAT(conn, smb_fname);
2399 ret = SMB_VFS_STAT(conn, smb_fname);
2402 return map_nt_error_from_unix(errno);
2405 fattr = dos_mode(conn, smb_fname);
2407 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2408 dirtype = aDIR|aARCH|aRONLY;
2411 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2413 return NT_STATUS_NO_SUCH_FILE;
2416 if (!dir_check_ftype(conn, fattr, dirtype)) {
2418 return NT_STATUS_FILE_IS_A_DIRECTORY;
2420 return NT_STATUS_NO_SUCH_FILE;
2423 if (dirtype_orig & 0x8000) {
2424 /* These will never be set for POSIX. */
2425 return NT_STATUS_NO_SUCH_FILE;
2429 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2430 return NT_STATUS_FILE_IS_A_DIRECTORY;
2433 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2434 return NT_STATUS_NO_SUCH_FILE;
2437 if (dirtype & 0xFF00) {
2438 /* These will never be set for POSIX. */
2439 return NT_STATUS_NO_SUCH_FILE;
2444 return NT_STATUS_NO_SUCH_FILE;
2447 /* Can't delete a directory. */
2449 return NT_STATUS_FILE_IS_A_DIRECTORY;
2454 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2455 return NT_STATUS_OBJECT_NAME_INVALID;
2456 #endif /* JRATEST */
2458 /* On open checks the open itself will check the share mode, so
2459 don't do it here as we'll get it wrong. */
2461 status = SMB_VFS_CREATE_FILE
2464 0, /* root_dir_fid */
2465 smb_fname, /* fname */
2466 DELETE_ACCESS, /* access_mask */
2467 FILE_SHARE_NONE, /* share_access */
2468 FILE_OPEN, /* create_disposition*/
2469 FILE_NON_DIRECTORY_FILE, /* create_options */
2470 /* file_attributes */
2471 posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 :
2472 FILE_ATTRIBUTE_NORMAL,
2473 0, /* oplock_request */
2474 0, /* allocation_size */
2475 0, /* private_flags */
2481 if (!NT_STATUS_IS_OK(status)) {
2482 DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
2483 nt_errstr(status)));
2487 status = can_set_delete_on_close(fsp, fattr);
2488 if (!NT_STATUS_IS_OK(status)) {
2489 DEBUG(10, ("do_unlink can_set_delete_on_close for file %s - "
2491 smb_fname_str_dbg(smb_fname),
2492 nt_errstr(status)));
2493 close_file(req, fsp, NORMAL_CLOSE);
2497 /* The set is across all open files on this dev/inode pair. */
2498 if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
2499 close_file(req, fsp, NORMAL_CLOSE);
2500 return NT_STATUS_ACCESS_DENIED;
2503 return close_file(req, fsp, NORMAL_CLOSE);
2506 /****************************************************************************
2507 The guts of the unlink command, split out so it may be called by the NT SMB
2509 ****************************************************************************/
2511 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2512 uint32 dirtype, struct smb_filename *smb_fname,
2515 char *fname_dir = NULL;
2516 char *fname_mask = NULL;
2518 NTSTATUS status = NT_STATUS_OK;
2519 TALLOC_CTX *ctx = talloc_tos();
2521 /* Split up the directory from the filename/mask. */
2522 status = split_fname_dir_mask(ctx, smb_fname->base_name,
2523 &fname_dir, &fname_mask);
2524 if (!NT_STATUS_IS_OK(status)) {
2529 * We should only check the mangled cache
2530 * here if unix_convert failed. This means
2531 * that the path in 'mask' doesn't exist
2532 * on the file system and so we need to look
2533 * for a possible mangle. This patch from
2534 * Tine Smukavec <valentin.smukavec@hermes.si>.
2537 if (!VALID_STAT(smb_fname->st) &&
2538 mangle_is_mangled(fname_mask, conn->params)) {
2539 char *new_mask = NULL;
2540 mangle_lookup_name_from_8_3(ctx, fname_mask,
2541 &new_mask, conn->params);
2543 TALLOC_FREE(fname_mask);
2544 fname_mask = new_mask;
2551 * Only one file needs to be unlinked. Append the mask back
2552 * onto the directory.
2554 TALLOC_FREE(smb_fname->base_name);
2555 smb_fname->base_name = talloc_asprintf(smb_fname,
2559 if (!smb_fname->base_name) {
2560 status = NT_STATUS_NO_MEMORY;
2564 dirtype = FILE_ATTRIBUTE_NORMAL;
2567 status = check_name(conn, smb_fname->base_name);
2568 if (!NT_STATUS_IS_OK(status)) {
2572 status = do_unlink(conn, req, smb_fname, dirtype);
2573 if (!NT_STATUS_IS_OK(status)) {
2579 struct smb_Dir *dir_hnd = NULL;
2581 const char *dname = NULL;
2582 char *talloced = NULL;
2584 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2585 status = NT_STATUS_OBJECT_NAME_INVALID;
2589 if (strequal(fname_mask,"????????.???")) {
2590 TALLOC_FREE(fname_mask);
2591 fname_mask = talloc_strdup(ctx, "*");
2593 status = NT_STATUS_NO_MEMORY;
2598 status = check_name(conn, fname_dir);
2599 if (!NT_STATUS_IS_OK(status)) {
2603 dir_hnd = OpenDir(talloc_tos(), conn, fname_dir, fname_mask,
2605 if (dir_hnd == NULL) {
2606 status = map_nt_error_from_unix(errno);
2610 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2611 the pattern matches against the long name, otherwise the short name
2612 We don't implement this yet XXXX
2615 status = NT_STATUS_NO_SUCH_FILE;
2617 while ((dname = ReadDirName(dir_hnd, &offset,
2618 &smb_fname->st, &talloced))) {
2619 TALLOC_CTX *frame = talloc_stackframe();
2621 if (!is_visible_file(conn, fname_dir, dname,
2622 &smb_fname->st, true)) {
2624 TALLOC_FREE(talloced);
2628 /* Quick check for "." and ".." */
2629 if (ISDOT(dname) || ISDOTDOT(dname)) {
2631 TALLOC_FREE(talloced);
2635 if(!mask_match(dname, fname_mask,
2636 conn->case_sensitive)) {
2638 TALLOC_FREE(talloced);
2642 TALLOC_FREE(smb_fname->base_name);
2643 smb_fname->base_name =
2644 talloc_asprintf(smb_fname, "%s/%s",
2647 if (!smb_fname->base_name) {
2648 TALLOC_FREE(dir_hnd);
2649 status = NT_STATUS_NO_MEMORY;
2651 TALLOC_FREE(talloced);
2655 status = check_name(conn, smb_fname->base_name);
2656 if (!NT_STATUS_IS_OK(status)) {
2657 TALLOC_FREE(dir_hnd);
2659 TALLOC_FREE(talloced);
2663 status = do_unlink(conn, req, smb_fname, dirtype);
2664 if (!NT_STATUS_IS_OK(status)) {
2666 TALLOC_FREE(talloced);
2671 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2672 smb_fname->base_name));
2675 TALLOC_FREE(talloced);
2677 TALLOC_FREE(dir_hnd);
2680 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2681 status = map_nt_error_from_unix(errno);
2685 TALLOC_FREE(fname_dir);
2686 TALLOC_FREE(fname_mask);
2690 /****************************************************************************
2692 ****************************************************************************/
2694 void reply_unlink(struct smb_request *req)
2696 connection_struct *conn = req->conn;
2698 struct smb_filename *smb_fname = NULL;
2701 bool path_contains_wcard = False;
2702 TALLOC_CTX *ctx = talloc_tos();
2704 START_PROFILE(SMBunlink);
2707 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2711 dirtype = SVAL(req->vwv+0, 0);
2713 srvstr_get_path_req_wcard(ctx, req, &name, (const char *)req->buf + 1,
2714 STR_TERMINATE, &status,
2715 &path_contains_wcard);
2716 if (!NT_STATUS_IS_OK(status)) {
2717 reply_nterror(req, status);
2721 status = filename_convert(ctx, conn,
2722 req->flags2 & FLAGS2_DFS_PATHNAMES,
2724 UCF_COND_ALLOW_WCARD_LCOMP,
2725 &path_contains_wcard,
2727 if (!NT_STATUS_IS_OK(status)) {
2728 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2729 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2730 ERRSRV, ERRbadpath);
2733 reply_nterror(req, status);
2737 DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname)));
2739 status = unlink_internals(conn, req, dirtype, smb_fname,
2740 path_contains_wcard);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 if (open_was_deferred(req->mid)) {
2743 /* We have re-scheduled this call. */
2746 reply_nterror(req, status);
2750 reply_outbuf(req, 0, 0);
2752 TALLOC_FREE(smb_fname);
2753 END_PROFILE(SMBunlink);
2757 /****************************************************************************
2759 ****************************************************************************/
2761 static void fail_readraw(void)
2763 const char *errstr = talloc_asprintf(talloc_tos(),
2764 "FAIL ! reply_readbraw: socket write fail (%s)",
2769 exit_server_cleanly(errstr);
2772 /****************************************************************************
2773 Fake (read/write) sendfile. Returns -1 on read or write fail.
2774 ****************************************************************************/
2776 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2780 size_t tosend = nread;
2787 bufsize = MIN(nread, 65536);
2789 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2793 while (tosend > 0) {
2797 if (tosend > bufsize) {
2802 ret = read_file(fsp,buf,startpos,cur_read);
2808 /* If we had a short read, fill with zeros. */
2809 if (ret < cur_read) {
2810 memset(buf + ret, '\0', cur_read - ret);
2813 if (write_data(fsp->conn->sconn->sock, buf, cur_read)
2815 char addr[INET6_ADDRSTRLEN];
2817 * Try and give an error message saying what
2820 DEBUG(0, ("write_data failed for client %s. "
2822 get_peer_addr(fsp->conn->sconn->sock, addr,
2829 startpos += cur_read;
2833 return (ssize_t)nread;
2836 #if defined(WITH_SENDFILE)
2837 /****************************************************************************
2838 Deal with the case of sendfile reading less bytes from the file than
2839 requested. Fill with zeros (all we can do).
2840 ****************************************************************************/
2842 static void sendfile_short_send(files_struct *fsp,
2847 #define SHORT_SEND_BUFSIZE 1024
2848 if (nread < headersize) {
2849 DEBUG(0,("sendfile_short_send: sendfile failed to send "
2850 "header for file %s (%s). Terminating\n",
2851 fsp_str_dbg(fsp), strerror(errno)));
2852 exit_server_cleanly("sendfile_short_send failed");
2855 nread -= headersize;
2857 if (nread < smb_maxcnt) {
2858 char *buf = SMB_CALLOC_ARRAY(char, SHORT_SEND_BUFSIZE);
2860 exit_server_cleanly("sendfile_short_send: "
2864 DEBUG(0,("sendfile_short_send: filling truncated file %s "
2865 "with zeros !\n", fsp_str_dbg(fsp)));
2867 while (nread < smb_maxcnt) {
2869 * We asked for the real file size and told sendfile
2870 * to not go beyond the end of the file. But it can
2871 * happen that in between our fstat call and the
2872 * sendfile call the file was truncated. This is very
2873 * bad because we have already announced the larger
2874 * number of bytes to the client.
2876 * The best we can do now is to send 0-bytes, just as
2877 * a read from a hole in a sparse file would do.
2879 * This should happen rarely enough that I don't care
2880 * about efficiency here :-)
2884 to_write = MIN(SHORT_SEND_BUFSIZE, smb_maxcnt - nread);
2885 if (write_data(fsp->conn->sconn->sock, buf, to_write)
2887 char addr[INET6_ADDRSTRLEN];
2889 * Try and give an error message saying what
2892 DEBUG(0, ("write_data failed for client %s. "
2895 fsp->conn->sconn->sock, addr,
2898 exit_server_cleanly("sendfile_short_send: "
2899 "write_data failed");
2906 #endif /* defined WITH_SENDFILE */
2908 /****************************************************************************
2909 Return a readbraw error (4 bytes of zero).
2910 ****************************************************************************/
2912 static void reply_readbraw_error(struct smbd_server_connection *sconn)
2918 smbd_lock_socket(sconn);
2919 if (write_data(sconn->sock,header,4) != 4) {
2920 char addr[INET6_ADDRSTRLEN];
2922 * Try and give an error message saying what
2925 DEBUG(0, ("write_data failed for client %s. "
2927 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2932 smbd_unlock_socket(sconn);
2935 /****************************************************************************
2936 Use sendfile in readbraw.
2937 ****************************************************************************/
2939 static void send_file_readbraw(connection_struct *conn,
2940 struct smb_request *req,
2946 struct smbd_server_connection *sconn = req->sconn;
2947 char *outbuf = NULL;
2950 #if defined(WITH_SENDFILE)
2952 * We can only use sendfile on a non-chained packet
2953 * but we can use on a non-oplocked file. tridge proved this
2954 * on a train in Germany :-). JRA.
2955 * reply_readbraw has already checked the length.
2958 if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
2959 (fsp->wcp == NULL) &&
2960 lp_use_sendfile(SNUM(conn), req->sconn->smb1.signing_state) ) {
2961 ssize_t sendfile_read = -1;
2963 DATA_BLOB header_blob;
2965 _smb_setlen(header,nread);
2966 header_blob = data_blob_const(header, 4);
2968 sendfile_read = SMB_VFS_SENDFILE(sconn->sock, fsp,
2969 &header_blob, startpos,
2971 if (sendfile_read == -1) {
2972 /* Returning ENOSYS means no data at all was sent.
2973 * Do this as a normal read. */
2974 if (errno == ENOSYS) {
2975 goto normal_readbraw;
2979 * Special hack for broken Linux with no working sendfile. If we
2980 * return EINTR we sent the header but not the rest of the data.
2981 * Fake this up by doing read/write calls.
2983 if (errno == EINTR) {
2984 /* Ensure we don't do this again. */
2985 set_use_sendfile(SNUM(conn), False);
2986 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2988 if (fake_sendfile(fsp, startpos, nread) == -1) {
2989 DEBUG(0,("send_file_readbraw: "
2990 "fake_sendfile failed for "
2994 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2999 DEBUG(0,("send_file_readbraw: sendfile failed for "
3000 "file %s (%s). Terminating\n",
3001 fsp_str_dbg(fsp), strerror(errno)));
3002 exit_server_cleanly("send_file_readbraw sendfile failed");
3003 } else if (sendfile_read == 0) {
3005 * Some sendfile implementations return 0 to indicate
3006 * that there was a short read, but nothing was
3007 * actually written to the socket. In this case,
3008 * fallback to the normal read path so the header gets
3009 * the correct byte count.
3011 DEBUG(3, ("send_file_readbraw: sendfile sent zero "
3012 "bytes falling back to the normal read: "
3013 "%s\n", fsp_str_dbg(fsp)));
3014 goto normal_readbraw;
3017 /* Deal with possible short send. */
3018 if (sendfile_read != 4+nread) {
3019 sendfile_short_send(fsp, sendfile_read, 4, nread);
3027 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
3029 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
3030 (unsigned)(nread+4)));
3031 reply_readbraw_error(sconn);
3036 ret = read_file(fsp,outbuf+4,startpos,nread);
3037 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
3046 _smb_setlen(outbuf,ret);
3047 if (write_data(sconn->sock, outbuf, 4+ret) != 4+ret) {
3048 char addr[INET6_ADDRSTRLEN];
3050 * Try and give an error message saying what
3053 DEBUG(0, ("write_data failed for client %s. "
3055 get_peer_addr(fsp->conn->sconn->sock, addr,
3062 TALLOC_FREE(outbuf);
3065 /****************************************************************************
3066 Reply to a readbraw (core+ protocol).
3067 ****************************************************************************/
3069 void reply_readbraw(struct smb_request *req)
3071 connection_struct *conn = req->conn;
3072 struct smbd_server_connection *sconn = req->sconn;
3073 ssize_t maxcount,mincount;
3077 struct lock_struct lock;
3080 START_PROFILE(SMBreadbraw);
3082 if (srv_is_signing_active(sconn) ||
3083 is_encrypted_packet(req->inbuf)) {
3084 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
3085 "raw reads/writes are disallowed.");
3089 reply_readbraw_error(sconn);
3090 END_PROFILE(SMBreadbraw);
3094 if (sconn->smb1.echo_handler.trusted_fde) {
3095 DEBUG(2,("SMBreadbraw rejected with NOT_SUPPORTED because of "
3096 "'async smb echo handler = yes'\n"));
3097 reply_readbraw_error(sconn);
3098 END_PROFILE(SMBreadbraw);
3103 * Special check if an oplock break has been issued
3104 * and the readraw request croses on the wire, we must
3105 * return a zero length response here.
3108 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3111 * We have to do a check_fsp by hand here, as
3112 * we must always return 4 zero bytes on error,
3116 if (!fsp || !conn || conn != fsp->conn ||
3117 req->vuid != fsp->vuid ||
3118 fsp->is_directory || fsp->fh->fd == -1) {
3120 * fsp could be NULL here so use the value from the packet. JRA.
3122 DEBUG(3,("reply_readbraw: fnum %d not valid "
3124 (int)SVAL(req->vwv+0, 0)));
3125 reply_readbraw_error(sconn);
3126 END_PROFILE(SMBreadbraw);
3130 /* Do a "by hand" version of CHECK_READ. */
3131 if (!(fsp->can_read ||
3132 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
3133 (fsp->access_mask & FILE_EXECUTE)))) {
3134 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
3135 (int)SVAL(req->vwv+0, 0)));
3136 reply_readbraw_error(sconn);
3137 END_PROFILE(SMBreadbraw);
3141 flush_write_cache(fsp, READRAW_FLUSH);
3143 startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0);
3144 if(req->wct == 10) {
3146 * This is a large offset (64 bit) read.
3148 #ifdef LARGE_SMB_OFF_T
3150 startpos |= (((SMB_OFF_T)IVAL(req->vwv+8, 0)) << 32);
3152 #else /* !LARGE_SMB_OFF_T */
3155 * Ensure we haven't been sent a >32 bit offset.
3158 if(IVAL(req->vwv+8, 0) != 0) {
3159 DEBUG(0,("reply_readbraw: large offset "
3160 "(%x << 32) used and we don't support "
3161 "64 bit offsets.\n",
3162 (unsigned int)IVAL(req->vwv+8, 0) ));
3163 reply_readbraw_error();
3164 END_PROFILE(SMBreadbraw);
3168 #endif /* LARGE_SMB_OFF_T */
3171 DEBUG(0,("reply_readbraw: negative 64 bit "
3172 "readraw offset (%.0f) !\n",
3173 (double)startpos ));
3174 reply_readbraw_error(sconn);
3175 END_PROFILE(SMBreadbraw);
3180 maxcount = (SVAL(req->vwv+3, 0) & 0xFFFF);
3181 mincount = (SVAL(req->vwv+4, 0) & 0xFFFF);
3183 /* ensure we don't overrun the packet size */
3184 maxcount = MIN(65535,maxcount);
3186 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
3187 (uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
3190 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
3191 reply_readbraw_error(sconn);
3192 END_PROFILE(SMBreadbraw);
3196 if (fsp_stat(fsp) == 0) {
3197 size = fsp->fsp_name->st.st_ex_size;
3200 if (startpos >= size) {
3203 nread = MIN(maxcount,(size - startpos));
3206 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
3207 if (nread < mincount)
3211 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
3212 "min=%lu nread=%lu\n",
3213 fsp->fnum, (double)startpos,
3214 (unsigned long)maxcount,
3215 (unsigned long)mincount,
3216 (unsigned long)nread ) );
3218 send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
3220 DEBUG(5,("reply_readbraw finished\n"));
3222 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
3224 END_PROFILE(SMBreadbraw);
3229 #define DBGC_CLASS DBGC_LOCKING
3231 /****************************************************************************
3232 Reply to a lockread (core+ protocol).
3233 ****************************************************************************/
3235 void reply_lockread(struct smb_request *req)
3237 connection_struct *conn = req->conn;
3244 struct byte_range_lock *br_lck = NULL;
3246 struct smbd_server_connection *sconn = req->sconn;
3248 START_PROFILE(SMBlockread);
3251 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3252 END_PROFILE(SMBlockread);
3256 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3258 if (!check_fsp(conn, req, fsp)) {
3259 END_PROFILE(SMBlockread);
3263 if (!CHECK_READ(fsp,req)) {
3264 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3265 END_PROFILE(SMBlockread);
3269 numtoread = SVAL(req->vwv+1, 0);
3270 startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
3272 numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
3274 reply_outbuf(req, 5, numtoread + 3);
3276 data = smb_buf(req->outbuf) + 3;
3279 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
3280 * protocol request that predates the read/write lock concept.
3281 * Thus instead of asking for a read lock here we need to ask
3282 * for a write lock. JRA.
3283 * Note that the requested lock size is unaffected by max_recv.
3286 br_lck = do_lock(req->sconn->msg_ctx,
3288 (uint64_t)req->smbpid,
3289 (uint64_t)numtoread,
3293 False, /* Non-blocking lock. */
3297 TALLOC_FREE(br_lck);
3299 if (NT_STATUS_V(status)) {
3300 reply_nterror(req, status);
3301 END_PROFILE(SMBlockread);
3306 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
3309 if (numtoread > sconn->smb1.negprot.max_recv) {
3310 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
3311 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3312 (unsigned int)numtoread,
3313 (unsigned int)sconn->smb1.negprot.max_recv));
3314 numtoread = MIN(numtoread, sconn->smb1.negprot.max_recv);
3316 nread = read_file(fsp,data,startpos,numtoread);
3319 reply_nterror(req, map_nt_error_from_unix(errno));
3320 END_PROFILE(SMBlockread);
3324 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3326 SSVAL(req->outbuf,smb_vwv0,nread);
3327 SSVAL(req->outbuf,smb_vwv5,nread+3);
3328 p = smb_buf(req->outbuf);
3329 SCVAL(p,0,0); /* pad byte. */
3332 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
3333 fsp->fnum, (int)numtoread, (int)nread));
3335 END_PROFILE(SMBlockread);
3340 #define DBGC_CLASS DBGC_ALL
3342 /****************************************************************************
3344 ****************************************************************************/
3346 void reply_read(struct smb_request *req)
3348 connection_struct *conn = req->conn;
3355 struct lock_struct lock;
3356 struct smbd_server_connection *sconn = req->sconn;
3358 START_PROFILE(SMBread);
3361 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3362 END_PROFILE(SMBread);
3366 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3368 if (!check_fsp(conn, req, fsp)) {
3369 END_PROFILE(SMBread);
3373 if (!CHECK_READ(fsp,req)) {
3374 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3375 END_PROFILE(SMBread);
3379 numtoread = SVAL(req->vwv+1, 0);
3380 startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
3382 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3385 * The requested read size cannot be greater than max_recv. JRA.
3387 if (numtoread > sconn->smb1.negprot.max_recv) {
3388 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3389 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3390 (unsigned int)numtoread,
3391 (unsigned int)sconn->smb1.negprot.max_recv));
3392 numtoread = MIN(numtoread, sconn->smb1.negprot.max_recv);
3395 reply_outbuf(req, 5, numtoread+3);
3397 data = smb_buf(req->outbuf) + 3;
3399 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
3400 (uint64_t)startpos, (uint64_t)numtoread, READ_LOCK,
3403 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
3404 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
3405 END_PROFILE(SMBread);
3410 nread = read_file(fsp,data,startpos,numtoread);
3413 reply_nterror(req, map_nt_error_from_unix(errno));
3417 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3419 SSVAL(req->outbuf,smb_vwv0,nread);
3420 SSVAL(req->outbuf,smb_vwv5,nread+3);
3421 SCVAL(smb_buf(req->outbuf),0,1);
3422 SSVAL(smb_buf(req->outbuf),1,nread);
3424 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3425 fsp->fnum, (int)numtoread, (int)nread ) );
3428 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
3430 END_PROFILE(SMBread);
3434 /****************************************************************************
3436 ****************************************************************************/
3438 static int setup_readX_header(struct smb_request *req, char *outbuf,
3444 outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3445 data = smb_buf(outbuf);
3447 memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3449 SCVAL(outbuf,smb_vwv0,0xFF);
3450 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3451 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3452 SSVAL(outbuf,smb_vwv6,
3454 + 1 /* the wct field */
3455 + 12 * sizeof(uint16_t) /* vwv */
3456 + 2); /* the buflen field */
3457 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3458 SSVAL(outbuf,smb_vwv11,smb_maxcnt);
3459 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3460 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3464 /****************************************************************************
3465 Reply to a read and X - possibly using sendfile.
3466 ****************************************************************************/
3468 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3469 files_struct *fsp, SMB_OFF_T startpos,
3473 struct lock_struct lock;
3474 int saved_errno = 0;
3476 if(fsp_stat(fsp) == -1) {
3477 reply_nterror(req, map_nt_error_from_unix(errno));
3481 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
3482 (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
3485 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
3486 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
3490 if (!S_ISREG(fsp->fsp_name->st.st_ex_mode) ||
3491 (startpos > fsp->fsp_name->st.st_ex_size)
3492 || (smb_maxcnt > (fsp->fsp_name->st.st_ex_size - startpos))) {
3494 * We already know that we would do a short read, so don't
3495 * try the sendfile() path.
3497 goto nosendfile_read;
3500 #if defined(WITH_SENDFILE)
3502 * We can only use sendfile on a non-chained packet
3503 * but we can use on a non-oplocked file. tridge proved this
3504 * on a train in Germany :-). JRA.
3507 if (!req_is_in_chain(req) &&
3508 !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
3509 (fsp->wcp == NULL) &&
3510 lp_use_sendfile(SNUM(conn), req->sconn->smb1.signing_state) ) {
3511 uint8 headerbuf[smb_size + 12 * 2];
3515 * Set up the packet header before send. We
3516 * assume here the sendfile will work (get the
3517 * correct amount of data).
3520 header = data_blob_const(headerbuf, sizeof(headerbuf));
3522 construct_reply_common_req(req, (char *)headerbuf);
3523 setup_readX_header(req, (char *)headerbuf, smb_maxcnt);
3525 nread = SMB_VFS_SENDFILE(req->sconn->sock, fsp, &header,
3526 startpos, smb_maxcnt);
3528 /* Returning ENOSYS means no data at all was sent.
3529 Do this as a normal read. */
3530 if (errno == ENOSYS) {
3535 * Special hack for broken Linux with no working sendfile. If we
3536 * return EINTR we sent the header but not the rest of the data.
3537 * Fake this up by doing read/write calls.
3540 if (errno == EINTR) {
3541 /* Ensure we don't do this again. */
3542 set_use_sendfile(SNUM(conn), False);
3543 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3544 nread = fake_sendfile(fsp, startpos,
3547 DEBUG(0,("send_file_readX: "
3548 "fake_sendfile failed for "
3552 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3554 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
3555 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3556 /* No outbuf here means successful sendfile. */
3560 DEBUG(0,("send_file_readX: sendfile failed for file "
3561 "%s (%s). Terminating\n", fsp_str_dbg(fsp),
3563 exit_server_cleanly("send_file_readX sendfile failed");
3564 } else if (nread == 0) {
3566 * Some sendfile implementations return 0 to indicate
3567 * that there was a short read, but nothing was
3568 * actually written to the socket. In this case,
3569 * fallback to the normal read path so the header gets
3570 * the correct byte count.
3572 DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
3573 "falling back to the normal read: %s\n",
3578 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
3579 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3581 /* Deal with possible short send. */
3582 if (nread != smb_maxcnt + sizeof(headerbuf)) {
3583 sendfile_short_send(fsp, nread, sizeof(headerbuf), smb_maxcnt);
3585 /* No outbuf here means successful sendfile. */
3586 SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
3587 SMB_PERFCOUNT_END(&req->pcd);
3595 if ((smb_maxcnt & 0xFF0000) > 0x10000) {
3596 uint8 headerbuf[smb_size + 2*12];
3598 construct_reply_common_req(req, (char *)headerbuf);
3599 setup_readX_header(req, (char *)headerbuf, smb_maxcnt);
3601 /* Send out the header. */
3602 if (write_data(req->sconn->sock, (char *)headerbuf,
3603 sizeof(headerbuf)) != sizeof(headerbuf)) {
3605 char addr[INET6_ADDRSTRLEN];
3607 * Try and give an error message saying what
3610 DEBUG(0, ("write_data failed for client %s. "
3612 get_peer_addr(req->sconn->sock, addr,
3616 DEBUG(0,("send_file_readX: write_data failed for file "
3617 "%s (%s). Terminating\n", fsp_str_dbg(fsp),
3619 exit_server_cleanly("send_file_readX sendfile failed");
3621 nread = fake_sendfile(fsp, startpos, smb_maxcnt);
3623 DEBUG(0,("send_file_readX: fake_sendfile failed for "
3624 "file %s (%s).\n", fsp_str_dbg(fsp),
3626 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3633 reply_outbuf(req, 12, smb_maxcnt);
3635 nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
3636 saved_errno = errno;
3638 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
3641 reply_nterror(req, map_nt_error_from_unix(saved_errno));
3645 setup_readX_header(req, (char *)req->outbuf, nread);
3647 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
3648 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3654 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
3655 TALLOC_FREE(req->outbuf);
3659 /****************************************************************************
3660 Reply to a read and X.
3661 ****************************************************************************/
3663 void reply_read_and_X(struct smb_request *req)
3665 connection_struct *conn = req->conn;
3669 bool big_readX = False;
3671 size_t smb_mincnt = SVAL(req->vwv+6, 0);
3674 START_PROFILE(SMBreadX);
3676 if ((req->wct != 10) && (req->wct != 12)) {
3677 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3681 fsp = file_fsp(req, SVAL(req->vwv+2, 0));
3682 startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
3683 smb_maxcnt = SVAL(req->vwv+5, 0);
3685 /* If it's an IPC, pass off the pipe handler. */
3687 reply_pipe_read_and_X(req);
3688 END_PROFILE(SMBreadX);
3692 if (!check_fsp(conn, req, fsp)) {
3693 END_PROFILE(SMBreadX);
3697 if (!CHECK_READ(fsp,req)) {
3698 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3699 END_PROFILE(SMBreadX);
3703 if (global_client_caps & CAP_LARGE_READX) {
3704 size_t upper_size = SVAL(req->vwv+7, 0);
3705 smb_maxcnt |= (upper_size<<16);
3706 if (upper_size > 1) {
3707 /* Can't do this on a chained packet. */
3708 if ((CVAL(req->vwv+0, 0) != 0xFF)) {
3709 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3710 END_PROFILE(SMBreadX);
3713 /* We currently don't do this on signed or sealed data. */
3714 if (srv_is_signing_active(req->sconn) ||
3715 is_encrypted_packet(req->inbuf)) {
3716 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3717 END_PROFILE(SMBreadX);
3720 /* Is there room in the reply for this data ? */
3721 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
3723 NT_STATUS_INVALID_PARAMETER);
3724 END_PROFILE(SMBreadX);
3731 if (req->wct == 12) {
3732 #ifdef LARGE_SMB_OFF_T
3734 * This is a large offset (64 bit) read.
3736 startpos |= (((SMB_OFF_T)IVAL(req->vwv+10, 0)) << 32);
3738 #else /* !LARGE_SMB_OFF_T */
3741 * Ensure we haven't been sent a >32 bit offset.
3744 if(IVAL(req->vwv+10, 0) != 0) {
3745 DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
3746 "used and we don't support 64 bit offsets.\n",
3747 (unsigned int)IVAL(req->vwv+10, 0) ));
3748 END_PROFILE(SMBreadX);
3749 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3753 #endif /* LARGE_SMB_OFF_T */
3758 NTSTATUS status = schedule_aio_read_and_X(conn,
3763 if (NT_STATUS_IS_OK(status)) {
3764 /* Read scheduled - we're done. */
3767 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3768 /* Real error - report to client. */
3769 END_PROFILE(SMBreadX);
3770 reply_nterror(req, status);
3773 /* NT_STATUS_RETRY - fall back to sync read. */
3776 smbd_lock_socket(req->sconn);
3777 send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
3778 smbd_unlock_socket(req->sconn);
3781 END_PROFILE(SMBreadX);
3785 /****************************************************************************
3786 Error replies to writebraw must have smb_wct == 1. Fix this up.
3787 ****************************************************************************/
3789 void error_to_writebrawerr(struct smb_request *req)
3791 uint8 *old_outbuf = req->outbuf;
3793 reply_outbuf(req, 1, 0);
3795 memcpy(req->outbuf, old_outbuf, smb_size);
3796 TALLOC_FREE(old_outbuf);
3799 /****************************************************************************
3800 Reply to a writebraw (core+ or LANMAN1.0 protocol).
3801 ****************************************************************************/
3803 void reply_writebraw(struct smb_request *req)
3805 connection_struct *conn = req->conn;
3808 ssize_t total_written=0;
3809 size_t numtowrite=0;
3815 struct lock_struct lock;
3818 START_PROFILE(SMBwritebraw);
3821 * If we ever reply with an error, it must have the SMB command
3822 * type of SMBwritec, not SMBwriteBraw, as this tells the client
3825 SCVAL(req->inbuf,smb_com,SMBwritec);
3827 if (srv_is_signing_active(req->sconn)) {
3828 END_PROFILE(SMBwritebraw);
3829 exit_server_cleanly("reply_writebraw: SMB signing is active - "
3830 "raw reads/writes are disallowed.");
3833 if (req->wct < 12) {
3834 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3835 error_to_writebrawerr(req);
3836 END_PROFILE(SMBwritebraw);
3840 if (req->sconn->smb1.echo_handler.trusted_fde) {
3841 DEBUG(2,("SMBwritebraw rejected with NOT_SUPPORTED because of "
3842 "'async smb echo handler = yes'\n"));
3843 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3844 error_to_writebrawerr(req);
3845 END_PROFILE(SMBwritebraw);
3849 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3850 if (!check_fsp(conn, req, fsp)) {
3851 error_to_writebrawerr(req);
3852 END_PROFILE(SMBwritebraw);
3856 if (!CHECK_WRITE(fsp)) {
3857 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3858 error_to_writebrawerr(req);
3859 END_PROFILE(SMBwritebraw);
3863 tcount = IVAL(req->vwv+1, 0);
3864 startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
3865 write_through = BITSETW(req->vwv+7,0);
3867 /* We have to deal with slightly different formats depending
3868 on whether we are using the core+ or lanman1.0 protocol */
3870 if(get_Protocol() <= PROTOCOL_COREPLUS) {
3871 numtowrite = SVAL(smb_buf(req->inbuf),-2);
3872 data = smb_buf(req->inbuf);
3874 numtowrite = SVAL(req->vwv+10, 0);
3875 data = smb_base(req->inbuf) + SVAL(req->vwv+11, 0);
3878 /* Ensure we don't write bytes past the end of this packet. */
3879 if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
3880 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3881 error_to_writebrawerr(req);
3882 END_PROFILE(SMBwritebraw);
3886 if (!fsp->print_file) {
3887 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
3888 (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK,
3891 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
3892 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
3893 error_to_writebrawerr(req);
3894 END_PROFILE(SMBwritebraw);
3900 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3903 DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
3904 "wrote=%d sync=%d\n",
3905 fsp->fnum, (double)startpos, (int)numtowrite,
3906 (int)nwritten, (int)write_through));
3908 if (nwritten < (ssize_t)numtowrite) {
3909 reply_nterror(req, NT_STATUS_DISK_FULL);
3910 error_to_writebrawerr(req);
3914 total_written = nwritten;
3916 /* Allocate a buffer of 64k + length. */
3917 buf = TALLOC_ARRAY(NULL, char, 65540);
3919 reply_nterror(req, NT_STATUS_NO_MEMORY);
3920 error_to_writebrawerr(req);
3924 /* Return a SMBwritebraw message to the redirector to tell
3925 * it to send more bytes */
3927 memcpy(buf, req->inbuf, smb_size);
3928 srv_set_message(buf,get_Protocol()>PROTOCOL_COREPLUS?1:0,0,True);
3929 SCVAL(buf,smb_com,SMBwritebraw);
3930 SSVALS(buf,smb_vwv0,0xFFFF);
3932 if (!srv_send_smb(req->sconn->sock,
3934 false, 0, /* no signing */
3935 IS_CONN_ENCRYPTED(conn),
3937 exit_server_cleanly("reply_writebraw: srv_send_smb "
3941 /* Now read the raw data into the buffer and write it */
3942 status = read_smb_length(req->sconn->sock, buf, SMB_SECONDARY_WAIT,
3944 if (!NT_STATUS_IS_OK(status)) {
3945 exit_server_cleanly("secondary writebraw failed");
3948 /* Set up outbuf to return the correct size */
3949 reply_outbuf(req, 1, 0);
3951 if (numtowrite != 0) {
3953 if (numtowrite > 0xFFFF) {
3954 DEBUG(0,("reply_writebraw: Oversize secondary write "
3955 "raw requested (%u). Terminating\n",
3956 (unsigned int)numtowrite ));
3957 exit_server_cleanly("secondary writebraw failed");
3960 if (tcount > nwritten+numtowrite) {
3961 DEBUG(3,("reply_writebraw: Client overestimated the "
3963 (int)tcount,(int)nwritten,(int)numtowrite));
3966 status = read_data(req->sconn->sock, buf+4, numtowrite);
3968 if (!NT_STATUS_IS_OK(status)) {
3969 char addr[INET6_ADDRSTRLEN];
3970 /* Try and give an error message
3971 * saying what client failed. */
3972 DEBUG(0, ("reply_writebraw: Oversize secondary write "
3973 "raw read failed (%s) for client %s. "
3974 "Terminating\n", nt_errstr(status),
3975 get_peer_addr(req->sconn->sock, addr,
3977 exit_server_cleanly("secondary writebraw failed");
3980 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
3981 if (nwritten == -1) {
3983 reply_nterror(req, map_nt_error_from_unix(errno));
3984 error_to_writebrawerr(req);
3988 if (nwritten < (ssize_t)numtowrite) {
3989 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3990 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3994 total_written += nwritten;
3999 SSVAL(req->outbuf,smb_vwv0,total_written);
4001 status = sync_file(conn, fsp, write_through);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
4004 fsp_str_dbg(fsp), nt_errstr(status)));
4005 reply_nterror(req, status);
4006 error_to_writebrawerr(req);
4010 DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
4012 fsp->fnum, (double)startpos, (int)numtowrite,
4013 (int)total_written));
4015 if (!fsp->print_file) {
4016 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
4019 /* We won't return a status if write through is not selected - this
4020 * follows what WfWg does */
4021 END_PROFILE(SMBwritebraw);
4023 if (!write_through && total_written==tcount) {
4025 #if RABBIT_PELLET_FIX
4027 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
4028 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
4031 if (!send_keepalive(req->sconn->sock)) {
4032 exit_server_cleanly("reply_writebraw: send of "
4033 "keepalive failed");
4036 TALLOC_FREE(req->outbuf);
4041 if (!fsp->print_file) {
4042 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
4045 END_PROFILE(SMBwritebraw);
4050 #define DBGC_CLASS DBGC_LOCKING
4052 /****************************************************************************
4053 Reply to a writeunlock (core+).
4054 ****************************************************************************/
4056 void reply_writeunlock(struct smb_request *req)
4058 connection_struct *conn = req->conn;
4059 ssize_t nwritten = -1;
4063 NTSTATUS status = NT_STATUS_OK;
4065 struct lock_struct lock;
4066 int saved_errno = 0;
4068 START_PROFILE(SMBwriteunlock);
4071 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4072 END_PROFILE(SMBwriteunlock);
4076 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4078 if (!check_fsp(conn, req, fsp)) {
4079 END_PROFILE(SMBwriteunlock);
4083 if (!CHECK_WRITE(fsp)) {
4084 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4085 END_PROFILE(SMBwriteunlock);
4089 numtowrite = SVAL(req->vwv+1, 0);
4090 startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
4091 data = (const char *)req->buf + 3;
4093 if (!fsp->print_file && numtowrite > 0) {
4094 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
4095 (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
4098 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
4099 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
4100 END_PROFILE(SMBwriteunlock);
4105 /* The special X/Open SMB protocol handling of
4106 zero length writes is *NOT* done for
4108 if(numtowrite == 0) {
4111 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4112 saved_errno = errno;
4115 status = sync_file(conn, fsp, False /* write through */);
4116 if (!NT_STATUS_IS_OK(status)) {
4117 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
4118 fsp_str_dbg(fsp), nt_errstr(status)));
4119 reply_nterror(req, status);
4124 reply_nterror(req, map_nt_error_from_unix(saved_errno));
4128 if((nwritten < numtowrite) && (numtowrite != 0)) {
4129 reply_nterror(req, NT_STATUS_DISK_FULL);
4133 if (numtowrite && !fsp->print_file) {
4134 status = do_unlock(req->sconn->msg_ctx,
4136 (uint64_t)req->smbpid,
4137 (uint64_t)numtowrite,
4141 if (NT_STATUS_V(status)) {
4142 reply_nterror(req, status);
4147 reply_outbuf(req, 1, 0);
4149 SSVAL(req->outbuf,smb_vwv0,nwritten);
4151 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
4152 fsp->fnum, (int)numtowrite, (int)nwritten));
4155 if (numtowrite && !fsp->print_file) {
4156 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
4159 END_PROFILE(SMBwriteunlock);
4164 #define DBGC_CLASS DBGC_ALL
4166 /****************************************************************************
4168 ****************************************************************************/
4170 void reply_write(struct smb_request *req)
4172 connection_struct *conn = req->conn;
4174 ssize_t nwritten = -1;
4178 struct lock_struct lock;
4180 int saved_errno = 0;
4182 START_PROFILE(SMBwrite);
4185 END_PROFILE(SMBwrite);
4186 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4190 /* If it's an IPC, pass off the pipe handler. */
4192 reply_pipe_write(req);
4193 END_PROFILE(SMBwrite);
4197 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4199 if (!check_fsp(conn, req, fsp)) {
4200 END_PROFILE(SMBwrite);
4204 if (!CHECK_WRITE(fsp)) {
4205 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4206 END_PROFILE(SMBwrite);
4210 numtowrite = SVAL(req->vwv+1, 0);
4211 startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
4212 data = (const char *)req->buf + 3;
4214 if (!fsp->print_file) {
4215 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
4216 (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
4219 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
4220 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
4221 END_PROFILE(SMBwrite);
4227 * X/Open SMB protocol says that if smb_vwv1 is
4228 * zero then the file size should be extended or
4229 * truncated to the size given in smb_vwv[2-3].
4232 if(numtowrite == 0) {
4234 * This is actually an allocate call, and set EOF. JRA.
4236 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
4238 reply_nterror(req, NT_STATUS_DISK_FULL);
4241 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
4243 reply_nterror(req, NT_STATUS_DISK_FULL);
4246 trigger_write_time_update_immediate(fsp);
4248 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4251 status = sync_file(conn, fsp, False);
4252 if (!NT_STATUS_IS_OK(status)) {
4253 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
4254 fsp_str_dbg(fsp), nt_errstr(status)));
4255 reply_nterror(req, status);
4260 reply_nterror(req, map_nt_error_from_unix(saved_errno));
4264 if((nwritten == 0) && (numtowrite != 0)) {
4265 reply_nterror(req, NT_STATUS_DISK_FULL);
4269 reply_outbuf(req, 1, 0);
4271 SSVAL(req->outbuf,smb_vwv0,nwritten);
4273 if (nwritten < (ssize_t)numtowrite) {
4274 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4275 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4278 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
4281 if (!fsp->print_file) {
4282 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
4285 END_PROFILE(SMBwrite);
4289 /****************************************************************************
4290 Ensure a buffer is a valid writeX for recvfile purposes.
4291 ****************************************************************************/
4293 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
4294 (2*14) + /* word count (including bcc) */ \
4297 bool is_valid_writeX_buffer(struct smbd_server_connection *sconn,
4298 const uint8_t *inbuf)
4301 connection_struct *conn = NULL;
4302 unsigned int doff = 0;
4303 size_t len = smb_len_large(inbuf);
4305 if (is_encrypted_packet(inbuf)) {
4306 /* Can't do this on encrypted
4311 if (CVAL(inbuf,smb_com) != SMBwriteX) {
4315 if (CVAL(inbuf,smb_vwv0) != 0xFF ||
4316 CVAL(inbuf,smb_wct) != 14) {
4317 DEBUG(10,("is_valid_writeX_buffer: chained or "
4318 "invalid word length.\n"));
4322 conn = conn_find(sconn, SVAL(inbuf, smb_tid));
4324 DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
4328 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
4331 if (IS_PRINT(conn)) {
4332 DEBUG(10,("is_valid_writeX_buffer: printing tid\n"));
4335 doff = SVAL(inbuf,smb_vwv11);
4337 numtowrite = SVAL(inbuf,smb_vwv10);
4339 if (len > doff && len - doff > 0xFFFF) {
4340 numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
4343 if (numtowrite == 0) {
4344 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
4348 /* Ensure the sizes match up. */
4349 if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
4350 /* no pad byte...old smbclient :-( */
4351 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
4353 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
4357 if (len - doff != numtowrite) {
4358 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
4359 "len = %u, doff = %u, numtowrite = %u\n",
4362 (unsigned int)numtowrite ));
4366 DEBUG(10,("is_valid_writeX_buffer: true "
4367 "len = %u, doff = %u, numtowrite = %u\n",
4370 (unsigned int)numtowrite ));
4375 /****************************************************************************
4376 Reply to a write and X.
4377 ****************************************************************************/
4379 void reply_write_and_X(struct smb_request *req)
4381 connection_struct *conn = req->conn;
4383 struct lock_struct lock;
4388 unsigned int smb_doff;
4389 unsigned int smblen;
4392 int saved_errno = 0;
4394 START_PROFILE(SMBwriteX);
4396 if ((req->wct != 12) && (req->wct != 14)) {
4397 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4398 END_PROFILE(SMBwriteX);
4402 numtowrite = SVAL(req->vwv+10, 0);
4403 smb_doff = SVAL(req->vwv+11, 0);
4404 smblen = smb_len(req->inbuf);
4406 if (req->unread_bytes > 0xFFFF ||
4407 (smblen > smb_doff &&
4408 smblen - smb_doff > 0xFFFF)) {
4409 numtowrite |= (((size_t)SVAL(req->vwv+9, 0))<<16);
4412 if (req->unread_bytes) {
4413 /* Can't do a recvfile write on IPC$ */
4415 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4416 END_PROFILE(SMBwriteX);
4419 if (numtowrite != req->unread_bytes) {
4420 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4421 END_PROFILE(SMBwriteX);
4425 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
4426 smb_doff + numtowrite > smblen) {
4427 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4428 END_PROFILE(SMBwriteX);
4433 /* If it's an IPC, pass off the pipe handler. */
4435 if (req->unread_bytes) {
4436 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4437 END_PROFILE(SMBwriteX);
4440 reply_pipe_write_and_X(req);
4441 END_PROFILE(SMBwriteX);
4445 fsp = file_fsp(req, SVAL(req->vwv+2, 0));
4446 startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
4447 write_through = BITSETW(req->vwv+7,0);
4449 if (!check_fsp(conn, req, fsp)) {
4450 END_PROFILE(SMBwriteX);
4454 if (!CHECK_WRITE(fsp)) {
4455 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4456 END_PROFILE(SMBwriteX);
4460 data = smb_base(req->inbuf) + smb_doff;
4462 if(req->wct == 14) {
4463 #ifdef LARGE_SMB_OFF_T
4465 * This is a large offset (64 bit) write.
4467 startpos |= (((SMB_OFF_T)IVAL(req->vwv+12, 0)) << 32);
4469 #else /* !LARGE_SMB_OFF_T */
4472 * Ensure we haven't been sent a >32 bit offset.
4475 if(IVAL(req->vwv+12, 0) != 0) {
4476 DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
4477 "used and we don't support 64 bit offsets.\n",
4478 (unsigned int)IVAL(req->vwv+12, 0) ));
4479 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4480 END_PROFILE(SMBwriteX);
4484 #endif /* LARGE_SMB_OFF_T */
4487 /* X/Open SMB protocol says that, unlike SMBwrite
4488 if the length is zero then NO truncation is
4489 done, just a write of zero. To truncate a file,
4492 if(numtowrite == 0) {
4495 if (req->unread_bytes == 0) {
4496 status = schedule_aio_write_and_X(conn,
4503 if (NT_STATUS_IS_OK(status)) {
4504 /* write scheduled - we're done. */
4507 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
4508 /* Real error - report to client. */
4509 reply_nterror(req, status);
4512 /* NT_STATUS_RETRY - fall through to sync write. */
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);
4524 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4525 saved_errno = errno;
4527 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
4531 reply_nterror(req, map_nt_error_from_unix(saved_errno));
4535 if((nwritten == 0) && (numtowrite != 0)) {
4536 reply_nterror(req, NT_STATUS_DISK_FULL);
4540 reply_outbuf(req, 6, 0);
4541 SSVAL(req->outbuf,smb_vwv2,nwritten);
4542 SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
4544 if (nwritten < (ssize_t)numtowrite) {
4545 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4546 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4549 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
4550 fsp->fnum, (int)numtowrite, (int)nwritten));
4552 status = sync_file(conn, fsp, write_through);
4553 if (!NT_STATUS_IS_OK(status)) {
4554 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4555 fsp_str_dbg(fsp), nt_errstr(status)));
4556 reply_nterror(req, status);
4560 END_PROFILE(SMBwriteX);
4565 END_PROFILE(SMBwriteX);
4569 /****************************************************************************
4571 ****************************************************************************/
4573 void reply_lseek(struct smb_request *req)
4575 connection_struct *conn = req->conn;
4581 START_PROFILE(SMBlseek);
4584 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4585 END_PROFILE(SMBlseek);
4589 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4591 if (!check_fsp(conn, req, fsp)) {
4595 flush_write_cache(fsp, SEEK_FLUSH);
4597 mode = SVAL(req->vwv+1, 0) & 3;
4598 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4599 startpos = (SMB_OFF_T)IVALS(req->vwv+2, 0);
4608 res = fsp->fh->pos + startpos;
4619 if (umode == SEEK_END) {
4620 if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
4621 if(errno == EINVAL) {
4622 SMB_OFF_T current_pos = startpos;
4624 if(fsp_stat(fsp) == -1) {
4626 map_nt_error_from_unix(errno));
4627 END_PROFILE(SMBlseek);
4631 current_pos += fsp->fsp_name->st.st_ex_size;
4633 res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
4638 reply_nterror(req, map_nt_error_from_unix(errno));
4639 END_PROFILE(SMBlseek);
4646 reply_outbuf(req, 2, 0);
4647 SIVAL(req->outbuf,smb_vwv0,res);
4649 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
4650 fsp->fnum, (double)startpos, (double)res, mode));
4652 END_PROFILE(SMBlseek);
4656 /****************************************************************************
4658 ****************************************************************************/
4660 void reply_flush(struct smb_request *req)
4662 connection_struct *conn = req->conn;
4666 START_PROFILE(SMBflush);
4669 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4673 fnum = SVAL(req->vwv+0, 0);
4674 fsp = file_fsp(req, fnum);
4676 if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
4681 file_sync_all(conn);
4683 NTSTATUS status = sync_file(conn, fsp, True);
4684 if (!NT_STATUS_IS_OK(status)) {
4685 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4686 fsp_str_dbg(fsp), nt_errstr(status)));
4687 reply_nterror(req, status);
4688 END_PROFILE(SMBflush);
4693 reply_outbuf(req, 0, 0);
4695 DEBUG(3,("flush\n"));
4696 END_PROFILE(SMBflush);
4700 /****************************************************************************
4702 conn POINTER CAN BE NULL HERE !
4703 ****************************************************************************/
4705 void reply_exit(struct smb_request *req)
4707 START_PROFILE(SMBexit);
4709 file_close_pid(req->smbpid, req->vuid);
4711 reply_outbuf(req, 0, 0);
4713 DEBUG(3,("exit\n"));
4715 END_PROFILE(SMBexit);
4719 /****************************************************************************
4720 Reply to a close - has to deal with closing a directory opened by NT SMB's.
4721 ****************************************************************************/
4723 void reply_close(struct smb_request *req)
4725 connection_struct *conn = req->conn;
4726 NTSTATUS status = NT_STATUS_OK;
4727 files_struct *fsp = NULL;
4728 START_PROFILE(SMBclose);
4731 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4732 END_PROFILE(SMBclose);
4736 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4739 * We can only use check_fsp if we know it's not a directory.
4742 if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) {
4743 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
4744 END_PROFILE(SMBclose);
4748 if(fsp->is_directory) {
4750 * Special case - close NT SMB directory handle.
4752 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
4753 status = close_file(req, fsp, NORMAL_CLOSE);
4757 * Close ordinary file.
4760 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
4761 fsp->fh->fd, fsp->fnum,
4762 conn->num_files_open));
4765 * Take care of any time sent in the close.
4768 t = srv_make_unix_date3(req->vwv+1);
4769 set_close_write_time(fsp, convert_time_t_to_timespec(t));
4772 * close_file() returns the unix errno if an error
4773 * was detected on close - normally this is due to
4774 * a disk full error. If not then it was probably an I/O error.
4777 status = close_file(req, fsp, NORMAL_CLOSE);
4780 if (!NT_STATUS_IS_OK(status)) {
4781 reply_nterror(req, status);
4782 END_PROFILE(SMBclose);
4786 reply_outbuf(req, 0, 0);
4787 END_PROFILE(SMBclose);
4791 /****************************************************************************
4792 Reply to a writeclose (Core+ protocol).
4793 ****************************************************************************/
4795 void reply_writeclose(struct smb_request *req)
4797 connection_struct *conn = req->conn;
4799 ssize_t nwritten = -1;
4800 NTSTATUS close_status = NT_STATUS_OK;
4803 struct timespec mtime;
4805 struct lock_struct lock;
4807 START_PROFILE(SMBwriteclose);
4810 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4811 END_PROFILE(SMBwriteclose);
4815 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4817 if (!check_fsp(conn, req, fsp)) {
4818 END_PROFILE(SMBwriteclose);
4821 if (!CHECK_WRITE(fsp)) {
4822 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4823 END_PROFILE(SMBwriteclose);
4827 numtowrite = SVAL(req->vwv+1, 0);
4828 startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
4829 mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
4830 data = (const char *)req->buf + 1;
4832 if (!fsp->print_file) {
4833 init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
4834 (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
4837 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
4838 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
4839 END_PROFILE(SMBwriteclose);
4844 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4846 set_close_write_time(fsp, mtime);
4849 * More insanity. W2K only closes the file if writelen > 0.
4854 DEBUG(3,("reply_writeclose: zero length write doesn't close "
4855 "file %s\n", fsp_str_dbg(fsp)));
4856 close_status = close_file(req, fsp, NORMAL_CLOSE);
4859 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
4860 fsp->fnum, (int)numtowrite, (int)nwritten,
4861 conn->num_files_open));
4863 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4864 reply_nterror(req, NT_STATUS_DISK_FULL);
4868 if(!NT_STATUS_IS_OK(close_status)) {
4869 reply_nterror(req, close_status);
4873 reply_outbuf(req, 1, 0);
4875 SSVAL(req->outbuf,smb_vwv0,nwritten);
4878 if (numtowrite && !fsp->print_file) {
4879 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
4882 END_PROFILE(SMBwriteclose);
4887 #define DBGC_CLASS DBGC_LOCKING
4889 /****************************************************************************
4891 ****************************************************************************/
4893 void reply_lock(struct smb_request *req)
4895 connection_struct *conn = req->conn;
4896 uint64_t count,offset;
4899 struct byte_range_lock *br_lck = NULL;
4901 START_PROFILE(SMBlock);
4904 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4905 END_PROFILE(SMBlock);
4909 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4911 if (!check_fsp(conn, req, fsp)) {
4912 END_PROFILE(SMBlock);
4916 count = (uint64_t)IVAL(req->vwv+1, 0);
4917 offset = (uint64_t)IVAL(req->vwv+3, 0);
4919 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4920 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
4922 br_lck = do_lock(req->sconn->msg_ctx,
4924 (uint64_t)req->smbpid,
4929 False, /* Non-blocking lock. */
4934 TALLOC_FREE(br_lck);
4936 if (NT_STATUS_V(status)) {
4937 reply_nterror(req, status);
4938 END_PROFILE(SMBlock);
4942 reply_outbuf(req, 0, 0);
4944 END_PROFILE(SMBlock);
4948 /****************************************************************************
4950 ****************************************************************************/
4952 void reply_unlock(struct smb_request *req)
4954 connection_struct *conn = req->conn;
4955 uint64_t count,offset;
4959 START_PROFILE(SMBunlock);
4962 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4963 END_PROFILE(SMBunlock);
4967 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
4969 if (!check_fsp(conn, req, fsp)) {
4970 END_PROFILE(SMBunlock);
4974 count = (uint64_t)IVAL(req->vwv+1, 0);
4975 offset = (uint64_t)IVAL(req->vwv+3, 0);
4977 status = do_unlock(req->sconn->msg_ctx,
4979 (uint64_t)req->smbpid,
4984 if (NT_STATUS_V(status)) {
4985 reply_nterror(req, status);
4986 END_PROFILE(SMBunlock);
4990 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4991 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
4993 reply_outbuf(req, 0, 0);
4995 END_PROFILE(SMBunlock);
5000 #define DBGC_CLASS DBGC_ALL
5002 /****************************************************************************
5004 conn POINTER CAN BE NULL HERE !
5005 ****************************************************************************/
5007 void reply_tdis(struct smb_request *req)
5009 connection_struct *conn = req->conn;
5010 START_PROFILE(SMBtdis);
5013 DEBUG(4,("Invalid connection in tdis\n"));
5014 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
5015 END_PROFILE(SMBtdis);
5021 close_cnum(conn,req->vuid);
5024 reply_outbuf(req, 0, 0);
5025 END_PROFILE(SMBtdis);
5029 /****************************************************************************
5031 conn POINTER CAN BE NULL HERE !
5032 ****************************************************************************/
5034 void reply_echo(struct smb_request *req)
5036 connection_struct *conn = req->conn;
5037 struct smb_perfcount_data local_pcd;
5038 struct smb_perfcount_data *cur_pcd;
5042 START_PROFILE(SMBecho);
5044 smb_init_perfcount_data(&local_pcd);
5047 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5048 END_PROFILE(SMBecho);
5052 smb_reverb = SVAL(req->vwv+0, 0);
5054 reply_outbuf(req, 1, req->buflen);
5056 /* copy any incoming data back out */
5057 if (req->buflen > 0) {
5058 memcpy(smb_buf(req->outbuf), req->buf, req->buflen);
5061 if (smb_reverb > 100) {
5062 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
5066 for (seq_num = 1 ; seq_num <= smb_reverb ; seq_num++) {
5068 /* this makes sure we catch the request pcd */
5069 if (seq_num == smb_reverb) {
5070 cur_pcd = &req->pcd;
5072 SMB_PERFCOUNT_COPY_CONTEXT(&req->pcd, &local_pcd);
5073 cur_pcd = &local_pcd;
5076 SSVAL(req->outbuf,smb_vwv0,seq_num);
5078 show_msg((char *)req->outbuf);
5079 if (!srv_send_smb(req->sconn->sock,
5080 (char *)req->outbuf,
5081 true, req->seqnum+1,
5082 IS_CONN_ENCRYPTED(conn)||req->encrypted,
5084 exit_server_cleanly("reply_echo: srv_send_smb failed.");
5087 DEBUG(3,("echo %d times\n", smb_reverb));
5089 TALLOC_FREE(req->outbuf);
5091 END_PROFILE(SMBecho);
5095 /****************************************************************************
5096 Reply to a printopen.
5097 ****************************************************************************/
5099 void reply_printopen(struct smb_request *req)
5101 connection_struct *conn = req->conn;
5105 START_PROFILE(SMBsplopen);
5108 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5109 END_PROFILE(SMBsplopen);
5113 if (!CAN_PRINT(conn)) {
5114 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5115 END_PROFILE(SMBsplopen);
5119 status = file_new(req, conn, &fsp);
5120 if(!NT_STATUS_IS_OK(status)) {
5121 reply_nterror(req, status);
5122 END_PROFILE(SMBsplopen);
5126 /* Open for exclusive use, write only. */
5127 status = print_spool_open(fsp, NULL, req->vuid);
5129 if (!NT_STATUS_IS_OK(status)) {
5130 file_free(req, fsp);
5131 reply_nterror(req, status);
5132 END_PROFILE(SMBsplopen);
5136 reply_outbuf(req, 1, 0);
5137 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
5139 DEBUG(3,("openprint fd=%d fnum=%d\n",
5140 fsp->fh->fd, fsp->fnum));
5142 END_PROFILE(SMBsplopen);
5146 /****************************************************************************
5147 Reply to a printclose.
5148 ****************************************************************************/
5150 void reply_printclose(struct smb_request *req)
5152 connection_struct *conn = req->conn;
5156 START_PROFILE(SMBsplclose);
5159 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5160 END_PROFILE(SMBsplclose);
5164 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
5166 if (!check_fsp(conn, req, fsp)) {
5167 END_PROFILE(SMBsplclose);
5171 if (!CAN_PRINT(conn)) {
5172 reply_force_doserror(req, ERRSRV, ERRerror);
5173 END_PROFILE(SMBsplclose);
5177 DEBUG(3,("printclose fd=%d fnum=%d\n",
5178 fsp->fh->fd,fsp->fnum));
5180 status = close_file(req, fsp, NORMAL_CLOSE);
5182 if(!NT_STATUS_IS_OK(status)) {
5183 reply_nterror(req, status);
5184 END_PROFILE(SMBsplclose);
5188 reply_outbuf(req, 0, 0);
5190 END_PROFILE(SMBsplclose);
5194 /****************************************************************************
5195 Reply to a printqueue.
5196 ****************************************************************************/
5198 void reply_printqueue(struct smb_request *req)
5200 connection_struct *conn = req->conn;
5204 START_PROFILE(SMBsplretq);
5207 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5208 END_PROFILE(SMBsplretq);
5212 max_count = SVAL(req->vwv+0, 0);
5213 start_index = SVAL(req->vwv+1, 0);
5215 /* we used to allow the client to get the cnum wrong, but that
5216 is really quite gross and only worked when there was only
5217 one printer - I think we should now only accept it if they
5218 get it right (tridge) */
5219 if (!CAN_PRINT(conn)) {
5220 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5221 END_PROFILE(SMBsplretq);
5225 reply_outbuf(req, 2, 3);
5226 SSVAL(req->outbuf,smb_vwv0,0);
5227 SSVAL(req->outbuf,smb_vwv1,0);
5228 SCVAL(smb_buf(req->outbuf),0,1);
5229 SSVAL(smb_buf(req->outbuf),1,0);
5231 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
5232 start_index, max_count));
5235 TALLOC_CTX *mem_ctx = talloc_tos();
5238 const char *sharename = lp_servicename(SNUM(conn));
5239 struct rpc_pipe_client *cli = NULL;
5240 struct policy_handle handle;
5241 struct spoolss_DevmodeContainer devmode_ctr;
5242 union spoolss_JobInfo *info;
5244 uint32_t num_to_get;
5248 ZERO_STRUCT(handle);
5250 status = rpc_connect_spoolss_pipe(conn, &cli);
5251 if (!NT_STATUS_IS_OK(status)) {
5252 DEBUG(0, ("reply_printqueue: "
5253 "could not connect to spoolss: %s\n",
5254 nt_errstr(status)));
5255 reply_nterror(req, status);
5259 ZERO_STRUCT(devmode_ctr);
5261 status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
5264 SEC_FLAG_MAXIMUM_ALLOWED,
5267 if (!NT_STATUS_IS_OK(status)) {
5268 reply_nterror(req, status);
5271 if (!W_ERROR_IS_OK(werr)) {
5272 reply_nterror(req, werror_to_ntstatus(werr));
5276 werr = rpccli_spoolss_enumjobs(cli, mem_ctx,
5284 if (!W_ERROR_IS_OK(werr)) {
5285 reply_nterror(req, werror_to_ntstatus(werr));
5289 if (max_count > 0) {
5290 first = start_index;
5292 first = start_index + max_count + 1;
5295 if (first >= count) {
5298 num_to_get = first + MIN(ABS(max_count), count - first);
5301 for (i = first; i < num_to_get; i++) {
5304 time_t qtime = spoolss_Time_to_time_t(&info[i].info2.submitted);
5306 uint16_t qrapjobid = pjobid_to_rap(sharename,
5307 info[i].info2.job_id);
5309 if (info[i].info2.status == JOB_STATUS_PRINTING) {
5315 srv_put_dos_date2(p, 0, qtime);
5316 SCVAL(p, 4, qstatus);
5317 SSVAL(p, 5, qrapjobid);
5318 SIVAL(p, 7, info[i].info2.size);
5320 srvstr_push(blob, req->flags2, p+12,
5321 info[i].info2.notify_name, 16, STR_ASCII);
5323 if (message_push_blob(
5326 blob, sizeof(blob))) == -1) {
5327 reply_nterror(req, NT_STATUS_NO_MEMORY);
5333 SSVAL(req->outbuf,smb_vwv0,count);
5334 SSVAL(req->outbuf,smb_vwv1,
5335 (max_count>0?first+count:first-1));
5336 SCVAL(smb_buf(req->outbuf),0,1);
5337 SSVAL(smb_buf(req->outbuf),1,28*count);
5341 DEBUG(3, ("%u entries returned in queue\n",
5345 if (cli && is_valid_policy_hnd(&handle)) {
5346 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
5351 END_PROFILE(SMBsplretq);
5355 /****************************************************************************
5356 Reply to a printwrite.
5357 ****************************************************************************/
5359 void reply_printwrite(struct smb_request *req)
5361 connection_struct *conn = req->conn;
5366 START_PROFILE(SMBsplwr);
5369 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5370 END_PROFILE(SMBsplwr);
5374 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
5376 if (!check_fsp(conn, req, fsp)) {
5377 END_PROFILE(SMBsplwr);
5381 if (!fsp->print_file) {
5382 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5383 END_PROFILE(SMBsplwr);
5387 if (!CHECK_WRITE(fsp)) {
5388 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5389 END_PROFILE(SMBsplwr);
5393 numtowrite = SVAL(req->buf, 1);
5395 if (req->buflen < numtowrite + 3) {
5396 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5397 END_PROFILE(SMBsplwr);
5401 data = (const char *)req->buf + 3;
5403 if (write_file(req,fsp,data,(SMB_OFF_T)-1,numtowrite) != numtowrite) {
5404 reply_nterror(req, map_nt_error_from_unix(errno));
5405 END_PROFILE(SMBsplwr);
5409 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
5411 END_PROFILE(SMBsplwr);
5415 /****************************************************************************
5417 ****************************************************************************/
5419 void reply_mkdir(struct smb_request *req)
5421 connection_struct *conn = req->conn;
5422 struct smb_filename *smb_dname = NULL;
5423 char *directory = NULL;
5425 TALLOC_CTX *ctx = talloc_tos();
5427 START_PROFILE(SMBmkdir);
5429 srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1,
5430 STR_TERMINATE, &status);
5431 if (!NT_STATUS_IS_OK(status)) {
5432 reply_nterror(req, status);
5436 status = filename_convert(ctx, conn,
5437 req->flags2 & FLAGS2_DFS_PATHNAMES,
5442 if (!NT_STATUS_IS_OK(status)) {
5443 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5444 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5445 ERRSRV, ERRbadpath);
5448 reply_nterror(req, status);
5452 status = create_directory(conn, req, smb_dname);
5454 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
5456 if (!NT_STATUS_IS_OK(status)) {
5458 if (!use_nt_status()
5459 && NT_STATUS_EQUAL(status,
5460 NT_STATUS_OBJECT_NAME_COLLISION)) {
5462 * Yes, in the DOS error code case we get a
5463 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
5464 * samba4 torture test.
5466 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
5469 reply_nterror(req, status);
5473 reply_outbuf(req, 0, 0);
5475 DEBUG(3, ("mkdir %s\n", smb_dname->base_name));
5477 TALLOC_FREE(smb_dname);
5478 END_PROFILE(SMBmkdir);
5482 /****************************************************************************
5484 ****************************************************************************/
5486 void reply_rmdir(struct smb_request *req)
5488 connection_struct *conn = req->conn;
5489 struct smb_filename *smb_dname = NULL;
5490 char *directory = NULL;
5492 TALLOC_CTX *ctx = talloc_tos();
5493 files_struct *fsp = NULL;
5495 struct smbd_server_connection *sconn = req->sconn;
5497 START_PROFILE(SMBrmdir);
5499 srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1,
5500 STR_TERMINATE, &status);
5501 if (!NT_STATUS_IS_OK(status)) {
5502 reply_nterror(req, status);
5506 status = filename_convert(ctx, conn,
5507 req->flags2 & FLAGS2_DFS_PATHNAMES,
5512 if (!NT_STATUS_IS_OK(status)) {
5513 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5514 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5515 ERRSRV, ERRbadpath);
5518 reply_nterror(req, status);
5522 if (is_ntfs_stream_smb_fname(smb_dname)) {
5523 reply_nterror(req, NT_STATUS_NOT_A_DIRECTORY);
5527 status = SMB_VFS_CREATE_FILE(
5530 0, /* root_dir_fid */
5531 smb_dname, /* fname */
5532 DELETE_ACCESS, /* access_mask */
5533 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
5535 FILE_OPEN, /* create_disposition*/
5536 FILE_DIRECTORY_FILE, /* create_options */
5537 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5538 0, /* oplock_request */
5539 0, /* allocation_size */
5540 0, /* private_flags */
5546 if (!NT_STATUS_IS_OK(status)) {
5547 if (open_was_deferred(req->mid)) {
5548 /* We have re-scheduled this call. */
5551 reply_nterror(req, status);
5555 status = can_set_delete_on_close(fsp, FILE_ATTRIBUTE_DIRECTORY);
5556 if (!NT_STATUS_IS_OK(status)) {
5557 close_file(req, fsp, ERROR_CLOSE);
5558 reply_nterror(req, status);
5562 if (!set_delete_on_close(fsp, true, &conn->server_info->utok)) {
5563 close_file(req, fsp, ERROR_CLOSE);
5564 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
5568 status = close_file(req, fsp, NORMAL_CLOSE);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 reply_nterror(req, status);
5572 reply_outbuf(req, 0, 0);
5575 dptr_closepath(sconn, smb_dname->base_name, req->smbpid);
5577 DEBUG(3, ("rmdir %s\n", smb_fname_str_dbg(smb_dname)));
5579 TALLOC_FREE(smb_dname);
5580 END_PROFILE(SMBrmdir);
5584 /*******************************************************************
5585 Resolve wildcards in a filename rename.
5586 ********************************************************************/
5588 static bool resolve_wildcards(TALLOC_CTX *ctx,
5593 char *name2_copy = NULL;
5598 char *p,*p2, *pname1, *pname2;
5600 name2_copy = talloc_strdup(ctx, name2);
5605 pname1 = strrchr_m(name1,'/');
5606 pname2 = strrchr_m(name2_copy,'/');
5608 if (!pname1 || !pname2) {
5612 /* Truncate the copy of name2 at the last '/' */
5615 /* Now go past the '/' */
5619 root1 = talloc_strdup(ctx, pname1);
5620 root2 = talloc_strdup(ctx, pname2);
5622 if (!root1 || !root2) {
5626 p = strrchr_m(root1,'.');
5629 ext1 = talloc_strdup(ctx, p+1);
5631 ext1 = talloc_strdup(ctx, "");
5633 p = strrchr_m(root2,'.');
5636 ext2 = talloc_strdup(ctx, p+1);
5638 ext2 = talloc_strdup(ctx, "");
5641 if (!ext1 || !ext2) {
5649 /* Hmmm. Should this be mb-aware ? */
5652 } else if (*p2 == '*') {
5654 root2 = talloc_asprintf(ctx, "%s%s",
5673 /* Hmmm. Should this be mb-aware ? */
5676 } else if (*p2 == '*') {
5678 ext2 = talloc_asprintf(ctx, "%s%s",
5694 *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
5699 *pp_newname = talloc_asprintf(ctx, "%s/%s",
5711 /****************************************************************************
5712 Ensure open files have their names updated. Updated to notify other smbd's
5714 ****************************************************************************/
5716 static void rename_open_files(connection_struct *conn,
5717 struct share_mode_lock *lck,
5718 const struct smb_filename *smb_fname_dst)
5721 bool did_rename = False;
5724 for(fsp = file_find_di_first(lck->id); fsp;
5725 fsp = file_find_di_next(fsp)) {
5726 /* fsp_name is a relative path under the fsp. To change this for other
5727 sharepaths we need to manipulate relative paths. */
5728 /* TODO - create the absolute path and manipulate the newname
5729 relative to the sharepath. */
5730 if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
5733 DEBUG(10, ("rename_open_files: renaming file fnum %d "
5734 "(file_id %s) from %s -> %s\n", fsp->fnum,
5735 file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp),
5736 smb_fname_str_dbg(smb_fname_dst)));
5738 status = fsp_set_smb_fname(fsp, smb_fname_dst);
5739 if (NT_STATUS_IS_OK(status)) {
5745 DEBUG(10, ("rename_open_files: no open files on file_id %s "
5746 "for %s\n", file_id_string_tos(&lck->id),
5747 smb_fname_str_dbg(smb_fname_dst)));
5750 /* Send messages to all smbd's (not ourself) that the name has changed. */
5751 rename_share_filename(conn->sconn->msg_ctx, lck, conn->connectpath,
5756 /****************************************************************************
5757 We need to check if the source path is a parent directory of the destination
5758 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
5759 refuse the rename with a sharing violation. Under UNIX the above call can
5760 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
5761 probably need to check that the client is a Windows one before disallowing
5762 this as a UNIX client (one with UNIX extensions) can know the source is a
5763 symlink and make this decision intelligently. Found by an excellent bug
5764 report from <AndyLiebman@aol.com>.
5765 ****************************************************************************/
5767 static bool rename_path_prefix_equal(const struct smb_filename *smb_fname_src,
5768 const struct smb_filename *smb_fname_dst)
5770 const char *psrc = smb_fname_src->base_name;
5771 const char *pdst = smb_fname_dst->base_name;
5774 if (psrc[0] == '.' && psrc[1] == '/') {
5777 if (pdst[0] == '.' && pdst[1] == '/') {
5780 if ((slen = strlen(psrc)) > strlen(pdst)) {
5783 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
5787 * Do the notify calls from a rename
5790 static void notify_rename(connection_struct *conn, bool is_dir,
5791 const struct smb_filename *smb_fname_src,
5792 const struct smb_filename *smb_fname_dst)
5794 char *parent_dir_src = NULL;
5795 char *parent_dir_dst = NULL;
5798 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
5799 : FILE_NOTIFY_CHANGE_FILE_NAME;
5801 if (!parent_dirname(talloc_tos(), smb_fname_src->base_name,
5802 &parent_dir_src, NULL) ||
5803 !parent_dirname(talloc_tos(), smb_fname_dst->base_name,
5804 &parent_dir_dst, NULL)) {
5808 if (strcmp(parent_dir_src, parent_dir_dst) == 0) {
5809 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask,
5810 smb_fname_src->base_name);
5811 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask,
5812 smb_fname_dst->base_name);
5815 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask,
5816 smb_fname_src->base_name);
5817 notify_fname(conn, NOTIFY_ACTION_ADDED, mask,
5818 smb_fname_dst->base_name);
5821 /* this is a strange one. w2k3 gives an additional event for
5822 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
5823 files, but not directories */
5825 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
5826 FILE_NOTIFY_CHANGE_ATTRIBUTES
5827 |FILE_NOTIFY_CHANGE_CREATION,
5828 smb_fname_dst->base_name);
5831 TALLOC_FREE(parent_dir_src);
5832 TALLOC_FREE(parent_dir_dst);
5835 /****************************************************************************
5836 Rename an open file - given an fsp.
5837 ****************************************************************************/
5839 NTSTATUS rename_internals_fsp(connection_struct *conn,
5841 const struct smb_filename *smb_fname_dst_in,
5843 bool replace_if_exists)
5845 TALLOC_CTX *ctx = talloc_tos();
5846 struct smb_filename *smb_fname_dst = NULL;
5847 NTSTATUS status = NT_STATUS_OK;
5848 struct share_mode_lock *lck = NULL;
5849 bool dst_exists, old_is_stream, new_is_stream;
5851 status = check_name(conn, smb_fname_dst_in->base_name);
5852 if (!NT_STATUS_IS_OK(status)) {
5856 /* Make a copy of the dst smb_fname structs */
5858 status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
5859 if (!NT_STATUS_IS_OK(status)) {
5863 /* Ensure the dst smb_fname contains a '/' */
5864 if(strrchr_m(smb_fname_dst->base_name,'/') == 0) {
5866 tmp = talloc_asprintf(smb_fname_dst, "./%s",
5867 smb_fname_dst->base_name);
5869 status = NT_STATUS_NO_MEMORY;
5872 TALLOC_FREE(smb_fname_dst->base_name);
5873 smb_fname_dst->base_name = tmp;
5877 * Check for special case with case preserving and not
5878 * case sensitive. If the old last component differs from the original
5879 * last component only by case, then we should allow
5880 * the rename (user is trying to change the case of the
5883 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
5884 strequal(fsp->fsp_name->base_name, smb_fname_dst->base_name) &&
5885 strequal(fsp->fsp_name->stream_name, smb_fname_dst->stream_name)) {
5887 char *fname_dst_lcomp_base_mod = NULL;
5888 struct smb_filename *smb_fname_orig_lcomp = NULL;
5891 * Get the last component of the destination name. Note that
5892 * we guarantee that destination name contains a '/' character
5895 last_slash = strrchr_m(smb_fname_dst->base_name, '/');
5896 fname_dst_lcomp_base_mod = talloc_strdup(ctx, last_slash + 1);
5897 if (!fname_dst_lcomp_base_mod) {
5898 status = NT_STATUS_NO_MEMORY;
5903 * Create an smb_filename struct using the original last
5904 * component of the destination.
5906 status = create_synthetic_smb_fname_split(ctx,
5907 smb_fname_dst->original_lcomp, NULL,
5908 &smb_fname_orig_lcomp);
5909 if (!NT_STATUS_IS_OK(status)) {
5910 TALLOC_FREE(fname_dst_lcomp_base_mod);
5914 /* If the base names only differ by case, use original. */
5915 if(!strcsequal(fname_dst_lcomp_base_mod,
5916 smb_fname_orig_lcomp->base_name)) {
5919 * Replace the modified last component with the
5922 *last_slash = '\0'; /* Truncate at the '/' */
5923 tmp = talloc_asprintf(smb_fname_dst,
5925 smb_fname_dst->base_name,
5926 smb_fname_orig_lcomp->base_name);
5928 status = NT_STATUS_NO_MEMORY;
5929 TALLOC_FREE(fname_dst_lcomp_base_mod);
5930 TALLOC_FREE(smb_fname_orig_lcomp);
5933 TALLOC_FREE(smb_fname_dst->base_name);
5934 smb_fname_dst->base_name = tmp;
5937 /* If the stream_names only differ by case, use original. */
5938 if(!strcsequal(smb_fname_dst->stream_name,
5939 smb_fname_orig_lcomp->stream_name)) {
5941 /* Use the original stream. */
5942 tmp = talloc_strdup(smb_fname_dst,
5943 smb_fname_orig_lcomp->stream_name);
5945 status = NT_STATUS_NO_MEMORY;
5946 TALLOC_FREE(fname_dst_lcomp_base_mod);
5947 TALLOC_FREE(smb_fname_orig_lcomp);
5950 TALLOC_FREE(smb_fname_dst->stream_name);
5951 smb_fname_dst->stream_name = tmp;
5953 TALLOC_FREE(fname_dst_lcomp_base_mod);
5954 TALLOC_FREE(smb_fname_orig_lcomp);
5958 * If the src and dest names are identical - including case,
5959 * don't do the rename, just return success.
5962 if (strcsequal(fsp->fsp_name->base_name, smb_fname_dst->base_name) &&
5963 strcsequal(fsp->fsp_name->stream_name,
5964 smb_fname_dst->stream_name)) {
5965 DEBUG(3, ("rename_internals_fsp: identical names in rename %s "
5966 "- returning success\n",
5967 smb_fname_str_dbg(smb_fname_dst)));
5968 status = NT_STATUS_OK;
5972 old_is_stream = is_ntfs_stream_smb_fname(fsp->fsp_name);
5973 new_is_stream = is_ntfs_stream_smb_fname(smb_fname_dst);
5975 /* Return the correct error code if both names aren't streams. */
5976 if (!old_is_stream && new_is_stream) {
5977 status = NT_STATUS_OBJECT_NAME_INVALID;
5981 if (old_is_stream && !new_is_stream) {
5982 status = NT_STATUS_INVALID_PARAMETER;
5986 dst_exists = SMB_VFS_STAT(conn, smb_fname_dst) == 0;
5988 if(!replace_if_exists && dst_exists) {
5989 DEBUG(3, ("rename_internals_fsp: dest exists doing rename "
5990 "%s -> %s\n", smb_fname_str_dbg(fsp->fsp_name),
5991 smb_fname_str_dbg(smb_fname_dst)));
5992 status = NT_STATUS_OBJECT_NAME_COLLISION;
5997 struct file_id fileid = vfs_file_id_from_sbuf(conn,
5998 &smb_fname_dst->st);
5999 files_struct *dst_fsp = file_find_di_first(fileid);
6000 /* The file can be open when renaming a stream */
6001 if (dst_fsp && !new_is_stream) {
6002 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
6003 status = NT_STATUS_ACCESS_DENIED;
6008 /* Ensure we have a valid stat struct for the source. */
6009 status = vfs_stat_fsp(fsp);
6010 if (!NT_STATUS_IS_OK(status)) {
6014 status = can_rename(conn, fsp, attrs);
6016 if (!NT_STATUS_IS_OK(status)) {
6017 DEBUG(3, ("rename_internals_fsp: Error %s rename %s -> %s\n",
6018 nt_errstr(status), smb_fname_str_dbg(fsp->fsp_name),
6019 smb_fname_str_dbg(smb_fname_dst)));
6020 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
6021 status = NT_STATUS_ACCESS_DENIED;
6025 if (rename_path_prefix_equal(fsp->fsp_name, smb_fname_dst)) {
6026 status = NT_STATUS_ACCESS_DENIED;
6029 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
6033 * We have the file open ourselves, so not being able to get the
6034 * corresponding share mode lock is a fatal error.
6037 SMB_ASSERT(lck != NULL);
6039 if(SMB_VFS_RENAME(conn, fsp->fsp_name, smb_fname_dst) == 0) {
6040 uint32 create_options = fsp->fh->private_options;
6042 DEBUG(3, ("rename_internals_fsp: succeeded doing rename on "
6043 "%s -> %s\n", smb_fname_str_dbg(fsp->fsp_name),
6044 smb_fname_str_dbg(smb_fname_dst)));
6046 if (lp_map_archive(SNUM(conn)) ||
6047 lp_store_dos_attributes(SNUM(conn))) {
6048 /* We must set the archive bit on the newly
6050 if (SMB_VFS_STAT(conn, smb_fname_dst) == 0) {
6051 uint32_t old_dosmode = dos_mode(conn,
6053 file_set_dosmode(conn,
6055 old_dosmode | FILE_ATTRIBUTE_ARCHIVE,
6061 notify_rename(conn, fsp->is_directory, fsp->fsp_name,
6064 rename_open_files(conn, lck, smb_fname_dst);
6067 * A rename acts as a new file create w.r.t. allowing an initial delete
6068 * on close, probably because in Windows there is a new handle to the
6069 * new file. If initial delete on close was requested but not
6070 * originally set, we need to set it here. This is probably not 100% correct,
6071 * but will work for the CIFSFS client which in non-posix mode
6072 * depends on these semantics. JRA.
6075 if (create_options & FILE_DELETE_ON_CLOSE) {
6076 status = can_set_delete_on_close(fsp, 0);
6078 if (NT_STATUS_IS_OK(status)) {
6079 /* Note that here we set the *inital* delete on close flag,
6080 * not the regular one. The magic gets handled in close. */
6081 fsp->initial_delete_on_close = True;
6085 status = NT_STATUS_OK;
6091 if (errno == ENOTDIR || errno == EISDIR) {
6092 status = NT_STATUS_OBJECT_NAME_COLLISION;
6094 status = map_nt_error_from_unix(errno);
6097 DEBUG(3, ("rename_internals_fsp: Error %s rename %s -> %s\n",
6098 nt_errstr(status), smb_fname_str_dbg(fsp->fsp_name),
6099 smb_fname_str_dbg(smb_fname_dst)));
6102 TALLOC_FREE(smb_fname_dst);
6107 /****************************************************************************
6108 The guts of the rename command, split out so it may be called by the NT SMB
6110 ****************************************************************************/
6112 NTSTATUS rename_internals(TALLOC_CTX *ctx,
6113 connection_struct *conn,
6114 struct smb_request *req,
6115 struct smb_filename *smb_fname_src,
6116 struct smb_filename *smb_fname_dst,
6118 bool replace_if_exists,
6121 uint32_t access_mask)
6123 char *fname_src_dir = NULL;
6124 char *fname_src_mask = NULL;
6126 NTSTATUS status = NT_STATUS_OK;
6127 struct smb_Dir *dir_hnd = NULL;
6128 const char *dname = NULL;
6129 char *talloced = NULL;
6131 int create_options = 0;
6132 bool posix_pathnames = lp_posix_pathnames();
6135 * Split the old name into directory and last component
6136 * strings. Note that unix_convert may have stripped off a
6137 * leading ./ from both name and newname if the rename is
6138 * at the root of the share. We need to make sure either both
6139 * name and newname contain a / character or neither of them do
6140 * as this is checked in resolve_wildcards().
6143 /* Split up the directory from the filename/mask. */
6144 status = split_fname_dir_mask(ctx, smb_fname_src->base_name,
6145 &fname_src_dir, &fname_src_mask);
6146 if (!NT_STATUS_IS_OK(status)) {
6147 status = NT_STATUS_NO_MEMORY;
6152 * We should only check the mangled cache
6153 * here if unix_convert failed. This means
6154 * that the path in 'mask' doesn't exist
6155 * on the file system and so we need to look
6156 * for a possible mangle. This patch from
6157 * Tine Smukavec <valentin.smukavec@hermes.si>.
6160 if (!VALID_STAT(smb_fname_src->st) &&
6161 mangle_is_mangled(fname_src_mask, conn->params)) {
6162 char *new_mask = NULL;
6163 mangle_lookup_name_from_8_3(ctx, fname_src_mask, &new_mask,
6166 TALLOC_FREE(fname_src_mask);
6167 fname_src_mask = new_mask;
6171 if (!src_has_wild) {
6175 * Only one file needs to be renamed. Append the mask back
6176 * onto the directory.
6178 TALLOC_FREE(smb_fname_src->base_name);
6179 smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
6183 if (!smb_fname_src->base_name) {
6184 status = NT_STATUS_NO_MEMORY;
6188 /* Ensure dst fname contains a '/' also */
6189 if(strrchr_m(smb_fname_dst->base_name, '/') == 0) {
6191 tmp = talloc_asprintf(smb_fname_dst, "./%s",
6192 smb_fname_dst->base_name);
6194 status = NT_STATUS_NO_MEMORY;
6197 TALLOC_FREE(smb_fname_dst->base_name);
6198 smb_fname_dst->base_name = tmp;
6201 DEBUG(3, ("rename_internals: case_sensitive = %d, "
6202 "case_preserve = %d, short case preserve = %d, "
6203 "directory = %s, newname = %s, "
6204 "last_component_dest = %s\n",
6205 conn->case_sensitive, conn->case_preserve,
6206 conn->short_case_preserve,
6207 smb_fname_str_dbg(smb_fname_src),
6208 smb_fname_str_dbg(smb_fname_dst),
6209 smb_fname_dst->original_lcomp));
6211 /* The dest name still may have wildcards. */
6212 if (dest_has_wild) {
6213 char *fname_dst_mod = NULL;
6214 if (!resolve_wildcards(smb_fname_dst,
6215 smb_fname_src->base_name,
6216 smb_fname_dst->base_name,
6218 DEBUG(6, ("rename_internals: resolve_wildcards "
6220 smb_fname_src->base_name,
6221 smb_fname_dst->base_name));
6222 status = NT_STATUS_NO_MEMORY;
6225 TALLOC_FREE(smb_fname_dst->base_name);
6226 smb_fname_dst->base_name = fname_dst_mod;
6229 ZERO_STRUCT(smb_fname_src->st);
6230 if (posix_pathnames) {
6231 SMB_VFS_LSTAT(conn, smb_fname_src);
6233 SMB_VFS_STAT(conn, smb_fname_src);
6236 if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
6237 create_options |= FILE_DIRECTORY_FILE;
6240 status = SMB_VFS_CREATE_FILE(
6243 0, /* root_dir_fid */
6244 smb_fname_src, /* fname */
6245 access_mask, /* access_mask */
6246 (FILE_SHARE_READ | /* share_access */
6248 FILE_OPEN, /* create_disposition*/
6249 create_options, /* create_options */
6250 posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
6251 0, /* oplock_request */
6252 0, /* allocation_size */
6253 0, /* private_flags */
6259 if (!NT_STATUS_IS_OK(status)) {
6260 DEBUG(3, ("Could not open rename source %s: %s\n",
6261 smb_fname_str_dbg(smb_fname_src),
6262 nt_errstr(status)));
6266 status = rename_internals_fsp(conn, fsp, smb_fname_dst,
6267 attrs, replace_if_exists);
6269 close_file(req, fsp, NORMAL_CLOSE);
6271 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
6272 nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
6273 smb_fname_str_dbg(smb_fname_dst)));
6279 * Wildcards - process each file that matches.
6281 if (strequal(fname_src_mask, "????????.???")) {
6282 TALLOC_FREE(fname_src_mask);
6283 fname_src_mask = talloc_strdup(ctx, "*");
6284 if (!fname_src_mask) {
6285 status = NT_STATUS_NO_MEMORY;
6290 status = check_name(conn, fname_src_dir);
6291 if (!NT_STATUS_IS_OK(status)) {
6295 dir_hnd = OpenDir(talloc_tos(), conn, fname_src_dir, fname_src_mask,
6297 if (dir_hnd == NULL) {
6298 status = map_nt_error_from_unix(errno);
6302 status = NT_STATUS_NO_SUCH_FILE;
6304 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6305 * - gentest fix. JRA
6308 while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname_src->st,
6310 files_struct *fsp = NULL;
6311 char *destname = NULL;
6312 bool sysdir_entry = False;
6314 /* Quick check for "." and ".." */
6315 if (ISDOT(dname) || ISDOTDOT(dname)) {
6317 sysdir_entry = True;
6319 TALLOC_FREE(talloced);
6324 if (!is_visible_file(conn, fname_src_dir, dname,
6325 &smb_fname_src->st, false)) {
6326 TALLOC_FREE(talloced);
6330 if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) {
6331 TALLOC_FREE(talloced);
6336 status = NT_STATUS_OBJECT_NAME_INVALID;
6340 TALLOC_FREE(smb_fname_src->base_name);
6341 smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
6345 if (!smb_fname_src->base_name) {
6346 status = NT_STATUS_NO_MEMORY;
6350 if (!resolve_wildcards(ctx, smb_fname_src->base_name,
6351 smb_fname_dst->base_name,
6353 DEBUG(6, ("resolve_wildcards %s %s failed\n",
6354 smb_fname_src->base_name, destname));
6355 TALLOC_FREE(talloced);
6359 status = NT_STATUS_NO_MEMORY;
6363 TALLOC_FREE(smb_fname_dst->base_name);
6364 smb_fname_dst->base_name = destname;
6366 ZERO_STRUCT(smb_fname_src->st);
6367 if (posix_pathnames) {
6368 SMB_VFS_LSTAT(conn, smb_fname_src);
6370 SMB_VFS_STAT(conn, smb_fname_src);
6375 if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
6376 create_options |= FILE_DIRECTORY_FILE;
6379 status = SMB_VFS_CREATE_FILE(
6382 0, /* root_dir_fid */
6383 smb_fname_src, /* fname */
6384 access_mask, /* access_mask */
6385 (FILE_SHARE_READ | /* share_access */
6387 FILE_OPEN, /* create_disposition*/
6388 create_options, /* create_options */
6389 posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
6390 0, /* oplock_request */
6391 0, /* allocation_size */
6392 0, /* private_flags */
6398 if (!NT_STATUS_IS_OK(status)) {
6399 DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE "
6400 "returned %s rename %s -> %s\n",
6402 smb_fname_str_dbg(smb_fname_src),
6403 smb_fname_str_dbg(smb_fname_dst)));
6407 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6409 if (!smb_fname_dst->original_lcomp) {
6410 status = NT_STATUS_NO_MEMORY;
6414 status = rename_internals_fsp(conn, fsp, smb_fname_dst,
6415 attrs, replace_if_exists);
6417 close_file(req, fsp, NORMAL_CLOSE);
6419 if (!NT_STATUS_IS_OK(status)) {
6420 DEBUG(3, ("rename_internals_fsp returned %s for "
6421 "rename %s -> %s\n", nt_errstr(status),
6422 smb_fname_str_dbg(smb_fname_src),
6423 smb_fname_str_dbg(smb_fname_dst)));
6429 DEBUG(3,("rename_internals: doing rename on %s -> "
6430 "%s\n", smb_fname_str_dbg(smb_fname_src),
6431 smb_fname_str_dbg(smb_fname_src)));
6432 TALLOC_FREE(talloced);
6434 TALLOC_FREE(dir_hnd);
6436 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
6437 status = map_nt_error_from_unix(errno);
6441 TALLOC_FREE(talloced);
6442 TALLOC_FREE(fname_src_dir);
6443 TALLOC_FREE(fname_src_mask);
6447 /****************************************************************************
6449 ****************************************************************************/
6451 void reply_mv(struct smb_request *req)
6453 connection_struct *conn = req->conn;
6455 char *newname = NULL;
6459 bool src_has_wcard = False;
6460 bool dest_has_wcard = False;
6461 TALLOC_CTX *ctx = talloc_tos();
6462 struct smb_filename *smb_fname_src = NULL;
6463 struct smb_filename *smb_fname_dst = NULL;
6465 START_PROFILE(SMBmv);
6468 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6472 attrs = SVAL(req->vwv+0, 0);
6474 p = (const char *)req->buf + 1;
6475 p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE,
6476 &status, &src_has_wcard);
6477 if (!NT_STATUS_IS_OK(status)) {
6478 reply_nterror(req, status);
6482 p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
6483 &status, &dest_has_wcard);
6484 if (!NT_STATUS_IS_OK(status)) {
6485 reply_nterror(req, status);
6489 status = filename_convert(ctx,
6491 req->flags2 & FLAGS2_DFS_PATHNAMES,
6493 UCF_COND_ALLOW_WCARD_LCOMP,
6497 if (!NT_STATUS_IS_OK(status)) {
6498 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6499 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6500 ERRSRV, ERRbadpath);
6503 reply_nterror(req, status);
6507 status = filename_convert(ctx,
6509 req->flags2 & FLAGS2_DFS_PATHNAMES,
6511 UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,
6515 if (!NT_STATUS_IS_OK(status)) {
6516 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6517 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6518 ERRSRV, ERRbadpath);
6521 reply_nterror(req, status);
6525 DEBUG(3,("reply_mv : %s -> %s\n", smb_fname_str_dbg(smb_fname_src),
6526 smb_fname_str_dbg(smb_fname_dst)));
6528 status = rename_internals(ctx, conn, req, smb_fname_src, smb_fname_dst,
6529 attrs, False, src_has_wcard, dest_has_wcard,
6531 if (!NT_STATUS_IS_OK(status)) {
6532 if (open_was_deferred(req->mid)) {
6533 /* We have re-scheduled this call. */
6536 reply_nterror(req, status);
6540 reply_outbuf(req, 0, 0);
6542 TALLOC_FREE(smb_fname_src);
6543 TALLOC_FREE(smb_fname_dst);
6548 /*******************************************************************
6549 Copy a file as part of a reply_copy.
6550 ******************************************************************/
6553 * TODO: check error codes on all callers
6556 NTSTATUS copy_file(TALLOC_CTX *ctx,
6557 connection_struct *conn,
6558 struct smb_filename *smb_fname_src,
6559 struct smb_filename *smb_fname_dst,
6562 bool target_is_directory)
6564 struct smb_filename *smb_fname_dst_tmp = NULL;
6566 files_struct *fsp1,*fsp2;
6568 uint32 new_create_disposition;
6572 status = copy_smb_filename(ctx, smb_fname_dst, &smb_fname_dst_tmp);
6573 if (!NT_STATUS_IS_OK(status)) {
6578 * If the target is a directory, extract the last component from the
6579 * src filename and append it to the dst filename
6581 if (target_is_directory) {
6584 /* dest/target can't be a stream if it's a directory. */
6585 SMB_ASSERT(smb_fname_dst->stream_name == NULL);
6587 p = strrchr_m(smb_fname_src->base_name,'/');
6591 p = smb_fname_src->base_name;
6593 smb_fname_dst_tmp->base_name =
6594 talloc_asprintf_append(smb_fname_dst_tmp->base_name, "/%s",
6596 if (!smb_fname_dst_tmp->base_name) {
6597 status = NT_STATUS_NO_MEMORY;
6602 status = vfs_file_exist(conn, smb_fname_src);
6603 if (!NT_STATUS_IS_OK(status)) {
6607 if (!target_is_directory && count) {
6608 new_create_disposition = FILE_OPEN;
6610 if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun,
6612 &new_create_disposition,
6615 status = NT_STATUS_INVALID_PARAMETER;
6620 /* Open the src file for reading. */
6621 status = SMB_VFS_CREATE_FILE(
6624 0, /* root_dir_fid */
6625 smb_fname_src, /* fname */
6626 FILE_GENERIC_READ, /* access_mask */
6627 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
6628 FILE_OPEN, /* create_disposition*/
6629 0, /* create_options */
6630 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
6631 INTERNAL_OPEN_ONLY, /* oplock_request */
6632 0, /* allocation_size */
6633 0, /* private_flags */
6639 if (!NT_STATUS_IS_OK(status)) {
6643 dosattrs = dos_mode(conn, smb_fname_src);
6645 if (SMB_VFS_STAT(conn, smb_fname_dst_tmp) == -1) {
6646 ZERO_STRUCTP(&smb_fname_dst_tmp->st);
6649 /* Open the dst file for writing. */
6650 status = SMB_VFS_CREATE_FILE(
6653 0, /* root_dir_fid */
6654 smb_fname_dst, /* fname */
6655 FILE_GENERIC_WRITE, /* access_mask */
6656 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
6657 new_create_disposition, /* create_disposition*/
6658 0, /* create_options */
6659 dosattrs, /* file_attributes */
6660 INTERNAL_OPEN_ONLY, /* oplock_request */
6661 0, /* allocation_size */
6662 0, /* private_flags */
6668 if (!NT_STATUS_IS_OK(status)) {
6669 close_file(NULL, fsp1, ERROR_CLOSE);
6673 if ((ofun&3) == 1) {
6674 if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
6675 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
6677 * Stop the copy from occurring.
6680 smb_fname_src->st.st_ex_size = 0;
6684 /* Do the actual copy. */
6685 if (smb_fname_src->st.st_ex_size) {
6686 ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size);
6689 close_file(NULL, fsp1, NORMAL_CLOSE);
6691 /* Ensure the modtime is set correctly on the destination file. */
6692 set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
6695 * As we are opening fsp1 read-only we only expect
6696 * an error on close on fsp2 if we are out of space.
6697 * Thus we don't look at the error return from the
6700 status = close_file(NULL, fsp2, NORMAL_CLOSE);
6702 if (!NT_STATUS_IS_OK(status)) {
6706 if (ret != (SMB_OFF_T)smb_fname_src->st.st_ex_size) {
6707 status = NT_STATUS_DISK_FULL;
6711 status = NT_STATUS_OK;
6714 TALLOC_FREE(smb_fname_dst_tmp);
6718 /****************************************************************************
6719 Reply to a file copy.
6720 ****************************************************************************/
6722 void reply_copy(struct smb_request *req)
6724 connection_struct *conn = req->conn;
6725 struct smb_filename *smb_fname_src = NULL;
6726 struct smb_filename *smb_fname_dst = NULL;
6727 char *fname_src = NULL;
6728 char *fname_dst = NULL;
6729 char *fname_src_mask = NULL;
6730 char *fname_src_dir = NULL;
6733 int error = ERRnoaccess;
6737 bool target_is_directory=False;
6738 bool source_has_wild = False;
6739 bool dest_has_wild = False;
6741 TALLOC_CTX *ctx = talloc_tos();
6743 START_PROFILE(SMBcopy);
6746 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6750 tid2 = SVAL(req->vwv+0, 0);
6751 ofun = SVAL(req->vwv+1, 0);
6752 flags = SVAL(req->vwv+2, 0);
6754 p = (const char *)req->buf;
6755 p += srvstr_get_path_req_wcard(ctx, req, &fname_src, p, STR_TERMINATE,
6756 &status, &source_has_wild);
6757 if (!NT_STATUS_IS_OK(status)) {
6758 reply_nterror(req, status);
6761 p += srvstr_get_path_req_wcard(ctx, req, &fname_dst, p, STR_TERMINATE,
6762 &status, &dest_has_wild);
6763 if (!NT_STATUS_IS_OK(status)) {
6764 reply_nterror(req, status);
6768 DEBUG(3,("reply_copy : %s -> %s\n", fname_src, fname_dst));
6770 if (tid2 != conn->cnum) {
6771 /* can't currently handle inter share copies XXXX */
6772 DEBUG(3,("Rejecting inter-share copy\n"));
6773 reply_nterror(req, NT_STATUS_BAD_DEVICE_TYPE);
6777 status = filename_convert(ctx, conn,
6778 req->flags2 & FLAGS2_DFS_PATHNAMES,
6780 UCF_COND_ALLOW_WCARD_LCOMP,
6783 if (!NT_STATUS_IS_OK(status)) {
6784 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6785 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6786 ERRSRV, ERRbadpath);
6789 reply_nterror(req, status);
6793 status = filename_convert(ctx, conn,
6794 req->flags2 & FLAGS2_DFS_PATHNAMES,
6796 UCF_COND_ALLOW_WCARD_LCOMP,
6799 if (!NT_STATUS_IS_OK(status)) {
6800 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6801 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6802 ERRSRV, ERRbadpath);
6805 reply_nterror(req, status);
6809 target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st);
6811 if ((flags&1) && target_is_directory) {
6812 reply_nterror(req, NT_STATUS_NO_SUCH_FILE);
6816 if ((flags&2) && !target_is_directory) {
6817 reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
6821 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(smb_fname_src->st)) {
6822 /* wants a tree copy! XXXX */
6823 DEBUG(3,("Rejecting tree copy\n"));
6824 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6828 /* Split up the directory from the filename/mask. */
6829 status = split_fname_dir_mask(ctx, smb_fname_src->base_name,
6830 &fname_src_dir, &fname_src_mask);
6831 if (!NT_STATUS_IS_OK(status)) {
6832 reply_nterror(req, NT_STATUS_NO_MEMORY);
6837 * We should only check the mangled cache
6838 * here if unix_convert failed. This means
6839 * that the path in 'mask' doesn't exist
6840 * on the file system and so we need to look
6841 * for a possible mangle. This patch from
6842 * Tine Smukavec <valentin.smukavec@hermes.si>.
6844 if (!VALID_STAT(smb_fname_src->st) &&
6845 mangle_is_mangled(fname_src_mask, conn->params)) {
6846 char *new_mask = NULL;
6847 mangle_lookup_name_from_8_3(ctx, fname_src_mask,
6848 &new_mask, conn->params);
6850 /* Use demangled name if one was successfully found. */
6852 TALLOC_FREE(fname_src_mask);
6853 fname_src_mask = new_mask;
6857 if (!source_has_wild) {
6860 * Only one file needs to be copied. Append the mask back onto
6863 TALLOC_FREE(smb_fname_src->base_name);
6864 smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
6868 if (!smb_fname_src->base_name) {
6869 reply_nterror(req, NT_STATUS_NO_MEMORY);
6873 if (dest_has_wild) {
6874 char *fname_dst_mod = NULL;
6875 if (!resolve_wildcards(smb_fname_dst,
6876 smb_fname_src->base_name,
6877 smb_fname_dst->base_name,
6879 reply_nterror(req, NT_STATUS_NO_MEMORY);
6882 TALLOC_FREE(smb_fname_dst->base_name);
6883 smb_fname_dst->base_name = fname_dst_mod;
6886 status = check_name(conn, smb_fname_src->base_name);
6887 if (!NT_STATUS_IS_OK(status)) {
6888 reply_nterror(req, status);
6892 status = check_name(conn, smb_fname_dst->base_name);
6893 if (!NT_STATUS_IS_OK(status)) {
6894 reply_nterror(req, status);
6898 status = copy_file(ctx, conn, smb_fname_src, smb_fname_dst,
6899 ofun, count, target_is_directory);
6901 if(!NT_STATUS_IS_OK(status)) {
6902 reply_nterror(req, status);
6908 struct smb_Dir *dir_hnd = NULL;
6909 const char *dname = NULL;
6910 char *talloced = NULL;
6914 * There is a wildcard that requires us to actually read the
6915 * src dir and copy each file matching the mask to the dst.
6916 * Right now streams won't be copied, but this could
6917 * presumably be added with a nested loop for reach dir entry.
6919 SMB_ASSERT(!smb_fname_src->stream_name);
6920 SMB_ASSERT(!smb_fname_dst->stream_name);
6922 smb_fname_src->stream_name = NULL;
6923 smb_fname_dst->stream_name = NULL;
6925 if (strequal(fname_src_mask,"????????.???")) {
6926 TALLOC_FREE(fname_src_mask);
6927 fname_src_mask = talloc_strdup(ctx, "*");
6928 if (!fname_src_mask) {
6929 reply_nterror(req, NT_STATUS_NO_MEMORY);
6934 status = check_name(conn, fname_src_dir);
6935 if (!NT_STATUS_IS_OK(status)) {
6936 reply_nterror(req, status);
6940 dir_hnd = OpenDir(ctx, conn, fname_src_dir, fname_src_mask, 0);
6941 if (dir_hnd == NULL) {
6942 status = map_nt_error_from_unix(errno);
6943 reply_nterror(req, status);
6949 /* Iterate over the src dir copying each entry to the dst. */
6950 while ((dname = ReadDirName(dir_hnd, &offset,
6951 &smb_fname_src->st, &talloced))) {
6952 char *destname = NULL;
6954 if (ISDOT(dname) || ISDOTDOT(dname)) {
6955 TALLOC_FREE(talloced);
6959 if (!is_visible_file(conn, fname_src_dir, dname,
6960 &smb_fname_src->st, false)) {
6961 TALLOC_FREE(talloced);
6965 if(!mask_match(dname, fname_src_mask,
6966 conn->case_sensitive)) {
6967 TALLOC_FREE(talloced);
6971 error = ERRnoaccess;
6973 /* Get the src smb_fname struct setup. */
6974 TALLOC_FREE(smb_fname_src->base_name);
6975 smb_fname_src->base_name =
6976 talloc_asprintf(smb_fname_src, "%s/%s",
6977 fname_src_dir, dname);
6979 if (!smb_fname_src->base_name) {
6980 TALLOC_FREE(dir_hnd);
6981 TALLOC_FREE(talloced);
6982 reply_nterror(req, NT_STATUS_NO_MEMORY);
6986 if (!resolve_wildcards(ctx, smb_fname_src->base_name,
6987 smb_fname_dst->base_name,
6989 TALLOC_FREE(talloced);
6993 TALLOC_FREE(dir_hnd);
6994 TALLOC_FREE(talloced);
6995 reply_nterror(req, NT_STATUS_NO_MEMORY);
6999 TALLOC_FREE(smb_fname_dst->base_name);
7000 smb_fname_dst->base_name = destname;
7002 status = check_name(conn, smb_fname_src->base_name);
7003 if (!NT_STATUS_IS_OK(status)) {
7004 TALLOC_FREE(dir_hnd);
7005 TALLOC_FREE(talloced);
7006 reply_nterror(req, status);
7010 status = check_name(conn, smb_fname_dst->base_name);
7011 if (!NT_STATUS_IS_OK(status)) {
7012 TALLOC_FREE(dir_hnd);
7013 TALLOC_FREE(talloced);
7014 reply_nterror(req, status);
7018 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",
7019 smb_fname_src->base_name,
7020 smb_fname_dst->base_name));
7022 status = copy_file(ctx, conn, smb_fname_src,
7023 smb_fname_dst, ofun, count,
7024 target_is_directory);
7025 if (NT_STATUS_IS_OK(status)) {
7029 TALLOC_FREE(talloced);
7031 TALLOC_FREE(dir_hnd);
7035 reply_nterror(req, dos_to_ntstatus(ERRDOS, error));
7039 reply_outbuf(req, 1, 0);
7040 SSVAL(req->outbuf,smb_vwv0,count);
7042 TALLOC_FREE(smb_fname_src);
7043 TALLOC_FREE(smb_fname_dst);
7044 TALLOC_FREE(fname_src);
7045 TALLOC_FREE(fname_dst);
7046 TALLOC_FREE(fname_src_mask);
7047 TALLOC_FREE(fname_src_dir);
7049 END_PROFILE(SMBcopy);
7054 #define DBGC_CLASS DBGC_LOCKING
7056 /****************************************************************************
7057 Get a lock pid, dealing with large count requests.
7058 ****************************************************************************/
7060 uint64_t get_lock_pid(const uint8_t *data, int data_offset,
7061 bool large_file_format)
7063 if(!large_file_format)
7064 return (uint64_t)SVAL(data,SMB_LPID_OFFSET(data_offset));
7066 return (uint64_t)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
7069 /****************************************************************************
7070 Get a lock count, dealing with large count requests.
7071 ****************************************************************************/
7073 uint64_t get_lock_count(const uint8_t *data, int data_offset,
7074 bool large_file_format)
7078 if(!large_file_format) {
7079 count = (uint64_t)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
7082 #if defined(HAVE_LONGLONG)
7083 count = (((uint64_t) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
7084 ((uint64_t) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
7085 #else /* HAVE_LONGLONG */
7088 * NT4.x seems to be broken in that it sends large file (64 bit)
7089 * lockingX calls even if the CAP_LARGE_FILES was *not*
7090 * negotiated. For boxes without large unsigned ints truncate the
7091 * lock count by dropping the top 32 bits.
7094 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
7095 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
7096 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
7097 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
7098 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
7101 count = (uint64_t)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
7102 #endif /* HAVE_LONGLONG */
7108 #if !defined(HAVE_LONGLONG)
7109 /****************************************************************************
7110 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
7111 ****************************************************************************/
7113 static uint32 map_lock_offset(uint32 high, uint32 low)
7117 uint32 highcopy = high;
7120 * Try and find out how many significant bits there are in high.
7123 for(i = 0; highcopy; i++)
7127 * We use 31 bits not 32 here as POSIX
7128 * lock offsets may not be negative.
7131 mask = (~0) << (31 - i);
7134 return 0; /* Fail. */
7140 #endif /* !defined(HAVE_LONGLONG) */
7142 /****************************************************************************
7143 Get a lock offset, dealing with large offset requests.
7144 ****************************************************************************/
7146 uint64_t get_lock_offset(const uint8_t *data, int data_offset,
7147 bool large_file_format, bool *err)
7149 uint64_t offset = 0;
7153 if(!large_file_format) {
7154 offset = (uint64_t)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
7157 #if defined(HAVE_LONGLONG)
7158 offset = (((uint64_t) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
7159 ((uint64_t) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
7160 #else /* HAVE_LONGLONG */
7163 * NT4.x seems to be broken in that it sends large file (64 bit)
7164 * lockingX calls even if the CAP_LARGE_FILES was *not*
7165 * negotiated. For boxes without large unsigned ints mangle the
7166 * lock offset by mapping the top 32 bits onto the lower 32.
7169 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
7170 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
7171 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
7174 if((new_low = map_lock_offset(high, low)) == 0) {
7176 return (uint64_t)-1;
7179 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
7180 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
7181 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
7182 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
7185 offset = (uint64_t)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
7186 #endif /* HAVE_LONGLONG */
7192 NTSTATUS smbd_do_locking(struct smb_request *req,
7196 uint16_t num_ulocks,
7197 struct smbd_lock_element *ulocks,
7199 struct smbd_lock_element *locks,
7202 connection_struct *conn = req->conn;
7204 NTSTATUS status = NT_STATUS_OK;
7208 /* Data now points at the beginning of the list
7209 of smb_unlkrng structs */
7210 for(i = 0; i < (int)num_ulocks; i++) {
7211 struct smbd_lock_element *e = &ulocks[i];
7213 DEBUG(10,("smbd_do_locking: unlock start=%.0f, len=%.0f for "
7214 "pid %u, file %s\n",
7217 (unsigned int)e->smblctx,
7220 if (e->brltype != UNLOCK_LOCK) {
7221 /* this can only happen with SMB2 */
7222 return NT_STATUS_INVALID_PARAMETER;
7225 status = do_unlock(req->sconn->msg_ctx,
7232 DEBUG(10, ("smbd_do_locking: unlock returned %s\n",
7233 nt_errstr(status)));
7235 if (!NT_STATUS_IS_OK(status)) {
7240 /* Setup the timeout in seconds. */
7242 if (!lp_blocking_locks(SNUM(conn))) {
7246 /* Data now points at the beginning of the list
7247 of smb_lkrng structs */
7249 for(i = 0; i < (int)num_locks; i++) {
7250 struct smbd_lock_element *e = &locks[i];
7252 DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for smblctx "
7253 "%llu, file %s timeout = %d\n",
7256 (unsigned long long)e->smblctx,
7260 if (type & LOCKING_ANDX_CANCEL_LOCK) {
7261 struct blocking_lock_record *blr = NULL;
7263 if (num_locks > 1) {
7265 * MS-CIFS (2.2.4.32.1) states that a cancel is honored if and only
7266 * if the lock vector contains one entry. When given mutliple cancel
7267 * requests in a single PDU we expect the server to return an
7268 * error. Windows servers seem to accept the request but only
7269 * cancel the first lock.
7270 * JRA - Do what Windows does (tm) :-).
7274 /* MS-CIFS (2.2.4.32.1) behavior. */
7275 return NT_STATUS_DOS(ERRDOS,
7276 ERRcancelviolation);
7278 /* Windows behavior. */
7280 DEBUG(10,("smbd_do_locking: ignoring subsequent "
7281 "cancel request\n"));
7287 if (lp_blocking_locks(SNUM(conn))) {
7289 /* Schedule a message to ourselves to
7290 remove the blocking lock record and
7291 return the right error. */
7293 blr = blocking_lock_cancel_smb1(fsp,
7299 NT_STATUS_FILE_LOCK_CONFLICT);
7301 return NT_STATUS_DOS(
7303 ERRcancelviolation);
7306 /* Remove a matching pending lock. */
7307 status = do_lock_cancel(fsp,
7314 bool blocking_lock = timeout ? true : false;
7315 bool defer_lock = false;
7316 struct byte_range_lock *br_lck;
7317 uint64_t block_smblctx;
7319 br_lck = do_lock(req->sconn->msg_ctx,
7331 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
7332 /* Windows internal resolution for blocking locks seems
7333 to be about 200ms... Don't wait for less than that. JRA. */
7334 if (timeout != -1 && timeout < lp_lock_spin_time()) {
7335 timeout = lp_lock_spin_time();
7340 /* If a lock sent with timeout of zero would fail, and
7341 * this lock has been requested multiple times,
7342 * according to brl_lock_failed() we convert this
7343 * request to a blocking lock with a timeout of between
7344 * 150 - 300 milliseconds.
7346 * If lp_lock_spin_time() has been set to 0, we skip
7347 * this blocking retry and fail immediately.
7349 * Replacement for do_lock_spin(). JRA. */
7351 if (!req->sconn->using_smb2 &&
7352 br_lck && lp_blocking_locks(SNUM(conn)) &&
7353 lp_lock_spin_time() && !blocking_lock &&
7354 NT_STATUS_EQUAL((status),
7355 NT_STATUS_FILE_LOCK_CONFLICT))
7358 timeout = lp_lock_spin_time();
7361 if (br_lck && defer_lock) {
7363 * A blocking lock was requested. Package up
7364 * this smb into a queued request and push it
7365 * onto the blocking lock queue.
7367 if(push_blocking_lock_request(br_lck,
7378 TALLOC_FREE(br_lck);
7380 return NT_STATUS_OK;
7384 TALLOC_FREE(br_lck);
7387 if (!NT_STATUS_IS_OK(status)) {
7392 /* If any of the above locks failed, then we must unlock
7393 all of the previous locks (X/Open spec). */
7395 if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
7397 if (type & LOCKING_ANDX_CANCEL_LOCK) {
7398 i = -1; /* we want to skip the for loop */
7402 * Ensure we don't do a remove on the lock that just failed,
7403 * as under POSIX rules, if we have a lock already there, we
7404 * will delete it (and we shouldn't) .....
7406 for(i--; i >= 0; i--) {
7407 struct smbd_lock_element *e = &locks[i];
7409 do_unlock(req->sconn->msg_ctx,
7419 DEBUG(3, ("smbd_do_locking: fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
7420 fsp->fnum, (unsigned int)type, num_locks, num_ulocks));
7422 return NT_STATUS_OK;
7425 /****************************************************************************
7426 Reply to a lockingX request.
7427 ****************************************************************************/
7429 void reply_lockingX(struct smb_request *req)
7431 connection_struct *conn = req->conn;
7433 unsigned char locktype;
7434 unsigned char oplocklevel;
7439 const uint8_t *data;
7440 bool large_file_format;
7442 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
7443 struct smbd_lock_element *ulocks;
7444 struct smbd_lock_element *locks;
7447 START_PROFILE(SMBlockingX);
7450 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7451 END_PROFILE(SMBlockingX);
7455 fsp = file_fsp(req, SVAL(req->vwv+2, 0));
7456 locktype = CVAL(req->vwv+3, 0);
7457 oplocklevel = CVAL(req->vwv+3, 1);
7458 num_ulocks = SVAL(req->vwv+6, 0);
7459 num_locks = SVAL(req->vwv+7, 0);
7460 lock_timeout = IVAL(req->vwv+4, 0);
7461 large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
7463 if (!check_fsp(conn, req, fsp)) {
7464 END_PROFILE(SMBlockingX);
7470 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
7471 /* we don't support these - and CANCEL_LOCK makes w2k
7472 and XP reboot so I don't really want to be
7473 compatible! (tridge) */
7474 reply_force_doserror(req, ERRDOS, ERRnoatomiclocks);
7475 END_PROFILE(SMBlockingX);
7479 /* Check if this is an oplock break on a file
7480 we have granted an oplock on.
7482 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
7483 /* Client can insist on breaking to none. */
7484 bool break_to_none = (oplocklevel == 0);
7487 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
7488 "for fnum = %d\n", (unsigned int)oplocklevel,
7492 * Make sure we have granted an exclusive or batch oplock on
7496 if (fsp->oplock_type == 0) {
7498 /* The Samba4 nbench simulator doesn't understand
7499 the difference between break to level2 and break
7500 to none from level2 - it sends oplock break
7501 replies in both cases. Don't keep logging an error
7502 message here - just ignore it. JRA. */
7504 DEBUG(5,("reply_lockingX: Error : oplock break from "
7505 "client for fnum = %d (oplock=%d) and no "
7506 "oplock granted on this file (%s).\n",
7507 fsp->fnum, fsp->oplock_type,
7510 /* if this is a pure oplock break request then don't
7512 if (num_locks == 0 && num_ulocks == 0) {
7513 END_PROFILE(SMBlockingX);
7516 END_PROFILE(SMBlockingX);
7517 reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
7522 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
7524 result = remove_oplock(fsp);
7526 result = downgrade_oplock(fsp);
7530 DEBUG(0, ("reply_lockingX: error in removing "
7531 "oplock on file %s\n", fsp_str_dbg(fsp)));
7532 /* Hmmm. Is this panic justified? */
7533 smb_panic("internal tdb error");
7536 reply_to_oplock_break_requests(fsp);
7538 /* if this is a pure oplock break request then don't send a
7540 if (num_locks == 0 && num_ulocks == 0) {
7541 /* Sanity check - ensure a pure oplock break is not a
7543 if(CVAL(req->vwv+0, 0) != 0xff)
7544 DEBUG(0,("reply_lockingX: Error : pure oplock "
7545 "break is a chained %d request !\n",
7546 (unsigned int)CVAL(req->vwv+0, 0)));
7547 END_PROFILE(SMBlockingX);
7553 (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
7554 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7555 END_PROFILE(SMBlockingX);
7559 ulocks = talloc_array(req, struct smbd_lock_element, num_ulocks);
7560 if (ulocks == NULL) {
7561 reply_nterror(req, NT_STATUS_NO_MEMORY);
7562 END_PROFILE(SMBlockingX);
7566 locks = talloc_array(req, struct smbd_lock_element, num_locks);
7567 if (locks == NULL) {
7568 reply_nterror(req, NT_STATUS_NO_MEMORY);
7569 END_PROFILE(SMBlockingX);
7573 /* Data now points at the beginning of the list
7574 of smb_unlkrng structs */
7575 for(i = 0; i < (int)num_ulocks; i++) {
7576 ulocks[i].smblctx = get_lock_pid(data, i, large_file_format);
7577 ulocks[i].count = get_lock_count(data, i, large_file_format);
7578 ulocks[i].offset = get_lock_offset(data, i, large_file_format, &err);
7579 ulocks[i].brltype = UNLOCK_LOCK;
7582 * There is no error code marked "stupid client bug".... :-).
7585 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
7586 END_PROFILE(SMBlockingX);
7591 /* Now do any requested locks */
7592 data += ((large_file_format ? 20 : 10)*num_ulocks);
7594 /* Data now points at the beginning of the list
7595 of smb_lkrng structs */
7597 for(i = 0; i < (int)num_locks; i++) {
7598 locks[i].smblctx = get_lock_pid(data, i, large_file_format);
7599 locks[i].count = get_lock_count(data, i, large_file_format);
7600 locks[i].offset = get_lock_offset(data, i, large_file_format, &err);
7602 if (locktype & LOCKING_ANDX_SHARED_LOCK) {
7603 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
7604 locks[i].brltype = PENDING_READ_LOCK;
7606 locks[i].brltype = READ_LOCK;
7609 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
7610 locks[i].brltype = PENDING_WRITE_LOCK;
7612 locks[i].brltype = WRITE_LOCK;
7617 * There is no error code marked "stupid client bug".... :-).
7620 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
7621 END_PROFILE(SMBlockingX);
7626 status = smbd_do_locking(req, fsp,
7627 locktype, lock_timeout,
7631 if (!NT_STATUS_IS_OK(status)) {
7632 END_PROFILE(SMBlockingX);
7633 reply_nterror(req, status);
7637 END_PROFILE(SMBlockingX);
7641 reply_outbuf(req, 2, 0);
7643 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
7644 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
7646 END_PROFILE(SMBlockingX);
7651 #define DBGC_CLASS DBGC_ALL
7653 /****************************************************************************
7654 Reply to a SMBreadbmpx (read block multiplex) request.
7655 Always reply with an error, if someone has a platform really needs this,
7656 please contact vl@samba.org
7657 ****************************************************************************/
7659 void reply_readbmpx(struct smb_request *req)
7661 START_PROFILE(SMBreadBmpx);
7662 reply_force_doserror(req, ERRSRV, ERRuseSTD);
7663 END_PROFILE(SMBreadBmpx);
7667 /****************************************************************************
7668 Reply to a SMBreadbs (read block multiplex secondary) request.
7669 Always reply with an error, if someone has a platform really needs this,
7670 please contact vl@samba.org
7671 ****************************************************************************/
7673 void reply_readbs(struct smb_request *req)
7675 START_PROFILE(SMBreadBs);
7676 reply_force_doserror(req, ERRSRV, ERRuseSTD);
7677 END_PROFILE(SMBreadBs);
7681 /****************************************************************************
7682 Reply to a SMBsetattrE.
7683 ****************************************************************************/
7685 void reply_setattrE(struct smb_request *req)
7687 connection_struct *conn = req->conn;
7688 struct smb_file_time ft;
7692 START_PROFILE(SMBsetattrE);
7696 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7700 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
7702 if(!fsp || (fsp->conn != conn)) {
7703 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
7708 * Convert the DOS times into unix times.
7711 ft.atime = convert_time_t_to_timespec(
7712 srv_make_unix_date2(req->vwv+3));
7713 ft.mtime = convert_time_t_to_timespec(
7714 srv_make_unix_date2(req->vwv+5));
7715 ft.create_time = convert_time_t_to_timespec(
7716 srv_make_unix_date2(req->vwv+1));
7718 reply_outbuf(req, 0, 0);
7721 * Patch from Ray Frush <frush@engr.colostate.edu>
7722 * Sometimes times are sent as zero - ignore them.
7725 /* Ensure we have a valid stat struct for the source. */
7726 status = vfs_stat_fsp(fsp);
7727 if (!NT_STATUS_IS_OK(status)) {
7728 reply_nterror(req, status);
7732 status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true);
7733 if (!NT_STATUS_IS_OK(status)) {
7734 reply_nterror(req, status);
7738 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u "
7741 (unsigned int)ft.atime.tv_sec,
7742 (unsigned int)ft.mtime.tv_sec,
7743 (unsigned int)ft.create_time.tv_sec
7746 END_PROFILE(SMBsetattrE);
7751 /* Back from the dead for OS/2..... JRA. */
7753 /****************************************************************************
7754 Reply to a SMBwritebmpx (write block multiplex primary) request.
7755 Always reply with an error, if someone has a platform really needs this,
7756 please contact vl@samba.org
7757 ****************************************************************************/
7759 void reply_writebmpx(struct smb_request *req)
7761 START_PROFILE(SMBwriteBmpx);
7762 reply_force_doserror(req, ERRSRV, ERRuseSTD);
7763 END_PROFILE(SMBwriteBmpx);
7767 /****************************************************************************
7768 Reply to a SMBwritebs (write block multiplex secondary) request.
7769 Always reply with an error, if someone has a platform really needs this,
7770 please contact vl@samba.org
7771 ****************************************************************************/
7773 void reply_writebs(struct smb_request *req)
7775 START_PROFILE(SMBwriteBs);
7776 reply_force_doserror(req, ERRSRV, ERRuseSTD);
7777 END_PROFILE(SMBwriteBs);
7781 /****************************************************************************
7782 Reply to a SMBgetattrE.
7783 ****************************************************************************/
7785 void reply_getattrE(struct smb_request *req)
7787 connection_struct *conn = req->conn;
7790 struct timespec create_ts;
7792 START_PROFILE(SMBgetattrE);
7795 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7796 END_PROFILE(SMBgetattrE);
7800 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
7802 if(!fsp || (fsp->conn != conn)) {
7803 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
7804 END_PROFILE(SMBgetattrE);
7808 /* Do an fstat on this file */
7810 reply_nterror(req, map_nt_error_from_unix(errno));
7811 END_PROFILE(SMBgetattrE);
7815 mode = dos_mode(conn, fsp->fsp_name);
7818 * Convert the times into dos times. Set create
7819 * date to be last modify date as UNIX doesn't save
7823 reply_outbuf(req, 11, 0);
7825 create_ts = get_create_timespec(conn, fsp, fsp->fsp_name);
7826 srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
7827 srv_put_dos_date2((char *)req->outbuf, smb_vwv2,
7828 convert_timespec_to_time_t(fsp->fsp_name->st.st_ex_atime));
7829 /* Should we check pending modtime here ? JRA */
7830 srv_put_dos_date2((char *)req->outbuf, smb_vwv4,
7831 convert_timespec_to_time_t(fsp->fsp_name->st.st_ex_mtime));
7834 SIVAL(req->outbuf, smb_vwv6, 0);
7835 SIVAL(req->outbuf, smb_vwv8, 0);
7837 uint32 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &fsp->fsp_name->st);
7838 SIVAL(req->outbuf, smb_vwv6, (uint32)fsp->fsp_name->st.st_ex_size);
7839 SIVAL(req->outbuf, smb_vwv8, allocation_size);
7841 SSVAL(req->outbuf,smb_vwv10, mode);
7843 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
7845 END_PROFILE(SMBgetattrE);